secp256r1 (P-256)
zisklib functions for secp256r1 (NIST P-256) base/scalar field
arithmetic, curve membership and scalar multiplication, and ECDSA
signature verification.
Overview
secp256r1 (NIST P-256) is the short-Weierstrass curve y² = x³ − 3x + b
defined over the prime field Fp with
p = 2²⁵⁶ − 2²²⁴ + 2¹⁹² + 2⁹⁶ − 1. The group has prime order n
(cofactor 1) and is the curve used for ECDSA in TLS certificates,
WebAuthn/passkeys, and the EVM RIP-7212 precompile at address 0x100.
The page is organized bottom-up:
| Section | Provides | Depends on |
|---|---|---|
| Base field (Fp) | Arithmetic for every coordinate computation. | — |
| Scalar field (Fn) | Arithmetic for signature components and exponents. | — |
| Curve | On-curve check, scalar mul, and double-scalar mul with G. | Fp, Fn |
| ECDSA | Signature verification. | Fn, Curve |
Base field (Fp)
The prime field Fp where curve coordinates live, with
p = 2²⁵⁶ − 2²²⁴ + 2¹⁹² + 2⁹⁶ − 1. Elements are 4 little-endian u64
limbs (256 bits). The Curve section ultimately reduces to these
Fp primitives for evaluating y² = x³ − 3x + b and for the coordinate
arithmetic inside scalar multiplication.
Addition in the secp256r1 base field Fp.
pub fn add_fp_secp256r1(x: &[u64; 4], y: &[u64; 4]) -> [u64; 4]
Parameters
| Name | Type | Description |
|---|---|---|
x | &[u64; 4] | First Fp operand as 4 LE limbs. |
y | &[u64; 4] | Second Fp operand as 4 LE limbs. |
Returns
| Type | Description |
|---|---|
[u64; 4] | x + y mod p in the secp256r1 base field. |
Example
let sum = zisklib::add_fp_secp256r1(&x_limbs, &y_limbs);
Scalar field (Fn)
The prime field Fn of integers modulo the curve order n, where
exponents and signature components live. Elements are 4 little-endian
u64 limbs (256 bits). Scalar multiplications on the curve consume Fn
elements, and ECDSA verification relies on Fn arithmetic to reconstruct
u₁ = z·s⁻¹ and u₂ = r·s⁻¹ before the curve multi-scalar step.
Reduces a 256-bit integer modulo the secp256r1 curve order n.
pub fn reduce_fn_secp256r1(x: &[u64; 4]) -> [u64; 4]
Parameters
| Name | Type | Description |
|---|---|---|
x | &[u64; 4] | 256-bit integer as 4 LE limbs. |
Returns
| Type | Description |
|---|---|
[u64; 4] | x mod n in the secp256r1 scalar field. |
Example
let reduced = zisklib::reduce_fn_secp256r1(&scalar);
Curve
The group of Fp-rational points on y² = x³ − 3x + b, including the
point at infinity. Affine points are [u64; 8] (x ++ y). Point
arithmetic consumes Fp elements for coordinates and Fn elements for
scalars; the double_scalar_mul_with_g_secp256r1 primitive in this
section is the building block reused by ECDSA verification.
Returns true if the affine point p satisfies the secp256r1
curve equation y² = x³ + a·x + b.
Assumes p is not the point at infinity.
pub fn is_on_curve_secp256r1(p: &[u64; 8]) -> bool
Parameters
| Name | Type | Description |
|---|---|---|
p | &[u64; 8] | Affine point encoded as x ++ y, each 4 LE limbs. Non-infinity. |
Returns
| Type | Description |
|---|---|
bool | true if p satisfies the secp256r1 curve equation, false otherwise. |
Example
assert!(zisklib::is_on_curve_secp256r1(&point));
ECDSA
ECDSA signature verification on secp256r1 (P-256), the algorithm used
by TLS, WebAuthn and the EVM precompile at 0x100. Verification
computes u₁·G + u₂·Q via the curve's multi-scalar primitive and
compares the resulting x-coordinate against r mod n. Inputs are
limbs: the public key is an affine point, while r, s and z are
Fn-sized 4-limb values.
Verifies a secp256r1 (P-256) ECDSA signature (r, s) over message
hash z using public key pk. Validates that r, s ∈ [1, n-1],
that pk is not the identity, that both coordinates of pk lie in
[0, p-1], and that pk is on the curve.
pub fn ecdsa_verify_secp256r1(
pk: &[u64; 8],
z: &[u64; 4],
r: &[u64; 4],
s: &[u64; 4],
) -> bool
Parameters
| Name | Type | Description |
|---|---|---|
pk | &[u64; 8] | Public key as affine x ++ y, 4 LE limbs each. |
z | &[u64; 4] | Message hash as 4 LE limbs. |
r | &[u64; 4] | Signature component r as 4 LE limbs. |
s | &[u64; 4] | Signature component s as 4 LE limbs. |
Returns
| Type | Description |
|---|---|
bool | true if the signature is valid, false otherwise. |
Example
let ok = zisklib::ecdsa_verify_secp256r1(&pk, &z, &r, &s);