TECHNICAL_DOC // CRYPTOGRAPHY / ENTROPY-RNG
ENTROPY
& RNG
& RNG
Entropy is the measure of unpredictability in a random number. Private key
generation requires 256 bits of cryptographic entropy — meaning the key must be indistinguishable
from a uniformly random selection from 2^256 possibilities. Weak entropy is the most
common real-world cause of key compromise and fund loss.
WHERE_ENTROPY_IS_REQUIRED
CRITICAL ENTROPY POINTS IN BITCOIN
1. Private Key Generation
Required: 256 bits of true entropy
Used for: all key operations, spending authority
2. BIP39 Seed Generation
Required: 128–256 bits (12–24 word phrases)
Used for: HD wallet master seed derivation
3. ECDSA Nonce k ← most dangerous
Required: unique, unpredictable per-signature 256-bit value
If reused or predictable: private key FULLY RECOVERABLE
4. AES / ChaCha20 encryption keys
Used for: wallet file encryption
ENTROPY_SOURCES
OS-Level CSPRNG
RECOMMENDED
Operating systems collect entropy from hardware events and provide it via a cryptographically secure random number generator. This is the correct source for all Bitcoin key material.
Linux: /dev/urandom (non-blocking, uses ChaCha20 CSPRNG)
/dev/random (deprecated blocking variant)
getrandom() (syscall, preferred)
macOS: /dev/random (both /dev/random and /dev/urandom are CSPRNG)
CCRandomGenerateBytes()
Windows: BCryptGenRandom()
CryptGenRandom() (legacy)
Hardware entropy sources (kernel collects):
- CPU timing jitter (RDRAND instruction)
- Disk I/O timing
- Network packet timing
- Keyboard/mouse events
- Hardware RNG chips (TPM, RDRAND)
The nonce k used in ECDSA signing must be unique and unpredictable for every signature.
Reusing k — even once — allows the private key to be trivially computed.
ECDSA signature: (r, s) where
r = (k×G).x mod n
s = k^(-1 × (hash + privkey × r)) mod n
If k is reused for two signatures (r is same, s1 ≠ s2):
s1 - s2 = k^-1 × (hash1 - hash2)
→ k = (hash1 - hash2) / (s1 - s2) mod n
→ privkey = (s1×k - hash1) / r mod n
FULLY RECOVERABLE. This is how the 2013 PS3 key was extracted.
Solution: RFC 6979 deterministic k generation
k = HMAC-SHA256(privkey, hash) ← deterministic, unique, unpredictable
Used by all modern Bitcoin implementations
schnorr-signatures/">Schnorr signatures (BIP340) use a similar deterministic nonce scheme, eliminating the catastrophic risk of random nonce reuse.
Weak Entropy Examples — Real Attacks
HISTORICAL FAILURES
Several real-world incidents demonstrate the catastrophic consequences of insufficient entropy in Bitcoin key generation.
Android Bitcoin Wallet (2013):
SecureRandom() bug on Android 4.x used same seed for many keys
→ Thousands of keys were predictable → funds drained
Early brain wallets (2012–2015):
Private keys generated from password hashes (e.g. SHA256("password"))
→ Attackers precomputed keys for common phrases
→ Any funds sent were stolen within seconds
Low-entropy embedded devices:
IoT devices / early hardware wallets with poor entropy on boot
→ Multiple devices generated identical "random" keys
TERMINOLOGY_INDEX
Entropy
A measure of randomness/unpredictability. 256 bits means 2^256 equally likely outcomes.
CSPRNG
Cryptographically Secure Pseudo-Random Number Generator. Produces output indistinguishable from true randomness.
Nonce k
The random value in ECDSA signing. Must be unique per signature — reuse reveals the private key.
RFC 6979
Standard for deterministic ECDSA nonce generation using HMAC-SHA256 of the private key and message hash.
RDRAND
Intel CPU instruction that provides hardware-generated random numbers, used as an entropy source by the OS.
Brain Wallet
A private key derived from a memorized passphrase. Insecure — attackers precompute keys for all common phrases.
INTERACTIVE — TRY IT YOURSELF
INTERACTIVE_DOC // CRYPTOGRAPHY / ENTROPY-RNG
ENTROPY & RNG
INTERACTIVE
INTERACTIVE
Most programmer instincts about "randomness" are dangerously wrong in a Bitcoin
context.
Math.random() is predictable. Hashing a password isn't entropy.
Reusing a signing nonce — even once — leaks the entire private key.
This page rebuilds your intuition from first principles, then lets you test it
interactively. By the end you should be able to spot bad randomness on sight
and explain to a colleague why their genKey() function will lose them money.
§ 1 — WHAT IS ENTROPY, ACTUALLY?
Entropy is a measure of unpredictability, expressed in bits. One bit of
entropy means two equally-likely outcomes.
n bits means 2ⁿ
equally-likely outcomes. The phrase "256 bits of entropy" is a precise claim:
an attacker faces 2²⁵⁶ equally-likely possibilities. If any outcome is more
likely than any other, you have less entropy than the bit-count suggests.
The number that matters is min-entropy:
−log₂(p_max) where
p_max is the probability of the most-likely outcome. A "256-bit" key drawn
from a generator that always returns the same first byte has at best 248 bits of
min-entropy — a billion-times-billion-times-billion times easier to crack.
INTERACTIVE — HOW MUCH ENTROPY DOES EACH SOURCE GIVE YOU?scaled to 256 bits
Counter-intuition: A 12-character password is < 80 bits of entropy.
A "secure-looking" 64-character SHA-256 of "password" has ~zero bits — it's
one of the first values in any rainbow table. Length is not entropy.
Hashing is not entropy.
§ 2 — WHY 256 BITS? (DRAG TO SEE COSTS)
The secp256k1 curve order
n is just under 2²⁵⁶. A Bitcoin
private key is a uniformly-random integer in [1, n−1]. Why this enormous
number? Because a brute-force attacker has to enumerate it, and 256 bits
is calibrated so that even at the hash-rate of the entire planet's hardware running for
the age of the universe, they cover an unmeasurable fraction. Drag the slider:
INTERACTIVE — BRUTE-FORCE COST CALCULATORdrag the slider
64 BITS OF ENTROPY
Combinations
2⁶⁴ ≈ 1.8 × 10¹⁹
Time @ 1 TH/s
585 years
Cost (cloud, est.)
~$10⁹
Reality check
national-scale attacker
Notice the cliff between 80 and 128 bits. Cryptographers don't think
in linear terms — every bit doubles the work. 80 bits is "barely defensible," 128 bits
is "permanently safe with current physics," 256 bits is "permanently safe with any
conceivable physics" — and gives a healthy margin against future quantum attacks
(Grover's algorithm halves the effective bit count, leaving secp256k1 keys at ~128 bits
against a quantum adversary).
§ 3 — PRNG vs CSPRNG (CAN YOU TELL?)
A PRNG (Pseudo-Random Number Generator) is a deterministic function
expanding a small seed into a long output stream. Standard library RNGs
(
Math.random(), Python's random, Java's Random)
use small internal state — typically 32 to 624 bits — and use fast algorithms like
Mersenne Twister. They look random but are catastrophically predictable:
given enough output, an attacker can recover the state and predict all future values.
A CSPRNG (Cryptographically Secure PRNG) is also deterministic, but
its design — and continuous reseeding from hardware noise — makes it computationally
infeasible to predict outputs even if the attacker has seen gigabytes of prior output.
crypto.getRandomValues(), Python's secrets, Linux's
/dev/urandom, Windows' BCryptGenRandom: all CSPRNGs.
Click each source below — they all "look random" to your eyes:
INTERACTIVE — 256-BIT VISUALIZERtry every source
— click a source button —
Each click generates 256 bits from that source. Watch closely — to your eyes the bad sources will look indistinguishable from the good one. That's the whole problem.
The cruel irony: visual inspection is useless.
Math.random()'s
output passes most casual statistical tests yet is fully predictable to anyone
who has seen ~624 prior outputs. The grid above is intentionally limited to 256 bits
— way below what a Mersenne-Twister attack needs to recover state. You cannot
tell good randomness from bad by looking at it. You must trust the source.
§ 4 — THE NONCE HORROR (WALK THROUGH IT)
ECDSA signing requires a per-signature secret integer
k — the
nonce. If you ever sign two different messages with the same
k, an observer with both signatures can compute your private key with
high-school algebra. This is not a theoretical bug. It has bankrupted real users and
famously broke Sony's PS3 master signing key in 2010. Click "Next step" to walk through
the recovery:
INTERACTIVE — NONCE REUSE → KEY RECOVERYclick step-by-step
SETUP
Alice signs two different messages with the same nonce k.
She holds private key x. The same broken RNG produces the same
k twice. Both signatures share the same r component
(since r = (k·G).x mod n), and that's the giveaway — anyone
watching the chain will spot two signatures with identical r.
EQUATION 1 — sig 1
Two unknowns to the attacker:
Write down the s-value of signature 1.
s₁ = k⁻¹ · (m₁ + r·x) mod nTwo unknowns to the attacker:
k and x. One equation.
Not solvable yet.
EQUATION 2 — sig 2
Same two unknowns, different message hash. Now we have two equations, two unknowns — algebra-class territory.
Write down the s-value of signature 2.
s₂ = k⁻¹ · (m₂ + r·x) mod nSame two unknowns, different message hash. Now we have two equations, two unknowns — algebra-class territory.
SUBTRACT
The
Subtract the equations to eliminate x.
s₁ − s₂ = k⁻¹ · (m₁ − m₂) mod nThe
r·x term is identical in both equations and cancels. The unknown
x vanishes. Only k remains.
SOLVE FOR k
All four values are public. The attacker now has Alice's nonce. This step alone already breaks the scheme (the nonce was supposed to be secret).
Recover the nonce.
k = (m₁ − m₂) · (s₁ − s₂)⁻¹ mod nAll four values are public. The attacker now has Alice's nonce. This step alone already breaks the scheme (the nonce was supposed to be secret).
SOLVE FOR x
From equation 1, rearranged. Now the attacker has Alice's complete private key.
Plug k back in to recover the private key.
x = r⁻¹ · (s₁·k − m₁) mod nFrom equation 1, rearranged. Now the attacker has Alice's complete private key.
RESULT
Funds are gone. There is no recovery.
Total time: a few milliseconds of algebra. The attacker now signs a transaction
sweeping every UTXO Alice controls under that key — and every future UTXO
— to themselves. This is why modern wallets use RFC 6979 deterministic
nonces: k = HMAC-SHA256(privkey, message_hash). No randomness involved.
No way to repeat. The class of bug is eliminated by construction.
§ 5 — SPOT THE VULN (6-QUESTION QUIZ)
Your turn. Below are six snippets in different languages. For each: is this safe to use
for generating Bitcoin private keys? Click your answer, then read the verdict. Aim for
6/6 — anything less means you might ship the bug.
INTERACTIVE — CODE REVIEW QUIZ6 questions
SCORE: 0 / 6
§ 6 — PRACTICAL CHECKLIST
DO
Use the OS CSPRNG via your language's standard binding:
crypto.getRandomValues (JS), secrets (Python), crypto/rand (Go), OsRng (Rust), SecRandomCopyBytes (Apple), BCryptGenRandom (Windows).DO
Use RFC 6979 deterministic nonces for ECDSA, or Schnorr (BIP 340) which derives nonces deterministically by spec. Both eliminate nonce-reuse as a class.
DO
Treat BIP 39 mnemonic generation as security-critical: 128–256 bits of CSPRNG entropy, never user-typed dice rolls without verification.
DO
On embedded / freshly-booted systems, wait for the entropy pool to be seeded before generating keys. Linux's
getrandom() blocks on first boot until ready — let it.DON'T
Never use
Math.random(), java.util.Random, Python's random module, or C's rand() for any cryptographic purpose. They are designed for simulations, not security.DON'T
Never seed a CSPRNG with the time, process ID, or any other guessable value. CSPRNGs seed themselves correctly — you can't help.
DON'T
Never derive private keys from passwords, passphrases, or "memorable" data unless you're using a hardened KDF (Argon2/scrypt) AND a high-entropy salt — and even then, prefer BIP 39 + a passphrase over a wallet-memorized-phrase-deprecated/">brain wallet.
DON'T
Never assume hashing increases entropy.
SHA256(weak_seed) has exactly the entropy of weak_seed, just compressed into 256 bits. If weak_seed has 30 bits of entropy, you have a 30-bit key.TERMINOLOGY_INDEX
Entropy
Measure of unpredictability in bits. n bits = 2ⁿ equally-likely outcomes.
Min-Entropy
−log₂(p_max). The honest measure when outcomes aren't uniform.
PRNG
Pseudo-Random Number Generator. Deterministic, fast, predictable from output.
CSPRNG
Cryptographically Secure PRNG. Output computationally indistinguishable from true randomness.
Mersenne Twister
Fast PRNG used by most stdlib random functions. State recoverable from 624 outputs. Not for crypto.
Entropy Pool
Kernel-managed buffer fed by hardware noise (timing jitter, RDRAND, peripheral events).
getrandom()
Linux syscall (kernel ≥ 3.17). Returns CSPRNG bytes. Blocks until pool seeded on first boot.
RFC 6979
Deterministic ECDSA nonce: k = HMAC-SHA256(privkey, msg_hash). Eliminates nonce-reuse risk.
Nonce k
Per-signature secret in ECDSA. Reuse with different messages → private key falls out via algebra.
Brain Wallet
Private key derived from a memorable phrase. Catastrophically weak — phrases are precomputed and indexed.
RDRAND
Intel/AMD instruction returning hardware-RNG output. Used by the kernel as one entropy source — never trusted alone.
Grover's Algorithm
Quantum search algorithm. Reduces brute-force from 2ⁿ to 2^(n/2). 256-bit keys → 128-bit equivalent against a quantum adversary.