fix(sample_ntt,sha3): FIPS-203 SHAKE-128 squeeze + self-checking sha3 TBs

sample_ntt was non-conformant: both RTL and the test reference re-ran
keccak_p after every 3-byte squeeze instead of consuming the full
1344-bit SHAKE-128 rate. Only coeff[0] matched a standard sampler, so
the generated A matrix would not interoperate with any compliant ML-KEM.

- sample_ntt_sync{,_shared}.v: walk all 56 groups of the rate block via
  grp_ptr_r; re-permute only when the block is exhausted. Verified
  256/256 against ml-kem-r Rust sample_ntt on two seeds, and 1536/1536
  in the Verilator framework (runtime ~128x faster per poly).
- gen_vectors.py: use a self-contained hashlib.shake_128 oracle.

sha3 testbench fixes (all now self-check hash_o against verified vectors,
cross-checked with hashlib and ml-kem-r mlkem_G):
- tb_sha3_xsim_simple.v: test G/H/J modes, not just G.
- tb_keccak_core_xsim.v: correct the wrong EXPECTED_STATE constant
  (RTL was correct; lane0 = 0xf1258f7940e1dde7 per FIPS 202).
- tb_sha3_xsim.v: read expected file and self-check per vector; add
  vectors/g_basic_{input,expected}.hex (3 G / 2 H / 2 J).

Remove stale sha3_chain test (its RTL was deleted in 1cace51) and its
README references. Extend .gitignore for XSIM artifacts and result dumps.
This commit is contained in:
2026-06-27 17:23:28 +08:00
parent 5d86000231
commit 4d7ce69405
12 changed files with 318 additions and 295 deletions

View File

@@ -33,8 +33,6 @@ mlkem/
│ │ ├── keccak_round.v # Single Keccak-f round (θ,ρ,π,χ,ι)
│ │ ├── keccak_core.v # 24-round sequential Keccak-f[1600] core
│ │ └── sha3_top.v # SHA3-512(G)/SHA3-256(H)/SHAKE-256(J) wrapper
│ ├── sha3_chain/ # G function for key generation
│ │ └── sha3_chain_top.v # SHA3-512 chain: G(d||k=2) → rho, sigma
│ ├── rng/ # Pseudorandom number generator
│ │ └── rng_sync.v # 256-bit Galois LFSR (taps: 255,253,252,247,0)
│ ├── ntt/ # Number Theoretic Transform
@@ -157,7 +155,7 @@ export LD_PRELOAD=/usr/lib64/libtinfo.so.5 # ncurses fix for 2019.2 on modern L
# Run all modules
for m in mod_add rng poly_arith comp_decomp storage \
sha3_chain ntt poly_mul sample_cbd sample_ntt; do
ntt poly_mul sample_cbd sample_ntt; do
./run_tb.sh "$m"
done
```
@@ -236,7 +234,6 @@ A single Keccak-f[1600] permutation engine is shared across all SHA-3/SHAKE modu
| `poly_mul_sync` | 512×coeff → 256×coeff | ~300 cycles | NTT-domain poly multiply |
| `comp_decomp_sync` | coeff_in[11:0], d[4:0] → coeff_out | 1 cycle | Compress/Decompress |
| `sha3_top` | data_i[511:0], mode → hash_o[511:0] | ~24 cycles | SHA3/SHAKE |
| `sha3_chain_top` | d_in[255:0], start → rho, sigma | ~24 cycles | G function |
| `sample_cbd_sync` | seed[255:0], nonce, eta → 256×coeff | ~300 cycles | CBD sampling |
| `sample_ntt_sync` | rho[255:0], k,i,j → 256×coeff | ~4000 cycles | SampleNTT |
| `s_bram` | rd/wr addr, data | 1 cycle | Single-port BRAM |
@@ -248,7 +245,6 @@ A single Keccak-f[1600] permutation engine is shared across all SHA-3/SHAKE modu
|--------|:---:|:---:|:---:|
| sha3_top | ✅ | ✅ | PASS |
| keccak_core | — | ✅ | PASS |
| sha3_chain_top | ✅ | ✅ | PASS |
| rng_sync | ✅ | ✅ | PASS |
| mod_add_sync | ✅ | ✅ | PASS |
| ntt_core | ✅ | ✅ | PASS |