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
038ba8ecf2
fix(kg): byte-reverse d_reg before sha3_chain to match FIPS 203
...
RTL was feeding d bytes in reversed order to SHA3-512,
causing G(d) to produce wrong rho/sigma. Fix: add d_rev
wire with byte reversal, connect to sha3_chain_top_shared.
2026-06-27 03:01:34 +08:00
3284aa443f
fix(kg): implement t_hat computation and pk/sk output in mlkem_top
...
- Add s_hat0_reg/s_hat1_reg for s_hat capture during CBD→NTT output
- Add tmul_accum register for poly_mul result accumulation
- Implement S_KG_TMUL_MUL_LD: load A+s coefficients into poly_mul
- Implement S_KG_TMUL_MUL_WAIT/ACCUM: accumulate A·s products
- Implement S_KG_TMUL_ADD_E: add e_hat to accumulated sum
- Assign pk_o_r = {t_hat1, t_hat0}_reg and sk_o_r = {s_hat1, s_hat0}_reg
- Shift Encaps/Decaps FSM states by +3
KeyGen: 5/5 vectors complete in ~47K cycles/op
2026-06-27 01:38:38 +08:00
03b4707879
feat(top): add shared keccak variants, arbiter, and mlkem_top integration
...
- sha3_chain_top_shared.v: external keccak_core interface (6 ports)
- sample_cbd_sync_shared.v: shared keccak variant (6 ports)
- sample_ntt_sync_shared.v: shared keccak variant (6 ports)
- keccak_arbiter.v: fixed-priority arbiter for 3 keccak consumers
- mlkem_top.v: 1403-line monolithic FSM with KeyGen/Encaps/Decaps
Architecture:
keccak_arbiter → keccak_core → keccak_round (shared)
sha3_chain_top_shared (consumer 0)
sample_cbd_sync_shared (consumer 1)
sample_ntt_sync_shared (consumer 2)
sha3_top (separate, own keccak_core)
rng_sync, ntt_core, poly_arith, poly_mul, comp_decomp, mod_add
sd_bram for polynomial storage
All original RTL files preserved unchanged.
2026-06-26 03:35:37 +08:00