椭圆曲线的数学基础
一、引言
椭圆曲线密码学(Elliptic Curve Cryptography, ECC)是现代公钥密码学的核心工具之一。
相比传统的 RSA,ECC 可以用 更短的密钥长度 提供 同等甚至更高的安全性,因此被广泛应用于区块链、TLS、移动设备加密等场景。
要理解 ECC,必须先了解它背后的数学结构 —— 椭圆曲线上的点运算。本文将从基础开始,逐步介绍椭圆曲线的数学原理。
二、椭圆曲线方程
一个椭圆曲线通常由如下方程表示:
y2=x3+ax+b y^2 = x^3 + ax + b y2=x3+ax+b
其中 a,ba, ba,b 是常数,要求曲线 无奇异点(即没有自相交和尖点),满足:
4a3+27b2≠0 4a^3 + 27b^2 \neq 0 4a3+27b2=0
在实数范围内,这条曲线看起来像一条光滑的对称曲线:
- 关于 x 轴对称
- 呈“S”形或“波浪”形
但在密码学中,我们不会在实数范围上研究,而是定义在 有限域 Fp\mathbb{F}_pFp(模素数 ppp)上的椭圆曲线。
三、有限域上的椭圆曲线
在有限域中,所有运算都取模 ppp:
y2≡x3+ax+b(modp) y^2 \equiv x^3 + ax + b \pmod p y2≡x3+ax+b(modp)
例如:
选择 p=17,a=2,b=2p = 17, a = 2, b = 2p=17,a=2,b=2,曲线为:
y2≡x3+2x+2(mod17) y^2 \equiv x^3 + 2x + 2 \pmod{17} y2≡x3+2x+2(mod17)
我们可以枚举 x∈[0,16]x \in [0,16]x∈[0,16],找到满足条件的点 (x,y)(x,y)(x,y),这就是曲线上的点集。
四、点运算(群结构)
ECC 的核心不是曲线方程本身,而是 曲线点上的运算规则。
椭圆曲线上的点(包括一个“无穷远点” OOO)形成一个 群,支持以下运算:
-
点加法 P+QP+QP+Q
- 几何直观:过两点作直线,直线与曲线相交于第三点 RRR,再取 RRR 关于 x 轴的对称点。
- 特殊情况:P=QP=QP=Q 时,用切线定义加法。
-
点倍乘 kPkPkP
- 相当于 P+P+...+PP+P+...+PP+P+...+P(共 kkk 次)。
- 在 ECC 中,公钥计算就是 点倍乘。
五、ECC 的安全性来源
- 容易:给定 PPP 和整数 kkk,计算 Q=kPQ = kPQ=kP 很快。
- 困难:给定 PPP 和 QQQ,求 kkk 很难(椭圆曲线离散对数问题,ECDLP)。
这种 单向性 是 ECC 的安全核心。
六、Go 语言小实验:有限域椭圆曲线点加法
下面我们用 Go 写一个小程序,在有限域 p=17p=17p=17 上实现椭圆曲线点加法。
package mainimport ("fmt""math/big"
)// 椭圆曲线参数: y^2 = x^3 + ax + b mod p
var p = big.NewInt(17)
var a = big.NewInt(2)
var b = big.NewInt(2)// 点结构
type Point struct {x, y *big.Intinf bool // 是否是无穷远点
}// 取模
func mod(v *big.Int) *big.Int {r := new(big.Int).Mod(v, p)if r.Sign() < 0 {r.Add(r, p)}return r
}// 逆元
func modInverse(v *big.Int) *big.Int {return new(big.Int).ModInverse(v, p)
}// 点加法
func add(P, Q Point) Point {// 处理无穷远点if P.inf {return Q}if Q.inf {return P}var m *big.Intif P.x.Cmp(Q.x) == 0 && P.y.Cmp(Q.y) == 0 {// P == Q, 切线斜率num := new(big.Int).Mul(big.NewInt(3), new(big.Int).Mul(P.x, P.x))num.Add(num, a)den := new(big.Int).Mul(big.NewInt(2), P.y)m = new(big.Int).Mul(num, modInverse(den))} else {// P != Q, 直线斜率num := new(big.Int).Sub(Q.y, P.y)den := new(big.Int).Sub(Q.x, P.x)m = new(big.Int).Mul(num, modInverse(den))}m = mod(m)xr := mod(new(big.Int).Sub(new(big.Int).Sub(new(big.Int).Mul(m, m), P.x), Q.x))yr := mod(new(big.Int).Sub(new(big.Int).Mul(m, new(big.Int).Sub(P.x, xr)), P.y))return Point{xr, yr, false}
}func main() {P := Point{big.NewInt(5), big.NewInt(1), false}Q := Point{big.NewInt(6), big.NewInt(3), false}R := add(P, Q)fmt.Printf("P=(%v,%v), Q=(%v,%v)\n", P.x, P.y, Q.x, Q.y)fmt.Printf("P+Q=(%v,%v)\n", R.x, R.y)
}
运行结果示例:
P=(5,1), Q=(6,3)
P+Q=(10,6)
说明在有限域上,椭圆曲线点运算是完全可行的。
七、总结
本文介绍了椭圆曲线的数学基础,包括:
- 椭圆曲线方程及有限域定义
- 点加法和点倍乘运算
- ECC 的安全来源 —— 椭圆曲线离散对数问题