code wiki / (root) / nx_p256_field.nx

nx_p256_field.nx

buildroot/runtime/nx_p256_field.nx

5644 B165 linesdepth 3pulls 3 transitivereach 759 importersview sourcekind tooltopic p256
docsdependenciesstructsconstsfunctions

about

nx_p256_field.nx -- NIST P-256 prime field arithmetic. Phase 0b §I.3 piece 1 of the ECDSA-P256 arc. Composes the nx_u256 big-int primitives (commit 6ff89dd8) with the P-256 prime p = 2^256 - 2^224 + 2^192 + 2^96 - 1 = FFFFFFFF 00000001 00000000 00000000 00000000 FFFFFFFF FFFFFFFF FFFFFFFF (big-endian) into modular add / subtract / negate primitives operating on F_p elements in canonical form (each element in [0, p)). Public API: p256_field_load_p(out) -- write the prime into a buffer p256_field_zero(out) / p256_field_one(out) p256_field_copy(out, src) p256_field_eq(a, b) -> 0|1 p256_field_add(r, a, b) -- r = (a + b) mod p p256_field_sub(r, a, b) -- r = (a - b) mod p p256_field_neg(r, a) -- r = (-a) mod p nx_p256_field_verdict_is_valid(v) Preconditions: callers MUST pass operands already reduced to canonical form [0, p). All outputs are guaranteed canonical. What this primitive does NOT do (queued for §1b): - Multiplication (schoolbook 8x8 = 16 limbs, then Solinas reduction using p's special form). - Squaring (mul fast path). - Modular inverse (Fermat: a^(p-2) mod p, ~256 squarings + ~30 muls). - These are bigger arcs; add/sub/neg ship first because every point operation uses them and they're well-defined alone. Algorithm references: - FIPS 186-5 §D.2.4 (P-256 prime + base point + group order) - SEC 1 v2.0 §2.2.1 (Weierstrass curve over F_p form) - HAC §14.2.1 (modular add/subtract conditional steps) - BoringSSL p256.c (modern u32-limb reference for layout)

dependencies 2 imports · 26 importers

nx_syscalls.nx nx_u256.nx nx_p256_field.nx nx_ecdsa_p256.nx nx_ecdsa_p256_test.nx nx_h2c_p256.nx nx_opaque_core.nx nx_p256_comb.nx nx_p256_ecdh.nx nx_p256_field_inv.nx nx_p256_field_inv_test.nx nx_p256_field_mul.nx nx_p256_field_mul_oracle_test.nx

diagram shows first 10 each side; +0 more imports, +16 more importers in the complete lists below.

imports: nx_syscalls.nxnx_u256.nx

imported by: nx_ecdsa_p256.nxnx_ecdsa_p256_test.nxnx_h2c_p256.nxnx_opaque_core.nxnx_p256_comb.nxnx_p256_ecdh.nxnx_p256_field_inv.nxnx_p256_field_inv_test.nxnx_p256_field_mul.nxnx_p256_field_mul_oracle_test.nxnx_p256_field_mul_test.nxnx_p256_field_test.nxnx_p256_fieldmul_bench.nxnx_p256_keyshare_test.nxnx_p256_point.nxnx_p256_point_add.nxnx_p256_point_add_test.nxnx_p256_point_test.nxnx_p256_pointloop_bench.nxnx_p256_scalar_mul.nxnx_p256_scalar_mul_test.nxnx_p256_scalar_mul_wnaf.nxnx_p256_solinas_difftest.nxnx_p256_solinas_timing.nxnx_p256_verify_timing.nxnx_voprf.nx

structs

none

consts

59const NX_P256_FIELD_OK: i64 = 1
60const NX_P256_FIELD_BAD: i64 = 2
61const NX_P256_FIELD_VERDICT_N: i64 = 3

functions

63func nx_p256_field_verdict_is_valid(v: i64) -> i64
called by 1: main
82func p256_field_load_p(out: *i64) -> i64
95func p256_field_zero(out: *i64) -> i64 { return u256_zero(out) }
96func p256_field_one(out: *i64) -> i64 { return u256_one(out) }
97func p256_field_copy(out: *i64, src: *i64) -> i64 { return u256_copy(out, src) }
calls 1: u256_copy
98func p256_field_eq(a: *i64, b: *i64) -> i64 { return u256_eq(a, b) }
108func p256_field_add(r: *i64, a: *i64, b: *i64) -> i64
133func p256_field_sub(r: *i64, a: *i64, b: *i64) -> i64
149func p256_field_neg(r: *i64, a: *i64) -> i64
163func main() -> i64