Caloogy 文章
English

助记词是怎么变成私钥的:BIP-39 与 HD 钱包

日期
2025 年 3 月 27 日
系列
钱包
阅读
4 分钟
主题
WalletBip 39Bip 32Bip 44

一句话版本

12 个英文单词其实是一个 128 位随机数加 4 位校验和的"人类可读编码"。它经过 PBKDF2 拉伸成一个 512 位的种子,再按 BIP-32 规则像树一样一层层派生出无数把私钥。所以一组助记词能管理所有链、所有地址。 也因此,助记词就是一切:丢了,所有地址都丢了;泄露了,所有地址都泄露了。

全文分三层:

  1. 通俗理解:一棵钥匙树
  2. 实际用处:为什么"导入后余额是 0"、passphrase 的作用、xpub 泄露的风险
  3. 原理与工程要点:BIP-39 编码与校验、PBKDF2、BIP-32 派生、派生路径,附一个标准测试向量

第一层:通俗理解

1.1 一棵钥匙树

早期的比特币钱包每生成一个新地址,就要多备份一把新私钥,非常麻烦。HD(分层确定性)钱包换了个办法:

  1. 只生成一个根秘密(就是那串助记词);
  2. 用固定的数学规则,从根上"长"出树枝和树叶,每片叶子是一把私钥;
  3. 同样的根、同样的规则,永远长出同样的树。

于是只要备份一次助记词,就能在任何钱包软件里把整棵树完整恢复出来。

1.2 为什么是单词

一个 128 位的随机数写成十六进制是 32 个字符,抄错一个就全完了。BIP-39 把它切成每 11 位一段,每段对应一个单词(211=20482^{11} = 2048 个词的词表),再附带校验位,抄错单词时钱包能发现(和弃九法与校验位里身份证最后一位的作用一样)。


第二层:实际用处


第三层:原理与工程要点

3.1 BIP-39:熵 → 单词

熵 校验和 总位数 单词数
128 位 4 位 132 12
256 位 8 位 264 24

校验和取 SHA256(熵)\mathrm{SHA256}(\text{熵}) 的前 熵位数/32\text{熵位数}/32 位,接在熵后面,再每 11 位查一次词表。

标准测试向量:全零熵

熵为 16 个零字节(128 个 0)。

  • SHA256(00×16)\mathrm{SHA256}(\texttt{00}\times 16) 的开头是 374708ff...,首个十六进制位 3 = 0011,所以校验和是 0011;
  • 132 位 = 前 121 位全是 0,最后 11 位是 0000000 0011;
  • 前 11 段都是 0,对应词表第 0 个词 abandon;最后一段是 3,对应第 3 个词 about(词表开头是 abandon、ability、able、about)。

助记词:abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon about。 这是 BIP-39 官方测试向量里的第一个,绝对不能拿来存钱:所有人都知道它。(校验和已用 Python 验算。)

12 个词里,最后一个词只有一部分位是熵,其余是校验和。所以随便写 12 个词,大约只有 1/161/16 的概率能通过校验。

3.2 单词 → 种子:PBKDF2

seed=PBKDF2-HMAC-SHA512(助记词, salt="mnemonic"+passphrase, 2048 次)\text{seed} = \mathrm{PBKDF2\text{-}HMAC\text{-}SHA512}\big(\text{助记词},\ \text{salt} = \texttt{"mnemonic"} + \text{passphrase},\ 2048 \text{ 次}\big)

2048 次迭代是密钥拉伸:让每猜一次口令都要多花一点时间。不过对于 128 位的随机熵,拉伸其实不太必要;它主要是在保护用户自己设的 passphrase。

3.3 种子 → 树:BIP-32

根节点:HMAC-SHA512("Bitcoin seed", seed)\mathrm{HMAC\text{-}SHA512}(\texttt{"Bitcoin seed"},\ \text{seed}),左 256 位是主私钥,右 256 位是"链码"(chain code)。

每个子节点由父节点的密钥、链码和子编号 ii 经 HMAC-SHA512 算出:

类型 输入 特点
普通派生(i<231i < 2^{31}) 父公钥 + 链码 + ii 只用 xpub 就能派生所有子公钥(方便只读监控)
硬化派生(i≥231i \ge 2^{31},写作 i′i') 父私钥 + 链码 + ii 必须有私钥才能派生;子私钥泄露不会连累父私钥

普通派生下,子私钥 $= $ 父私钥 +tweak+ \text{tweak}(模曲线阶 nn),而 tweak 只依赖公开的 xpub。所以"xpub + 一把子私钥"就能减出父私钥。这就是为什么路径的上面几层都要用硬化派生。

3.4 派生路径

BIP-44 规定:m / purpose' / coin_type' / account' / change / address_index

链 常见路径
比特币(传统地址) m/44'/0'/0'/0/0
比特币(原生隔离见证) m/84'/0'/0'/0/0
以太坊 m/44'/60'/0'/0/0

3.5 工程要点


总结

层次 要点
直觉 一个根秘密,按固定规则长出整棵钥匙树
BIP-39 熵 + SHA-256 校验和,每 11 位一个词;PBKDF2 拉伸成种子
BIP-32 HMAC-SHA512 逐层派生;硬化派生保护父私钥
风险 助记词即一切;路径不同显示余额为 0;xpub 泄露隐私且有连带风险