ethereum.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:
29 | """ |
---|---|
30 | Verifies a P-256 signature. |
31 | Parameters |
32 | ---------- |
33 | evm : |
34 | The current EVM frame. |
35 | """ |
36 | data = evm.message.data |
37 | |
38 | # GAS |
39 | charge_gas(evm, GAS_P256VERIFY) |
40 | |
41 | if len(data) != 160: |
42 | return |
43 | |
44 | # OPERATION |
45 | message_hash_bytes = buffer_read(data, U256(0), U256(32)) |
46 | message_hash = Hash32(message_hash_bytes) |
47 | r = U256.from_be_bytes(buffer_read(data, U256(32), U256(32))) |
48 | s = U256.from_be_bytes(buffer_read(data, U256(64), U256(32))) |
49 | public_key_x = U256.from_be_bytes( |
50 | buffer_read(data, U256(96), U256(32)) |
51 | ) # qx |
52 | public_key_y = U256.from_be_bytes( |
53 | buffer_read(data, U256(128), U256(32)) |
54 | ) # qy |
55 | |
56 | # Signature component bounds: |
57 | # Both r and s MUST satisfy 0 < r < n and 0 < s < n |
58 | if r <= U256(0) or r >= SECP256R1N: |
59 | return |
60 | if s <= U256(0) or s >= SECP256R1N: |
61 | return |
62 | |
63 | # Public key bounds: |
64 | # Both qx and qy MUST satisfy 0 ≤ qx < p and 0 ≤ qy < p |
65 | if public_key_x < U256(0) or public_key_x >= SECP256R1P: |
66 | return |
67 | if public_key_y < U256(0) or public_key_y >= SECP256R1P: |
68 | return |
69 | |
70 | # Point validity: The point (qx, qy) MUST satisfy the curve equation |
71 | # qy^2 ≡ qx^3 + a*qx + b (mod p) |
72 | if not is_on_curve_secp256r1(public_key_x, public_key_y): |
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 | try: |
80 | secp256r1_verify(r, s, public_key_x, public_key_y, message_hash) |
81 | except InvalidSignatureError: |
82 | return |
83 | |
84 | evm.output = left_pad_zero_bytes(b"\x01", 32) |