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) |