SM2算法与国密算法集成 - 第2节
SM2算法数学基础:椭圆曲线密码学(ECC)核心概念
说实话,很多工程师一听到「椭圆曲线」四个字就头大。我当年刚接触国密时也一样,觉得这东西太抽象了。但后来我发现,你不需要成为数学家也能用好它。关键是理解几个核心概念,然后记住参数怎么用就行。
椭圆曲线密码学(ECC),说白了就是利用椭圆曲线上的点构成一个群,然后在这个群上做运算。为什么选椭圆曲线?因为它的数学结构能让我们用更短的密钥达到和RSA一样的安全强度。举个例子,256位的ECC密钥,安全性和3072位的RSA差不多。这在嵌入式设备、物联网场景下,优势非常明显。
什么是椭圆曲线?
数学上,椭圆曲线是满足下面这个方程的所有点(x, y)的集合:
y² = x³ + ax + b
再加上一个无穷远点O(你可以把它想象成「零元」)。这里a和b是系数,它们决定了曲线的形状。我习惯把椭圆曲线理解成「在有限域上画出来的一条特殊曲线」,但注意,它和我们平时在纸上画的曲线不太一样——它是一堆离散的点。
关键条件:判别式 Δ = -16(4a³ + 27b²) ≠ 0。如果等于0,曲线会出现奇点(比如自交或尖点),这样的曲线不能用于密码学。
有限域上的椭圆曲线
嗯,这里要重点说一下。我们实际用的椭圆曲线,不是在实数域上,而是在有限域上。SM2使用的是素域Fp,p是一个大素数。曲线方程变成:
y² ≡ x³ + ax + b (mod p)
所有运算都在模p下进行。这意味着曲线上的点不再是连续的,而是一堆离散的整数点。我在项目中遇到过有人把实数域上的曲线图像直接套用到有限域上,结果调试了半天发现点根本不在曲线上——因为取模后坐标变了。
有限域上的椭圆曲线有几个重要性质:
- 封闭性:曲线上任意两点相加(定义一种特殊加法),结果仍在曲线上。
- 交换律:P + Q = Q + P。
- 存在单位元:无穷远点O就是单位元,P + O = P。
- 每个点都有逆元:点P(x, y)的逆元是P'(x, -y mod p)。
这些性质构成了一个阿贝尔群。你想想看,密码学里我们需要的「单向函数」——正向计算容易,反向推导极难——正好可以建立在这个群的离散对数问题上。
椭圆曲线上的点加法
点加法是ECC最核心的运算。我建议你记住几何意义,但实际编码时直接用公式。几何上,两个点P和Q相加:
- 过P和Q画一条直线,交曲线于第三点R'。
- R'关于x轴的对称点R,就是P + Q的结果。
如果P = Q,那就是倍点运算:过P做切线,交曲线于另一点,再取对称。
实际计算时,我们用代数公式。SM2的推荐参数已经帮我们选好了曲线,你只需要调用现成的库函数就行。但理解底层逻辑有助于你排查问题——我曾经在移植SM2算法到ARM Cortex-M0芯片时,发现点加运算结果不对,最后定位到是模逆运算的溢出问题。
SM2推荐曲线参数
SM2算法使用的是国家密码管理局推荐的椭圆曲线参数。这些参数是公开的,你可以在GM/T 0003-2012标准中找到。我个人习惯把这些参数记在项目的配置文件中,方便后续维护。
SM2使用的曲线是y² = x³ + ax + b,定义在素域Fp上。具体参数如下:
| 参数 | 含义 | SM2推荐值(十六进制) |
|---|---|---|
| p | 素域模数 | FFFFFFFE FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF 00000000 FFFFFFFF FFFFFFFF |
| a | 曲线系数 | FFFFFFFE FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF 00000000 FFFFFFFF FFFFFFFC |
| b | 曲线系数 | 28E9FA9E 9D9F5E34 4D5A9E4B CF6509A7 F39789F5 15AB8F92 DDBCBD41 4D940E93 |
| Gx | 基点G的x坐标 | 32C4AE2C 1F198119 5F990446 6A39C994 8FE30BBF F2660BE1 715A4589 334C74C7 |
| Gy | 基点G的y坐标 | BC3736A2 F4F6779C 59BDCEE3 6B692153 D0A9877C C62A4740 02DF32E5 2139F0A0 |
| n | 基点G的阶(素数) | FFFFFFFE FFFFFFFF FFFFFFFF FFFFFFFF 7203DF6B 21C6052B 53BBF409 39D54123 |
| h | 余因子 | 1 |
我的建议:参数p和n都是256位的素数。p的取值很巧妙——它等于2²⁵⁶ - 2²²⁴ - 2⁹⁶ + 2⁶⁴ - 1。这种特殊形式可以加速模约减运算。如果你在做硬件实现,可以利用这个特性优化性能。
参数解读
咱们逐个看看这些参数的意义:
- p:有限域的大小。所有坐标运算都要模p。SM2的p是256位,提供约128位的安全强度。
- a和b:曲线方程的系数。SM2的a = p - 3,这个设计是为了加速点加运算中的模约减。b是一个随机选取的值,经过验证没有特殊弱点。
- G:基点,也就是生成元。所有密钥对都基于G生成。G的坐标是公开的,你可以验证它确实在曲线上。
- n:基点G的阶。n是一个大素数,表示G自加n次后得到无穷远点。n的大小决定了算法的安全性。
- h:余因子,h = #E(Fp) / n。SM2的h = 1,说明曲线上的点数和n相等,没有子群攻击的风险。
避坑指南:我曾经在项目中看到有人直接把SM2的参数复制到代码里,结果因为字节序问题(大端vs小端)导致签名验证失败。SM2标准使用的是大端序(Big-Endian),如果你的平台是小端序,记得做转换。
为什么选这些参数?
SM2的参数选择不是随意的。国家密码管理局在选取时考虑了以下因素:
- 安全性:曲线没有异常点,阶n是大素数,抵抗Pollard's rho攻击、MOV攻击、SSSA攻击等已知攻击方法。
- 性能:a = p - 3可以加速点加运算;p的特殊形式可以加速模约减。
- 兼容性:256位密钥长度,和AES-128的安全级别匹配,适合作为商用密码标准。
说实话,你不需要自己验证这些参数的安全性——国家密码管理局已经替我们做过了。但作为工程师,我建议你至少验证一下G点是否在曲线上,以及n是否是素数。我在做安全审计时,第一步就是检查这些参数有没有被篡改。
知识体系总览
下面这张图总结了本章的核心逻辑。你可以把它当作一个快速参考:
从这张图可以看得很清楚:椭圆曲线定义 → 有限域 → 群结构 → SM2参数 → 具体应用,是一条完整的技术链路。我个人建议你把这个框架记在脑子里,以后遇到国密相关的问题,先定位到具体层级,再深入排查。