nx_crc32c_test.nx source
↩ module page · 74 lines · 2652 B
1// nx_crc32c_test.nx -- 1:1 KAT for fast table CRC-32C (nx_crc32c.nx).
2// Verifies against (a) the CANONICAL check value 0xE3069283, (b) the
3// bit-by-bit reference over an EXHAUSTIVE length sweep (the table must
4// equal the spec kernel for every input), (c) empty, (d) streaming/
5// chained, and (e) per-PDU integrity (intact accepted, 1-bit flip
6// rejected).
7//
8// expect_exit: 0
9// license_tier: ORIGINAL
10
11import "nx_crc32c.nx"
12
13// bit-by-bit reference kernel (the spec; nx_crc32_v1's documented vector).
14func crc32c_ref(bytes: *u8, n: i64) -> i64 {
15 var crc: i64 = 0xFFFFFFFF
16 var i: i64 = 0
17 while i < n {
18 crc = (crc ^ ((bytes[i] as i64) & 0xff)) & 0xFFFFFFFF
19 var k: i64 = 0
20 while k < 8 {
21 if (crc & 1) != 0 { crc = (crc >> 1) ^ 0x82F63B78 } else { crc = crc >> 1 }
22 k = k + 1
23 }
24 i = i + 1
25 }
26 return crc ^ 0xFFFFFFFF
27}
28
29func main() -> i64 {
30 let t: *i64 = crc32c_build_table()
31
32 // ---- T1: canonical check value ----
33 let msg: *u8 = "123456789" as *u8
34 if crc32c_table(t, msg, 9) != 0xE3069283 { return 1 }
35
36 // ---- T2: empty input -> 0 ----
37 if crc32c_table(t, msg, 0) != 0 { return 2 }
38
39 // ---- T3: EXHAUSTIVE differential vs the spec kernel, lengths 0..64 ----
40 let buf: *u8 = sys_mmap(128)
41 var len: i64 = 0
42 while len <= 64 {
43 var j: i64 = 0
44 while j < len { buf[j] = ((len * 7 + j * 13 + 1) & 0xff) as u8; j = j + 1 }
45 if crc32c_table(t, buf, len) != crc32c_ref(buf, len) { return 3 }
46 len = len + 1
47 }
48
49 // ---- T4: streaming/chained == one-shot ----
50 let a: *u8 = "12345" as *u8
51 let b: *u8 = "6789" as *u8
52 var st: i64 = crc32c_begin()
53 st = crc32c_update(t, st, a, 5)
54 st = crc32c_update(t, st, b, 4)
55 if crc32c_final(st) != crc32c_table(t, msg, 9) { return 4 }
56
57 // ---- T5: per-PDU integrity ----
58 let pay: *u8 = "hello-pdu" as *u8
59 let plen: i64 = 9
60 let crc: i64 = crc32c_table(t, pay, plen)
61 let pdu: *u8 = sys_mmap(64)
62 var p: i64 = 0
63 while p < plen { pdu[p] = pay[p]; p = p + 1 }
64 pdu[plen] = ((crc >> 24) & 0xff) as u8
65 pdu[plen+1] = ((crc >> 16) & 0xff) as u8
66 pdu[plen+2] = ((crc >> 8) & 0xff) as u8
67 pdu[plen+3] = (crc & 0xff) as u8
68 if crc32c_pdu_check(t, pdu, plen + 4) != 1 { return 5 } // intact -> accept
69 pdu[2] = ((pdu[2] as i64) ^ 0x40) as u8 // flip a bit
70 if crc32c_pdu_check(t, pdu, plen + 4) != 0 { return 6 } // corrupted -> reject
71
72 sys_write(1, "CRC32C KAT PASS (canonical 0xE3069283 + exhaustive differential vs spec + streaming + PDU integrity)\n", 100)
73 return 0
74}