def test_verify_recoverable_sign(self): """Verifies recovering a signature.""" test_requests = [TEST_REQUEST_TRANSFER_ICX, TEST_REQUEST_SCORE_FUNCTION_CALL, TEST_REQUEST_SEND_MESSAGE, TEST_REQUEST_SCORE_UPDATE, TEST_REQUEST_SCORE_ISNTALL] for request in test_requests: # Serialize a signature private_key_object = PrivateKey() msg_hash_bytes = sha3_256(serialize(request["params"])).digest() sign_bytes = sign(msg_hash_bytes, private_key_object.private_key) # Deserialize a signature recoverable_sign = private_key_object.ecdsa_recoverable_deserialize(sign_bytes[0:64], sign_bytes[64]) sign_ = private_key_object.ecdsa_recoverable_convert(recoverable_sign) # Verify a signature with a public key self.assertTrue(private_key_object.pubkey.ecdsa_verify(msg_hash_bytes, sign_, raw=True)) # Verify a signature when an message is invalid invalid_msg_hash = sha3_256(f'invalid message'.encode()).digest() self.assertFalse(private_key_object.pubkey.ecdsa_verify(invalid_msg_hash, sign_, raw=True)) # Verify a signature when a private key is invalid invalid_private_key = PrivateKey() self.assertFalse(invalid_private_key.pubkey.ecdsa_verify(msg_hash_bytes, sign_, raw=True))
def test_for_serialize_case_for_sending_normal_tx(self): """Test when serializer serializes perfectly in this case when is normal send transaction.""" tx_request = TEST_REQUEST_TRANSFER_ICX correct_serialized_params = "icx_sendTransaction.from.hxbe258ceb872e08851f1f59694dac2558708ece11.nid.0x3f." \ "nonce.0x1.stepLimit.0x12345.timestamp.0x563a6cf330136.to.hx5bfdb090f43a808005" \ "ffc27c25b213145e80b7cd.value.0xde0b6b3a7640000.version.0x3" self.assertEqual(correct_serialized_params.encode(), serialize(tx_request["params"]))
def test_check_if_wallet_signed_equally(self): msg = serialize(TEST_REQUEST_TRANSFER_ICX["params"]) message_hash = sha3_256(msg).digest() sign1 = signer1.sign(message_hash, bytes.fromhex(self.wallet1.get_private_key())) sign2 = signer2.sign(message_hash, bytes.fromhex(self.wallet2.get_private_key())) self.assertEqual(sign1, sign2)
def test_for_serialize_case_for_calling(self): """Test when serializer serializes perfectly in this case when dataType is call.""" tx_request = TEST_REQUEST_SCORE_FUNCTION_CALL correct_serialized_params = "icx_sendTransaction.data.{method.transfer.params.{to.hxab2d8215eab14bc6bdd8b" \ "fb2c8151257032ecd8b.value.0x1}}.dataType.call.from.hxbe258ceb872e08851f1f596" \ "94dac2558708ece11.nid.0x3f.nonce.0x1.stepLimit.0x12345.timestamp.0x563a6cf33" \ "0136.to.cxb0776ee37f5b45bfaea8cff1d8232fbb6122ec32.version.0x3" self.assertEqual(correct_serialized_params.encode(), serialize(tx_request["params"]))
def __init__(self, transaction: Transaction, wallet: Wallet): """Converts raw transaction into the signed transaction object having a signature. :param transaction: A transaction object not having a signature field yet :param wallet: A wallet object """ self.__signed_transaction_dict = self.to_dict(transaction, wallet) message_hash = sha3_256(serialize( self.__signed_transaction_dict)).digest() signature = wallet.sign(message_hash) self.__signed_transaction_dict["signature"] = b64encode( signature).decode()
async def create_icx_tx(self, kwargs: dict) -> Tuple[int, Optional[str], str]: """ Handler of 'create_icx_tx' message. 'create_icx_tx' is generated by 'icx_sendTransaction' Validate transaction and enqueue to transaction queue :param kwargs: transaction data :return: message code and transaction hash """ Logger.debug(f'Get create_tcx_tx message!! {kwargs}', "create_icx_tx") block_manager = self._block_manager # generate tx hash serialized_data = serialize(kwargs) tx_hash = create_hash(serialized_data) # check duplication duplicated_tx = False for tx in block_manager.tx_queue: if tx_hash == tx['txHash']: duplicated_tx = True if duplicated_tx is False and block_manager._block.get_transaction( tx_hash=tx_hash): duplicated_tx = True if duplicated_tx: return message_code.Response.fail_tx_invalid_duplicated_hash, None, '' # check signature validity signature = kwargs['signature'] if signature != 'sig': msg_hash = hashlib.sha3_256(serialized_data).digest() sig_byte = base64.b64decode(signature) if not verify_signature(msg_hash, sig_byte, kwargs['from']): return message_code.Response.fail_tx_invalid_signature, None, '' # append to transaction queue block_manager.add_tx(tx_hash=tx_hash, tx=kwargs) Logger.debug(f'Response create_icx_tx!!', "create_icx_tx") return message_code.Response.success, f"0x{tx_hash}", ''
def __init__(self, transaction: Transaction, wallet: Wallet, step_limit: int = None): """Converts raw transaction into the signed transaction object having a signature. :param transaction: A transaction object not having a signature field yet :param wallet: A wallet object """ if step_limit is not None: transaction.step_limit = step_limit if transaction.step_limit is None: raise DataTypeException( "Transaction should have step limit when signed.") self.__signed_transaction_dict = self.convert_tx_to_jsonrpc_request( transaction, wallet) message_hash = sha3_256(serialize( self.__signed_transaction_dict)).digest() signature = wallet.sign(message_hash) self.__signed_transaction_dict["signature"] = b64encode( signature).decode()
def test_verify_recoverable_sign(self): """Verifies recovering a signature.""" test_requests = [ TEST_REQUEST_TRANSFER_ICX, TEST_REQUEST_SCORE_FUNCTION_CALL, TEST_REQUEST_SEND_MESSAGE, TEST_REQUEST_SCORE_UPDATE, TEST_REQUEST_SCORE_ISNTALL ] for request in test_requests: # Serialize a signature private_key_object: PrivateKey = PrivateKey() private_key_bytes: bytes = private_key_object.secret msg = serialize(request["params"]) message_hash = sha3_256(msg).digest() sign_bytes = sign(message_hash, private_key_bytes) public_key = PublicKey.from_signature_and_message(sign_bytes, message_hash, hasher=None) self.assertEqual(public_key.format(), private_key_object.public_key.format())