BIP39描述了如何生成助记符,并将其转换为二进制种子。该种子可以生成确定性钱包。
如何生层助记词
我们先看看助记词范围——单词表。生成助记词的过程就是这个表里(2048个单词,记住这个数值)选出12个单词。是不是很简单,你可能会想我自己挑选12个不就OK了;这就有个概率的问题,你自己选的和别人选的,有多大概率重复呢?你想想你注册某个网站起名字的时候就知道了,是不是经常重复?所以说生成助记词的难点就是如何让每个钱包的助记词都不一样,和区块链里账户的地址,还有hash等是一个道理。
1、生成一个128~256bit的熵(熵的解释可以看一下附录)。这里规定了熵只能是32的整数倍,熵值越大,越安全,助记词也会越多。熵的长度成为ENT(128~256);熵的来源比较重要,一般肯能使用的OS提供,用户不会感知这个过程;有些为了提高熵值,会让用户通过摄像头取获取照相,毕竟每个人照像一样的概率很小吧。
2、取熵哈希后的前CS位作为校验值,这里CS=ENT/32。CS取值4,5,6,7,8 。
3、生成一个新的序列,熵+校验值。
4、把步骤3中的序列,按照11bit进行切割;为什么是11呢?上边说了2048个助记词,。如果我们这2048个词编个号,则每11bit就对应一个单词。
序号 | 单词 |
00000000000 | abandon |
... ... | ... ... |
11111111111 | zoo |
5、步骤四中依次产生的单词就是助记词了。
ENT:熵长度。CS:校验长度。MS:助记词长度。之间的关系如下:
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 |
助记词生成种子
6、我们使用PBKDF2函数,助记词作为密码,"mnemonic" +passphrase作盐。有了这两个参数就可以进行下一步了。用户可以决定用passphrase。如果不存在passphrase,则使用空字符串“”。(PBKDF2的解释可以看一下附录里的key stretching)
7、HMAC-SHA512用作伪随机函数,迭代计数设置为2048。
8、生成长度为512bit的种子。
至此就完成了,下一步就可以拿着种子去生成私钥了。
这玩意儿接触越多,越觉得像量子力学,一个庞大稳定的系统建立在一个依赖概率的密码学之上。
附录:
熵:熵的概念最早起源于物理学,用于度量一个热力学系统的无序程度。在信息论里面,熵是对不确定性的测量。我们知道,任何粒子的常态都是随机运动,也就是"无序运动",如果让粒子呈现"有序化",必须耗费能量。所以,温度(热能)可以被看作"有序化"的一种度量,而"熵"可以看作是"无序化"的度量。
1948年,香农Claude E. Shannon引入信息(熵),将其定义为离散随机事件的出现概率。一个系统越是有序,信息熵就越低;反之,一个系统越是混乱,信息熵就越高。所以说,信息熵可以被认为是系统有序化程度的一个度量。
文章开始也说了我们需要每个钱包生成助记词都不一样,当然是希望熵高,混乱,就是每个钱包的熵值都不一样的。
Key stretching 在密码学中,秘钥延伸技术通常用来增加弱密码的安全性,增加暴力破解 (Brute-force attack) 密码时花费的时间。任何系统中都会有弱密码的存在,尤其是人为设定的密码,通常都比较短,或者有规律可循,以致于容易被暴力破解出来。秘钥延伸技术让这种攻击更难成功。
密钥延伸技术的工作机制,算法的输入是初始key, 算法的输出是增强key。 增强key应该足够长以抵御暴力破解(至少128bits)。这个算法的基本要求是:找不到一个比该算法能更快能从初始key算出增强key的捷径。
PBKDF2(Password-Based Key Derivation Function 2) 是常用的 key stretching 算法中的一种。基本原理是通过一个为随机函数(例如 HMAC 函数),把明文和盐值作为输入参数,然后重复进行运算最终产生密钥。