介绍
椭圆曲线密码学(Elliptic curve cryptography),简称 ECC,和RSA、ElGamel 算法等类似,是一种公开秘钥加密的算法,也就是非对称加密。ECC 被公认为在给定秘钥长度下最安全的加密算法。ECC 依赖于解决大椭圆曲线离散对数问题的困难性。它的优势主要在于相对于其它方法,它可以在使用较短密钥长度的同时保持相同的密码强度。
数学基础与算法介绍
群
一个集合 G 以及定义在集合 G 上的二元运算 ∗ 称为群(group),若满足以下条件:
- ∗ 运算满足结合律
- G 有单位元
- 对于任意 a∈G , a有逆元
若群上的运算满足交换律,则称该群为可交换群或阿贝尔群。
群是一个二元组 (G, ∗),有时候为了方便就直接用 G 表示群。
域
定义:F 是一个集合, + 和 ⋅ 是定义在 F 上的两个二元运算,分别称作加法和乘法。(F,+,⋅) 称为域(field),若满足:
- (F,+,⋅) 构成一个环,且 0 和 1 是不同的元素
- (F−{0},⋅) 构成可交换群
显然,一个域至少要包含 0 和 1 两个元素。域是一个三元组 (F,+,⋅) ,有时候直接用 F 表示域。
由定义可以推出,给定域 (F,+,⋅) ,对于任意 a∈F ,0 ⋅ a = 0 。
有限域
有限域也被称为伽罗瓦域(Galois field)。
对于任何一个素数 p ,集合 G = {0,1,…,p−1} 对模 p 加法和模 p 乘法构成有限域,记为 GF(p) 。简单来说,GF(p) 就是 mod p,因为一个数模 p 后,结果在 [0, p - 1] 之间。对于元素a和b,那么 (a + b) mod p 和 (a * b) mod p,其结果都是域中的元素。
通常用 GF(q) 表示一个阶为 q 的有限域,q 必定是某个素数 p 的幂。
射影平面
射影平面的概念是从普通直角坐标系引入的,即笛卡尔积坐标系。
笛卡尔积坐标系是没有设置无穷点的,所以为了表示无穷远点,就产生了一个叫做射影平面坐标系的东西,这个射影平面坐标系可以同时表示无穷远点和平常点。
有限域上的椭圆曲线
有限域上的椭圆曲线是指在椭圆曲线的定义式:
$y^2+axy+by=x^3+cx^2+dx+e$
其中所有的系数都是在某个有限域GF(p)中的元素,其中p为一个大素数。
当然,并不是所有的椭圆曲线都适合于加密,最为常用的方程如下:
$y^2=x^3+ax+b$
其中 $4a^3+27b^2 \bmod p \neq 0$
我们称该方程的所有解$(x,y),(x\in Fp , y \in Fp)$,以及一个称为“无穷远点”(O)组成的集合为定义在 Fp 上的一个椭圆曲线,记为 E(Fp)。
一般定义椭圆曲线密码需要以下条件:
假设E(Fp)对于点的运算 ⊕ 形成一个able群(交换群,逆元存在,封闭性等),设 $p\in E(Fq)$,且满足下列条件的 t 很大
$p \oplus p \oplus … \oplus p=O$
其中共有 t 个 p 参与运算。这里我们称 t 为 p 的周期。此外,对于$Q\in E(Fq)$ ,定有某个正整数 m 使得下列式子成立,定义$m=log_pq$
$Q=m\cdot p =p \oplus p \oplus … \oplus p$(m 个 p 参与运算)
此外,假设 G 是该 $E_q (a,b)$ 的生成元,即可以生成其中的所有元素,其阶为满足 $nG=O$ 的最小正整数 n。
ECC中的ElGamal
假设用户 B 要把消息加密后传给用户 A。
密钥生成
用户A先选择一条椭圆曲线 $E_q (a,b))$ ,然后选择其上的一个生成元 G,假设其阶为 n,之后再选择一个正整数 $n_a$ 作为密钥,计算$P_a=n_aG$。
其中,$E_q(a,b), q,G$ 都会被公开。
公钥为 $P_a$,私钥为 $n_a $。
加密
用户 B 在向用户 A 发送消息 m,这里假设消息 m 已经被编码为椭圆曲线上的点,其加密步骤如下
- 查询用户 A 的公钥 $E_q(a,b), q, P_a,G$ 。
- 在 (1,q - 1) 的区间内选择随机数 k 。
- 根据 A 的公钥计算点 $(x_1,y_1)=kG$。
- 计算点 $(x_2,y_2)=kP_a$,如果为 0,则从第二步重新开始。
- 计算 $C=m+(x_2,y_2)$
- 将 $((x_1,y_1),C)$ 发送给 A。
解密
解密步骤如下
- 利用私钥计算点 $n_a(x_1,y_1)=n_akG=kP_a=(x_2,y_2)$。
- 计算消息 $m=C-(x_2,y_2)$ 。
关键点
这里的关键点在于我们即使知道了 $(x_1,y_1) $ 也难以知道 k,这是由离散对数的问题的难度决定的。
例子
以 2013 SECCON CTF quals Cryptanalysis 为例
我们已知椭圆曲线方程以及对应的生成元 base,还知道相应的模数以及公钥以及加密后的结果。
1 | a = 1234577 |
ECC中的Pohlig-Hellman
加解密
首先我们不妨假设需要求解的式子为:
$Q = l * P$
其中 P 为我们选取的一个基点,l 就是我们选定的随机数,相当于要求解的私钥。
首先求得 P 的阶 n,也就是可使得 n * P 不存在的最小正整数
然后我们将 n 进行分解,我们设
$n = p_1^{e_1} * p_2^{e_2} ……p_r^{e_r}$
然后我们将这些因子拿出来,对于 i 属于 [1, r],计算
$li = l \space mod \space p_i^{e_i}$
于是我们便得到了下面的这一系列等式
$l ≡ (l_1 \space mod \space p_1^{e_1})$
$l ≡ (l_2 \space mod \space p_2^{e_2})$
……
$l ≡ (l_r \space mod \space p_r^{e_r})$
看上去是不是有点眼熟,如果得到了这些 $l_i$ 的值我们就能使用中国剩余定理进行求解得到 l 了,现在的问题就是求解这些 $l_i$
首先我们将 $l_i$ 设为成 $p_i$ 表示的多项式,如下:
$l_i = z_0 +z_1p_i+z_2p_i^2+…+z_{e-1}p_i$
接下来我们的任务就是求解这些 z,注意这里的z应该是属于 $[0,p_i-1]$
下面就很有意思了,为了计算 $z_i$,我们分别取 $P_0$ 和 $Q_0$,并取值:
$P_0 = \frac{n}{p_i}P$
$Q_0=\frac{n}{p_i}Q$
这样我们就有了 $p_i*P_0 = nP$,接下来我们可以得到 $Q_0$ 的表达式:
$Q_0=\frac{n}{p_i}Q=\frac{n}{p_i}(lP)=l(\frac{n}{p_i}P)=lP_0$
其实就是在我们原表达式的两边乘上了 $n/p_i$
这样的话我们再转回 $l_i$,先求解 $z_0$
$l_i*P=Q$
$=>l_i*P_0=Q_0$
$=>(z_0+z_1P_i+…+z_{e-1}P_i^{e-1})P_0=Q_0$
$=> z_0*P_0=Q_0$
这时我们便将在 P 域上的离散对数分解到了 $P_0$ 域上,因为 $P_0$ 的阶是 $n/p_i$,已经较原本的阶 n 运算的复杂度小了很多,当然,除非 n 本身就是个大素数
在这里我们可以求得 $z_0$,然后我们再代回原式
$(z_0+z_1p_i+…+z_{e-1}p_i^{e-1}P_0=Q_0)$
$=>z_0P_0+(z_1p_i+…+z_{e-1}p_i^{e-1}P_0=Q_0)$
$=>(z_1p_i+…+z_{e-1}p_i^{e-1}P_0=Q_0-z_0P_0)$
$=>z_1p_i=Q_0-z_0P_0$
此时就可以求解 $z_1$,然后依次将 $z_i$ 全部算出来,这样我们就得到了 $l_1$,然后便可以代入前面的等式,将 $l_1$ 都求出后即可利用中国剩余定理求出 $l$
例子
picoCTF 2017的 ECC 2-200 题目
1 | Elliptic Curve: y^2 = x^3 + A*x + B mod M |
第一步解决 b 通过重新排列椭圆曲线方程:
$y^2 = x^3 + ax + b\bmod n$
$b = y^2 - x^3 - ax\bmod n$
在Sage中,可以通过替换 x 和 y 值求出 b,如下所示:
1 | M = 93556643250795678718734474880013829509320385402690660619699653921022012489089 |
再求得P的阶,然后将其分解,sage 如下。
1 | M = 93556643250795678718734474880013829509320385402690660619699653921022012489089 |
之后就是求分解后对应的阶下也就是 $P_0$ 对应的 $l_i$ 了,这个我们也可以用 sage 里的 discrete_log 函数来直接完成:
1 | primes = [4, 3, 5, 7, 137, 593, 24337, 25589, 3637793, 5733569, 106831998530025000830453, 1975901744727669147699767] |
可以看到有两个阶的 $l_i$ 没有算出来,不过这并不影响我们得到结果,得到了这些以后我们就可以利用中国剩余定理来求解了,而这也可以直接在 sage 里使用 crt 函数来调用:
1 | primes = [4, 3, 5, 7, 137, 593, 24337, 25589, 3637793, 5733569] |
完整代码:
1 | M = 93556643250795678718734474880013829509320385402690660619699653921022012489089 |