-
5.3 从种子中创造HD钱包
-
HD钱包从单个根种子(root seed)创建,后者为128,256到512位的随机数。最常见的是,这个种子是从助记词产生的,如上一节所述。
HD钱包的所有密钥是由根种子确定的,使用这个根种子就可以在任何兼容HD钱包中重新创造整个HD钱包。所以简单的转移生成HD钱包根种子的助记词就可以很容易地备份,储存导出以及导入HD钱包中所包含的数以千计百万计的密钥。
图5-9展示从根种子创建主密钥以及HD钱包的主链码的过程。
图5-9 从根种子创建主密钥,主链码
根种子作为HMAC-SHA512算法的输入,得到的哈希值可以用来创造主私钥master private key(m) 和 主链码master chain code(c) 。
主私钥(m)使用标准椭圆曲线乘法过程m * G生成对应的主公钥(M)。
链码用于从父密钥创造子密钥的函数中引入熵。如下一节所示。
5.3.1 私有子密钥的衍生
分层确定性钱包使用子密钥衍生child key derivation,简称CKD函数从父密钥衍生出子密钥。
子密钥衍生函数是基于单向哈希函数。这个函数结合了:
.一个父私钥或者公钥(ECDSA压缩密钥)
.一个叫做链码(256 位)的种子
.一个索引号(32 位)
链码是用来给这个过程引入确定性随机数据的,使得仅凭索引和子密钥也不足以衍生其他子密钥。因此,有了子密钥并不能发现自己的姊妹密钥,除非再有了链码。最初的链码种子(在密码树的根部)是用种子制造的,随后的子链码从各自的父链码衍生出来。
这三个项目(父密钥,链码,索引)相结合并哈希计算生成子密钥,如下。
父公钥,链码以及索引号合并在一起用HMAC-SHA512算法哈希计算之后产生512位的哈希值。所得的哈希拆分为两部分。右半部分的256位成为子链链码。左半部分256位附加到父私钥来衍生子私钥。在图5-10中,我们看到,索引设置为0,生成父级的“0”子级(第一个索引)。
图5-10 扩展父私钥创建子私钥
改变索引允许我们扩展父级,并按顺序创建其他子级,例如子级0、子级1、子级2等。每一个父密钥可以有2,147,483,647 (231) 个子密钥。(231是整个232范围可用的一半,另一半是为特定类型的推导而保留的,我们将在本章稍后讨论。)
向密码树下一层重复这个过程,每个子密钥可以依次成为父密钥,继续创造它自己的子密钥,直到无限代。
5.3.2 使用衍生的子密钥
子私钥与不确定(随机)密钥区别不大。因为衍生函数是单向的,所以子密钥不能被用来发现它的父密钥。子密钥也不能用来发现它们的相同层级的姊妹密钥。如果你有第n个子密钥,你不能发现它的姐妹密钥,比如前面的(第n-1)或者后面的子密钥(n+1)或者在同一顺序中的其他子密钥。只有父密钥以及链码才能得到所有的子密钥。没有子链码,子密钥也不能衍生出任何孙密钥。你需要同时有子私钥以及对应的子链码才能创建一个新的分支,衍生出孙密钥。