code wiki / hub / nx_voprf.nx

nx_voprf.nx

buildroot/runtime/hub/nx_voprf.nx

14069 B348 linesdepth 9pulls 18 transitivereach 96 importersview sourcekind librarytopic voprf
docsdependenciesstructsconstsfunctions

about

nx_voprf.nx -- RFC 9497 OPRF(P-256, SHA-256) Mode Base. "Verifiable" in the file name is aspirational: this V1 ships ONLY the Base mode of the OPRF protocol per RFC 9497 §3. The Verifiable mode (VOPRF) and Partially-Oblivious mode (POPRF) add DLEQ proof generation + verification (~300 more lines). OPAQUE PAKE (V-MODAUTH-2) requires ONLY Base mode per IETF draft-irtf-cfrg-opaque-13 §6.1, so V1 scope ends here. OPRF = Oblivious Pseudorandom Function. Two parties: Server: holds a long-term scalar skS in [1, n-1]. Client: has an input string x. At protocol end, client learns y = F(skS, x) where F is a pseudorandom function, and: - Server NEVER sees x (only a blinded curve point). - Client NEVER sees skS. - Both confirm y matches without sending it on the wire. OPAQUE uses OPRF to derive a per-password key (from password + server's OPRF key) that the client uses to encrypt their long-term secret. The result: even if the server is compromised, an attacker cannot mount offline crack on the password (they don't have the OPRF key and the protocol requires interaction to evaluate). COMPOSES (per "avoid duplicate primitives" cardinal): hub/nx_h2c_p256 hash_to_curve_p256 + hash_to_field nx_p256_scalar_mul scalar * P256Point nx_p256_modn scalar arithmetic mod n (group order) nx_p256_point P256Point + load_g + to_affine + sgn0 nx_u256 8-limb LE u256 byte conversion nx_csprng random scalar source sha256 Finalize() hash + part of DST COMPOSED BY: hub/nx_opaque_pake.nx V-MODAUTH-2 (uses Blind/Eval/Finalize) bench/nx_voprf_smoke.sh RFC 9497 §A.1.1 test vectors (queued) SPEC REFERENCES: RFC 9497 §3 Base mode protocol (Blind / BlindEvaluate / Finalize) RFC 9497 §3.2 contextString construction

dependencies 11 imports · 4 importers

nx_syscalls.nx nx_u256.nx nx_p256_field.nx nx_p256_field_inv.nx nx_p256_modn.nx nx_p256_point.nx nx_p256_point_add.nx nx_p256_scalar_mul.nx nx_csprng.nx sha256.nx nx_voprf.nx nx_opaque_core.nx nx_opaque_pake.nx nx_voprf_finalize.nx nx_voprf_rfc_kat.nx

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

imports: nx_syscalls.nxnx_u256.nxnx_p256_field.nxnx_p256_field_inv.nxnx_p256_modn.nxnx_p256_point.nxnx_p256_point_add.nxnx_p256_scalar_mul.nxnx_csprng.nxsha256.nxnx_h2c_p256.nx

imported by: nx_opaque_core.nxnx_opaque_pake.nxnx_voprf_finalize.nxnx_voprf_rfc_kat.nx

structs

none

consts

72const NX_VOPRF_OK: i64 = 0
73const NX_VOPRF_BAD_INPUT: i64 = 1320
74const NX_VOPRF_BUF_OVERFLOW: i64 = 1321
75const NX_VOPRF_CSPRNG_FAILED: i64 = 1322
76const NX_VOPRF_H2C_FAILED: i64 = 1323
77const NX_VOPRF_INVALID_ELEMENT: i64 = 1324
78const NX_VOPRF_INVALID_SCALAR: i64 = 1325
79const NX_VOPRF_DESERIALIZE_FAILED: i64 = 1326
82const NX_VOPRF_SCALAR_BYTES: i64 = 32 // P-256 scalar = 32 bytes (256 bits)
83const NX_VOPRF_ELEMENT_BYTES: i64 = 33 // compressed P-256 point: 1-byte prefix + 32-byte X
84const NX_VOPRF_FINALIZE_OUT_BYTES: i64 = 32 // SHA-256 output
85const NX_VOPRF_MAX_INPUT_LEN: i64 = 4096 // sanity cap; OPAQUE passes passphrase (typ < 256B)
86const NX_VOPRF_RANDOM_RETRY_MAX: i64 = 16 // rejection sampling cap
89const NX_VOPRF_COMPRESS_EVEN: i64 = 0x02 // Y is even
90const NX_VOPRF_COMPRESS_ODD: i64 = 0x03 // Y is odd
109const NX_VOPRF_CONTEXT_STR_LEN: i64 = 20
142const NX_VOPRF_DST_H2C_LEN: i64 = 32

functions

111func _voprf_load_context_string(out: *u8) -> i64
144func _voprf_load_dst_h2c(out: *u8) -> i64
161func nx_voprf_serialize_element(point: *P256Point, out_33: *u8) -> i64
175func nx_voprf_deserialize_element(bytes_33: *u8, out_point: *P256Point) -> i64
234func nx_voprf_random_scalar(out_32: *u8) -> i64
269func nx_voprf_blind(
321func nx_voprf_blind_evaluate(