A seed phrase is a human-readable encoding of a random number. Your wallet stretches that number into a 512-bit seed (BIP-39), builds a tree of keys from the seed (BIP-32), and picks keys from the tree using standard paths (BIP-44 and related). Anyone who has the words, plus the passphrase if you set one, can rebuild every key in that tree on any compatible wallet. That makes storage the part that matters most.
BIP-39: from randomness to words
- The wallet generates entropy: 128 bits for 12 words, up to 256 bits for 24 words.
- It appends a checksum, the first
entropy_bits / 32bits ofSHA-256(entropy). That's 4 bits for 12 words and 8 for 24. - It splits the result into 11-bit chunks. Each chunk is an index into a fixed list of 2048 words.
| Words | Entropy | Checksum | Total bits |
|---|---|---|---|
| 12 | 128 | 4 | 132 |
| 24 | 256 | 8 | 264 |
The words are only an encoding, so the security comes from the entropy. 128 random bits is already far beyond brute force. The checksum means most typos are caught, but not every one. And because the last word partly encodes the checksum, you can't pick all 12 words yourself.
The words then become a seed through a deliberately slow hash:
seed = PBKDF2-HMAC-SHA512(
password = mnemonic (NFKD-normalized),
salt = "mnemonic" + passphrase,
iterations = 2048,
length = 64 bytes
)
The optional passphrase (sometimes called the 25th word) goes into the salt. Every passphrase produces a valid, different wallet, and there is no "wrong passphrase" error. Lose the passphrase and the funds are gone even if you still have the words.
BIP-32: one seed, a tree of keys
The master key comes from HMAC-SHA512(key = "Bitcoin seed", data = seed). The left 32 bytes are the master private key and the right 32 bytes are the chain code. Each child key is derived from its parent key, its chain code, and an index.