def test_transacting_power_sign_message(testerchain): # Manually create a TransactingPower eth_address = testerchain.etherbase_account power = TransactingPower(password=INSECURE_DEVELOPMENT_PASSWORD, signer=Web3Signer(testerchain.client), account=eth_address) # Manually unlock power.unlock(password=INSECURE_DEVELOPMENT_PASSWORD) # Sign data_to_sign = b'Premium Select Luxury Pencil Holder' signature = power.sign_message(message=data_to_sign) # Verify is_verified = verify_eip_191(address=eth_address, message=data_to_sign, signature=signature) assert is_verified is True # Test invalid address/pubkey pair is_verified = verify_eip_191(address=testerchain.client.accounts[1], message=data_to_sign, signature=signature) assert is_verified is False
def test_blockchain_ursula_substantiates_stamp(blockchain_ursulas): first_ursula = list(blockchain_ursulas)[0] signature_as_bytes = first_ursula.operator_signature signature_as_bytes = to_standard_signature_bytes(signature_as_bytes) # `operator_address` was derived in nucypher_core, check it independently assert verify_eip_191(address=first_ursula.operator_address, message=bytes(first_ursula.stamp), signature=signature_as_bytes)
def test_blockchain_ursula_substantiates_stamp(blockchain_ursulas): first_ursula = list(blockchain_ursulas)[0] signature_as_bytes = first_ursula.decentralized_identity_evidence signature_as_bytes = to_standard_signature_bytes(signature_as_bytes) assert verify_eip_191(address=first_ursula.worker_address, message=bytes(first_ursula.stamp), signature=signature_as_bytes) # This method is a shortcut for the above. assert first_ursula._stamp_has_valid_signature_by_worker()
def test_character_transacting_power_signing(testerchain, agency, test_registry): # Pretend to be a character. eth_address = testerchain.etherbase_account signer = Character(is_me=True, eth_provider_uri=MOCK_ETH_PROVIDER_URI, registry=test_registry, checksum_address=eth_address) # Manually consume the power up transacting_power = TransactingPower( password=INSECURE_DEVELOPMENT_PASSWORD, signer=Web3Signer(testerchain.client), account=eth_address) signer._crypto_power.consume_power_up(transacting_power) # Retrieve the power up power = signer._crypto_power.power_ups(TransactingPower) assert power == transacting_power # Sign Message data_to_sign = b'Premium Select Luxury Pencil Holder' signature = power.sign_message(message=data_to_sign) is_verified = verify_eip_191(address=eth_address, message=data_to_sign, signature=signature) assert is_verified is True # Sign Transaction transaction_dict = { 'nonce': testerchain.client.w3.eth.getTransactionCount(eth_address), 'gasPrice': testerchain.client.w3.eth.gasPrice, 'gas': 100000, 'from': eth_address, 'to': testerchain.unassigned_accounts[1], 'value': 1, 'data': b'' } signed_transaction = power.sign_transaction( transaction_dict=transaction_dict) # Demonstrate that the transaction is valid RLP encoded. restored_transaction = Transaction.from_bytes( serialized_bytes=signed_transaction) restored_dict = restored_transaction.as_dict() assert to_checksum_address(restored_dict['to']) == transaction_dict['to']
def test_verify_eip191(testerchain, signature_verifier): message = os.urandom(100) # Generate Umbral key umbral_privkey = SecretKey.random() umbral_pubkey = umbral_privkey.public_key() umbral_pubkey_bytes = pubkey_as_uncompressed_bytes(umbral_pubkey) # # Check EIP191 signatures: Version E # # Produce EIP191 signature (version E) signable_message = encode_defunct(primitive=message) signature = Account.sign_message( signable_message=signable_message, private_key=umbral_privkey.to_secret_bytes()) signature = bytes(signature.signature) # Off-chain verify, just in case checksum_address = to_checksum_address( canonical_address_from_umbral_key(umbral_pubkey)) assert verify_eip_191(address=checksum_address, message=message, signature=signature) # Verify signature on-chain version_E = b'E' assert signature_verifier.functions.verifyEIP191(message, signature, umbral_pubkey_bytes, version_E).call() # Of course, it'll fail if we try using version 0 version_0 = b'\x00' assert not signature_verifier.functions.verifyEIP191( message, signature, umbral_pubkey_bytes, version_0).call() # Check that the hash-based method also works independently hash = signature_verifier.functions.hashEIP191(message, version_E).call() eip191_header = "\x19Ethereum Signed Message:\n" + str(len(message)) assert hash == keccak_digest(eip191_header.encode() + message) address = signature_verifier.functions.recover(hash, signature).call() assert address == checksum_address # # Check EIP191 signatures: Version 0 # # Produce EIP191 signature (version 0) validator = to_canonical_address(signature_verifier.address) signable_message = SignableMessage(version=HexBytes(version_0), header=HexBytes(validator), body=HexBytes(message)) signature = Account.sign_message( signable_message=signable_message, private_key=umbral_privkey.to_secret_bytes()) signature = bytes(signature.signature) # Off-chain verify, just in case checksum_address = to_checksum_address( canonical_address_from_umbral_key(umbral_pubkey)) assert checksum_address == Account.recover_message( signable_message=signable_message, signature=signature) # On chain verify signature assert signature_verifier.functions.verifyEIP191(message, signature, umbral_pubkey_bytes, version_0).call() # Of course, now it fails if we try with version E assert not signature_verifier.functions.verifyEIP191( message, signature, umbral_pubkey_bytes, version_E).call() # Check that the hash-based method also works independently hash = signature_verifier.functions.hashEIP191(message, version_0).call() eip191_header = b"\x19\x00" + validator assert hash == keccak_digest(eip191_header + message) address = signature_verifier.functions.recover(hash, signature).call() assert address == checksum_address