oritwoen/vuke
GitHub: oritwoen/vuke
用于复现和逆向分析比特币历史上各类脆弱密钥生成方式的密码学安全研究工具。
Stars: 11 | Forks: 6
# vuke
[](https://crates.io/crates/vuke)
[](https://crates.io/crates/vuke)
[](LICENSE)
[](https://deepwiki.com/oritwoen/vuke)
用于分析和复现脆弱比特币密钥生成的研究工具。
## 功能
- **模块化架构** - 可插拔的源和转换方式
- **多种输入源**
- 数字范围(测试弱种子)
- 字典(脑钱包分析)
- 时间戳(基于时间的 PRNG 利用)
- Stdin 流式传输(pipeline 集成)
- **历史漏洞转换**
- Direct(原始字节作为密钥)
- SHA256(经典脑钱包)
- Double SHA256(比特币风格哈希)
- MD5(遗留弱哈希)
- SHA256 chain(迭代/索引确定性派生)
- Milksad(MT19937 PRNG - CVE-2023-39910)
- MultiBit HD(seed-as-entropy bug)
- Electrum pre-BIP39(2011-2014 确定性派生)
- Armory(遗留 HD 派生)
- **密钥起源分析** - 逆向检测脆弱的生成方法
- 通过 Rayon 实现**并行处理**
- 用于扫描已知目标的**地址匹配**
- 用于保存结果的**文件输出**
- **云存储** - 异步上传至 S3/R2/MinIO
- **纯 Rust** 实现
## 为什么有这个项目?
本工具专为**安全研究**而设计 - 了解过去脆弱密钥的生成方式有助于改进现代钱包的安全性。
本工具可以复现的历史漏洞:
| 漏洞 | 年份 | 影响 |
|--------------|------|--------|
| 脑钱包 | 2011-2015 | SHA256(passphrase) 容易被破解 |
| 弱 PRNG | 2013-2023 | 可预测的种子(时间戳、PID) |
| [Milksad](https://milksad.info/) | 2023 | libbitcoin `bx` 使用带有 32 位种子的 MT19937 |
| [MultiBit HD](https://github.com/Multibit-Legacy/multibit-hd/issues/445) | 2014-2016 | 64 字节 BIP39 种子被用作熵 |
| Electrum pre-BIP39 | 2011-2014 | 带有弱扩展的自定义确定性派生 |
| Armory HD | 2012-2016 | BIP32 之前的确定性派生 |
| LCG PRNGs | 1990s-2010s | glibc rand(), MINSTD, MSVC - 仅 31-32 位状态 |
| Xorshift PRNGs | 2003-至今 | V8/SpiderMonkey Math.random() - 64-128 位状态 |
| SHA256 chains | 2010s-至今 | 基于弱种子的确定性密钥派生 |
## 安装
### Cargo
```
cargo install vuke
```
### 从源码构建
```
git clone https://github.com/oritwoen/vuke
cd vuke
cargo build --release
```
## 用法
### 从密码短语生成单个密钥
```
vuke single "correct horse battery staple" --transform sha256
```
输出:
```
Passphrase: "correct horse battery staple"
Transform: sha256
Source: correct horse battery staple
---
Private Key (hex): c4bbcb1fbec99d65bf59d85c8cb62ee2db963f0fe106f483d9afa73bd4e39a8a
WIF (compressed): L3p8oAcQTtuokSCRHQ7i4MhjWc9zornvpJLfmg62sYpLRJF9woSu
---
P2PKH (compressed): 1JwSSubhmg6iPtRjtyqhUYYH7bZg3Lfy1T
P2WPKH: bc1qfnpg7ceg02y64qrskgz0drwp3y6hma3q6wvnzr
```
### 扫描字典以查找已知地址
```
vuke scan --transform=sha256 --targets known_addresses.txt wordlist --file passwords.txt
```
### 数据提供者
使用提供者引用代替文件路径,以实现动态目标加载:
```
# 扫描所有未解决的 b1000 谜题
vuke scan --transform=milksad --targets boha:b1000:unsolved range --start 1 --end 1000000
# 使用过滤器扫描特定集合
vuke scan --transform=sha256 --targets boha:b1000:with-pubkey wordlist --file words.txt
# 可用过滤器:all, unsolved, solved, with-pubkey
vuke scan --targets boha:hash_collision:unsolved wordlist --file words.txt
```
提供者语法:`provider:collection:filter` 或 `provider:collection:id`
可用集合(boha 提供者):
- `b1000` - Bitcoin puzzle 1000(256 个谜题,1-256 位)
- `gsmg` - GSMG puzzle
- `bitaps` - Bitaps puzzle
- `hash_collision` - Hash collision puzzles
- `zden` - Zden puzzles
- `bitimage` - Bitimage puzzles
### 测试数字范围(弱种子)
```
vuke generate --transform=milksad range --start 1 --end 1000000
```
### 测试基于 LCG 的密钥
```
# 使用 glibc rand() 生成密钥(默认 big-endian)
vuke generate --transform=lcg:glibc range --start 1 --end 1000000
# 使用 MINSTD 变体和 big-endian 字节序
vuke generate --transform=lcg:minstd:be range --start 1 --end 1000
# 一次测试所有 LCG 变体
vuke generate --transform=lcg range --start 1 --end 100
```
### 测试基于 xorshift 的密钥
```
# 使用所有 xorshift 变体生成密钥(分析需要 cascade 过滤器)
vuke generate --transform=xorshift range --start 1 --end 1000000
# 使用特定变体
vuke generate --transform=xorshift:64 range --start 1 --end 1000
vuke generate --transform=xorshift:128 range --start 1 --end 1000
vuke generate --transform=xorshift:128plus range --start 1 --end 1000
vuke generate --transform=xorshift:xoroshiro range --start 1 --end 1000
```
### 测试基于时间戳的密钥
```
vuke scan --transform=sha256 --targets addresses.txt timestamps --start 2015-01-01 --end 2015-01-31
```
### 从文件派生密钥 (Bitimage)
```
# 从单个文件生成密钥
vuke generate --transform=bitimage files --file image.jpg
# 递归扫描目录
vuke generate --transform=bitimage files --dir ./images/
# 使用自定义派生路径和密码
vuke generate --transform=bitimage --bitimage-path "m/44'/0'/0'/0/0" --bitimage-passphrase "secret" files --file photo.png
# 每个文件派生多个地址
vuke generate --transform=bitimage --bitimage-derive-count 10 files --dir ./data/
# 从 wordlist 暴力破解密码
vuke scan --transform=bitimage --bitimage-passphrase-wordlist passphrases.txt --targets addresses.txt files --dir ./images/
```
### 多重转换
```
vuke scan --transform=sha256 --transform=double_sha256 --transform=md5 --targets addresses.txt wordlist --file words.txt
```
### 从 stdin 管道输入
```
cat passwords.txt | vuke generate --transform=sha256 stdin
```
### 将结果保存到文件
```
vuke generate --output results.csv range --start 1 --end 1000000
vuke generate --output results.txt --verbose range --start 1 --end 1000
vuke scan --output hits.txt --targets addresses.txt wordlist --file passwords.txt
```
### 持久化存储 (Parquet)
以 Parquet 格式存储结果,用于 TB 级分析(需要 `storage` feature):
```
# 使用存储支持构建
cargo build --release --features storage
# 将生成的密钥存储到 Parquet
vuke generate --storage ./results --transform milksad range --start 1 --end 1000000
# 配置分块轮换
vuke generate --storage ./results --chunk-records 500000 --chunk-bytes 50M range --start 1 --end 10000000
# 配置压缩(默认:zstd 级别 3)
vuke generate --storage ./results --compression zstd --compression-level 9 range --start 1 --end 1000000
# 无压缩(最快写入)
vuke generate --storage ./results --compression none range --start 1 --end 1000000
# 可用算法:none, snappy, gzip, lz4, zstd
```
### 查询存储的结果 (SQL)
使用 SQL 查询存储的 Parquet 文件(需要 `storage-query` feature):
```
# 使用查询支持构建
cargo build --release --features storage-query
# 按转换统计结果
vuke query ./results "SELECT transform, COUNT(*) FROM results GROUP BY transform"
# 查找匹配项
vuke query ./results "SELECT * FROM results WHERE matched_target IS NOT NULL LIMIT 10"
# 导出到 JSON
vuke query ./results --format json "SELECT source, wif_compressed FROM results LIMIT 100"
# 导出到 CSV
vuke query ./results --format csv "SELECT address_p2pkh_compressed, wif_compressed FROM results" > export.csv
# 显示 schema
vuke query ./results --schema
```
输出格式:`table`(默认)、`json`、`csv`
### 云端上传 (S3 兼容)
将 Parquet 结果上传至兼容 S3 的存储(需要 `storage-cloud` feature):
```
# 使用云上传支持构建
cargo build --release --features storage-cloud
# 设置凭证(AWS S3)
export AWS_ACCESS_KEY_ID=your_key
export AWS_SECRET_ACCESS_KEY=your_secret
# 上传到 AWS S3
vuke generate --storage ./results --cloud-upload --cloud-bucket my-bucket \
--transform milksad range --start 1 --end 1000000
# 上传到 Cloudflare R2
vuke generate --storage ./results --cloud-upload \
--cloud-endpoint https://account.r2.cloudflarestorage.com \
--cloud-bucket my-r2-bucket \
--transform milksad range --start 1 --end 1000000
# 上传到 MinIO(自托管)
vuke generate --storage ./results --cloud-upload \
--cloud-endpoint http://localhost:9000 \
--cloud-bucket vuke-results \
--transform milksad range --start 1 --end 1000000
# 成功上传后删除本地文件
vuke generate --storage ./results --cloud-upload --cloud-bucket my-bucket \
--cloud-delete-local \
--transform milksad range --start 1 --end 1000000
# 上传出错时快速失败(默认:失败后继续)
vuke generate --storage ./results --cloud-upload --cloud-bucket my-bucket \
--cloud-fail-fast \
--transform milksad range --start 1 --end 1000000
```
云端上传特性:
- 流式分段上传(对大文件具有内存效率)
- 带有指数退避的自动重试(5 次重试,100ms→30s)
- 具有可配置并行度的并发上传
- 仅删除成功上传的本地文件
### Iceberg catalog 注册
将上传的 Parquet 文件注册到 Apache Iceberg catalog 中,以进行 SQL 查询(需要 `storage-iceberg` feature):
```
# 使用 Iceberg 支持构建
cargo build --release --features storage-iceberg
# 设置凭证
export CLOUD_ACCESS_KEY_ID=your_key
export CLOUD_SECRET_ACCESS_KEY=your_secret
# 在 Iceberg catalog 中生成、上传并注册
vuke generate --storage ./results --cloud-upload --cloud-bucket my-bucket \
--iceberg-catalog http://localhost:8181 \
--transform milksad range --start 1 --end 1000000
# 使用自定义命名空间和表名
vuke generate --storage ./results --cloud-upload --cloud-bucket my-bucket \
--iceberg-catalog http://localhost:8181 \
--iceberg-namespace my_namespace \
--iceberg-table my_results \
--transform milksad range --start 1 --end 1000000
# 使用环境变量
export ICEBERG_CATALOG=http://localhost:8181
export ICEBERG_NAMESPACE=vuke
export ICEBERG_TABLE=results
vuke generate --storage ./results --cloud-upload --cloud-bucket my-bucket \
--transform milksad range --start 1 --end 1000000
```
Iceberg catalog 特性:
- REST catalog 协议(兼容 Apache Polaris、Nessie、Tabular 等)
- 根据 schema 和分区规则自动建表
- 按 `transform`(恒等分区)和 `timestamp`(按天分区)进行分区
- 凭证与云上传共享(CLOUD_*/AWS_* 环境变量)
### 基准测试转换
```
vuke bench --transform milksad
```
### 分析私钥起源
检查一个私钥是否由某种脆弱的方法生成:
```
vuke analyze c4bbcb1fbec99d65bf59d85c8cb62ee2db963f0fe106f483d9afa73bd4e39a8a
```
输出:
```
Private Key: c4bbcb1fbec99d65bf59d85c8cb62ee2db963f0fe106f483d9afa73bd4e39a8a
Bit Length: 256
Hamming Weight: 144
---
Analysis:
✗ milksad: NOT_FOUND (checked 4294967296 seeds)
✗ direct: NOT_FOUND (no direct patterns detected)
? heuristic: UNKNOWN (entropy=5.00, hamming=144)
```
快速模式(跳过暴力破解):
```
vuke analyze --fast L3p8oAcQTtuokSCRHQ7i4MhjWc9zornvpJLfmg62sYpLRJF9woSu
```
JSON 输出:
```
vuke analyze --fast --json c4bbcb1f...
```
特定分析器:
```
vuke analyze --analyzer milksad c4bbcb1f...
```
### LCG 分析器
检查密钥是否由线性同余生成器生成:
```
# 检查所有 LCG 变体
vuke analyze --analyzer lcg
# 检查特定变体和字节序
vuke analyze --analyzer lcg:glibc:le
# 使用掩码进行谜题分析
vuke analyze --analyzer lcg:glibc --mask 5 0x15
```
### 掩码密钥分析 (BTC1000 风格谜题)
一些比特币谜题使用了一种掩码方案,其中:
1. 生成一个完整的 256 位密钥(例如,来自 MT19937)
2. 将密钥掩码为 N 位,并将最高位置为 1
公式:`masked_key = (full_key & (2^N - 1)) | 2^(N-1)`
```
# 分析 5位 谜题密钥 0x15
vuke analyze 0x15 --mask 5 --analyzer milksad
```
输出:
```
Private Key: 0000000000000000000000000000000000000000000000000000000000000015
Bit Length: 5
Hamming Weight: 3
---
Analysis:
✓ milksad: CONFIRMED (seed=1610000002, full_key=7ed2...5055, masked=0x15, mask_bits=5, formula=(key & 0x1f) | 0x10)
```
```
# 分析 10位 谜题密钥
vuke analyze 0x202 --mask 10 --analyzer milksad
```
### 级联过滤器(多重谜题验证)
在分析掩码密钥时,单个小位数的匹配具有很高的误报率。
级联过滤器会针对多个已知谜题密钥验证候选者:
```
# 对照多个位宽递增的谜题验证种子
vuke analyze 0x16 --analyzer milksad --cascade "5:0x16,10:0x273,15:0x7a85"
```
输出:
```
Private Key: 0000000000000000000000000000000000000000000000000000000000000016
Bit Length: 5
Hamming Weight: 3
---
Analysis:
✓ milksad: CONFIRMED (seed=100 (0x00000064))
P5: target=0x16, full_key=08961c8b18dbd0ab4337434767df7b69572fad6c4f00c186b03f43d88af70a26
P10: target=0x273, full_key=5e413501b4371e2862271f1f3550bc2f4236b6abe29ec9350e166bd322c3e673
P15: target=0x7a85, full_key=f133ff22f0aac1de185139938f664d10e4ac2de46be7d29f3c458e353a1efa85)
```
级联格式为 `bits:target,bits:target,...`,其中:
- `bits` 是掩码宽度 (1-64)
- `target` 是十六进制(带 0x 前缀)或十进制
概率分析:
- 仅 P5:1/16 的误报概率
- P5 + P10:1/16 × 1/512 = 1/8192
- P5 + P10 + P15:误报几乎不可能
### 基于提供者的分析
使用数据提供者自动配置谜题分析:
```
# 根据谜题位数自动设置掩码(谜题 #5 = 5 位)
vuke analyze 0x15 --puzzle boha:b1000:5
# 根据已解决的相邻谜题构建 cascade(谜题 #5 之前的 3 个谜题)
vuke analyze 0x15 --cascade boha:b1000:5:3 --analyzer milksad
# 针对整个集合验证密钥
vuke analyze 0x01 --verify boha:b1000
# 用于脚本的 JSON 输出
vuke analyze 0x01 --verify boha:b1000 --json
```
`--puzzle` 标志:
- 从提供者加载谜题上下文
- 从 puzzle.key.bits 自动设置 `--mask`
- 显示预期地址以供验证
带有提供者的 `--cascade`:
- 格式:`boha:collection:puzzle_id:neighbor_count`
- 从目标之前的 N 个已解谜题构建级联
- 默认:如果未指定数量,则为 5 个邻居
### MT19937-64 分析器(64 位种子)
为了测试 64 位种子假设,`mt64` 分析器**要求**使用级联过滤器
(64 位种子空间无法进行穷举搜索):
```
# MT19937-64 cascade 搜索 - 需要 cascade 过滤器
vuke analyze 0x15 --analyzer mt64 --cascade "5:0x15,10:0x202,20:0xd2c55,30:0x3d94cd64"
```
进度显示搜索速率和级联过滤器命中数:
```
⠋ Searched: 1200000 seeds | Rate: 850K/s | Elapsed: 1.4s | Cascade hits: 73
```
### Xorshift 分析器(64 位种子)
由于 64 位种子空间的限制,Xorshift PRNG(用于 V8/SpiderMonkey JavaScript 引擎)同样需要级联过滤器:
```
# 测试所有 xorshift 变体
vuke analyze 0x15 --analyzer xorshift --cascade "5:0x15,10:0x202,20:0xd2c55"
# 测试特定变体
vuke analyze 0x15 --analyzer xorshift:64 --cascade "5:0x15,10:0x202,20:0xd2c55"
vuke analyze 0x15 --analyzer xorshift:128plus --cascade "5:0x15,10:0x202,20:0xd2c55"
```
支持的变体:
- `xorshift:64` - 经典 64 位状态 xorshift
- `xorshift:128` - 128 位状态 xorshift(种子初始化为 `(seed, 0)`)
- `xorshift:128plus` - Xorshift128+(用于 V8/SpiderMonkey Math.random())
- `xorshift:xoroshiro` - Xoroshiro128**(现代变体)
### MultiBit HD 分析器(seed-as-entropy bug)
MultiBit HD Beta 7 (2014-2016) 存在一个 bug,即将 64 字节的 BIP39 种子直接
传递给 BitcoinJ 的 `DeterministicSeed` 构造函数作为熵(预期为 16-32 字节)。
这产生了不兼容的密钥,无法使用标准的 BIP39 工具恢复。
```
# 检查密钥是否由 MultiBit HD 漏洞生成
vuke analyze --analyzer multibit-hd --mnemonic "word1 word2 ... word12"
# 使用特定密码进行测试
vuke analyze --analyzer multibit-hd --mnemonic "word1 word2 ..." --passphrase "my passphrase"
# 使用 mnemonic 文件进行字典攻击
vuke analyze --analyzer multibit-hd --mnemonic-file candidates.txt
```
从已知的助记词生成带有 bug 的密钥:
```
vuke single "skin join dog sponsor camera puppy ritual diagram arrow poverty boy elbow" --transform=multibit
```
输出(位于 m/0'/0/0 的第一个密钥):
```
P2PKH (compressed): 1LQ8XnNKqC7Vu7atH5k4X8qVCc9ug2q7WE
```
这与 [MultiBit HD issue #445](https://github.com/Multibit-Legacy/multibit-hd/issues/445) 中的有 bug 的地址匹配。
正确的 BIP39 地址应为 `12QxtuyEM8KBG3ngNRe2CZE28hFw3b1KMJ`。
### Electrum pre-BIP39 密钥(2011-2014)
采用 BIP39 之前的 Electrum 钱包使用自定义的确定性派生方案:
- 128 位十六进制种子通过 100,000 次 SHA256 迭代进行扩展
- 子密钥派生为 `(master + sequence) mod n`
- 使用未压缩的公钥生成地址
从旧的 Electrum 种子生成密钥:
```
# 生成接收链地址(前 20 个密钥)
vuke single "acb740e454c3134901d7c8f16497cc1c" --transform electrum
# 生成找零链地址
vuke single "acb740e454c3134901d7c8f16497cc1c" --transform electrum:change
```
输出(接收地址 0):
```
P2PKH (uncompressed): 1FJEEB8ihPMbzs2SkLmr37dHyRFzakqUmo
```
### SHA256 chain 分析器
检测使用确定性 SHA256 链生成的密钥(key[n] = SHA256(key[n-1]) 或 SHA256(seed || n)):
```
# 使用迭代链进行检查(默认):key[n] = SHA256(key[n-1])
vuke analyze --analyzer sha256_chain --chain-depth 20
# 检查索引变体:key[n] = SHA256(seed || n as bytes)
vuke analyze --analyzer sha256_chain:indexed --chain-depth 20
# 使用掩码进行谜题分析
vuke analyze 0x15 --mask 5 --analyzer sha256_chain --chain-depth 10
# 使用 cascade 过滤器以减少误报
vuke analyze 0x15 --analyzer sha256_chain --cascade "5:0x15,10:0x202" --chain-depth 10
```
支持的变体:
- `sha256_chain` 或 `sha256_chain:iterated` - 链式派生:key[n] = SHA256(key[n-1])
- `sha256_chain:indexed` 或 `sha256_chain:indexed:be` - 索引派生:大端序的 SHA256(seed || n)
- `sha256_chain:indexed:le` - 小端序字节顺序的索引派生
- `sha256_chain:counter` - 字符串索引:SHA256(seed || "n")
### SHA256 chain 转换
使用 SHA256 链派生生成密钥:
```
# 从数字种子生成迭代链密钥
vuke generate --transform=sha256_chain range --start 1 --end 1000
# 使用计数器字符串生成索引链
vuke generate --transform=sha256_chain:counter --chain-depth 5 wordlist --file seeds.txt
# 使用特定链深度生成
vuke generate --transform=sha256_chain:iterated --chain-depth 10 range --start 1 --end 100
```
## 支持的转换
| 转换 | 描述 | 用例 |
|-----------|-------------|----------|
| `direct` | 填充至 32 字节的原始字节 | 测试原始数字种子 |
| `sha256` | SHA256(input) | 经典脑钱包 |
| `double_sha256` | SHA256(SHA256(input)) | 比特币风格哈希 |
| `md5` | 复制 MD5(input) 至 32 字节 | 遗留弱哈希 |
| `milksad` | 带有 32 位种子的 MT19937 PRNG | CVE-2023-39910 (libbitcoin) |
| `mt64` | 带有 64 位种子的 MT19937-64 PRNG | 64 位种子假设测试 |
| `multibit` | MultiBit HD seed-as-entropy bug | 2014-2016 MultiBit HD 钱包 |
| `armory` | Armory HD 派生链 | BIP32 之前的钱包 |
| `electrum` | Electrum pre-BIP39 派生 | 2011-2014 Electrum 钱包 |
| `electrum:change` | Electrum 找零链 | 2011-2014 Electrum 找零地址 |
| `lcg[:variant][:endian]` | 带有 32 位种子的 LCG PRNG | 遗留 C 标准库 rand() |
| `xorshift[:variant]` | 带有 64 位种子的 Xorshift PRNG | V8/SpiderMonkey Math.random() |
| `sha256_chain[:variant]` | 确定性 SHA256 链 | 迭代/索引密钥派生 |
| `bitimage` | 文件→base64→SHA256→BIP39→HD | Bitimage 谜题密钥派生 |
## 支持的分析器
| 分析器 | 方法 | 用例 |
|----------|--------|----------|
| `milksad` | 暴力破解 2^32 个种子 | 检查密钥是否为 Milksad 受害者 |
| `milksad --mask N | 带有 N 位掩码的暴力破解 | BTC1000 风格的谜题分析 |
| `milksad --cascade` | 多目标顺序验证 | 减少谜题研究中的误报 |
| `mt64 --cascade` | 带有级联过滤器的暴力破解 2^64 | BTC1000 64 位 PRNG 假设 |
| `multibit-hd --mnemonic` | 针对密钥测试助记词 | 验证 MultiBit HD bug 来源 |
| `multibit-hd --mnemonic-file` | 字典攻击 | 查找 MultiBit HD 密钥的助记词 |
| `direct` | 模式检测 | 检测小种子、ASCII 字符串 |
| `heuristic` | 统计分析 | 熵、汉明重量异常 |
| `lcg[:variant][:endian]` | 暴力破解 2^31-2^32 个种子 | 检测 glibc/minstd/msvc/borland rand() |
| `xorshift[:variant] --cascade` | 带有级联过滤器的暴力破解 2^64 | V8/SpiderMonkey xorshift PRNG |
| `sha256_chain[:variant]` | 带有链深度的暴力破解 2^32 个种子 | 确定性 SHA256 密钥链 |
## 库用法
```
use vuke::derive::KeyDeriver;
use vuke::transform::{Input, Transform, Sha256Transform};
fn main() {
let deriver = KeyDeriver::new();
let transform = Sha256Transform;
let input = Input::from_string("test passphrase".to_string());
let mut buffer = Vec::new();
transform.apply_batch(&[input], &mut buffer);
for (source, key) in buffer {
let derived = deriver.derive(&key);
println!("Source: {}", source);
println!("WIF: {}", derived.wif_compressed);
println!("Address: {}", derived.p2pkh_compressed);
}
}
```
## 架构
```
src/
├── main.rs # CLI entry point (clap derive)
├── lib.rs # Library exports
├── derive.rs # Private key → address derivation
├── matcher.rs # Address matching against targets
├── network.rs # Bitcoin network handling
├── benchmark.rs # Performance testing
├── provider.rs # Data provider system (boha puzzles)
├── lcg.rs # LCG PRNG shared logic
├── xorshift.rs # Xorshift PRNG shared logic
├── mt64.rs # MT19937-64 PRNG shared logic
├── multibit.rs # MultiBit HD bug logic (PBKDF2, BIP32)
├── electrum.rs # Electrum pre-BIP39 deterministic derivation
├── sha256_chain.rs # SHA256 chain shared logic (iterated/indexed)
├── bitimage.rs # Bitimage puzzle derivation logic
├── analyze/
│ ├── mod.rs # Analyzer trait and types
│ ├── key_parser.rs # Parse hex/WIF/decimal keys
│ ├── output.rs # Plain text and JSON formatting
│ ├── milksad.rs # MT19937 brute-force (GPU accelerated)
│ ├── mt64.rs # MT19937-64 brute-force (requires cascade)
│ ├── multibit.rs # MultiBit HD mnemonic verification
│ ├── lcg.rs # LCG brute-force (glibc, minstd, msvc, borland)
│ ├── xorshift.rs # Xorshift brute-force (requires cascade)
│ ├── sha256_chain.rs # SHA256 chain brute-force (GPU accelerated)
│ ├── direct.rs # Pattern detection
│ └── heuristic.rs # Statistical analysis
├── source/
│ ├── mod.rs # Source trait and types
│ ├── range.rs # Numeric range source
│ ├── wordlist.rs # File-based wordlist
│ ├── timestamps.rs # Date range → Unix timestamps
│ ├── stdin.rs # Streaming from stdin
│ └── files.rs # File/directory source for binary data
├── output/
│ ├── mod.rs # Output trait
│ ├── console.rs # Console output (compact CSV + verbose YAML)
│ ├── multi.rs # Multi-output dispatcher
│ ├── storage.rs # Parquet backend bridge (feature: storage)
│ └── query_format.rs # DuckDB result formatting (feature: storage-query)
├── transform/
│ ├── mod.rs # Transform trait and types
│ ├── input.rs # Input value representation
│ ├── direct.rs # Raw bytes transform
│ ├── sha256.rs # SHA256 hashing
│ ├── double_sha256.rs # Double SHA256
│ ├── md5.rs # MD5 hashing
│ ├── milksad.rs # MT19937 PRNG (CVE-2023-39910)
│ ├── mt64.rs # MT19937-64 PRNG transform
│ ├── multibit.rs # MultiBit HD seed-as-entropy bug
│ ├── electrum.rs # Electrum pre-BIP39 deterministic derivation
│ ├── lcg.rs # LCG PRNG transform
│ ├── xorshift.rs # Xorshift PRNG transform
│ ├── sha256_chain.rs # SHA256 chain transform
│ ├── bitimage.rs # File-derived HD keys (Bitimage puzzle)
│ └── armory.rs # Armory HD derivation
├── gpu/ # WebGPU acceleration (feature: gpu)
│ ├── mod.rs # Module exports
│ ├── context.rs # GPU device initialization
│ ├── error.rs # GPU error types
│ ├── buffer.rs # GPU buffer utilities
│ ├── hash.rs # SHA256/MD5 hash pipelines
│ ├── mt19937.rs # MT19937 brute-force pipeline
│ ├── sha256_chain.rs # SHA256 chain pipeline
│ └── shaders/ # WGSL compute shaders
│ ├── mt19937.wgsl
│ ├── sha256.wgsl
│ └── md5.wgsl
└── storage/ # Persistent storage (feature: storage)
├── mod.rs # StorageBackend trait
├── schema.rs # Arrow schema definitions
├── parquet_backend.rs # Parquet file writer with auto-chunking
├── query.rs # DuckDB SQL executor (feature: storage-query)
├── cloud/ # S3-compatible upload (feature: storage-cloud)
│ ├── mod.rs # CloudUploader trait
│ ├── s3.rs # S3/R2/MinIO implementation
│ ├── credentials.rs # Credential resolution
│ ├── sync.rs # Batch upload with concurrency
│ ├── progress.rs # Upload progress tracking
│ └── error.rs # Cloud error types
└── iceberg/ # Iceberg catalog (feature: storage-iceberg)
├── mod.rs # Iceberg integration entry
├── catalog.rs # REST catalog client
├── schema.rs # Iceberg schema mapping
├── partition.rs # Partition spec
└── error.rs # Iceberg error types
```
## 环境要求
- Rust 1.70+
## 免责声明
本工具仅供**教育和安全研究目的**使用。请勿使用它访问非本人所有的钱包。作者不对任何滥用行为负责。
## 许可证
MIT License - 详见 [LICENSE](LICENSE)。
## 参考文献
- [Milksad 漏洞](https://milksad.info/) - CVE-2023-39910
- [MultiBit HD issue #445](https://github.com/Multibit-Legacy/multibit-hd/issues/445) - Seed-as-entropy bug
- [脑钱包攻击](https://eprint.iacr.org/2016/103.pdf) - 学术论文
- [Armory 文档](https://btcarmory.com/) - 遗留 HD 钱包
- [线性同余生成器](https://en.wikipedia.org/wiki/Linear_congruential_generator) - 维基百科
- [Xorshift PRNGs](https://en.wikipedia.org/wiki/Xorshift) - 维基百科
- [Electrum 1.x 密钥派生](https://github.com/spesmilo/electrum/blob/b9196260cfd515363a026c3bfc7bc7aa757965a0/lib/bitcoin.py) - Pre-BIP39 源代码
标签:Armory, CVE-2023-39910, Electrum, LCG, MD5, Milksad, MT19937, PRNG, Rayon, Rust, S3, SHA256, xorshift, 云存储, 云资产清单, 伪随机数生成器, 加密货币, 区块链安全, 可视化界面, 哈希碰撞, 多比特, 密钥生成, 并行计算, 弱密钥, 恶意软件检测, 梅森旋转算法, 比特币, 漏洞分析, 漏洞探索, 确定性推导, 纯Rust实现, 网络安全, 网络流量审计, 脑钱包, 路径探测, 逆向工程, 通知系统, 隐私保护