nx_fec_gf256_test.nx source
↩ module page · 78 lines · 2807 B
1// nx_fec_gf256_test.nx -- 1:1 KAT for Reed-Solomon GF(256) erasure coding
2// (nx_fec_gf256.nx). Proves the MDS ceiling: an RS(6,4) code recovers
3// ANY 2 erasures in ANY positions -- verified EXHAUSTIVELY over all 15
4// two-erasure patterns (data+data, data+parity, parity+parity). Plus
5// GF-field sanity and the honest over-budget (3 erasures) -> failure.
6//
7// expect_exit: 0
8// license_tier: ORIGINAL
9
10import "nx_fec_gf256.nx"
11
12const RK: i64 = 4
13const RR: i64 = 2
14const RS_: i64 = 4
15// n = 6 symbols
16
17func gft_load(recv: *u8, data: *u8, parity: *u8) -> i64 {
18 var i: i64 = 0
19 while i < RK * RS_ { recv[i] = data[i]; i = i + 1 }
20 var j: i64 = 0
21 while j < RR * RS_ { recv[RK * RS_ + j] = parity[j]; j = j + 1 }
22 return 0
23}
24func gft_zero_pkt(recv: *u8, idx: i64) -> i64 {
25 var b: i64 = 0
26 while b < RS_ { recv[idx * RS_ + b] = 0 as u8; b = b + 1 }
27 return 0
28}
29
30func main() -> i64 {
31 let exp: *i64 = sys_mmap(512 * 8) as *i64
32 let log: *i64 = sys_mmap(256 * 8) as *i64
33 gf_build(exp, log)
34
35 // ---- GF(256) field sanity ----
36 if gf_mul(exp, log, 7, 1) != 7 { return 90 } // identity
37 if gf_mul(exp, log, 7, gf_inv(exp, log, 7)) != 1 { return 91 } // inverse
38 if gf_mul(exp, log, 0, 200) != 0 { return 92 } // absorbing
39
40 let n: i64 = RK + RR
41 let data: *u8 = sys_mmap(RK * RS_)
42 var i: i64 = 0
43 while i < RK * RS_ { data[i] = ((i * 23 + 5) & 0xff) as u8; i = i + 1 }
44 let parity: *u8 = sys_mmap(RR * RS_)
45 rs_encode(exp, log, data, RK, RR, RS_, parity)
46
47 let recv: *u8 = sys_mmap(n * RS_)
48 let present: *i64 = sys_mmap(n * 8) as *i64
49 let out: *u8 = sys_mmap(RK * RS_)
50
51 // ---- EXHAUSTIVE: ANY 2 erasures (all 15 patterns) -> full recovery ----
52 var a: i64 = 0
53 while a < n {
54 var b: i64 = a + 1
55 while b < n {
56 gft_load(recv, data, parity)
57 var p: i64 = 0
58 while p < n { present[p] = 1; p = p + 1 }
59 gft_zero_pkt(recv, a); present[a] = 0
60 gft_zero_pkt(recv, b); present[b] = 0
61 if rs_decode_erasures(exp, log, recv, present, RK, RR, RS_, out) != 0 { return 1 }
62 var z: i64 = 0
63 while z < RK * RS_ { if (out[z] & 0xff) != (data[z] & 0xff) { return 2 } z = z + 1 }
64 b = b + 1
65 }
66 a = a + 1
67 }
68
69 // ---- over-budget: 3 erasures (only R=2 tolerated) -> honest -1 ----
70 gft_load(recv, data, parity)
71 var q: i64 = 0
72 while q < n { present[q] = 1; q = q + 1 }
73 present[0] = 0; present[2] = 0; present[4] = 0
74 if rs_decode_erasures(exp, log, recv, present, RK, RR, RS_, out) != (0 - 1) { return 3 }
75
76 sys_write(1, "FEC-GF256 KAT PASS (RS(6,4) MDS: ALL 15 two-erasure patterns recovered exactly; over-budget honestly fails)\n", 108)
77 return 0
78}