什么是 BIP-39

2023-04-15分类:钱包 阅读(

BIP-39 规范主要描述了基于助记词(一组便于记忆的单词)来生成确定性钱包的算法和过程。

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 Key 或 Parent 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)。

我们可以从 扩展私钥 推导出 扩展公钥,而反之则不可以,因此对于某些交易场景(如电商),可以为每笔交易生成一个新的公钥和地址来收款,而扩展私钥可以被存储在纸质钱包或者硬件钱包中,用于安全的离线签署交易。可以看到 扩展公钥 的安全性相对高一些,下图为通过 扩展 父公钥 来衍生 子私钥进而生成子公钥 的传递机制:

Tags: