比特币早期的钱包客户端 Satoshi Client 里面会自动随机生成 100 个私钥、公钥对,这些私钥之间完全没有关联,这种钱包也叫做随机钱包(Random Wallet)或者非确定性钱包(Non-Deterministic Wallet),钱包的备份和恢复必须针对每个私钥进行

如果能随机产生一个种子,然后根据这个种子去生成一系列的私钥、公钥对,这样钱包的备份就会容易很多,因为只需要备份随机的种子就行了,这种根据随机种子按确定规则生成一系列钱包的方式就叫做种子钱包(Seeded Wallet)或确定性钱包(Deterministic Wallet),种子钱包在生成多个私钥时会用到序号作为参数,所以这种钱包也叫线性确定性钱包(Sequential Deterministic Wallet)

种子钱包解决了备份的问题,但是还是不完美,没有办法把钱包的一部分共享出去给别人管理,但同时自己保有知情权、控制权。社区的智慧是无穷的,分层确定性钱包应运而生:

根据父节点私钥(Parent Private Key)生成子节点私钥(Child Private Key)的流程如下图:

把父节点公钥、父节点链码、子节点序号作为参数求 HMAC-SHA512 得到 512 位输出;
把步骤 1 的输出拆分为两个等长的 256 位串,分别标记为 L、R;
把步骤 2 的输出 L 和父节点公钥做运算得到子节点公钥(Child Public Key);
把步骤 2 的输出 R 当做子节点链码(Child Chain Code);
子私钥生成函数在 BIP32 中被标记为:
根据父节点公钥生成子节点公钥的流程如下图

根据父节点私钥和椭圆曲线乘法推导出父节点公钥(Parent Public Key);
把父节点公钥、父节点链码、子节点序号作为参数求 HMAC-SHA512 得到 512 位输出;
把步骤 2 的输出拆分为两个等长的 256 位串,分别标记为 L、R;
把步骤 3 的输出 L 和父节点私钥做运算得到子节点私钥(Child Private Key);
把步骤 3 的输出 R 当做子节点链码(Child Chain Code);
子节点私钥、子节点链码可以作为输入传给 CKD,就可以生成孙节点,以及任意深度的节点。子私钥生成函数在 BIP32 中被标记为:
主秘钥的生成。任选128到256位的数字作为种子。可以转换成助记词
种子经过一次HMAC-SHA512计算得到主密钥。
生成 128 位的随机数,这个随机数在 BIP29 中叫做熵(Entropy,简写为 ENT);
对随机数做 SHA256,取前 4 位为校验码(Checksum);
把步骤 1、2 中的结果拼接得到 132 位的结果,然后分割成 12 个长度为 11 位的串;
将 12 个串转化为十进制数字去此表中查找对应的单词;
把查找到的单词按顺序拼接起来构成助记词;