主页 > 官网最新版imtoken钱包 > 比特币源码学习(7)——钱包原理

比特币源码学习(7)——钱包原理

官网最新版imtoken钱包 2023-05-08 07:10:21

首先,我们需要知道比特币钱包中没有比特币。钱包是管理密钥、地址、跟踪余额和创建交易的软件。我们的比特币数据存储在区块链上,而不是钱包中。

经过前面几篇文章的解读,我们知道私钥生成公钥,公钥生成地址。这三者是一一对应的,即一个私钥只有一个公钥和一个地址。但是当我们将钱存入交易所时,我们会看到交易所为我们每个人生成了一个唯一的地址。这是怎么做到的?接下来,君易将为大家解读比特币钱包

目前有两种钱包,一种是非确定性(随机)钱包,随机生成多个私钥,钱包管理这些私钥。如果需要上千个地址随机生成私钥,就需要存储这么多不规则的私钥,非常麻烦且难以管理。另一种是确定性(种子)钱包,这意味着可以通过种子生成无数的私钥,我们只需要记住种子即可。我们使用钱包时记住的助记词可以产生种子,只要我们保留助记词,我们的硬币就可以被找回。那么问题来了?

种子是从哪里来的?种子是如何产生无数地址的?

带着这两个问题,我们来研究一下。先来一张粗略的图,然后我们一步步分析

钱包生成私钥

主要流程是这样的

火币转账到比特币钱包要多久_比特币钱包_win7 怎么删除比特币钱包cpan

首先,随机生成 128 到 258 位的随机数,我们这里称之为熵;

其次,熵通过一定的方法处理,生成助记词;

三、助记词通过key扩展函数PBKDF2生成种子;

四、种子通过HMAC-SHA512算法生成父密钥;

五、通过CKD(child key derivation)函数,父key生成无数个子key。

接下来,君怡会一步步分析细节

一、从熵到助记符

win7 怎么删除比特币钱包cpan_火币转账到比特币钱包要多久_比特币钱包

1、随机产生一个 128 到 258 位的数称为熵

2、熵通过SHA256哈希得到一个值,取前几位(熵长/32),记为y

3、熵和y组成一个新序列,

4、新序列是11位的一部分,已经预定义了2048个单词的字典,对应的单词列表是这样的

5、生成的顺序词组就是助记词

如图:

比特币钱包_火币转账到比特币钱包要多久_win7 怎么删除比特币钱包cpan

二、从助记词生成种子

助记符表示长度为 128 到 256 位的熵。通过使用密钥扩展函数 PBKDF2,熵用于派生更长(512 位)的种子。

PBKDF2的基本原理是传递一个伪随机函数(如HMAC函数),以明文和一个盐值作为输入参数,然后重复操作,最终生成一个密钥。如果重复次数足够多,破解的成本会变得非常高。加盐值也会增加“彩虹表”攻击的难度。

比特币在钱包中,PBKDF2函数的第一个参数是助记词,第二个参数是salt,由一个字符串常量“mnemonic”和一个可选的用户提供的密码字符串组成。使用 HMAC-SHA512 算法,使用 2048 个哈希扩展助记词和盐参数,得到一个 512 位的值作为其最终输出。这个 512 位的值就是种子。图

从助记词生成种子

三、从种子到父键

512位被分成两等份,左边的256位是父私钥,右边的256位是链码。父私钥、链码和索引号、CKD(child key derivation)函数从父密钥导出子密钥。如图所示

火币转账到比特币钱包要多久_比特币钱包_win7 怎么删除比特币钱包cpan

从种子到主密钥

三、 从父键到子键

父键、链码和索引与 HMAC-SHA512 函数组合并散列以生成 512 位散列。生成的哈希可以拆分为两部分。哈希右半部分的 256 位输出可以作为子链的链码。将左半部分的 256 位哈希和索引代码加载到父私钥上,以导出子私钥。在图中,我们看到了这个注——索引集设置为0产生父键的第0个子键(第一个通过索引)。

从主密钥到子密钥

四、扩展键

父密钥和链码的组合称为扩展密钥,扩展私钥可以推导出子私钥比特币钱包,扩展公钥可以推导出子公钥。有了扩展公钥,就可以导出子公钥,服务器不需要父私钥,更加安全方便。但是还有一个问题,就是扩展公钥包含链码,如果子私钥已知或者泄露,链码可以用来推导出所有其他的子私钥。只需泄露私钥以及父链码,就会暴露所有子密钥。更糟糕的是,子私钥和父链码可以用来推导出父私钥。

为此,HD 钱包使用一种称为强化派生的替代派生函数。这“破坏”了父公钥和子链码之间的关系。这个强化的派生函数使用父私钥来派生子链码,而不是父公钥。这会在父/子序列中创建一个“防火墙”——存在链码,但不能用于推断子链码或姐妹私钥。硬化派生函数看起来几乎与普通派生的子私钥相同,只是父私钥用于输入散列函数而不是父公钥。如图所示

比特币钱包_win7 怎么删除比特币钱包cpan_火币转账到比特币钱包要多久

扩展密钥

五、钱包索引

1、如前所述,索引和私钥链码可以生成一个子键,这个索引号是一个32位的整数。为了区分key是从普通推导函数还是硬化推导函数推导出来的,这个索引号分为两个范围。 0 到 2^31–1(0x0 到 0x7FFFFFFF)之间的索引号仅用于常规推导。 2^31 和 2^32 – 1 之间的索引号(0x80000000 到 0xFFFFFFFF)仅用于硬化衍生品。因此,小于2^31的索引号表示子键是正则的,大于等于2^31的子键是硬化的。

2、钱包索引识别路径

HD钱包中的密钥以“路径”命名,每层之间用斜线(/)字符表示(见表5-6)。从主私钥派生的私钥以“m”开头”。从主公钥导出的公钥以“M”开头。因此,主密钥生成的第一个子私钥是m/0。第一个公钥是M/0。子密钥第一个子键是m/0/1,以此类推。

从右到左读取密钥的“祖先”比特币钱包,直到您到达派生它的主密钥。例如,标识符 m/x/y/z 描述了子键 m/x /y 的第 z 个子键。子键 m/x/y 是 m/x 的第 y 个子键。 m/x 是 m 的第 x 个子键。

钱包密钥识别符(路径)

参考链接: