由上一篇ECC算法筆記記錄的公鑰生成方式:K = k * G :html
私鑰 k 一般是隨機選出的一串數字串(通過sha256加密),而後經過ECC算法來產生一個公鑰(K),最後經過單項Hash算法來生成Bitcoin地址。git
描述:github
存在三種密鑰,而且都是使用 Base58Check 編碼成 ASCII 碼呈現:算法
第一步:私鑰 (private key)產生數組
僞隨機數產生的256bit私鑰示例:安全
8F72F6B29E6E225A36B68DFE333C7CE5E55D83249D3D2CD6332671FA445C4DD3網絡
第二步:公鑰 (public key)學習
1. 拿私鑰產生256bit私鑰經secp256k1橢圓曲線推出的公鑰(前綴04+X公鑰+Y公鑰):字體
04編碼
06CCAE7536386DA2C5ADD428B099C7658814CA837F94FADE365D0EC6B1519385
FF83EC5F2C0C8F016A32134589F7B9E97ACBFEFD2EF12A91FA622B38A1449EEB
2. 計算公鑰的 SHA-256 哈希值(32bytes):
2572e5f4a8e77ddf5bb35b9e61c61f66455a4a24bcfd6cb190a8e8ff48fc097d
3. 取上一步結果,計算 RIPEMD-160 哈希值(20bytes):
0b14f003d63ab31aef5fedde2b504699547dd1f6
4. 取上一步結果,前面加入地址版本號(比特幣主網版本號「0x00」):
000b14f003d63ab31aef5fedde2b504699547dd1f6
5. 取上一步結果,計算兩次 SHA-256 哈希值(32bytes)
---1--- ddc2270f93cc84cc6869dd373f3c340bbf5cb9a8f5559297cc9e5d947aab2536
---2--- 869ac57b83ccf75ca9da8895823562fffb611e3c297d9c2d4612aeeb32850078
6. 取上一步結果的前4個字節(8位十六進制)
869ac57b
7. hash of public key,把這4個字節加在第4步的結果後面,做爲校驗(這就是比特幣地址的16進制形態)
000b14f003d63ab31aef5fedde2b504699547dd1f6869ac57b
第三步:地址 (address)
最終給用戶使用的:用base58編碼變換一下地址(這就是最多見的比特幣地址形態)
121bWssvSgsA9SKjR4DbYncEAoJjmBFwog
本質上私鑰就是一串隨機選出的 256 個 bit 的 01 數字(32 字節 * 8 = 256 bits),可是這串數字卻控制着你的比特幣帳號的全部權,所以這串數字至關重要,要具備足夠的隨機性,通常採用密碼學安全的僞隨機數生成器(CSPNG),而且須要有一個來自具備足夠熵值的源的種子(seed)。
比特幣客戶端軟件使用 Secp256k1ECDSA 標準生成橢圓曲線,使用橢圓生成一個私鑰,而後再從私鑰中生成對應的公鑰。
若是自行選取簡單的123456密碼,最終生成的帳戶但是「公交車帳戶」了哈哈。
選擇 32 個字節的緣由是由於 Bitcoin 使用的是 ECDSA 算法,而且使用的是 secp256k1 曲線。
Bitcoin 的公鑰是經過 橢圓曲線密碼學算法(K = k * G)來生成,其中公式中的:
Bitcoin 使用了 secp256k1 標準定義的一種特殊的橢圓曲線和一系列的數學常量。
如上公式,以私鑰 k 爲起點,與預約的生成點 G 相乘來生成公鑰 K,而且由於全部 Bitcoin 用戶的生成點 G 都是相同的(常量),因此由一個肯定的私鑰 k 生成一個肯定的公鑰 K,而且是單向的。
# 私鑰生成公鑰示例(非壓縮公鑰) private key: de97fdbdb823a197603e1f2cb8b1bded3824147e88ebd47367ba82d4b5600d73 public key: 047c91259636a5a16538e0603636f06c532dd6f2bb42f8dd33fa0cdb39546cf449612f3eaf15db9443b7e0668ef22187de9059633eb23112643a38771c630db911
簡單來講,對於壓縮公鑰生成地址時,則只取非壓縮公鑰的X部分便可。
從上面的輸出示例中能夠看到 public key 一共有 130 個 16 進制的字符,共 520 個字節,其中的前綴爲 04,這裏的 04 表示該公鑰爲 非壓縮格式,即完整存儲了 x 和 y 座標(各 256 個 bits),可是從 secp256k1 的橢圓曲線方式能夠看到,只要知道其中一個座標值,另一個座標值都是能夠經過解方程得出的,由於能夠只存儲其中一個座標,這樣就能夠節約 256 個 bits,從而引入了 壓縮格式 的公鑰。
上面的 04 前綴表示 非壓縮格式,若是爲壓縮格式,則前綴爲 02 或 03,有兩個前綴主要是由於方程(y² = x³ + ax + b)的左側的 y 爲平方根,可能爲正或者爲負。
以下爲一個與上面示例對應的壓縮格式的公鑰值:
private key: de97fdbdb823a197603e1f2cb8b1bded3824147e88ebd47367ba82d4b5600d73
public key compressed: 037c91259636a5a16538e0603636f06c532dd6f2bb42f8dd33fa0cdb39546cf449
Bitcoin 的地址由公鑰通過單向的加密哈希算法 SHA256 和 RIPEMD160 生成,公式以下:
A = RIPEMD160(SHA256(K))
其中:
- K 爲公鑰
- A 爲最終生成的地址;
# 生成的地址示例,地址的長度爲 40 個 16 進制串,即 160 個bits: private key: de97fdbdb823a197603e1f2cb8b1bded3824147e88ebd47367ba82d4b5600d73 public key compressed: 037c91259636a5a16538e0603636f06c532dd6f2bb42f8dd33fa0cdb39546cf449 address: 52dab5e951ef4848a31b7ead8437df8184acbc54
公鑰哈希就是你們看到的比特幣地址,大部分比特幣地址由公鑰經過 base58Check 編碼而來,把公鑰地址從 512-Bit 哈希到 160-Bit ,但並非全部的比特幣地址都是公鑰推導出來,也有多是經過腳本創建在比特幣網絡中的虛擬幣(好比彩色幣)的腳本標識。
咱們一般看到的 Bitcoin 地址都是通過 Base58Check 編碼後的地址,Base58Check 編碼也用於私鑰,加密的密鑰以及腳本中,用來提升可讀性和錄入的正確性。
下圖描述了經過 公鑰生成 Base58Check 編碼格式的地址的整個過程:
其中 Public Key Hash 咱們在上面已經生成的地址,以後就是經過 Base58Check 編碼生成 Bitcoin 的地址格式。
(摘自 wiki)相比Base64,Base58不使用數字"0",字母大寫"O",字母大寫"I",和字母小寫"l",以及"+「和」/"符號。
設計Base58主要的目的是:
base58符號映射表
爲了進一步增長安全性,Base58Check 格式又在 Base58 的基礎上新增了內置檢查錯誤的校驗和(checksum),該校驗和是添加到末尾的額外 4 個字節,校驗和的生成算法以下:
checksum = SHA256(SHA256(prefix+data))
其中 私鑰 的前綴爲 128(即 0x80),對應的編碼後前綴爲 5,以下爲咱們的私鑰編碼後的:
// base58編碼 de97fdbdb823a197603e1f2cb8b1bded3824147e88ebd47367ba82d4b5600d73 5KWKSRnmzxCjUP1NKR4dNyyHhaZWSGRTbGzBnm1vwgwpoe2AVGQ
下面爲公鑰以及生成的 Base58Check 格式的地址信息:
// base58編碼 public key compressed: 037c91259636a5a16538e0603636f06c532dd6f2bb42f8dd33fa0cdb39546cf449 checksum: 4caf1695 base58check address: 18Z6R1VF7Do8RTHneeGzdVdbgjtXDVPmfS
base58check address: 18Z6R1VF7Do8RTHneeGzdVdbgjtXDVPmfS
便於對應上面理解咱們能夠對比看看base58解碼後的BTC地址:Version Public key hash Checksum 00 62E907B15CBF27D5425399EBF6F0FB50EBB88F18 C29B7D93
Base58Check 的編碼過程:
所以實際上在 bitcoin 中大多數須要向用戶展現的數據都是使用的 Base58Check 編碼格式。
筆記總結參考: