code wiki / (root) / nx_kyber_sample_ntt_wasm.nx

nx_kyber_sample_ntt_wasm.nx

buildroot/runtime/nx_kyber_sample_ntt_wasm.nx

2658 B74 linesdepth 0pulls 0 transitivereach 0 importersview sourcekind orphan librarytopic kyber
docsdependenciesstructsconstsfunctions

about

nx_kyber_sample_ntt_wasm.nx -- FIPS 203 §4.2.1 SampleNTT (rejection sampling). Turns a SHAKE128 byte stream into a uniformly-random NTT-domain polynomial: 256 coefficients in Z_3329. The matrix A used in ML-KEM-768 K-PKE keygen / encrypt is built from 9 such polynomials (k * k = 9, k=3 for ML-KEM-768), one per (i, j) pair seeded by the (rho || j || i) byte string SHAKE128'd into bytes. Algorithm (FIPS 203 §4.2.1 Algorithm 4): Read 3 bytes at a time from the SHAKE stream. Split into two 12-bit values d1 = b0 | ((b1 & 0xf) << 8), d2 = (b1 >> 4) | (b2 << 4). If d < q, accept as next coefficient. Otherwise discard and continue. Stop when 256 coefficients have been accepted. Browser-side glue: 1. SHAKE128.absorb(rho || j_byte || i_byte) 2. SHAKE128.squeeze(buf, buf_len) -- ~600 bytes usually enough 3. nx_kyber_sample_ntt(poly_out, buf, buf_len) -> n_consumed (>=0) OR -1 if buffer too short (caller should squeeze more + retry) API: nx_kyber_sample_ntt(poly_out, buf, buf_len) -> i64 returns number of bytes consumed on success, -1 if buffer too short to reach 256 accepted coefficients. Verified: KAT against PQClean reference (a known SHAKE stream produces a known polynomial). license_tier: INDEPENDENT_REDERIVE genealogy_id: international-research-sources/nist/fips_203 lineage_id: nishi_kyber_sample_ntt_wasm_q1 safe_shift_audit: no 64-bit rotations in this module

dependencies 0 imports · 0 importers

imports: none

imported by: nobody (leaf or entry point)

structs

none

consts

34const KYBER_Q: i64 = 3329
35const KYBER_N: i64 = 256

functions

37func _pstore(p: *u8, i: i64, v: i64) -> i64
called by 1: nx_kyber_sample_ntt
48func nx_kyber_sample_ntt(poly: *u8, buf: *u8, buf_len: i64) -> i64
calls 1: _pstore