跳至主要內容

什麼是 BIP39

今日已更新

BIP-39 規範主要描述了基於助記詞(一組便於記憶的單字)來生成確定性錢包的演算法和過程。

該規範中主要由兩部分構成:

  1. 如何生成助記詞;

  2. 如何將生成的助記詞轉化成一個二進位種子;

下面就先分別介紹這兩個部分來看看如何生成確定性錢包。

生成助記詞

生成助記詞的演算法過程如下圖:

具體過程如下:

  1. 建立一個 128 到 256 位(步長 32 位)的隨機序列(熵);

  2. 對上一步生成的隨機序列進行 SHA256 生成 Hash 值,並取出該 Hash 值的前 N 位(熵長/32,如:128 位,則 N = 4)作為隨機序列的校驗和(Checksum);

  3. 將 Checksum 添加至第一步生成的隨機序列的尾部,此時對於圖中示例加上 Checksum 之後為 128 + 4 = 132 位的隨機序列;

  4. 將上一步的隨機序列按照 11 位一段進行分隔(Split),這樣對於 128 位熵長的序列就會生成 12 段(132 / 11 = 12);

  5. 此時將每個包含 11 位部分的值與一個預定義的 2048 個單字的詞典進行對應;

  6. 按照切割順序生成了最終的單字組就是助記詞;

從助記詞生成種子

助記詞生成之後我們可以透過金鑰生成函數 PBKDF2 演算法來生成種子。

PBKDF2 需要提供兩個參數:助記詞和鹽(Salt)。其中 Salt 的目的是增加破解難度,而在 BIP-39 中,我們可以引入密碼(Passphrase)來作為保護種子的附加安全因素。

PBKDF2 is part of RSA Laboratories’ Public-Key Cryptography Standards (PKCS) series, specifically PKCS #5 v2.0, also published as Internet Engineering Task Force’s RFC 2898.

接著上面的助記詞生成之後,如下圖為生成 seed 的演算法過程:

  1. PBKDF2 的第一個參數是上面生成的助記詞;

  2. PBKDF2 的第二個參數就是 Salt,一般有字串和可選的使用者提供的密碼字串連接組成;

  3. PBKDF2 使用 HMAC-SHA512 演算法,使用了 2048 次 Hash 之後產生一個 512 位的值作為種子;

從種子開始生成 HD 錢包

下面就將上面生成的種子作為 HD 錢包的根種子(Root Seed),任何 HD 錢包的根種子都可以重新創造整個 HD 錢包。

將 Root Seed 輸入到 HMAC-SHA512 演算法中可以得到一個 512 位的 Hash,該 Hash 的左邊 256 位作為 主私鑰 m(Master Private Key),右邊 256 位作為 主鏈碼(Master Chain Code)。之後的主公鑰 M(Master Public Key,264 bits)可以透過主私鑰 m 生成。

從上圖可以看到,HD 的金鑰生成如下幾個參數:

  • Parent Private KeyParent Public Key;(均為未壓縮的 256 bits 的 ECDSA 密鑰

  • 256 bits 的 Parent Chain Code

  • 32-bit 整型的 index number(索引號);

另外,上面的過程是可以遞迴下去的,圖中的 Child Private Key 可以作為其下一層級的 Parent Private Key

透過將(Parent Publick Key, Parent Chain Code, Index Number)輸入至 HMAC-SHA512 演算法中,我們就可以生成其子金鑰,並且我們可以透過調整 Index Number 來生成同一層級的多個子金鑰。

關於擴展金鑰

因為這個金鑰衍生函數是單向的,所有 子金鑰 都是不能夠被用來推導出它們的 父金鑰 的,也不能推導出同層級的 姊妹金鑰 的,只有 父金鑰 和 父鏈碼(又是由 Parent 的 Parent 層級的 鑰匙 和 鏈碼 生成) 可以推導出所有的 子金鑰 和 子鏈碼,後續也就可以生成相應的 子公鑰 以及地址,並且用於對交易進行簽名。

將 金鑰 Key 和 Chain Code 結合起來稱為 擴展金鑰(Extended Key),可以透過 擴展金鑰 來生成自其而下的所有分支。

擴展金鑰 中提供的金鑰可以是 私鑰 或者 公鑰,和 鏈碼 結合起來分別稱為 擴展私鑰(Extended Private Key)擴展公鑰(Extended Public Key),並且分別記為 (k, c) 和 (K, c),其中公鑰 K = point(k)。

我們可以從 擴展私鑰 推導出 擴展公鑰,而反之則不可以,因此對於某些交易場景(如電商),可以為每筆交易生成一個新的公鑰和地址來收款,而擴展私鑰可以被儲存在紙質錢包或者硬體錢包中,用於安全的離線簽署交易。可以看到 擴展公鑰 的安全性相對高一些,下图為透過 擴展 父公鑰 來衍生 子私鑰進而生成子公鑰 的傳遞機制:

是否回答了您的問題?