Creating a BIP-39 Seed Phrase by Hand with Dice

Overview

This guide describes how to generate a standard 12-word BIP-39 recovery phrase using nothing more than a 20-sided die, pencil and paper, and (optionally) an air-gapped computer for the checksum calculation. A 24-word phrase is also possible. See 128-Bit vs. 256-Bit Entropy.

Motivation

A Bitcoin wallet is only as secure as the randomness used to generate its seed phrase. If that randomness is predictable or flawed, an attacker may be able to reconstruct the seed and steal the funds. This is what happened in the Coldcard theft. A firmware bug unintentionally reduced the quality of the randomness used during seed generation firmware. The bug remained undiscovered for years until it was found by a bad actor using AI, and millions were stolen. This could potentially happen to any wallet that uses a random number generator. As a user, it is very difficult or impossible to audit thoroughly.

Generating the entropy yourself with physical dice removes the need to trust a hardware wallet's random number generator. By recording each roll and converting the results into binary, you know exactly where every bit of entropy came from.

The only step that cannot realistically be performed by hand is the SHA-256 checksum calculation required by the BIP-39 standard. Two approaches for generating the checksum are discussed.


Security Considerations

Before beginning:


Step 1 — Generate 128 Bits of Entropy

A 12-word BIP-39 mnemonic begins with 128 bits of random entropy.

Each accepted d20 roll contributes 4 bits.

Roll a 20-sided die 32 times.

For each roll:

This rejection sampling ensures every 4-bit value is equally likely.


Step 2 — Convert Each Roll to Four Bits

Each resulting value is written as a four-bit binary number:

d20 Roll Value (Roll − 1) Binary
1 0 0000
2 1 0001
3 2 0010
4 3 0011
5 4 0100
6 5 0101
7 6 0110
8 7 0111
9 8 1000
10 9 1001
11 10 1010
12 11 1011
13 12 1100
14 13 1101
15 14 1110
16 15 1111
17 Reroll
18 Reroll
19 Reroll
20 Reroll

After 32 accepted rolls you will have exactly 128 bits.


Step 3 — Compute the Checksum

A 12-word BIP-39 mnemonic requires four additional checksum bits.

These are defined as:

The first four bits of the SHA-256 hash of the 128-bit entropy.

This produces:

Several methods for obtaining these checksum bits are described later.


Step 4 — Append the Checksum

Append the four checksum bits to the end of the entropy.

Example:

128 entropy bits

10100110...

+

4 checksum bits

0110

↓

132 bits total

Step 5 — Split into Eleven-Bit Groups

Divide the 132-bit stream into groups of 11 bits.

You should obtain exactly 12 groups.

Example:

01101010110
11010100101
00011100110
...

Each 11-bit value represents an integer between 0 and 2047.


Step 6 — Look Up the Words

Use the standard BIP-39 English word list. Download the list here, which includes each word and its binary equivalent.

Each 11-bit value corresponds to one word.

For example:

00000000000 → abandon
00000000001 → ability
...
11111111111 → zoo

The resulting twelve words form your recovery phrase.


Checksum Options

Option 1 — Air-Gapped Computer

Boot a trusted operating system such as Tails from a USB drive.

Disable networking and do not enable Persistent Storage.

Run a standalone SHA-256 implementation (see the python example below).

Compute:

checksum = first four bits of SHA256(entropy)

Append those bits to the entropy.

Python Example

Create a file called checksum.py.

import hashlib

bits = "00000111110001..." #128-bit binary string

entropy = int(bits, 2).to_bytes(16, "big")

print("Checksum:", f"{hashlib.sha256(entropy).digest()[0] >> 4:04b}")

In a terminal, run python checksum.py.


Option 2 — Guess-and-Check the Final Word

The final BIP-39 word contains:

Since there are only 16 possible checksum values, there are exactly 16 possible final words.

Procedure:

  1. Generate the first eleven words normally.
  2. Determine the first seven bits of the final word.
  3. Construct all sixteen possible last words.
  4. Import each candidate into an offline BIP-39-compatible wallet.
  5. Exactly one should be accepted as having a valid checksum.

This avoids using an air-gapped computer.


Verifying the Finished Mnemonic

Before storing funds:

A transcription error made during generation is much easier to fix before funds are deposited than years later during recovery.


128-Bit vs. 256-Bit Entropy

A 12-word BIP-39 mnemonic contains 128 bits of entropy, while a 24-word mnemonic contains 256 bits of entropy. Even 128 bits is considered extraordinarily secure: an attacker would need to search approximately (2^{128}) possible seeds, or about 340 undecillion (340 followed by 36 zeros). To put this in perspective, this number is so large that it is far beyond the reach of all existing and foreseeable computing technology. A properly generated 128-bit seed is therefore regarded as practically impossible to brute force and is sufficient for virtually all personal and professional use. A 256-bit seed increases the search space to (2^{256}), providing an even larger security margin, but for most users this additional security offers little practical benefit because 128 bits is already overwhelmingly secure.

If you prefer a 24-word mnemonic, the process is almost identical. Instead of generating 128 bits, generate 256 bits by making 64 accepted d20 rolls (again rerolling any result from 17–20). Convert each accepted roll into four bits using the same lookup table, producing a total of 256 entropy bits. The checksum is now 8 bits (the first byte of the SHA-256 hash of the entropy) instead of 4 bits, resulting in 264 total bits. Divide the bit stream into twenty-four 11-bit groups and look up each value in the standard BIP-39 word list to obtain the final 24-word recovery phrase.