[TOC]
前言
原文地址:https://www.jianshu.com/p/2472bb87f04b
作者:梦幻艾斯
备注:欢迎转载,请保留原文地址。
摘要
这个BIP描述了一个使用一组方便记忆的单词(简称助记词)生成确定性钱包种子的方案
它由两部分组成:
生成助记词
-
将助记词转化成二进制种子。
这个种子可以通过BIP-0032方法或者类似方法生成一个确定性钱包。
解决的问题
与处理钱包种子的原始二进制或十六进制表示相比,助记码或句子对于人类更容易理解和记忆。助记词可以写在纸上或通过电话说出来。
本指南旨在将计算机生成的随机性与人类可读的转录相结合。这不是一种将用户创建的句子(也称为脑袋)处理成钱包种子的方式。
生成助记词
助记词必须将熵的长度编码为32的倍数。熵的长度越长,安全系数越高,相应的生成的助记词长度越长。我们将初始熵的长度称为ENT。ENT允许的长度是128-256位。
首先,生成一个ENTbits的熵。通过SHA256生成熵的hash,取<pre>ENT / 32</pre> bits当作checksum。这个checksum加在初始熵的后面。
接下来,这些连接的比特被分成11位的组,每个编码从0到2047的数字,用作词表中的索引。最后,我们将这些数字转换成单词,并将这些连词作为助记句。
下表描述了 初始化熵长度 (ENT), checksum 长度 (CS) 和 生成的助记词长度
(MS) 之间的关系
<pre>
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 |
</pre>
疑问:
-
为什么将ENT+CS分割成11位的组?
因为211等于2048,助记词单词列表的个数为2048个。所以11位长度就可以完全覆盖单词列表的索引。
-
为什么ENT的长度是32的倍数
通过公式我们得出MS = (ENT + CS) / 11=(ENT + ENT / 32) / 11得到最终结果:
3ENT = 32 MS
因为ENT和MS都是整数,所以得出ENT是32的倍数,MS是3的倍数
单词表
理想的单词列表具有以下特征:
-
最好的单词选择方式
选择的单词最好只需要输入单词的前4位就可以唯一标识单词
-
避免类似单词
像"build" 和 "built", "woman" 和 "women", 或者 "quick" 和 "quickly"这类单词容易记错或者写错。应该避免使用
-
单词排好序
- 单词列表被排序,允许更高效地查找代码单词
(即实现可以使用二分搜索而不是线性搜索) - 这也允许使用trie(前缀树),例如为了更好的压缩
- 单词列表被排序,允许更高效地查找代码单词
单词列表可以包含本地字符,但它们必须使用规范化表单兼容性分解(NFKD)以UTF-8编码。
从助记词生成种子
用户应该使用密码来保护他们的助记词。如果用户没有提供密码,程序将会用空字符串""代替。
为了从助记词中生成二进制的种子。我们使用PBKDF2函数,以一个助记词句子(以UTF-8 NFKD表示)为参数,使用"mnemonic" + 密码作为盐(以UTF-8 NFKD表示)。迭代次数设置为2048次,HMAC-SHA512函数作为为随机函数。生成的密钥长度为512位(等于64字节)。
盐格式示例:
- 密码为空时盐="mnemonic"
- 密码为"111111"时,盐="mnemonic111111"
这个种子可以在后续使用BIP-0032或类似方法生成确定性钱包。
助记词的选择和助记词生成种子的方法是独立的。这样做使得代码变得很简单。由于对助记词句子对结构没有约束,客户端可以自用的实现他们的单词列表或者助记词生成器。从而简称拼写错误或者其它需求。
虽然使用不是由“生成助记符”部分中描述的算法生成的助记符是可能的,但不建议这样做,并且软件必须使用单词表计算助记符句子的校验和,并且如果它无效则发出警告。
所描述的方法还提供了合理的可否认性,因为每个密码短语都会生成有效的种子(因此也就是确定性的钱包),但只有正确的种子才能使所需的钱包可用。
助记词单词列表
这里是这种语言作为助记词单词列表的使用方式,客户端可以根据需求定制自己的助记词单词列表。