Use EIP-191 Signatures on Geth and PyEVM backends

pull/1040/head
Kieran R. Prasch 2019-05-30 08:22:44 -07:00 committed by Kieran Prasch
parent f2c655efae
commit ed1436aac4
No known key found for this signature in database
GPG Key ID: 199AB839D4125A62
4 changed files with 20 additions and 26 deletions

View File

@ -231,7 +231,9 @@ class GethClient(Web3Client):
def unlock_account(self, address, password): def unlock_account(self, address, password):
return self.w3.geth.personal.unlockAccount(address, password) return self.w3.geth.personal.unlockAccount(address, password)
def verify_signature(self, account, message, signature) -> bool:
@staticmethod
def verify_signature(account: str, message: bytes, signature: bytes) -> bool:
""" """
EIP-191 Compatible signature verification for usage with w3.eth.sign. EIP-191 Compatible signature verification for usage with w3.eth.sign.

View File

@ -107,33 +107,26 @@ class BlockchainPower(CryptoPowerUp):
if not self.is_unlocked: if not self.is_unlocked:
raise PowerUpError("Failed to unlock account {}".format(self.account)) raise PowerUpError("Failed to unlock account {}".format(self.account))
def sign_message(self, message: bytes): def sign_message(self, message: bytes) -> bytes:
""" """
Signs the message with the private key of the BlockchainPower. Signs the message with the private key of the BlockchainPower.
""" """
if not self.is_unlocked: if not self.is_unlocked:
raise PowerUpError("Account is not unlocked.") raise PowerUpError("Account is not unlocked.")
signature = self.blockchain.interface.client.sign_message(self.account, message)
return signature
signature = self.blockchain.interface.call_backend_sign(self.account, message) def verify_message(self, address: str, message: bytes, signature: bytes) -> bool:
return bytes(signature)
def verify_message(self, address: str, pubkey: bytes, message: bytes, signature_bytes: bytes):
""" """
Verifies that the message was signed by the keypair. Verifies that the message was signed by the private key of the address provided.
""" """
# Check that address and pubkey match signature_is_valid = self.blockchain.interface.client.verify_message(address=address,
eth_pubkey = PublicKey(pubkey) message=message,
signature = EthSignature(signature_bytes=signature_bytes) signature=signature)
if not eth_pubkey.to_checksum_address() == address: if signature_is_valid:
raise ValueError("Pubkey address ({}) doesn't match the provided address ({})".format(eth_pubkey.to_checksum_address, address))
hashed_message = keccak(message)
if not self.blockchain.interface.call_backend_verify(
eth_pubkey, signature, hashed_message):
raise PowerUpError("Signature is not valid for this message or pubkey.")
else:
return True return True
else:
raise PowerUpError("Signature is not valid for this message or pubkey.")
def __del__(self): def __del__(self):
""" """

View File

@ -907,15 +907,14 @@ class Teacher:
# Stamp # Stamp
# #
def _stamp_has_valid_wallet_signature(self): def _stamp_has_valid_wallet_signature(self) -> bool:
signature_bytes = self._evidence_of_decentralized_identity signature_bytes = self._evidence_of_decentralized_identity
if signature_bytes is NOT_SIGNED: if signature_bytes is NOT_SIGNED:
return False return False
signature_is_valid = Web3Client.verify_signature(message=bytes(self.stamp),
signature = EthSignature(signature_bytes) signature=signature_bytes,
proper_pubkey = signature.recover_public_key_from_msg(bytes(self.stamp)) account=self.checksum_public_address)
proper_address = proper_pubkey.to_checksum_address() return signature_is_valid
return proper_address == self.checksum_public_address
def stamp_is_valid(self): def stamp_is_valid(self):
""" """

View File

@ -95,7 +95,7 @@ def test_ganache_web3_client():
assert interface.is_local assert interface.is_local
def test_client_signature(): def test_EIP_191_client_signatures():
# Start a geth process # Start a geth process
geth = NuCypherGethDevProcess() geth = NuCypherGethDevProcess()