def 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, title="ECRecover: R") validate_lt_secpk1n(s, title="ECRecover: S") validate_lte(v, 28, title="ECRecover: V") validate_gte(v, 27, title="ECRecover: V") except ValidationError: return computation canonical_v = v - 27 try: signature = keys.Signature(vrs=(canonical_v, r, s)) public_key = signature.recover_public_key_from_msg_hash(message_hash) except BadSignature: return computation address = public_key.to_canonical_address() padded_address = pad32(address) computation.output = padded_address return computation
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 validate(self): super().validate() # includes validation of `(int_)gas_price` validate_canonical_address(self.destination, "Transaction.destination") validate_uint256(self.value, "Transaction.value") validate_uint256(self.min_block, "Transaction.min_block") validate_uint256(self.max_block, "Transaction.max_block") validate_uint256(self.nonce, "Transaction.nonce") validate_is_bytes(self.msg_data, "Transaction.msg_data") validate_uint256(self.v, title="Transaction.v") validate_uint256(self.r, title="Transaction.r") validate_uint256(self.s, title="Transaction.s") validate_lt_secpk1n(self.r, title="Transaction.r") validate_gte(self.r, minimum=1, title="Transaction.r") validate_lt_secpk1n(self.s, title="Transaction.s") validate_gte(self.s, minimum=1, title="Transaction.s") validate_gte(self.v, minimum=27, title="Transaction.v") validate_lte(self.v, maximum=28, title="Transaction.v")
def validate(self): validate_uint256(self.nonce, title="Transaction.nonce") validate_uint256(self.gas_price, title="Transaction.gas_price") validate_uint256(self.gas, title="Transaction.gas") if self.to != CREATE_CONTRACT_ADDRESS: validate_canonical_address(self.to, title="Transaction.to") validate_uint256(self.value, title="Transaction.value") validate_is_bytes(self.data, title="Transaction.data") validate_uint256(self.v, title="Transaction.v") validate_uint256(self.r, title="Transaction.r") validate_uint256(self.s, title="Transaction.s") validate_lt_secpk1n(self.r, title="Transaction.r") validate_gte(self.r, minimum=1, title="Transaction.r") validate_lt_secpk1n(self.s, title="Transaction.s") validate_gte(self.s, minimum=1, title="Transaction.s") validate_gte(self.v, minimum=self.v_min, title="Transaction.v") validate_lte(self.v, maximum=self.v_max, title="Transaction.v") super(FrontierTransaction, self).validate()
def validate(self): validate_uint256(self.nonce, title="Transaction.nonce") validate_uint256(self.gas_price, title="Transaction.gas_price") validate_uint256(self.gas, title="Transaction.gas") if self.to != CREATE_CONTRACT_ADDRESS: validate_canonical_address(self.to, title="Transaction.to") validate_uint256(self.value, title="Transaction.value") validate_is_bytes(self.data, title="Transaction.data") validate_uint256(self.v, title="Transaction.v") validate_uint256(self.r, title="Transaction.r") validate_uint256(self.s, title="Transaction.s") validate_lt_secpk1n(self.r, title="Transaction.r") validate_gte(self.r, minimum=1, title="Transaction.r") validate_lt_secpk1n(self.s, title="Transaction.s") validate_gte(self.s, minimum=1, title="Transaction.s") validate_gte(self.v, minimum=27, title="Transaction.v") validate_lte(self.v, maximum=28, title="Transaction.v") super(FrontierTransaction, self).validate()
def validate(self): validate_uint256(self.nonce) validate_uint256(self.gas_price) validate_uint256(self.gas) if self.to != CREATE_CONTRACT_ADDRESS: validate_canonical_address(self.to) validate_uint256(self.value) validate_is_bytes(self.data) validate_uint256(self.v) validate_uint256(self.r) validate_uint256(self.s) validate_lt_secpk1n(self.r) validate_gte(self.r, minimum=1) validate_lt_secpk1n(self.s) validate_gte(self.s, minimum=1) validate_gte(self.v, minimum=27) validate_lte(self.v, maximum=28) super(FrontierTransaction, self).validate()
def test_validate_lt_secpk1n(value, is_valid): if is_valid: validate_lt_secpk1n(value) else: with pytest.raises(ValidationError): validate_lt_secpk1n(value)
def validate(self): super(HomesteadTransaction, self).validate() validate_lt_secpk1n(self.s * 2)