code wiki / _hdl_build / nx_rand_gate.nx
nx_rand_gate.nx source
↩ module page · 65 lines · 3202 B
1// nx_rand_gate.nx -- GATE for nx_rand (the /dev/urandom CSPRNG wrapper). Flagged by the HONESTY SYSTEM
2// 2026-07-16 as the #2 untested load-bearer: reach=587 organs (session tokens, CSRF, nonces) with ZERO
3// direct validation. A CSPRNG wrapper cannot be KAT'd (nondeterministic BY CONTRACT) -- so the gate proves
4// the CONTRACT: fills exactly n, never all-zeros, consecutive draws differ, bounded draws stay in bounds,
5// fd-caching survives repeated use. license_tier: ORIGINAL expect_exit:0
6import "nx_syscalls.nx"
7import "nx_rand.nx"
8import "nx_gate_verdict.nx"
9
10func gw(s: *u8) -> i64 { var n:i64=0; while s[n]!=(0 as u8){n=n+1} sys_write(1,s,n); return 0 }
11func gn(v: i64) -> i64 { let b:*u8=sys_mmap(24); var m:i64=v; if m<0{sys_write(1,"-" as *u8,1);m=0-m} let t:*u8=sys_mmap(24); var k:i64=0; if m==0{t[0]=48 as u8;k=1} while m>0{t[k]=(48+(m%10)) as u8;m=m/10;k=k+1} var j:i64=0; while j<k{b[j]=t[k-1-j];j=j+1} sys_write(1,b,k); return 0 }
12
13func main() -> i64 {
14 var pass: i64 = 0
15 let a: *u8 = sys_mmap(8192)
16 let b: *u8 = sys_mmap(8192)
17
18 // T1: rand_bytes fills exactly n
19 let r1: i64 = rand_bytes(a, 64)
20 if r1 == 64 { pass = pass + 1; gw("T1 fill-64 PASS\n" as *u8) } else { gw("T1 FAIL got=" as *u8); gn(r1); gw("\n" as *u8) }
21
22 // T2: not all zeros (2^-512 by contract)
23 var nz: i64 = 0
24 var i: i64 = 0
25 while i < 64 { if a[i] != (0 as u8) { nz = 1 } i = i + 1 }
26 if nz == 1 { pass = pass + 1; gw("T2 nonzero PASS\n" as *u8) } else { gw("T2 FAIL all-zero draw\n" as *u8) }
27
28 // T3: consecutive 64-byte draws differ
29 rand_bytes(b, 64)
30 var diff: i64 = 0
31 i = 0
32 while i < 64 { if a[i] != b[i] { diff = 1 } i = i + 1 }
33 if diff == 1 { pass = pass + 1; gw("T3 draws-differ PASS\n" as *u8) } else { gw("T3 FAIL identical draws\n" as *u8) }
34
35 // T4: rand_u64 twice differ
36 let u1: i64 = rand_u64()
37 let u2: i64 = rand_u64()
38 if u1 != u2 { pass = pass + 1; gw("T4 u64-differ PASS\n" as *u8) } else { gw("T4 FAIL u64 repeat\n" as *u8) }
39
40 // T5: rand_below(10) stays in [0,10) over 200 draws
41 var ok5: i64 = 1
42 i = 0
43 while i < 200 {
44 let v: i64 = rand_below(10)
45 if v < 0 { ok5 = 0 }
46 if v >= 10 { ok5 = 0 }
47 i = i + 1
48 }
49 if ok5 == 1 { pass = pass + 1; gw("T5 bounded PASS\n" as *u8) } else { gw("T5 FAIL out-of-bounds\n" as *u8) }
50
51 // T6: big fill (4096) exact + fd cache survives all prior calls
52 let r6: i64 = rand_bytes(a, 4096)
53 if r6 == 4096 { pass = pass + 1; gw("T6 fill-4096 PASS\n" as *u8) } else { gw("T6 FAIL got=" as *u8); gn(r6); gw("\n" as *u8) }
54
55 gw("NX-RAND GATE " as *u8); gn(pass); gw("/6" as *u8)
56 // MIGRATED onto nx_gate_verdict by nx_gate_dry_apply (D001, minimal form): every check
57 // row above is untouched, so the PASS/FAIL vector cannot change; only the hand-rolled
58 // verdict emission is replaced by the ONE shared base class. Proven by nx_gate_migrate verify.
59 let ctr__dry: *i64 = gv_ctr()
60 ctr__dry[0] = pass
61 ctr__dry[1] = 6
62 let rc__dry: i64 = gv_verdict("RAND-GATE" as *u8, ctr__dry, "teeth unchanged; verdict emission migrated onto the shared base class" as *u8)
63 sys_exit(rc__dry)
64 return rc__dry
65}