主页 > imtoken如何安装 > 比特币学习2-BIP32协议翻译解读

比特币学习2-BIP32协议翻译解读

imtoken如何安装 2023-01-17 14:27:57

======================== 翻译和口译 =================

抽象的

该文件描述了分层确定性钱包(或“HD 钱包”):可以部分或完全与不同系统共享的钱包,每个系统都可以或不可以花费硬币。

该规范旨在为可在不同客户端之间互换的确定性钱包设定标准。 虽然此处描述的钱包具有许多功能,但并非所有支持客户都需要它们。

本规范由两部分组成。 在第一部分中,介绍了一种从单个种子派生密钥对树的系统。 第二部分演示如何在这样的树上构建钱包结构。

注意:在这里写下你对非确定性钱包、确定性钱包、分层确定性钱包的理解

非确定性钱包——随机生成的密钥对的集合确定性钱包——从一个种子生成的密钥对的集合分层确定性钱包——扩展密钥(私钥、链码),扩展密钥可以生成多个密钥对和多个单词。 扩展密钥协议要解决的问题(动机)

比特币标准客户端使用随机生成的密钥。 为避免每次交易后备份钱包,(默认情况下)客户端会生成 100 个密钥并缓存在备用密钥池中。 该钱包无意共享私钥和跨不同系统使用。 (注:这句话的翻译有点假,请看原文)。 他们使用钱包加密来隐藏他们的私钥而不是共享密码。 (解读:这类钱包在备份时,总是备份一个加密文件,恢复时从加密文件中恢复),但这些“中立”的钱包也失去了生成公钥的能力。 (注:本文解决非确定性钱包的问题)

确定性钱包不需要如此频繁的备份,椭圆曲线数学允许在不泄露私钥的情况下计算公钥的方案。 这允许例如在线商店业务使其网络服务器为每个订单或每个客户生成一个新地址(公钥哈希),而无需让网络服务器访问相应的私钥(这是收到的资金需要花费的地方)。

然而,确定性钱包通常由一对密钥组成。 只有一条链意味着共享钱包时,接收者可以完全控制你的钱包。 但有时我们只需要共享部分公钥。 在网上商店的例子中,网络服务器不需要访问商家钱包的所有公钥; 只有那些用于接收客户付款的地址,而不是更改地址,例如,当商家花钱时。 分层确定性钱包通过支持从单个根生成的多个密钥对链来允许这种选择性共享。 (注:本文解决的是确定性钱包的问题)

规范:关键公式推导约定

在本文的其余部分,我们将假设使用比特币中的公钥密码术,即使用

具有定义字段和曲线参数的椭圆曲线密码学。 以下变量是:

(注:描述Fp上的椭圆曲线,常用六个参数:T=(p,a,b,G,n,h),详见比特币学习1--椭圆曲线算法)

两个坐标对的加法(+)定义为EC组运算的应用。 串联 (||) 是将一个字节序列附加到另一个字节序列的操作。

作为标准转换函数,我们假设:

扩展键

接下来,我们将定义一个从父键派生一些子键的函数。 为了防止这些仅依赖于父密钥本身,我们首先使用额外的 256 位熵扩展私钥和公钥。 此扩展称为链代码。 相应的私钥和公钥的链码相同,由 32 个字节组成。

我们将扩展私钥表示为 (k,c),其中 k 是普通私钥,c 是链码。扩展公钥表示为 (K,c),其中 K = point(k),c 是链码

每个扩展密钥有 231 个普通子密钥和 231 个增强子密钥。 这些子项中的每一个都有一个索引。 普通子项使用索引 0 到 231 -1。 强化子项使用索引 231 到 232 -1。 为了简化强化键索引的表示法,数字 iH 表示 i+231。

子密钥推导方法

给定父扩展密钥和索引 i,可以计算相应的子扩展密钥。 该算法取决于父扩展密钥是私有扩展密钥还是公共扩展密钥,以及 i 是普通索引还是加固索引 (i >= 231)

父私钥 -> 子私钥

函数 CKDpriv((kpar, cpar), i) → (ki, ci) 从父扩展私钥计算子扩展私钥:

将 I 分成两个 32 字节的序列,IL 和 IR。 得到的子私钥ki = parse256(IL) + kpar (mod n)。 得到的链码ci = IR。 当 parse256(IL) ≥ n 或 ki = 0 时,导出的子密钥无效,我们应该将索引 i 设置为下一个值。 (注:2127年发生这种情况的概率小于1。)

HMAC-SHA512 函数在 [RFC 4231] 中定义。

父公钥 -> 子公钥

函数 CKDpub((Kpar, cpar), i) → (Ki, ci) 从父扩展公钥计算子扩展公钥。 只适用于普通子公钥(索引i满足0个子公钥

定义:函数N((k, c)) → (K, c)计算扩展私钥对应的扩展公钥(作为中间版本,去掉了签署交易的功能)。

从父私钥计算子公钥的方法:

它们是等价的这一事实使非强化密钥变得有用(人们可以在不知道任何私钥的情况下派生出给定父密钥的子公钥),也是它们与强化密钥的区别。 不总是使用非硬化密钥(更有用)的原因是安全性; 进一步了解更多信息。

子公钥可以在不知道父私钥的情况下从父公钥导出。 这就是非强化密钥的用处,也是它们与强化密钥的区别所在。 那么为什么不总是使用非硬化密钥呢? 这里涉及到安全问题,具体请看后面的内容。 (注:此译文有点虚构,附原文)

父公钥 -> 子私钥

不可能的

=============子键推导方法谜题解读开始============

在父公钥->子公钥推导过程中,子公钥是从父公钥推导出来的。 我们知道每个公钥只对应一个私钥,那么子公钥对应的私钥到底是什么呢? (这个问题在我第一次看到这个协议的时候疑惑了很久)

先给出答案:父公钥->子公钥导出的公钥对应的私钥就是父私钥->子私钥导出的私钥。 下面我们证明这个公式。

因为Kpar = point(kpar)比特币私钥分享,所以得出Ik等于IK

公式K=kG=point(k)由公钥导出,子私钥乘以G得到

kiG = parse256(IkL)G + kpar (mod n)*G

K=点(parse256(IkL))+ Kpar =点(parse256(IKL))+ Kpar

证明完成

非硬化密钥母公钥推导子公钥的安全问题:

访问扩展公钥并不能访问子私钥。 然而,由于扩展公钥包含链码,如果子私钥已知或泄露,链码可用于派生所有其他子私钥。 一个简单的泄露私钥,连同父链代码,可以暴露所有子密钥。 更糟糕的是,子私钥和父链码可以用来推断父私钥。

解决方案:为了避免推导主密钥,最好对主密钥派生出的一级子密钥使用增强推导。

具体参考:《精通比特币——第4章》

=============子密钥推导方法谜题解读完毕=============密钥树

下一步是级联几个 CKD 结构来构建树。 我们从根开始,即主扩展密钥 m。 通过对 i 的多个值计算 CKDpriv(m,i),我们得到许多 1 级派生节点。 由于这些节点是扩展密钥,因此 CKDpriv 也可以应用于这些节点。

为了简化符号,我们将 CKDpriv(CKDpriv(CKDpriv(m,3H),2),5) 写为 m/3H/2/5。 相当于公钥,我们把CKDpub(CKDpub(CKDpub(M,3),2),5)写成M/3/2/5。 这导致以下身份:

但是N(m/aH)不能写成N(m)/aH,因为后者是不可能的。 从父公钥->子公钥算法可知,加固子健不能使用公钥推导出子公钥

树中的每个叶节点对应于一个实际的键,而内部节点对应于从它们下降的键集合。 叶节点的链码被忽略,只有它们嵌入的私钥或公钥是相关的。 由于这种结构,知道扩展私钥允许重构所有后代私钥和公钥,知道扩展公钥允许重构所有后代非加密公钥。

密钥标识符

可以通过序列化 ECDSA 公钥 K 的 Hash160(SHA256 之后的 RIPEMD160)来识别扩展密钥,忽略链代码。 这与传统比特币地址中使用的数据完全相同。 不建议以 base58 格式表示此数据,因为它可能被解释为一种地址(并且钱包软件不需要接受对链密钥本身的付款)。

标识符的前 32 位称为密钥指纹。

序列化格式

扩展的公钥和私钥序列化格式如下

这个78字节的结构可以像其他比特币数据一样使用Base58编码,先加上一个32位校验和(对78字节数据做两次SHA-256运算,然后取结果的前32位)然后执行Base58编码。 最后得到一个长度为112的字符。 由于不同情况下选择的版本号不同,以Base58格式表示的扩展密钥有以下规则。主网以“xprv”或“xpub”开头,测试网以“tprv”或“tpub”开头

请注意,父节点的指纹识别只能用作检测软件中父节点和子节点的快速方法,软件必须愿意处理冲突。 在内部,可以使用完整的 160 位标识符。

导入序列化扩展公钥时,实现必须验证公钥数据中的 X 坐标对应于曲线上的一个点。 否则,扩展公钥无效。

主密钥生成

可用的扩展密钥对总数约为 2512,但生成的密钥长度仅为 256 位,并且必须删除一半的不安全密钥对。 所以主密钥不是直接生成的,而是从一个短种子生成的。

比特币私钥分享_比特币私钥分享_比特币私钥是什么

图片

规格:钱包结构

前面的部分指定了关键树及其节点。 下一步是在这棵树上强加一个钱包结构。 本节中定义的布局仅为默认布局,但鼓励客户模拟它以实现兼容性,即使并非所有功能都受支持。

默认钱包布局

一个HD钱包由多个“账户”组成。 账户有编码,默认账户("")的编码为0。如果客户端不需要支持多账户,只需要使用默认账户即可。

每个帐户都包含两个密钥对:内部和外部。 外部钥匙串用于生成新的公共地址,而内部钥匙串用于所有其他操作(更改地址比特币私钥分享,生成地址,......,任何不需要传输的东西)。 不支持拆分链代码的客户端应该对所有内容使用外部密钥对。