Commit Graph

8 Commits

Author SHA1 Message Date
9824ed8f2c feat(mlkem_top): KeyGen stage 4 - H(ek) + full dk, end-to-end KAT pass
Add ST_H stage: second sha3_top (mb_en=1) computes H(ek) over 800B ek as 6
pre-padded SHA3-256 rate blocks. Per block: assemble 136 bytes (h_padbyte
applies 0x06...0x80 padding on final block) into h_block_r, feed (hold valid
until mb_ready drops), wait permute; capture digest on last block into hek_r.

Full dk readback tap: dk = dk_pke(768) || ek(800) || H(ek)(32) || z(32) = 1632B.

End-to-end TB (tb_mlkem_kg_kat_xsim, no force/release): drive KAT count=0 d/z,
run full KeyGen FSM (IDLE->G->A->C->N->M->E->H->DONE), verify:
  ek  == KAT pk (800B)  byte-exact
  dk  == KAT sk (1632B) byte-exact
Done in 21403 cycles. ML-KEM-512 KeyGen complete and KAT-verified.
Prior stage TBs (2c/2e/2f) still pass (no regression).
2026-06-28 02:18:52 +08:00
17914911c3 feat(mlkem_top): KeyGen stage 2f (byteEncode12 -> ek, dk_pke)
Add ST_E stage: serialize t_hat[0..1] -> ek_mem[0..767], s_hat[0..1] ->
dkp_mem[0..767] via byteEncode12 (2 coeffs -> 3 bytes, LSB-first 12-bit:
b0=c0[7:0], b1={c1[3:0],c0[11:8]}, b2=c1[11:4]), then copy rho into
ek_mem[768..799]. Byte readback tap (dbg_byte_sel/idx -> dbg_byte_o).

Verified vs KAT-derived golden: ek 800B (== KAT pk) + dk_pke 768B
(== KAT sk prefix) byte-exact (20430 cyc). Completes Stage 2 datapath.
2026-06-28 02:03:03 +08:00
a9e50ebc0c feat(mlkem_top): KeyGen stage 2e (matrix accumulate t_hat)
Add ST_M stage: t_hat[i] = e_hat[i] + sum_j A_hat[i][j] o s_hat[j] via
poly_mul_sync + inline mod-add accumulation. Per (i,j): stream 256 (A,shat)
pairs into poly_mul, then accumulate 256 products into T_i (seeded from E_i
when j==0, else running T_i). m_pending waits for poly_mul IDLE between terms.

Verified vs ml-kem-r golden: 512/512 t_hat coeffs exact (19885 cyc).
2026-06-28 01:53:23 +08:00
4c692e570a feat(mlkem_top): KeyGen stage 2d (forward NTT of s/e)
Add ST_N stage: forward NTT (ntt_core mode=0, no scaling) of s[0],s[1],
e[0],e[1] in place (slots S0,S1,E0,E1). Per slot: stream 256 coeffs into
ntt_core during LOAD, collect 256 outputs back to same slot. n_pending
waits for core IDLE between slots.

Verified vs ml-kem-r golden: 1024/1024 shat/ehat coeffs exact (17318 cyc).
2026-06-28 01:47:54 +08:00
2f206a6bc5 feat(mlkem_top): KeyGen stages 2a-2c (G, SampleNTT A_hat, CBD s/e)
Fresh valid/ready KeyGen FSM for ML-KEM-512 (K=2, eta1=3). Independent
keccak per consumer (no arbiter). Verified stage-by-stage vs ml-kem-r golden:
- 2a G(d||K): rho/sigma exact (d byte0-low, K at byte32, no reversal).
- 2b SampleNTT: A_hat[i][j] from seed rho||j||i, 1024/1024 coeffs exact.
- 2c CBD: s[i]=CBD3(PRF(sigma,i)), e[i]=CBD3(PRF(sigma,K+i)); signed->mod-q
  (+Q when negative); 2048/2048 (A+s+e) coeffs exact.

polymem register array (10 slots x 256), debug readback tap (dbg_slot/idx ->
coeff, rho/sigma taps) for stage TBs. a_busy/c_busy guards (defensive after
sample_ntt fix). FSM: IDLE->G->A->C->DONE (datapath extended in later stages).

Plan + progress doc in .claude/plans/keygen_plan.md.
2026-06-28 01:41:44 +08:00
1cace51649 delete mlkem_top 2026-06-27 03:20:52 +08:00
5e0ba7ad77 fix(tb): strict numerical pass/fail — FSM completion without value match now counts as FAIL 2026-06-27 01:46:35 +08:00
0e6798beb5 feat(tb): add KAT testbench for mlkem_top (ML-KEM-512)
- gen_vectors.py: parse kat_MLKEM_512.rsp, generate hex vectors
- tb_mlkem_top_xsim.v: force-inject d/msg/z for KAT testing
- mlkem_top_input.hex: 5 vectors (d + msg + z)
- mlkem_top_expected.hex: 5 vectors (pk + sk + ct + ss)
- xsim_run.tcl: full dependency chain compilation

Known issue: mlkem_top FSM has combinational race on rng_valid_i
- rng_valid_i driven by state_r (registered) causes rng_sync
  to miss valid_i pulse when state transitions at posedge
- Fix: change rng_valid_i to use state_next pattern
  (same as sha3_top uses state_next for kc_valid_i)
2026-06-27 01:07:34 +08:00