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 知识体系总览

下面这张图把本章的核心概念串起来了,我建议你仔细看看:

椭圆曲线基础 · 知识体系 椭圆曲线 E(Fₚ) Weierstrass 方程 点集与群结构 阶与基点 y² = x³ + ax + b Δ = -16(4a³+27b²) ≠ 0 点加法 · 倍点 · 逆元 无穷远点 O 为单位元 #E(Fₚ) = n · h 基点 G,阶 n 为大素数 标量乘法 kG 双倍-加算法 离散对数问题 SM2 密钥对:私钥 d ← 随机数,公钥 Q = dG 核心安全假设:已知 Q 和 G,求 d 在计算上不可行 这就是椭圆曲线离散对数问题(ECDLP)的困难性

2.7 小结与个人体会

这一章的内容,说白了就是三件事:

  1. 曲线长什么样——Weierstrass方程,光滑性条件
  2. 点怎么运算——群结构,点加法,标量乘法
  3. 安全从哪来——阶是大素数,基点生成循环群,离散对数难解

我个人觉得,理解椭圆曲线密码最好的方式就是动手实现一遍点加法。哪怕只是在小域上(比如p=23),把每个点的坐标算出来,把加法表列出来,你就能直观感受到“群”到底是怎么回事。我当年就是这么干的,虽然代码写得丑,但从此再也没搞混过点加和倍点。

嗯,这一章就到这里。记住:SM2的所有安全性,都建立在“已知公钥Q求私钥d很困难”这个假设上。后面讲签名和加密时,你会反复看到这个核心逻辑。