域参数
我们的椭圆曲线算法是基于有限域上椭圆曲线的循环子群,所以一般需要以下参数:
- 素数 p p p定义有限域的小。
- 椭圆曲线方程的系数a和b。
- 生成循环子群的基点 G G G。
- 子群的阶 n n n。
- 子群的协因子 h h h。
注意:当 p = h n p = hn p=hn时(即当有限域的阶等于椭圆曲线的阶的时候),曲线易受到Smart的攻击,这个攻击可以在传统计算机上在多项式时间内解决离散对数问题。
ECC
- 私钥:从 1 , . . . , n − 1 {1,...,n-1} 1,...,n−1中任意选取一个整数 d d d(n为子群的阶)。
- 公钥是点 H = d G H = dG H=dG(G为子群的基点)。
ECDH
ECDH是一种密钥交换协议,是DH的变体。ECDH可以让通信双方在互相不了解的情况下,在第三方信道上建立共享密钥。ECDH与DH的密钥协商流程基本一致,DH基于模幂与离散对数计算困难性问题,而ECDH是基于标量乘法与基于椭圆曲线的离散对数问题。
ECDH协议流程
设Alice和Bob为通信双方。首先Alice和Bob选定公共参数(CURVE,G)。其中CURVE为椭圆曲线,G为基点,Alice和Bob之后基于椭圆曲线的计算都要在所选的CURVE上。具体计算流程如下:
- Alice随机选取一个数 d A d_A dA, 计算标量乘法 P A = d A ⋅ G P_A = d_A \cdot G PA=dA⋅G。将 P A P_A PA发送给Bob。
- Bob随机选取一个数 d B d_B dB,计算标量乘法 P B = d B ⋅ G P_B = d_B \cdot G PB=dB⋅G。将 P B P_B PB发送给Alice。
- Alice对收到的 P B P_B PB计算标量乘法 P B A = d A ⋅ P B P_{BA} = d_A\cdot P_B PBA=dA⋅PB。Bob对收到的 P A P_A PA计算标量乘法 P A B = d B ⋅ P A P_{AB} = d_B\cdot P_A PAB=dB⋅PA。
- P B A = d A ⋅ d B ⋅ G = P A B = d B ⋅ d A ⋅ G P_{BA} = d_A\cdot d_B \cdot G= P_{AB} = d_B\cdot d_A\cdot G PBA=dA⋅dB⋅G=PAB=dB⋅dA⋅G,即为共享密钥。可以用于后续的对称加密通信。
说明:在标量乘法 P = k ⋅ G P = k\cdot G P=k⋅G中,已知标量 k k k,计算 k ⋅ G = P k\cdot G = P k⋅G=P是容易的,已知 P P P和 G G G,计算标量 k k k是困难的。所以当有敌手劫取了Alice发给Bob的 P A P_A PA和Bob发给Alice P B P_B PB,也无法计算出Alice和Bob选取的随机数 d A d_A dA或者 d B d_B dB,进而无法计算出共享密钥 d A ⋅ d B ⋅ G d_A \cdot d_B\cdot G dA⋅dB⋅G。
ECDSA
ECDSA是数字签名算法,是DSA的变体。在数字签名算法中,消息发送方对消息进行签名,消息接收方对消息验签,这样能够保证数据的完整性(保证消息内容未被第三方篡改)、消息源鉴别(确定消息是由本人发出,而不是他人伪造)和不可否认性(消息发送方无法否认自己发出过这则消息)。
ECDSA流程
签名
消息发送方并不是对消息本身进行签名,而是对消息的哈希值进行签名。消息的哈希值长度仅保留
t
t
t位。
t
t
t是椭圆曲线上子群的阶的位数。我们把处理后的消息记为
z
z
z。
- 消息发送方A选取私钥 d A ∈ [ 1 , n − 1 ] d_A\in[1,n-1] dA∈[1,n−1],其中 n n n为椭圆曲线上子群的阶,计算公钥 P = d A ⋅ G P = d_A\cdot G P=dA⋅G,并公开公钥 P P P。
- 发送方A随机选取一个随机数 k ∈ [ 1 , n − 1 ] k\in[1,n-1] k∈[1,n−1],选取的 k k k必须是随机且保密的,计算标量乘 Q = k ⋅ G Q = k\cdot G Q=k⋅G。
- 计算 r = x Q m o d n r = x_Q~mod~n r=xQ mod n.
- 如果 r = 0 r = 0 r=0,就换一个 k k k试试。
- 计算 s = k − 1 ( z + r ⋅ d A ) m o d ( n ) s = k^{-1}(z + r\cdot d_A)~mod~(n) s=k−1(z+r⋅dA) mod (n)。
- 如果 s = 0 s = 0 s=0,换一个 k k k试试。
- (r,s)即为签名。
验签:
为了验签,我们需要Alice的公钥
H
A
H_A
HA,截断的哈希值
z
z
z和签名(r,s)。
- 计算整数 u 1 = s − 1 z m o d n u_1 = s^{-1}z mod~n u1=s−1zmod n.
- 计算整数 u 2 = s − 1 r m o d n u_2 = s^{-1}r mod~n u2=s−1rmod n.
- 计算点
P
=
u
1
G
+
u
2
H
A
P = u_1G+u_2H_A
P=u1G+u2HA.
如果 r = x p m o d n r = x_p mod~n r=xpmod n,那么签名就是合法的。
k k k的重要性
在生成ECDSA算法的签名时, k k k必须是保密的且随机的。否则攻击者可以计算出我们的私钥(公式可推导)。
计算椭圆曲线离散对数的高效算法
Baby step, Giant step Algorithm:一种中间相遇攻击
给定椭圆曲线上的两个点
P
P
P和
Q
Q
Q,计算
x
x
x,使得
Q
=
x
P
Q = xP
Q=xP。点P和Q都在椭圆曲线的一个循环子群中,循环子群的阶为n,基点为G。
令x = am+b,则
Q
=
(
a
m
+
b
)
P
Q = (am+b)P
Q=(am+b)P,即
Q
−
a
m
P
=
b
P
Q-amP = bP
Q−amP=bP
计算步骤如下:
- 对于每一个 b ∈ [ 0 , m ] b\in[0,m] b∈[0,m],计算 b P bP bP,并把这些结果存储在一个哈希表中。
- 对于每一个
a
∈
[
0
,
m
]
a\in[0,m]
a∈[0,m]:
计算 a m P amP amP.
计算 Q − a m P Q-amP Q−amP.
在哈希表中查找是否存在 Q − a m P = b P Q-amP = bP Q−amP=bP,若存在, 则 x = a m + b x = am+b x=am+b.
时间复杂度:我们最多进行2m次加法和乘法。如果查找哈希表的时间视为O(1)。时间和空间复杂度都为O(n),(或者O(2^{2/k},如果按位长度来计算)。
Pollard’s
ρ
\rho
ρ Algorithm:
时间复杂度为O(n),空间复杂度为O(1)。