私鑰的格式
私鑰可以以許多不同的格式表示,所有這些都對(duì)應(yīng)于相同的 256 位的數(shù)字。。
私鑰表示法(編碼格式)
種類版本描 述
HexNone64 hexadecimal digits
base58Check encoding: base58 with version
WIF5
prefix of 128 and 32-bit checksum
WIF-compressedK or LAs above, with added suffix 0x01 before encoding 表 4-3 展示了用這三種格式所生成的私鑰。
同樣的私鑰,不同的格式格式私鑰
1E99423A4ED27608A15A2616A2B0E9E52CED330AC530ED
Hex
WIF
WIF-compr essed
CC32C8FFC6A526AEDD
5J3mBbAH58CpQ3Y5RNJpUKPE62SQ5tfcvU2JpbnkeyhfsYB 1Jcn KxFC1jmwwCoACiCAWZ3eXa96mBM6tb3TYzGmf6YwgdGW ZgawvrtJ
這些表示法都是用來表示相同的數(shù)字、相同的私鑰的不同方法。雖然編碼后的字符串看起來不同,但不同的格式彼此之間可以很容易地相互轉(zhuǎn)換。
將 base58Check 編碼解碼為十六進(jìn)制sx工具包(參見"Libbitcoin 和 sx Tools")可用來編寫一些操作比特幣密鑰、地址及交易的 shell 腳本和命令行"管道"。你也可以使用 sx 工具從命令行對(duì) base58Check 格式進(jìn)行解碼。
我們使用的命令是 base58check-decode:
$sxbase58check-decode5J3mBbAH58CpQ3Y5RNJpUKPE62SQ5tfcvU2JpbnkeyhfsYB1Jcn 1e99423a4ed27608a15a2616a2b0e9e52ced330ac530edcc32c8ffc6a 526aedd 128
所得結(jié)果是十六進(jìn)制的密鑰,緊接著是錢包導(dǎo)入格式(Wallet import Format,WIF)的版本前綴 128。
將十六進(jìn)制轉(zhuǎn)換為 base58Check 編碼要轉(zhuǎn)換成 base58Check 編碼(和之前的命令正好相反),我們需提供十六進(jìn)制的私鑰和錢包導(dǎo)入格式(Wallet import Format,WIF)的版本號(hào)前綴 128:
$sx base58check-encode 1e99423a4ed27608a15a2616a2b0e9e52ced330ac530edcc32c8ffc6a 526aedd 128
5J3mBbAH58CpQ3Y5RNJpUKPE62SQ5tfcvU2JpbnkeyhfsYB1Jcn
將十六進(jìn)制(壓縮格式密鑰)轉(zhuǎn)換為 base58Check 編碼
要將壓縮格式的私鑰編碼為 base58Check(參見"壓縮格式私鑰"一節(jié)),我們需在十六進(jìn)制私鑰的后面添加后綴 01,然后使用跟上面一樣的方法:
$ sx base58check-encode 1e99423a4ed27608a15a2616a2b0e9e52ced330ac530edcc32c8ffc6a 526aedd01 128 KxFC1jmwwCoACiCAWZ3eXa96mBM6tb3TYzGmf6YwgdGWZgawvrtJ
生成的 WIF 壓縮格式的私鑰以字母"K"開頭,用以表明被編碼的私鑰有一個(gè)后綴"01",且該私鑰只能被用于生成壓縮格式的公鑰(參見"壓縮格式公鑰"一節(jié))。
公鑰的格式
公鑰也可以用多種不同格式來表示,最重要的是它們分為非壓縮格式或壓縮格式公鑰這兩種形式。
我們從前文可知,公鑰是在橢圓曲線上的一個(gè)點(diǎn),由一對(duì)坐標(biāo)(x,y)組成。公鑰通常表示為前綴 04 緊接著兩個(gè) 256 比特的數(shù)字。其中一個(gè) 256 比特 數(shù)字是公鑰的 x 坐標(biāo),另一個(gè) 256 比特?cái)?shù)字是 y 坐標(biāo)。前綴 04 是用來區(qū)分非壓縮格式公鑰,壓縮格式公鑰是以 02 或者 03 開頭。
下面是由前文中的私鑰所生成的公鑰,其坐標(biāo) x 和 y 如下:
x = F028892BAD7ED57D2FB57BF33081D5CFCF6F9ED3D3D7F159C2E2FFF57 9DC341A
y = 07CF33DA18BD734C600B96A72BBC4749D5141C90EC8AC328AE52DDFE2 E505BDB
下面是同樣的公鑰以 520 比特的數(shù)字(130 個(gè)十六進(jìn)制數(shù)字)來表達(dá)。這個(gè) 520
比特的數(shù)字以前綴 04 開頭,緊接著是 x 及 y 坐標(biāo),組成格式為 04 x y:
K = 04F028892BAD7ED57D2FB57BF33081D5CFCF6F9ED3D3D7F159C2E2FFF
579DC341A07CF33DA18BD734C600B96A72BBC4749D5141C90EC8AC328
AE52DDFE2E505BDB
壓縮格式公鑰
引入壓縮格式公鑰是為了減少比特幣交易的字節(jié)數(shù),從而可以節(jié)省那些運(yùn)行區(qū)塊鏈數(shù)據(jù)庫的節(jié)點(diǎn)磁盤空間。大部分比特幣交易包含了公鑰,用于驗(yàn)證用戶的憑據(jù)和支付比特幣。每個(gè)公鑰有520比特(包括前綴,x 坐標(biāo),y 坐標(biāo))。如果每個(gè)區(qū)塊有數(shù)百個(gè)交易,每天有成千上萬的交易發(fā)生,區(qū)塊鏈里就會(huì)被寫入大量的數(shù)據(jù)。
正如我們?cè)?quot;公鑰"一節(jié)所見,一個(gè)公鑰是一個(gè)橢圓曲線上的點(diǎn)(x, y)。而橢圓曲線實(shí)際是一個(gè)數(shù)學(xué)方程,曲線上的點(diǎn)實(shí)際是該方程的一個(gè)解。因此,如果我們知道了公鑰的 x 坐標(biāo),就可以通過解方程y2mod p = (x3 + 7) mod p 得到 y 坐標(biāo)。這種方案可以讓我們只存儲(chǔ)公鑰的 x 坐標(biāo),略去 y 坐標(biāo),從而將公鑰的大小和存儲(chǔ)空間減少了 256 比特。每個(gè)交易所需要的字節(jié)數(shù)減少了近一半, 隨著時(shí)間推移,就大大節(jié)省了很多數(shù)據(jù)傳輸和存儲(chǔ)。
未壓縮格式公鑰使用 04 作為前綴,而壓縮格式公鑰是以 02 或 03 作為前綴。需要這兩種不同前綴的原因是:因?yàn)闄E圓曲線加密的公式的左邊是 y2 ,也就是說 y 的解是來自于一個(gè)平方根,可能是正值也可能是負(fù)值。更形象地說,y 坐標(biāo)可能在 x 坐標(biāo)軸的上面或者下面。從圖的橢圓曲線圖中可以看出,曲線是對(duì)稱的,從 x 軸看就像對(duì)稱的鏡子兩面。因此,如果我們略去 y 坐標(biāo),就必須儲(chǔ)存 y 的符號(hào)(正值或者負(fù)值)。換句話說,對(duì)于給定的 x 值,我們需要知道 y值 在 x 軸的上面還是下面,因?yàn)樗鼈兇頇E圓曲線上不同的點(diǎn),即不同的公鑰。當(dāng)我們?cè)谒財(cái)?shù) p 階的有限域上使用二進(jìn)制算術(shù)計(jì)算橢圓曲線的時(shí)候,y 坐標(biāo)可能是奇數(shù) 或者偶數(shù),分別對(duì)應(yīng)前面所講的 y 值的正負(fù)符號(hào)。因此,為了區(qū)分 y 坐標(biāo)的兩種可能值,我們?cè)谏蓧嚎s格式公鑰時(shí),如果 y 是偶數(shù),則使用 02 作為前綴;如果 y 是奇數(shù),則使用 03 作為前綴。這樣就可以根據(jù)公鑰中給定的 x 值, 正確推導(dǎo)出對(duì)應(yīng)的 y 坐標(biāo),從而將公鑰解壓縮為在橢圓曲線上的完整的點(diǎn)坐標(biāo)。下面是前述章節(jié)所生成的公鑰,使用了 264 比特(66 個(gè)十六進(jìn)制數(shù)字)的壓縮格式公鑰格式,其中前綴 03 表示 y 坐標(biāo)是一個(gè)奇數(shù):
K = 03F028892BAD7ED57D2FB57BF33081D5CFCF6F9ED3D3D7F159C2E2FFF
579DC341A
這個(gè)壓縮格式公鑰對(duì)應(yīng)著同樣的一個(gè)私鑰,這意味它是由同樣的私鑰所生成。但是壓縮格式公鑰和非壓縮格式公鑰差別很大。更 重要的是,如果我們使用雙哈希函數(shù)(RIPEMD160(SHA256(K)))將壓縮格式公鑰轉(zhuǎn)化成比特幣地址,得到的地址將會(huì)不同于由非壓縮格式公鑰 產(chǎn)生的地址。這種結(jié)果會(huì)讓人迷惑,因?yàn)橐粋€(gè)私鑰可以生成兩種不同格式的公鑰——壓縮格式和非壓縮格式,而這兩種格式的公鑰可以生成兩個(gè)不同的比特幣地址。 但是,這兩個(gè)不同的比特幣地址的私鑰是一樣的。
壓縮格式公鑰漸漸成為了各種不同的比特幣客戶端的默認(rèn)格式,它可以大大減少交易所需的字節(jié)數(shù),同時(shí)也讓存儲(chǔ)區(qū)塊鏈所需的磁盤空間變小。然而,并非所有的客戶端都支持壓縮格式公鑰,于是那些較新的支持壓縮格式公鑰的客戶端就不得不考慮如何處理那些來自較老的不支持壓縮格式公鑰的客戶端的交易。
這在錢包 應(yīng)用導(dǎo)入另一個(gè)錢包應(yīng)用的私鑰的時(shí)候就會(huì)變得尤其重要,因?yàn)樾洛X包需要掃描區(qū)塊鏈并找到所有與這些被導(dǎo)入私鑰相關(guān)的交易。比特幣錢包應(yīng)該掃描哪個(gè)比特幣地 址呢?新客戶端不知道應(yīng)該使用哪個(gè)公鑰:因?yàn)椴徽撌峭ㄟ^壓縮的公鑰產(chǎn)生的比特幣地址,還是通過非壓縮的公鑰產(chǎn)生的地址,兩個(gè)都是合法的比特幣地址,都可以 被私鑰正確簽名,但是他們是完全不同的比特幣地址。為了解決這個(gè)問題,當(dāng)私鑰從錢包中被導(dǎo)出時(shí),較新的比特幣客戶端將使用一種不同的錢包導(dǎo)入格式(Wallet import Format)。這種新的錢包導(dǎo)入格式可以用來表明該私鑰已經(jīng)被用來生成壓縮的公鑰,同時(shí)生成的比特幣地址也是基于該壓縮的公鑰。這個(gè)方案可以解決導(dǎo)入私 鑰來自于老錢包還是新錢包的問題,同時(shí)也解決了通過公鑰生成的比特幣地址是來自于壓縮格式公鑰還是非壓縮格式公鑰的問題。最后新錢包在掃描區(qū)塊鏈時(shí),就可 以使用對(duì)應(yīng)的比特幣地址去查找該比特幣地址在區(qū)塊鏈里所發(fā)生的交易。我們將在下一節(jié)詳細(xì)解釋這種機(jī)制是如何工作的。
壓縮格式私鑰
實(shí)際上"壓縮格式私鑰"是一種名稱上的誤導(dǎo),因?yàn)楫?dāng)一個(gè)私鑰被使用 WIF 壓縮格式導(dǎo)出時(shí),不但沒有壓縮,而且比"非壓縮格式"私鑰長(zhǎng)出一個(gè)字節(jié)。這 個(gè)多出來的一個(gè)字節(jié)是私鑰被加了后綴 01,用以表明該私鑰是來自于一個(gè)較新的錢包,只能被用來生成壓縮的公鑰。私鑰是非壓縮的,也不能被壓縮。"壓縮的私 鑰"實(shí)際上只是表示"用于生成壓縮格式公鑰的私鑰",而"非壓縮格式私鑰"用來表明"用于生成非壓縮格式公鑰的私鑰"。為避免更多誤解,應(yīng)該只可以說導(dǎo)出 格式是"WIF 壓縮格式"或者"WIF",而不能說這個(gè)私鑰是"壓縮"的。
要注意的是,這些格式并不是可互換使用的。在較新的實(shí)現(xiàn)了壓縮格式公鑰的錢包中,私鑰只能且永遠(yuǎn)被導(dǎo)出為 WIF 壓縮格式(以 K 或 L 為前綴)。對(duì)于較老的沒有實(shí)現(xiàn)壓縮格式公鑰的錢包,私鑰將只能被導(dǎo)出為 WIF 格式(以 5 為前綴)導(dǎo)出。這樣做的目的就是為了給導(dǎo)入這些私鑰的錢包一個(gè)信號(hào):到底是使用壓縮 格式公鑰和比特幣地址去掃描區(qū)塊鏈,還是使用非壓縮格式公鑰和比特幣地址。
如果一個(gè)比特幣錢包實(shí)現(xiàn)了壓縮格式公鑰,那么它將會(huì)在所有交易中使用該壓格式縮公鑰。錢包中的私鑰將會(huì)被用來生成壓縮格式公鑰,壓縮格式公鑰然后被 用來生成交易中的比特幣地址。當(dāng)從一個(gè)實(shí)現(xiàn)了壓縮格式公鑰的比特幣錢包導(dǎo)出私鑰時(shí),錢包導(dǎo)入格式(WIF)將會(huì)被修改為 WIF 壓縮格式,該格式將會(huì)在私鑰 的后面附加一個(gè)字節(jié)大小的后綴 01。最終的 base58Check 編碼格式的私鑰被稱作 WIF("壓縮")私鑰,以字母"K"或"L"開頭。而以"5"開 頭的是從較老的錢包中以 WIF(非壓縮)格式導(dǎo)出的私鑰。
Hex WIF
1E99423A4ED27608A15A2616A2B0E9E52CED330AC530EDC C32C8FFC6A526AEDD
5J3mBbAH58CpQ3Y5RNJpUKPE62SQ5tfcvU2JpbnkeyhfsYB1 Jcn
格式私鑰
Hex-compr 1E99423A4ED27608A15A2616A2B0E9E52CED330AC530EDC
essedC32C8FFC6A526AEDD01
WIF-compr KxFC1jmwwCoACiCAWZ3eXa96mBM6tb3TYzGmf6YwgdGW
essedZgawvrtJ
"壓縮格式私鑰"是一個(gè)不當(dāng)用詞!私鑰不是壓縮的。WIF 壓縮格式的私鑰只是用來表明他們只能被生成壓縮的公鑰和對(duì)應(yīng)的比特幣地址。相反地,"WIF 壓 縮"編碼的私鑰還多出一個(gè)字節(jié),因?yàn)檫@種私鑰多了后綴"01"。該后綴是用來區(qū)分"非壓縮格式"私鑰和"壓縮格式"私鑰。








