2021SC@SDUSC
在上一篇中介绍了实数域下的椭圆曲线的相关运算,但在实际的加密过程中使用的是离散量而不是连续量(这是由小数不能参加模运算决定的),因此不能使用椭圆曲线方程
y
2
=
x
3
+
a
x
+
b
y^2 = x^3 +ax + b
y2=x3+ax+b 。我们说的ECDSA椭圆曲线数字签名算法要使用如下方程:
y
2
=
(
x
3
+
a
x
+
b
)
m
o
d
p
y^2=(x^3+ax+b)\,mod\,p
y2=(x3+ax+b)modp
由于该图像不再是连续图像,因此呈现在坐标系中是离散的点,直观上看上去不再是“椭圆曲线”,但是实数域下的椭圆曲线图像的一些性质还在这个方程中得以保留,本篇将以次方程为基础,讲解有限域下的椭圆曲线方程。
模运算和有限域
模运算
模运算中加法减法乘法比较简单,对一个数的模运算结果实际上就是让这个数除以模的数得到的余数。下面主要介绍加法逆、乘法逆和除法运算。在求逆元前我们首先要知道的是单位元,对于一种运算单位元可以唯一确定,不同运算的单位元不一定相同,比如定义在整数集合上的加法运算单位元就是0,而同样定义在整数集合上的乘法运算则是1。
因此对于定义在集合{0,1,2……,p-1}上的模p加法运算而言,它的单位元要满足集合内任何一个整数加上该单位元之后取模得到的结果不变,于是我们很自然想到0就是模p加法运算的单位元;同理,1就是模p乘法运算的单位元。
接下来有了单位元我们就可以讨论逆元了,模p加法运算中一个元素的逆元要满足这个元素加上他的逆元再取模之后得到的结果是模p加法运算的单位元0,其实这个结果是很显然的,我们只需用p减去这个元素就可以得到这个逆元了,如在模23加法运算中5的逆元就是18。
于是下面我们将注意力放到模p乘法运算中,事实上要求得乘法逆元并不是一件容易的事情,但是验证比较简单,一个元素的乘法逆元只需满足这个元素乘以他的逆元再取模之后得到的结果是单位元1,如在模23乘法运算中9的逆元就是18,这是因为(9×18)mod 23 = 1。具体的计算方法需要用到扩展欧几里得算法,我会在以后的博客中说明,在此不再赘述。
有了乘法逆元接下来说除法运算,定义 ( a / b ) m o d p = ( a b − 1 ) m o d p ( a / b ) mod\,p=( a b^{-1} ) mod\,p (a/b)modp=(ab−1)modp ,即 ( a / b ) m o d p ( a / b )\,mod\,p (a/b)modp结果为a乘以mod p运算下b的乘法逆 b − 1 b^{-1} b−1。
有限域
在ECDSA椭圆曲线数字签名算法中仅仅定义一个“加法”运算是不够的,还需要引入一个“乘法”运算,这里的“加法”和“乘法”对应的是有限域GF(p)上的模p加法运算和模p乘法运算。与之前的连续椭圆曲线方程不同,由于模运算使得集合成为一个有限整数集合(之前的连续椭圆曲线方程取的x值y值是无限的实数),有限域由此得名。
关于域F对其上两个运算的要求,可以概括为三点:
第一,F对加法组成一个交换群。可以理解为如果把乘法运算剔除,单独把数据集合和加法运算拿出来就满足交换群的五个条件(参见上一篇博客)。
第二,除去0,F对乘法组成一个交换群。除去0元素是因为由于0元素的加入使得“逆元”条件无法成立,即对0元素找不到它的逆元使得0乘以它的逆元再模p结果为1。
第三,分配律成立,对F中的任意元素a、b、c,有a(b+c)=ab+ac和(a+b)c=ac+bc成立。
有限域上的椭圆曲线
这段的标题是有限域上的椭圆曲线,那么我们上次研究的椭圆曲线是什么呢?很显然我们连续的椭圆曲线是基于所有连续实数的,也就是说椭圆曲线的横纵坐标可以取全体实数,也就是实数域(当然x取值实际上是有限制的,不能取值过小导致 x 3 + a x + b x^3 +ax + b x3+ax+b 小于0使得y在实数范围内不能取值)。那么有限域上的椭圆曲线就是说我只能取有限域上的点,作为横纵坐标,得到椭圆曲线上的点。
那么我们先来研究有限域上的点,先对有限域中的一些参数命名:
规定有限域(galois field)的阶为p,一个阶为p的有限域为GF(p),表示在这个有限域中只有p个元素。这里的p与
y
2
=
(
x
3
+
a
x
+
b
)
y^2 = (x^3 +ax + b)
y2=(x3+ax+b) mod p 中的p是一个。有限域中的取值集合就是{0,1,2……,p-1},那么接下来我们可以定义有限域上的加法乘法模运算,满足域对加法乘法模运算的三个要求条件。
接下来我们将椭圆曲线给放到有限域中。
首先构造坐标系。构造一个x∈[0,p-1],y∈[0,p-1]的坐标系,注意这里x和y取值必须是整数,由于我们的域是一个有限域,因为我们只取了x和y均为整数且在区间[0,p-1]内的点,那么这个坐标系内的点完全是可数的。
然后在坐标系中放入椭圆曲线。椭圆曲线上的点的横纵坐标必须满足
y
2
=
(
x
3
+
a
x
+
b
)
m
o
d
p
y^2 = (x^3 +ax + b)mod\,p
y2=(x3+ax+b)modp ,因此我们完全可以确定这样的点有几个,但在椭圆曲线密码算法里面我们往往还需要加上一个无穷远点,我们令这时点的个数为n。
有限域上椭圆曲线上的点和有限域上椭圆曲线上的运算会构成一个群,椭圆曲线上的有限点个数n称为该群的秩Order。下面定义有限域上椭圆曲线的运算即几何加法运算。我们可以重新思考连续椭圆曲线上的我们定义的运算法则了,有限域上的椭圆曲线几何加法和连续椭圆曲线上的几何加法法则一致,对于两点P和Q,定义P+Q的结果为P和Q的连线交有限域内一点,该点关于“某条线”的在有限域内的对称点即为P+Q的结果R点。这里存在与连续椭圆曲线不一致的两个问题:
第一,P和Q的连线可能不再那么自然,在一个无限大的坐标平面中我们可以随意地画一条直线,但在模运算中这个坐标系是有边界的,这条直线如果画出来直观上看会呈现一定的周期性。
第二,这里的某条线不能再是横轴了,因为我们令坐标系中x∈[0,p-1],y∈[0,p-1],因此这条对称直线实际上就是y=p/2,这里的p就是有限域的阶。关于这点的证明可以通过设域中的一点坐标,找到纵坐标关于y=p/2的对称点,代入原来的横坐标看等式两边是否能保持成立。
下面的图可以帮助理解这些概念,同时也可以看到图像是关于y= p/2 =6.5对称的。
那么你可能想要计算出实际的点坐标,但在这里我们不再需要重新推导新的公式了,你可以在上一篇博客中找到连续曲线的公式,在这里同样适用,只需在最后取模(本例中p=13)即可。下面以上图为例,介绍运算过程。
图中有P(6,6)Q(7,3),p=13:
求斜率
m
=
y
P
−
y
Q
x
P
−
x
Q
m
o
d
p
=
(
y
P
−
y
Q
)
(
x
P
−
x
Q
)
−
1
m
o
d
p
有
(
y
P
−
y
Q
)
=
3
,
(
x
P
−
x
Q
)
=
−
1
其中求
(
x
P
−
x
Q
)
=
−
1
的乘法逆元
(
x
P
−
x
Q
)
−
1
用扩展欧几里得算法可以求得
−
1
模
13
的乘法逆元为
12
即
(
x
P
−
x
Q
)
−
1
=
12
则
m
=
3
×
12
m
o
d
13
=
−
3
代入
x
R
′
=
(
m
2
−
x
P
−
x
Q
)
m
o
d
p
得
x
R
′
=
9
代入
y
R
′
=
y
P
+
m
(
x
R
′
−
x
P
)
m
o
d
p
得
y
R
′
=
10
找
R
′
关于直线
y
=
p
/
2
的对称点,横坐标不变
x
R
=
x
R
′
y
R
=
p
−
y
R
′
=
3
求斜率m=\frac{y_P-y_Q}{x_P-x_Q} \,mod\,p=(y_P-y_Q)(x_P-x_Q)^{-1} mod\,p\\ 有(y_P-y_Q)=3,(x_P-x_Q)=-1\\其中求(x_P-x_Q)=-1的乘法逆元(x_P-x_Q)^{-1}\\用扩展欧几里得算法可以求得-1模13的乘法逆元为12\\即(x_P-x_Q)^{-1}=12\\则m=3×12 mod 13 = -3\\ 代入x_R' =( m^2 - x_P - x_Q )mod\,p 得 x_R' = 9\\ 代入y_R' = y_P + m (x_R' - x_P) mod\,p 得 y_R' = 10\\找R'关于直线y=p/2的对称点,横坐标不变x_R=x_R' \\y_R = p - y_R' =3
求斜率m=xP−xQyP−yQmodp=(yP−yQ)(xP−xQ)−1modp有(yP−yQ)=3,(xP−xQ)=−1其中求(xP−xQ)=−1的乘法逆元(xP−xQ)−1用扩展欧几里得算法可以求得−1模13的乘法逆元为12即(xP−xQ)−1=12则m=3×12mod13=−3代入xR′=(m2−xP−xQ)modp得xR′=9代入yR′=yP+m(xR′−xP)modp得yR′=10找R′关于直线y=p/2的对称点,横坐标不变xR=xR′yR=p−yR′=3
可以看到和上图给出的结果一致。
标量乘法与循环子群
在定义了有限域上的椭圆曲线的点集和椭圆曲线上的几何加法运算之后我们就可以再说明他的标量乘法运算了,这里还是需要注意,标量乘法运算不是这个群上的新运算,有限域上的椭圆曲线构成的群只有一个几何加法运算,标量乘法运算本质上还是几何加法运算。
下面开始对有限域上椭圆曲线的标量乘法运算给出说明。有了前面连续椭圆曲线上的铺垫,其实标量乘法不过是n个点做加法运算,这里我们令点为P,给定一点P,经过标量乘法运算之后得到的点必定还在这个有限域中,那么我们现在的问题是如何计算P+P得到的点的坐标。回忆在连续椭圆曲线上的公式,其实就是找椭圆曲线P点的切线交椭圆曲线于一点,然后关于x轴对称。那么我们现在的问题是在有限域中全都是离散点,无从找切线。那么其实在这里我们的切线斜率还是可以使用连续椭圆曲线推导出来的切线求导公式:
m
=
3
x
P
2
+
a
2
y
P
m
o
d
p
m =\frac {3 x_P^2 + a} { 2 y_P }\, mod\,p
m=2yP3xP2+amodp,比如下图的例子:
图中有P(3,6),p=17:
m
=
3
x
P
2
+
a
2
y
P
m
o
d
p
=
(
3
x
P
2
+
a
)
(
2
y
P
)
−
1
m
o
d
p
3
x
P
2
+
a
=
29
下面要求
2
y
P
=
12
的乘法逆元
用扩展欧几里得算法可以求得
12
的乘法逆元为
10
于是
m
=
(
29
×
10
)
m
o
d
17
=
1
代入
x
Q
′
=
(
m
2
−
2
x
P
)
m
o
d
p
得
x
Q
′
=
12
代入
y
Q
′
=
y
P
+
m
(
x
Q
′
−
x
P
)
m
o
d
p
得
y
Q
′
=
15
找
Q
′
关于直线
y
=
p
/
2
的对称点,横坐标不变
x
Q
=
x
Q
′
y
Q
=
p
−
y
Q
′
=
2
m =\frac {3 x_P^2 + a} { 2 y_P }\, mod\,p=(3 x_P^2 + a)(2 y_P)^{-1}\, mod\,p\\ 3 x_P^2 + a=29\\下面要求 2 y_P =12 的乘法逆元\\用扩展欧几里得算法可以求得12的乘法逆元为10\\于是m=(29×10)mod\,17=1\\代入x_Q' =( m^2 - 2x_P ) mod\,p 得 x_Q' = 12\\代入y_Q' = yP + m (x_Q' - x_P) mod\,p 得 y_Q'= 15\\找Q'关于直线y=p/2的对称点,横坐标不变x_Q=x_Q'\\y_Q = p - y_Q' =2
m=2yP3xP2+amodp=(3xP2+a)(2yP)−1modp3xP2+a=29下面要求2yP=12的乘法逆元用扩展欧几里得算法可以求得12的乘法逆元为10于是m=(29×10)mod17=1代入xQ′=(m2−2xP)modp得xQ′=12代入yQ′=yP+m(xQ′−xP)modp得yQ′=15找Q′关于直线y=p/2的对称点,横坐标不变xQ=xQ′yQ=p−yQ′=2
可以看到计算结果和上图一致,以此类推可以计算出3P、4P……
但是我们很容易就会想到一个问题,在实数域中点是无穷多的,而在有限域中点的个数是有限的,比如在这个图中算上无穷远点一共也就22个点而已,由于椭圆曲线群的封闭性,我们最多把P加22次就会产生循环,椭圆曲线中的点很快就会耗尽。但我们又会想到,如果把p取非常大,也就说我们有足够大的有限域,那么我们的群中应该就会有非常多的点集,这样的话应该不会特别容易产生循环。但对于22个点的这个图来说,事实上不用把n加22次,只要加11次就重合了。比如对上图n=2时,我们在n=13就会得到与之完全相同的Q点:
显然我们得到了一个原椭圆曲线群的一个循环子群,循环子群的元素个数为12,点P可看作这个循环子群的一个生成元。
那么我们猜想的增大p让有限域足够大会不会让循环子群更大,大到可以与这个椭圆曲线相同呢。下面我们尝试增大p:
在这个图里面p=97,那么其中一点P(3,6)生成的循环子群会不会更大一点呢?很不幸的是,最终只循环五次(上图n=2,下图n=7)就回到原点了,也就是说循环子群元素个数只有5:
也就是说仅仅增大p并不能得到我们期望的结果,如果只有这么几个点其实在密码中想要攻破私钥是非常简单的,因为我们只需尝试几个就可以找到。因此我们要综合考量椭圆曲线的两个参数a和b的取值,P点的选取,以及选一个足够大的素数p,才能让循环子群足够大,大到可以遍历椭圆曲线群内全部的点。事实上这样的一组参数已经找到了,它在一定程度上可以保证安全性,满足这组参数的椭圆曲线和基准点P就是secp256k1椭圆曲线。
到此为止ECDSA主要的数学原理已经解释完毕,下一篇博客我会结合代码具体解释ECDSA椭圆曲线数字签名算法原理。