code wiki / (root) / nx_fec_gf256_test.nx

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}