feat(enc): Encaps E2 - sample y/e1/e2 (CBD eta1/eta2, r seed)

ST_ENC_C reuses the ST_C CBD datapath with Encaps muxes: seed=r (not sigma),
eta=eta1 for y[0..K-1] then eta2 for e1[0..K-1]/e2, nonce 0..2K. 2K+1 polys
(vs KeyGen 2K). y/e1 -> bank_se rel slots 0..2K-1; e2 -> bank_t rel slot 0
(free during C/N/U since TDEC is deferred to V-prep so the 28-slot banks hold
all of A+y_hat+e1+e2 at K=4 without resizing).

Bring-up golden via ml-kem-r dump_encaps_full (working-tree example):
vectors/encgold/ec_k2_c0_{y,e1,e2}.hex. Verified (K=2 c0) y[0..1],e1[0..1],e2
== ml-kem-r; A_hat (E1) and ss (E0) still pass; K=3/4 no timeout.
This commit is contained in:
2026-06-29 01:55:47 +08:00
parent 31c967c8a4
commit cdc5ce25b1
12 changed files with 2645 additions and 34 deletions

View File

@@ -92,16 +92,22 @@ module tb_mlkem_enc_katK_xsim;
if (errors == 0) $display("K=%0d CASE %0d PASS (E0): ss == KAT.ss", KP, casenum);
else $display("K=%0d CASE %0d FAIL (E0): %0d ss mismatches", KP, casenum, errors);
// ---- E1: verify A_hat (slots 0..K^2-1) and t_hat (slots slot_t..) ----
// The KAT case-0 Encaps reuses ek=pk from KeyGen case-0, so regenerated
// A_hat and decoded t_hat equal KeyGen's golden vectors (K=2 c0 only).
if (KP == 2 && casenum == 0) verify_e1;
// ---- E1: verify A_hat (slots 0..K^2-1). t_hat (byteDecode12) is re-
// verified at E6 (V uses it); TDEC is deferred to V-prep so e2 can use
// bank_t during C/N/U. A_hat equals KeyGen golden (K=2 c0). ----
// ---- E2: verify y[i], e1[i] (bank_se), e2 (bank_t slot_t) vs ml-kem-r.
if (KP == 2 && casenum == 0) begin
verify_e1;
verify_e2;
end
$finish;
end
// golden coeff arrays (K=2 c0): A_hat[i][j] and t_hat[i], 256 coeffs each
reg [11:0] ga [0:4*256-1]; // A00,A01,A10,A11 concatenated (slot*256+idx)
reg [11:0] gt [0:2*256-1]; // t_hat0, t_hat1
// E1 golden: A_hat[i][j] (KeyGen golden, K=2 c0)
reg [11:0] ga [0:4*256-1];
// E2 golden: y0,y1,e1_0,e1_1 (bank_se rel slots 0..3), e2 (bank_t slot 0)
reg [11:0] gy [0:4*256-1];
reg [11:0] ge2 [0:255];
integer ce, slot, idx;
task verify_e1;
begin
@@ -109,10 +115,7 @@ module tb_mlkem_enc_katK_xsim;
$readmemh("test_framework/modules/mlkem_keygen/golden/c000_Ahat_0_1.hex", ga, 256, 511);
$readmemh("test_framework/modules/mlkem_keygen/golden/c000_Ahat_1_0.hex", ga, 512, 767);
$readmemh("test_framework/modules/mlkem_keygen/golden/c000_Ahat_1_1.hex", ga, 768, 1023);
$readmemh("test_framework/modules/mlkem_keygen/golden/c000_that_0.hex", gt, 0, 255);
$readmemh("test_framework/modules/mlkem_keygen/golden/c000_that_1.hex", gt, 256, 511);
ce = 0;
// A_hat: slots 0..3 (i*k+j)
for (slot = 0; slot < 4; slot = slot + 1)
for (idx = 0; idx < 256; idx = idx + 1) begin
dbg_slot_i = slot[3:0]; dbg_idx_i = idx[7:0];
@@ -122,18 +125,42 @@ module tb_mlkem_enc_katK_xsim;
ce = ce + 1;
end
end
// t_hat: slots slot_t_rt(=8) .. +1
for (slot = 0; slot < 2; slot = slot + 1)
if (ce == 0) $display("K=2 CASE 0 PASS (E1): A_hat (1024) == KeyGen golden");
else $display("K=2 CASE 0 FAIL (E1): %0d A mismatches", ce);
end
endtask
// y[i],e1[i] live in bank_se at rel slots 0..K-1 (y), K..2K-1 (e1).
// dbg slot for bank_se = slot_s_rt + rel. K=2: slot_s_rt=4 -> y0=4,y1=5,e1_0=6,e1_1=7.
// e2 lives in bank_t rel slot 0 -> dbg slot = slot_t_rt = 8.
task verify_e2;
begin
$readmemh("sync_rtl/top/TB/vectors/encgold/ec_k2_c0_y_0.hex", gy, 0, 255);
$readmemh("sync_rtl/top/TB/vectors/encgold/ec_k2_c0_y_1.hex", gy, 256, 511);
$readmemh("sync_rtl/top/TB/vectors/encgold/ec_k2_c0_e1_0.hex", gy, 512, 767);
$readmemh("sync_rtl/top/TB/vectors/encgold/ec_k2_c0_e1_1.hex", gy, 768, 1023);
$readmemh("sync_rtl/top/TB/vectors/encgold/ec_k2_c0_e2.hex", ge2);
ce = 0;
// y0,y1,e1_0,e1_1 at bank_se dbg slots 4..7
for (slot = 0; slot < 4; slot = slot + 1)
for (idx = 0; idx < 256; idx = idx + 1) begin
dbg_slot_i = (8+slot); dbg_idx_i = idx[7:0];
dbg_slot_i = (4+slot); dbg_idx_i = idx[7:0];
@(posedge clk); @(posedge clk); @(posedge clk);
if (dbg_coeff_o !== gt[slot*256+idx]) begin
if (ce < 12) $display(" T[%0d,%0d] got=%03x exp=%03x", slot, idx, dbg_coeff_o, gt[slot*256+idx]);
if (dbg_coeff_o !== gy[slot*256+idx]) begin
if (ce < 8) $display(" Y[s%0d,%0d] got=%03x exp=%03x", slot, idx, dbg_coeff_o, gy[slot*256+idx]);
ce = ce + 1;
end
end
if (ce == 0) $display("K=2 CASE 0 PASS (E1): A_hat (1024) + t_hat (512) == KeyGen golden");
else $display("K=2 CASE 0 FAIL (E1): %0d coeff mismatches", ce);
// e2 at bank_t dbg slot 8
for (idx = 0; idx < 256; idx = idx + 1) begin
dbg_slot_i = 8; dbg_idx_i = idx[7:0];
@(posedge clk); @(posedge clk); @(posedge clk);
if (dbg_coeff_o !== ge2[idx]) begin
if (ce < 12) $display(" E2[%0d] got=%03x exp=%03x", idx, dbg_coeff_o, ge2[idx]);
ce = ce + 1;
end
end
if (ce == 0) $display("K=2 CASE 0 PASS (E2): y[0..1],e1[0..1],e2 == ml-kem-r golden");
else $display("K=2 CASE 0 FAIL (E2): %0d coeff mismatches", ce);
end
endtask
initial begin #120000000; $display("FAIL: global timeout"); $finish; end

View File

@@ -0,0 +1,256 @@
cff
d00
000
001
d00
001
d00
d00
d00
d00
cff
d00
d00
000
000
000
001
000
000
001
d00
000
002
d00
d00
001
001
002
002
d00
001
001
000
d00
000
001
001
000
cff
000
d00
d00
000
000
cff
cff
000
d00
001
000
d00
d00
001
d00
d00
001
cff
000
001
d00
000
d00
002
001
000
002
d00
d00
d00
001
001
002
000
001
000
d00
000
d00
000
001
002
d00
cff
cff
d00
001
cff
000
000
002
001
001
d00
000
d00
d00
000
cff
002
d00
cff
000
000
d00
d00
001
001
d00
d00
000
cff
cff
cff
002
d00
d00
001
000
001
001
001
001
001
000
000
001
d00
002
cff
d00
001
000
000
001
000
d00
000
001
001
001
000
000
000
000
000
001
000
d00
d00
d00
000
000
d00
000
000
000
000
000
000
000
001
001
d00
000
d00
001
002
d00
000
d00
d00
001
d00
d00
000
d00
000
000
001
d00
002
001
d00
000
d00
000
002
000
d00
000
cff
002
d00
000
000
001
001
d00
d00
000
d00
002
000
d00
000
d00
001
001
d00
000
001
001
000
d00
000
000
d00
000
000
001
000
000
002
d00
d00
000
d00
002
001
d00
000
000
001
002
001
d00
002
001
001
000
d00
000
001
d00
cff
d00
001
cff
001
001
001
001
d00
001
000
d00

View File

@@ -0,0 +1,256 @@
d00
000
d00
000
d00
000
001
000
000
000
000
001
001
002
cff
d00
d00
002
d00
000
000
001
001
001
001
d00
000
000
000
000
000
000
000
000
d00
d00
000
001
002
d00
000
000
d00
000
001
001
000
001
001
000
002
d00
d00
000
001
000
001
000
000
000
001
002
000
000
000
001
d00
d00
002
001
001
000
000
000
d00
d00
000
000
d00
001
001
001
000
000
d00
000
001
d00
000
000
000
001
d00
cff
002
000
000
d00
d00
d00
000
000
cff
000
001
001
000
001
d00
002
001
cff
001
000
000
001
001
001
d00
000
000
001
000
000
001
000
000
001
d00
000
001
000
cff
000
002
001
001
001
001
000
d00
000
001
002
000
d00
000
000
cff
000
000
cff
001
002
d00
d00
000
000
001
d00
001
000
000
002
000
cff
001
d00
000
000
001
d00
d00
002
001
d00
002
000
d00
cff
000
000
d00
001
000
d00
001
001
001
002
001
000
cff
000
d00
001
000
d00
000
d00
000
d00
002
000
d00
001
001
d00
001
001
001
000
d00
d00
002
001
000
000
000
d00
001
001
000
000
001
cff
000
001
001
001
001
d00
000
001
000
000
000
000
000
001
001
001
cff
d00
cff
cff
d00
001
000
001
001
000
002
000
001
000

View File

@@ -0,0 +1,256 @@
cff
000
000
000
d00
002
d00
000
000
d00
d00
001
001
d00
d00
001
000
000
000
000
000
d00
001
002
001
001
001
000
002
000
001
002
d00
000
000
d00
000
001
d00
d00
001
000
d00
d00
d00
d00
d00
d00
001
001
001
001
001
000
001
001
001
000
cff
001
000
002
000
000
001
000
000
000
000
001
000
cff
000
d00
000
001
002
000
000
d00
d00
001
000
002
001
001
001
d00
d00
d00
000
d00
001
001
001
d00
001
000
000
000
d00
000
000
d00
001
001
001
001
000
001
001
d00
000
001
001
001
001
000
002
001
000
002
d00
000
d00
001
001
000
001
000
001
000
000
000
000
000
002
001
000
000
001
000
000
d00
d00
001
002
000
000
002
000
000
000
000
002
001
d00
000
d00
000
000
d00
d00
d00
000
000
002
000
d00
d00
000
001
001
000
000
d00
d00
d00
000
001
001
000
000
d00
000
000
001
d00
000
cff
000
d00
d00
d00
001
001
001
d00
000
000
000
d00
001
001
d00
cff
d00
000
d00
001
000
d00
000
001
d00
d00
001
001
001
001
001
000
001
d00
000
000
cff
000
001
000
001
000
000
000
000
001
d00
000
000
000
000
000
000
000
000
000
002
d00
001
001
002
000
d00
d00
000
000

View File

@@ -0,0 +1,256 @@
857
7b5
384
b79
827
564
1bc
873
391
113
431
91b
00e
22a
a9e
483
63d
2f5
a7a
057
af4
643
0f9
cc2
bce
2af
6a2
ad7
3f5
bcc
a37
6b3
77a
710
41d
698
9c2
7eb
0eb
9fe
8c6
a63
72f
403
3d9
530
bb5
28e
8b6
0c0
2bf
9ba
636
7c3
940
188
1e7
1f6
1ed
523
285
91c
c08
3c8
77a
9a9
bd6
7ca
cf1
452
7db
3f6
3e1
48c
197
cfc
219
666
65a
576
7f6
20d
c55
966
c36
856
9bf
448
11c
67c
59a
a3e
162
317
57d
ae4
c3d
739
577
755
58c
311
757
11e
75b
78f
088
a61
b31
8ff
ba3
842
65a
bdb
108
791
2e3
c6d
8a1
97d
5bc
882
bbb
423
9ec
6c5
70b
415
305
546
7d5
63a
204
0f3
6c8
c8b
2c4
a44
5b6
cb7
a80
019
18f
293
5b8
56f
421
b76
918
715
8e5
619
814
192
2a8
06f
0d7
93a
6d8
1b3
83a
5cb
415
0a4
1bf
b9f
18f
8a5
2e0
c75
5b5
59b
364
8c9
8e2
283
cf6
b81
243
2ae
8d9
32b
b15
cd7
6b0
8d2
36f
543
048
72b
4fb
c73
05d
402
87d
342
085
32c
745
3cf
959
3d4
9fa
90f
4bf
89e
0ed
a7f
c1a
036
731
67f
316
636
a45
828
a24
746
ab3
580
6dc
6e3
542
6a9
95a
aa0
7a7
a1f
c5c
1b2
049
768
830
134
076
294
392
549
19d
8ae
84b
881
8b9
81a
549
642
901
191
274
c50
24d
3f0
160
882
ce6
11a

View File

@@ -0,0 +1,256 @@
541
565
972
68c
0fb
416
1a8
6b2
0f3
3a4
604
94e
5c9
330
beb
56d
b19
883
019
421
525
c52
ab4
943
207
a89
1a1
3b9
04b
a86
33f
65b
a0f
b82
cbf
2a3
ac0
b3b
590
2cc
18c
cae
8c2
c4f
a70
aa4
7d1
20b
4bc
57d
5c5
a4d
176
90e
139
b5b
131
8d7
099
280
8c7
045
2d4
aea
c06
c41
b60
766
9fe
99f
57d
7f9
2ac
2c3
4b7
6aa
070
b84
c21
bcd
0dc
941
243
144
4fc
99b
7d2
72a
bde
a87
1ee
37e
cdb
1cf
a10
36c
27c
c15
6c5
c3a
2b7
6c8
c20
7f1
67f
c9d
7bf
31a
b2a
6c5
c4e
6a3
972
64a
548
0e5
69b
b43
441
a27
1b4
101
176
bd9
267
9b3
1d1
3f2
97b
492
c67
ccb
1fa
2f7
bd0
6b8
6d1
cbf
62d
cfe
b03
7d5
5e2
377
70c
657
48b
59c
c2c
c85
55a
c45
9b8
9e1
cb0
ae5
769
25c
b11
b24
4ba
9e6
cba
39a
031
607
05b
afd
a56
7ae
02e
b45
9c5
3bc
4f2
12d
4be
5f1
59b
488
b03
50e
c2a
2b4
271
0ad
b36
1e9
44b
85d
c92
bfa
bdc
3e9
c43
4ad
b67
4ce
773
627
14c
150
58a
931
49d
c60
2ba
2d1
c18
8e8
2a1
c0e
689
350
901
8a6
646
9f4
2f5
672
6df
079
910
4f7
0f8
a18
2f7
02c
2d9
27d
4ad
521
9fa
b77
b64
ce0
ad2
bdf
0fa
564
103
b98
bd2
96b
9b9
632
237
21b
99b
3b7
450
76f
50b
7de
81d
6a3

View File

@@ -0,0 +1,256 @@
b05
019
247
3b4
9a8
2d3
58a
3f0
201
110
62d
6fb
8d0
789
842
260
4a8
239
5a2
212
819
b2b
ccb
062
076
7e8
b62
adf
b26
282
4e2
38c
816
76f
022
6ca
a18
03b
292
394
a33
11b
a68
370
17b
c7e
20e
305
07d
9e7
9b0
a9d
aa1
610
87b
51a
701
6a7
7ef
905
79d
56a
cb0
ca9
43d
aef
8f8
170
633
5c4
a01
8a2
086
9d7
250
047
558
304
c3a
333
a60
788
a18
142
0d5
202
628
201
174
05c
9b9
46f
0f2
29b
2d6
786
30e
9f9
0d8
a2b
02d
884
c6d
7b7
cd9
445
04e
75e
812
3c0
1b5
ae1
bb3
aa1
bdf
5f0
6cb
b14
ce4
b35
c0c
797
392
c9d
b13
5d0
b33
065
166
5d7
4ba
bb8
7de
a8f
d00
8a8
a54
b99
5e8
c8d
254
b88
027
8a2
b2e
6be
06e
aee
121
24c
810
4ca
beb
970
41b
6cb
17b
552
345
3c4
4e0
942
113
a1b
91c
c83
529
c54
989
326
456
b35
189
6bb
1a8
c0c
781
714
9b0
04e
b4a
991
c97
a01
3eb
7b2
470
01f
a7c
beb
b64
5bf
43c
6c0
58e
132
6ed
79e
834
6a8
c2a
81e
685
3cc
939
2ae
098
b84
830
810
2f6
537
b35
06c
89d
729
33b
3eb
90a
af5
77f
92b
a00
0f4
6ee
7ed
034
ab3
01d
574
6f6
ce4
24d
104
4bf
767
bee
5d5
cc7
93d
346
227
13a
74c
0b5
cc0
3ea
890
50a
a36
765
5b2
268
943
a37
1ee

View File

@@ -0,0 +1,256 @@
d00
001
d00
001
002
cff
002
d00
003
000
000
000
d00
000
003
000
001
002
cff
cfe
cff
d00
001
cff
000
002
000
001
000
001
002
002
001
001
d00
cff
d00
001
001
002
002
001
000
000
000
002
000
d00
001
001
001
d00
001
000
cff
000
000
001
001
002
000
cff
003
000
cff
000
001
000
d00
cff
000
002
d00
003
001
d00
cff
002
cff
d00
d00
000
000
d00
000
d00
cff
cff
000
002
002
000
000
001
000
d00
003
001
cff
001
000
cff
001
001
001
d00
001
d00
001
d00
001
001
d00
001
000
000
000
000
002
d00
001
001
000
001
d00
000
cff
000
001
d00
001
d00
002
000
001
d00
cfe
001
001
001
001
000
001
002
d00
002
d00
cff
001
003
000
000
000
d00
002
001
001
000
000
000
cff
000
d00
001
d00
001
000
cff
001
002
002
d00
002
000
d00
001
002
cff
d00
002
001
000
000
000
001
000
000
d00
000
000
d00
000
cff
d00
000
d00
001
d00
002
001
000
000
d00
000
001
001
000
001
001
000
cff
000
000
002
002
000
000
001
000
002
001
001
cff
000
d00
d00
cff
000
002
001
000
000
000
002
000
000
d00
cff
000
d00
d00
d00
002
d00
002
003
000
001
d00
002
002
000
d00
000
002
002

View File

@@ -0,0 +1,256 @@
000
d00
d00
cff
000
cff
002
000
001
cff
002
001
001
d00
000
d00
001
d00
d00
d00
d00
001
001
d00
000
000
cff
000
d00
d00
001
001
000
000
001
001
001
000
d00
001
000
d00
cff
000
002
000
002
001
d00
000
000
d00
d00
000
002
cff
001
000
d00
001
001
000
d00
001
d00
000
000
d00
001
001
001
d00
d00
001
d00
001
001
cff
001
000
d00
d00
002
000
001
001
d00
d00
000
000
d00
002
d00
cff
d00
d00
cff
d00
002
cfe
001
002
001
001
d00
001
001
002
000
cff
d00
d00
cfe
000
d00
d00
001
000
002
cff
d00
cff
d00
000
cff
002
000
001
000
d00
001
d00
001
003
001
d00
000
000
001
002
000
001
d00
002
001
d00
000
001
cff
002
002
000
000
001
000
d00
000
000
001
002
001
d00
d00
d00
cff
d00
002
000
001
000
000
001
003
cff
000
000
d00
cff
000
d00
003
cff
cfe
d00
d00
002
002
001
000
d00
d00
000
d00
002
001
000
000
001
d00
d00
000
cff
000
002
000
002
000
d00
000
000
cff
000
000
001
d00
d00
003
000
001
001
cff
d00
000
000
002
d00
001
000
cff
003
000
002
001
000
001
cfe
003
001
000
001
002
d00
000
cff
001
000
000
001
000
cff
000
000
001
001
000
d00

View File

@@ -0,0 +1,256 @@
793
7a2
012
c51
c83
055
745
0d1
41c
4d5
29b
b80
485
19c
19b
462
c11
c32
84f
6ec
4aa
8aa
1cb
00f
359
298
a34
60f
8aa
342
c3a
301
55d
7c8
403
97f
544
8c1
34b
95e
a82
384
aa6
515
9f0
2fc
4ff
a4d
4f2
13b
64c
8f4
c7e
172
55e
809
9ff
360
182
3fd
101
078
804
82a
6f8
21d
bb1
19b
a3f
2df
632
9b0
cef
7f8
c29
1be
0f4
cc1
af3
31c
7c9
45e
92a
890
bec
2c5
42d
4bb
8ed
10d
050
2dc
9a3
006
36d
331
732
365
7f0
5d9
461
ab4
6a9
bbe
042
952
84f
0e2
67b
0d5
cd8
bad
8dd
8d6
c94
9d4
cbd
bf5
422
85b
031
45e
afb
061
a3f
718
b95
780
a5e
8d6
a36
13a
813
7f6
166
2ff
320
8c3
53a
115
7a7
c57
1b6
25a
ab1
55d
13d
ba7
62d
343
35c
69d
50c
3e0
066
c9a
a9e
bf5
b25
722
19b
821
95d
05b
6e1
3c1
6af
06e
5a4
c46
b10
2af
bf7
364
198
21b
654
35e
c6e
78b
b19
22e
82d
208
17b
a2b
1a1
ccb
770
362
242
a3e
82f
73d
409
83b
091
a70
776
2b1
880
ae5
98c
1c5
299
83b
4b0
850
7a5
bba
34b
7e0
2c6
c1a
5e5
861
474
8fc
54c
6fb
abf
3d7
99b
0e9
2bd
a05
215
a66
be8
55d
10b
ca1
5da
47a
1cd
9a9
a80
1c3
711
1fa
5eb
856
6ee
cae
0cf
532
529
801
30a
508
b07
cc5
c46
6a7
140
61b

View File

@@ -0,0 +1,256 @@
a0d
990
c4b
481
9e3
190
135
bfe
0d4
579
a7f
66a
863
20a
9a4
b18
7f8
492
909
b37
101
750
4b9
104
3f4
b6c
b80
139
144
09f
b5f
20b
0d5
b3c
a70
6df
c31
698
2e6
15c
2d2
148
2a4
572
a56
5d2
a3e
0c7
cc6
55e
6b7
cff
683
877
76e
10d
5d5
1bd
a9b
617
9ee
930
2dc
088
5ac
ce7
413
56c
422
478
51a
369
9b0
3c7
032
79e
9d0
043
95a
11a
6ca
c1d
981
07a
43e
4cc
c2d
08f
454
c74
2df
cf1
02c
6da
191
b51
61b
453
303
921
520
396
6f6
405
4ce
797
b9e
20f
cfb
a50
7c4
c82
bb1
402
276
c12
ae2
242
4d1
689
c8b
88c
835
360
866
5ea
66c
02b
af9
29f
905
783
9c1
9ff
500
4a1
984
bb0
a05
08d
636
8da
887
ab6
37e
7ae
7f3
06d
1e6
29b
942
72a
1e1
13e
6ac
4fe
a34
994
8db
bda
3c1
4ec
8b4
6d7
227
946
a62
9aa
163
6d6
96f
bb7
161
a7f
651
8e1
622
78d
60b
86b
8bd
031
246
55e
7a0
736
cc9
a07
2c3
58b
691
8c7
c13
381
49a
85d
c91
43b
86a
0fb
2a8
5b9
743
283
8a7
bef
be1
20d
a3a
b6d
42f
b91
501
bc8
0be
66b
3fe
994
418
440
6c2
8d1
995
980
800
8c6
0f4
6d2
c7f
cef
781
738
3ec
065
a50
b75
46a
4d1
ad8
377
3ee
a4a
3a2
5e9
29f
597
56a
c70
8dc
7c0
989
c5f
3c1
05a
497
afd

View File

@@ -212,12 +212,17 @@ module mlkem_top #(
.clk(clk), .rd_addr(bt_rd_addr), .rd_data(bt_rd_data),
.wr_en(bt_we), .wr_addr(bt_wa), .wr_data(bt_wd)
);
// bank_t write: KeyGen ST_M accumulate, or Encaps TDEC byteDecode12.
// ST_M: t_hat[m_i][m_oidx] <= (acc+product) mod Q when pm_vo.
// ST_ENC_TDEC: t_hat[td_poly][2*td_trip(+1)] <= decoded coeff (td_we/wa/wd).
assign bt_we = ((st == ST_M) && pm_vo) || td_we;
assign bt_wa = td_we ? td_wa : ((m_i*256 + m_oidx) & ((1<<PT_AW)-1));
assign bt_wd = td_we ? td_wd : m_accq;
// bank_t write: KeyGen ST_M accumulate, Encaps TDEC byteDecode12, or Encaps
// e2 (ST_ENC_C c_poly==2K -> bank_t rel slot 0, free during C/N/U).
wire e2_we = (st == ST_ENC_C) && c_busy && cbd_vo && cbd_ack &&
(c_poly == {1'b0, k_r, 1'b0}); // c_poly == 2K
assign bt_we = ((st == ST_M) && pm_vo) || td_we || e2_we;
assign bt_wa = td_we ? td_wa :
e2_we ? (c_widx & ((1<<PT_AW)-1)) :
((m_i*256 + m_oidx) & ((1<<PT_AW)-1));
assign bt_wd = td_we ? td_wd :
e2_we ? cbd_modq :
m_accq;
// Debug readback (registered for timing)
reg [11:0] dbg_coeff_r;
@@ -243,7 +248,11 @@ module mlkem_top #(
dbg_se_addr[PSE_AW-1:0];
// bank_se write port: ST_C CBD store (rel slot c_poly), ST_N NTT writeback
// (rel slot n_slot). Disjoint states.
// bank_se write: KeyGen ST_C CBD (s/e), Encaps ST_ENC_C CBD (y/e1, c_poly<2K;
// e2 at c_poly==2K goes to bank_t instead), ST_N NTT writeback. Disjoint.
assign bse_we = ((st == ST_C) && c_busy && cbd_vo && cbd_ack) ||
((st == ST_ENC_C) && c_busy && cbd_vo && cbd_ack &&
(c_poly < {1'b0, k_r, 1'b0})) ||
((st == ST_N) && ntt_vo);
assign bse_wa = (st == ST_N) ? ((n_slot*256 + n_widx) & ((1<<PSE_AW)-1))
: ((c_poly*256 + c_widx) & ((1<<PSE_AW)-1));
@@ -547,11 +556,19 @@ module mlkem_top #(
wire cbd_last;
reg cbd_ack;
// CBD inputs muxed KeyGen vs Encaps:
// KeyGen ST_C: seed=sigma, eta=eta1 (all polys), nonce=c_poly.
// Encaps ST_ENC_C: seed=r, nonce=c_poly; eta = eta1 for y (c_poly<K),
// eta2 for e1/e2 (c_poly>=K). nonce sequence 0..2K matches FIPS.
wire cbd_enc = (st == ST_ENC_C);
wire [255:0] cbd_seed = cbd_enc ? r_r : sigma_r;
wire [1:0] cbd_eta = cbd_enc ? ((c_poly < {2'b0, k_r}) ? eta1_rt : eta2_rt)
: eta1_rt;
sample_cbd_sync_shared u_cbd (
.clk(clk), .rst_n(rst_n),
.seed_i(sigma_r),
.seed_i(cbd_seed),
.nonce_i(c_nonce),
.eta_i(eta1_rt),
.eta_i(cbd_eta),
.valid_i(cbd_valid),
.ready_o(cbd_ready),
.coeff_o(cbd_coeff),
@@ -708,8 +725,9 @@ module mlkem_top #(
ST_ENC_H: if (h_phase == 2'd3) st_next = ST_ENC_G;
ST_ENC_G: if (sha3_vo) st_next = ST_ENC_LOAD; // (K,r) captured
ST_ENC_LOAD: if (rl_idx >= 6'd33) st_next = ST_ENC_A; // rho loaded
ST_ENC_A: if (a_pair >= kk_rt) st_next = ST_ENC_TDEC;
ST_ENC_TDEC: if (td_done) st_next = ST_DONE; // E1: stop here (A, t_hat ready)
ST_ENC_A: if (a_pair >= kk_rt) st_next = ST_ENC_C;
ST_ENC_C: if (c_poly >= {k_r, 1'b1}) st_next = ST_DONE; // E2: stop (2K+1 polys: y,e1,e2)
ST_ENC_TDEC: if (td_done) st_next = ST_DONE; // (TDEC deferred to V-prep later)
ST_DONE: st_next = ST_IDLE;
default: st_next = ST_IDLE;
endcase
@@ -869,8 +887,9 @@ module mlkem_top #(
end
end
// Arm C stage when A finishes
if (st == ST_A && st_next == ST_C) begin
// Arm C stage when A finishes (KeyGen ST_A or Encaps ST_ENC_A)
if ((st == ST_A && st_next == ST_C) ||
(st == ST_ENC_A && st_next == ST_ENC_C)) begin
cbd_valid <= 1'b1;
cbd_ack <= 1'b1;
c_poly <= 3'd0;
@@ -878,21 +897,26 @@ module mlkem_top #(
c_busy <= 1'b0;
end
// ---- ST_C: drive CBD, store 256 mod-q coeffs per poly ----
if (st == ST_C) begin
// ---- ST_C / ST_ENC_C: drive CBD, store 256 mod-q coeffs per poly ----
// KeyGen: 2K polys (s,e). Encaps: 2K+1 polys (y,e1,e2). Loop bound
// differs: KeyGen restarts while c_poly+1 < 2K; Encaps while < 2K+1.
if (st == ST_C || st == ST_ENC_C) begin
if (cbd_valid && cbd_ready) begin
cbd_valid <= 1'b0;
c_busy <= 1'b1;
end
if (c_busy && cbd_vo && cbd_ack) begin
// bank_se write is the combinational bse_we/bse_wa/bse_wd
// assigns (rel slot c_poly); here only advance counters.
if (cbd_last) begin
c_poly <= c_poly + 3'd1;
c_widx <= 8'd0;
c_busy <= 1'b0;
if (c_poly + 3'd1 < {1'b0, k_r, 1'b0}) cbd_valid <= 1'b1;
// restart for next poly while more remain (state-dependent bound)
if (st == ST_ENC_C) begin
if (c_poly + 3'd1 < {k_r, 1'b1}) cbd_valid <= 1'b1; // < 2K+1
end else begin
if (c_poly + 3'd1 < {1'b0, k_r, 1'b0}) cbd_valid <= 1'b1; // < 2K
end
end else begin
c_widx <= c_widx + 8'd1;
end