作者:Mi Zeng

每当你创建加密货币钱包时,钱包都会从一份包含 2048 个标准英文单词的词表(BIP39 词表)里,随机挑选出一串单词作为助记词。助记词安不安全,关键就看这个 “挑选” 的过程够不够随机。“足够随机”,意味着他人偶然得到相同助记词的概率极其小,即使有意想找到它,也没有捷径,只能穷举。问题在于,钱包内部到底是怎么挑的,我们看不见也无法验证。一旦这个过程存在问题,就会给资产带来致命的安全隐患。好在这个随机挑选的过程,我们完全可以自己动手来完成。

那么怎样才能足够随机地从 2048 个词里挑出一串单词呢?想象这样一个场景:把 2048 个单词分别写在大小完全相同的卡片上,然后将所有卡片放进一个大抽奖箱里充分摇匀,闭着眼睛抽出一张,记下单词,再把卡片放回去摇匀,接着抽下一张。这样每抽一次,每个单词被抽中的概率都是 1/2048。

但是制作 2048 张卡片太费事了,我们也很难保证每张卡片的大小完全一致,并在抽奖箱里摇晃均匀。好在有一个现成的替代品 —— 硬币。抛一次硬币,有 2 种结果(正面或反面);抛两次,有 4 种组合(正正、正反、反正、反反);抛三次,有 8 种。每多抛一次,组合数就翻一倍。一直翻下去,抛 11 次时,正反面的组合刚好是 2048 种(2×2×2×2×2×2×2×2×2×2×2=2048),不多不少,正好和词表里的 2048 个单词一一对应。这 2048 种组合中每一种出现的概率也都是 1/2048,和抽卡片一模一样。

也就是说,连续抛 11 次硬币,就相当于从那个装着 2048 张卡片的抽奖箱里抽了一次。只要有一种办法,将这 11 次抛硬币的结果和 2048 个单词一一对应,那么凭借一枚硬币和纸笔,我们就能亲手生成一套完整的 12 词助记词。本教程将带你完整走一遍这个过程。

前期准备

动手前,先准备好以下三样工具:

  1. 一枚普通硬币
  2. 一支笔
  3. 下载好以下两份 PDF 文件,打印出来:

第一步:抛出结果并记录

拿出打印好的《抛硬币记录表》,找一个平整的桌面,抛硬币时保证有一定高度,让它在空中充分翻转后自由落地。将抛出的硬币正反面依次记录在表格中,统一将硬币的正面记为 1,反面记为 0。从第 1 词第 1 格开始,从左到右、逐行往下填入 0 或 1。按照记录表的要求,填满前 11 行,第 12 行只填前 7 格,后 4 格标有 “不填” 的灰色格子留空。你一共需要抛掷 128 次硬币。

在抛硬币的过程当中,你可能会抛出多个连续的 0 或 1,这很正常,不要根据自己的主观意愿去调整 0、1 的分布。

第二步:计算编号,查询词表

记录表每个格子上方都标了一个数,从左到右是 1024、512、256……每往右一格就减半,最右边是 1。抛出正面(记 1)的格子,就把它上方的数加进来;反面(记 0)的格子不加。这样一来,11 次抛硬币的每一种组合,都会对应 0 到 2047 之间唯一的一个编号,正好和 2048 个单词一一对应。把一行加出来的总数写进「加出来的数(编号)」这一栏,算式也一起写上,方便之后核对。

示例:

如果第 1 行抛出的记录是 1 0 1 1 1 0 1 1 1 0 0

10245122561286432168421
10111011100
  • 找出写了 1 的格子上方数字:1024256128641684
  • 加在一起:1024 + 256 + 128 + 64 + 16 + 8 + 4 = 1500

摊开打印好的《BIP39 单词表》,按编号找到对应的英文单词,例如第 1 行编号 1500 对应的单词是 romance,抄在「单词」这一栏。

完成每一行的编号计算,然后查找前 11 行编号对应的单词,填进「单词」栏。第 12 行计算出编号之后,单词栏暂时留空,具体的单词留给下一步解决。

为了方便你对照,下面是一份完整的 12 词推导示范表:

第几个词10245122561286432168421加出来的数(编号)单词
第 1 词101110111001024+256+128+64+16+8+4 = 1500romance
第 2 词00100000100256+4 = 260calm
第 3 词01010010100512+128+16+4 = 660family
第 4 词00110111001256+128+32+16+8+1 = 441damp
第 5 词101011000111024+256+64+32+2+1 = 1379property
第 6 词110001000111024+512+32+2+1 = 1571settle
第 7 词01100101101512+256+32+8+4+1 = 813grant
第 8 词100010011111024+64+8+4+2+1 = 1103measure
第 9 词00010001100128+8+4 = 140bag
第 10 词100101011011024+128+32+8+4+1 = 1197noble
第 11 词01111001010512+256+128+64+8+2 = 970junk
第 12 词0010001不填不填不填不填256+16 = 272(留空,待第三步试出)

第三步:用钱包试出第 12 个词

第 12 个单词比较特殊,不能直接通过查表得出。记录表第 12 行的最后 4 格标着 “不填”,这是留给防错校验机制用的:4 个格子,每格都有 0 和 1 两种填法,一共就有 2×2×2×2 = 16 种填法,每一种组合都对应一个不同的单词,也就是从算出的编号开始(含该编号本身)往后连续 16 个单词。我们不需要弄懂复杂的校验公式,直接利用钱包自带的检验功能挨个尝试,就能把唯一正确的那一个试出来。

首先,我们需要在单词表里找到这 16 个候选单词。 以上文示范表为例,第 12 行算出的基础编号是 272。打开打印好的单词表,从 272 开始往后数 16 个单词(即编号 272 到 287),这 16 个候选词分别是:

capitalcaptaincarcarboncardcargocarpetcarrycartcasecashcasinocastlecasualcatcatalog

接下来,在钱包中尝试这 16 个词:

  1. 打开你日常使用的钱包,选择「导入钱包」或「恢复助记词」。
  2. 依次输入前面查好的前 11 个单词。
  3. 输入第 12 个单词时,按顺序挨个尝试填入这 16 个候选词。
  4. 如果钱包提示 “助记词无效” 或 “校验错误”,换下一个候选词继续试。

在这 16 个词里,有且仅有 1 个词能够成功通过钱包验证(在本示例中,唯一能成功通过的是 carpet)。

只要钱包顺利通过校验并成功导入,就说明这个词完全正确。把这个单词工整地抄在记录表的第 12 行最后一格。

第四步:倒序核对与正式备份

  1. 倒序核对:花几分钟从后往前倒着核对一遍加法计算是否正确,以及编号对应的单词是否抄写准确。倒着检查能更有效地避开大脑的惯性,防止粗心看错行。
  2. 正式备份:将确认无误的 12 个单词,工整抄写在专用的助记词卡片或金属助记词板上。然后,妥善保管好你的备份。

第五步:彻底销毁草稿与打印表

确认助记词已经正确抄写备份后,请立即处理现场留下的所有纸质痕迹:

  • 刚才填写的《抛硬币记录表》上记录了完整的硬币正反面与计算推导过程;
  • 《BIP39 单词表》上也可能留有查阅的痕迹。

请务必使用剪刀彻底剪碎、放入碎纸机或直接安全烧毁,绝对不要完整地丢进垃圾桶,防止被他人发现与再次利用。

注意事项

  • 严禁直接套用文中的演示数据:本文中出现的所有演示数据以及推导出的助记词,均为全网公开的信息。切勿直接将文中的任何示例用于真实钱包。
  • 严禁拍照与任何数字化记录:记录表上的数据与助记词只允许存在于纸上,千万不要使用手机拍照,不要通过在线工具传输,更不要保存到任何笔记软件中。
  • 正式存入资产前进行演练测试:在正式存入大额资产前,建议先将钱包重置清空,尝试完全重新导入一遍助记词;并转入、转出一笔极小金额测试交易功能,确认没有问题后再投入正式使用。
  • 关于 24 词助记词:本教程只介绍 12 词助记词的生成方式。对绝大多数人来说,12 词助记词在安全强度上已经完全足够,并不需要刻意追求 24 个词。如果你仍然想要手动创建 24 词助记词,则必须借助工具才能完成,具体做法可以参考这篇文章