nx_mlkem_verify.nx source
↩ module page · 34 lines · 1804 B
1// nx_mlkem_verify.nx -- native harness that PROVES the real ML-KEM-768 (nx_ml_kem_768_wasm.nx)
2// works: keygen -> encaps -> decaps and assert the encaps/decaps shared secrets MATCH (its built-in
3// round-trip KAT returns 0 on success, a non-zero failure bitmap otherwise). This is the anti-liar
4// check: the sibling ml_kem_768.nx is a STUB (encaps/decaps just zero + return PENDING); the wasm
5// variant is the genuine implementation. license_tier: ORIGINAL
6import "nx_syscalls.nx"
7import "nx_itoa_lib.nx" // shared MSB-first emitter (zero-alloc)
8import "nx_ml_kem_768_wasm.nx"
9const K_MAGIC_131072: i64 = 131072
10
11func mv_puts(s: *u8) -> i64 { var n: i64 = 0; while s[n] != (0 as u8) { n = n + 1 } sys_write(1, s, n); return 0 }
12// MIGRATED to the shared emitter (debt 1785563586). The old body mmapped a scratch buffer
13// per call and never freed it. At PAGE granularity that is 4096B leaked PER CALL -- the
14// defect that took 28.5GB of a 36GB host in nx_ts_lumadiff (2MB input, ~3.66M calls).
15// nxi_* is MSB-first, allocates NOTHING, and emits identical bytes including the sign.
16func mv_putn(v: i64) -> i64 { nxi_out(v); return 0 }
17
18func main() -> i64 {
19 let seed: *u8 = sys_mmap(64)
20 let msg: *u8 = sys_mmap(32)
21 let scratch: *u8 = sys_mmap(K_MAGIC_131072) // 128 KB, >= the documented >=32 KB
22 var i: i64 = 0
23 while i < 64 { seed[i] = (i + 1) as u8; i = i + 1 }
24 i = 0
25 while i < 32 { msg[i] = ((i * 7) + 3) as u8; i = i + 1 }
26
27 let r: i64 = nx_mlkem_round_trip_test(seed, msg, scratch)
28 if r != 0 {
29 mv_puts("ML-KEM-768 round-trip FAIL failure_bitmap=" as *u8); mv_putn(r); mv_puts("\n" as *u8)
30 return 1
31 }
32 mv_puts("ML-KEM-768 round-trip PASS (real keygen/encaps/decaps, FO transform, shared secrets MATCH)\n" as *u8)
33 return 0
34}