Skip to content
This repository has been archived by the owner on Dec 15, 2021. It is now read-only.

IS-1024: Add sha_256 function for SCORE development #422

Merged
merged 1 commit into from
Mar 5, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion iconservice/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@
from .icon_constant import IconServiceFlag
from .iconscore.icon_container_db import VarDB, DictDB, ArrayDB
from .iconscore.icon_score_base import interface, eventlog, external, payable, IconScoreBase, IconScoreDatabase
from .iconscore.icon_score_base2 import (InterfaceScore, revert, sha3_256, json_loads, json_dumps,
from .iconscore.icon_score_base2 import (InterfaceScore, revert, sha3_256, sha_256, json_loads, json_dumps,
get_main_prep_info, get_sub_prep_info, recover_key,
create_address_with_key, create_interface_score)
from .iconscore.icon_system_score_base import IconSystemScoreBase
28 changes: 26 additions & 2 deletions iconservice/iconscore/icon_score_base2.py
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,7 @@ def timestamp(self) -> int:

class ScoreApiStepRatio(IntEnum):
SHA3_256 = 1000
SHA_256 = 1000
CREATE_ADDRESS_WITH_COMPRESSED_KEY = 15000
CREATE_ADDRESS_WITH_UNCOMPRESSED_KEY = 1500
JSON_DUMPS = 5000
Expand Down Expand Up @@ -149,11 +150,33 @@ def revert(message: Optional[str] = None, code: int = 0) -> None:

def sha3_256(data: bytes) -> bytes:
"""
Computes hash using the input data
Computes sha3_256 hash using the input data

:param data: input data
:return: hashed data in bytes
"""
return _hash("sha3_256", data)


def sha_256(data: bytes) -> bytes:
"""
Computes sha256 hash using the input data

:param data: input data
:return: hashed data in bytes
"""
return _hash("sha256", data)


def _hash(name: str, data: bytes) -> bytes:
"""Protected hash function

:param name: hash function name: "sha256" or "sha3_256"
:param data: data to hash
:return: hashed data in bytes
"""
if name not in ("sha3_256", "sha256"):
raise InvalidParamsException(f"Not supported: {name}")
if not isinstance(data, bytes):
raise InvalidParamsException("Invalid dataType")

Expand All @@ -171,7 +194,8 @@ def sha3_256(data: bytes) -> bytes:

context.step_counter.consume_step(StepType.API_CALL, step)

return hashlib.sha3_256(data).digest()
func = getattr(hashlib, name)
return func(data).digest()


def json_dumps(obj: Any) -> str:
Expand Down
28 changes: 24 additions & 4 deletions tests/test_icon_score_api.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@
from iconservice.iconscore.icon_score_base2 import ScoreApiStepRatio
from iconservice.iconscore.icon_score_base2 import _create_address_with_key, _recover_key
from iconservice.iconscore.icon_score_base2 import create_address_with_key, recover_key
from iconservice.iconscore.icon_score_base2 import sha3_256, json_dumps, json_loads
from iconservice.iconscore.icon_score_base2 import sha3_256, sha_256, json_dumps, json_loads
from iconservice.iconscore.icon_score_context import ContextContainer
from iconservice.iconscore.icon_score_context import IconScoreContext, IconScoreContextType, IconScoreContextFactory
from iconservice.iconscore.icon_score_step import IconScoreStepCounterFactory, StepType
Expand Down Expand Up @@ -245,19 +245,39 @@ def test_create_address_with_key_step_with_tx_v3(self):
step_used: int = self.context.step_counter.step_used
self.assertEqual(compressed_step_cost, step_used)

def test_sha3_256_step(self):
def test_sha3_256(self):
step_cost: int = self._calc_step_cost(ScoreApiStepRatio.SHA3_256)

for i in range(0, 512):
chunks = i // 32
if i % 32 > 0:
chunks += 1

sha3_256(b'\x00' * i)
data: bytes = b'\x00' * i
hash_value: bytes = sha3_256(data)
assert hash_value == hashlib.sha3_256(data).digest()

expected_step: int = step_cost + step_cost * chunks // 10
step_used: int = self.context.step_counter.step_used
self.assertEqual(expected_step, step_used)
assert step_used == expected_step

self.context.step_counter.reset(self.step_limit)

def test_sha_256(self):
step_cost: int = self._calc_step_cost(ScoreApiStepRatio.SHA_256)

for i in range(0, 512):
chunks = i // 32
if i % 32 > 0:
chunks += 1

data: bytes = b'\x00' * i
hash_value: bytes = sha_256(data)
assert hash_value == hashlib.sha256(data).digest()

expected_step: int = step_cost + step_cost * chunks // 10
step_used: int = self.context.step_counter.step_used
assert step_used == expected_step

self.context.step_counter.reset(self.step_limit)

Expand Down