前面我們一起學(xué)習(xí)了《比特幣的私鑰是怎么產(chǎn)生的》,今天我們再來學(xué)另一個(gè)重要的概念——公鑰。比特幣的公鑰和私鑰是一對秘鑰對挎狸,你用私鑰簽名的交易(transaction),可以通過公開的公鑰進(jìn)行驗(yàn)證断楷,以此保證私鑰不被泄露出去锨匆。這種用一把秘鑰簽名,再用另一把秘鑰對其驗(yàn)證的方式冬筒,被稱作非對稱加密算法恐锣。在比特幣中,這種算法有一個(gè)獨(dú)特的名字——橢圓曲線算法账千,如下圖所示
橢圓曲線
橢圓曲線的定義非常簡單侥蒙,滿足下面公式的所有 坐標(biāo)的集合,就是我們所說的橢圓曲線
上面公式中匀奏, 是取余符號鞭衩,而 ?
是一個(gè)很大的素?cái)?shù),到這一步娃善,公式中就只剩下自變量 ?
和因變量 ?
了论衍,你完全可以把它看成初中學(xué)過的二元多次函數(shù),不過聚磺,并不是所有實(shí)數(shù) ?
都滿足這個(gè)曲線坯台,所以實(shí)際上橢圓曲線是一個(gè)散點(diǎn)圖,下圖是當(dāng) ?
為17時(shí)瘫寝,滿足上述公式的圖形:
spec256k1 橢圓曲線
實(shí)際上蜒蕾, 取不同的素?cái)?shù),橢圓曲線會呈現(xiàn)出完全不同的形態(tài)焕阿,
越大咪啡,這個(gè)橢圓也就越大,可承載的數(shù)值范圍也就越大暮屡,沖突率會降低撤摸,乃至于更安全喳整,所以出于安全性考慮掉冶,比特幣中采用的是一個(gè)特定的橢圓曲線,我們叫它
spec256k1
凌蔬,它是由 NIST(National Institute of Standards and Technology)這個(gè)組織確定的莺掠。
剛才說 是一個(gè)很大的素?cái)?shù)衫嵌,那么
spec256k1
所選的 有多大呢?我們可以看一下
p = 115792089237316195423570985008687907853269984665640564039457584007908834671663
這個(gè) 可以確定一個(gè)橢圓彻秆,我們再在其中取一個(gè)點(diǎn)
x = 55066263022277343669578718895168534326250603453777594175500187360389116729240
y = 32670510020758816978083085130507043184471273380659243275938904335757337482424
把該點(diǎn)中的 和
帶入上面的公式中渐扮,看等式兩邊是否成立:
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
算出的結(jié)果论悴,可以看到時(shí)符合預(yù)期的掖棉。
橢圓曲線運(yùn)算
上面我們已經(jīng)認(rèn)識了橢圓曲線墓律,它看上去很有趣,但我覺得更有趣的是橢圓曲線的運(yùn)算幔亥,公鑰的算法就是運(yùn)用了這些基本運(yùn)算:
- 加法運(yùn)算
- 無限點(diǎn)(point at infinity)定義
- 乘法運(yùn)算
加法
在橢圓曲線上耻讽,任意兩個(gè)點(diǎn)的連線會和曲線上的第三個(gè)點(diǎn)相交,如果前兩個(gè)點(diǎn)重合帕棉,那么這條線為該點(diǎn)上的切線针肥,有了這個(gè)條件后,我們就可以定義橢圓曲線的加法操作了
橢圓曲線上香伴,任意兩點(diǎn)
與
相加慰枕,等于曲線上另外一個(gè)點(diǎn)
,設(shè)
和
的連線(或切線)與曲線上相交的點(diǎn)為
即纲,則
和
關(guān)于
軸對稱具帮。
接下來我們舉個(gè)例子,假設(shè)橢圓曲線上有一個(gè)點(diǎn) 低斋,
和
分別是點(diǎn)
的
坐標(biāo)和
坐標(biāo)蜂厅,則
在橢圓曲線上的點(diǎn)如下圖所示:
無限點(diǎn)(point at infinity)
無限點(diǎn)(point at infinity)的概念存在的原因是:可能存在兩點(diǎn)的連線正好和 軸垂直的情況膊畴,這時(shí)就不會有與曲線相交的另外一個(gè)點(diǎn)了掘猿,這種情況下,規(guī)定該點(diǎn)為無限點(diǎn)唇跨。
同時(shí)稠通,無限點(diǎn)和任意一個(gè)點(diǎn) 相加,仍然是
买猖。例如:假設(shè)
是無限點(diǎn)改橘,那么
從這個(gè)角度來看,無限點(diǎn)又具備了 的特性政勃。
乘法
如果加法和無限點(diǎn)的概念刷新了你的認(rèn)知唧龄,那么乘法就親切很多,它和我們所熟知的代數(shù)中的乘法并無差異:乘法就是加法的展開式奸远,假設(shè) 點(diǎn)是橢圓曲線上的一個(gè)點(diǎn)既棺,那么
產(chǎn)生一個(gè)私鑰
有了以上的基礎(chǔ),我們才可以來計(jì)算公鑰懒叛,產(chǎn)生公鑰的算法其實(shí)就是橢圓曲線上的乘法運(yùn)算:
上面公式中丸冕, 是橢圓曲線上的一個(gè)點(diǎn),且這個(gè)點(diǎn)在比特幣中是固定不變的薛窥;
是我們的私鑰胖烛,上一篇中我們已經(jīng)知道了私鑰是一個(gè)很大的隨機(jī)數(shù)眼姐;而結(jié)果
就是我們產(chǎn)生的公鑰,根據(jù)上面的知識佩番,可以知道公鑰是
個(gè)
相加的結(jié)果众旗,這個(gè)結(jié)果仍然是橢圓上的一個(gè)點(diǎn)
上圖是一個(gè)公鑰產(chǎn)生的示意圖,如果你能看懂趟畏,恭喜你贡歧,你已經(jīng)掌握了公鑰的生成算法。
相關(guān)文章: