ethereum.forks.osaka.vm.precompiled_contracts.p256verify

Ethereum Virtual Machine (EVM) P256VERIFY PRECOMPILED CONTRACT.

.. contents:: Table of Contents :backlinks: none :local:

Introduction.

Implementation of the P256VERIFY precompiled contract.

p256verify

Verifies a P-256 signature.

Parameters

evm : The current EVM frame.

def p256verify(evm: Evm) -> None:
31
    """
32
    Verifies a P-256 signature.
33
34
    Parameters
35
    ----------
36
    evm :
37
        The current EVM frame.
38
39
    """
40
    data = evm.message.data
41
42
    # GAS
43
    charge_gas(evm, GAS_P256VERIFY)
44
45
    if len(data) != 160:
46
        return
47
48
    # OPERATION
49
    message_hash_bytes = buffer_read(data, U256(0), U256(32))
50
    message_hash = Hash32(message_hash_bytes)
51
    r = U256.from_be_bytes(buffer_read(data, U256(32), U256(32)))
52
    s = U256.from_be_bytes(buffer_read(data, U256(64), U256(32)))
53
    public_key_x = U256.from_be_bytes(
54
        buffer_read(data, U256(96), U256(32))
55
    )  # qx
56
    public_key_y = U256.from_be_bytes(
57
        buffer_read(data, U256(128), U256(32))
58
    )  # qy
59
60
    # Signature component bounds:
61
    # Both r and s MUST satisfy 0 < r < n and 0 < s < n
62
    if r <= U256(0) or r >= SECP256R1N:
63
        return
64
    if s <= U256(0) or s >= SECP256R1N:
65
        return
66
67
    # Public key bounds:
68
    # Both qx and qy MUST satisfy 0 ≤ qx < p and 0 ≤ qy < p
69
    # U256 is unsigned, so we don't need to check for < 0
70
    if public_key_x >= SECP256R1P:
71
        return
72
    if public_key_y >= SECP256R1P:
73
        return
74
75
    # Point should not be at infinity (represented as (0, 0))
76
    if public_key_x == U256(0) and public_key_y == U256(0):
77
        return
78
79
    # Point validity: The point (qx, qy) MUST satisfy the curve equation
80
    # qy^2 ≡ qx^3 + a*qx + b (mod p)
81
    if not is_on_curve_secp256r1(public_key_x, public_key_y):
82
        return
83
84
    try:
85
        secp256r1_verify(r, s, public_key_x, public_key_y, message_hash)
86
    except InvalidSignatureError:
87
        return
88
89
    evm.output = left_pad_zero_bytes(b"\x01", 32)