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