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}