数学基础(上):有限域与椭圆曲线基础概念、SM2推荐曲线参数详解
说实话,很多工程师学 SM2 时,一上来就啃代码。结果遇到点乘算不对、密钥长度搞混,又回头翻数学书。我当年也踩过这个坑。
这一章,咱们把数学地基打牢。不扯太深的数论,只讲 SM2 真正用到的部分。你理解透了,后面写代码会顺很多。
1. 有限域:SM2 的“数字世界”
有限域,说白了就是一个元素个数有限的集合。里面的数可以做加减乘除,结果还在这个集合里。SM2 用的是素域 Fp,p 是一个大素数。
举个例子,p = 7 的有限域 F7,里面的元素是 {0,1,2,3,4,5,6}。3 + 5 = 8,但 8 mod 7 = 1,所以结果还是 1,在集合里。这就是“封闭性”。
核心要点: SM2 的所有点坐标、曲线参数,都是在 Fp 上运算的。p 是 256 位的素数,保证了安全性。
我在项目中遇到过一个问题:两个大数相乘,结果溢出。就是因为没做模约减。记住,在有限域里,每一步运算都要 mod p。
2. 椭圆曲线:不只是“曲线”
椭圆曲线不是椭圆,而是一个方程:y² = x³ + ax + b。在 SM2 里,a 和 b 是常数,x 和 y 都在 Fp 上。
这条曲线上的点,加上一个无穷远点 O,构成一个群。群的意思就是:点之间可以做“加法”,结果还是曲线上的点。
- 点加:P + Q = R,几何意义是过 P、Q 的直线与曲线交于第三点,再关于 x 轴对称。
- 点倍:2P = P + P,几何意义是过 P 的切线与曲线交于另一点,再对称。
- 标量乘:kP = P + P + ... + P(k 次),这是 SM2 签名和密钥交换的核心运算。
我的习惯: 刚开始学椭圆曲线时,我建议你画个草图。虽然 SM2 的曲线是离散点,但几何直觉能帮你理解“加法”为什么那样定义。
3. SM2 推荐曲线参数详解
SM2 国标里给了一套推荐参数。你写代码时直接用就行,但理解每个参数的含义,能帮你避免很多坑。
| 参数 | 含义 | SM2 推荐值(十六进制) |
|---|---|---|
| p | 有限域 Fp 的模数,256 位素数 | FFFFFFFE FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF 00000000 FFFFFFFF FFFFFFFF |
| a | 曲线方程 y² = x³ + ax + b 中的系数 | FFFFFFFE FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF 00000000 FFFFFFFF FFFFFFFC |
| b | 曲线方程中的常数项 | 28E9FA9E 9D9F5E34 4D5A9E4B CF6509A7 F39789F5 15AB8F92 DDBCBD41 4D940E93 |
| G | 基点,椭圆曲线上的一个生成元 | Gx: 32C4AE2C 1F198119 5F990446 6A39C994 8FE30BBF F2660BE1 715A4589 334C74C7 Gy: BC3736A2 F4F6779C 59BDCEE3 6B692153 D0A9877C C62A4740 02DF32E5 2139F0A0 |
| n | 基点 G 的阶,素数 | FFFFFFFE FFFFFFFF FFFFFFFF FFFFFFFF 7203DF6B 21C6052B 53BBF409 39D54123 |
| h | 余因子,h = #E(Fp) / n | 1 |
注意: 我曾经见过有人把 G 的 x 和 y 坐标写反,结果签名验证一直失败。检查参数时,一定要逐字节核对。G 的坐标是 32 字节,别漏了。
4. 参数之间的关系
这些参数不是随便选的。它们之间有关系:
- p 和 a、b:决定了曲线的形状和点的数量。SM2 的曲线是随机曲线,不是超奇异曲线,安全性有保障。
- G 和 n:G 是生成元,n 是 G 的阶。所有私钥 d 必须满足 1 ≤ d ≤ n-1。公钥 Q = dG。
- h = 1:意味着曲线上的点数量等于 n,没有小因子。这简化了实现,也避免了某些攻击。
你想想看,如果 h 不是 1,比如 h = 4,那曲线上的点数是 4n。这时候选基点就要小心,不能选到小阶子群里的点。SM2 直接设 h = 1,省了很多麻烦。
5. 知识体系结构图
下面这张图,把本章的核心概念串起来了。你看一遍,心里就有谱了。
6. 实战中的注意事项
嗯,这里要注意几个点:
- 参数验证:拿到 SM2 参数后,先验证 4a³ + 27b² ≠ 0 mod p。这是曲线非奇异的条件。我见过有人用错参数,曲线有奇点,点加运算直接崩溃。
- 点是否在曲线上:计算 y² mod p 和 (x³ + ax + b) mod p,看是否相等。公钥交换时一定要验证,否则可能收到无效点。
- 标量乘优化:SM2 的私钥是 256 位,标量乘用双倍-加算法。我习惯用 Montgomery ladder,能抗侧信道攻击。
小技巧: 调试时,先用小素数 p(比如 p=23)和简单曲线测试你的点加、点倍代码。确认逻辑正确后,再换成 SM2 的大参数。这样定位问题快很多。
好了,数学基础就讲到这里。你理解了有限域、椭圆曲线和 SM2 参数,后面学签名、加密、密钥交换时,就不会觉得代码是“黑盒”了。