比特币源码分析--深入理解区块链 14.椭圆曲线在比特币中的使用

        椭圆曲线(EllipticCurve缩写作 EC)为一平面代数曲线,椭圆曲线加密学是一种基于椭圆曲线数学的公开密钥加密演算法。椭圆曲线在密码学中的使用是在1985年由Neal Koblitz]和Victor Miller分别独立提出的签名。目前是比特币使用的主要加密算法。本文主要介绍椭圆曲线数学上的基本原理和使用方法。

椭圆曲线

        在数学上,椭圆曲线(Ellipticcurve,简称EC)为一平面代数曲线,由如下形式的方程定义:

\begin{aligned} y^2=x^3+ax+b \end{aligned}

  其中a和b为实数。椭圆曲线是光滑的、射影的、亏格为1的代数曲线,其上有一个特定的点O,也叫无穷远点,无穷远点是平面代数曲线上的概念,比较难理解,维基上这么说的:

  1. 无穷远点,又称为理想点,是一个加在实数轴上后得到实射影直线\mathbb{R}P^1的点。实射影直线与扩展的实数轴不是一样的,扩展的实数轴有两个不同的无穷远点。
  2. 无穷远点也可以加在复平面\mathbb{C}^1上,于是把它变成一个闭曲面,称为黎曼球面{\mathbb{C}P}^1(把球面穿一个孔,并把所得到的边拉开来,便得到一个平面;相反的过程便把复平面变为{\mathbb{C}P}^1,在平面外加上一个点,并把平面向这个点包起来,便得到球面。)这个结构可以推广到任何拓扑空间。所得到的空间称为原空间的单点紧化。因此,圆形是直线的单点紧化,而球面则是平面的单点紧化。
  3. 现在考虑实射影平面\mathbb{R}P^2上的一对平行直线。由于这对直线是平行的,因此它们相交于无穷远点,这个点位于\mathbb{R}P^2的无穷远直线上。更进一步,这两条直线都是\mathbb{R}P^2上的射影直线:每一条都有自己的无穷远点。当一对射影直线平行时,它们相交于它们公共的无穷远点。

        总之很难理解,有兴趣的可以尝试去理解,它有助于理解椭圆曲线加密算法的原理和推导过程。这个无穷远点之所以这么重要,是因为:无穷远点\mathcal{O}是椭圆曲线算术中的单位元。任意点和此点相加,相加前和相加后的结果不变。若无穷远点加上无穷远点等于无穷远点。

\begin{flushleft} \mathcal{O}+\mathcal{O}=\mathcal{O}\\ \mathcal{O}+P=P \end{flushleft}

        无穷远点写成0,注意这里的相加,不是一般意义上的数学加法,而是定义了自己的代数加法,理解这点很重要,椭圆曲线是下面这个模样,它只展示了坐标系上的一小部分,右上和右下的曲线可能在曲面上无限延申,最后于无穷远点相交。

 椭圆曲线实数域图像

上图我们可以在juypter-lab中使用如下代码绘制:

import numpy as np
import matplotlib.pyplot as plt
a = 0
b = 7
y, x = np.ogrid[-5:5:100j, -5:5:100j]
plt.contour(x.ravel(), y.ravel(), pow(y, 2) - pow(x, 3) - x * a - b, [0])
plt.grid()
plt.show()

这里强调几点:

  1. 比特币中使用曲线实数a=0, b=7。
  2. 针对密码学应用上的椭圆曲线是在有限域(不是实数域)的平面曲线。是因为实数域是连续的点,容易破解和反推。对椭圆曲线来说最流行的有限域是以素数为模的整数域(参见模运算)GF(p),或是特征为2的伽罗瓦域 GF(2m)。在数学中,有限域(finite field)或伽罗瓦域(Galois field,为纪念埃瓦里斯特·伽罗瓦命名)是包含有限个元素的域。与其他域一样,有限域是进行加减乘除运算都有定义并且满足特定规则的集合。有限域最常见的例子是当 p 为素数时,整数对 p 取模。这里注意:
  • 在该域内的运算都是自己定义的,而不是一般意义的加减乘除;
  • 域内的点是整数对素数取模的离散点;
  • 有限域的乘法群是循环群,表示从一点出发,经过若干次运算后回到该点。

椭圆曲线上的运算

在椭圆曲线上,点P和Q连接成直线,相交于点R,椭圆曲线上的点相加是这样定义的:

 \begin{flushleft} P+\ Q+\ R=0\\P+\ Q=-R\end{flushleft}

如下图所示:

其中0就是无穷远点,至于为什么会有上面的算式,其中的证明很复杂,可以参考:https://zh.wikipedia.org/wiki/%E6%A4%AD%E5%9C%86%E6%9B%B2%E7%BA%BF,一般使用只需要套用这个公式就行了。

图二是P与点Q与曲线相切,因此点R=Q;所以:

\\P+\ Q+\ Q=0 \\P+\ 2Q=0

图三交点R可认为是无穷远点0;所以:

 \\P+\ Q+\ 0=0 \\P=\ -Q

图四的Q=P, R=无穷远点,所以:

\\P+\ P+\ 0=0 \\2P=0

 反相

点的反相是指针对某一个点,可以找到另一个点,与其相加后为无穷远点

\\P+(-P)=0

 在椭圆曲线上,一点反相点的x坐标会和该点相同,而y坐标为该点坐标的负值:

\\\left(x,\ y\right)+\left(-\left(x,y\right)\right)=0 \\\left(x,\ y\right)+(x,\ -y)=0 \\\left(x,\ -y\right)\ =-(x,\ y)

上述的式子,我们可以使用上面的图来证明:

\\\left(x,\ y\right)+\left(-\left(x,y\right)\right)=x-x+y-y=0+0=0

其中x – x = x + (-x) 就是上图三的一个特例,-x是它在X轴的对称点,同样的可证明其它的算式。

点的相加

针对二个相异点P和Q,其加法定定义为P和Q所形成的直线,和曲线交点的反相点R.

\\P+Q=-R \\\left(x_p,\ y_p\right)+\left(x_q,\ y_q\right)=(x_r,\ y_r)

假设椭圆曲线的方程式是:

\\{\ y}^2=x^3+\ ax+b

可以计算得到:

\\\lambda=\ \frac{y_q-y_p}{x_q-\ x_p} \\x_r=\lambda^2-x_p-x_q \\y_r=\lambda\left(x_p-x_r\right)-y_p

注意这是两个不同点相加的计算公式

点的加倍

        假设点P和Q重合(相同的点),其加法类似,但无法依上述方式定义直线,因此使用极限的作法,取曲线E在P点的切线。计算同上,取导数(dE/dx)/(dE/dy)可得:

\lambda=\ \frac{3x_p^2+a}{​{2y}_p}

点乘法

        假定在有限域上定义的曲线E(例如E: y^2=x^3+ax+b,其点乘定义为重复的进行在曲线上点的加法,表示为kP = P + P + P + … + P,其中k是数(整数)以及在曲线上的一点P=(x,y)。現代椭圆曲线密码学安全性的基础是在给定Q和P,以及Q = kP的情形下,若k很大,无法求得k的特性而来(此问题称为椭圆曲线离散对数问题)。这里要注意的是k,就是比特中的私钥(256位),一般是较复杂的随机数。 

椭圆曲线的有限域

        给定一条曲线E(x^2=y^3+7),以及一个域GF(p) ,对椭圆曲线来说最流行的有限域是以素数为模的整数域。例如有限域GF(p)给定某个质数p, 根据模的运算规律,它是由0,1,2……p-1共p个元素组成的整数集合中定义的加减乘除运算。考虑有(x,\ y)形式的有理数点E(p)的阿贝尔群。其中x和y都在GF(p)中并且定义这条曲线上的群运算“ +”(在上面有描述)。然后定义第二个运算“*”Z\times E\left(p\right)\rightarrow E(p)

         椭圆曲线是连续的,并不适合用于加密;所以,我们必须把椭圆曲线变成离散的点,我们要把椭圆曲线定义在有限域上。所以上述以质数为模的整数域GF\left(p\right)图像类似:

如果P是E(q)上的某个点,那么定义2*P = P + P, 3*P=2*+P = P + P + P。

举个例子,假设椭圆曲线x^2=y^3+7在有限域GF\left(23\right)写成:

x^2=y^3+7\ mod\ 23

设点P(3,10)。求(1)-P;(2)2P:

  1. 根据 –(x,y) = (x, -y)得:(3, -10 mod 23) = (3,13)
  2. 根据点的加倍求:

\lambda=\ \frac{3x_p^2+a}{​{2y}_p}=\frac{3\times3^2+0}{2\times10}\ mod\ 23

根据模反元素计算:

整数a对余n之模反元素是指满足以下公式得整数b

a^{-1}\equiv b\ (mod\ n)

也可以写成以下的式子

ab\equiv1\ (mod\ n)

ab\ mod\ n=1

根据上述公式,举例,这里的 a = 1

\lambda=\ \frac{​{3\times3}^{2+1}}{2\times10}=7\bullet5^{-1}\ mod\ 23

可以转换为

5\bullet5^{-1}\ mod\ 23=1\ mod\ 23\ \ \Rightarrow5\bullet\ x\ mod\ 23=1

可以得出5*x = 70,70%23 == 1,因此 x = 14。

 故得出:


5^{-1}\ =14 \\{7\bullet5}^{-1}\ =7\bullet14\ mod\ 23=\lambda=\ 6

下面的例子a = 0

\lambda=\ \frac{3x_p^2+a}{​{2y}_p}=\frac{3\times3^2+0}{2\times10}\ mod\ 23=27\ \bullet{20}^{-1}\ mod\ 23 \\\ 20\ \bullet{20}^{-1}=1\ mod\ 23\ \Rightarrow20\ \bullet x\ mod\ 23=1 \\\Rightarrow{20}^{-1}=15 \\\Rightarrow27\ \bullet15\ mod\ 23=14

故 

2P=({14}^2-3-3\ mod\ 23,\ 14\ \times\left(3-6\right)-10\ mod\ 23)=(6,\ \ 17)

  经过n轮也就是nP后就会回到几点P(3,10),因此说这些点构成了一个循环阿贝尔群,其中单位元为P,阶数为n。

 椭圆曲线的密钥和常用参数

        考虑P=k*G ,其中P、G为椭圆曲线Ep(a,b)上的点,n为G的阶(nG=O∞,它表示的是经过多少轮运算后回到基点的意思),k为小于n的整数。则给定k和G,根据加法法则,计算P很容易,但反过来,给定P和G,求k就非常困难。因为实际使用中的ECC原则上把p取得相当大(p上面介绍的是有限域上的素数,对整数取模运算用,它越大说明整个有限域就越大),n也相当大,要把n个解点逐一算出来列成上表是不可能的。这就是椭圆曲线加密算法的数学依据。

P=kG

相当于k个G相加,其中:

  • 点G称为基点(base point)
  • k(k<n)为私有密钥(privte key)
  • P为公开密钥(public key)
  • p整数对p取模的素数。

通常将GF(p)上的一条椭圆曲线描述为T=(p,a,b,G,n,h)p、a、b确定一条椭圆曲线G为基点,n为点G的阶,h是椭圆曲线上所有点的个数m与n相除的商的整数部分。比特币使用的数据是:

a = 0

b = 7

p = 115792089237316195423570985008687907853269984665640564039457584007908834671663

n = 115792089237316195423570985008687907852837564279074904382605163141518161494337

h = 1

Gx = 55066263022277343669578718895168534326250603453777594175500187360389116729240

Gy = 32670510020758816978083085130507043184471273380659243275938904335757337482424

在实际运算过程中,使用的都是大整数(BigInteger)的计算,因为系统默认的数据类型无法处理256位长度计算,因此需要专门设计针对256位的大整数计算。

如果Alice和Bob有私钥k_ak_b,公钥是P_aP_b,那么Alice能计算k_a{\ast P}_b=\ k_a{\ast k}_b\ast G;Bob能计算同样的值k_b{\ast P}_a=\ k_b{\ast k}_a\ast G

这允许一个“秘密”值的建立,这样Alice和Bob能很容易地计算出,但任何的第三方却很难得到。另外,Bob在处理期间不会获得任何关于Alice的私钥,因此Alice的私钥仍然是私有的。

 椭圆曲线的加密安全

        对于ECC系统来说,完成运行系统所必须的群操作比同样大小的因数分解系统或模整数离散对数系统要慢。不过,ECC系统的拥护者相信ECDLP问题比DLP或因数分解问题要难的多,并且因此使用ECC能用小的多的密钥长度来提供同等的安全,在这方面来说它确实比例如RSA之类的更快。到目前为止已经公布的结果趋于支持这个结论,不过一些专家表示怀疑。ECC被广泛认为是在给定密钥长度的情况下,最强大的非对称算法,因此在对带宽要求十分紧的连接中会十分有用。

        美国国家标准与技术局和ANSI X9已经设定了最小密钥长度的要求,RSA和DSA是最小2048位,ECC是最小224位,相应的对称密钥加密的密钥长度是最小128位,这样的组合在2030年以前是安全的。 在2005年2月16日,NSA宣布决定采用椭圆曲线密码的战略作为美国政府标准的一部分,用来保护敏感但不保密的信息。

        如果攻击者拥有大型量子计算机,那么他可以使用秀尔算法解决离散对数问题,从而破解私钥和共享秘密。目前的估算认为:破解256位素数域上的椭圆曲线,需要2330个量子比特与1260亿个托佛利门。相比之下,使用秀尔算法破解2048位的RSA则需要4098个量子比特与5.2万亿个托佛利门。因此,椭圆曲线会更先遭到量子计算机的破解。目前还不存在建造如此大型量子计算机的科学技术,因此椭圆曲线密码学至少在未来十年(或更久)依然是安全的。

公钥的计算强度

        从上面可得知,私钥k是一个256位长度的随机数,要计算出公钥P,就必要经过k次相加运算。虽然公式是kG,但这不是传统上的乘法,而是点乘法,其实就是k个G相加。在这里我们随机生成一个32字节的随机数作为k:

0x60f943c0d7fc0425cc1b4a225242e9e882fffc13b36d3b6673a6face7a0284f8

换算成十进制就是:

43862445999184202203462610795088226019833149308826913010961699807770578158840

这个大小是什么概念呢?

如果按照CPU是3GHz(每秒运行三十亿次/秒)的话,那么运行k次,需要169222399688210656649161307079815686804911841469239633529944829(天)

没看错,这样的运算速度如果按照一个个相加的话到地球毁灭可能都没运算完。因此在公钥计算过程中,必须使用高效的算法,比如Double-and-add:

要計算kG,要先將k以二進制表示

以下是迭代演算法:

该算法很快,一般也就是在几秒内完成。

猜你喜欢

转载自blog.csdn.net/dragon_trooquant/article/details/125010471