第2章:SM2算法原理:椭圆曲线基础归纳总结
聊SM2之前,得先搞明白它背后的数学基石——椭圆曲线。说实话,我刚接触密码学时也觉得这东西很抽象,后来在项目中踩过坑才真正体会到:你如果不理解椭圆曲线,SM2的密钥对、签名验签就是黑盒调试,出了问题根本无从下手。
2.1 什么是椭圆曲线?
椭圆曲线不是椭圆函数,也不是椭圆形状的曲线。它是一条在二维平面上满足特定方程的曲线。密码学中常用的形式是Weierstrass方程:
y² = x³ + ax + b (其中4a³ + 27b² ≠ 0)
那个不等于零的条件是为了保证曲线没有“奇点”(尖点或自交),否则加法运算就不良定义。我在项目中遇到过把a、b参数抄错导致曲线校验不通过的情况,排查了好久才发现是文档拷贝时多了一个空格。
椭圆曲线长什么样子?举个例子,a = -1, b = 0 时的曲线在实数域上是左右对称的图形,有点像两个驼峰。但密码学里我们不在实数域上做运算——浮点数误差没法控制,所以要用有限域。
2.2 有限域上的椭圆曲线
SM2使用的是素域Fp,p是一个大素数。曲线上的点坐标都是0到p-1之间的整数,所有运算对p取模。这样一来,曲线上的点集就变成了一个有限的离散点集合,这是密码学能用的前提。
| 域类型 | 典型p长度 | SM2标准 | 运算特点 |
|---|---|---|---|
| 素域 Fp | 256位 | SM2推荐p = 2^256 - 2^224 - 2^96 + 2^64 - 1 | 整数模p运算,硬件友好 |
| 二进制定域 F2^m | 同上 | SM2不采用 | 适合特定硬件,但安全性分析复杂 |
我个人习惯上只记素域Fp,因为SM2、SM3、SM4这条链路里的国密标准全部基于它。你想想看,整个SM2的密钥交换、签名验算都跑在Fp上,所以理解好模运算很重要。
2.3 椭圆曲线上的点加法
这是椭圆曲线最精彩的部分。两个在曲线上的点P和Q相加,可以得到第三个点R。几何解释很简单:
- 过P和Q作直线,与曲线相交于第三点R'
- 将R'关于x轴对称得到R,就是P+Q的结果
注意几个边界情况:
- 如果P=Q,则做切线(倍点运算)
- 如果P是Q关于x轴的对称点,则P+Q = 无穷远点(零元)
- 无穷远点记作O,任何点加O等于它本身
我一直记得刚学倍点公式时,总是把斜率计算搞反。后来写了一个小demo验证:先算一个点,再算两倍,再算三倍,看看能不能拼回原值。我建议你也这样做一次——亲手验算几个点,比你背十遍公式都牢。
2.4 群的阶与基点
所有曲线上点的个数加上无穷远点,称为曲线的阶,记作#E(Fp)。阶是一个很难计算的大数,SM2标准直接给出了SM2曲线的阶n。
基点是曲线上一个特定的点G,它的阶是一个大素数(通常是n)。为什么需要基点?因为所有参与者的运算都从G开始:
- 私钥 d: 一个随机大整数,范围 [1, n-1]
- 公钥 Q: Q = d × G (标量乘法)
标量乘法就是连续的点加和倍点运算,比如 d×G = G+G+...+G(d次)。这就是椭圆曲线密码学的核心——从私钥算公钥很容易,但反过来从公钥算私钥非常困难(椭圆曲线离散对数问题,ECDLP)。
2.5 SM2椭圆曲线参数一览
SM2标准里给出了一套固定的曲线参数(SM2P256V1)。你不用自己选,直接用标准里的即可。我见过一些团队试图“增强安全性”修改参数,结果导致互操作性问题,最后不得不回退。
重要的几个:
| 参数名 | 含义 | SM2标准值(十六进制截取) |
|---|---|---|
| p | 素域模数 | FFFFFFFE FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF 00000000 FFFFFFFF FFFFFFFF |
| a | Weierstrass系数a | FFFFFFFE FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF 00000000 FFFFFFFF FFFFFFFC |
| b | Weierstrass系数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 |
2.6 密钥对生成流程
有了基点G和阶n,密钥生成就是一个标量乘法。流程很简单:
- 生成随机数 d ∈ [1, n-1](作为私钥)
- 计算 Q = d × G(点乘)
- 输出 (d, Q)
点乘的实现有很多种:二进制展开、滑动窗口、Montgomery ladder(防侧信道攻击)。SM2推荐用二进制展开,但如果你做安全芯片,我建议用Montgomery ladder——它在时间上恒定,不容易被时序攻击。
2.7 核心概念关系图
为了帮你把这几节内容串起来,我画了一张结构图。它展示了SM2椭圆曲线密码体系的骨架:
2.8 本章小结
椭圆曲线密码学本质上是一套在有限域上封闭的加法群操作。你只要记住三件事:
- 曲线方程和域参数决定群结构
- 点加/倍点定义运算规则
- 私钥→公钥是单向的标量乘法