def precompile_ecrecover(computation): computation.gas_meter.consume_gas(constants.GAS_ECRECOVER, reason="ECRecover Precompile") raw_message_hash = computation.msg.data[:32] message_hash = pad32r(raw_message_hash) v_bytes = pad32r(computation.msg.data[32:64]) v = big_endian_to_int(v_bytes) r_bytes = pad32r(computation.msg.data[64:96]) r = big_endian_to_int(r_bytes) s_bytes = pad32r(computation.msg.data[96:128]) s = big_endian_to_int(s_bytes) try: validate_lt_secpk1n(r) validate_lt_secpk1n(s) validate_lte(v, 28) validate_gte(v, 27) except ValidationError: return computation try: raw_public_key = ecdsa_raw_recover(message_hash, (v, r, s)) except ValueError: return computation public_key = encode_raw_public_key(raw_public_key) address = public_key_to_address(public_key) padded_address = pad32(address) computation.output = padded_address return computation
def ecdsa_raw_verify(self, msg_hash, vrs, raw_public_key): v, r, s = vrs signature = encode_signature(v, r, s)[1:] + NULL_BYTE signature = self.__recoverable_to_normal(signature) public_key = encode_raw_public_key(raw_public_key) return self.keys.PublicKey(public_key).verify(signature, msg_hash, hasher=None)
def extract_transaction_sender(transaction): vrs = (transaction.v, transaction.r, transaction.s) unsigned_transaction = transaction.as_unsigned_transaction() raw_public_key = get_ecc_backend().ecdsa_raw_recover( keccak(rlp.encode(unsigned_transaction)), vrs, ) public_key = encode_raw_public_key(raw_public_key) sender = public_key_to_address(public_key) return sender
def test_raw_recover(): raw_public_key = ecdsa_raw_recover(MSG_HASH, (V, R, S)) recovered_public_key = encode_raw_public_key(raw_public_key) assert recovered_public_key == PUBLIC_KEY
PUBLIC_KEY = ( b'\x04:QAvFo\xa8\x15\xedH\x1f\xfa\xd0\x91\x10\xa2\xd3D\xf6\xc9\xb7\x8c\x1d\x14\xaf\xc3Q\xc3\xa5\x1b\xe3=\x80r\xe7y9\xdc\x03\xbaDy\x07y\xb7\xa1\x02\x5b\xaf0\x03\xf6s$0\xe2\x0c\xd9\xb7m\x953\x91\xb3' # noqa: E501 ) RAW_PUBLIC_KEY = decode_public_key(PUBLIC_KEY) ADDRESS = (b'\xa9OSt\xfc\xe5\xed\xbc\x8e*\x86\x97\xc1S1g~n\xbf\x0b') MSG = b'my message' MSG_HASH = b'#tpO\xbbmDaqK\xcb\xab\xebj\x16\x0c"E\x9ex\x1b\x08\\\x83lI\x08JG\x0e\xd6\xa4' V = 27 R = 54060028713369731575288880898058519584012347418583874062392262086259746767623 S = 41474707565615897636207177895621376369577110960831782659442889110043833138559 assert keccak(MSG) == MSG_HASH assert encode_raw_public_key(decode_public_key(PUBLIC_KEY)) == PUBLIC_KEY def test_raw_signing(): v, r, s = ecdsa_raw_sign(MSG_HASH, PRIVATE_KEY) assert ecdsa_raw_verify(MSG_HASH, (v, r, s), RAW_PUBLIC_KEY) def test_raw_recover(): raw_public_key = ecdsa_raw_recover(MSG_HASH, (V, R, S)) recovered_public_key = encode_raw_public_key(raw_public_key) assert recovered_public_key == PUBLIC_KEY def test_raw_verify(): assert ecdsa_raw_verify(MSG_HASH, (V, R, S), RAW_PUBLIC_KEY)
def test_ecdsa_raw_recover(backend, label, d): raw_public_key = backend.ecdsa_raw_recover(MSGHASH, d['raw_sig']) assert encode_raw_public_key(raw_public_key) == d['pubkey']
def test_encode_decode_raw_public_key(label, d): assert encode_raw_public_key(decode_public_key(d['pubkey'])) == d['pubkey']