Web3 – OSKey 的实现 – 助记词是怎么生成的?

我们现在使用钱包,无论是软件钱包还是硬件钱包,第一步操作就是让选择生成助记词还是导入助记词,对于新人来说,一定是生成助记词,那这个助记词是怎么生成呢?

我们在前一篇文章中已经介绍过了技术总览,Web3 – 摩天大楼的地基 – 钱包在做什么?- 助记词,本篇详细讨论下助记词的生成步骤。

BIP39

助记词是有共识性标准的,几乎所有的钱包和链都会遵守,文件在这里 https://github.com/bitcoin/bips/blob/master/bip-0039.mediawiki。BIP39 规定了生成的步骤和提供了标准单词表。

OSKey 实现完全遵循 BIP39 规范,并完整通过提供的测试向量。

助记词是什么?

助记词的本质是一段随机数,助记词用人类可读的方式记录这个随机数。单词数越多的助记词对应越长的随机数,安全性越高。

我们先看下规范中的描述:

MS: 助记词单词个数,数量在 12-24 之间按 3 个单词递增。

ENT: 随机数长度

CS: 校验长度

CS = ENT / 32
MS = (ENT + CS) / 11

|  ENT  | CS | ENT+CS |  MS  |
+-------+----+--------+------+
|  128  |  4 |   132  |  12  |
|  160  |  5 |   165  |  15  |
|  192  |  6 |   198  |  18  |
|  224  |  7 |   231  |  21  |
|  256  |  8 |   264  |  24  |

如果是需要 12 个单词的助记词,对应 128 bits 的随机数,对这个随机数进行 SHA256,取 hash 的 4 bits 作为校验位,总长度 132 bits。

单词是如何对应到随机数的?

上面提到的 ENT(随机数)+ CS(校验)总是 11 的倍数,把它们按照每组 11 个 bit 分组,把 11 个 bit 的 2 进制转为 10 进制,我们会得到 0-2047,这些数字对应到单词表就可以得到助记词。

可以看到最后一个单词是带校验的,所以不是从单词表取对应数量的单词就是助记词。

这是单词表,对应各个语言,为了通用性,我们一般选择英语。https://github.com/bitcoin/bips/tree/master/bip-0039

Web3 – OSKey 的实现 - 助记词是怎么生成的?

OSKey 的随机数

计算机如何能够提供一个足够随机的随机熵一直是一个难题,多个钱包因为随机数生成的问题造成用户的资金损失。

OSKey 使用硬件随机数生成器(RNG)来获取随机数,芯片的硬件随机数生成器一般都是符合工业标准的。采用多种方式保证足够随机。

如果芯片没有硬件支持的随机数生成器,则 OSKey 这时候会回退到基于时间的伪随机,如果 OSKey 提示芯片不具备硬件随机数生成器,则生成过程不够安全。

OSKey 助记词的实现

对于助记词的实现在这里,我们解释下生成相关的方法。

https://github.com/butterfly-community/oskey-lib-core/blob/main/wallet/src/mnemonic.rs

Mnemonic::from_phrase(phrase: &str) -> Result<Self>

输入助记词,还原回原始熵并校验校验位,导入

Mnemonic::from_entropy(entropy: &[u8]) -> Result<Self, anyhow::Error>

从随机数生成助记词,提供需要的原始熵。

Mnemonic:: entropy_to_bits(entropy: &[u8]) -> Result<BitVec>

从原始熵生成按 11 个 bit 分组的助记词序号

Mnemonic::bits_to_words(bits: &BitVec) -> Result<Vec<&'static str, 24>>

从助记词序号列表中取出对应的单词,最多 24 个。

OSKey 导入助记词的实现

我们从上面助记词的生成过程已经知晓,不是任意一组单词都是助记词,最后一个单词可以校验输入的单词是否正确。

完整实现中,我们需要执行一个反向的过程,还原回原始熵然后计算一遍校验,对比校验是否正确,如果正确则开始下一步。

关于下一步的实现我们在接下来的 HD Wallet 篇中讨论。

(2)
ChaoChao
上一篇 08/30/2025 17:36
下一篇 04/01/2025 09:38

相关推荐

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注