In this article
- TL;DR
- What Is BIP39?
- 12 Words vs 24 Words
- How Your Wallet Derives Keys
- How To Generate BIP39 Wallets In Node.js
- Tech Stack
- Imports And Constants
- Generating A Wallet
- Checking Address Activity
- Persisting Hits
- Orchestrating The Run
- The 25th Word Most Holders Never Set
- Physical theft becomes survivable
- The attack surface gets smaller
- The Attacks That Drain Bitcoin Wallets
- What NOT to Do With Your Seed Phrase
- How to Store Your Seed Phrase
- Metal backup, not paper
- Hardware wallet picks for 2026
- Quantum Computing and BIP39
- BIP39 Survives. The Human Layer Often Does Not.
I work in the crypto self-custody space. Every month someone asks whether they should worry about a brute-force attack on their seed phrase. The math says no. The behavior says yes, for reasons they did not expect.
Treat those 12 or 24 words as the Bitcoin itself. Whoever holds the phrase owns every satoshi in the wallet. Nobody can reset it for you.
Below: how BIP39 works, where it breaks, the 12 vs 24 word question, and what is, in my view, the most underused security feature in Bitcoin: the BIP39 passphrase.
TL;DR
A BIP39 seed phrase is the master key to your Bitcoin: 12 to 24 English words encoding 128 to 256 bits of entropy (BIP-39 spec). The wordlist has 2,048 words, word order matters, and PBKDF2 stretches the phrase into a 512-bit seed that derives every key in the wallet. Brute force against real entropy is out of reach. Risk lives elsewhere: weak random number generators, photos of the phrase, cloud copies, typos, and malware. Write it on metal or paper. Never digital.
What Is BIP39?
The BIP39 authors wrote that a sentence of words "is superior for human interaction compared to the handling of raw binary or hexadecimal representations of a wallet seed" (BIP-39 spec). BIP39 standardised that sentence.
How it works:
- A wallet generates entropy. A random value of 128 to 256 bits, in 32-bit increments.
- The wallet appends a checksum. The first bits of a SHA-256 hash of the entropy go on the end.
- The combined value splits into 11-bit segments. Each segment maps to one word from the BIP39 wordlist.
- You get 12, 15, 18, 21, or 24 words depending on the initial entropy.
The BIP39 wordlist contains exactly 2,048 words (2^11, by design). The spec says the English list lets you identify each word from its first four letters, which cuts typing errors (BIP-39 spec). BIP-39 ships 10 official wordlists across English, Japanese, Korean, Spanish, Chinese (Simplified), Chinese (Traditional), French, Italian, Czech, and Portuguese (BIP-39 wordlist registry). The spec itself strongly discourages non-English lists, because most wallets support only English. Marek Palatinus, Pavol Rusnak, Aaron Voisine, and Sean Bowe wrote the standard, assigned on 10 September 2013 (BIP-39 spec).
Then the PBKDF2 key stretching function runs the mnemonic through 2,048 rounds of HMAC-SHA512 to produce a 512-bit binary seed (BIP-39 spec). That seed feeds the BIP32 HD (hierarchical deterministic) wallet derivation algorithm, which generates the entire tree of private and public keys the wallet uses.
One seed phrase covers a whole tree of keys: every key in the tree can have 2^31 normal and 2^31 hardened children (BIP-32 spec). Every address the wallet has generated is recoverable from those words plus the passphrase, if you set one.
12 Words vs 24 Words
BIP39 maps 128 bits of entropy to 12 words and 256 bits to 24 words (BIP-39 spec). The entropy numbers translate like this:
| Phrase Length | Entropy | Possible Combinations |
|---|---|---|
| 12 words | 128 bits | ~3.4 × 10^38 (2^128) |
| 24 words | 256 bits | ~1.16 × 10^77 (2^256) |
A worked example. Every guess costs 2,048 rounds of HMAC-SHA512. An RTX 4090 runs PBKDF2-HMAC-SHA512 at 3,120.9 thousand hashes per second at 999 iterations (hashcat benchmark), which scales to about 1.5 million seed checks per second at 2,048. At that rate one card needs about 7 × 10^24 years to try every 12-word seed, and a million cards still need about 7 × 10^18 years. The Sun has about 5 billion years left (NASA). For a full walkthrough of choosing and using a wallet, see the self-custody guide.
24 words give the seed 256 bits. The keys it derives still sit on the secp256k1 curve, which SEC 2 rates at 128-bit security (SEC 2, Table 1). So the extra 12 words protect the seed, not the signing keys.
Both are secure today. My rule of thumb: 24 words for long-term savings, because the margin costs nothing but a few minutes of writing.
How Your Wallet Derives Keys
The derivation path explains why one seed phrase is so powerful, and so dangerous to expose.
Your seed phrase, via PBKDF2, produces the master seed. The master seed, via BIP32, produces the master private key and master chain code.
From the master private key, the wallet derives child keys along a derivation path. BIP44 defines the path layout (BIP-44 spec), and BIP84 reuses it with purpose 84' for native SegWit addresses (BIP-84 spec). A BIP44 path looks like this:
m / 44' / 0' / 0' / 0 / 0
Where:
m= master key44'= BIP44 purpose0'= Bitcoin (coin type 0)0'= first account0= external chain (receiving addresses)0= first address index
Every Bitcoin address you have ever received funds on is deterministically derived from that master seed. Restore the seed phrase on a compatible wallet, with the same passphrase and derivation path, and everything comes back: addresses, balances, transaction history.
Lose the seed phrase and there is nothing to restore. No central server, no recovery path.
How To Generate BIP39 Wallets In Node.js
The fastest way to understand BIP39 entropy is to generate it yourself. The Node.js setup below spins up wallets and checks whether the generated addresses have ever held funds. Working code from Bi-Catalyst/bruteforcebitcoin. Educational only. Generating random wallets and checking on-chain activity is a brute-force exercise that confirms the math. It is not a path to anyone else's coins.
Tech Stack
- axios for HTTP requests to blockchain APIs
- bip39 for mnemonic generation and seed derivation
- bitcoinjs-lib for address derivation and transaction tooling
package.json:
{
"name": "bruteforcebitcoin",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"run": "node generate_wallet.js"
},
"license": "MIT",
"dependencies": {
"axios": "^1.4.0",
"bip39": "^3.1.0",
"bitcoinjs-lib": "^5.2.0"
}
}
Imports And Constants
const axios = require("axios");
const bip39 = require("bip39");
const bitcoin = require("bitcoinjs-lib");
const fs = require("fs");
const parallelLimit = 10;
const iterations = 100;
const batchSize = 10;
const delayBetweenBatches = 5000; // 5 seconds
const apiDelay = 3000; // 3 seconds
let useBlockchainInfoAPI = true;
Generating A Wallet
async function generateWallet() {
// Generate a new 12-word mnemonic seed phrase
const mnemonic = bip39.generateMnemonic(128);
console.log("Mnemonic:", mnemonic);
// Convert the mnemonic to a seed
const seed = await bip39.mnemonicToSeed(mnemonic);
// Derive the wallet from the seed using BIP32
const network = bitcoin.networks.bitcoin;
const hdMaster = bitcoin.bip32.fromSeed(seed, network);
const account = hdMaster.derivePath("m/44'/0'/0'/0");
// Generate a new Bitcoin address
const { address } = bitcoin.payments.p2pkh({
pubkey: account.derive(0).publicKey,
network,
});
console.log("Bitcoin Address:", address);
const hasTransactions = await checkAddressActivity(address);
await new Promise((resolve) => setTimeout(resolve, apiDelay));
return { address, hasTransactions };
}
Checking Address Activity
Two public block explorers alternating to manage rate limits. Blockchain.com's API and BlockCypher's API:
async function checkAddressActivity(address) {
try {
let response;
if (useBlockchainInfoAPI) {
response = await axios.get(`https://blockchain.info/rawaddr/${address}`);
} else {
response = await axios.get(`https://api.blockcypher.com/v1/btc/main/addrs/${address}`);
}
useBlockchainInfoAPI = !useBlockchainInfoAPI;
let hasTransactions = false;
if (response.data.txs) {
hasTransactions = response.data.txs.length > 0;
} else if (response.data.txrefs) {
hasTransactions = response.data.txrefs.length > 0;
}
if (hasTransactions) {
console.log("This address has transactions associated with it.");
return true;
} else {
console.log("This address has no transactions associated with it.");
return false;
}
} catch (error) {
console.error("Error fetching address data:", error.message);
return false;
}
}
Persisting Hits
function appendToFile(filename, data) {
fs.appendFile(filename, data, (err) => {
if (err) {
console.error(`Error saving data to ${filename}:`, err.message);
} else {
console.log(`Data saved to ${filename}`);
}
});
}
Orchestrating The Run
async function main() {
const walletPromises = [];
for (let i = 0; i < iterations; i++) {
walletPromises.push(generateWallet());
if (walletPromises.length === parallelLimit) {
await processBatch(walletPromises);
walletPromises.length = 0;
}
}
if (walletPromises.length > 0) {
await processBatch(walletPromises);
}
}
Run it overnight and you will not hit a funded wallet. The script runs 10 wallets at a time, waits 3 seconds after each API call and 5 seconds between batches (generate_wallet.js), so it checks about one wallet per second against a space of 2^128 seeds. It proves the math by failing to defeat it.
Full repo at github.com/Bi-Catalyst/bruteforcebitcoin.
The 25th Word Most Holders Never Set
BIP39 includes an optional passphrase, the "25th word". In my experience most holders never set one. That is a mistake.
When the mnemonic converts to a binary seed, PBKDF2 takes two inputs: your mnemonic and an optional passphrase. By default the passphrase is an empty string (BIP-39 spec). You can enter anything. A word, a phrase, symbols, numbers.
A different passphrase produces a different wallet: same 24 words, new master seed, new addresses, new balances. Two security implications follow.
Physical theft becomes survivable
Someone breaks in and finds your seed phrase on paper. Without the passphrase, they reach only the empty-passphrase wallet, a decoy with a small amount in it. The BIP39 spec names this property: every passphrase generates a valid wallet, which "provides plausible deniability" (BIP-39 spec).
Keep a small balance in the base wallet. Keep the real stack behind the passphrase. Make the passphrase long and random: a thief with your words can test guesses offline with BTCRecover, so a short word buys little.
The attack surface gets smaller
Most attack vectors (physical theft, shoulder surfing, a leaked photo) need only the seed words. The passphrase adds a second factor. Never write it on the same paper, never keep it in the same location, never send it digitally.
Coldcard, Jade, Trezor, and Ledger all support it. Coldcard sells the Q with a QWERTY keyboard "ideal for long BIP-39 passphrases" (COLDCARD Q). Jade has a BIP39 passphrase setting (Jade changelog). Trezor lists passphrase protection on the Safe 3 (Trezor Safe 3). Ledger puts it under Settings, then Security, on the Nano S Plus, and under Settings, then Advanced, on the Flex (Ledger support).
One warning. The passphrase is not recoverable. Forget it, and that Bitcoin is gone. Write it down separately, store it securely, and test your recovery before depositing anything significant.
The Attacks That Drain Bitcoin Wallets
Real-world seed phrase failures almost never involve brute force against good entropy. I sort them into three categories: digital, physical, mathematical.
Digital attacks come first. In my experience phishing causes the most losses: fake wallet apps, fake "wallet recovery" websites, fake support agents. Ledger says it "will never ask you for the 24 words of your recovery phrase" (Ledger), and BitBox says the same of its recovery words (BitBox02). Treat anyone who asks as a thief. Photos are next. In February 2025 Kaspersky found apps in Google Play and Apple's App Store that scanned phone galleries with text recognition to steal recovery phrases, and the infected Google Play apps had over 242,000 downloads (Securelist). Malware (keyloggers, clipboard hijackers) on internet-connected machines can capture seed phrases during entry, which is why dedicated hardware wallets exist.
Physical attacks are slower, and they still happen. Someone finds your written seed phrase in a drawer, behind a frame, on a fridge magnet. Storage location plus the BIP39 passphrase are your defences here. Shoulder surfing is the mild version. Someone watches you generate or enter your seed phrase. Set up hardware wallets in private and check for cameras before confirming anything sensitive.
Mathematical attacks (brute forcing the entropy itself) are the subject of this post's title. They have drained wallets only when the entropy was weak. Libbitcoin Explorer's bx seed produced seeds with 32 bits of real entropy, and the Milk Sad researchers estimate over $900,000 was stolen (Milk Sad disclosure). Coinkite's advisory of 30 July 2026, updated on 1 August, says a Coldcard firmware bug weakened seed generation, that Mk4, Q and Mk5 seeds carried about 72 bits instead of 128, and that attackers regenerated the weak seeds offline and stole funds (Coinkite advisory). The full story is in the Coldcard weak-entropy post. The math holds. Losses come from behavior and from broken entropy sources.
What NOT to Do With Your Seed Phrase
My hard rules:
- No digital photos. Ever.
- No cloud storage. Dropbox, Google Drive, iCloud, OneDrive.
- No password managers unless you have thought through the threat model.
Beyond the above, also skip email (not to yourself, not to anyone), messaging apps (WhatsApp, Signal, iMessage), screenshots, and any website that claims to be a "seed phrase validator" or "wallet recovery tool". Those are scams.
Keep the phrase on paper or metal, in places you control.
How to Store Your Seed Phrase
Generate on a dedicated device (Coldcard, Jade, Trezor) and not a browser extension, mobile app, or any desktop wallet with internet access. A connected computer has too many attack surfaces. A device can still ship a bad random number generator, so add your own entropy where the device allows it. Coinkite's advisory says seeds made with at least 50 private dice rolls kept at least 128 bits of entropy despite the bug (Coinkite advisory).
Metal backup, not paper
Paper burns, gets wet, deteriorates. Metal backups hold your seed words in steel. Cryptosteel calls its Seed24 fireproof (Cryptosteel), and SEEDOR states its 316L stainless steel safe withstands 1,450 °C (SEEDOR). One copy in one location is a single point of failure. Keep two or three metal backups in separate physical locations. If you use a BIP39 passphrase, store it separately from the seed words.
Hardware wallet picks for 2026
Also covered in Wallets Staying Secure.
- Coldcard Q. Bitcoin-only, airgapped, USD 319 (COLDCARD Q). In my view the most security-focused of the four.
- Jade Plus. Fully open source, USD 169.99 (Blockstream Jade).
- Trezor Safe 5. GPL-3.0 firmware (Trezor firmware repository) and what Trezor calls an "NDA-free EAL 6+ Secure Element" (Trezor Safe 5). The Safe 5, and the Safe 3 since June 2024, default to a 20-word SLIP-39 backup, with 12 or 24 BIP-39 words selectable (Trezor backups guide).
- Ledger Nano S Plus and BitBox02. Ledger uses a 24-word recovery phrase (Ledger support). BitBox02 backs up to a microSD card, with recovery words as an option (BitBox02). Ledger has published two incidents of its own: a 2020 breach of customer contact data (Ledger) and the December 2023 Connect Kit compromise (Ledger incident report).
Test before you deposit. Wipe the device. Restore from your seed phrase. Verify all addresses match. Confirm the passphrase works. Only then send real Bitcoin to the wallet.
Quantum Computing and BIP39
Shor's algorithm solves discrete logarithms (Shor 1995), the problem behind the elliptic curve signatures Bitcoin uses for transactions. It does not apply to BIP39 entropy. A large enough quantum computer could derive a private key from a public key already visible on chain. Against the seed, the best known attack is Grover's search, which needs about the square root of the classical number of guesses (Grover 1996). That turns 2^128 into about 2^64 quantum steps for a 12-word seed and 2^256 into about 2^128 for a 24-word seed, each step still running 2,048 rounds of HMAC-SHA512.
NIST published its first three finalised post-quantum standards, FIPS 203, 204 and 205, on 13 August 2024 (NIST). Bitcoin does not use them yet. Taproot's Schnorr signatures (BIP-340) run on the same secp256k1 curve as ECDSA, so they face the same Shor risk. In my view any migration will be a coordinated protocol change. Full breakdown in the quantum threat analysis.
BIP39 Survives. The Human Layer Often Does Not.
The cryptography is sound. Real 128 or 256 bits of entropy produce a keyspace no adversary can brute force (BIP-39 spec).
The vulnerabilities are human, plus the occasional broken random number generator. Seed phrases get photographed, cloud-synced, typed into phishing sites, stored in a single location with no redundancy. A strong BIP39 passphrase, supported by every hardware wallet named above, defeats most of those scenarios with one extra step.
Do three things. Enable the BIP39 passphrase and store it separately from your seed words. Move to a metal backup, because paper is not a permanent solution. Test your recovery before it matters by wiping the device, restoring from seed and passphrase, and verifying it works.
BIP39 does its part. Whether your coins stay yours depends on the passphrase, the backup and the restore test you add on top.
This article draws on publicly available BIP-39 documentation and hardware-wallet vendor information as of October 2026. It is not security advice. Hardware-wallet firmware and feature sets change. Test every recovery flow on a dedicated device before depositing significant Bitcoin, verify the open-source status of any wallet firmware against the vendor's current public repository, and treat any "BIP-39 brute force" service offer as a scam. Security guidance dates fast. When in doubt, ask an independent security professional or a FINMA-supervised custodian before depositing material capital into a setup you cannot independently verify.
Sources:
- BIP-39 specification
- BIP-39 wordlist registry
- BIP-32 specification
- SEC 2: Recommended Elliptic Curve Domain Parameters
- hashcat benchmark on an RTX 4090
- Milk Sad disclosure
- Coinkite Coldcard security advisory
- Kaspersky Securelist: SparkCat
- Trezor firmware repository
- Trezor backups guide
- NIST Post-Quantum Cryptography project
New to Bitcoin? Start with Chapter 1.
Want the full picture? Read all 19 chapters free or order the physical book.
