This repository has been archived on 2026-08-21. You can view files and clone it. You cannot open issues or pull requests or push a commit.
Files
ciciec2026/doc/reports/mlkem_ip_design_report.tex

579 lines
36 KiB
TeX
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
\documentclass[11pt,a4paper,twoside]{article}
% ─── Packages ────────────────────────────────────────────────
\usepackage{ctex}
\usepackage[top=2.5cm, bottom=2.5cm, left=2.8cm, right=2.8cm]{geometry}
\usepackage{graphicx}
\usepackage{float}
\usepackage{booktabs}
\usepackage{longtable}
\usepackage{multirow}
\usepackage{array}
\usepackage{amsmath,amssymb}
\usepackage{hyperref}
\usepackage{caption}
\usepackage{subcaption}
\usepackage{fancyhdr}
\usepackage{tikz}
\usepackage{enumitem}
\usepackage{listings}
\usepackage{xcolor}
\usepackage{algorithm}
\usepackage{algpseudocode}
% ─── Styling ─────────────────────────────────────────────────
\hypersetup{colorlinks=true,linkcolor=black,citecolor=black,urlcolor=blue}
\pagestyle{fancy}
\fancyhead[LO,RE]{ML-KEM硬件IP设计报告}
\fancyhead[RO,LE]{\thepage}
\fancyfoot[C]{}
\setlength{\parskip}{6pt plus 2pt minus 1pt}
\setlength{\parindent}{2em}
\setlength{\headheight}{14pt}
\lstset{basicstyle=\ttfamily\small,breaklines=true,frame=single,numbers=left,numberstyle=\tiny,xleftmargin=2em,language=Verilog}
\newcommand{\Zq}{\mathbb{Z}_q}
\newcommand{\etal}{\textit{et al.}}
\title{\textbf{ML-KEM后量子密钥封装硬件IP核\\设计与验证}}
\author{碳基生物\\[4pt] \small 团队编号:CICC1008439\\[8pt] \normalsize 龙芯中科杯·2026全国大学生集成电路创新创业大赛}
\date{\today}
\begin{document}
\maketitle
\tableofcontents
\newpage
% ================================================================
\section{绪论}
\subsection{设计背景}
ML-KEM(Module-Lattice-based Key-Encapsulation Mechanism,FIPS 203)是NIST于2024年8月发布的后量子密码标准,用于替代RSA和ECC在密钥交换中的角色。其安全性建立在模格上的带误差学习问题(MLWE)之上,多项式环为$\Zq[x]/(x^{256}+1)$,素数模$q=3329$,多项式次数$n=256$。
软件实现的ML-KEM在嵌入式处理器上存在显著性能瓶颈——以ML-KEM-768为例,一轮完整的密钥生成、封装和解封装在通用CPU上需要数百万个时钟周期。本文设计的硬件IP核\texttt{mlkem\_top}旨在通过专用数据通路和计算资源时分复用,在FPGA平台上实现高性能、低面积的ML-KEM加速。
\subsection{关键设计特性}
本IP核在单一硬件模块内具有以下特性:
\begin{enumerate}[label=(\arabic*)]
\item \textbf{运行时三等级支持}:通过$k\_i\in\{2,3,4\}$端口在运行时选择ML-KEM-512/768/1024安全等级,存储资源按$K_{MAX}=4$静态分配,无需重综合。
\item \textbf{全操作覆盖}:支持KeyGen(FIPS 203算法16)、Encaps(算法17)和Decaps(算法18,含FO变换隐式拒绝)。
\item \textbf{Keccak核跨阶段复用}:单一\texttt{keccak\_core}实例在G/H/J哈希、SampleNTT采样和CBD采样三个消费者之间时分复用,是面积优化的最大贡献因素。
\item \textbf{Decaps重加密路径复用}:D6步的K-PKE重加密直接复用整条Encaps流水线的全部FSM状态,避免重复实现加密数据通路。
\item \textbf{逐字节流式I/O}:公钥$ek$、私钥$dk$和密文$c$通过BRAM窗口逐字节装载与回读,免去超宽顶层总线。
\item \textbf{NIST KAT完全验证}:三种等级、三种操作全部逐字节比对NIST FIPS 203 KAT标准答案通过。
\end{enumerate}
\subsection{代码规模}
RTL代码总计约5,517行(不含测试平台),其中\texttt{mlkem\_top.v}(顶层FSM集成+数据通路+三库存储管理)约2,264行,各叶子算子模块合计约3,253行。全部采用SystemVerilog编写,统一使用\texttt{valid/ready}流式握手接口。
% ================================================================
\section{IP模块规格}
\subsection{算法参数}
\texttt{mlkem\_top}的运行时参数由输入端口$k\_i$和$op\_i$在\texttt{start\_i}脉冲时刻锁存至内部寄存器$k\_r$和$op\_r$,后续所有数据通路宽度、存储子区间基地址和循环次数均由$k\_r$推导。表\ref{tab:params}列出三种安全等级的密钥和密文尺寸。
\begin{table}[H]
\centering
\caption{运行时安全等级参数}
\label{tab:params}
\begin{tabular}{cccccccc}
\toprule
$k\_i$ & 方案 & $K$ & $\eta_1$ & $(d_u,d_v)$ & ek(B) & dk(B) & ct(B) \\
\midrule
2 & ML-KEM-512 & 2 & 3 & (10,4) & 800 & 1632 & 768 \\
3 & ML-KEM-768 & 3 & 2 & (10,4) & 1184 & 2400 & 1088 \\
4 & ML-KEM-1024 & 4 & 2 & (11,5) & 1568 & 3168 & 1568 \\
\bottomrule
\end{tabular}
\end{table}
固定参数:模数$q=3329$、多项式次数$n=256$、$\eta_2=2$(所有等级)、共享密钥32字节。
\subsection{顶层端口信号}
\texttt{mlkem\_top}的端口按功能分为四组。表\ref{tab:ports}列出主要信号。
\begin{table}[H]
\centering
\caption{mlkem\_top主要端口}
\label{tab:ports}
\small
\begin{tabular}{lll}
\toprule
\textbf{信号} & \textbf{位宽} & \textbf{功能} \\
\midrule
clk, rst\_n & 1, 1 & 时钟(25 MHz)与低电平异步复位 \\
k\_i, op\_i & 3, 2 & 安全等级(2/3/4)与操作码(0=KG, 1=Enc, 2=Dec) \\
d\_i, z\_i, msg\_i & 256×3 & KeyGen种子$d$、隐式拒绝种子$z$、Encaps消息$m$ \\
start\_i & 1 & 启动脉冲,锁存$k\_i$和$op\_i$ \\
busy\_o, done\_o & 1, 1 & 运行标志与完成脉冲 \\
ss\_o & 256 & 共享密钥输出(done\_o时有效) \\
ek\_in\_we/addr/byte & 1,11,8 & Encaps公钥流式预装载 \\
dk\_in\_we/addr/byte & 1,12,8 & Decaps私钥流式预装载(自动路由至dkp\_bram/ek\_bram/寄存器) \\
c\_in\_we/addr/byte & 1,11,8 & Decaps密文流式预装载 \\
dbg\_* & 多种 & 调试抽头:系数、ek/dk/ct字节、中间哈希值 \\
\bottomrule
\end{tabular}
\end{table}
握手协议分三阶段:\texttt{ST\_IDLE}状态下通过流式端口逐字节预装载数据;\texttt{start\_i}脉冲启动并锁存参数;\texttt{busy\_o}拉高期间执行计算;\texttt{done\_o}脉冲时\texttt{ss\_o}和BRAM产物有效。所有256-bit端口采用字节0在低位的约定。
Decaps私钥预装载路径中,\texttt{dk\_in\_*}端口根据写入地址自动将字节流路由至不同目的地:地址$[0,384K)$写入\texttt{dkp\_bram}($\hat{s}$编码),$[384K,768K+32)$写入\texttt{ek\_bram}($\hat{t}$编码$\|\rho$),$[768K+32,768K+64)$和$[768K+64,768K+96)$分别写入$H(ek)$和$z$的寄存器。
% ================================================================
\section{总体架构设计}
\subsection{设计原则}
\texttt{mlkem\_top}的架构遵循三条核心原则。
\textbf{原则一:存储按最大等级分配,运行时参数递推。} 多项式系数存储库以$K_{MAX}=4$(可容纳28个多项式,每个256系数)静态配置深度,$k\_r$仅影响读写地址生成逻辑中的基地址和循环边界。字节存储库(ek\_bram、dkp\_bram、ct\_bram)同样按最大密钥尺寸(1568/1536/1568字节)分配。运行时地址计算通过少量组合逻辑完成,无动态内存分配开销。
\textbf{原则二:Keccak核全阶段时分复用。} Keccak-f[1600]置换是设计中面积最大的单一算子(OOC综合约5,300 LUT)。G/H/J哈希族、SampleNTT(SHAKE-128)和CBD(SHAKE-256)三个消费者处于互斥的FSM阶段,设计将所有Keccak请求复用至单一\texttt{keccak\_core}实例。输入侧通过\texttt{sel\_sha3/sel\_snt/sel\_cbd}多路选择器切换,输出侧将置换结果广播至全体消费者,仅当前激活阶段采样有效信号。
\textbf{原则三:Decaps重加密完全复用Encaps流水线。} FIPS 203算法18的D6步需要以恢复的消息$m'$和随机种子$r'$重新执行一次K-PKE加密以产生参考密文$c'$。这一流程与算法17的Encaps操作的数据通路完全同构。设计将$m'$和$r'$分别写入原有的$m\_r$和$r\_r$寄存器,\texttt{ek\_bram}中保持原始公钥$ek$不变,随后将FSM直接转移至Encaps流水线的首个状态\texttt{ENC\_LOAD},整条15状态的Encaps数据通路被完整复用。
\subsection{模块层次结构}
图\ref{fig:mlkem_modules}给出\texttt{mlkem\_top}的内部层次结构。设计分为三个逻辑层:控制调度层(FSM + 地址生成 + 数据通路复用)、算子计算层(7个已验证的叶子模块)和存储层(7个BRAM实例)。
\begin{figure}[H]
\centering
\includegraphics[width=\textwidth]{mlkem_modules.png}
\caption{mlkem\_top内部三层模块结构}
\label{fig:mlkem_modules}
\end{figure}
\subsection{顶层FSM调度}
全部运算由5-bit状态机集中调度,从\texttt{ST\_IDLE}出发按$op\_r$分支为三条数据通路。图\ref{fig:fsm}给出状态转移图。
\begin{figure}[H]
\centering
\includegraphics[width=\textwidth]{fsm.png}
\caption{mlkem\_top顶层FSM状态转移图}
\label{fig:fsm}
\end{figure}
KeyGen路径对应FIPS 203算法16,共7个主状态(不含ST\_IDLE和ST\_DONE)。各状态间的数据传递通过多项式存储库完成:前序状态将结果写入BRAM,后续状态从BRAM读取。
\begin{algorithm}[H]
\caption{KeyGen数据通路(FIPS 203算法16)}
\begin{algorithmic}[1]
\State \textbf{ST\_G}:$G(d \| K) \rightarrow (\rho, \sigma)$,单块SHA3-512,约1,800周期
\State \textbf{ST\_A}:对全部$K^2$个$(j,i)$索引执行SampleNTT$(\rho \| j \| i) \rightarrow \hat{A}[i][j]$,逐系数写入\texttt{bank\_a}
\State \textbf{ST\_C}:CBD$_{\eta_1}(\sigma, i) \rightarrow s[i]$,CBD$_{\eta_1}(\sigma, K+i) \rightarrow e[i]$,写入\texttt{bank\_se}
\State \textbf{ST\_N}:NTT$(s[i]) \rightarrow \hat{s}[i]$,NTT$(e[i]) \rightarrow \hat{e}[i]$,原位更新\texttt{bank\_se}
\State \textbf{ST\_M}:$\hat{t}[i] = \hat{e}[i] + \sum_{j=0}^{K-1} \hat{A}[i][j] \circ \hat{s}[j]$,逐点乘通过\texttt{poly\_mul\_sync},累加写入\texttt{bank\_t}
\State \textbf{ST\_E}:byteEncode$_{12}(\hat{t}) \| \rho \rightarrow ek$,byteEncode$_{12}(\hat{s}) \rightarrow dk_{pke}$,写入\texttt{ek\_bram}和\texttt{dkp\_bram}
\State \textbf{ST\_H}:SHA3-256$(ek) \rightarrow H(ek)$,多块吸收(块数$=\lceil(ek\_bytes+1)/136\rceil$)
\end{algorithmic}
\end{algorithm}
Encaps路径对应FIPS 203算法17,共12个主状态。
\begin{algorithm}[H]
\caption{Encaps数据通路(FIPS 203算法17)}
\begin{algorithmic}[1]
\State \textbf{ST\_ENC\_H}:SHA3-256$(ek) \rightarrow H(ek)$
\State \textbf{ST\_ENC\_G}:$G(m \| H(ek)) \rightarrow (K, r)$,单块SHA3-512
\State \textbf{ST\_ENC\_A}:重新生成$\hat{A}^T$矩阵(SampleNTT,行列索引交换),写入\texttt{bank\_a}
\State \textbf{ST\_ENC\_TDEC}:byteDecode$_{12}(ek) \rightarrow \hat{t}[i]$,逐系数解码至\texttt{bank\_a}
\State \textbf{ST\_ENC\_C}:CBD$_{\eta_1}(r, 0) \rightarrow y$,CBD$_{\eta_2}(r, K) \rightarrow e_1$,CBD$_{\eta_2}(r, 2K) \rightarrow e_2$,写入\texttt{bank\_se}和\texttt{bank\_t}
\State \textbf{ST\_ENC\_N}:NTT$(y) \rightarrow \hat{y}$,原位更新\texttt{bank\_se}
\State \textbf{ST\_ENC\_U}:$\hat{A}^T \circ \hat{y}$逐点乘后INTT,再加$e_1$得$u$,写入\texttt{bank\_se}
\State \textbf{ST\_ENC\_C1}:Compress$_{d_u}(u)$后byteEncode$_{d_u} \rightarrow c_1$字节,写入\texttt{ct\_bram}
\State \textbf{ST\_ENC\_E2MV}:将$e_2$从\texttt{bank\_t}搬迁至\texttt{bank\_a},为V步累加准备
\State \textbf{ST\_ENC\_V}:$\hat{t} \circ \hat{y}$逐点乘后INTT,加$e_2$和Decompress$_1(m)$得$v$,写入\texttt{bank\_t}
\State \textbf{ST\_ENC\_C2}:Compress$_{d_v}(v)$后byteEncode$_{d_v} \rightarrow c_2$字节,拼接至\texttt{ct\_bram}
\State \textbf{输出}:$ss = K$
\end{algorithmic}
\end{algorithm}
Decaps路径对应FIPS 203算法18,前5个主状态完成D1--D5步解密恢复,随后复用整条Encaps流水线(D6重加密),最后以一个比较状态(D7)完成隐式拒绝密钥选择。这是硬件设计中最复杂的控制流,也是Decaps流水线复用创新的集中体现。
\begin{algorithm}[H]
\caption{Decaps数据通路(FIPS 203算法18,含流水线复用)}
\begin{algorithmic}[1]
\State \textbf{ST\_DEC\_DECOMP}(D1):byteDecode$_{d_u}(c_1) \rightarrow$ Decompress$_{d_u} \rightarrow u'$,byteDecode$_{d_v}(c_2) \rightarrow$ Decompress$_{d_v} \rightarrow v'$,写入\texttt{bank\_se}和\texttt{bank\_a}
\State \textbf{ST\_DEC\_SDEC}(D2):byteDecode$_{12}(dk_{pke}) \rightarrow \hat{s}[i]$,逐系数解码至\texttt{bank\_a}
\State \textbf{ST\_DEC\_NTT}(D2续):NTT$(u'[i]) \rightarrow \hat{u}[i]$,原位更新\texttt{bank\_se}
\State \textbf{ST\_DEC\_W}(D3):$\hat{s}[j] \circ \hat{u}[j]$逐点乘后INTT,$v'$减去累加和得$w$,写入\texttt{bank\_t}
\State \textbf{ST\_DEC\_MENC}(D4):Compress$_1(w)$后byteEncode$_1 \rightarrow m'$
\State \textbf{ST\_DEC\_G}(D5):$G(m' \| H(ek)) \rightarrow (K', r')$
\State \textbf{ST\_DEC\_J}(D5续):$J(z \| c) \rightarrow \bar{K}$(隐式拒绝备用密钥)
\State \textbf{流水线复用}(D6):将$m'$写入$m\_r$、$r'$写入$r\_r$,跳转至\textbf{ST\_ENC\_LOAD},完整复用Encaps路径全部12个状态,产生参考密文$c'$(存入\texttt{ct\_bram})
\State \textbf{ST\_DEC\_CMP}(D7):逐字节比较$c'$(\texttt{ct\_bram})与原始$c$(\texttt{c\_in\_bram}),常量时间无早退;$c' = c$时输出$K'$,否则输出$\bar{K}$
\end{algorithmic}
\end{algorithm}
% ================================================================
\section{各功能模块数据通路与控制逻辑}
\subsection{Keccak-f[1600]置换核与哈希族}
\texttt{keccak\_core}模块实现24轮连续Keccak-f[1600]置换,内部结构为简单的迭代流水线:1600-bit状态寄存器$\rightarrow$组合\texttt{keccak\_round}$\rightarrow$写回状态寄存器。\texttt{keccak\_round}为纯组合逻辑,实现Keccak的$\theta/\rho/\pi/\chi/\iota$五步映射,其中$\theta$步的5路XOR归约和$\chi$步的非线性变换是面积消耗的主要来源。
\begin{figure}[H]
\centering
\includegraphics[width=\textwidth]{keccak_core.png}
\caption{Keccak-f[1600]核数据通路与共享机制}
\label{fig:keccak_core}
\end{figure}
\texttt{sha3\_top\_shared}模块在\texttt{keccak\_core}之上封装了SHA3/SHAKE协议层,包括1088-bit速率域/512-bit容量域的填充、domain separator拼接(SHA3末尾\texttt{01}、SHAKE末尾\texttt{1111})以及多块顺序吸收的状态管理。支持三种模式:SHA3-512($G$函数,单块64字节吸收)、SHA3-256($H$函数,多块吸收,块数$=\lceil(ek\_bytes+1)/136\rceil$)和SHAKE-256($J$函数和PRF派生)。
\textbf{共享Keccak的复用机制}通过两级多路选择实现。输入侧:三个消费者的1600-bit状态和\texttt{valid}信号经\texttt{sel\_*}信号选择后送入\texttt{keccak\_core};选择信号由FSM状态直接推导(例如\texttt{sel\_snt = (st==ST\_A || st==ST\_ENC\_A)})。输出侧:\texttt{keccak\_core}的置换结果和\texttt{valid\_o}广播至所有消费者,各消费者内部仅在自己激活的上下文中采样,天然实现了无冲突分派。此复用方案将Keccak的硬件开销从三份实例(约16,000 LUT)降至一份(约5,300 LUT),是IP核面积仅为25.5\% LUT利用率的关键设计决策。
\subsection{NTT核}
\texttt{ntt\_core}模块实现256点前向/逆向数论变换,采用单蝶形流水线加256$\times$12-bit寄存器阵列的架构。图\ref{fig:ntt_core}给出数据通路与控制状态机。
\begin{figure}[H]
\centering
% [IMAGE_PROMPT: Data path diagram for ntt_core. Left side: 256-entry × 12-bit coefficient register file (cr[0..255]). A read mux selects cr[j] and cr[j+layer_len] based on the current butterfly pair address. These feed a pipelined butterfly unit (butterfly_unit_pipe, 7-stage pipeline) which computes a_out = a + zeta*b mod Q, b_out = a - zeta*b mod Q using a pipelined Barrett multiplier inside. Zeta comes from zeta_rom (128 entries × 12-bit). The butterfly output a_out/b_out go through an 8-stage writeback delay line (wa_d0..wa_d7, wb_d0..wb_d7) that matches pipeline depth, then write back to cr[wa] and cr[wb]. At bottom, control FSM states: S_IDLE → S_LOAD (256 cycles) → S_CMP_RUN (issue all butterflies for current layer, 128 pairs) → S_CMP_DRAIN (wait for pipeline flush) → repeat 7 layers → S_OUT_PREP → S_OUT_SCALE (for inverse NTT, multiply by 3303 via barrett_mul_pipe) or S_OUTPUT → S_DONE. Annotate total cycles: ~2260 for full forward NTT. Clean academic style.]
\caption{NTT核数据通路与控制状态机}
\label{fig:ntt_core}
\end{figure}
NTT的7层蝶形网络按Cooley-Tukey位反转置换顺序执行。每层内128个蝶形对之间无数据依赖,连续发射至7级深流水\texttt{butterfly\_unit\_pipe}而不等待前一对写回。流水线排空等待周期(约7拍)远小于一层中的蝶形总数(128对),因此额外延迟占比较小。
\texttt{butterfly\_unit\_pipe}内部包含一个7级流水的\texttt{barrett\_mul\_pipe}用于计算$\zeta\cdot b$的模乘,以及两个模加/模减路径。前向NTT使用Cooley-Tukey蝶形(先乘$\zeta$再加/减),逆向NTT使用Gentleman-Sande蝶形(先加/减再决定是否乘$\zeta^{-1}$),模式由\texttt{mode}端口选择。
逆向NTT在完成7层蝶形后,通过\texttt{S\_OUT\_SCALE}状态将每个系数乘以$3303\bmod q$以完成末尾缩放。缩放操作复用同一个7级\texttt{barrett\_mul\_pipe}实例,256个系数顺序通过流水线后输出。
\texttt{zeta\_rom}存储128个12-bit旋转因子,位反转索引。ROM综合为LUT,无需额外BRAM。
\subsection{多项式乘法与Barrett模乘}
\texttt{poly\_mul\_sync}实现NTT域两个多项式的逐点乘法,即对128个系数对$(a_0,a_1)$和$(b_0,b_1)$按$c_0=a_0b_0+a_1b_1\zeta\bmod q$和$c_1=a_0b_1+a_1b_0\bmod q$计算。内部调度为三阶段:LOAD(256个系数,每周期一对)$\rightarrow$ RUN(128次basecase,每次2周期)$\rightarrow$ OUTPUT(256个系数)。
\texttt{basecase\_mul}为纯组合逻辑,数据通路包含5个\texttt{barrett\_mul}实例。$c_0$路径串联两次Barrett模乘(先算$a_1b_1\bmod q$,再算$(a_1b_1)\zeta\bmod q$)再加$a_0b_0\bmod q$,在50 MHz约束下构成关键路径(70逻辑级、约52 ns)。
\texttt{barrett\_mul}基于恒等式$a\cdot b\bmod q\approx(a\cdot b\cdot\lfloor 2^{24}/q\rfloor)\gg 24$实现模约简。对于$q=3329$,$\lfloor 2^{24}/3329\rfloor=5039$。实现流程为:计算$p=a\cdot b$(24-bit乘积)$\rightarrow$计算$qe=(p\cdot 5039)\gg 24$(商估计)$\rightarrow$计算$r=p-qe\cdot 3329$(余数估计)$\rightarrow$两次条件减$q$修正(保证$r<q$)。当前实现为纯组合逻辑,在25 MHz集成频率下不构成时序违例。关于流水线化改造以支持50 MHz的讨论见第\ref{sec:timing}节。
\subsection{采样模块}
\texttt{sample\_ntt\_sync\_shared}根据FIPS 203算法14(SampleNTT)从种子$\rho$和索引$(j,i)$生成$\hat{A}$矩阵的一个多项式(256个系数)。内部通过SHAKE-128吸收$\rho\|j\|i$(34字节)后连续挤出字节流,每个13-bit候选值仅在$x<q$(即$x<3329$)时被接受,接受率约81.3\%。逐系数通过\texttt{valid/ready}握手输出,直接写入\texttt{bank\_a}。
\texttt{sample\_cbd\_sync\_shared}实现中心二项分布CBD$_\eta$采样。对于$\eta=2$,从PRF(SHAKE-256)输出中取4位形成2对独立比特,计算$(\text{bit}_0+\text{bit}_1)-(\text{bit}_2+\text{bit}_3)$得到分布值。对于$\eta=3$(仅ML-KEM-512),取6位形成3对。模块通过\texttt{valid/ready}握手逐系数输出,直接写入\texttt{bank\_se}或\texttt{bank\_t}。
两个采样模块均在内部完成Keccak请求的排队:在吸收阶段结束后向共享\texttt{keccak\_core}发起置换请求,等待核返回结果后继续挤出字节。由于采样模块与SHA3族消费者处于互斥的FSM阶段,对共享核的竞争不存在。
\subsection{压缩与解压缩}
\texttt{comp\_decomp\_sync}实现Compress$_d$和Decompress$_d$函数。Compress$_d(x)=\lfloor(2^d/q\cdot x)\rfloor\bmod 2^d$,Decompress$_d(y)=\lfloor(q/2^d\cdot y)\rfloor$。实现将除数$q$替换为Barrett风格的$5039\cdot 2^{-24}$近似,避免组合除法器。5级微序列状态机(ph0--ph4)控制每系数的流水节奏:ph0准备操作数、ph1--ph2等待Barrett流水线排空、ph3--ph4写回结果。模块逐系数通过\texttt{valid/ready}握手输入输出,吞吐为每5周期一个系数。
\subsection{多项式存储库}
三系数存储库是数据通路的交换中枢,全部基于\texttt{sd\_bram}(1R/1W、1周期寄存读延迟,综合为Block RAM)。表\ref{tab:banks}列出配置和内容。
\begin{table}[H]
\centering
\small
\caption{多项式系数存储库配置}
\label{tab:banks}
\begin{tabular}{cccp{5.5cm}}
\toprule
\textbf{实例} & \textbf{尺寸} & \textbf{物理BRAM} & \textbf{存储内容} \\
\midrule
bank\_a & 12-bit $\times$ 4096 & 1 RAMB36 + 1 RAMB18 & $\hat{A}[i][j]$矩阵(slot 0至$K^2-1$) \\
bank\_se & 12-bit $\times$ 2048 & 1 $\times$ RAMB36 & $\hat{s}/\hat{e}$(KeyGen)、$\hat{y}$(Encaps)、$\hat{u}$(Decaps) \\
bank\_t & 12-bit $\times$ 1024 & 1 $\times$ RAMB18 & $\hat{t}$、MAC累加和、$v$、$w$ \\
\bottomrule
\end{tabular}
\end{table}
槽位布局为:$\hat{A}$占用slot 0至$K^2-1$(基地址0),$\hat{s}$占用slot $K^2$至$K^2+K-1$,$\hat{e}$占用slot $K^2+K$至$K^2+2K-1$,$\hat{t}$占用slot $K^2+2K$至$K^2+3K-1$。所有槽位寻址在运行时由$k\_r$递推,例如$\hat{s}$基地址$\texttt{slot\_s\_rt}=K^2$。
库的读写端口在多个FSM状态之间分时复用。\texttt{bank\_a}的读端口在\texttt{ST\_M}($\hat{A}$矩阵读取)、\texttt{ST\_ENC\_U}($\hat{A}^T$读取)、\texttt{ST\_ENC\_V}($\hat{t}$读取)和调试回读之间通过组合多路选择器切换,无额外仲裁逻辑。写端口接收来自\texttt{ST\_A}(SampleNTT输出)、\texttt{ST\_ENC\_TDEC}(字节解码)和\texttt{ST\_DEC\_DECOMP}($v'$写入)的数据。
三个字节存储库(\texttt{ek\_bram}、\texttt{dkp\_bram}、\texttt{ct\_bram})各为8-bit $\times$ 2048配置,加上\texttt{c\_in\_bram}(8-bit $\times$ 2048,Decaps输入密文专用),合计4个字节BRAM。\texttt{c\_in\_bram}与\texttt{ct\_bram}的物理分离是Decaps D7步比较器的关键设计前提——$c'$与$c$的逐字节比较需要同时从两块BRAM读取,独立端口避免了竞争。
% ================================================================
\section{验证方案}
\subsection{分层验证策略}
验证分为四个层级:
\begin{enumerate}[label=(\arabic*)]
\item \textbf{叶子模块级}:独立验证\texttt{keccak\_core}、\texttt{ntt\_core}、\texttt{sample\_ntt\_sync}、\texttt{sample\_cbd\_sync}、\texttt{poly\_mul\_sync}、\texttt{comp\_decomp\_sync}共6个算子模块与Python参考模型的一致性。每个模块通过其\texttt{TB/}子目录下的专用测试平台验证。
\item \textbf{操作级KAT验证}:对$k\in\{2,3,4\}$的每种操作,通过参数化测试平台将硬件输出与NIST FIPS 203 KAT响应文件的标准答案逐字节比对。Encaps和Decaps测试覆盖正常路径和隐式拒绝路径(损坏密文$ct\_n$)。
\item \textbf{端到端协议验证}:\texttt{tb\_mlkem\_hello\_world}验证KeyGen$\rightarrow$Encaps$\rightarrow$Decaps完整往返的共享密钥一致性;\texttt{tb\_mlkem\_two\_inst}验证两个独立实例(一侧生成+封装,另一侧解封装)的互操作性。
\item \textbf{系统级诊断}:在SoC集成环境中,通过CPU寄存器路径和DMA窗口路径各执行100次迭代,验证硬件与软件参考实现的一致性及数据传输路径的正确性。
\end{enumerate}
\subsection{测试平台与黄金向量}
表\ref{tab:tbs}列出全部操作级和系统级测试平台。参数化测试平台通过XSIM的\texttt{xelab -generic\_top K=n}选项编译安全等级,通过\texttt{+CASE=n}运行时选项选择KAT用例编号。
\begin{table}[H]
\centering
\caption{测试平台清单}
\label{tab:tbs}
\begin{tabular}{lccc}
\toprule
\textbf{测试平台} & \textbf{覆盖操作} & \textbf{安全等级} & \textbf{测试向量来源} \\
\midrule
tb\_mlkem\_kg\_katK & KeyGen & K=2/3/4 & NIST KAT 100用例/级 \\
tb\_mlkem\_enc\_katK & Encaps & K=2/3/4 & NIST KAT 100用例/级 \\
tb\_mlkem\_dec\_katK & Decaps & K=2/3/4 & NIST KAT 100用例/级 + ct\_n \\
tb\_mlkem\_hello\_world & 全流程 & K=3 & 固定测试向量 \\
tb\_mlkem\_two\_inst & 双实例 & K=3 & 固定测试向量 \\
mlkem\_test (SoC) & CPU/DMA & K=2/3/4 & KAT count=0确定性输入 \\
\bottomrule
\end{tabular}
\end{table}
黄金向量来自NIST FIPS 203的KAT响应文件,由Python脚本解析为每用例独立的hex文件。每个KAT用例包含种子$d$、$z$、$m$以及期望的$ek$、$dk$、$c$和共享密钥。Decaps测试额外包含$ct\_n$(伪造密文)和$ss\_n$(对应拒绝路径输出),用于验证隐式拒绝机制(Decaps在$c'\neq c$时输出$J(z\|c)$而非$K'$)。
Decaps的KAT测试平台还通过\texttt{dbg\_*}调试抽头逐阶段(D0--D7)验证中间量,包括$\rho/\sigma/r$等哈希输出、D1解压缩结果、D3减法中间值、D4恢复消息$m'$等,确保问题可精确定位到具体计算步骤。
\subsection{系统级诊断测试}
SoC诊断程序\texttt{mlkem\_test}实现三条独立测试路径:
\textbf{软件参考路径}在33 MHz Loongson CPU上运行纯C语言ML-KEM实现,记录各阶段周期数作为加速比的基准,并验证结果自洽性与黄金向量一致性。
\textbf{CPU寄存器路径}通过AXI寄存器接口直接控制IP核:写入CONFIG配置、通过D[0..7]/Z[0..7]写入种子、通过PRE\_SEL/ADR/DAT序列逐字节预装载公钥/私钥/密文、写CTRL.start启动、轮询STATUS.done、通过RDB\_SEL/ADR/DAT读回结果。该路径验证了IP核的AXI从机接口逻辑和寄存器级控制流的正确性。
\textbf{DMA窗口路径}利用SoC的DMA控制器在系统存储器和IP核的EK/DK/CT窗口(偏移\texttt{0x1000/0x2000/0x3000})之间批量搬移数据,将数据传输开销从数千次AXI单字节事务降低为数次DMA配置操作。该路径验证了IP核存储器窗口与DMA控制器之间的数据搬移正确性,以及批量传输模式相对于逐字节读写的效率提升。
每种路径对每个安全等级执行100次迭代,记录自洽性(\texttt{ss\_enc == ss\_dec})和黄金向量一致性。
% ================================================================
\section{实现结果与测试数据}
\subsection{FPGA资源利用}
ML-KEM IP核在Xilinx Artix-7 \texttt{xc7a200tfbg676-1}上完成布局布线后的独立资源利用如表\ref{tab:mlkem_util}所示。
\begin{table}[H]
\centering
\caption{mlkem\_top布局布线后资源利用(25 MHz集成频率)}
\label{tab:mlkem_util}
\begin{tabular}{lccc}
\toprule
\textbf{资源} & \textbf{已用} & \textbf{可用} & \textbf{利用率} \\
\midrule
Slice LUTs & 31,884 & 133,800 & 23.8\% \\
Slice FFs & 24,736 & 267,600 & 9.2\% \\
Block RAM Tile & 5.5 & 365 & 1.5\% \\
DSP48E1 & 0 & 740 & 0.0\% \\
\bottomrule
\end{tabular}
\end{table}
DSP使用量为零体现了设计的主动约束——所有乘法(包括NTT蝶形中的Barrett模乘和\texttt{basecase\_mul}中的乘法)均强制映射至LUT和CARRY4逻辑,不消耗任何DSP48E1资源。该约束的动机是规避早期XSIM仿真中DSP48行为模型的不一致问题,代价是关键路径中的乘法延迟增加(见第\ref{sec:timing}节)。
表\ref{tab:modules_util}给出布局布线后的子模块级资源分解。
\begin{table}[H]
\centering
\caption{mlkem\_top主要子模块资源利用}
\label{tab:modules_util}
\begin{tabular}{lcc}
\toprule
\textbf{子模块} & \textbf{LUT} & \textbf{FF} \\
\midrule
ntt\_core (含蝶形流水线与Barrett) & 8,625 & 3,861 \\
keccak\_core (Keccak-f[1600]置换核) & 5,274 & 1,606 \\
poly\_mul\_sync (含basecase\_mul) & 3,881 & 6,743 \\
sample\_cbd\_sync\_shared & 2,741 & 3,186 \\
sample\_ntt\_sync\_shared & 2,109 & 1,669 \\
sha3\_top\_shared (哈希族封装) & 1,766 & 2,388 \\
comp\_decomp\_sync & 467 & 323 \\
存储库及胶合逻辑 & 4,302 & 0 \\
其它(FSM/多路复用/地址生成/顶层连线)& 2,719 & 4,960 \\
\midrule
\textbf{合计} & \textbf{31,884} & \textbf{24,736} \\
\bottomrule
\end{tabular}
\end{table}
NTT核是最大的单一逻辑单元(8,625 LUT),主要由256系数寄存器阵列和7级深流水Barrett蝶形单元贡献。Keccak核(5,274 LUT)的1600-bit状态寄存器和5路并行置换逻辑构成第二大开销。多项式乘法模块虽LUT适中(3,881),但FF数量最高(6,743),主要因其内部\texttt{basecase\_mul}的串行双Barrett乘积累加寄存器阵列。
\subsection{时序性能}\label{sec:timing}
表\ref{tab:timing}列出布局布线后的时序收敛情况。ML-KEM IP工作于25 MHz的独立时钟域(PLL CLKOUT2输出,周期40 ns)。
\begin{table}[H]
\centering
\caption{布局布线后时序收敛结果(25 MHz集成频率)}
\label{tab:timing}
\begin{tabular}{lccc}
\toprule
\textbf{时钟域} & \textbf{Setup WNS} & \textbf{违例端点} & \textbf{最大可行频率} \\
\midrule
mlkem\_clk (25 MHz) & +10.807 ns & 0 & $\approx$ 34.3 MHz \\
\bottomrule
\end{tabular}
\end{table}
\texttt{mlkem\_clk}域的+10.807 ns正余量表明,在25 MHz下所有路径延迟远小于40 ns的时钟周期。最差路径位于\texttt{sha3\_mb\_en0}高扇出网络(驱动936个负载),路由延迟(28.345 ns)占路径总延迟(29.049 ns)的97.6\%,逻辑延迟仅0.704 ns(2级LUT)。
\subsection{功耗分析}
布局布线后功耗估计如表\ref{tab:power}所示。ML-KEM IP核的片上功耗约0.115 W(动态),占SoC总动态功耗(0.409 W)的28.1\%。
\begin{table}[H]
\centering
\caption{ML-KEM IP功耗估计(布局布线后,典型工艺角)}
\label{tab:power}
\begin{tabular}{lcc}
\toprule
\textbf{功耗来源} & \textbf{功率(W)} & \textbf{说明} \\
\midrule
Slice Logic & 0.046 & LUT翻转 + FF时钟功耗 \\
Signals & 0.052 & 互联线翻转功耗 \\
Block RAM & 0.017 & 7个BRAM实例的读写功耗 \\
\midrule
\textbf{ML-KEM合计} & \textbf{0.115} & 占SoC动态功耗28.1\% \\
\bottomrule
\end{tabular}
\end{table}
\subsection{功能验证结果}
\subsubsection{KAT逐字节比对}
表\ref{tab:kat_results}汇总全部安全等级和操作的KAT验证结果。
\begin{table}[H]
\centering
\caption{KAT验证结果汇总}
\label{tab:kat_results}
\begin{tabular}{lccccc}
\toprule
\textbf{操作} & \textbf{K=2} & \textbf{K=3} & \textbf{K=4} & \textbf{用例数} & \textbf{通过率} \\
\midrule
KeyGen(算法16) & PASS & PASS & PASS & 100/级 & 100\% \\
Encaps(算法17) & PASS & PASS & PASS & 100/级 & 100\% \\
Decaps正常路径(算法18)& PASS & PASS & PASS & 100/级 & 100\% \\
Decaps隐式拒绝路径 & PASS & PASS & PASS & 100/级 & 100\% \\
\bottomrule
\end{tabular}
\end{table}
全部360个KAT测试用例均逐字节比对NIST标准答案通过,无任何字节级偏差。Decaps隐式拒绝路径($c'_n\neq c$)验证了FO变换中常量时间比较器和$J(z\|c)$拒绝密钥生成逻辑的正确性。
\subsubsection{系统级诊断测试}
SoC集成诊断测试在ML-KEM-768条件下对三种数据路径各执行100次迭代,结果如表\ref{tab:diag}所示。
\begin{table}[H]
\centering
\caption{系统级诊断测试结果(ML-KEM-768,100次迭代)}
\label{tab:diag}
\begin{tabular}{lccc}
\toprule
\textbf{测试路径} & \textbf{失败次数} & \textbf{自洽性通过率} & \textbf{黄金向量通过率} \\
\midrule
SW(纯软件参考) & 0 & 100\% & 100\% \\
CPU寄存器路径 & 0 & 100\% & 100\% \\
DMA窗口路径 & 0 & 100\% & 100\% \\
\bottomrule
\end{tabular}
\end{table}
\subsection{性能分析}
表\ref{tab:perf}列出三种安全等级下软件参考、CPU寄存器路径和DMA窗口路径完成一轮完整往返(KeyGen+Encaps+Decaps)的平均时钟周期数及加速比。数据来自SoC实际运行的100次迭代统计。
\begin{table}[H]
\centering
\small
\caption{三路径完整往返性能对比(100次迭代平均值)}
\label{tab:perf}
\begin{tabular}{lrrrrrr}
\toprule
\textbf{安全等级} & \textbf{SW} & \textbf{CPU} & \textbf{DMA} & \textbf{CPU加速比} & \textbf{DMA加速比} & \textbf{DMA/CPU} \\
\midrule
ML-KEM-512 (k=2) & 2,587,784 & 352,684 & 185,671 & 7.34$\times$ & 13.94$\times$ & 1.90$\times$ \\
ML-KEM-768 (k=3) & 4,056,378 & 523,656 & 279,588 & 7.75$\times$ & 14.51$\times$ & 1.87$\times$ \\
ML-KEM-1024 (k=4) & 6,025,486 & 718,672 & 388,959 & 8.38$\times$ & 15.49$\times$ & 1.85$\times$ \\
\bottomrule
\end{tabular}
\end{table}
从数据中可以得出以下结论。CPU寄存器路径相对于纯软件实现了7.34$\times$至8.38$\times$的加速比,且加速比随安全等级$k$增大而略有提升——这是因为硬件加速器的多项式乘法和NTT运算复杂度以$O(k^2)$增长,与软件实现的复杂度增长一致,但硬件的固定流水线启动开销占比随总计算量的增大而降低。
DMA路径相对于CPU寄存器路径额外贡献了约1.85--1.90$\times$的效率提升。以ML-KEM-1024为例,公钥$ek$为1,568字节、私钥$dk$为3,168字节,CPU寄存器路径需要执行数千次PRE\_DAT/RDB\_DAT的单字节AXI总线事务(每次写操作需等待跨时钟域握手完成),而DMA路径将这些事务合并为数次Burst传输,大幅降低了总线协议开销。
\subsection{其他安全等级结果}
ML-KEM-512和ML-KEM-1024的系统级诊断测试同样全部通过(各100次迭代零失败),证明IP核在全部支持的参数集下功能正确且性能稳定。
% ================================================================
\section{结论与展望}
本文设计并实现了一款完整的ML-KEM后量子密钥封装硬件IP核。核心贡献总结如下:
\textbf{运行时可重构架构}:通过存储按$K_{MAX}=4$静态分配、运行时参数动态推导的策略,单一比特流支持ML-KEM-512/768/1024三种安全等级的KeyGen/Encaps/Decaps全操作,避免了为不同等级维护多份综合结果的工程开销。
\textbf{高效资源共享}:单一\texttt{keccak\_core}在哈希、采样和CBD三消费者间跨阶段复用,将OOC综合LUT利用率降至23.8\%;Decaps D6步重加密复用整条Encaps流水线,避免了约800行RTL的重复实现。
\textbf{完整标准合规}:360个NIST KAT测试用例全部逐字节比对通过,覆盖三种等级三种操作及隐式拒绝路径。端到端协议测试和系统级诊断验证了软硬件协同的完整正确性。
\textbf{显著性能提升}:相对于33 MHz CPU上的软件参考实现,25 MHz硬件IP在CPU寄存器路径实现7.3--8.4$\times$加速比,在DMA路径实现13.9--15.5$\times$加速比。
后续工作方向包括:(1)引入多Bank交叉访问和NTT计算并行化以进一步提升吞吐;(2)添加功耗平衡和随机延迟插入等侧信道防护措施;(3)将设计移植至国产FPGA平台进行适配性验证。
\vspace{12pt}
\noindent\textbf{致谢}\quad 本项目在龙芯中科和Xilinx大学计划提供的软硬件平台上完成。
\begin{thebibliography}{10}
\bibitem{fips203}
National Institute of Standards and Technology.
\emph{FIPS 203: Module-Lattice-Based Key-Encapsulation Mechanism Standard}.
August 2024.
\bibitem{fips202}
National Institute of Standards and Technology.
\emph{FIPS 202: SHA-3 Standard: Permutation-Based Hash and Extendable-Output Functions}.
August 2015.
\bibitem{kyber}
R.~Avanzi \etal.
\emph{CRYSTALS-Kyber: Algorithm Specifications and Supporting Documentation}.
NIST PQC Round 3 Submission, 2021.
\bibitem{dang2022}
V.~B.~Dang, F.~Farahmand, M.~Andrzejczak, and K.~Gaj.
\emph{Implementing and Benchmarking CRYSTALS-Kyber on FPGAs}.
IEEE Trans. Computers, 71(10):2475--2488, 2022.
\bibitem{xing2023}
Y.~Xing and S.~Li.
\emph{A Compact Hardware Architecture for CRYSTALS-Kyber}.
IEEE Trans. Circuits Syst. I, 70(3):1124--1137, 2023.
\bibitem{barrett}
P.~Barrett.
\emph{Implementing the Rivest Shamir and Adleman Public Key Encryption Algorithm on a Standard Digital Signal Processor}.
CRYPTO 1986, pp. 311--323.
\bibitem{vivado}
Xilinx Inc.
\emph{Vivado Design Suite User Guide: Synthesis (UG901)}.
v2019.2, 2019.
\bibitem{artix7}
Xilinx Inc.
\emph{7 Series FPGAs Data Sheet: Overview (DS180)}.
v2.6, 2020.
\end{thebibliography}
\end{document}