
Herramienta de investigación para estudiar la generación de claves criptográficas vulnerables (brainwallet, PRNG, milksad, LCG, xorshift)
Herramienta de investigación para analizar y reproducir la generación vulnerable de claves de Bitcoin.
Esta herramienta está diseñada para investigación en seguridad: comprender cómo se generaban claves vulnerables en el pasado ayuda a mejorar la seguridad de las carteras modernas.
Vulnerabilidades históricas que esta herramienta puede reproducir:
cargo install vuke
### De la fuente```bash
git clone https://github.com/oritwoen/vuke
cd vuke
cargo build --release
vuke single "correct horse battery staple" --transform sha256
Salida:```
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
### Proveedores de datos
En lugar de rutas de archivo, usa referencias de proveedores para la carga dinámica de objetivos:```bash
# Scan all unsolved b1000 puzzles
vuke scan --transform=milksad --targets boha:b1000:unsolved range --start 1 --end 1000000
# Scan specific collection with filter
vuke scan --transform=sha256 --targets boha:b1000:with-pubkey wordlist --file words.txt
# Available filters: all, unsolved, solved, with-pubkey
vuke scan --targets boha:hash_collision:unsolved wordlist --file words.txt
Sintaxis del proveedor: provider:collection:filter o provider:collection:id
Colecciones disponibles (proveedor boha):
b1000 - Acertijo de Bitcoin 1000 (256 acertijos, 1-256 bits)gsmg - Acertijo GSMGbitaps - Acertijo Bitapshash_collision - Acertijos de colisión de hashzden - Acertijos Zdenbitimage - Acertijos Bitimagevuke generate --transform=milksad range --start 1 --end 1000000
### Prueba 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
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
### Prueba de claves basadas en timestamp```bash
vuke scan --transform=sha256 --targets addresses.txt timestamps --start 2015-01-01 --end 2015-01-31
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/
vuke scan --transform=bitimage --bitimage-passphrase-wordlist passphrases.txt --targets addresses.txt files --dir ./images/
### Múltiples transformaciones```bash
vuke scan --transform=sha256 --transform=double_sha256 --transform=md5 --targets addresses.txt wordlist --file words.txt
cat passwords.txt | vuke generate --transform=sha256 stdin
### Guardar resultados en archivo```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
Almacena resultados en formato Parquet para análisis a escala de TB (requiere la característica storage):```bash
cargo build --release --features storage
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
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
### Consultar resultados almacenados (SQL)
Consulte archivos Parquet almacenados usando SQL (requiere la función `storage-query`):```bash
# Build with query support
cargo build --release --features storage-query
# Count results by transform
vuke query ./results "SELECT transform, COUNT(*) FROM results GROUP BY transform"
# Find matches
vuke query ./results "SELECT * FROM results WHERE matched_target IS NOT NULL LIMIT 10"
# Export to JSON
vuke query ./results --format json "SELECT source, wif_compressed FROM results LIMIT 100"
# Export to CSV
vuke query ./results --format csv "SELECT address_p2pkh_compressed, wif_compressed FROM results" > export.csv
# Show schema
vuke query ./results --schema
Formatos de salida: table (predeterminado), json, csv
Sube resultados Parquet a almacenamiento compatible con S3 (requiere la función storage-cloud):```bash
cargo build --release --features storage-cloud
export AWS_ACCESS_KEY_ID=your_key export AWS_SECRET_ACCESS_KEY=your_secret
vuke generate --storage ./results --cloud-upload --cloud-bucket my-bucket
--transform milksad range --start 1 --end 1000000
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
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
Características de carga en la nube:
- Carga multiparte en streaming (eficiente en memoria para archivos grandes)
- Reintento automático con retroceso exponencial (5 reintentos, 100ms→30s)
- Cargas concurrentes con paralelismo configurable
- Solo elimina archivos locales que se cargaron correctamente
### Registro del catálogo Iceberg
Registra archivos Parquet cargados en un catálogo Apache Iceberg para consultas SQL (requiere la funcionalidad `storage-iceberg`):```bash
# Build with Iceberg support
cargo build --release --features storage-iceberg
# Set credentials
export CLOUD_ACCESS_KEY_ID=your_key
export CLOUD_SECRET_ACCESS_KEY=your_secret
# Generate, upload, and register in Iceberg catalog
vuke generate --storage ./results --cloud-upload --cloud-bucket my-bucket \
--iceberg-catalog http://localhost:8181 \
--transform milksad range --start 1 --end 1000000
# With custom namespace and table name
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
# Using environment variables
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
Características del catálogo Iceberg:
transform (identidad) y timestamp (día)vuke bench --transform milksad
### Analizar el origen de la clave privada
Verificar si una clave privada podría haber sido generada mediante un método vulnerable:```bash
vuke analyze c4bbcb1fbec99d65bf59d85c8cb62ee2db963f0fe106f483d9afa73bd4e39a8a
Analysis: ✗ milksad: NOT_FOUND (checked 4294967296 seeds) ✗ direct: NOT_FOUND (no direct patterns detected) ? heuristic: UNKNOWN (entropy=5.00, hamming=144)
Modo rápido (omitir fuerza bruta):```bash
vuke analyze --fast L3p8oAcQTtuokSCRHQ7i4MhjWc9zornvpJLfmg62sYpLRJF9woSu
Salida JSON:```bash vuke analyze --fast --json c4bbcb1f...
Analizador específico:```bash
vuke analyze --analyzer milksad c4bbcb1f...
Comprueba si una clave fue generada utilizando un Generador Congruencial Lineal:```bash
vuke analyze --analyzer lcg
vuke analyze --analyzer lcg:glibc:le
vuke analyze --analyzer lcg:glibc --mask 5 0x15
### Análisis de claves enmascaradas (BTC1000-style puzzles)
Algunos puzzles de Bitcoin utilizan un esquema de enmascaramiento donde:
1. Se genera una clave completa de 256 bits (por ejemplo, de MT19937)
2. La clave se enmascara a N bits con el bit más alto forzado a 1
Fórmula: `masked_key = (full_key & (2^N - 1)) | 2^(N-1)````bash
# Analyze 5-bit puzzle key 0x15
vuke analyze 0x15 --mask 5 --analyzer milksad
Analysis: ✓ milksad: CONFIRMED (seed=1610000002, full_key=7ed2...5055, masked=0x15, mask_bits=5, formula=(key & 0x1f) | 0x10)
[No content provided in the INPUT section.]```bash
# Analyze 10-bit puzzle key
vuke analyze 0x202 --mask 10 --analyzer milksad
Al analizar claves enmascaradas, una coincidencia de un solo bit pequeño tiene altas tasas de falsos positivos. El filtro en cascada verifica candidatos contra múltiples claves de acertijo conocidas:```bash
vuke analyze 0x16 --analyzer milksad --cascade "5:0x16,10:0x273,15:0x7a85"
Process Builder no es una herramienta de simulación, lo que significa que debes tener cuidado al ejecutarla en un proceso en vivo. La herramienta solo debe ser utilizada por analistas en sistemas que poseen, para los que tienen permiso de prueba, o en capturas de memoria sin conexión.```
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)
El formato de cascada es bits:target,bits:target,... donde:
bits es el ancho de la máscara (1-64)target es hexadecimal (con prefijo 0x) o decimalAnálisis de probabilidad:
Utilice proveedores de datos para configurar automáticamente el análisis de puzzles:```bash
vuke analyze 0x15 --puzzle boha:b1000:5
vuke analyze 0x15 --cascade boha:b1000:5:3 --analyzer milksad
vuke analyze 0x01 --verify boha:b1000
vuke analyze 0x01 --verify boha:b1000 --json
La bandera `--puzzle`:
- Carga el contexto del acertijo desde el proveedor
- Autoestablece `--mask` desde puzzle.key.bits
- Muestra la dirección esperada para verificación
La bandera `--cascade` con proveedor:
- Formato: `boha:collection:puzzle_id:neighbor_count`
- Construye cascada a partir de N acertijos resueltos antes del objetivo
- Valor predeterminado: 5 vecinos si no se especifica el conteo
### Analizador MT19937-64 (semillas de 64 bits)
Para probar hipótesis de semillas de 64 bits, el analizador `mt64` **requiere** filtro de cascada
(el espacio de semillas de 64 bits no es exhaustivamente buscable):```bash
# MT19937-64 cascade search - REQUIRES cascade filter
vuke analyze 0x15 --analyzer mt64 --cascade "5:0x15,10:0x202,20:0xd2c55,30:0x3d94cd64"
Progreso muestra tasa de búsqueda y aciertos del filtro en cascada:``` ⠋ Searched: 1200000 seeds | Rate: 850K/s | Elapsed: 1.4s | Cascade hits: 73
### Analizador Xorshift (semillas de 64 bits)
Los PRNG Xorshift (usados en los motores JavaScript V8/SpiderMonkey) también requieren filtro en cascada debido al espacio de semillas de 64 bits:```bash
# Test all xorshift variants
vuke analyze 0x15 --analyzer xorshift --cascade "5:0x15,10:0x202,20:0xd2c55"
# Test specific variant
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"
Variantes compatibles:
xorshift:64 - Xorshift clásico de estado de 64 bitsxorshift:128 - Xorshift de estado de 128 bits (semilla inicializada como (seed, 0))xorshift:128plus - Xorshift128+ (usado en V8/SpiderMonkey Math.random())xorshift:xoroshiro - Xoroshiro128** (variante moderna)MultiBit HD Beta 7 (2014-2016) tenía un error donde la semilla BIP39 de 64 bytes se pasaba
directamente al constructor DeterministicSeed de BitcoinJ como entropía (se esperaban 16-32 bytes).
Esto creaba claves incompatibles que no pueden recuperarse con herramientas BIP39 estándar.```bash
vuke analyze --analyzer multibit-hd --mnemonic "word1 word2 ... word12"
vuke analyze --analyzer multibit-hd --mnemonic "word1 word2 ..." --passphrase "my passphrase"
vuke analyze --analyzer multibit-hd --mnemonic-file candidates.txt
Generar claves defectuosas a partir de un mnemónico conocido:```bash
vuke single "skin join dog sponsor camera puppy ritual diagram arrow poverty boy elbow" --transform=multibit
Salida (primera clave en m/0'/0/0):``` P2PKH (compressed): 1LQ8XnNKqC7Vu7atH5k4X8qVCc9ug2q7WE
Esto coincide con la dirección errónea del [problema #445 de MultiBit HD](https://github.com/Multibit-Legacy/multibit-hd/issues/445).
La dirección correcta de BIP39 sería `12QxtuyEM8KBG3ngNRe2CZE28hFw3b1KMJ`.
### Claves Electrum pre-BIP39 (2011-2014)
Las billeteras Electrum anteriores a la adopción de BIP39 usaban un esquema de derivación determinística personalizado:
- Semilla hexadecimal de 128 bits estirada mediante 100 000 iteraciones de SHA256
- Claves hijas derivadas como `(master + sequence) mod n`
- Claves públicas sin comprimir para direcciones
Generar claves desde una semilla Electrum antigua:```bash
# Generate receiving chain addresses (first 20 keys)
vuke single "acb740e454c3134901d7c8f16497cc1c" --transform electrum
# Generate change chain addresses
vuke single "acb740e454c3134901d7c8f16497cc1c" --transform electrum:change
Salida (dirección de recepción 0):``` P2PKH (uncompressed): 1FJEEB8ihPMbzs2SkLmr37dHyRFzakqUmo
### SHA256 chain analyzer
Detecta claves generadas usando cadenas SHA256 deterministas (key[n] = SHA256(key[n-1]) or SHA256(seed || n)):```bash
# Check with iterated chain (default): key[n] = SHA256(key[n-1])
vuke analyze <KEY> --analyzer sha256_chain --chain-depth 20
# Check indexed variant: key[n] = SHA256(seed || n as bytes)
vuke analyze <KEY> --analyzer sha256_chain:indexed --chain-depth 20
# With masking for puzzle analysis
vuke analyze 0x15 --mask 5 --analyzer sha256_chain --chain-depth 10
# With cascade filter for reduced false positives
vuke analyze 0x15 --analyzer sha256_chain --cascade "5:0x15,10:0x202" --chain-depth 10
Variantes admitidas:
sha256_chain o sha256_chain:iterated - Derivación en cadena: key[n] = SHA256(key[n-1])sha256_chain:indexed o sha256_chain:indexed:be - Indexado: SHA256(seed || n) con big-endiansha256_chain:indexed:le - Indexado con orden de bytes little-endiansha256_chain:counter - Indexado por cadena: SHA256(seed || "n")Generar claves usando la derivación en cadena SHA256:```bash
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
## Transformaciones admitidas
| Transformación | Descripción | Caso de uso |
|-----------|-------------|----------|
| `direct` | Bytes sin procesar rellenados a 32 bytes | Prueba de semillas numéricas sin procesar |
| `sha256` | SHA256(entrada) | Brainwallets clásicos |
| `double_sha256` | SHA256(SHA256(entrada)) | Hashing estilo Bitcoin |
| `md5` | MD5(entrada) duplicado a 32 bytes | Hashing débil heredado |
| `milksad` | PRNG MT19937 con semilla de 32 bits | CVE-2023-39910 (libbitcoin) |
| `mt64` | PRNG MT19937-64 con semilla de 64 bits | Prueba de hipótesis de semilla de 64 bits |
| `multibit` | Error de semilla como entropía de MultiBit HD | Billeteras MultiBit HD 2014-2016 |
| `armory` | Cadena de derivación HD de Armory | Billeteras pre-BIP32 |
| `electrum` | Derivación pre-BIP39 de Electrum | Billeteras Electrum 2011-2014 |
| `electrum:change` | Cadena de cambio de Electrum | Direcciones de cambio de Electrum 2011-2014 |
| `lcg[:variant][:endian]` | PRNG LCG con semilla de 32 bits | rand() de stdlib C heredado |
| `xorshift[:variant]` | PRNG Xorshift con semilla de 64 bits | Math.random() de V8/SpiderMonkey |
| `sha256_chain[:variant]` | Cadena SHA256 determinista | Derivación de clave iterada/indexada |
| `bitimage` | Archivo→base64→SHA256→BIP39→HD | Derivación de clave del puzzle Bitimage |
## Analizadores compatibles
| Analizador | Método | Caso de uso |
|----------|--------|----------|
| `milksad` | Fuerza bruta de 2^32 semillas | Verificar si la clave es víctima de Milksad |
| `milksad --mask N` | Fuerza bruta con enmascaramiento de N bits | Análisis de puzzle estilo BTC1000 |
| `milksad --cascade` | Verificación secuencial multiobjetivo | Reducir falsos positivos en investigación de puzzles |
| `mt64 --cascade` | Fuerza bruta de 2^64 con filtro en cascada | Hipótesis de PRNG de 64 bits de BTC1000 |
| `multibit-hd --mnemonic` | Probar mnemónico contra la clave | Verificar origen del error de MultiBit HD |
| `multibit-hd --mnemonic-file` | Ataque de diccionario | Encontrar mnemónico para clave MultiBit HD |
| `direct` | Detección de patrones | Detectar semillas pequeñas, cadenas ASCII |
| `heuristic` | Análisis estadístico | Anomalías de entropía, peso de Hamming |
| `lcg[:variant][:endian]` | Fuerza bruta de 2^31-2^32 semillas | Detectar rand() de glibc/minstd/msvc/borland |
| `xorshift[:variant] --cascade` | Fuerza bruta de 2^64 con filtro en cascada | PRNG Xorshift de V8/SpiderMonkey |
| `sha256_chain[:variant]` | Fuerza bruta de 2^32 semillas con profundidad de cadena | Cadenas de clave SHA256 deterministas |
## Uso de la biblioteca```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);
}
}
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
## Requisitos
- Rust 1.70+
## Descargo de responsabilidad
Esta herramienta es solo para **fines educativos y de investigación en seguridad**. No la utilices para acceder a carteras que no te pertenezcan. Los autores no se responsabilizan por ningún uso indebido.
## Licencia
Licencia MIT: consulta [LICENSE](https://github.com/oritwoen/vuke/blob/HEAD/LICENSE) para más detalles.
## Referencias
- [Vulnerabilidad Milksad](https://milksad.info/) - CVE-2023-39910
- [Problema de MultiBit HD #445](https://github.com/Multibit-Legacy/multibit-hd/issues/445) - Error de semilla como entropía
- [Ataques a brainwallets](https://eprint.iacr.org/2016/103.pdf) - Artículo académico
- [Documentación de Armory](https://btcarmory.com/) - Cartera HD heredada
- [Generador de congruencia lineal](https://en.wikipedia.org/wiki/Linear_congruential_generator) - Wikipedia
- [PRNG Xorshift](https://en.wikipedia.org/wiki/Xorshift) - Wikipedia
- [Derivación de claves de Electrum 1.x](https://github.com/spesmilo/electrum/blob/b9196260cfd515363a026c3bfc7bc7aa757965a0/lib/bitcoin.py) - Código fuente pre-BIP39
| Vulnerabilidad | Año | Impacto |
|---|
| Brainwallets | 2011-2015 | SHA256(contraseña) fácilmente descifrable |
| PRNG débiles | 2013-2023 | Semillas predecibles (marcas de tiempo, PIDs) |
| Milksad | 2023 | libbitcoin bx usaba MT19937 con semillas de 32 bits |
| MultiBit HD | 2014-2016 | Semilla BIP39 de 64 bytes usada como entropía |
| Electrum pre-BIP39 | 2011-2014 | Derivación determinista personalizada con estiramiento débil |
| Armory HD | 2012-2016 | Derivación determinista pre-BIP32 |
| PRNG LCG | 1990s-2010s | glibc rand(), MINSTD, MSVC - solo estado de 31-32 bits |
| PRNG Xorshift | 2003-presente | Math.random() en V8/SpiderMonkey - estado de 64-128 bits |
| Cadenas SHA256 | 2010s-presente | Derivación determinista de claves a partir de semillas débiles |