feat(enc): Encaps E7 - c2 = byteEncode_dv(Compress_dv(v)) + end-to-end KAT

Reuses the E5 bit-packer FSM for ST_ENC_C2, generalized over region:
- coeff source: cp_coeff_src = bank_t[UPSUM] (v) for C2, bank_se (u) for C1
- bit width: cp_d already = dv_rt for C2 else du_rt
- poly count: cp_poly_max = 1 (single v) for C2, K for C1
- ct write pointer cp_wa CONTINUES from c1_bytes into C2 (not reset), so c2
  lands right after c1. c1 ends on a whole-byte/poly boundary (256*du/8
  integral), so cp_buf/nbits are empty at the C1->C2 handoff.

FSM tail: ST_ENC_V -> ST_ENC_C2 -> ST_DONE.

TB: verify_e7 compares the full ct (c1||c2, CTB bytes) to KAT.ct byte-exact
via the dbg_ct tap. Combined with the E0 ss==KAT.ss check this is the full
end-to-end Encaps KAT (ct==KAT.ct && ss==KAT.ss).

Verified end-to-end for K=2/3/4, cases 0-2 (K2) / 0-1 (K3,K4):
ct==KAT.ct && ss==KAT.ss. ML-KEM Encaps complete. KeyGen unregressed.
This commit is contained in:
2026-06-29 11:18:58 +08:00
parent e114bec5ee
commit 7228bebb78
3 changed files with 65 additions and 17 deletions

View File

@@ -113,6 +113,8 @@ module tb_mlkem_enc_katK_xsim;
// E5: c1 = byteEncode_du(Compress_du(u)) must equal KAT.ct[0..C1B-1].
// Runs for every K/case (ct_b is the full KAT ciphertext).
verify_e5;
// E7: full ct = c1 || c2 must equal KAT.ct (all CTB bytes). End-to-end.
verify_e7;
$finish;
end
@@ -244,4 +246,24 @@ module tb_mlkem_enc_katK_xsim;
else $display("K=2 CASE 0 FAIL (E6): %0d coeff mismatches", ce);
end
endtask
// E7: full ciphertext ct = c1 || c2 read from ct_bram (0..CTB-1) via dbg_ct
// tap; compare to KAT.ct byte-exact. This is the end-to-end Encaps check
// (ct == KAT.ct). ss == KAT.ss is already checked at E0.
task verify_e7;
integer be;
begin
be = 0;
for (i = 0; i < CTB; i = i + 1) begin
dbg_ct_idx_i = i[10:0];
@(posedge clk); @(posedge clk); @(posedge clk);
if (dbg_ct_o !== ct_b[i]) begin
if (be < 8) $display(" CT[%0d] got=%02x exp=%02x", i, dbg_ct_o, ct_b[i]);
be = be + 1;
end
end
if (be == 0) $display("K=%0d CASE %0d PASS (E7): ct (%0d B) == KAT.ct [ct==KAT.ct && ss==KAT.ss]", KP, casenum, CTB);
else $display("K=%0d CASE %0d FAIL (E7): %0d ct byte mismatches", KP, casenum, be);
end
endtask
endmodule