seedroller
Generate a BIP39 mnemonic seed phrase from physical dice rolls, hardened with operating system RNG entropy.
The seedroller tool combines the randomness of real-world dice rolls with your operating system's random number generator (RNG) to produce a standard 24-word BIP39 mnemonic seed phrase for use in bitcoin wallets.
How it works
- Collect dice rolls — You roll a physical 6-sided die and type each result (1–6). A minimum of 100 rolls is required.
- Verify entropy — The roll distribution is checked to ensure it contains enough measurable entropy (see below).
- Mix entropy sources — Your dice rolls are concatenated with 32 bytes (256 bits) from the operating system RNG (
getrandom). - Hash — The combined input is hashed with SHA-256, producing exactly 32 bytes (256 bits) of entropy.
- Generate seed phrase — The 32 bytes are encoded as a standard BIP39 24-word mnemonic with checksum.
- Output the seed phrase — The 24 seed words, space separated, are written to standard output; the numbered word list and all other messages go to standard error and appear on your terminal as usual. This lets you capture the phrase in a shell variable or pipe it straight into the
keyderivertool to derive the master extended private key (xprv) and BIP380 descriptor account keys (BIP44/BIP84 path).
dice rolls (~258 bits) ──┐
├── SHA-256 ──> 256 bits ──> BIP39 (24 words) ──> keyderiver (master xprv + BIP380 account keys)
OS RNG (256 bits) ──┘
Either entropy source alone provides at least 256 bits, so the seed remains secure even if one source is compromised.
Entropy verification
Before generating the seed, the Shannon entropy of your dice rolls is validated:
| Check | Requirement | Why |
|---|---|---|
| Shannon entropy | ≥ 256 bits total | Calculated from the actual roll distribution, not just roll count. 100 uniform rolls give ~258.5 bits. Skewed distributions are rejected even if all 6 values appear. |
When you press Enter after 100+ rolls, the check runs. If it fails, the program tells you the current state (e.g. Insufficient dice entropy: 255.6 bits — minimum 256 bits required.) and lets you keep rolling until the requirement is met — a typical honest 100-roll session lands just under 256 bits, and ~10 extra rolls reliably pushes it over. The program only exits with an error if you end input early (EOF / Ctrl+D) with insufficient entropy.
Examples:
| Distribution | Total entropy | Result |
|---|---|---|
| All same value | 0 bits | Rejected |
| 2 values, even split | 100 bits | Rejected |
| 6 values, heavy skew [50,20,10,10,5,5] | ~206 bits | Rejected |
| 6 values, mild unevenness [18,18,17,17,15,15] | ~258 bits | Accepted |
| 6 values, uniform [17,17,17,17,16,16] | ~258.5 bits | Accepted |
Installation
This builds the release binary and installs it to ~/.cargo/bin/seedroller.
Usage
Normal mode (recommended)
Press keys 1–6 as you roll your die — each keypress registers immediately, no Enter needed. After 100 rolls, press Enter to finish once the entropy checks pass, or keep adding more rolls for extra entropy.
Capture or pipe the seed phrase
Only the seed words are written to standard output — everything else (prompts, the numbered word list, warnings) goes to standard error and still appears on your terminal. This lets you pipe the phrase directly into keyderiver:
|
or capture it in a shell variable:
SEED=
|
In both cases the seed phrase never appears on the command line or in your shell history.
Reproducible mode (testing only)
Skips the operating system RNG. The seed is derived only from your dice rolls, so the same rolls always produce the same seed phrase. A bold warning is displayed when this mode is active. Do not use this for real funds.
Help
Tests
Security notes
- This tool only verifies the entropy of your dice rolls, not their randomness. Randomness is critical for a strong seed value but can not be verified by this tool. You must ensure the randomness of your dice roles and the data generated by your operating system. See entropy vs randomness.
- Run in an ephemeral environment. For improved security, only run this on a local temporary system such as TAILS — a live operating system that runs from a USB stick, leaves no trace on shutdown, and keeps your seed phrase off your everyday machine.
- Startup sanity check. Before any key material is handled, the tool verifies the operating system RNG and monotonic clock actually work — every byte position of a 32-byte RNG draw must come back nonzero within 1024 draws, and the clock must advance across a short sleep (modeled on Bitcoin Core's
Random_SanityCheck()). The tool refuses to run on a system whose RNG appears broken. - Write down your seed phrase on paper. It is displayed on screen as a numbered list (standard error) and remains in your terminal scrollback — clear it with
clearwhen done. - Only the seed words go to standard output. When you capture them (
SEED=$(seedroller)) or pipe them (seedroller | keyderiver), the phrase never appears on screen — but a captured phrase lives in your shell's memory: do notexportthe variable (exported variables are visible to all child processes), andunsetit as soon as you are done.echois a shell builtin, so piping it does not expose the phrase in process listings. - Sensitive intermediate values are wiped with
zeroize. The main owned secrets (rolls,entropy, andphrase) are wrapped inZeroizing, so they are zeroized automatically when they go out of scope. The BIP39 mnemonic type already zeroizes on drop. - The crate forbids
unsafecode (#![forbid(unsafe_code)]). - Dependencies are minimal:
bip39,bitcoin,clap,getrandom,zeroize.
License
Licensed under either of
- Apache License, Version 2.0 (LICENSE-APACHE)
- MIT License (LICENSE-MIT)
at your option.