feat(enc): Encaps E5 - c1 = byteEncode_du(Compress_du(u))
ST_ENC_C1: per-coeff Compress_du via comp_decomp_sync (mode 0) then LSB-first byte packing into ct_bram. 5-phase micro-seq reads u[cp_poly] from bank_se (rel K+poly), feeds the compressor (1-cyc pipe), appends du bits to cp_buf, and drains whole bytes. Each poly = 256*du bits (whole bytes) so the bit buffer empties at every poly boundary. ST_ENC_U now advances to ST_ENC_C1 (was ST_DONE). TB: verify_e5 compares ct_bram[0..c1_bytes-1] to the KAT.ct prefix via the dbg_ct tap. run_enc.sh: encaps TB runner (compiles comp_decomp_sync which the KeyGen tcl omits). Verified K=2/3/4 c1 == KAT.ct prefix (640/960/1408 B; K=4 du=11 cross-byte path), K=2 cases 0-2.
This commit is contained in:
@@ -10,6 +10,8 @@ module tb_mlkem_enc_katK_xsim;
|
||||
parameter KP = 2;
|
||||
localparam EKB = 384*KP + 32; // ek (=pk) bytes
|
||||
localparam CTB = (KP==4) ? 1568 : (32*(10*KP+4)); // ct bytes: K2 768,K3 1088,K4 1568
|
||||
localparam DU = (KP==4) ? 11 : 10; // compression du
|
||||
localparam C1B = 32*DU*KP; // c1 byte count: K2 640,K3 960,K4 1408
|
||||
|
||||
reg clk=0, rst_n=0, start_i=0;
|
||||
reg [2:0] k_i;
|
||||
@@ -41,8 +43,9 @@ module tb_mlkem_enc_katK_xsim;
|
||||
reg [7:0] ek_b [0:EKB-1];
|
||||
reg [7:0] m_b [0:31];
|
||||
reg [7:0] ss_b [0:31];
|
||||
reg [7:0] ct_b [0:CTB-1];
|
||||
integer c, i, errors, casenum, j;
|
||||
reg [8*80-1:0] tag, ekfile, mfile, ssfile;
|
||||
reg [8*80-1:0] tag, ekfile, mfile, ssfile, ctfile;
|
||||
|
||||
initial begin
|
||||
if (!$value$plusargs("CASE=%d", casenum)) casenum = 0;
|
||||
@@ -50,9 +53,11 @@ module tb_mlkem_enc_katK_xsim;
|
||||
$sformat(ekfile, "sync_rtl/top/TB/vectors/enc_%0s_c%0d_ek.hex", tag, casenum);
|
||||
$sformat(mfile, "sync_rtl/top/TB/vectors/enc_%0s_c%0d_m.hex", tag, casenum);
|
||||
$sformat(ssfile, "sync_rtl/top/TB/vectors/enc_%0s_c%0d_ss.hex", tag, casenum);
|
||||
$sformat(ctfile, "sync_rtl/top/TB/vectors/enc_%0s_c%0d_ct.hex", tag, casenum);
|
||||
$readmemh(ekfile, ek_b);
|
||||
$readmemh(mfile, m_b);
|
||||
$readmemh(ssfile, ss_b);
|
||||
$readmemh(ctfile, ct_b);
|
||||
|
||||
// build m_i: byte i in m_i[8*i +: 8]
|
||||
m_i = 256'd0;
|
||||
@@ -102,6 +107,9 @@ module tb_mlkem_enc_katK_xsim;
|
||||
verify_e3;
|
||||
verify_e4;
|
||||
end
|
||||
// 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;
|
||||
$finish;
|
||||
end
|
||||
|
||||
@@ -193,4 +201,24 @@ module tb_mlkem_enc_katK_xsim;
|
||||
end
|
||||
endtask
|
||||
initial begin #120000000; $display("FAIL: global timeout"); $finish; end
|
||||
|
||||
// E5: read ct_bram bytes 0..C1B-1 via dbg_ct tap; compare to KAT.ct prefix.
|
||||
// dbg_ct_idx_i -> ct_rd_addr (1-cyc registered read) -> dbg_ct_o (comb tap):
|
||||
// wait 3 cycles per byte (same cadence as the coeff readback tasks).
|
||||
task verify_e5;
|
||||
integer be;
|
||||
begin
|
||||
be = 0;
|
||||
for (i = 0; i < C1B; 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(" C1[%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 (E5): c1 (%0d B) == KAT.ct prefix", KP, casenum, C1B);
|
||||
else $display("K=%0d CASE %0d FAIL (E5): %0d c1 byte mismatches", KP, casenum, be);
|
||||
end
|
||||
endtask
|
||||
endmodule
|
||||
|
||||
Reference in New Issue
Block a user