64

比特币的公钥算法

 5 years ago
source link: https://mp.weixin.qq.com/s/SjVWMNEMBv4d5CLblKR72A?amp%3Butm_medium=referral
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

vqiYRze.jpg!web

前面我们一起学习了 《比特币的私钥是怎么产生的》 ,今天我们再来学另一个重要的概念——公钥。

比特币的公钥和私钥是一对秘钥对,你用私钥签名的交易(transaction),可以通过公开的公钥进行验证,以此保证私钥不被泄露出去。这种用一把秘钥签名,再用另一把秘钥对其验证的方式,被称作非对称加密算法。在比特币中,这种算法有一个独特的名字——椭圆曲线算法,如下图所示

6jAnEbq.jpg!web

椭圆曲线

椭圆曲线的定义非常简单,满足下面公式的所有坐标的集合,就是我们所说的椭圆曲线

yUvaauM.png!web

上面公式中,是取余符号,而 是一个很大的素数,到这一步,公式中就只剩下自变量和因变量了,你完全可以把它看成初中学过的二元多次函数,不过,并不是所有实数都满足这个曲线,所以实际上椭圆曲线是一个散点图,下图是当为17时,满足上述公式的图形:

JVVFVbA.png!web

spec256k1 椭圆曲线

实际上,取不同的素数,椭圆曲线会呈现出完全不同的形态,越大,这个椭圆也就越大,可承载的数值范围也就越大,冲突率会降低,乃至于更安全,所以出于安全性考虑,比特币中采用的是一个特定的椭圆曲线,我们叫它 spec256k1 ,它是由 NIST(National Institute of Standards and Technology)这个组织确定的。

刚才说是一个很大的素数,那么 spec256k1 所选的有多大呢?我们可以看一下

p = 115792089237316195423570985008687907853269984665640564039457584007908834671663

接着,我们再在  spec256k1  椭圆上选一个点

x = 55066263022277343669578718895168534326250603453777594175500187360389116729240
y = 32670510020758816978083085130507043184471273380659243275938904335757337482424

把该点中的和带入上面的公式中,看等式两边是否成立:

Python 2.7.10 (default, Jul 15 2017, 17:16:57)
[GCC 4.2.1 Compatible Apple LLVM 9.0.0 (clang-900.0.31)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> x=55066263022277343669578718895168534326250603453777594175500187360389116729240
>>> y=32670510020758816978083085130507043184471273380659243275938904335757337482424
>>> p=115792089237316195423570985008687907853269984665640564039457584007908834671663
>>> (x**3+7)%p - y**2%p
0L

上面是我用 Python 算出的结果,可以看到结果符合预期。

椭圆曲线运算

上面我们已经认识了椭圆曲线,它看上去很有趣,但我觉得更有趣的是椭圆曲线的运算,公钥的算法就是运用了这些基本运算:

  1. 加法运算

  2. 无限点(point at infinity)定义

  3. 乘法运算

加法

在椭圆曲线上,任意两个点的连线会和曲线上的第三个点相交,如果前两个点重合,那么这条线为该点上的切线,有了这个条件后,我们就可以定义椭圆曲线的加法操作了

椭圆曲线上,任意两点与相加,等于曲线上另外一个点,设和  的连线(或切线)与曲线上相交的点为,则和关于轴对称。

接下来我们举个例子,假设椭圆曲线上有一个点,和分别是点的坐标和坐标,则 EruAVvR.png!web 在椭圆曲线上的点如下图所示:

7jIruan.jpg!web P的切线和曲线相交于P1'(c,d),则P1'关于x轴的映射就是我们要求的P1(c,-d)

无限点(point at infinity)

无限点(point at infinity)的概念存在的原因是:可能存在两点的连线正好和轴垂直的情况,这时就不会有与曲线相交的另外一个点了,这种情况下,规定该点为无限点。

同时,无限点和任意一个点相加,仍然是。例如:假设是无限点,那么

2aABV3r.png!web

从这个角度来看,无限点又具备了的特性。

乘法

如果椭圆曲线的加法和无限点的概念刷新了你的认知,那么乘法就亲切很多,它和我们所熟知的代数中的乘法并无差异:乘法就是加法的展开式,假设点是椭圆曲线上的一个点,那么

fqAJ7bE.png!web

产生一个私钥

有了以上的基础,我们才可以来计算公钥,产生公钥的算法其实就是椭圆曲线上的乘法运算:

mA7BVf7.png!web

上面公式中,是椭圆曲线上的一个点,且这个点在比特币中是固定不变的;是我们的私钥,上一篇中我们已经知道了私钥是一个很大的随机数;而结果就是我们产生的公钥,根据上面的知识,可以知道公钥是个相加的结果,这个结果仍然是椭圆上的一个点

QziUvuB.jpg!web

上图是一个公钥产生的示意图,如果你能看懂,恭喜你,你已经掌握了公钥的生成算法。

总结

本文我们一起学习了公钥是如何计算出来的,它背后的原理也很简单,即是利用了椭圆曲线中的基本运算法则,掌握了这些知识后,给你一个私钥,你自己也可以算出其对应的公钥了。

相关文章:


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK