![12bd53ecf55f9554e110c08b8c416465.png](https://i-blog.csdnimg.cn/blog_migrate/9c841fccaa1a55b9179f52e44e315abd.jpeg)
原文题目:Elliptic Curve Cryptography: finite fields and discrete logarithms
椭圆曲线密码体制:有限域和离散对数
这个帖子是ECC系列的的第二章:一个简单的介绍。
在之前的帖子中,我们可以发现在实数范围内椭圆曲线可以被用来定义一个群。特别地,我们定义了一个点加法的规则:给出三个不相同的点,他们的和为0。我们可以得到关于计算点加法的几何解法和算数解法。
之后,我们介绍了纯数乘法,并发现了计算数乘的简单算法:倍乘和相加。
现在,我们有限域范围内限制我们的椭圆曲线,而不是在实数集内,我们可以看到它是如何变化的。
模p的整数域
首先,限定域的意思,就是说限定元素的数量。举个限定域的例子,一整套关于模p的整数域,其中p是质数,通常记为,ℤ/p,或我们选择后者作为标记符号。
在这个域里面,我们有两种操作:加法和乘法。两种运算都是封闭的,相关的和可交换的。对于两种操作,域里都存在着一种唯一的特性元素,对于每一个元素,域里都存在和它特定的逆元素。最后,关于加法的乘法分配律:。
一系列关于模p的整数包括所有从0到p-1整数。加法和乘法作为模算法(亦可被理解为“时钟算法”)的方式。这里,我们给出几个关于在域的实际例子:
- 加法:
- 减法:
- 乘法:
- 加法逆运算:
- 乘法逆运算:
如果这些等式对于你来说看起来不相似,那么你需要知道质数的模算法,具体可以参考Khan Academy。
正如我们之前所说,关于模p的整数是一个域,因此上面列出来的所有的性质都是成立的。注意,p是质数尤为重要!一系列关于模4的整数不存在域:2就没有乘法可逆性(例如:方程)。
模p的除法
我们即将定义了在上的椭圆曲线,但是在此之前我们需要明确一点,那就是在上x/y是否有意义?简言之,或者说,x除以y相当于x乘以y的乘法逆。这个现象没有什么奇怪的,但是给我们一个关于实施除法的基本方法,那就是找到这个数的乘法逆,然后对它实施简单的乘法即可。
扩展欧几里得算法,可以简单的计算出一个数的乘法逆,如果考虑比特长度,算法复杂度为(或),这无疑是最糟糕的方案。
我们不会详细介绍扩展的Euclidean算法,因为它与主题无关,但是这里有一个的Python可以实现:
def extended_euclidean_algorithm(a, b):
"""
Returns a three-tuple (gcd, x, y) such that
a * x + b * y == gcd, where gcd is the greatest
common divisor of a and b.
This function implements the extended Euclidean
algorithm and runs in O(log b) in the worst case.
"""
s, old_s = 0, 1
t, old_t = 1, 0
r, old_r = b, a
while r != 0:
quotient = old_r // r
old_r, r = r, old_r - quotient * r
old_s, s = s, old_s - quotient * s
old_t, t = t, old_t - quotient * t
return old_r, old_s, old_t
def inverse_of(n, p):
"""
Returns the multiplicative inverse of
n modulo p.
This function returns an integer m such that
(n * m) % p == 1.
"""
gcd, x, y = extended_euclidean_algorithm(n, p)
assert (n * x + p * y) % p == gcd
if gcd != 1:
# Either n is 0, or p is not a prime number.
raise ValueError(
'{} has no multiplicative inverse '
'modulo {}'.format(n, p))
else:
return x % p
在上的椭圆曲线
现在我们有了所有必要的元素在上限制椭圆曲线,这一系列的点,在之前的帖子里已经给出:
现在变为:
其中,0始终是定义的那个点,a和b是在内的两个整数。
![f99ac4ee0e0d3c8c840b19d46b7ebce2.png](https://i-blog.csdnimg.cn/blog_migrate/141e62a77379a60454ff4e635b9ae41f.jpeg)
曲线,其中。可以看到,对于每一个,都有两个点,且这两个点是关于 对称。
![30746287f6a16ada01bf507c1a56bcae.png](https://i-blog.csdnimg.cn/blog_migrate/91cf4d04aaf84d50749cd5dadb39dea7.png)
曲线 是奇异的,它有在(0,0)处有一个三重点,因此它不是一个有效的椭圆曲线。
以前的连续曲线,而现在是平面上的一系列不连续点。但是我们可以证明,即使我们限制了我们的域,在上的椭圆曲线,仍然可以构成一个阿贝尔群。
点加法
很明显,为了让加法在上仍然有效,我们需要对加法的定义进行一点小的改变。在实数区域,我们认为在一条直线的三个点的和是0。为了继续保持这个定义,但是这不意味着在上一条直线上的三个点仍然和为0.
如果这里存在一条线可以连接它们,那么我们可以说三个点是在一条线上的。当然,现在,线在域上和在实数域ℝ是不同的。同样地,我们可以说,一系列点在域的直线是满足方程,(这是一个标准的直线方程,只是添加了mod p)。
![5e6e795fa4981dfac7d8f6a7b05c9653.png](https://i-blog.csdnimg.cn/blog_migrate/707db8fcbf23bf27221f07e8fa7b696f.png)
在曲线上添加点和,发现在这个平面内,直线是如何连接这些“重复”的点。
鉴于我们在这个群里面,点加法仍然保持我们已经知道的性质:
- (从特定元素的定义得出)
- 对于任意的非零Q,它的逆-Q和它有着相同的横坐标和相反的纵坐标。或者把它记为-Q=( mod p)。例如,如果在域里曲线有一个点,那么有。
- 同样地,(从逆元素的定义得出)
代数和
除了我们需要在每个表达式后面添加“mod p”,关于计算点加法的方程和之前帖子的内容是完全一样。所以,给出,和,我们就可以计算:
其中
如果 ,斜率表示为:
否则,如果,那么有,
方程没有发生改变,这不是巧合,事实上,这些方程在任何域都是适用的,限定或者非限定(除了和外,这两个是特殊的情况)。现在,我认为我可以提供关于这个现象的一个解释。而问题是:证明这些群法则通常需要复杂的数学概念。然而,我发现关于Stefan Friedl的证明仅仅只需要元素的概念。如果你有对这些在任何域都能适用的方程兴趣,可自行阅读。
回到刚才,我们不会去定义几何算法,事实上,确实存在几个问题。举例来说,在之前的帖子中,我们说,如果要计算P+P,需要知道在P处曲线的正切值。但是,如果没有连续性,关于正切值这个概念将没有任何意义。我们可以绕过这个问题,而纯几何算法太复杂,也不具有实际可操作性。
相反地,你可以利用我写好的计算点加法的交互工具来玩玩看。
椭圆曲线群的阶
我们说到在限定域里的椭圆曲线有几个限定的点。那么更为重要的问题是,我们要问了:到底有多少个点呢?
首先,我们先来说说在一个群里的几个点,称之为群的阶。
在计算点的时候,试图从0到p-1计算所有x的可能值不是一个可行的方法,这个需要个步骤,当质数p非常大的时候是非常困难的。
幸运的是,有一个很快的算法去计算这个阶,那就是Schoof算法。我不会去将关于这个算法的细节,这需要大量的运行时间,这不是我们所需要的。
纯量的乘法和循环子集
对于实数而言,乘法可以被定义为:
我们再次使用倍乘和加法算法去实现一个需要步骤的乘法(或),这里k指的是n的字节数。我也已经写了一个交互工具来实行一个纯量的乘法。
在域上关于椭圆曲线上的点的乘法,是具有有趣的性质的。考虑曲线 和点 ,现在计算所有P的倍数。
![7b3a36ba4bef55cc61e3cfacdc5f48a1.png](https://i-blog.csdnimg.cn/blog_migrate/242e8378b7703999d9177db3f7a7d5f9.png)
点的倍数只有五个不同的点(0,1P,2P,3P和4P),并且它们是重复循环的。很容易找到在椭圆曲线上的纯数乘法和模算法上的加法两者的相似性。
- …
这里,我们可以马上发现两个事情:第一,P的倍数只有五个:椭圆曲线上其他点不会出现;第二,这些点是重复循环的。我们可以这么写:
对于每一个整数k,可以看出五个方程是可以简化成一个方程的,那就是模形式:。
不仅如此,但是我们可以马上证明这五个点在加法运算中是封闭的,这也就意味着虽然我加了,结果始终是这五个点,其他椭圆曲线上的点是不会出现的。
不仅仅是对点P=(3,6),这对于任意一个点都是成立的。事实上,如果我们拿出一个P,都有:
这也就意味着:如果我们加入两个P的倍数,我们可以得到一个P的倍数(也就是说,在加法运算中,P的倍数是封闭的)。这足够能证明一系列P的倍数在椭圆曲线组成的群上是一个循环子群。
子群就是另一个群的子集。一个循环子群意味着子群里的任意元素都是循环重复的,就像我们之前举过的例子。点P可以被称为是这个循环子群的产生着或者基点。
循环子群就是ECC和其他密码学的基础,在之后的帖子里我们可以看出原因。
子群阶
我们自问道:什么是通过点P产生的子群的阶(或者说,什么是P的阶?)。回答这个问题,我们不能使用Schoof算法,因为这种算法只有在完整的群上椭圆曲线才成立,而不是单一的子群上。在解决这个问题之前,我们需要知道以下几点:
- 目前为止,我们已经定义了许多点的群的阶。这种定义一直是有效的,但是在一个循环子群里我们可以给出一个新的定义:P的阶是最小的正整数n,例如。事实上,如果你注意到之前的例子,那个子群中包含五个点,且有。
- 根据Lagrange理论,P的阶是和椭圆曲线的阶相关的,这就意味着子群的阶是可以被主群的阶所整除的的。换句话说,如果椭圆曲线上包含了N个点,其中一个子群包含n个点,那么N能整除n。
这两条信息共同告诉我们一个寻找基于点P的子群的阶的方法:
- 利用Schoof算法计算椭圆曲线的阶N;
- 寻找到N的所有因数;
- 对于每一个N的因数n,计算nP;
- 满足nP=0的最小值n就是子群的阶。
举个例子,曲线在域上有阶,那么这个子群可能有以下阶。如果我们将,我们可以看到有,因此P的阶。
注意到找到最小的因数是很重要的,而不是随机的一个数。如果我们随机地进行这个过程,比如我们取n=14,这个数就不是子群的阶,而是它的一个倍数。
在举一个例子,椭圆曲线定义的方程在域上有阶(质数),它的子群可能只有两个阶n=1或37。正如你所猜想的那样,当n=1时,这个子群只包含了一个点,当n=N时,这个子群包含了椭圆曲线的所有点。
找到基点
对于ECC密码学,我们想要一个有最高阶的子群。因此通常来说我们会选择一个椭圆曲线,并且计算它的阶N,选择最高的因数作为子群的阶n,最终找到一个合适的基点。也就是说:我们选择一个基点并且计算它的阶,但是我们会做它相反的事情,我们首先会选择一个阶,然后观察它是否足够,接着我们会寻找一个合适的基点。那么我们要怎么做?
首先,我们需要引入一个术语。Lagrange定理告诉我们数字h=N/n必然是一个整数(因为n是N的因数),我们把这个数称之为子群的余因数。
现在我们考虑一下,在椭圆曲线上任意一点都有成立,这是因为N是一个任意一个候选数n的倍数。利用余因数的定义,我们可以这样写,。
现在假设n是一个质数(具体的原因我会在之后的内容中解释,我们更喜欢是质数的阶)。这个方程告诉我们点产生了一个阶为n的子群(除了这种情况,此时子群的阶为1)。
鉴于此,我们可以列出以下的运算法则:
- 计算椭圆曲线的阶N;
- 选择子群的阶n,为了使算法能够成立,这个数必须是质数,且必须是N的因数;
- 计算余因数h=N/n;
- 选择曲线上任意一点P;
- 计算G=hP;
- 如果G=0,那么回到第4步;如果G≠0,那么很好,我们就有了一个阶为n、余因数为h的子群的产生方法。
注意的是,这个算法只有在n为质数的时候有有效,如果n不是质数,那么G的阶可能是n的因数中的其中一个。
离散对数
之前我们的工作都是基于连续的椭圆曲线,接下来我们将要讨论一个问题:如果已知P和Q,什么样的k才能使=kP成立?
这个问题,就是椭圆曲线上的离散对数问题,当然它是相当难的,现在为止没有已知的多项式时间算法可以在计算机上运行。然而,这个猜想现在还没有一个数学证明。
这个问题和其他利用离散对数的密码学(如,Digital Signature Algorithm (DSA), the Diffie-Hellman key exchange (D-H) 和 ElGamal算法 )也是相似的。当然他们有着相同的名称,这不是巧合;而不同的是,这些算法,我们是利用模的幂指数而不是纯数的乘法。离散对数的问题可以这样描述:已知,那么什么样的才能使得 成立?
这些问题都是关于“离散”的,这是因为它们涉及到了有限集(更准确的说是循环子集)。而且这些问题也是关于“对数”的,因为它们和普通的对数是相似的。
时至今日,如果和其他密码学上的相似问题相比,ECC由于椭圆曲线上的离散对数问题而使得它变得更有趣,也更难。这就表明为了实现和其他密码学同样安全等级的条件下,我们需要知道更小的整数k,具体的内容会在下个帖子里面讲到。