The Database of All Bitcoin Private Keys Is a Magic Trick
You come across keys.lol, a website claiming to contain every Bitcoin private key. You open a page and find private keys listed beside their addresses, with links to more pages than you could ever browse. The last page number has 75 digits. If the site supposedly has the key to your wallet too, shouldn’t you be worried?
The site calculates each page when you ask for it. Understanding that small trick explains why displaying a keyspace is easy and searching it is not.
A private key is a number
A Bitcoin private key is an integer from 1 to:
115792089237316195423570985008687907852837564279074904382605163141518161494336
The upper bound is n − 1, where n is the order of the secp256k1 elliptic
curve group. Valid keys satisfy 1 ≤ k < n; the range is just under 2²⁵⁶.
Multiply the curve’s generator by that integer to get a public key. Hash and
encode the public key to obtain a legacy Pay-to-Public-Key-Hash (P2PKH) address.
The forward calculation is cheap. Recovering the secret from a public key or
address is computationally infeasible under the usual classical models.
The directory uses the forward calculation. A page number selects a short run of integers, and the server derives their addresses. Every key is “already there” in the same sense that every integer is already on the number line. The site is a pocket calculator wearing a trench coat.
Here is the public-key derivation and the hash used in a legacy address:
import hashlib
from coincurve import PrivateKey
def hash160(data):
sha256 = hashlib.sha256(data).digest()
return hashlib.new("ripemd160", sha256).digest()
secret = 1 # Any integer in [1, n).
pub = PrivateKey.from_int(secret).public_key.format(compressed=False)
pubkey_hash = hash160(pub)
# P2PKH address = Base58Check(0x00 || pubkey_hash)
For secret = 1, the uncompressed public-key form gives
1EHNa6Q4Jz2uvNExL497mE43ikXhwF6kZm. Part 3 checks its rather busy transaction
history. The number is a valid key; choosing it as a secret is another matter.
That distinction runs through the series. Uniform selection across the valid
range supplies about 256 bits of source entropy. A fixed algorithm starting
from a 32-bit seed reaches at most 2^32 outputs, however long the resulting
key looks. Part 0
introduces that difference between output length and input uncertainty.
Storing the directory
The range contains about:
2^256 ≈ 1.16 × 10^77 keys
One byte per key would already require about 10⁷⁷ bytes. An actual key-and-address record would need much more. No useful storage plan starts there.
Calculating a requested page avoids the storage problem. It gives no shortcut to finding a particular secret: the server still has to choose which page to calculate. That is where the size of the range becomes inconvenient.
Searching instead
On one laptop core, the companion scanner derives both legacy P2PKH address forms at about 31,000 keys/s. Loading the funded-address index and screening both forms brings the measured control rate to about 28,000 keys/s. Round up generously to 10¹² keys per year per core:
| Search | Candidates | Exhaustion time at 10¹² candidates/year |
|---|---|---|
| Full private-key range | ≈2²⁵⁶ | ≈10⁶⁵ years |
| All valid 12-word BIP39 mnemonics | 2¹²⁸ | ≈10²⁶ years |
The mnemonic row borrows the raw-key rate to show scale. It assumes uniform generation, a fixed passphrase, and specified derivation paths. A real mnemonic search also performs Password-Based Key Derivation Function 2 (PBKDF2) and BIP32 derivation; this project has not measured that pipeline.
The universe is about 1.4 × 10¹⁰ years old. Exhausting even the 12-word space at this assumed rate takes roughly 10¹⁶ times that long. A million cores and a million-fold speedup remove twelve orders of magnitude. There are still plenty left.
We ran a small random search anyway. The control generated 1,500,000 keys, derived both P2PKH forms, and screened the resulting three million addresses against the 57,205,029-address snapshot dated October 13, 2026. There were zero index flags, so the run made no live explorer lookups.
Of the snapshot entries, 21,198,062 have the legacy 1… prefix. Treat every one
as a valid P2PKH target and assume ideal address hashes. The probability of any
exact address match is then at most approximately:
3,000,000 × 21,198,062 / 2^160 ≈ 4.35 × 10^-35
Zero is the expected observation. It applies to those two address forms in that snapshot. Part 3 explains the prefix index and why a miss says nothing about other output types or a later balance.
Which secret, and how many targets?
Exhausting a range is only one attack model. Two distinctions affect the cost:
An exposed public key permits a discrete-log attack. A generic attack such as Pollard’s rho needs roughly √n ≈ 2¹²⁸ group operations on secp256k1. That is about 128 bits of classical security for an exposed public key. Recovering that key’s secret generally does not recover its mnemonic or the wallet’s whole key tree. BIP32 treats those properties separately.
Finding any target can be easier than finding one specified target. Suppose there were 2²⁶ distinct, uniformly generated 12-word mnemonics, all using the fixed passphrase and paths under search. Finding any one would take about 2¹²⁸ / 2²⁶ = 2¹⁰² guesses on average, or roughly 10¹⁹ years at our assumed rate. The address dump does not establish that population: an address count tells us neither how many distinct mnemonic-backed wallets exist nor their derivation paths.
For a different example, uniformly generated raw keys matching any of 2²⁶ P2PKH address hashes would take about 2¹⁶⁰ / 2²⁶ = 2¹³⁴ trials. That is an address-hash search. Its work units differ from the group operations in a discrete-log attack and the full derivations in a mnemonic search.
The smaller spaces people actually chose
Real key-guessing attacks exploit secrets drawn from much smaller populations: short seeds, unsuitable pseudorandom generators, and human-chosen phrases. Other failures occur later. A repeated signing nonce can expose a strong key through signature algebra; a copied recovery phrase needs no search at all.
Part 2 follows the normal wallet generation stack and the 12-versus-24-word question. Then Part 3 measures four candidate-generation rules against the snapshot, and Part 4 examines documented randomness failures and a separate synthetic benchmark.
The scanner reads public blockchain data and never constructs or broadcasts a transaction. The other experiments use synthetic data. A funded match would be a statistic to report; it would not authorize spending from that address.