code wiki / _hdl_build / nx_xxhash_kat.nx
nx_xxhash_kat.nx source
↩ module page · 61 lines · 3165 B
1// nx_xxhash_kat.nx -- KAT for nx_xxhash (XXH64). HONESTY [W] weak point (reach untested). Anchors correctness
2// to the CANONICAL reference vector XXH64("", seed=0) = 0xEF46DB3751D8E999, then proves the hash properties:
3// determinism, seed-sensitivity, input-sensitivity, length-sensitivity, and no-stuck-value over many inputs.
4// license_tier: ORIGINAL expect_exit:0
5import "nx_syscalls.nx"
6import "nx_xxhash.nx"
7
8func xw(s: *u8) -> i64 { var n:i64=0; while s[n]!=(0 as u8){n=n+1} sys_write(1,s,n); return 0 }
9func xh(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 let e: *u8 = sys_mmap(8)
14
15 // T1: canonical reference anchor -- XXH64("", seed=0) = 0xEF46DB3751D8E999
16 let h0: i64 = nx_xxh64(e, 0, 0)
17 if h0 == 0xEF46DB3751D8E999 { pass = pass + 1; xw("T1 XXH64(\"\",0) canonical PASS\n" as *u8) } else { xw("T1 FAIL got=" as *u8); xh(h0); xw("\n" as *u8) }
18
19 // build a 64-byte test buffer
20 let b: *u8 = sys_mmap(80)
21 var i: i64 = 0
22 while i < 64 { b[i] = (i * 7 + 11) as u8; i = i + 1 }
23
24 // T2: determinism -- same buf+seed -> same hash
25 if nx_xxh64(b, 64, 0) == nx_xxh64(b, 64, 0) { pass = pass + 1; xw("T2 determinism PASS\n" as *u8) } else { xw("T2 FAIL\n" as *u8) }
26
27 // T3: seed sensitivity
28 if nx_xxh64(b, 64, 0) != nx_xxh64(b, 64, 1) { pass = pass + 1; xw("T3 seed-sensitivity PASS\n" as *u8) } else { xw("T3 FAIL\n" as *u8) }
29
30 // T4: input sensitivity -- flip one bit -> different hash
31 let h_a: i64 = nx_xxh64(b, 64, 0)
32 b[30] = (b[30] ^ 1) as u8
33 let h_b: i64 = nx_xxh64(b, 64, 0)
34 b[30] = (b[30] ^ 1) as u8
35 if h_a != h_b { pass = pass + 1; xw("T4 input-sensitivity PASS\n" as *u8) } else { xw("T4 FAIL\n" as *u8) }
36
37 // T5: length sensitivity -- 63 vs 64 bytes differ
38 if nx_xxh64(b, 63, 0) != nx_xxh64(b, 64, 0) { pass = pass + 1; xw("T5 length-sensitivity PASS\n" as *u8) } else { xw("T5 FAIL\n" as *u8) }
39
40 // T6: no stuck value -- 256 single-byte inputs produce >=250 distinct hashes (crude collision check)
41 let seen: *i64 = sys_mmap(300*8) as *i64
42 var sn: i64 = 0
43 var c: i64 = 0
44 while c < 256 {
45 e[0] = c as u8
46 let hh: i64 = nx_xxh64(e, 1, 0)
47 var dup: i64 = 0
48 var k: i64 = 0
49 while k < sn { if seen[k] == hh { dup = 1; k = sn } else { k = k + 1 } }
50 if dup == 0 { seen[sn] = hh; sn = sn + 1 }
51 c = c + 1
52 }
53 if sn >= 250 { pass = pass + 1; xw("T6 distinct=" as *u8); let dd: *u8=sys_mmap(8); var q: i64=sn; var kk: i64=0; let tt: *u8=sys_mmap(8); if q==0{tt[0]=48 as u8;kk=1} while q>0{tt[kk]=(48+(q%10)) as u8;q=q/10;kk=kk+1} var j: i64=0; while j<kk{dd[j]=tt[kk-1-j];j=j+1} sys_write(1,dd,kk); xw("/256 PASS\n" as *u8) } else { xw("T6 FAIL too many collisions\n" as *u8) }
54
55 xw("NX-XXHASH-KAT " as *u8)
56 let d1: *u8 = sys_mmap(4); d1[0] = (48 + pass) as u8; sys_write(1, d1, 1)
57 xw("/6" as *u8)
58 if pass == 6 { xw(" GREEN\n" as *u8); return 0 }
59 xw(" RED\n" as *u8)
60 return 1
61}