feat(enc): Encaps E4 - u = INTT(sum A^T o y_hat) + e1
ST_ENC_U computes u[i] per row in 3 sub-phases reusing shared u_pmul + u_ntt:
sub0 MAC : sum_j A_hat[j][i] o y_hat[j] (TRANSPOSE: slot=j*K+i) -> NTT-domain
psum in bank_t rel slot UPSUM=1 (e2 in slot 0), init 0 at j==0
sub1 INTT: INTT(psum) mode=1 (built-in x3303) in place in bank_t[UPSUM]
sub2 ADD : u[i][w] = psum[w] + e1[i][w] mod Q -> bank_se rel (K+i), over e1
y_hat (bank_se 0..K-1) preserved for V. ntt_core mode + input muxed for the
INTT sub-phase; bank_a/se/t read+write ports extended for all 3 sub-phases.
Fixed a duplicate 'assign bse_we' (stale + new both present -> ADD writes
X-dropped); collapsed to one. Verified (K=2 c0) u[0..1] == ml-kem-r golden
(transpose + INTT + e1 all correct); E0/E1/E3 pass, E2 trimmed to e2 (e1
consumed into u, transitively checked by E4); K=3/4 no timeout.
This commit is contained in:
@@ -100,6 +100,7 @@ module tb_mlkem_enc_katK_xsim;
|
||||
verify_e1;
|
||||
verify_e2;
|
||||
verify_e3;
|
||||
verify_e4;
|
||||
end
|
||||
$finish;
|
||||
end
|
||||
@@ -135,32 +136,20 @@ module tb_mlkem_enc_katK_xsim;
|
||||
// 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_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);
|
||||
$readmemh("sync_rtl/top/TB/vectors/encgold/ec_k2_c0_e2.hex", ge2);
|
||||
ce = 0;
|
||||
// e1_0,e1_1 at bank_se dbg slots 6,7 (time-domain, untouched by NTT).
|
||||
// (y at slots 4,5 is overwritten in place by y_hat -> checked in E3.)
|
||||
for (slot = 2; slot < 4; slot = slot + 1)
|
||||
for (idx = 0; idx < 256; idx = idx + 1) begin
|
||||
dbg_slot_i = (4+slot); dbg_idx_i = idx[7:0];
|
||||
@(posedge clk); @(posedge clk); @(posedge clk);
|
||||
if (dbg_coeff_o !== gy[slot*256+idx]) begin
|
||||
if (ce < 8) $display(" E1[s%0d,%0d] got=%03x exp=%03x", slot-2, idx, dbg_coeff_o, gy[slot*256+idx]);
|
||||
ce = ce + 1;
|
||||
end
|
||||
end
|
||||
// e2 at bank_t dbg slot 8
|
||||
// e2 at bank_t dbg slot 8 (survives; e1 is consumed/overwritten by u
|
||||
// in E4 -> e1 correctness is transitively verified by E4's u check).
|
||||
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]);
|
||||
if (ce < 8) $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): e1[0..1],e2 == ml-kem-r golden");
|
||||
else $display("K=2 CASE 0 FAIL (E2): %0d coeff mismatches", ce);
|
||||
if (ce == 0) $display("K=2 CASE 0 PASS (E2): e2 == ml-kem-r golden");
|
||||
else $display("K=2 CASE 0 FAIL (E2): %0d e2 mismatches", ce);
|
||||
end
|
||||
endtask
|
||||
// y_hat[i] = NTT(y[i]) in place at bank_se rel slots 0..K-1 -> dbg slots 4..5 (K=2).
|
||||
@@ -183,5 +172,25 @@ module tb_mlkem_enc_katK_xsim;
|
||||
else $display("K=2 CASE 0 FAIL (E3): %0d coeff mismatches", ce);
|
||||
end
|
||||
endtask
|
||||
// u[i] = INTT(sum A^T o y_hat) + e1[i] over e1 in bank_se rel K+i -> dbg 6,7 (K=2).
|
||||
reg [11:0] gu [0:2*256-1];
|
||||
task verify_e4;
|
||||
begin
|
||||
$readmemh("sync_rtl/top/TB/vectors/encgold/ec_k2_c0_u_0.hex", gu, 0, 255);
|
||||
$readmemh("sync_rtl/top/TB/vectors/encgold/ec_k2_c0_u_1.hex", gu, 256, 511);
|
||||
ce = 0;
|
||||
for (slot = 0; slot < 2; slot = slot + 1)
|
||||
for (idx = 0; idx < 256; idx = idx + 1) begin
|
||||
dbg_slot_i = (6+slot); dbg_idx_i = idx[7:0]; // bank_se rel K+slot (K=2)
|
||||
@(posedge clk); @(posedge clk); @(posedge clk);
|
||||
if (dbg_coeff_o !== gu[slot*256+idx]) begin
|
||||
if (ce < 8) $display(" U[s%0d,%0d] got=%03x exp=%03x", slot, idx, dbg_coeff_o, gu[slot*256+idx]);
|
||||
ce = ce + 1;
|
||||
end
|
||||
end
|
||||
if (ce == 0) $display("K=2 CASE 0 PASS (E4): u[0..1] == ml-kem-r golden");
|
||||
else $display("K=2 CASE 0 FAIL (E4): %0d coeff mismatches", ce);
|
||||
end
|
||||
endtask
|
||||
initial begin #120000000; $display("FAIL: global timeout"); $finish; end
|
||||
endmodule
|
||||
|
||||
Reference in New Issue
Block a user