This EIP adds a new EIP-7932 algorithm of type 0x0
for supporting P256 signatures.
P256 (a.k.a secp256r1) is a widely-used NIST standardized algorithm that already has a presence within the Ethereum codebase. This makes it a great algorithm to write test cases against implementations of EIP-7932.
This EIP defines a new EIP-7932 algorithmic type with the following parameters:
| Constant | Value |
| - | - |
| ALG_TYPE
| Bytes1(0x0)
|
| GAS_PENALTY
| 500
|
| MAX_SIZE
| 128
|
N = 0xffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632551
def verify(signature_info: bytes, payload_hash: Hash32) -> Bytes:
assert(len(signature_info) == 128)
(r, s, x, y) = (signature_info[0:32], signature_info[32:64], signature_info[64:96], signature_info[96:128])
# This is similar to [EIP-2](/eips/eip-2.html)'s malleability verification.
assert(s <= N/2)
# This is defined in []()
assert(P256Verify(payload_hash, r, s, x, y))
return x.to_bytes(32, "big") + y.to_bytes(32, "big")
P256Verify
FunctionThe P256Verify
function is identical to the precompile introduced by RIP-7212. However, due to EIP linking restrictions, the verification steps defined below MUST be used instead of any definitions in RIP-7212.
“secp256r1” is a specific elliptic curve, also known as “P-256” and “prime256v1” curves. The curve is defined with the following equation and domain parameters:
# curve: short weierstrass form
y^2 ≡ x^3 + ax + b
# p: curve prime field modulus
0xffffffff00000001000000000000000000000000ffffffffffffffffffffffff
# a: elliptic curve short weierstrass first coefficient
0xffffffff00000001000000000000000000000000fffffffffffffffffffffffc
# b: elliptic curve short weierstrass second coefficient
0x5ac635d8aa3a93e7b3ebbd55769886bc651d06b0cc53b0f63bce3c3e27d2604b
# G: base point of the subgroup
(0x6b17d1f2e12c4247f8bce6e563a440f277037d812deb33a0f4a13945d898c296,
0x4fe342e2fe1a7f9b8ee7eb4a7c0f9e162bce33576b315ececbb6406837bf51f5)
# n: subgroup order (number of points)
0xffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632551
# h: cofactor of the subgroup
0x1
The signature verifying algorithm takes the signed message hash, the signature components provided by the “secp256r1” curve algorithm, and the public key derived from the signer private key. The verification can be done with the following steps:
# h (message hash)
# pubKey = (public key of the signer private key)
# Calculate the modular inverse of the signature proof:
s1 = s^(−1) (mod n)
# Recover the random point used during the signing:
R' = (h * s1) * G + (r * s1) * pubKey
# Take from R' its x-coordinate:
r' = R'.x
# Calculate the signature validation result by comparing whether:
r' == r
The following requirements MUST be checked by the precompiled contract to verify signature components are valid:
r
and s
values are in (0, n)
(exclusive) where n
is the order of the subgroup.(x, y)
is on the curve and that both x
and y
are in [0, p)
(inclusive 0, exclusive p) where p
is the prime field modulus. Note that many implementations use (0, 0)
as the reference point at infinity, which is not on the curve and should therefore be rejected.Much of this proposal is drawn from RIP-7212. Some of the test cases in RIP-7212 show that P256 is slower than secp256k1 and as such, a small penalty has been added to combat the slowdown of verification.
P256 or secp256r1, is used globally but (more importantly) has an existing implementation in all execution clients. This allows easy implementation of a known-safe algorithm, which is perfect for a test algorithm.
No backward compatibility issues found.
Needs discussion.
Copyright and related rights waived via CC0.