ECDSA算法(深入浅出密码学笔记)
ECDSA标准中的步骤与DSA方案的步骤在概念上紧密相连,但ECDSA中的离散对数问题是在椭圆曲线群中构建起来的。因此,实际计算一个ECDSA签名所执行的算术运算与DSA中的完全不同。
ECDSA标准是针对素数域 Z p \mathbb{Z}_p Zp和有限域 G F ( 2 m ) GF(2^m) GF(2m)上的椭圆曲线定义的
密钥生成
- 使用椭圆曲线 E E E,其中:模数为 p p p;系数为 a a a和 b b b;生成素数阶 q q q的循环群的点A
- 选择一个随机整数 d d d,且 0 < d < q 0<d<q 0<d<q.
- 计算 B = d A B=dA B=dA
密钥为:
k
p
u
b
=
(
p
,
a
,
b
,
q
,
A
,
B
)
k_{pub}=(p,a,b,q,A,B)
kpub=(p,a,b,q,A,B)
k
p
r
=
(
d
)
k_{pr}=(d)
kpr=(d)
注意:我们已经建立了一个离散对数问题,其中整数d为私钥,标量乘法的结果点B为公钥。与DSA一样,循环群的阶是q;而为了达到更高的安全等级,这个数的长度大小应该大于等于160位。
签名与验证
与DSA一样, E C D S A ECDSA ECDSA签名由一对整数 ( r , s ) (r,s) (r,s)组成,其中每个值的位长度都与 q q q相同,这也有助于实现十分简洁的签名。使用公钥和私钥计算消息 x x x的签名的方式如下:
ECDSA签名生成
- 选择一个整数作为随机临时密钥 k E k_E kE,且 0 < k E < q 0<k_E<q 0<kE<q。
- 计算 R = k E A R=k_EA R=kEA。
- 设置 r = x R r=x_R r=xR。
- 设置 s ≡ ( h ( x ) + d ⋅ r ) k E − 1 m o d q s\equiv(h(x)+d\cdot r)k_E^{-1} \mod q s≡(h(x)+d⋅r)kE−1modq。
在步骤3中,点R的x坐标赋给变量r。在计算s时,必须使用函数h对消息x进行哈希。哈希函数的输出长度必须至少与q一样长。
ECDSA签名验证
- 计算辅助值 w ≡ s − 1 m o d q w\equiv s^{-1} \mod q w≡s−1modq。
- 计算辅助值 u 1 ≡ w ⋅ h ( x ) m o d q u_1\equiv w\cdot h(x) \mod q u1≡w⋅h(x)modq。
- 计算辅助值 u 2 ≡ w ⋅ r m o d q u_2\equiv w\cdot r \mod q u2≡w⋅rmodq。
- 计算 P = u 1 A + u 2 B P=u_1A+u_2B P=u1A+u2B。
- 验证
v
e
r
k
p
u
b
(
x
,
(
r
,
s
)
)
ver_{k_{pub}}(x,(r,s))
verkpub(x,(r,s))为:
若 x p ≡ r m o d q x_p\equiv r \mod q xp≡rmodq则为有效签名;
若 x p ≢ r m o d q x_p \not\equiv r \mod q xp≡rmodq则为无效签名。
最后一步中的 x p x_p xp表示点P的x坐标。只有当 x p x_p xp与签名参数r模q相等时,验证者才会接受签名(r,s);否则,此签名将被看做时无效的。
证明就不放了,放个小例子吧
举例
首先,椭圆曲线为: E : y 2 ≡ x 3 + 2 x + 2 m o d 17 E:y^2\equiv x^3+2x+2 \mod 17 E:y2≡x3+2x+2mod17
B o b 选 择 p = 17 , a = 2 , b = 2 的 曲 线 E 和 q = 19 的 点 A = ( 5 , 1 ) 。 选 择 d = 7 ; 计 算 B = d A = 7 ⋅ ( 5 , 1 ) = ( 0 , 6 ) Bob选择p=17,a=2,b=2的曲线E和q=19的点A=(5,1)。选择d=7;计算B=dA=7\cdot(5,1)=(0,6) Bob选择p=17,a=2,b=2的曲线E和q=19的点A=(5,1)。选择d=7;计算B=dA=7⋅(5,1)=(0,6)
B o b 向 A l i c e 发 送 公 钥 ( p , a , b , q , A , B ) = ( 17 , 2 , 2 , 19 , ( 5 , 1 ) , ( 0 , 6 ) ) Bob向Alice发送公钥(p,a,b,q,A,B)=(17,2,2,19,(5,1),(0,6)) Bob向Alice发送公钥(p,a,b,q,A,B)=(17,2,2,19,(5,1),(0,6))
签 名 : B o b 计 算 消 息 h ( x ) = 26 的 哈 希 值 ; 选 择 临 时 密 钥 k E = 10 , R = 10 ⋅ ( 5 , 1 ) = ( 7 , 11 ) , r = x R = 7 , s = ( 26 + 7 ⋅ 7 ) ⋅ 2 ≡ 17 m o d 19 签名:Bob计算消息h(x)=26的哈希值;选择临时密钥k_E=10,R=10\cdot (5,1)=(7,11),r=x_R=7,s=(26+7\cdot 7)\cdot 2\equiv 17 \mod 19 签名:Bob计算消息h(x)=26的哈希值;选择临时密钥kE=10,R=10⋅(5,1)=(7,11),r=xR=7,s=(26+7⋅7)⋅2≡17mod19
发 送 签 名 : ( x , ( r , s ) ) = ( x , ( 7 , 17 ) ) 发送签名:(x,(r,s))=(x,(7,17)) 发送签名:(x,(r,s))=(x,(7,17))
A
l
i
c
e
方
验
证
:
Alice方验证:
Alice方验证:
w
=
1
7
−
1
≡
9
m
o
d
19
w=17^{-1}\equiv9 \mod 19
w=17−1≡9mod19
u
1
=
9
⋅
26
=
6
m
o
d
19
u_1 =9\cdot 26=6 \mod 19
u1=9⋅26=6mod19
u
2
=
9
⋅
7
≡
6
m
o
d
19
u_2=9\cdot7\equiv6\mod 19
u2=9⋅7≡6mod19
P
=
6
⋅
(
5
,
1
)
+
6
⋅
(
0
,
6
)
=
(
7
,
11
)
P=6\cdot(5,1)+6\cdot(0,6)=(7,11)
P=6⋅(5,1)+6⋅(0,6)=(7,11)
x
p
≡
r
m
o
d
19
⇒
有
效
的
签
名
x_p\equiv r \mod 19\Rightarrow 有效的签名
xp≡rmod19⇒有效的签名
Python实现
需要引入模块ecdsa
import ecdsa
选取一个椭圆曲线,这里以NIST256p为例
gen = ecdsa.NIST256p.generator
order = gen.order()
ecdsa模块中有封装好了的函数可以赋值直接生成ecdsa公钥,私钥的对象
# 生成私钥d_A
d_A = random.randrange(1,order-1)
# 生成公私钥对象
public_key = ecdsa.ecdsa.Public_key(gen,gen * d_A)
private_key = ecdsa.ecdsa.Private_key(public_key,d_A)
数字签名
message = "message"
m = int(hashlib.sha1(message.encode("utf8")).hexdigest(),16)
# 临时密钥
k = random.randrange(1,order-1)
# 签名
signature = private_key.sign(m,k)
r = signature.r
s = signature.s