# ML-KEM Keccak、SHA3 与采样模块技术说明 ## 1. Keccak-f[1600] 置换核 `keccak_core` 保存 1600 位状态,并调用组合 `keccak_round` 每周期执行一轮 Keccak-f[1600]。轮函数包含 theta、rho、pi、chi 和 iota 五个步骤,轮常数由 5 位轮计数 选择。默认执行 24 轮,输入在 `valid_i && ready_o` 时装载,最后一轮结果通过 `valid_o/ready_i` 交付;接收端反压时保持最终状态。 该结构只实例化一份 1600 位轮函数,单次置换约需 24 个计算周期,面积主要来自宽 XOR、 移位布线和 chi 非线性逻辑。它不是 24 轮完全展开的单周期实现,也不是每周期接收一个 新状态的深流水实现。 本文件中的 Keccak、SHA3/SHAKE、SampleNTT 和 CBD 均位于 `mlkem_clk` 域。共享接口是 同一时钟域内的 valid/ready 复用,不是 CDC。SYS--ML-KEM 跨域终止于外层 AXI 前端。 ## 2. SHA3/SHAKE 协议层 `sha3_top_shared` 在置换核外实现吸收、填充、多块状态累积和输出提取。单块模式支持 KeyGen 使用的 G、SHA3-256 H、SHAKE-256 J,以及对完整 64 字节消息执行的 SHA3-512 G。 模块依据模式选择 576 位或 1088 位 rate,并加入 SHA3 或 SHAKE 域分隔后执行 pad10*1。 多块模式面向长度随安全等级变化的公钥哈希。调用方预先构造 1088 位 rate block,并用 `mb_last_i` 标记最终块。模块将新块异或到累计 sponge 状态,调用共享 Keccak,最后从 低 256 位提取摘要。多块状态在一次消息结束前保持,不会在块间重新初始化。 ML-KEM 顶层以状态机选择当前 Keccak 消费者。SHA3、SampleNTT 和 CBD 在算法调度上互斥, 因此可以共享一个置换核;若未来引入跨状态并行,必须增加显式仲裁和每个消费者独立的 sponge 上下文,不能继续依赖状态互斥假设。 ## 3. SampleNTT 拒绝采样 `sample_ntt_sync_shared` 实现 FIPS 203 SampleNTT。模块吸收 32 字节 rho 以及行列索引 `j,i`,形成 34 字节 SHAKE-128 输入。挤出字节流按每 3 字节拆成两个 12 位候选值,只有 候选值小于 q=3329 时才输出。模块持续采样直到产生 256 个有效系数。 输出使用 `coeff_valid_o/coeff_ready_i` 握手,反压时保持当前系数和索引。拒绝采样的运行 周期依赖候选值分布,因此系统 FSM 依据有效系数计数结束,而不是使用固定延迟。对固定 rho 和索引,输出必须与软件 SampleNTT 逐系数一致。 ## 4. 中心二项分布采样 `sample_cbd_sync_shared` 使用 SHAKE-256 PRF 生成伪随机字节,再实现 CBD_eta。eta=2 时, 每个系数消耗 4 bit,计算两组 2 bit 的汉明重量差;eta=3 时,每个系数消耗 6 bit,计算 两组 3 bit 的汉明重量差。ML-KEM-512 的 eta1 为 3,其余等级的 eta1 为 2,eta2 始终为 2。 CBD 输出转换到模 q 表示后,以 valid/ready 逐系数写入系数 Bank。当前优化版本对 CBD 输出到 Bank 写入路径增加寄存,以缩短组合路径;地址和有效信号必须与该流水级同步延迟。 ## 5. 共享接口约束 三个消费者向共享 Keccak 提供状态、valid 和 ready。选择信号由 ML-KEM 主状态直接推导, 未选中的消费者不能认为广播输出属于自己。消费者内部必须只在活动上下文采样 `kc_valid_o`。复位需要同时清除 Keccak busy、各 sponge 状态、候选字节缓存和输出计数, 否则下一次请求可能继承前一消息状态。 ## 6. 验证方法 Keccak 应使用标准空消息和多块测试向量逐 bit 比较。SHA3/SHAKE 层应覆盖 rate 边界前后 的消息长度、域分隔和多块最后一块填充。SampleNTT 应比较全部 256 个系数并统计拒绝 候选数;CBD 应覆盖 eta=2/3、输出反压和连续请求。顶层 KAT 通过能够发现大部分功能错误, 但叶子级握手、边界填充和共享仲裁仍需要独立测试平台验证。