π RingSide Replay Attack:
Recovering $61,025 from Compromised Bitcoin Wallet
Comprehensive Cryptanalysis of CVE-2023-39910 "Milk Sad" Vulnerability
π° Recovered Funds: $61,025 USD
Address: 1NiojfedphT6MgMD7UsowNdQmx5JY15djG
Research by: CryptoDeepTech | KEYHUNTERS
π Executive Summary
This research paper presents a detailed cryptanalysis of a critical vulnerability in Bitcoin wallet generation,
designated CVE-2023-39910 and codenamed "Milk Sad".
The vulnerability was discovered in the popular Libbitcoin Explorer utility
(versions 3.0.0β3.6.0), which is used to create and manage Bitcoin wallets offline.
The underlying flaw lies in the use of a cryptographically insecure Mersenne Twister-32
(MT19937) pseudorandom number generator, initialized using the system time, which limits the entropy space
to only 32 bits. This catastrophic weakness reduced the theoretical 256-bit security
of Bitcoin private keys to a mere 4.3 billion possible values, making brute force attacks feasible on modern hardware.
π― Key Findings
Vulnerability Impact: Over 227,200 unique Bitcoin addresses compromised
Total Theft: Over $900,000 USD stolen across multiple blockchains
Attack Complexity: LOW - Entire 2Β³Β² keyspace searchable in seconds to minutes
Case Study Recovery: $61,025 USD from address 1NiojfedphT6MgMD7UsowNdQmx5JY15djG
The following case study demonstrates the practical application of the RingSide Replay Attack methodology
to recover a private key from a compromised Bitcoin wallet. This address was created using a vulnerable
version of Libbitcoin Explorer and subsequently had its funds recovered through cryptanalytic techniques.
The recovered private key must satisfy the constraint for secp256k1:
1 β€ k < n
where n = 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141
β 1.158 Γ 10β·β·
β VALID - The recovered key is within the allowed scalar range for secp256k1
Recovery Methodology
The recovery process exploited the weak entropy generation in Libbitcoin Explorer 3.x. By systematically
searching through the limited 2Β³Β² seed space and reconstructing the deterministic key generation process,
the private key was successfully recovered, granting complete control over the wallet and its $61,025 balance.
π¬ Mathematical Formulas Used by BTCDetect Application
ECDSA on secp256k1 Elliptic Curve
Bitcoin utilizes the secp256k1 elliptic curve for its public-key cryptography. The curve is defined by
the Weierstrass equation:
yΒ² = xΒ³ + 7 (mod p)
where the prime field modulus is: p = 2Β²β΅βΆ - 2Β³Β² - 2βΉ - 2βΈ - 2β· - 2βΆ - 2β΄ - 1
The order of the cyclic subgroup used in Bitcoin is:
n = FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFE BAAEDCE6 AF48A03B BFD25E8C D0364141ββ
This represents approximately 2Β²β΅βΆ possible private keys.
Public Key Derivation
In ECDSA, the public key P is derived from the private key d through elliptic curve point multiplication:
P = d Γ G
where:
β’ d = private key (scalar in range [1, n-1])
β’ G = generator point on secp256k1
β’ P = public key (point on curve)
The security of this system relies on the computational infeasibility of solving the elliptic curve discrete
logarithm problem (ECDLP) β recovering d given only P and G.
The Milk Sad Vulnerability: Entropy Reduction
The Milk Sad vulnerability stems from Libbitcoin Explorer's use of MT19937 PRNG initialized with
timestamp-based entropy:
seed = timestamp mod 2Β³Β²
The entropy generation process in vulnerable versions follows this pseudocode:
The resulting P2PKH addresses start with "1" on Bitcoin mainnet.
WIF (Wallet Import Format) Conversion
The Wallet Import Format provides a more user-friendly representation of private keys:
Conversion algorithm (HEX to WIF):
1. private_key_hex: 4ACBB2E3CE1EE22224219B71E3B72BF6C8F2C9AA1D992666DBD8B48AA826FF6B
2. Add mainnet version byte: 804ACBB2E3CE1EE22224219B71E3B72BF6C8F2C9AA1D992666DBD8B48AA826FF6B
3. Add compression flag: 804ACBB2E3CE1EE22224219B71E3B72BF6C8F2C9AA1D992666DBD8B48AA826FF6B01
4. Double SHA-256 for checksum
5. Base58 encode
6. Result (WIF): Kyj6yvb4oHHDGBW23C8Chzji3zdYQ5QMr8r9zWpGVHdvWuYqCGVU
Compressed WIF keys start with "K" or "L" on mainnet, while uncompressed keys start with "5".
βοΈ BTCDetect Application: Process Workflow
BTCDetect is a specialized cryptanalytic tool designed to recover lost
Bitcoin wallets by identifying and exploiting vulnerabilities in cryptographic libraries such as
Libbitcoin's SharpECC implementation. The application automates the RingSide Replay Attack methodology
through a systematic 11-step process.
ECDSA on secp256k1
Elliptic Curve Equation: yΒ² = xΒ³ + 7 (mod p)
Order of curve subgroup: n = FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141
π― STEP 3: Private Key Generation Analysis
Libbitcoin Explorer vulnerability:
seed = MT19937(timestamp_32bit)
entropy_effective = 32 bits (instead of 256 bits)
For wallet created at timestamp t:
MT19937.seed(t mod 2Β³Β²)
Generate pseudo-random bytes β BIP39 mnemonic β Private Key
βοΈ STEP 4: Brute Force Attack Algorithm
For each timestamp t in range [t_min, t_max]:
1. Initialize MT19937 with seed = t
2. Generate entropy_bytes from PRNG
3. Derive BIP39 mnemonic from entropy_bytes
4. Compute private_key from mnemonic (BIP32/BIP44)
5. Compute public_key = private_key Γ G (elliptic curve multiplication)
6. Derive Bitcoin address from public_key
7. If address == target_address: MATCH FOUND
ECDSA Signature Generation:
1. Generate random k (nonce)
2. Calculate R = k Γ G, extract r = R.x
3. Calculate s = kβ»ΒΉ(z + r Γ d) mod n
4. Signature = (r, s)
π STEP 6: Nonce Reuse Attack
If two signatures use same nonce k:
sβ = kβ»ΒΉ(zβ + r Γ d) mod n
sβ = kβ»ΒΉ(zβ + r Γ d) mod n
Recover nonce k: k = (zβ - zβ) Γ (sβ - sβ)β»ΒΉ mod n
Recover private key d: d = (s Γ k - z) Γ rβ»ΒΉ mod n
In June-July 2023, an unusual phenomenon was discovered on the Bitcoin blockchain: multiple wallets created
in different years began to empty on the same date, despite no connection between their owners. The research
team Distrust conducted a detailed analysis and discovered that all the compromised wallets had one thing in
common: they were created using the bx seed command from Libbitcoin Explorer version 3.x.
The Mersenne Twister (MT19937) is a pseudorandom number generator developed by Matsumoto and Nishimura
in 1997. While it has good statistical properties and computational speed, it is absolutely NOT
intended for cryptographic applications for the following reasons:
// VULNERABLE CODE - Libbitcoin Explorer 3.x pseudo_random.cpp
data_chunk random_bytes(size_t length) {{
std::random_device random;
std::default_random_engine engine(random());
std::uniform_int_distribution<uint32_t> distribution(0, 255);
data_chunk result(length);
for (auto& byte : result)
byte = distribution(engine);
return result;
}}
// In this code:
// β’ std::random_device random initializes the seed using system time
// β’ std::default_random_engine (implemented as std::mt19937) receives
// a single value from random_device
// β’ The effective entropy is limited to 32 bits!
The team bx seed uses this function to generate initial entropy:
bx seed -b 256 | bx mnemonic-new
This command would generate 256 bits of random entropy, which would then be converted into a 24-word
BIP-39 mnemonic phrase. However, due to the 32-bit limitation of the actual entropy space, the entire
mnemonic phrase can be reconstructed given the wallet's creation time.
Mathematical Analysis of Vulnerability
The space of possible seed values for MT19937 is limited to 2Β³Β² combinations:
Search space = 2Β³Β² β 4.29 Γ 10βΉ possible values
If the wallet creation date (or approximate date range) is known, the search space can be further reduced.
The system time used to initialize MT19937 can be reconstructed with a high degree of certainty.
Key Derivation Process
Once the original 256-bit entropy has been recovered, its transformation into a private key is fully deterministic according to BIP-39 and BIP-32 standards:
β’ E = entropy to be generated (256 bits)
β’ S = seed for MT19937, where S β [0, 2Β³Β²)
β’ f(S) = function that generates the MT19937 sequence from seed S
β’ trunc_32(x) = function that takes the first 32 bytes from MT19937 sequence
β’ bip39(E) = entropy transformation into BIP-39 mnemonics
β’ derive(m) = converting mnemonics into a private key
β’ addr(k) = set of all possible Bitcoin addresses, derivatives of private key k
Vulnerability is defined as: β k, S : trunc_32(f(S)) β‘ E (mod 256)
such that addr(derive(bip39(E))) = A_target
where A_target is the target Bitcoin address.
Attack Success Probability
When searching through the entire space 2Β³Β²:
P(success) = 1 β (1 β 1/N)^(2Β³Β²)
where N = 2ΒΉβΆβ° is the total number of possible Bitcoin addresses (for P2PKH addresses)
Since 2Β³Β² << 2ΒΉβΆβ°, the probability of a false match is negligible, and P(success) β 1 when the correct seed is found
Performance Analysis
On modern equipment (e.g., GPU NVIDIA RTX 3090):
Hash Rate: ~10βΉ operations per second
Total Search Space: 2Β³Β² β 4.29 billion seeds
Time to Complete Search: ~4-5 seconds
With Date Range Optimization: Milliseconds to seconds
Key Insight: These calculations show that recovering a private key is practically
feasible even for non-professional attackers with commodity hardware. The vulnerability transforms
Bitcoin's 256-bit security into a trivial 32-bit problem.
π Scientific Research by KEYHUNTERS
Entropy Weakness Exploit in Key Generation
The KEYHUNTERS research team has conducted extensive analysis of the CVE-2023-39910 vulnerability,
demonstrating how flaws in the entropy source can have catastrophic consequences for Bitcoin and other
cryptocurrencies. Their research emphasizes that this attack, known as the "Entropy Weakness Exploit
in Key Generation" or "PRNG Seed Recovery Attack," illustrates scientifically how a fundamental flaw
in cryptoengineering can undermine trust in entire classes of wallets.
Ring Signature Vulnerabilities
An attacker with knowledge of a random number generator vulnerability (such as the use of a Mersenne
Twister-type PRNG with small seeds) stages a veritable "cryptographic boxing match in the ring": they
observe the public keys and salts in Borromean ring signatures published on a blockchain or other
protocol that uses libbitcoin.
Critical Vulnerability Analysis
Vulnerable versions of Libbitcoin Explorer (3.0.0β3.6.0) used the mt19937 (Mersenne Twister) generator to generate private key entropy, which allowed attackers to:
Reconstruct the entire sequence of "random" bytes that were generated at a specific time
Recover the original seed phrase (BIP-39 mnemonic)
Calculate the private key and gain complete control over the wallet
Execute mass theft of bitcoins from wallets created using vulnerable versions
Vulnerable Code Example
// VULNERABLE VARIANT - Weak PRNG!
std::mt19937 rng(seed);
// seed - 32-bit value from system time and/or user input
uint256 secret;
for (size_t i = 0; i < 32; ++i)
secret[i] = rng() & 0xFF;
// Only 2Β³Β² variants total!
Secure Code Implementation
A secure code snippet for generating a private key:
After analyzing the Borromean ring signature implementation code, KEYHUNTERS identified several
potential areas where cryptographic vulnerabilities related to secret key and private key leakage
may occur:
Vulnerability: Secret keys are stored in cleartext in the data structure
secret_keys_map. This structure may remain in memory longer than necessary, creating
a risk of leakage via side-channel attacks or memory dumps.
Vulnerability #2: Direct Secret Key Usage in Arithmetic Operations
// Critical vulnerability at line 216
const auto& k = salts[i];
const auto& x = secret;
const auto s = k - e_i_j * x;
if (!s)
return false;
This operation s = k - e_i_j * x is extremely vulnerable to:
Timing attacks: The execution time may depend on the value of the secret key
Power analysis: CPU power consumption during multiplication and subtraction can leak information about x
Cache attacks: Memory access patterns can reveal secret key bits
Vulnerability #3: Hash Function Concatenation Order
static ec_scalar borromean_hash(const hash_digest& M, const data_slice& R,
uint32_t i, uint32_t j) NOEXCEPT
{{
// e = H(M || R || i || j)
hash_digest hash{{}};
stream::out::fast stream{{{{ hash }}}};
hash::sha256::fast sink(stream);
sink.write_bytes(R);
sink.write_bytes(M);
sink.write_4_bytes_big_endian(i);
sink.write_4_bytes_big_endian(j);
sink.flush();
return hash;
}}
While the function itself appears secure, the order of data concatenation may create opportunities
for length extension or collision attacks in certain scenarios.
BTCDetect Research Methodology
KEYHUNTERS developed BTCDetect as a cryptographic entropy analysis and detection framework capable
of identifying weak randomness in Bitcoin wallet generation. BTCDetect operates by systematically
tracing the entropy initialization process in key generation routines, applying mathematical analysis,
and reproducing potential weak seeds.
BTCDetect Operational Model
Entropy Source Detection: Identifies the PRNG used (e.g., mt19937)
Seed Space Enumeration: Systematically searches the limited 2Β³Β² seed space
Deterministic Key Reconstruction: Reproduces the exact key generation process
Blockchain Correlation: Matches derived addresses against blockchain data
Scientific Significance
The scientific significance of BTCDetect extends beyond the Milk Sad case, as its methodology
applies to a wide class of PRNG vulnerabilities:
Universal Applicability: Any wallet generation using weak PRNGs (mt19937, LCGs, etc.) falls under exploitable models
Entropy as Cryptographic Primitive: Demonstrates that entropy itself must be treated as a cryptographic primitive
Systemic Risk Assessment: A weak PRNG corrupts the entire security chain from seed generation to transaction authorization
Address 1NiojfedphT6MgMD7UsowNdQmx5JY15djG - Demonstrated in this research
Attack Complexity vs. Impact
Attack Complexity: LOW
β’ Modern GPUs can perform approximately 10βΉ hash operations per second
β’ Entire 2Β³Β² keyspace can be searched in mere seconds to minutes
β’ No specialized equipment required - commodity hardware sufficient
Impact: CRITICAL
β’ Complete private key recovery
β’ Total loss of funds
β’ Irreversible cryptocurrency theft
β’ Systemic trust violation in affected wallet software
Capabilities with Recovered Private Key
A recovered private key gives complete control over the Bitcoin wallet, allowing
an attacker to:
Transfer all funds to any address without authorization
Sign arbitrary transactions on behalf of the wallet owner
Access all derived addresses in the BIP-32 hierarchical structure
Compromise multiple cryptocurrencies if the same seed was used across blockchains
Steal future deposits as the attacker retains permanent access
π‘οΈ Security Recommendations and Countermeasures
For Users
β οΈ CRITICAL ACTION REQUIRED
If you created Bitcoin wallets using Libbitcoin Explorer 3.x:
IMMEDIATELY transfer all funds to a new wallet created with secure software
Generate new wallets using hardware wallets (Ledger, Trezor) or reputable software (Electrum, Bitcoin Core)
Never reuse the compromised wallet or seed phrase
Verify that new wallets use cryptographically secure random number generators
Entropy Generation Requirements
Platform
Recommended CSPRNG
Do NOT Use
Linux/Unix
/dev/urandom, getrandom()
/dev/random (can block), time-based seeds
Windows
CryptGenRandom(), BCryptGenRandom()
rand(), srand(), std::mt19937
C++
std::random_device (with proper implementation)
std::mt19937, std::default_random_engine
Python
os.urandom(), secrets module
random module, time.time()
Correct Entropy Generation in C++
#include <fstream>
#include <array>
void secure_random_bytes(uint8_t* buf, size_t len) {{
std::ifstream urandom("/dev/urandom", std::ios::in | std::ios::binary);
if (!urandom)
throw std::runtime_error("Cannot open /dev/urandom");
urandom.read(reinterpret_cast<char*>(buf), len);
if (urandom.gcount() != static_cast<std::streamsize>(len))
throw std::runtime_error("Read error from /dev/urandom");
}}
// Generate a protected private key
std::array<uint8_t, 32> secret;
secure_random_bytes(secret.data(), secret.size());
// Additional security measures:
// β’ Use mlock() to protect critical data from swapping to disk
// β’ Clear sensitive data immediately after use
// β’ Consider using dedicated cryptographic libraries (e.g., libsodium)
For Developers
Mandatory Security Practices
Never use non-cryptographic PRNGs (mt19937, rand(), etc.) for key generation
Use only OS-provided cryptographic random sources or vetted cryptographic libraries
Implement entropy quality tests to verify randomness before key generation
Regular security audits by independent cryptography experts
Memory protection: Use mlock() and secure erasure for sensitive data
Hardware wallet integration: Leverage hardware RNGs when available
Fail-safe defaults: Default to maximum security, never optimize for speed at expense of security
Security Standards for Hardware Wallets
True Random Number Generator (TRNG): Hardware-based entropy sources
FIPS 140-2/140-3 compliance: Certified cryptographic modules
Secure element chips: Tamper-resistant hardware for key storage
Firmware verification: Cryptographically signed and verified firmware updates
Air-gapped operation: No direct internet connectivity
π― Conclusions and Future Research
Key Findings
The CVE-2023-39910 (Milk Sad) vulnerability demonstrates the critical importance of proper entropy
generation in cryptographic applications. Although the use of Mersenne Twister-32 was documented as
insecure, many developers and users ignored the warnings, leading to a large-scale compromise of over
227,200 Bitcoin wallets.
Vulnerability can be expressed through mathematical relationships:
Entropy is paramount: The security of cryptographic systems depends entirely
on the quality of random number generation. No amount of sophisticated mathematics can compensate
for weak entropy.
Implementation matters as much as theory: Bitcoin's underlying cryptography
(ECDSA, secp256k1) is mathematically sound, but poor implementation (weak PRNG) completely
undermined its security.
Systemic risk from single component: One weak component (32-bit PRNG seed)
can compromise the integrity of the entire system, resulting in total loss of funds.
Time-based attacks are feasible: Knowledge of approximate wallet creation
time dramatically reduces the search space, making attacks trivial.
Reversibility is impossible: Once a private key is compromised and funds
are stolen, recovery is impossible due to Bitcoin's irreversible transaction model.
Future Research Directions
Automated vulnerability scanning: Tools to detect weak entropy in deployed cryptocurrency systems
Blockchain forensics: Methods to identify potentially compromised addresses before exploitation
Post-quantum cryptography: Preparing for quantum computing threats to elliptic curve cryptography
Hardware-based entropy: Integration of quantum random number generators (QRNGs)
Formal verification: Mathematical proof systems to verify cryptographic implementations
Emergency response protocols: Rapid response mechanisms for disclosed vulnerabilities
Final Thoughts
Cryptographic systems and implementation errors are not due to theoretical maturity, but to simple
engineering miscalculations. Without constant auditing, the use of only cryptographically
secure random number generation libraries, and prompt incident response, risks in cryptocurrency
systems will always be fatal and systemic.
The Milk Sad attack is a harsh lesson for the entire cryptocurrency industry:
one weak component can compromise the integrity of the entire system. The $61,025 recovery
demonstrated in this research serves as a concrete example of how theoretical vulnerabilities
translate into real-world financial losses.
β οΈ EDUCATIONAL PURPOSE ONLY β οΈ
This research is presented for educational and security awareness purposes only.
The methodologies described should be used exclusively for:
Academic research and cryptographic analysis
Security auditing with proper authorization
Recovery of legitimately owned lost wallets
Development of defensive security measures
Unauthorized access to cryptocurrency wallets is illegal and unethical.