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