4. 性能评估指标体系:定义关键指标

做PQC性能评估,说白了就是回答一个问题:这套算法在我的芯片上跑得动吗?

我见过不少团队,算法选型时只看安全强度,结果移植到IoT设备上,签名生成要3秒,Flash占掉200KB——产品经理当场就炸了。所以,在动手调优之前,咱们得先把“什么是好”定义清楚。

这一章,我就带你梳理PQC在IoT场景下的五个核心指标。每个指标我都会结合项目里踩过的坑来讲,希望能帮你少走弯路。

核心观点:性能评估不是跑个分就完事。你得根据设备类型(MCU还是MPU?电池供电还是插电?)给每个指标设一个“及格线”。没有及格线的评估,都是耍流氓。

4.1 签名/密钥生成时间

这个指标最直观,也最容易测。但要注意,密钥生成和签名生成是两个完全不同的操作,千万别混为一谈。

  • 密钥生成时间:通常只在设备初始化或证书轮换时执行一次。对于电池供电的传感器,这个时间可以放宽到几秒甚至几十秒。但对于需要频繁更换密钥的高安全场景(比如每次会话都生成新密钥),这个时间就必须压到毫秒级。
  • 签名生成时间:这是每次发送数据都要做的操作。比如一个智能电表每15分钟上报一次数据,每次都要签名。如果签名时间超过100ms,就会影响上报频率或导致数据积压。

我个人习惯用循环调用法来测:连续执行100次操作,取平均值。这样可以消除单次测量的抖动。但要注意,第一次调用往往包含初始化开销,建议先“预热”一次再开始计时。

避坑指南:我曾经在测试Dilithium签名时,发现第一次签名比后续签名慢了近10倍。排查了半天,发现是随机数生成器在第一次调用时需要初始化熵池。所以,预热是必须的,否则你的评估数据会严重失真。

4.2 验证时间

验证时间往往比签名时间快一个数量级,但它在IoT场景下同样关键——尤其是固件升级场景。

你想想看,一个网关设备可能要同时验证几十个传感器的签名。如果每个签名验证需要5ms,那还好。但如果验证时间飙到50ms,整个系统的吞吐量就会断崖式下跌。

这里有个容易被忽略的点:验证时间对公钥格式的敏感度。有些算法(如Falcon)的验证时间几乎不受公钥大小影响,而有些算法(如某些基于编码的方案)在公钥较大时,验证时间会显著增加。我在项目中就遇到过,换了个公钥编码方式,验证时间直接降了30%。

算法 签名时间 (ms) 验证时间 (ms) 备注
Dilithium-2 0.8 0.3 适合通用场景
Falcon-512 1.2 0.2 验证极快,签名稍慢
SPHINCS+-128s 12.0 0.5 签名慢,但安全性高

注:以上数据基于Cortex-M4 @ 120MHz 实测,仅供参考。

4.3 内存占用(RAM/Flash)

这是IoT设备最硬的约束。一个典型的MCU可能只有16KB RAM和128KB Flash。而PQC算法的公钥、私钥、签名动辄几千字节,甚至上万字节。

我建议把内存占用拆成两个维度来看:

  • 静态内存:代码段(.text)和常量数据(.rodata)占用的Flash空间。这部分是固定的,编译完就定了。
  • 动态内存:运行时分配的栈和堆空间。这部分取决于算法实现和调用方式。

嗯,这里要注意:栈空间是很多问题的根源。有些PQC算法(比如Falcon的签名过程)会递归调用,栈深度可能达到几KB。如果你的RTOS任务栈只分配了4KB,那基本上一调用就栈溢出。

警告:我曾经在一个项目中,把Falcon移植到FreeRTOS上,结果任务栈从默认的2KB改到8KB才稳定运行。所以,务必在移植后做栈使用量分析。可以用工具(如GCC的 -fstack-usage)或者手动在关键函数入口/出口打标记。

4.4 功耗

对于电池供电的设备,功耗是比性能更重要的指标。但功耗和性能往往是矛盾的:跑得快,功耗就高;跑得慢,功耗就低。

我个人习惯用能量消耗(Energy per Operation)来评估,而不是只看峰值电流。公式很简单:

能量 (μJ) = 平均电流 (mA) × 电压 (V) × 时间 (ms) / 1000

举个例子:一个签名操作耗时10ms,平均电流50mA,电压3.3V,那么能量消耗就是:

50 × 3.3 × 10 / 1000 = 1.65 μJ

这个值可以帮你估算电池寿命。假设你的设备每天签名1000次,电池容量是1000mAh @ 3.7V,那光签名这一项,每天消耗的能量就是:

1.65 μJ × 1000 = 1.65 mJ
电池总能量 = 1000 mAh × 3.7 V × 3600 s = 13,320,000 mJ
理论续航 = 13,320,000 / 1.65 ≈ 8,072,727 天 ≈ 22,117 年

当然,这只是理论值。实际还要考虑待机功耗、通信功耗等。但这个计算至少能帮你判断:签名操作是不是功耗瓶颈。

4.5 吞吐量

吞吐量衡量的是系统在单位时间内能处理多少操作。对于网关或服务器端设备,这个指标尤其重要。

吞吐量通常用每秒签名数(Signatures per Second, SPS)或每秒验证数(Verifications per Second, VPS)来表示。但要注意,吞吐量不是简单的1/延迟。因为你可以用流水线或并行处理来提升吞吐量。

举个例子:一个签名操作需要1ms,但如果你用双核MCU,一个核负责签名,另一个核负责通信,那吞吐量可以接近2倍。但如果你只有一个核,而且签名操作是阻塞的,那吞吐量就是1000 SPS。

我建议在评估吞吐量时,考虑以下因素:

  • CPU占用率:签名操作占用了多少CPU时间?剩下的时间够不够做其他事?
  • DMA/硬件加速:如果算法支持硬件加速(比如AES加速器),吞吐量可能会大幅提升。
  • 并发模型:是单任务顺序执行,还是多任务并行?

小技巧:我在评估吞吐量时,喜欢用“最坏情况下的持续吞吐量”作为基准。因为很多算法在缓存命中时很快,但一旦缓存未命中,性能会急剧下降。用最坏情况来设计系统,才能保证稳定性。

4.6 指标之间的关系与权衡

这五个指标不是孤立的。它们之间存在着复杂的权衡关系。我画了一张图来帮你理解:

PQC性能指标权衡关系图 PQC性能指标权衡关系 PQC算法 签名/密钥生成时间 验证时间 内存占用 功耗 吞吐量 时间 ↔ 内存:通常成反比 (查表快但占Flash大) 功耗 ↔ 时间:跑得快功耗高 (动态电压频率调整可缓解) 吞吐量 ↔ 内存:流水线需要缓冲 (缓冲区越大吞吐越高)

从这张图可以看出,没有完美的算法。你只能在五个指标之间做取舍。比如:

  • 如果你选SPHINCS+,签名时间很长,但验证快、内存占用小、安全性高。
  • 如果你选Falcon,签名和验证都快,但实现复杂、栈空间需求大。
  • 如果你选Dilithium,各方面比较均衡,但公钥和签名尺寸偏大。

所以,我的建议是:先明确你的设备类型和应用场景,再给每个指标设一个“硬上限”。比如:

  • 对于电池供电的传感器:功耗是第一位,签名时间可以放宽到100ms,RAM不超过8KB。
  • 对于网关设备:吞吐量是关键,验证时间必须小于1ms,Flash可以放宽到512KB。
  • 对于固件升级场景:验证时间最重要,因为要验证大文件,签名时间可以忽略。

总结一下:这五个指标——签名/密钥生成时间、验证时间、内存占用、功耗、吞吐量——构成了PQC性能评估的完整框架。每个指标都有其独特的测量方法和注意事项。在实际项目中,你不可能同时优化所有指标,必须根据场景做权衡。下一章,我会带你用具体的工具和脚本,把这些指标一个个测出来。