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