引言
椭圆曲线密码学(ECC, Elliptic Curve Cryptography)是现代密码学中最优雅且实用的技术之一。它将19世纪代数几何中的椭圆曲线理论,转化为保护当今互联网通信的加密武器。从TLS 1.3到比特币,从Signal到物联网设备,ECC以其短小精悍的密钥长度和数学上坚固的安全性,成为公钥密码学的绝对主流。
一、椭圆曲线的数学基础
1.1 Weierstrass标准形式
椭圆曲线最经典的表示是短Weierstrass形式:
y² = x³ + ax + b,其中判别式 Δ = -16(4a³ + 27b²) ≠ 0,确保曲线无奇点(无自交点和尖点)。
以secp256k1曲线(比特币所用)为例:y² = x³ + 7,即 a=0, b=7。定义在有限域 GF(p) 上,其中 p = 2²⁵⁶ - 2³² - 977。
1.2 群结构的加法法则
椭圆曲线上的点构成一个Abel群,加法规则如下:
- 单位元:无穷远点 O
- 逆元:点 P=(x,y) 的逆元为 -P=(x,-y)
- 点加:过两点 P、Q 作直线,与曲线交于第三点 R,P+Q = -R
- 倍点:P=Q 时,取切线,2P = -(切线第三交点)
1.3 有限域上的算术
在 GF(p) 上,所有坐标运算均为模 p 运算。模逆元通过扩展欧几里得算法或费马小定理(a⁻¹ ≡ aᵖ⁻² mod p)计算。
二、椭圆曲线离散对数问题(ECDLP)
ECC的安全性建立在ECDLP之上:给定基点 G 和公钥 Q = kG,求解私钥 k 在计算上不可行。
2.1 攻击复杂度对比
| 算法 | 复杂度 | 适用性 |
|---|---|---|
| Pollard's Rho | O(√n) | 通用,目前最优通用攻击 |
| Pohlig-Hellman | O(√p),p为最大素因子 | 要求曲线阶有平滑因子 |
| MOV攻击 | 亚指数级 | 仅适用于超奇异曲线(k≤6) |
| Smart攻击 | 多项式级 | 仅适用于反常曲线(#E = p) |
2.2 安全参数选择
为使Pollard's Rho攻击代价达到2¹²⁸,曲线阶 n 必须 ≥ 2²⁵⁶。选择原则:
- 曲线阶 n 为大素数或含大素因子
- n ≠ p(排除Smart攻击)
- #E(GF(pᵏ)) ≠ p 对某个小k成立(排除MOV攻击)
- 余因子 h = #E/n 尽量小(≤8)
三、核心算法实现
3.1 标量乘法(kG的计算)
double-and-add(二进制法)是基础算法:
Input: 标量 k = (k_{t-1}...k_0)_2, 基点 G
Output: Q = kG
Q ← O
for i = t-1 downto 0:
Q ← 2Q
if k_i = 1: Q ← Q + G
return Q
更高效的变体包括:
- NAF(非相邻形式):密度从1/2降至1/3,减少加法次数
- wNAF(窗口NAF):预计算小倍数表,进一步加速
- GLV/GLS分解:利用自同态将k拆分为两个减半长度的标量,实现常数级加速
3.2 安全的随机数生成
ECDSA中随机数k的致命性:若k重复或可预测,私钥瞬间泄露。RFC 6979提出了确定性nonce方案:k = HMAC_K(V || bits2octets(h1) || 0x00...),确保k唯一且不可预测。
四、主流曲线家族
4.1 NIST曲线
P-256、P-384、P-521由NIST标准化。P-256广泛用于TLS。争议:参数种子(c49d3608...)来源不明,被怀疑可能存在后门。
4.2 Curve25519 & Ed25519
Daniel Bernstein设计,完全透明:p = 2²⁵⁵ - 19,曲线方程 y² = x³ + 486662x² + x(Montgomery形式)。
- X25519:ECDH密钥交换,恒定时间实现天然抗侧信道
- Ed25519:EdDSA签名方案,确定性nonce,批量验证可达100k sigs/sec
4.3 国密SM2
中国商用密码标准,曲线方程 y² = x³ + ax + b 定义在 256-bit素数域上。应用于金融、政务系统,支持密钥交换、数字签名、公钥加密三种功能。
五、ECDSA深度实战
5.1 签名与验证
签名 (d, M):
k ← RANDOM(1, n-1)
(x1, y1) = kG
r = x1 mod n
k_inv = k^(-1) mod n
e = HASH(M)
s = k_inv * (e + r*d) mod n
输出 (r, s)
验证 (Q, M, (r,s)):
s_inv = s^(-1) mod n
e = HASH(M)
u1 = e * s_inv mod n
u2 = r * s_inv mod n
(x1, y1) = u1*G + u2*Q
有效当且仅当 x1 mod n == r
5.2 常见陷阱
- 不验证公钥:无效曲线攻击可导致私钥泄漏 → 验证 Q 在正确阶子群上
- 复用随机数k:两个签名的r相同 → d = (s1·k - e1) / r mod n
- s未限制范围:s和n-s都有效 → 强制-low-s规则(BIP 62/BIP 66)
- 定时侧信道:分支依赖密钥位 → 恒定时间Montgomery ladder
六、后量子时代的ECC
Shor算法可在多项式时间内破解ECDLP。NIST PQ标准化已选CRYSTALS-Kyber和CRYSTALS-Dilithium作为替代方案。然而在椭圆曲线同源密码学(如SIKE、CSIDH)方向,ECC仍可能延续其生命——尽管SIKE已被经典计算机攻破,CSIDH及其变体仍在积极研究中。
七、TLS 1.3中的ECC部署
TLS 1.3彻底移除了RSA密钥交换和静态DH,ECDHE成为必经之路。握手流程:
- ClientHello:supported_groups扩展列出曲线偏好,key_share扩展提供X25519/P-256公钥
- ServerHello:选定曲线,返回key_share
- 双方完成ECDHE共享密钥推导,Forward Secrecy天然保障
Chrome/Firefox优先使用X25519,NIST P-256次之。TLS 1.3的1-RTT握手使ECC性能成为关键指标。
八、从零实现迷你ECC(Python演示)
class ECPoint:
def __init__(self, x, y, a, b, p, infinity=False):
self.x, self.y, self.a, self.b, self.p = x, y, a, b, p
self.inf = infinity
def __add__(self, other):
if self.inf: return other
if other.inf: return self
if self.x == other.x and (self.y + other.y) % self.p == 0:
return ECPoint(0,0,self.a,self.b,self.p,infinity=True)
if self.x != other.x:
lam = (other.y - self.y) * pow(other.x - self.x, -1, self.p) % self.p
else:
lam = (3 * self.x**2 + self.a) * pow(2 * self.y, -1, self.p) % self.p
x3 = (lam**2 - self.x - other.x) % self.p
y3 = (lam * (self.x - x3) - self.y) % self.p
return ECPoint(x3, y3, self.a, self.b, self.p)
def mul(self, k):
R = ECPoint(0,0,self.a,self.b,self.p,infinity=True)
addend = ECPoint(self.x, self.y, self.a, self.b, self.p)
while k:
if k & 1: R = R + addend
addend = addend + addend
k >>= 1
return R
结语
椭圆曲线密码学是纯数学理论转化为工程实践的典范。从椭圆曲线上的有理点加法,到手机里每一次TLS握手,这种跨学科的优雅正是密码学最美妙的一面。在后量子过渡期,深入理解ECC仍至关重要——不仅是兼容性需求,更是理解下一代密码构建基础的必经之路。

发表评论 取消回复