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:
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user