Skip to content

Commit c346176

Browse files
committed
Tests: Update rsecbinary tests to the caller-prepared tables convention
The helper now takes reversed log-domain generator coefficients with -1 denoting a zero coefficient, plus caller-supplied log and two-period anti-log tables, in place of the previous rsprod procedure. Extend coverage to the zero-feedback shift branch and the zero-coefficient sentinel branch.
1 parent 214e8ee commit c346176

1 file changed

Lines changed: 67 additions & 32 deletions

File tree

tests/ps_tests/rsecbinary.ps.test

Lines changed: 67 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -8,96 +8,131 @@
88

99
%
1010
% Standalone tests for the rsecbinary helper (streaming RSEC over GF(2^n)).
11-
% Uses a self-contained GF(8) rsprod so the tests don't depend on any encoder.
11+
% Uses self-contained GF(8) tables so the tests don't depend on any encoder.
1212
% GF(8) with primitive polynomial x^3 + x + 1, alpha = 2.
1313
%
14+
% Calling convention:
15+
%
16+
% {getdata} nd logcoeffsrev lfsr rslog rsalog //rsecbinary exec
17+
%
18+
% where logcoeffsrev holds the generator coefficients reversed and in the
19+
% log domain with -1 denoting a zero coefficient, and rsalog spans two
20+
% periods of the multiplicative group so that log-sums resolve without a
21+
% modulo reduction.
22+
%
1423

1524
/rsecbinary dup /uk.co.terryburton.bwipp findresource cvx def
1625

1726
% log table: gf8_log[x] = i such that alpha^i = x (log[0] unused; set 0 for safety)
18-
/gf8_log [0 0 1 3 2 6 4 5] def
19-
% alog table: gf8_alog[i] = alpha^i, cycles every 7
20-
/gf8_alog [1 2 4 3 6 7 5] def
21-
22-
/gf8_rsprod {
23-
dup 0 ne { 1 index 0 ne {
24-
gf8_log exch get exch gf8_log exch get add 7 mod gf8_alog exch get
25-
} { pop pop 0 } ifelse } { pop pop 0 } ifelse
26-
} bind def
27+
/gf8_log [0 0 1 3 2 6 4 5] def
28+
% anti-log table spanning two periods: gf8_alog2[i] = alpha^(i mod 7)
29+
/gf8_alog2 [1 2 4 3 6 7 5 1 2 4 3 6 7] def
2730

2831
%
29-
% Test 1: Minimal case. nc=2, nd=1, data=[3], coeffs=[2, 3].
32+
% Test 1: Minimal case. nc=2, nd=1, data=[3].
33+
% Generator coefficients 3 and 2 (logs 3 and 1): logcoeffsrev=[3 1].
3034
% Hand-computed expected ECC = [5, 6]:
3135
% lfsr = [0, 0]
32-
% m=0: fb = 3 XOR 0 = 3
33-
% j=0: lfsr[0] = lfsr[1] XOR (coeffs[1] * fb) = 0 XOR (3*3) = alpha^6 = 5
34-
% lfsr[1] = coeffs[0] * fb = 2*3 = alpha^4 = 6
36+
% m=0: fb = 3 XOR 0 = 3, log(fb) = 3
37+
% j=0: lfsr[0] = lfsr[1] XOR alog[3+3] = 0 XOR alpha^6 = 5
38+
% lfsr[1] = alog[3+1] = alpha^4 = 6
3539
%
3640
/rsdata [3] def
3741
/lfsr 2 array def
38-
{ rsdata exch get } 1 [2 3] 2 lfsr /gf8_rsprod load //rsecbinary exec
42+
{ rsdata exch get } 1 [3 1] lfsr gf8_log gf8_alog2 //rsecbinary exec
3943
lfsr 0 2 getinterval
4044
[5 6] debugIsEqual
4145

4246
%
4347
% Test 2: Two-codeword input. nc=2, nd=2, data=[3, 1].
4448
% After m=0 (as Test 1): lfsr = [5, 6]
45-
% m=1: fb = 1 XOR 5 = 4
46-
% j=0: lfsr[0] = lfsr[1] XOR (3*4) = 6 XOR (alpha^3*alpha^2) = 6 XOR alpha^5 = 6 XOR 7 = 1
47-
% lfsr[1] = 2*4 = alpha*alpha^2 = alpha^3 = 3
49+
% m=1: fb = 1 XOR 5 = 4, log(fb) = 2
50+
% j=0: lfsr[0] = lfsr[1] XOR alog[2+3] = 6 XOR alpha^5 = 6 XOR 7 = 1
51+
% lfsr[1] = alog[2+1] = alpha^3 = 3
4852
% Expected ECC = [1, 3]
4953
%
5054
/rsdata [3 1] def
51-
{ rsdata exch get } 2 [2 3] 2 lfsr /gf8_rsprod load //rsecbinary exec
55+
{ rsdata exch get } 2 [3 1] lfsr gf8_log gf8_alog2 //rsecbinary exec
5256
lfsr 0 2 getinterval
5357
[1 3] debugIsEqual
5458

5559
%
56-
% Test 3: nc=1 boundary. data=[5], coeffs=[7]. nd=1.
60+
% Test 3: nc=1 boundary. data=[5], coefficient 7 (log 5). nd=1.
5761
% lfsr = [0]
58-
% m=0: fb = 5 XOR 0 = 5
62+
% m=0: fb = 5 XOR 0 = 5, log(fb) = 6
5963
% inner j loop has nc-2 = -1 range -> no iterations
60-
% lfsr[0] = coeffs[0] * fb = 7*5 = alpha^5*alpha^6 = alpha^11 = alpha^4 = 6
64+
% lfsr[0] = alog[6+5] = alog[11] = alpha^4 = 6
6165
% Expected ECC = [6]
6266
%
6367
/rsdata [5] def
6468
/lfsr 1 array def
65-
{ rsdata exch get } 1 [7] 1 lfsr /gf8_rsprod load //rsecbinary exec
69+
{ rsdata exch get } 1 [5] lfsr gf8_log gf8_alog2 //rsecbinary exec
6670
lfsr 0 1 getinterval
6771
[6] debugIsEqual
6872

6973
%
7074
% Test 4: nd=0 boundary. Empty data -> ECC stays all zero.
7175
%
7276
/lfsr 3 array def
73-
{ rsdata exch get } 0 [1 2 3] 3 lfsr /gf8_rsprod load //rsecbinary exec
77+
{ rsdata exch get } 0 [3 1 0] lfsr gf8_log gf8_alog2 //rsecbinary exec
7478
lfsr 0 3 getinterval
7579
[0 0 0] debugIsEqual
7680

7781
%
7882
% Test 5: Reuse of lfsr across calls. Same buffer, two calls with different
79-
% nc/coeffs. Validates the helper zero-fills on entry (no state leak).
83+
% nc/coefficients. Validates the helper zero-fills on entry (no state leak).
8084
%
8185
/lfsr 4 array def % sized for the larger call
8286
/rsdata [2] def
83-
% First: nc=2
84-
{ rsdata exch get } 1 [2 3] 2 lfsr /gf8_rsprod load //rsecbinary exec
87+
% First: nc=2, logcoeffsrev=[3 1]
88+
{ rsdata exch get } 1 [3 1] lfsr gf8_log gf8_alog2 //rsecbinary exec
8589
lfsr 0 2 getinterval
8690
[6 4] debugIsEqual
8791
% Second: nc=3 using same lfsr. First 3 cells overwritten; cell 3 stale
8892
% but irrelevant because caller reads only the first nc cells.
89-
{ rsdata exch get } 1 [1 2 3] 3 lfsr /gf8_rsprod load //rsecbinary exec
90-
% Hand-compute: fb=2, j=0: S[0] = S[1] ^ (3*2) = 0 ^ alpha^4 = 6
91-
% j=1: S[1] = S[2] ^ (2*2) = 0 ^ alpha^2 = 4
92-
% S[2] = 1*2 = alpha^1 = 2
93+
% Coefficients 3, 2 and 1 (logs 3, 1 and 0): logcoeffsrev=[3 1 0]
94+
{ rsdata exch get } 1 [3 1 0] lfsr gf8_log gf8_alog2 //rsecbinary exec
95+
% Hand-compute: fb=2, log(fb)=1
96+
% j=0: S[0] = S[1] XOR alog[1+3] = 0 XOR alpha^4 = 6
97+
% j=1: S[1] = S[2] XOR alog[1+1] = 0 XOR alpha^2 = 4
98+
% S[2] = alog[1+0] = alpha^1 = 2
9399
lfsr 0 3 getinterval
94100
[6 4 2] debugIsEqual
95101

96102
%
97103
% Test 6: getdata procedure isn't assumed to be a trivial array read.
98104
% Use a stride-2 access into a flat array to prove the helper is indifferent.
99105
%
106+
/lfsr 2 array def
100107
/rsflat [0 3 0 1] def % stride 2 starting at 1: [3, 1]
101-
{ 2 mul 1 add rsflat exch get } 2 [2 3] 2 lfsr /gf8_rsprod load //rsecbinary exec
108+
{ 2 mul 1 add rsflat exch get } 2 [3 1] lfsr gf8_log gf8_alog2 //rsecbinary exec
102109
lfsr 0 2 getinterval
103110
[1 3] debugIsEqual % same result as Test 2
111+
112+
%
113+
% Test 7: Zero feedback. data=[3, 5] makes fb vanish at m=1, exercising the
114+
% pure-shift branch.
115+
% After m=0 (as Test 1): lfsr = [5, 6]
116+
% m=1: fb = 5 XOR 5 = 0 -> shift: lfsr[0] = lfsr[1] = 6, lfsr[1] = 0
117+
% Expected ECC = [6, 0]
118+
%
119+
/rsdata [3 5] def
120+
{ rsdata exch get } 2 [3 1] lfsr gf8_log gf8_alog2 //rsecbinary exec
121+
lfsr 0 2 getinterval
122+
[6 0] debugIsEqual
123+
124+
%
125+
% Test 8: Zero coefficient. logcoeffsrev=[3 -1 1] has a -1 sentinel in the
126+
% middle, exercising the zero-product branch.
127+
% lfsr = [0, 0, 0]
128+
% m=0: fb = 3 XOR 0 = 3, log(fb) = 3
129+
% j=0: lfsr[0] = lfsr[1] XOR alog[3+3] = 0 XOR alpha^6 = 5
130+
% j=1: lfsr[1] = lfsr[2] XOR 0 = 0
131+
% lfsr[2] = alog[3+1] = alpha^4 = 6
132+
% Expected ECC = [5, 0, 6]
133+
%
134+
/rsdata [3] def
135+
/lfsr 3 array def
136+
{ rsdata exch get } 1 [3 -1 1] lfsr gf8_log gf8_alog2 //rsecbinary exec
137+
lfsr 0 3 getinterval
138+
[5 0 6] debugIsEqual

0 commit comments

Comments
 (0)