
Scientific and technical article.
BIP-0039 defines a mnemonic interface for representing cryptographic entropy and a procedure for deriving a 512-bit seed. This seed is then used in BIP-0032 hierarchical deterministic wallets and compatible derivation schemes. The standard addresses the problem of reliably recording machine-generated randomness by humans, but does not provide a mechanism for randomness generation, backup encryption, or error correction.
From a cryptanalytic perspective, BIP-0039 should be viewed as a reversible encoding of the ENT value with a short checksum and as a one-way expansion of the mnemonic via PBKDF2-HMAC-SHA512. The wallet’s strength is determined primarily by the quality of the initial entropy, the secrecy of the mnemonic, and, if it is compromised, the entropy of the additional passphrase.
Status and purpose
BIP-0039, which has a Deployed status , is part of the Bitcoin application-layer specification and was assigned on September 10, 2013. Its authors are listed as Marek Palatinus, Pavol Rusnak, Aaron Voisine, and Sean Bowe. The document is distributed under the MIT license.
The practical motivation is simple: a binary seed or a long hexadecimal string are poorly suited for manual backup, whereas a sequence of words can be written down, verified, and transferred offline. However, a phrase is not intended to turn a user’s quotation, password, or “memorable phrase” into a secure wallet: it is a classic brainwallet model, vulnerable to dictionary attacks.
Data model
| Designation | Meaning | Acceptable/fixed values | Cryptanalytic meaning |
|---|---|---|---|
ENT | Primary random entropy | 128, 160, 192, 224 or 256 bits | Upper bound on the search space for a valid CSPRNG |
CS | Checksum | ENT / 32 bit | Checks for some random errors, but does not add any privacy |
MS | Length of mnemonic | 12, 15, 18, 21 or 24 words | Determines the volume of ENT being coded, not the “power of words” |
seed | PBKDF2 result | 512 bits = 64 bytes | Material for BIP-0032; its length does not increase the initial entropy |
CS = ENT / 32 MS = (ENT + CS) / 11 LaTeX: \(CS = ENT/32\), \(MS = (ENT + CS)/11\).
Each word encodes 11 bits, since the dictionary contains 2048 entries: 2048 = 2^11. Therefore, a 12-word mnemonic carries 132 bits, of which 128 bits are entropy and 4 bits are checksum.
| ENT, bit | CS, bit | ENT + CS, bit | MS, words |
|---|---|---|---|
| 128 | 4 | 132 | 12 |
| 160 | 5 | 165 | 15 |
| 192 | 6 | 198 | 18 |
| 224 | 7 | 231 | 21 |
| 256 | 8 | 264 | 24 |
Construction of mnemonics
The algorithm begins by obtaining the ENT bits from a cryptographically secure random number generator (CSPRNG). The SHA-256 of the ENT is then calculated, the first CS bits of the hash are taken, and appended to the ENT. The resulting string is divided into 11-bit blocks; each block is interpreted as a word index from 0 to 2047.
C = SHA256(ENT)[0:CS] B = ENT || C w_i = Wordlist[ int(B[11i : 11(i+1)]) ] LaTeX: \(C=\operatorname{prefix}_{CS}(\operatorname{SHA256}(ENT))\), \(B=ENT\parallel C\).
Illustrative test vector
For an ENT of 128 zero bits, the checksum is equal to the first four bits of the SHA-256 of that value; according to the official test vectors, the result is a 12-word English phrase beginning with eleven abandon and ending with about. This is a public test, not a seed for storing funds: the mnemonic, familiar to any reader, is completely compromised.
ENT (hex): 000000000000000000000000000000000 Mnemonic: abandon abandon abandon abandon abandon abandon abandon abandon abandon about Passphrase: TREZOR
This vector is useful for auditing: the developer checks the entire pipeline—SHA-256, bit order, dictionary indexing, NFKD normalization, and PBKDF2—against the expected result. Using a null, template, or demo ENT in production code is prohibited.
Dictionaries and normalization
A high-quality BIP-0039 dictionary contains 2048 words, is lexicographically sorted, avoids dangerously similar pairs, and allows for unambiguous recognition of English words based on their first four letters. Sorting allows for searches using binary search or trie; this is an access optimization, not cryptographic protection.
UTF-8 with Unicode Normalization Form Compatibility Decomposition (NFKD) is used for strings. Normalization is critical: visually similar or canonically equivalent Unicode representations without a common rule could yield different byte strings and, therefore, different seeds.
Operational risk: Translating the words of one mnemonic into another language is not a wallet transformation. PBKDF2 accepts the phrase text, not the hidden ENT; the modified text produces a different seed. In the current ecosystem, the English dictionary is the most compatible, and the specification strongly discourages releasing new mnemonics in non-English dictionaries unless absolutely necessary.
Transition to seed
The mnemonic and optional passphrase are normalized using NFKD. The mnemonic phrase is used as a PBKDF2 password, and the salt is formed by the string "mnemonic", to which the passphrase is appended. BIP-0039 parameters are fixed: 2048 iterations, PRF = HMAC-SHA512, and the result length is 64 bytes.
seed = PBKDF2-HMAC-SHA512( password = NFKD(mnemonic), salt = NFKD(“mnemonic” || passphrase), iterations = 2048, dkLen = 64 ) LaTeX: \(seed=\operatorname{PBKDF2\!\text{-}\!HMAC\!\text{-}\!SHA512}(\operatorname{NFKD}(M),\operatorname{NFKD}(\text{“mnemonic”}\parallel P),2048.64)\).
The result is passed to BIP-0032 or a compatible deterministic system. BIP-0039 itself does not specify the derivation path, address type, network, or accounting model: the same seed can generate different sets of addresses with different paths and wallet agreements.
Passphrase and plausible deniability
Any passphrase, including an empty string, yields a formally valid seed and a separate deterministic wallet. This creates plausible deniability, but also makes backups fragile: loss, typos, different Unicode input, or incorrect passphrase layout won’t cause a cryptographic error—the user will simply see a different wallet.
Cryptanalytic evaluation
For a fairly generated 128-bit ENT, the mnemonic search space is on the order of 2^128; for a 256-bit ENT, it’s on the order of 2^256. Checksum doesn’t complicate the attack: it merely discards most random word strings as invalid. A mnemonic isn’t a password of words, but rather an encoding of a random secret.
N_{valid} = 2^{ENT} P_{undetected} = 2^{-CS} LaTeX: \(N_{valid}=2^{ENT}\), \(P_{undetected}=2^{-CS}\).
For 24 words, CS = 8, meaning that approximately one in 256 random errors can pass the checksum; for 12 words, CS = 4, meaning the probability of an undetected random error is approximately 1/16. The checksum does not correct errors or authenticate the origin of the phrase, and therefore should not be considered a defense against forgery or exfiltration.
PBKDF2 with 2048 iterations increases the cost of a single hypothesis check but does not increase entropy. If the attacker already knows the mnemonic and the passphrase is short, predictable, or taken from a dictionary, offline passphrase brute-force is practically the primary threat. Conversely, an unknown high-entropy mnemonic retains its strength regardless of the relatively moderate PBKDF2 parameter.
Historical lessons
Brainwallet: A Predictable Secret
Historical brainwallet compromises demonstrate why BIP-0039 explicitly requires computer-generated randomness. Services and attackers could pre-hash huge dictionaries of quotes, song lyrics, common phrases, and passwords, calculate the corresponding public keys, and automatically withdraw funds from the addresses they were deposited into. The reason isn’t the weakness of SHA-256 or the elliptic curve secp256k1, but the low entropy of the human-generated input.
Milk Sad: A weak source of ENT
The Milk Sad incident, disclosed in 2023, demonstrated a similar risk for deterministic wallets: vulnerable Libbitcoin Explorer implementations created wallets with predictable randomness based on 32-bit time. Since BIP-0039 only encodes the ENT, valid words and checksums do not save a wallet if the ENT can be recovered by brute-forcing a narrow range of time. This case is particularly important for generator auditing: compliance with the BIP-0039 format does not prove the cryptographic strength of the source material.
Backup compromise
Phishing “seed verification” forms, malicious browser extensions, cloud backup photos, and importing the passphrase into an unknown website transform the hacking task from cryptanalysis to simple secret copying. If the mnemonic is compromised, the BIP-0039 passphrase can restrict access, but it doesn’t eliminate the need to immediately generate a new independent seed on a trusted device and transfer the assets.
Specification limitations
| Limitation | Why does it arise? | Practical consequence |
|---|---|---|
| Dictionary dependence | PBKDF2 is fed with the mnemonic text, not the original ENT | Translating words changes the seed; the original language/dictionary must be stored |
| One-sidedness | The mnemonic is hashed when the seed is received. | An arbitrary BIP-0032 seed cannot be correctly represented by a BIP-0039 phrase. |
| Short checksum | CS is only ENT/32 | There is only limited error detection; no correction. |
| No versioning | The phrase does not carry information about the path/address format | Recovery requires knowledge of the derivation path and wallet policy; descriptor wallets mitigate the problem. |
The authors of BIP-0039 point to SLIP-0039 as a way to address some of the shortcomings. Unlike a single phrase, threshold-based secret sharing helps distribute storage risk, but introduces its own requirements for recovery procedures, share inventory, and interoperability between implementations.
Safe implementation methodology
- Obtain ENT only from a trusted operating system CSPRNG or hardware source with proper failure handling; never use time, counter,
Math.random(), custom phrase, or demo template. - Strictly adhere to bit splitting, SHA-256 checksum, 11-bit indexes, official dictionary, and NFKD. An endianess or normalization error will create an incompatible wallet.
- Validate the implementation with official test vectors, including a passphrase vector
TREZORand Unicode/Japanese cases; the test should compare ENT, mnemonic, and the resulting 64-byte seed. - Do not send mnemonics or passphrases to web interfaces, logs, telemetry, crash reports, or cloud synchronization. Consider any online BIP-0039 check a potential exfiltration of key material.
- When using a passphrase, create it as an independent, high-entropy secret and back it up separately. It cannot be “hinted” by words from the phrase, date, nickname, or project name.
- Document the derivation path, script/address type, network, and descriptors. A single phrase isn’t always sufficient for quickly and accurately detecting all historical UTXOs.
Minimal pseudocode
function entropy_to_mnemonic(entropy_bytes, wordlist):
ENT = bit_length(entropy_bytes)
require ENT in {128, 160, 192, 224, 256}
CS = ENT / 32
bits = bits_of(entropy_bytes) || first_bits(SHA256(entropy_bytes), CS)
return join(wordlist[integer(bits[i:i+11])] for i in range(0, ENT+CS, 11))
function mnemonic_to_seed(mnemonic, passphrase = ""):
password = UTF8_NFKD(mnemonic)
salt = UTF8_NFKD("mnemonic" || passphrase)
return PBKDF2_HMAC_SHA512(password, salt, 2048, 64)
The pseudocode is intentionally not a production library. In real-world software, consistent length checking, correct Unicode handling, not keeping secrets in memory longer than necessary, compatibility tests, and independent entropy source auditing are essential.
Conclusions
BIP-0039 is a successful standard for portable representation of a random secret, not a standalone “12- or 24-word security solution.” Its cryptographic security relies on four conditions: unpredictable ENT, strict adherence to the format and Unicode normalization, preservation of the secrecy of the passphrase, and sufficient entropy of the passphrase when used.
The key fact for a cryptanalyst: the format validity of a mnemonic is not equivalent to the strength of a wallet. Checksum verification, 2048 PBKDF2 iterations, and a 512-bit seed length do not compensate for a weak ENT generator, pattern reuse, or a human-guessable passphrase.
Sources
BIP-0039: mnemonic code for generating deterministic keys: https://dynet.ru/bip-0039-mnemonic-code-for-generating-deterministic-keys/
