2. 椭圆曲线基础:有限域上的椭圆曲线、Weierstrass方程、阶与基点
好,我们正式开始进入椭圆曲线的世界。说实话,我第一次接触椭圆曲线时,脑子里全是问号——这玩意儿跟加密有什么关系?后来做项目踩了坑才明白,理解这章的内容,是后面看懂SM2签名、加密、密钥交换的基石。
咱们不绕弯子,直接说核心:椭圆曲线不是椭圆,它是一条三次方程确定的点集。之所以叫“椭圆”,是因为计算椭圆周长的积分公式里会出现这类方程——嗯,历史原因,记住就行。
2.1 从实数域到有限域
教科书上通常先讲实数域上的椭圆曲线,图像是一条光滑曲线。但实际密码学里,我们用的是有限域。为什么?
你想想看,实数域上的点是连续的,有无穷多个。计算机没法精确表示无理数,更没法在无穷集合上做密码。有限域就不一样了——点的数量是有限的,每个点坐标都是整数,计算机处理起来干净利落。
SM2用的是素域Fp,p是一个大素数。说白了,就是集合{0, 1, 2, ..., p-1},加减乘除都在模p下做。我当年第一次写有限域上的点加代码时,忘了对除法做模逆运算,结果调试了一整天——嗯,这个坑后面会细说。
2.2 Weierstrass方程
椭圆曲线的标准形式是Weierstrass方程:
y² = x³ + ax + b
在有限域Fp上,a和b都是Fp中的元素。曲线还要满足一个条件:
判别式 Δ = -16(4a³ + 27b²) ≠ 0 (mod p)
这个条件保证曲线是“光滑”的——没有尖点,没有自交点。如果Δ=0,曲线就有奇点,密码学上就不安全了。
SM2算法使用的曲线参数是固定的,由国家密码管理局发布。具体参数我后面会列出来,这里先记住:SM2曲线是定义在素域Fp上的一条特定椭圆曲线。
2.3 椭圆曲线上的点集与群结构
椭圆曲线上的所有点,加上一个特殊的“无穷远点”O,构成一个阿贝尔群。这个群是密码学的基础。
群运算包括:
- 点加法:P + Q = R,几何意义是过P和Q的直线与曲线交于第三点,再关于x轴对称
- 倍点运算:P + P = 2P,几何意义是过P的切线与曲线交于另一点,再对称
- 逆元:-P = (x, -y),关于x轴对称
- 单位元:无穷远点O,满足P + O = P
我个人习惯把点加法想象成“弦切法”——两个点连一条弦,找到第三个交点,再翻个跟头。这个几何直觉在理解标量乘法时特别有用。
避坑指南:我曾经在实现点加法时,忘记处理P=Q的情况(倍点)和P=-Q的情况(结果为O)。这两个边界条件在代码里特别容易漏掉,写单元测试时一定要覆盖到。
2.4 阶与基点
椭圆曲线上的点集是有限群,这个群的大小称为曲线的阶,记作#E(Fp)。
对于SM2曲线,阶n是一个大素数。这意味着什么?意味着群是循环群,存在一个基点G,通过G的标量乘法可以生成整个群。
基点的定义:
- G是曲线上一个非无穷远点
- G的阶是n,即nG = O,且对于任意1 ≤ k < n,kG ≠ O
- 所有点都可以表示为kG的形式,k ∈ [1, n-1]
SM2的基点G是公开的,坐标固定。私钥就是一个随机数d,公钥就是Q = dG。你看,密码学的核心就这么简单——从私钥到公钥容易(标量乘法),从公钥反推私钥难(离散对数问题)。
| 参数 | 含义 | SM2取值特点 |
|---|---|---|
| p | 素域模数 | 256位素数 |
| a, b | Weierstrass方程系数 | 固定值,公开 |
| n | 基点G的阶 | 大素数,与p接近 |
| G | 基点坐标(Gx, Gy) | 固定值,公开 |
2.5 标量乘法与安全基础
标量乘法kG是椭圆曲线密码的核心运算。实现时用双倍-加算法(Double-and-Add):
// 计算 k * G,k 是整数,G 是基点
function scalarMultiply(k, G):
result = O // 无穷远点
temp = G
while k > 0:
if k & 1: // 当前位为1
result = add(result, temp)
temp = double(temp) // 倍点
k = k >> 1 // 右移一位
return result
这个算法的时间复杂度是O(log k),对于256位的k,只需要做256次倍点和平均128次点加。效率很高。
安全警告:上面这个朴素实现存在侧信道攻击风险。攻击者可以通过分析功耗或执行时间来推断k的比特位。我在做安全芯片项目时,必须使用常数时间实现——不管k的当前位是0还是1,执行时间和操作序列都一样。这个后面讲SM2实现时会专门展开。
2.6 知识体系总览
下面这张图把本章的核心概念串起来了,我建议你仔细看看:
2.7 小结与个人体会
这一章的内容,说白了就是三件事:
- 曲线长什么样——Weierstrass方程,光滑性条件
- 点怎么运算——群结构,点加法,标量乘法
- 安全从哪来——阶是大素数,基点生成循环群,离散对数难解
我个人觉得,理解椭圆曲线密码最好的方式就是动手实现一遍点加法。哪怕只是在小域上(比如p=23),把每个点的坐标算出来,把加法表列出来,你就能直观感受到“群”到底是怎么回事。我当年就是这么干的,虽然代码写得丑,但从此再也没搞混过点加和倍点。
嗯,这一章就到这里。记住:SM2的所有安全性,都建立在“已知公钥Q求私钥d很困难”这个假设上。后面讲签名和加密时,你会反复看到这个核心逻辑。