半年前有客户问我:公司手里那把用于长期数据加密的证书密钥,申请一次要用好几年,要不要现在就把算法换成后量子加密(PQC)?我当时没敢拍胸脯。回来后我花了几个星期,把权威标准组织陆续公开的后量子密码学标准化文件翻了个遍,把候选算法的参考实现跑了个遍,最后干脆拿了块带ARM硬核的FPGA开发板,把其中最典型的一个密钥封装算法从数学公式一路写到了RTL代码,完整复现了一遍。这篇文章就是这次调研与复现项目的全程记录。
文章覆盖三块内容:一是后量子密码学目前的算法版图和选型逻辑,二是如何在FPGA上把以ML-KEM为代表的核心计算单元跑起来,三是硬件实现过程中那些软件工程师永远遇不到的坑。想入坑PQC、做密码硬件加速、或者打算把设备密钥体系升级到抗量子方案的读者,这篇文章可以直接当参照系。
1. 为什么是现在:量子威胁倒计时与PQC调研起点
1.1 Shor算法到底撕开了多大的口子
要说PQC为什么突然从学术圈冲到工程圈,绕不开Shor算法。1994年Shor提出用量子计算机在多项式时间内分解大整数之后,RSA这类基于大整数分解困难性的公钥体系就在数学层面被判了死刑。椭圆曲线密码也好不到哪去,因为椭圆曲线离散对数问题同样被Shor算法覆盖。注意我说的是数学层面,不是现实层面——目前没人造出一台能稳定运行几千个逻辑量子比特的机器,所以在座的RSA-2048短期内依然安全。但问题恰恰出在"短期"这个词上。
公钥密码体系有一个经常被忽略的隐含假设:秘密存续期。证书私钥、长寿命密钥、档案加密密钥,很多数据需要保密十年、二十年甚至更长。如果今天有人把密文截获,等十多年后量子计算机成熟后再解密,那今天部署的系统就等于白部署了。这就是业界常说的"现在收割,以后解密"(harvest now, decrypt later)。对有长期保密需求的数据来说,威胁不是未来的,而是当下的。调研时我反复跟团队强调:别只盯着量子计算机哪年造出来,要先看自己的数据哪年必须解密。
1.2 标准化窗口已关闭,工程迁移窗口才刚刚打开
另一个更现实的推动力是标准化。权威标准组织在2024年正式发布了几份后量子密码标准:FIPS 203(ML-KEM,密钥封装)、FIPS 204(ML-DSA,数字签名)、FIPS 205(SLH-DSA,无状态哈希签名),随后又补了FN-DSA相关标准。标准的落地意味着算法设计竞赛阶段结束,工程适配阶段开始。操作系统、浏览器、加密库已经在逐步加入混合模式——也就是经典算法和后量子算法同时使用、只有两者一起被攻破才失效。这个趋势非常明确,越晚动手,存量系统的迁移包袱就越重。
所以我调研的第一个体会是:PQC已经不是"要不要做"的问题,而是"什么时候做、从哪开始做"的问题。真正留给工程师的是迁移顺序问题。先把哪些资产保护起来、哪些链路先换、怎么保证过渡期兼容,这些问题比算法本身更影响落地节奏。
1.3 调研范围怎么收敛:算法多,但真正要复现的只有一个
PQC候选算法从最早的几十个收敛到现在的几个标准,背后的数学基础分了好几派:格、编码、多变量、哈希。最终进入标准的主要是格基和哈希两类。格基算法又分两路:做密钥封装的ML-KEM,以及做签名的ML-DSA和FN-DSA,哈希签名SLH-DSA走的是完全不同的保守路线。
调研时不要平均用力。我把火力集中在ML-KEM上,理由有三:第一,它是TLS混合模式里预期最先大规模部署的组件;第二,它的模块格结构在硬件上非常规整,适合FPGA实现;第三,它涉及到的NTT(数论变换)和Keccak恰好是FPGA实现里最有含金量的两个计算单元。把这两个单元啃下来,后面再看其他格基算法都会轻松很多。
2. 算法版图梳理:密钥封装三兄弟与一套曲线救国组合
2.1 ML-KEM(Kyber):模块格上的密钥封装
ML-KEM的前身是Kyber,属于Module-LWE(模块格)方案。看不懂数学没关系,先把骨架记住——它做的是一件事:让双方在没有预先共享秘密的情况下,通过公钥协商出一个只有双方知道的会话密钥。KEM是"密钥封装机制"的缩写,你可以把它理解成"一次性密码信封":发送方拿公钥封装一个随机生成的会话密钥,接收方用私钥解封装。它和传统TLS里的协商不太一样,不需要来回多个握手轮,逻辑更简单。
具体到参数:多项式环是R_q = Z_q[x]/(x^256+1),这里q=3329,n=256。每个多项式有256个系数,每个系数是0到3328之间的整数。安全级别靠模块维度k区分:ML-KEM-512的k=2、ML-KEM-768的k=3、ML-KEM-1024的k=4。密钥生成过程可以简单理解为:生成一个随机的小系数秘密向量s,再从种子扩展出一个公开矩阵A,计算b = A·s + e,其中e是精心设计的小噪声。公钥是(A, b),私钥是s。攻击者拿到(A, b)要恢复s,等于在格上求解带噪声的线性方程组——这就是LWE问题的困难本质。
为什么带噪声的方程难解?生活化类比:你在一张表格里知道每一行是某些列值的线性组合,但每个结果都被一个"几毛钱的小误差"污染了。小误差单看无所谓,但列数一多,可能的组合数量爆炸,每个组合都对应一个几乎相同的表格,攻击者无法分辨哪一个是真秘密。格密码的安全性恰恰来自"区分最接近的解"的难度。
2.2 签名三件套:ML-DSA、SLH-DSA、FN-DSA怎么选
签名方面,ML-DSA(Dilithium)和ML-KEM同出一门,都是模块格,性能均衡,适合作为主力签名。FN-DSA(Falcon)的优势是签名尺寸小,但实现复杂度高,需要处理浮点数和NTRU格,更适合对带宽敏感的封闭系统。SLH-DSA(SPHINCS+)则彻底抛弃格,安全性只依赖哈希函数的性质,属于最保守的选择,代价是签名和性能都不好看。
工程上常用组合是:正常流量用ML-DSA,重要的长期资产用SLH-DSA做交叉备份。签名不同于密钥封装,不是二选一的关系,可以根据场景混用,这也是PQC落地时比较灵活的一点。
2.3 规格速查表与选择逻辑
| 算法 | 标准化名称 | 数学基础 | 类型 | 突出特点 | 通常场景 |
|---|---|---|---|---|---|
| Kyber | ML-KEM | 模块格 | 密钥封装 | 密钥密文小、性能好 | TLS、证书、加密会话 |
| Dilithium | ML-DSA | 模块格 | 数字签名 | 综合性能均衡 | 通用签名、代码签名 |
| Falcon | FN-DSA | NTRU格 | 数字签名 | 签名尺寸最小 | 带宽受限场景 |
| SPHINCS+ | SLH-DSA | 哈希函数 | 数字签名 | 保守、无结构 | 长期资产、密钥备份 |
| RSA/ECC | — | 数论/椭圆曲线 | 混合过渡 | 已成熟 | 与PQC混合过渡期 |
这套表是调研后给团队做选型用的,最终结论是:如果只选一个算法开始工程适配,选ML-KEM;如果只选一个签名,选ML-DSA;SLH-DSA作为长期备份。这个结论直接指导了后面FPGA复现的选题——先啃ML-KEM这颗硬骨头。
3. FPGA复现选型:为什么要用硬件把算法"焊"一遍
3.1 三个说服自己的理由
很多人一听说调研PQC,第一反应是跑个Python脚本或者C参考实现就够了,为什么非得上FPGA?我当时的想法有三层。
第一,PQC真正的大规模应用场景不一定是PC和服务器,而是嵌入式设备、网关、工业控制器、车机这一类算力和内存都紧张的地方。这些设备目前大量依赖专用密码引擎,算法迁移时必须在硬件上验证,不能只靠软件模拟。第二,软件实现把算法关键性能藏在内存带宽和CPU指令流水线里,FPGA实现能逼着你把存储布局、乘法器数量、关键路径一个个摆到桌面上来,理解深度完全不一样。第三,FPGA能接入真实物理环境做功耗和侧信道评估,这是软件库给不了的。
第三个理由在调研时显得尤为重要。PQC算法虽然是新面孔,但硬件实现中的侧信道风险一点没少——功耗曲线、电磁辐射、指令时序都可能泄露私钥信息。FPGA上可以做可控的电源噪声注入和电磁探头测量,这套环境在普通软件运行环境里根本搭不出来。
3.2 硬件平台与开发环境
开发板选了一块带ARM硬核的中端FPGA板,逻辑规模大概覆盖几万LUT,板载UART、若干开关和指示灯。ARM核负责接收上位机指令、通过UART把测试向量和种子灌进来,可编程逻辑部分只留一个简洁的计算核。开发环境用的是主流FPGA厂商的综合工具,RTL语言用Verilog。
为什么选这个组合?因为调试DDR和复杂总线太费时间,PQC核心计算单元只需要几十KB存储,双端口BRAM足够,ARM只是当个"高级串口控制器",把我从繁琐的PC通信中解放出来。这也是给没接触过FPGA的读者一个建议:不要迷信高端板卡,先看算法需求,再看接口需求,最后看调试复杂度。ML-KEM这个量级的算法,一块中端板子完全够用。
3.3 实现范围:只做核心引擎,不做完整产品
项目没有把完整的ML-KEM-768握手流程做成产品级引擎,而是聚焦三件事:第一,跑通密钥生成、封装、解封装三个主流程;第二,重点验证模多项式乘法和Keccak这两个热点模块;第三,对外开放状态观测接口方便调试和教学。这个边界一开始就定好,后面少走很多弯路。
如果一开始就想做"全流程+旁路安全+多通道并发",大概率会因为调试复杂度失控而卡壳。先把边界切小,把核心模块的质量做扎实,后面扩展才有基础。
4. 系统顶层架构:从串口数据到三块BRAM再到状态机
4.1 模块划分:六个模块,各管一摊
顶层框架按数据流划分了六个模块:通信接口、顶层控制器、存储管理器、NTT加速核、Keccak核、多项式运算单元。
通信接口最简单,就是把ARM软核发过来的数据按包格式拆开,存成seed、公钥、密文等测试输入。顶层控制器是一个细粒度状态机,负责把密钥生成、封装、解封装三大流程翻译成一系列存储读写和计算指令。存储管理器不直接让计算单元访问物理RAM,而是通过一组带读写valid/ready信号的接口来管理,这样既方便仿真,也方便后面换DDR或者加内存隔离。
Keccak核是PQC的"配角但主角"——ML-KEM的矩阵A生成、哈希函数、随机数扩展全都靠它。NTT加速核和多项式运算单元是真正的算力核心,一次多项式乘法打包成正变换-点乘-逆变换三步。所有大数运算走到乘法单元后都统一经过流水线蝶形算子。这个架构几乎没有为特定算法做过度的定制,后续换参数集或者改算法映射都比较容易。
4.2 存储布局:12比特系数和双端口带宽
存储布局早期设计时吃过亏,多讲几句。ML-KEM-768需要维护k×k矩阵(k=3)的多项式,也就是9个多项式;每个多项式256个系数,一个系数12比特。按单系数12比特算,一个多项式需要384字节,9个约3.5KB。板载36Kb(约4.5KB)的块RAM单块就能放下这些,实际用了几块双端口BRAM。
为什么用双端口?因为蝶形运算每个周期需要同时读两个系数,写完结果还要让另一个端口继续输出给下级处理,单端口会卡死流水线。
还有一个实用教训:系数位宽不要图省事按16比特存。12比特才是有效位宽,按16比特存会白占三分之一带宽。算带宽时严格按12比特计,BRAM的读写使能按字节拼接。前几版为了省事统一按16比特,结果内存带宽差了25%,改回12比特后性能立竿见影。对FPGA来说,BRAM带宽往往比逻辑资源更紧缺,位宽设计从一开始就要抠。
4.3 主状态机:八个状态走完一个流程
主状态机定义了八个状态,按顺序走:IDLE、LOAD_SEED、EXPAND_A、NTT_WS、POINTWISE、INTT_WT、PACK、DONE。每个状态做的事很专一。
比如EXPAND_A是从种子出发用Keccak生成矩阵A的系数,NTT_WS是对秘密向量s做正变换,POINTWISE则是在NTT域做逐项乘加,INTT_WT做逆变换回到普通域。状态之间用一组completion信号握手,避免出现一拍没对准就全盘错乱的情况。所有的中间系数都缓存在BRAM工作区,不额外加通用寄存器堆——寄存器堆在这种密集数据流场景里是浪费。
这里值得说明为什么用状态机而不用微代码或软核:状态机每个跳转都是确定性的,时序容易收敛,验证简单。对于ML-KEM这种流程固定的算法,状态机是最不容易出错的实现方式。ARM软核只负责通信和结果回传,计算流程不依赖它,路径很干净。
5. 核心计算单元解剖:NTT蝶形、模约减与Keccak
5.1 多项式乘法为什么是性能命门
ML-KEM的安全性建立在格上,工程性能却几乎全部押在多项式乘法上。一个多项式有256个系数,直接做教科书卷积需要65536次乘加——看起来不算多,但密钥生成、封装、解封装要反复做很多次,而且每次乘加之后还要做模3329约减。如果直接做,光约减涉及的除法就要占掉大部分周期。
NTT就是来解决这个问题的:它把多项式转到频域,两个多项式乘法变成逐项点乘,再做一次逆变换。复杂度从O(n²)降到O(n log n),对n=256来说大概是8倍差距。更重要的是,NTT之后所有系数固定在某个域内,模约减可以统一用一个乘法加一个移位替代除法,硬件实现非常友好。
Kyber的q=3329专门选成了满足q≡1 mod 256的素数,这意味着x^256+1在模q的多项式环上能完全分解,可以直接做256点NTT而不需要额外补零。实际参考实现还把256点NTT拆成两层,用128个二次因子迭代完成,硬件上表现为一组组小的蝶形级联。这个性质不是巧合,是算法设计时为了让硬件和软件都能高效实现特意选的。复现PQC时多留意这类参数选择,会让实现思路清晰很多。
5.2 蝶形运算单元:一乘两加,流水线要细抠
NTT的核心算子是蝶形运算:
a' = a + ζ·b (mod q) b' = a - ζ·b (mod q)其中ζ是预计算的旋转因子。硬件上只需要一个乘法器加两个加减法器就能实现一个蝶形。我最初的实现是每四个周期完成一组蝶形,流水线分四段:取系数、乘法、约减、加减。后来发现乘法器和约减器的组合逻辑深度是瓶颈,改成六级流水后频率从150MHz提到180MHz,有效吞吐反而提升。
代码骨架大致如下:
module butterfly_unit #( parameter Q = 3329 ) ( input wire clk, input wire valid_in, input wire [11:0] a_in, input wire [11:0] b_in, input wire [11:0] zeta_in, output reg valid_out, output reg [11:0] a_out, output reg [11:0] b_out ); // 流水线第一级:乘法 reg [23:0] prod_reg; always @(posedge clk) begin if (valid_in) prod_reg <= b_in * zeta_in; end // 第二级:Barrett约减 wire [11:0] prod_mod = barrett_reduce(prod_reg); // 第三级:加减 always @(posedge clk) begin if (valid_in) begin a_out <= (a_in + prod_mod) % Q; b_out <= (a_in - prod_mod + Q) % Q; end end // valid同步打拍 reg [2:0] valid_delay; always @(posedge clk) valid_delay <= {valid_delay[1:0], valid_in}; assign valid_out = valid_delay[2]; endmodule注意这个骨架为了表达清楚简化了很多细节,真实代码里a_out/b_out必须与valid信号严格同步,而且流水线级数变化时,控制信号也要跟着变化。这就是第7章第一个坑的伏笔。
5.3 Barrett约减:用乘法器替代除法,位宽是命门
模约减在FPGA里的核心问题是如何用乘法器替代除法。我的方案是Barrett约减:预计算常数c = floor(2^16 / 3329),约减时先做一次乘法得到商的高位估计,再做一次乘法和减法得到余数。误差控制在很小的范围内,只要输入范围不超过某个上限,最后一步只需一次条件减法就能把结果拉回[0, 3328]。
这个方案比Montgomery舒服的地方在于,不需要把模数转成特殊形式,也不需要额外的转换因子,系数在每个阶段都可以直接解释为标准值。但位宽必须小心。Barrett约减要求乘法器输出位宽足够容纳高位估计,我最初用的普通乘法器截到高16位,结果在边界情况偶尔丢精度。后来改用完整位宽乘法器,高位估计单独接出来,问题立刻消失。
具体计算公式是:t = a - floor(a·c / 2^16)·q。这个floor操作在硬件里的等价实现是:先做a×c乘法,取结果的高16位作为商估计,再乘以q做减法。因为c≈2^16/q,商估计会有约1的误差,最后补一次条件减法。理解这个误差边界对位宽设计非常重要。
5.4 Keccak核:24轮轮函数,单轮展开最划算
Keccak是SHA-3系列的核心置换,一个f[1600]置换包括24轮,每轮要执行θ、ρ、π、χ、ι五个步骤,处理1600比特的状态。ML-KEM里Keccak承担的角色很重:种子扩展为矩阵A、哈希、XOF都靠它。如果Keccak核太慢,整个密钥生成和封装流程都会拖住。
我选择了单轮展开结构:把一轮的θ/ρ/π/χ/ι组合逻辑写出来,状态寄存器在每个周期载入一轮结果,重复24次完成一次置换。全展开(24轮全部展开)能省循环开销,但LUT消耗大好几倍,频率也难上去,不划算。单轮展开配合状态旁路,Keccak核跑一次SHAKE256大约1.3µs,对整体流程来说够用。
Keccak的旋转偏移表和轮常数是固定查表,这个坑我在第7章详述。这里只提醒一句:直接从规范附件复制,不要凭记忆。
6. 综合结果与实测数据:面积换吞吐的账
6.1 资源和时序报告
综合后的关键数字如下,基于我这版只实现了单路径核心的配置:
| 资源项 | 数量 | 说明 |
|---|---|---|
| LUT | 约12k | 主要是Keccak和NTT逻辑 |
| FF | 约8.7k | 流水线寄存器和状态寄存器 |
| DSP | 6 | 蝶形乘法器,含Barrett相关 |
| BRAM | 6块36Kb | 系数存储与中间工作区 |
| 最大频率 | 180MHz | 关键路径在Keccak轮函数 |
这是单套NTT核、单套Keccak核、主频180MHz的结果。资源不算紧张,但也不能算宽裕,因为Keccak的24轮组合逻辑确实吃资源。如果把Keccak和NTT都做成双实例并行,面积大概翻1.6倍而不是2倍——控制逻辑可以共用,这是并行化时的一个隐藏红利。
6.2 关键流程耗时拆解
用板级测试跑完整ML-KEM-768三流程,实测耗时如下(从ARM收到命令到打印结果的时间,UART开销约2µs可忽略):
| 流程 | 实测耗时 |
|---|---|
| 密钥生成(KeyGen) | 42µs |
| 封装(Encaps) | 64µs |
| 解封装(Decaps) | 85µs |
拆下来看:密钥生成里矩阵A的Keccak扩展约占三分之一,NTT相关计算占二分之一,其余是打包和随机数处理。封装和解封装因为要处理更多参数,Keccak调用次数更多,时间更长。
6.3 与软件实现的对照:FPGA并不"更慢"
对比软件参考实现,普通PC上优化的C版本大致在几十微秒到一百多微秒之间,FPGA这组数据放到资源受限的嵌入式场景里是很有竞争力的。更重要的是这个性能是可预测的、确定性的,没有操作系统调度干扰。对工业控制、车载、网关这类实时性敏感的场合,确定性比峰值性能更值钱。
功耗方面,我实测的核心逻辑功耗在几百毫瓦量级,远低于常见CPU跑软件的功耗。虽然这次没有做精细的DVFS调优,但已经能看出FPGA在PQC场景下的功耗优势。对电池供电的物联网设备来说,这个优势往往比绝对性能更关键。
7. 踩坑实录:流水线错位、约减溢出与上板崩
7.1 蝶形流水线的valid延迟必须同步
第一个坑出现在NTT核联调的时候。单独测蝶形单元,输入输出都正确;单独测NTT的地址生成,访存地址也对;可一旦把两级连起来,输出结果就完全对不上。查了两天,最后把波形拉出来逐周期看才发现问题:蝶形单元里加了流水线寄存器,a_out和b_out比a_in和b_in晚了几拍才出来,但地址生成模块还按"下一拍读下一组系数"在操作,读到的数据完全错位。这是典型的valid延迟不同步问题:数据通路的流水级数变了,控制通路没有跟着变。
解决方式很朴素但通用:给控制信号手动打同样拍数的延迟,保证valid和data在时间上严格对齐。更稳的做法是让地址生成模块把数据请求做成"请求-应答"式的握手,而不是固定时序的"发起-等待",这样流水线任何一级改变深度都不会影响正确性。经过这次之后,我在项目里所有数据通路都强制使用握手信号,再没犯这类错。
7.2 Barrett约减位宽溢出:单测过不了边界
第二个坑是约减偶尔飘。表现为:单测几百组都没问题,跑长流程(密钥生成加封装加解封装)会在随机位置冒出个别系数大于3329。一开始以为是存取的随机性问题,后来把出问题的系数单独拎出来复算,发现每次都是同一个中间多项式里的同一类位置。对照Barrett约减公式细看才明白:常量c约等于19.7,做高位估计时如果乘法结果截断太多,部分输入的商估计偏小,最后的条件减法来不及修正。
解决方法是把乘法器输出完整保留,扩大乘法位宽而不是裁到高16位,或者把条件减法扩展为循环减法。我选了更直接的方案:乘法器输出完整保留,高位估计单独拉出来,极大减小截断误差。改完之后,连续跑了一整夜随机测试向量,零异常。
这个坑给的经验是:模约减这类模块,单测样例再多也顶不上随机长流程;但反过来,调试时又要先构造特定边界值来压测,把最坏情况暴露出来,再跑长流程验证。两个方向都缺一不可。
7.3 Keccak旋转常量记错半个比特,中间状态就全乱
第三个坑有点丢人:Keccak的旋转偏移表我一开始按记忆写,结果反了。Keccak规范里旋转量表的某一行我记错了两个数,单轮置换测不出来,因为很多状态值对错误旋转不敏感;但在跑ML-KEM的向量比对时,扩展出来的矩阵A系数偶尔对不上。最后是用离线参考实现对中间状态逐一比对,定位到某一轮的输出差异,才把表改对。
教训:Keccak的轮常量和旋转表是公认的又长又容易抄错,务必直接从规范文档复制,不要手输,更不要凭记忆。硬件验证里"小错不爆发、爆发难定位"是最贵的,能用离线脚本一个周期跑完的检查不要留给板级调试。
7.4 仿真全过,一上板就随机出错
第四个坑集中在通信和时钟域。RTL仿真里UART、顶层控制器、Keccak全连起来能一次跑通,但板子上一跑就随机丢字节、偶发握手超时。排查过程先怀疑UART波特率微小偏差,用逻辑分析仪抓了波形,发现是ARM发出的读请求在可编程逻辑端偶尔收不到——原因是异步时钟域间的握手信号没有同步。FPGA里两个时钟域的信号直接采,大概率会采到亚稳态。
解决分两步:第一,给所有跨时钟信号加两级同步器;第二,在时序约束里显式声明异步时钟组,把跨时钟路径设为false path,不然工具乱报时序,综合结果也会偏。改完再上板跑,连续十二小时没有一次错误。
仿真过不等于上板过,这个道理做FPGA的都知道,但每次踩到都还是疼。跨时钟域问题尤其隐蔽,因为它在仿真里往往不出现,只有真实硅片上才露出獠牙。
8. 调研结论与后续扩展
8.1 PQC落地比想象的快,但迁移顺序很重要
调研下来我最大的感受是:PQC落地的真实阻力已经不是算法成熟度,而是存量系统的迁移成本。混合模式(经典算法与PQC同时启用)是过渡期的必然选择。TLS场景预计会先动,然后是证书体系、代码签名、固件升级链路。对普通企业来说,先把密钥生命周期管理摸清楚,把哪些资产需要长期保密梳理出来,这个优先级比纠结选Kyber还是Dilithium更现实。
算法本身方面,ML-KEM的优势非常突出,它和现有密码库的接口兼容性也做得很好,工程适配成本比想象中低。签名方面ML-DSA是均衡之选,SLH-DSA则适合作为长期资产的保守备份。这轮调研让我对"什么时候换、先换什么"有了清晰答案。
8.2 如果继续做,我会碰这几个方向
FPGA这个项目还可以往几个方向走:一是把单一NTT核改成多实例并行,用面积换吞吐,适合网关等高并发场景;二是把核心计算单元加上侧信道防护,比如在NTT蝶形上做掩码处理,用FPGA验证防护对性能的影响;三是把经典算法和PQC做成同一个硬核里的混合模式加速单元,这样设备升级时不用换芯片只换逻辑。
我个人接下来最想做的是第三项,因为它更接近真实产品的形态。混合模式的硬件加速器一旦成熟,设备厂商只需要更新比特流,不需要改动电路板,这对存量设备的平滑迁移价值很大。
最后分享一点体会。PQC的数学门槛不高,难的是把一个看起来只是"换算法"的工程问题,拆成算法选型、硬件映射、验证三条线并行推进。FPGA复现的过程逼着我从数学定义一路走到电路时序,这种全局视角是只看文档学不来的。如果你也想做类似的事,我建议从ML-KEM起步,先跑通参考实现,再动手写NTT核,不要一上来就追求完整产品。先让核心计算单元稳定跑起来,再谈优化和扩展,这条路走下来最顺。