4. ECC性能瓶颈分析
好,咱们进入正题。上一章我们聊了Ed25519为什么快,这一章反过来,看看传统ECC到底慢在哪。尤其是嵌入式设备上,那个差距简直让人抓狂。
我最早接触ECC是在一个智能门锁项目上。芯片选的是某款Cortex-M0,主频48MHz,RAM只有16KB。当时天真地以为ECC比RSA快,结果一跑签名——好家伙,一次签名花了将近3秒。用户开个门要等3秒,这产品还怎么卖?
所以今天我就把当年踩过的坑,一个一个给你拆开看。
4.1 大数运算:ECC的“心脏”也是“瓶颈”
ECC的核心运算是什么?说白了就是标量乘法:k * G。这里的k是一个256位的随机数,G是椭圆曲线上的一个点。
每次标量乘法,背后是成千上万次的大数加法和乘法。256位的数,在32位MCU上,一次乘法要拆成8个32位字,然后做16次乘法、32次加法、还要处理进位。你算算,一次点加就要几百次大数运算,一次标量乘法要几百次点加——这数字堆起来,CPU直接跑满。
核心瓶颈:传统ECC(如P-256)的模数p是一个随机素数,没有特殊结构。每次模约减都要做完整的除法或Montgomery约减,计算量远高于Ed25519的2^255 - 19这种“伪梅森素数”。
我举个例子你就明白了。P-256的模数是:
p = 2^256 - 2^224 + 2^192 + 2^96 - 1
这个数没有规律,做模约减的时候,你得老老实实算乘法、移位、加减、判断借位。而Ed25519的模数:
p = 2^255 - 19
一个移位加一个减法就搞定了。差距就在这里。
4.2 坐标系统:仿射坐标的“除法之痛”
椭圆曲线上的点加法,在仿射坐标下需要做模逆运算。模逆是什么?就是求1/x mod p。这个运算比乘法慢一个数量级。
我记得有一次做性能分析,发现模逆占了整个标量乘法时间的40%以上。我当时就懵了——这还怎么优化?
后来项目组引入了雅可比坐标(Jacobian coordinates),把除法变成了乘法。点加从“12次乘法 + 2次模逆”变成了“16次乘法 + 0次模逆”。速度一下就上来了。
但即使这样,传统ECC的坐标转换和混合加法仍然比Ed25519的扩展坐标要重。Ed25519用的是一种叫“扩展爱德华坐标”的东西,点加只需要8次乘法,比P-256的16次少了一半。
| 坐标系统 | 点加(乘法次数) | 倍点(乘法次数) | 是否需要模逆 |
|---|---|---|---|
| 仿射坐标 | 12 + 1模逆 | 7 + 1模逆 | 是 |
| 雅可比坐标 | 16 | 10 | 否 |
| 扩展爱德华坐标 | 8 | 8 | 否 |
你看,光乘法次数就差了一倍。在嵌入式设备上,这可不是小数目。
4.3 侧信道攻击的“性能税”
嵌入式设备还有一个头疼的问题——侧信道攻击。攻击者可以通过分析功耗、电磁辐射、甚至执行时间来窃取私钥。
传统ECC的标量乘法,如果直接用“双倍-加”算法(double-and-add),执行时间跟私钥的比特位直接相关。私钥里1多,运算就慢;0多,运算就快。攻击者拿个示波器一测,私钥就出来了。
所以你必须加防护:
- 恒定时间实现:不管私钥是0还是1,执行时间必须一样。这意味着你要做“虚拟”的加法操作,浪费CPU周期。
- 随机化标量:每次运算前把私钥拆成两个随机数的和,增加攻击难度。但这又多了几次大数运算。
- 坐标随机化:每次点加前给坐标乘一个随机数,防止DPA攻击。同样要额外计算。
这些防护措施,每一项都要吃掉5%~20%的性能。我见过一个项目,为了过CC EAL5+认证,性能直接掉了30%。
避坑指南:我曾经在一个IoT项目中,为了省电把侧信道防护全关了。结果产品上市三个月,就被安全团队用简单功耗分析(SPA)攻破了私钥。后来全部返工,损失惨重。嵌入式设备上,性能和安全永远是跷跷板,但安全这根弦不能松。
4.4 内存占用:小芯片的“致命伤”
嵌入式MCU的RAM通常只有几KB到几十KB。传统ECC的标量乘法需要存储多个中间点:
- 窗口法(如4-bit窗口)需要预计算16个点,每个点两个坐标,每个坐标32字节——总共1KB以上。
- Montgomery阶梯法虽然省内存,但运算次数多,速度慢。
- 还要留出堆栈空间给大数运算的临时变量。
我做过一个测试,在STM32F103上跑P-256签名,光预计算表就占了1.2KB RAM。加上其他变量,总共用了将近4KB。对于只有20KB RAM的芯片来说,这已经是很重的负担了。
而Ed25519呢?它的标量乘法可以用“固定基点的梳状法”(fixed-base comb method),预计算表可以放在Flash里,RAM占用不到1KB。这就是差距。
4.5 一张图看懂ECC性能瓶颈
下面这张图总结了传统ECC在嵌入式设备上的四大瓶颈,以及它们之间的关联关系。
4.6 总结:传统ECC的“慢”是系统性的
你看,传统ECC在嵌入式设备上慢,不是某一个环节的问题。从底层的大数运算,到上层的坐标系统,再到安全防护和内存管理,每个环节都在拖后腿。
我个人觉得,最核心的问题还是“通用性”。P-256设计的时候,考虑的是在各种平台上都能跑,没有针对特定场景做极致优化。而Ed25519从一开始就瞄准了“高性能+高安全”这个目标,在曲线选择、坐标系统、实现技巧上都做了针对性设计。
所以,如果你的项目跑在ARM Cortex-A系列或者x86上,P-256的性能可能还能接受。但一旦到了Cortex-M0、M3这种资源受限的芯片上,差距就原形毕露了。
我的建议:新项目选型,如果嵌入式设备是目标平台,优先考虑Ed25519或Curve25519系列。如果因为兼容性必须用P-256,那一定要在芯片选型阶段就做好性能评估,留出足够的余量。别像我当年那样,等产品快量产了才发现性能不够,那才叫一个被动。