vuke 0.5.0

Research tool for studying vulnerable Bitcoin key generation practices
Documentation
# vuke

Research tool for analyzing and reproducing vulnerable Bitcoin key generation.

## Features

- **Modular architecture** - pluggable sources and transforms
- **Multiple input sources**
  - Numeric ranges (test weak seeds)
  - Wordlists (brainwallet analysis)
  - Timestamps (time-based PRNG exploitation)
  - Stdin streaming (pipeline integration)
- **Historical vulnerability transforms**
  - Direct (raw bytes as key)
  - SHA256 (classic brainwallet)
  - Double SHA256 (Bitcoin-style hashing)
  - MD5 (legacy weak hashing)
  - Milksad (MT19937 PRNG - CVE-2023-39910)
  - Armory (legacy HD derivation)
- **Key origin analysis** - reverse detection of vulnerable generation methods
- **Parallel processing** via Rayon
- **Address matching** for scanning known targets
- **File output** for saving results
- **Pure Rust** implementation

## Why This Project?

This tool is designed for **security research** - understanding how vulnerable keys were generated in the past helps improve modern wallet security.

Historical vulnerabilities this tool can reproduce:

| Vulnerability | Year | Impact |
|--------------|------|--------|
| Brainwallets | 2011-2015 | SHA256(passphrase) easily cracked |
| Weak PRNGs | 2013-2023 | Predictable seeds (timestamps, PIDs) |
| [Milksad]https://milksad.info/ | 2023 | libbitcoin `bx` used MT19937 with 32-bit seeds |
| Armory HD | 2012-2016 | Pre-BIP32 deterministic derivation |
| LCG PRNGs | 1990s-2010s | glibc rand(), MINSTD, MSVC - only 31-32 bit state |

## Installation

### Cargo

```bash
cargo install vuke
```

### From source

```bash
git clone https://github.com/oritwoen/vuke
cd vuke
cargo build --release
```

## Usage

### Generate single key from passphrase

```bash
vuke single "correct horse battery staple" --transform sha256
```

Output:
```
Passphrase: "correct horse battery staple"
Transform: sha256
Source: correct horse battery staple
---
Private Key (hex):     c4bbcb1fbec99d65bf59d85c8cb62ee2db963f0fe106f483d9afa73bd4e39a8a
WIF (compressed):      L3p8oAcQTtuokSCRHQ7i4MhjWc9zornvpJLfmg62sYpLRJF9woSu
---
P2PKH (compressed):   1JwSSubhmg6iPtRjtyqhUYYH7bZg3Lfy1T
P2WPKH:               bc1qfnpg7ceg02y64qrskgz0drwp3y6hma3q6wvnzr
```

### Scan wordlist for known addresses

```bash
vuke scan --transform=sha256 --targets known_addresses.txt wordlist --file passwords.txt
```

### Test numeric range (weak seeds)

```bash
vuke generate --transform=milksad range --start 1 --end 1000000
```

### Test LCG-based keys

```bash
# Generate keys using glibc rand() (default big-endian)
vuke generate --transform=lcg:glibc range --start 1 --end 1000000

# Use MINSTD variant with big-endian byte order
vuke generate --transform=lcg:minstd:be range --start 1 --end 1000

# Test all LCG variants at once
vuke generate --transform=lcg range --start 1 --end 100
```

### Test timestamp-based keys

```bash
vuke scan --transform=sha256 --targets addresses.txt timestamps --start 2015-01-01 --end 2015-01-31
```

### Multiple transforms

```bash
vuke scan --transform=sha256 --transform=double_sha256 --transform=md5 --targets addresses.txt wordlist --file words.txt
```

### Pipe from stdin

```bash
cat passwords.txt | vuke generate --transform=sha256 stdin
```

### Save results to file

```bash
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
```

### Benchmark transforms

```bash
vuke bench --transform milksad
```

### Analyze private key origin

Check if a private key could have been generated by a vulnerable method:

```bash
vuke analyze c4bbcb1fbec99d65bf59d85c8cb62ee2db963f0fe106f483d9afa73bd4e39a8a
```

Output:
```
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)
```

Fast mode (skip brute-force):

```bash
vuke analyze --fast L3p8oAcQTtuokSCRHQ7i4MhjWc9zornvpJLfmg62sYpLRJF9woSu
```

JSON output:

```bash
vuke analyze --fast --json c4bbcb1f...
```

Specific analyzer:

```bash
vuke analyze --analyzer milksad c4bbcb1f...
```

### LCG analyzer

Check if a key was generated using a Linear Congruential Generator:

```bash
# Check all LCG variants
vuke analyze --analyzer lcg <KEY>

# Check specific variant and endianness
vuke analyze --analyzer lcg:glibc:le <KEY>

# With masking for puzzle analysis
vuke analyze --analyzer lcg:glibc --mask 5 0x15
```

### Masked key analysis (BTC1000-style puzzles)

Some Bitcoin puzzles use a masking scheme where:
1. A full 256-bit key is generated (e.g., from MT19937)
2. The key is masked to N bits with highest bit forced to 1

Formula: `masked_key = (full_key & (2^N - 1)) | 2^(N-1)`

```bash
# Analyze 5-bit puzzle key 0x15
vuke analyze 0x15 --mask 5 --analyzer milksad
```

Output:
```
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)
```

```bash
# Analyze 10-bit puzzle key
vuke analyze 0x202 --mask 10 --analyzer milksad
```

### Cascading filter (multi-puzzle verification)

When analyzing masked keys, a single small-bit match has high false positive rates.
The cascading filter verifies candidates against multiple known puzzle keys:

```bash
# Verify seed against multiple puzzles with increasing bit widths
vuke analyze 0x16 --analyzer milksad --cascade "5:0x16,10:0x273,15:0x7a85"
```

Output:
```
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)
```

The cascade format is `bits:target,bits:target,...` where:
- `bits` is the mask width (1-64)
- `target` is hex (with 0x prefix) or decimal

Probability analysis:
- P5 alone: 1/16 chance of false positive
- P5 + P10: 1/16 × 1/512 = 1/8192
- P5 + P10 + P15: virtually impossible false positive

## Supported Transforms

| Transform | Description | Use Case |
|-----------|-------------|----------|
| `direct` | Raw bytes padded to 32 bytes | Testing raw numeric seeds |
| `sha256` | SHA256(input) | Classic brainwallets |
| `double_sha256` | SHA256(SHA256(input)) | Bitcoin-style hashing |
| `md5` | MD5(input) duplicated to 32 bytes | Legacy weak hashing |
| `milksad` | MT19937 PRNG with 32-bit seed | CVE-2023-39910 (libbitcoin) |
| `armory` | Armory HD derivation chain | Pre-BIP32 wallets |
| `lcg[:variant][:endian]` | LCG PRNG with 32-bit seed | Legacy C stdlib rand() |

## Supported Analyzers

| Analyzer | Method | Use Case |
|----------|--------|----------|
| `milksad` | Brute-force 2^32 seeds | Check if key is Milksad victim |
| `milksad --mask N` | Brute-force with N-bit masking | BTC1000-style puzzle analysis |
| `milksad --cascade` | Multi-target sequential verification | Reduce false positives in puzzle research |
| `direct` | Pattern detection | Detect small seeds, ASCII strings |
| `heuristic` | Statistical analysis | Entropy, hamming weight anomalies |
| `lcg[:variant][:endian]` | Brute-force 2^31-2^32 seeds | Detect glibc/minstd/msvc/borland rand() |

## Library Usage

```rust
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);
    }
}
```

## Architecture

```
src/
├── main.rs          # CLI entry point
├── 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
├── lcg.rs           # LCG PRNG shared logic
├── analyze/
│   ├── mod.rs       # Analyzer trait and types
│   ├── key_parser.rs # Parse hex/WIF/decimal keys
│   ├── milksad.rs   # MT19937 brute-force
│   ├── lcg.rs       # LCG brute-force (glibc, minstd, msvc, borland)
│   ├── direct.rs    # Pattern detection
│   ├── heuristic.rs # Statistical analysis
│   └── output.rs    # Plain text and JSON formatting
├── 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
├── 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)
│   ├── lcg.rs       # LCG PRNG transform
│   └── armory.rs    # Armory HD derivation
└── output/
    ├── mod.rs       # Output trait
    └── console.rs   # Console output handler
```

## Requirements

- Rust 1.70+

## Disclaimer

This tool is for **educational and security research purposes only**. Do not use it to access wallets you do not own. The authors are not responsible for any misuse.

## License

MIT License - see [LICENSE](LICENSE) for details.

## References

- [Milksad vulnerability]https://milksad.info/ - CVE-2023-39910
- [Brainwallet attacks]https://eprint.iacr.org/2016/103.pdf - Academic paper
- [Armory documentation]https://btcarmory.com/ - Legacy HD wallet
- [Linear Congruential Generator]https://en.wikipedia.org/wiki/Linear_congruential_generator - Wikipedia