diff --git a/BTC/Basic/hdwallet/extendKeys.md b/BTC/Basic/hdwallet/extendKeys.md new file mode 100644 index 000000000..9102d4de8 --- /dev/null +++ b/BTC/Basic/hdwallet/extendKeys.md @@ -0,0 +1,104 @@ +HD钱包中的**扩展公钥(Extended Public Key, xPub)**和**扩展私钥(Extended Private Key, xPriv)**是BIP32标准的一部分,它们是用于派生子密钥和管理钱包的关键概念。以下是它们的详细技术介绍。 + +### 1. **扩展密钥的定义** +- **扩展私钥(xPriv)**:包含私钥和链码的信息,允许派生出子私钥和子公钥。 +- **扩展公钥(xPub)**:包含公钥和链码的信息,只能派生出子公钥,无法推导出私钥。 + +![extend keys](./imgs/hd-wallets-extended-keys.png) + +### 2. **扩展密钥的组成** +扩展密钥不仅包括公钥或私钥,还包括链码(Chain Code)、路径信息等,以支持分层确定性派生。扩展密钥的完整组成如下: + +- **公钥/私钥**:用于加密和签名的密钥。 +- **链码**:确保子密钥派生时的不可预测性,提供额外的随机性。 +- **深度(Depth)**:当前密钥的层级深度,根节点为0。 +- **父公钥指纹(Parent Fingerprint)**:标识父密钥,用于防止路径冲突。 +- **索引(Index)**:指示该密钥在父密钥下的派生索引。 +- **版本(Version)**:指示密钥类型(xPub 或 xPriv)。 +- **校验和**:用于验证密钥完整性。 + +### 3. **扩展密钥的编码格式** +扩展密钥通常以Base58Check格式进行编码,确保其易于人类读取和传输。Base58Check编码避免了易混淆的字符(如0和O,l和I)。编码后的扩展密钥通常以以下前缀开头: +- **xPub**:用于表示扩展公钥。 +- **xPriv**:用于表示扩展私钥。 + +#### **编码示例** +扩展密钥的编码格式如下: +``` +[version (4 bytes)][depth (1 byte)][parent fingerprint (4 bytes)][child number (4 bytes)] +[chain code (32 bytes)][key data (33 bytes)][checksum (4 bytes)] +``` + +### 4. **生成扩展私钥和扩展公钥** +#### a. **生成扩展私钥** +扩展私钥是通过HMAC-SHA512生成的。算法步骤如下: +- 生成主私钥和链码时,将种子输入HMAC-SHA512,并使用“Bitcoin seed”作为密钥。 +- 输出前32字节是私钥,后32字节是链码。 + +#### b. **生成扩展公钥** +从扩展私钥可以生成扩展公钥,通过椭圆曲线加密(ECC)运算将私钥转换为公钥。 + +**扩展公钥生成步骤**: +- 取扩展私钥的前32字节(私钥部分),并将其转换为公钥。 +- 保留链码和其他元数据。 + +### 5. **子密钥派生过程** +扩展密钥的强大之处在于,它们支持通过链码进行分层确定性派生,生成子密钥而不需要暴露父级的私钥。 + +#### a. **从扩展私钥派生子私钥** +扩展私钥可以派生子私钥和子公钥。 +- **算法**: + ``` + I = HMAC-SHA512(key=parent_chain_code, data=0x00 || parent_private_key || child_index) + ``` + - `I` 的前32字节用作派生的子私钥的一部分,后32字节用作新的子链码。 + - 子私钥公式:`child_private_key = (IL + parent_private_key) % n`。 + +#### b. **从扩展公钥派生子公钥** +扩展公钥只能派生子公钥,无法反推出私钥,确保了安全性。 +- **算法**: + ``` + I = HMAC-SHA512(key=parent_chain_code, data=parent_public_key || child_index) + ``` + - 子公钥通过公钥加法计算得出。 + - 子公钥公式:`child_public_key = G * IL + parent_public_key`(`G` 为椭圆曲线生成点)。 + + +![why-it-works](./imgs/hd-wallets-extended-keys-why-it-works.png) + +### 6. **硬化派生与标准派生** +- **硬化派生**(Hardened Derivation):只能通过扩展私钥派生,子公钥无法通过扩展公钥派生出来,增加了安全性。索引大于等于 `2^31` 的值用于硬化派生。 +- **标准派生**(Non-Hardened Derivation):可以通过扩展公钥派生出子公钥,索引小于 `2^31`。 + +### 7. **用途和安全性** +- **xPub的应用**:适用于公开应用,如钱包软件中用来显示和管理多个收款地址。通过扩展公钥,第三方可以生成新的地址而不接触私钥。 +- **xPriv的应用**:仅用于安全环境,绝不能公开,以防止密钥泄露。 + +**安全注意事项**: +- **保护扩展私钥**:xPriv的泄露意味着整个密钥树的私钥都处于危险中。 +- **使用硬化派生**:在可能被公开的路径中,建议使用硬化派生来确保私钥安全。 + +### 8. **示例代码** +以下是使用JavaScript库生成扩展密钥的示例代码: + +```javascript +const bip32 = require('bip32'); +const bip39 = require('bip39'); + +// 生成助记词和种子 +const mnemonic = bip39.generateMnemonic(); +const seed = bip39.mnemonicToSeedSync(mnemonic); + +// 生成根节点 +const root = bip32.fromSeed(seed); + +// 获取扩展公钥和扩展私钥 +const xPriv = root.toBase58(); +const xPub = root.neutered().toBase58(); + +console.log('扩展私钥 (xPriv):', xPriv); +console.log('扩展公钥 (xPub):', xPub); +``` + +### **总结** +扩展公钥(xPub)和扩展私钥(xPriv)是HD钱包中的核心概念,提供了派生和管理子密钥的能力。xPriv 可以派生子私钥和子公钥,而 xPub 只能派生子公钥。使用这些扩展密钥,用户和开发者可以实现灵活的密钥管理,同时保证密钥的安全性。 \ No newline at end of file diff --git a/BTC/Basic/hdwallet/imgs/entry-to-mnemonic.png b/BTC/Basic/hdwallet/imgs/entry-to-mnemonic.png new file mode 100644 index 000000000..6c910099d Binary files /dev/null and b/BTC/Basic/hdwallet/imgs/entry-to-mnemonic.png differ diff --git a/BTC/Basic/hdwallet/imgs/hd-wallets-extended-keys-why-it-works.png b/BTC/Basic/hdwallet/imgs/hd-wallets-extended-keys-why-it-works.png new file mode 100644 index 000000000..79cb14a13 Binary files /dev/null and b/BTC/Basic/hdwallet/imgs/hd-wallets-extended-keys-why-it-works.png differ diff --git a/BTC/Basic/hdwallet/imgs/hd-wallets-extended-keys.png b/BTC/Basic/hdwallet/imgs/hd-wallets-extended-keys.png new file mode 100644 index 000000000..4615602eb Binary files /dev/null and b/BTC/Basic/hdwallet/imgs/hd-wallets-extended-keys.png differ diff --git a/BTC/Basic/hdwallet/imgs/mnemonic-to-seed.jpeg b/BTC/Basic/hdwallet/imgs/mnemonic-to-seed.jpeg new file mode 100644 index 000000000..664314fae Binary files /dev/null and b/BTC/Basic/hdwallet/imgs/mnemonic-to-seed.jpeg differ diff --git a/BTC/Basic/hdwallet/imgs/seed-to-root.png b/BTC/Basic/hdwallet/imgs/seed-to-root.png new file mode 100644 index 000000000..dfdbb47d4 Binary files /dev/null and b/BTC/Basic/hdwallet/imgs/seed-to-root.png differ diff --git a/BTC/Basic/hdwallet/mnemonic.md b/BTC/Basic/hdwallet/mnemonic.md new file mode 100644 index 000000000..9d358a867 --- /dev/null +++ b/BTC/Basic/hdwallet/mnemonic.md @@ -0,0 +1,88 @@ +HD钱包中的助记词(Mnemonic Phrase)是一组人类可读的单词,用来表示随机生成的种子。助记词为用户提供了一个易于备份和恢复的钱包方式,极大地简化了复杂的密钥管理。以下是HD钱包助记词的详细技术原理: + +### 1. **助记词的定义和作用** +助记词是一串用来帮助用户记忆种子的单词序列。HD钱包使用助记词来生成用于派生密钥的种子,因此只要备份助记词,就可以恢复整个钱包的密钥树。 + +### 2. **助记词生成的步骤** +助记词生成过程基于BIP39标准,涉及以下步骤: + +#### a. **生成熵(Entropy)** +- **熵的定义**:熵是用于随机生成助记词的随机位序列。常见的熵长度有128位、160位、192位、224位和256位。 +- **例子**:假设熵为128位,它会生成12个单词的助记词。 + +#### b. **计算校验和(Checksum)** +- 将熵进行SHA-256哈希,取哈希结果的前 `ENT / 32` 位作为校验和,其中 `ENT` 是熵的位长度。 +- **例子**:如果熵是128位,则校验和为 `128 / 32 = 4` 位。 + +#### c. **组合熵和校验和** +- 将原始熵和校验和组合,形成一个新的位序列。例如,128位熵加上4位校验和形成132位序列。 + +#### d. **分割为11位块** +- 将132位的位序列分割为多个11位的块,每个块可以表示0到2047之间的一个数字。 +- 这些数字用于从一个2048个单词的字典(BIP39单词表)中查找对应的单词。 + + +![entry-to-mnemonic.png](./imgs/entry-to-mnemonic.png) + +### 3. **BIP39单词表** +- **固定单词表**:BIP39定义了一个包含2048个单词的标准单词表。这些单词具有以下特点: + - 每个单词都有明确的拼写,不易混淆。 + - 单词表的不同语言版本保持一致性,但使用的是本地语言词汇。 + +### 4. **种子生成** +助记词本身并不能直接用于密钥派生。助记词需要经过密码学处理生成一个种子,种子用来生成HD钱包的主私钥和链码。 + +#### a. **PBKDF2函数** +- 助记词通过PBKDF2-HMAC-SHA512算法与一个盐值组合,生成512位种子。 +- **盐值**:通常是 `mnemonic` 加上一个用户提供的密码短语(可选),增强了安全性。 +- **算法**: + ```text + seed = PBKDF2(mnemonic, "mnemonic" + passphrase, 2048, 64, HMAC-SHA512) + ``` + + +![mnemonic-to-seed.png](./imgs/mnemonic-to-seed.jpeg) + + +### 5. **助记词的恢复** +当用户输入助记词进行恢复时,钱包软件会执行以下步骤: +- 将助记词映射回原始熵和校验和。 +- 验证助记词是否有效(检查校验和)。 +- 使用PBKDF2函数将助记词和用户输入的密码短语(如果有)转换为种子。 +- 通过该种子生成HD钱包的主私钥和链码,从而恢复整个密钥树。 + + +![seed-to-root.png](./imgs/seed-to-root.png) + + +### 6. **助记词的优点** +- **易于记忆和备份**:助记词比纯随机的密钥更容易记住和存储。 +- **便于恢复**:只要用户保留助记词,就可以在任何支持BIP39的HD钱包中恢复整个钱包。 +- **增加安全性**:通过密码短语增强了助记词的安全性。如果助记词被泄露,攻击者仍然需要知道密码短语才能恢复钱包。 + +### 7. **助记词的安全注意事项** +- **备份和存储**:助记词应以离线方式备份,如写在纸上并存放在安全的地方。不要将助记词存储在联网设备上。 +- **密码短语**:使用一个复杂且不易猜测的密码短语可以大大提高安全性,即使助记词被盗,攻击者也无法轻易访问钱包。 +- **防止物理和电子威胁**:确保助记词的存储位置防范火灾、盗窃或电子攻击。 + +### 8. **技术示例** +以下是使用JavaScript库生成助记词和种子的示例代码: + +```javascript +const bip39 = require('bip39'); + +// 生成12个单词的助记词 +const mnemonic = bip39.generateMnemonic(); +console.log('助记词:', mnemonic); + +// 验证助记词是否合法 +const isValid = bip39.validateMnemonic(mnemonic); +console.log('助记词是否合法:', isValid); + +// 将助记词转换为种子 +const seed = bip39.mnemonicToSeedSync(mnemonic, '可选的密码短语'); +console.log('生成的种子:', seed.toString('hex')); +``` + +### **总结** +HD钱包的助记词系统提供了一种安全、便捷的方式来管理和恢复钱包。助记词通过熵、校验和、PBKDF2算法生成种子,从而衍生出一棵密钥树。理解助记词的原理有助于用户更好地保护自己的数字资产,同时也能帮助开发者实现符合BIP39标准的钱包应用。 \ No newline at end of file