From c7f8eec9b8cf1b3911b805bbfab7e02ecb94b36f Mon Sep 17 00:00:00 2001 From: Alexandru Popenta Date: Thu, 18 Apr 2024 15:42:40 +0300 Subject: [PATCH 1/2] update dependencies & fix encode signed number --- multiversx_sdk_core/codec.py | 5 ++- multiversx_sdk_core/codec_test.py | 75 +++++++++++++++++++++++++++++++ pyproject.toml | 6 +-- requirements.txt | 4 +- 4 files changed, 84 insertions(+), 6 deletions(-) create mode 100644 multiversx_sdk_core/codec_test.py diff --git a/multiversx_sdk_core/codec.py b/multiversx_sdk_core/codec.py index 32013c8..d405ca5 100644 --- a/multiversx_sdk_core/codec.py +++ b/multiversx_sdk_core/codec.py @@ -7,7 +7,10 @@ def encode_unsigned_number(arg: int) -> bytes: def encode_signed_number(arg: int) -> bytes: - return arg.to_bytes(INTEGER_MAX_NUM_BYTES, byteorder="big", signed=True).lstrip(bytes([255])) + if arg == 0: + return b'' + length = ((arg + (arg < 0)).bit_length() + 7 + 1) // 8 + return arg.to_bytes(length, byteorder="big", signed=True) def decode_unsigned_number(arg: bytes) -> int: diff --git a/multiversx_sdk_core/codec_test.py b/multiversx_sdk_core/codec_test.py new file mode 100644 index 0000000..25705d4 --- /dev/null +++ b/multiversx_sdk_core/codec_test.py @@ -0,0 +1,75 @@ +from multiversx_sdk_core.codec import encode_signed_number + +test_vectors_1 = [ + [-1, 0xFF], + [1, 0x01], + [2, 0x02], + [-2, 0xFE], + [3, 0x03], + [-3, 0xFD], + [4, 0x04], + [-4, 0xFC], +] + +test_vectors_2 = [ + [-1, 0xFF], + [1, 0x01], + [2, 0x02], + [-2, 0xFE], + [3, 0x03], + [-3, 0xFD], + [4, 0x04], + [-4, 0xFC], + [5, 0x05], + [-5, 0xFB], + [6, 0x06], + [-6, 0xFA], +] + +test_vectors_3 = [ + [125, 0x7D], + [-125, 0x83], + [126, 0x7E], + [-126, 0x82], + [127, 0x7F], + [-127, 0x81], + [-128, 0x80], +] + +test_vectors_4 = [ + [128, [0x00, 0x80]], + [129, [0x00, 0x81]], + [-129, [0xFF, 0x7F]], + [130, [0x00, 0x82]], + [-130, [0xFF, 0x7E]], + [253, [0x00, 0xFD]], + [256, [0x01, 0x00]], + [-256, [0xFF, 0x00]], + [-257, [0xFE, 0xFF]], + [258, [0x01, 0x02]], +] + + +def test_encode_signed_number(): + assert encode_signed_number(-256) == bytes([0xFF, 0x00]) + assert encode_signed_number(-0x11) == bytes([0xEF]) + assert encode_signed_number(-128) == bytes([0x80]) + assert encode_signed_number(-1) == bytes([0xFF]) + assert encode_signed_number(0) == bytes([]) + assert encode_signed_number(1) == bytes([0x01]) + assert encode_signed_number(256) == bytes([0x01, 0x00]) + assert encode_signed_number(127) == bytes([0x7F]) + assert encode_signed_number(0x11) == bytes([0x11]) + assert encode_signed_number(255) == bytes([0x00, 0xFF]) + + for input_data, expected_data in test_vectors_1: + assert encode_signed_number(input_data) == bytes([expected_data]) + + for input_data, expected_data in test_vectors_2: + assert encode_signed_number(input_data) == bytes([expected_data]) + + for input_data, expected_data in test_vectors_3: + assert encode_signed_number(input_data) == bytes([expected_data]) + + for input_data, expected_data in test_vectors_4: + assert encode_signed_number(input_data) == bytes(expected_data) # type: ignore diff --git a/pyproject.toml b/pyproject.toml index 135c525..a235c2f 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -4,7 +4,7 @@ build-backend = "hatchling.build" [project] name = "multiversx-sdk-core" -version = "0.8.0" +version = "0.8.1" authors = [ { name="MultiversX" }, ] @@ -18,8 +18,8 @@ classifiers = [ "Operating System :: OS Independent", ] dependencies = [ - "pycryptodomex==3.16.0", - "protobuf==3.20.1" + "pycryptodomex==3.19.1", + "protobuf==3.20.2" ] [project.urls] diff --git a/requirements.txt b/requirements.txt index 03be1fd..2bfd275 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,2 +1,2 @@ -pycryptodomex==3.16.0 -protobuf==3.20.1 +pycryptodomex==3.19.1 +protobuf==3.20.2 From 80e89202ddb170f56f8633965170670b23f1ff77 Mon Sep 17 00:00:00 2001 From: Alexandru Popenta Date: Thu, 18 Apr 2024 15:50:26 +0300 Subject: [PATCH 2/2] add method to compute hash for signing --- multiversx_sdk_core/transaction.py | 5 +++++ multiversx_sdk_core/transaction_test.py | 16 ++++++++++++++++ 2 files changed, 21 insertions(+) diff --git a/multiversx_sdk_core/transaction.py b/multiversx_sdk_core/transaction.py index c15d0af..fa300ff 100644 --- a/multiversx_sdk_core/transaction.py +++ b/multiversx_sdk_core/transaction.py @@ -4,6 +4,8 @@ from hashlib import blake2b from typing import Any, Dict, Optional, Protocol +from Cryptodome.Hash import keccak + from multiversx_sdk_core.constants import (DEFAULT_HRP, DIGEST_SIZE, TRANSACTION_MIN_GAS_PRICE, TRANSACTION_OPTIONS_DEFAULT, @@ -87,6 +89,9 @@ def compute_bytes_for_signing(self, transaction: ITransaction) -> bytes: serialized = self._dict_to_json(dictionary) return serialized + def compute_hash_for_signing(self, transaction: ITransaction) -> bytes: + return keccak.new(digest_bits=256).update(self.compute_bytes_for_signing(transaction)).digest() + def compute_transaction_hash(self, transaction: ITransaction) -> bytes: proto = ProtoSerializer() serialized_tx = proto.serialize_transaction(transaction) diff --git a/multiversx_sdk_core/transaction_test.py b/multiversx_sdk_core/transaction_test.py index 88ca4ff..d85d89a 100644 --- a/multiversx_sdk_core/transaction_test.py +++ b/multiversx_sdk_core/transaction_test.py @@ -191,3 +191,19 @@ def test_compute_transaction_with_dummy_guardian(self): tx_hash = self.transaction_computer.compute_transaction_hash(transaction) assert tx_hash.hex() == "242022e9dcfa0ee1d8199b0043314dbda8601619f70069ebc441b9f03349a35c" + + def test_sign_transaction_by_hash(self): + tx = Transaction( + sender="erd1qyu5wthldzr8wx5c9ucg8kjagg0jfs53s8nr3zpz3hypefsdd8ssycr6th", + receiver="erd1spyavw0956vq68xj8y4tenjpq2wd5a9p2c6j8gsz7ztyrnpxrruqzu66jx", + value=0, + gas_limit=50000, + version=2, + options=1, + chain_id="integration tests chain ID", + nonce=89 + ) + serialized = self.transaction_computer.compute_hash_for_signing(tx) + tx.signature = self.alice.secret_key.sign(serialized) + + assert tx.signature.hex() == "f0c81f2393b1ec5972c813f817bae8daa00ade91c6f75ea604ab6a4d2797aca4378d783023ff98f1a02717fe4f24240cdfba0b674ee9abb18042203d713bc70a"