code wiki / _hdl_build / nx_hash_kat.nx
nx_hash_kat.nx source
↩ module page · 55 lines · 3138 B
1// nx_hash_kat.nx -- KAT for nx_hash (FNV-1a-64 + open-addressing table). HONESTY [W] weak point (reach=101,
2// 5 children, ZERO tests): the shared hash under many organs was unproven. FNV-1a KAT'd vs the CANONICAL
3// published vectors (a wrong constant/loop-order fails); table proven by put/get roundtrip, absent-key,
4// collision-probe correctness, and update-in-place. license_tier: ORIGINAL expect_exit:0
5import "nx_syscalls.nx"
6import "nx_hash.nx"
7
8func hw(s: *u8) -> i64 { var n:i64=0; while s[n]!=(0 as u8){n=n+1} sys_write(1,s,n); return 0 }
9func hx(v: i64) -> i64 { let d: *u8="0123456789abcdef" as *u8; let o: *u8=sys_mmap(20); o[0]=48 as u8; o[1]=120 as u8; var i: i64=0; while i<16 { o[2+i]=d[(v>>((15-i)*4))&15]; i=i+1 } sys_write(1,o,18); return 0 }
10
11func main() -> i64 {
12 var pass: i64 = 0
13
14 // ---- FNV-1a-64 canonical KAT vectors ----
15 // T1: "" -> the offset basis 0xCBF29CE484222325
16 let e0: *u8 = sys_mmap(4)
17 let h0: i64 = nx_hash_fnv1a_bytes(e0, 0)
18 if h0 == 0xCBF29CE484222325 { pass = pass + 1; hw("T1 fnv(\"\") PASS\n" as *u8) } else { hw("T1 FAIL got=" as *u8); hx(h0); hw("\n" as *u8) }
19
20 // T2: "a" -> 0xaf63dc4c8601ec8c
21 let sa: *u8 = sys_mmap(4); sa[0] = 0x61 as u8
22 let ha: i64 = nx_hash_fnv1a_bytes(sa, 1)
23 if ha == 0xaf63dc4c8601ec8c { pass = pass + 1; hw("T2 fnv(\"a\") PASS\n" as *u8) } else { hw("T2 FAIL got=" as *u8); hx(ha); hw("\n" as *u8) }
24
25 // T3: "foobar" -> 0x85944171f73967e8
26 let sf: *u8 = sys_mmap(8)
27 sf[0]=0x66 as u8; sf[1]=0x6f as u8; sf[2]=0x6f as u8; sf[3]=0x62 as u8; sf[4]=0x61 as u8; sf[5]=0x72 as u8
28 let hf: i64 = nx_hash_fnv1a_bytes(sf, 6)
29 if hf == 0x85944171f73967e8 { pass = pass + 1; hw("T3 fnv(\"foobar\") PASS\n" as *u8) } else { hw("T3 FAIL got=" as *u8); hx(hf); hw("\n" as *u8) }
30
31 // ---- hash table ----
32 let t: *NxHash = nx_hash_new(256) // 256 slots (cap IS the arg; must be pow2) -- holds the 200 test keys
33 // T4: put/get roundtrip over many keys (probe correctness)
34 var ok4: i64 = 1
35 var i: i64 = 1
36 while i <= 200 { nx_hash_put(t, i, i * 7 + 3); i = i + 1 }
37 i = 1
38 while i <= 200 { if nx_hash_get(t, i) != i * 7 + 3 { ok4 = 0 } i = i + 1 }
39 if ok4 == 1 { pass = pass + 1; hw("T4 table roundtrip 200 keys PASS\n" as *u8) } else { hw("T4 FAIL roundtrip\n" as *u8) }
40
41 // T5: absent key -> get=-1, has=0
42 if nx_hash_get(t, 999999) == (0 - 1) { if nx_hash_has(t, 999999) == 0 { pass = pass + 1; hw("T5 absent PASS\n" as *u8) } else { hw("T5 FAIL has\n" as *u8) } } else { hw("T5 FAIL get not -1\n" as *u8) }
43
44 // T6: update-in-place -- put existing key new val, get returns new, count unchanged
45 let n_before: i64 = t.n
46 nx_hash_put(t, 50, 424242)
47 if nx_hash_get(t, 50) == 424242 { if t.n == n_before { pass = pass + 1; hw("T6 update-in-place PASS\n" as *u8) } else { hw("T6 FAIL count changed\n" as *u8) } } else { hw("T6 FAIL update\n" as *u8) }
48
49 hw("NX-HASH-KAT " as *u8)
50 let dd: *u8 = sys_mmap(4); dd[0] = (48 + pass) as u8; sys_write(1, dd, 1)
51 hw("/6" as *u8)
52 if pass == 6 { hw(" GREEN\n" as *u8); return 0 }
53 hw(" RED\n" as *u8)
54 return 1
55}