Reference · Bitcoin seed generation

Dice to seed

Bitcoin wallets that generate seeds from dice rolls all use the same recipe. This documents it, verifies it against every implementation, and looks honestly at what imperfect dice actually cost.

First published
2026-08-03
Scope
Dice → BIP-39
Method
Source-read
Status
Living document
The short version
1
recipe, shared across the ecosystem
0
mismatches over 4,000 sequences run against Coldcard
2.4×
bias before a 24-word seed drops to 128 bits
11
bits a realistically bad die costs, 245 remain

1Why dice at all

Every Bitcoin wallet has to produce a seed from somewhere, and almost all of them use the device's own random number generator. You are then trusting that generator, and there is nothing in its output you can inspect to tell whether it did its job. A sound generator and a broken one produce results that look exactly alike.

Dice are for when you would rather not take that on trust. The rolls are the only input, so the seed is a pure function of something you watched happen, reproducible elsewhere to confirm the device did what it should.

A seed the device chose, you can only trust. A seed you rolled yourself, you can verify.

Note what that does not claim. Verifying needs a computer, because the SHA-256 in this recipe cannot be done by hand at any speed. Coin flips are the format that survives a pencil: 128 or 256 flips are already BIP-39 entropy, so all but the final word can be read off a printed table with no arithmetic at all, and only the checksum word needs a hash. That is exactly the word the devices in the addendum offer to compute, and it is why their paper-table methods drop the hash rather than adopt it. This recipe buys reproducibility, not hand-verifiability.

2How it works

50 rolls makes a 12-word seed. 99 rolls makes a 24-word seed. Every implementation listed below does exactly this. A formal specification with test vectors is at the end.

1

Roll a die 99 times

This example follows a 24-word seed the whole way through.

2

Write the digits down

655152231316521321611331544441236164664431121534415633526456254462245546236542364246312613322234612
3

Hash the digits once with SHA-256

>>> sha256("655152231316521321611331544441236164664431…") 51531761ec7a738946e0b9f46bb11320a695495430e345c14f01ad8b3b898a6d

The quotation marks matter: the digits go in as text. The result is always 32 bytes, regardless of how long the input was. For a 12-word seed, only the first 16 are used.

4

Write those bytes out in binary

5101010001530101001117000101116101100001ec11101100

Each byte is eight bits. Nothing has changed yet, the same hash, written differently.

5

Collect the bits into groups of 11

010100010101001100010111011000011
6

Look each group up in the BIP-39 word list

01010001010650+1651eyebrow
100110001011221+11222obvious
110110000111731+11732such
110110001111735+11736suggest
… 20 more

Each group is a number from 0 to 2047. The +1 accounts for printed word lists, which start counting at 1 rather than 0. The final group carries a checksum.

7

Build the final word

The entropy ends in 6d, and 23 words have used all but its last 3 bits01101101
Hash the entropy itself, and keep the first bytesha256(entropy) =867da839c3…
That byte in binary is the checksum10000110
3 left over plus 8 checksum makes the last 11 bits101100001101414+11415radio

This is why the last word cannot be chosen freely.

8

Read off the words

1eyebrow2obvious3such4suggest5poet6seven7breeze8blame9virtual10frown11dynamic12donor13harsh14pigeon15express16broccoli17easy18apology19scatter20force21recipe22shadow23claim24radio

Any implementation of this recipe gives the same 24 words from the same rolls.

Why 50 and 99 rolls

A die has six faces, so N rolls produce 6N possible sequences. The only question is whether that is as many as there are possible seeds.

Possible dice sequencesPossible seeds
50 rolls → 12 words650 ≈ 8.1 × 10382128 ≈ 3.4 × 1038129.2 bits, over the 128 needed
99 rolls → 24 words699 ≈ 1.1 × 10772256 ≈ 1.2 × 1077255.9 of 256 bits

50 rolls comfortably exceeds what a 12-word seed needs. 99 rolls lands at 255.9 bits against 256, a 100th roll would push past what a 256-bit seed can hold.

Bit figures throughout assume SHA-256 behaves as an ideal randomness extractor, so N rolls carrying H bits each yield min(256, N·H). Standard practice, and the margins here are far too large for the difference to matter.

3Who implements it

Each was read from source at a pinned commit, not from documentation.

ImplementationLanguageSource
Signing devices and air-gapped apps, where seeds get generated
ColdcardMicroPythonColdcard/firmware @ 3238f6fd
KernCodudex/Kern
KruxMicroPythonselfcustody/krux
SeedSignerPythonSeedSigner @ 0.8.7
AirGap Vault
Default mode, 24 words only
TypeScriptairgap-vault @ aa50b7f
Software tools, for independently checking one
Gordian seedtool-cliC++BlockchainCommons/seedtool-cli, CLI
Gordian Seed Tool
iOS app, 12 words only
SwiftGordianSeedTool-iOS @ 1.6
iancoleman.io
Hex or Base 10 mode
JavaScriptiancoleman/bip39, web or signed download
Seed ToolJavaScriptBitcoinQnA/seedtool, web or signed download
Two carry limits worth knowing before you rely on them. AirGap Vault requires 99 rolls and produces only 24 words, with no 50-roll path. Gordian Seed Tool for iOS is the mirror image: it always truncates to 16 bytes, so its dice mode produces only 12 words however many times you roll.

If the wallet you are looking for is not in this table, start with the addendum. Keystone, BlueWallet, BitBox02, Blockstream Jade and Foundation Passport all offer something for hand-rolled seeds, but not this recipe.

Appearing in this table is not a recommendation

Coldcard is here because its construction is the one several of these projects converged on, and because it is the implementation this document checks the recipe against. That is a statement about one hashing routine, not about the device. After the entropy failure disclosed on 1 August 2026, set out in §7, this document treats Coldcard as a reference for the construction and as part of its history, not as a live option for new storage.

The same separation applies to every row. What is verified here is that a given implementation turns your rolls into the same seed as the others. Nothing about that speaks to the rest of a device, its firmware, or the parts of it a dice roll never touches.

Run the web tools offline

The two browser tools ship signed standalone builds with PGP signatures: iancoleman's bip39-standalone.html and Seed Tool's index.html. A URL is fine for a try. For anything real: download, verify, disconnect.

One caveat, and it matters: iancoleman.io reproduces the recipe in its Hex and Base 10 modes. Its Dice mode uses a different approach and gives a different seed.

Many implementations, many languages, one recipe, with no specification, but a reference implementation several of these projects deliberately matched.

This is not blind convergence, and presenting it as such would be misleading. iancoleman.io functions as the de-facto reference: seedtool-cli's source carries the comment “Compatibility with iancoleman.io/bip39”, SeedSigner's docstring cites iancoleman and Seed Tool as its model, and Seed Tool is code-derived from iancoleman. At least three deliberately targeted it. Krux and Kern share an author, and both Gordian tools come from Blockchain Commons, so treat each of those as one lineage.

The recipe has also left Bitcoin. LumenSigner, a SeedSigner fork for Stellar, carries the function across essentially unchanged. That is worth knowing for what it says about how a convention spreads: by being copied, not by being specified.

Roll once, verify anywhere. The same rolls give the same seed on any of these, so checking your wallet against one is a real cross-implementation test, not the same code twice.

4Does dice quality matter?

The honest measure is min-entropy, conservative, assuming an attacker knows your die's exact bias and always guesses the most likely sequences first. Every figure below already assumes that worst case.

24-word (99 rolls)    12-word (50 rolls)

A perfectly fair die 255.9 / 128.0 bits

One face 8% more often than it should 244.9 / 123.7 bits

20% more often, visibly odd 229.9 / 116.1 bits

50% more often, obviously defective 198.0 / 100.0 bits

110% more often, grossly loaded 149.9 / 75.7 bits

Half of all rolls, a trick die 99.0 / 50.0 bits

Bars scaled to 256 bits. Solid line: the 128-bit “secure forever” threshold. Dashed line: a 100-bit practical floor, still far beyond any attacker. The 24-word bar clears both until the die is a trick die.

For a 24-word seed to fall even to 128 bits, one face would have to come up 40.8% of the time, about two and a half times its fair share. Not a slightly warped die; one you would notice in an evening of board games.

The detection paradox

Take a die favoring one face 8% more than it should. It costs a 24-word seed 11 bits, leaving 245 of 256. To detect that bias with statistical confidence you would need roughly 6,200 rolls.

You would roll for hours to find a defect worth a rounding error. And the arithmetic runs the other way too: any bias large enough to matter is large enough to notice casually.

The ten-dice-in-a-box method

A common recommendation is to put ten dice of any quality in a box, shake, and read them left to right. It helps, for a reason worth understanding: after a shake, which physical die lands in which position is itself random, so each reading is drawn from the average of the pool's ten distributions, and averaging independent biases pulls that mixture toward uniform.

Dice qualityOne die, repeatedlyPool of tenRegained
Very good2.4962.556+0.060
Ordinary2.3332.501+0.168
Poor2.1182.421+0.303
Bad1.8892.314+0.425
Min-entropy in bits per roll; a perfectly fair die scores 2.585. Modeling caveat: this treats each reading as an independent draw from the averaged distribution. A shake reads each die exactly once, so a block of ten is slightly more predictable than the model implies, negligible for mild bias, more material for badly skewed dice. Figures are means over randomly-generated dice, not a guarantee for yours.
The honest limit

Averaging cancels bias only when the biases differ. Ten identical dice from one bag sharing a manufacturing defect average to exactly the same defect, simulated, and the gain is precisely zero. Use a mixed handful if you can.

The bigger win is speed: ten shakes instead of 99 rolls. Tedium is a real risk: bored people start placing dice by hand. One caveat: shake hard, or faces repeat between readings.

What to actually do

  1. Don't test your dice. The arithmetic above shows it cannot pay off.
  2. If you're worried, choose 24 words. The extra 49 rolls buy enormous headroom.
  3. The ten-dice box method is a good one, mostly for speed, with a real if modest bias-averaging bonus. Mixed handful, vigorous shake.
  4. Just roll normally. Toss it so it tumbles, let it settle. Casinos make dice hit a studded back wall because they face professionals deliberately controlling throws for money, you have no reason to cheat yourself.

5Why not roll more than 99?

Advice to roll 120 or 150 times circulates, on the theory that extra rolls buy margin against an imperfect die.

With a fair die there is a ceiling. A 24-word seed is 256 bits, and 99 fair rolls already deliver 255.9 of them. Roll 150 times and you feed 388 bits into a hash that can only emit 256, the surplus is discarded.

With a biased die, extra rolls do restore what bias costs, this is worth stating plainly rather than pretending otherwise:

If your die is99 rolls givesRolls to reach a full 256
Fair255.9 bits100
8% biased244.9 bits104
20% biased229.9 bits111
50% biased, obviously defective198.0 bits128

So the argument against rolling more is not that it does nothing. It is that the thing it buys back is not worth buying: 245 bits against a 100-bit floor. More rolls also means more tedium, and tedium produces the rushed throws that are a far bigger risk than any manufacturing tolerance.

99 is not a floor to exceed for safety; it is the number that fills the seed.

6Guarding against bad rolls

None of the above addresses a different problem: someone who types the same digit fifty times, or an obvious pattern. Implementations differ on whether they try to catch this.

ImplementationGuard
KruxLive Shannon-entropy meter against the 128/256-bit threshold, arithmetic-pattern detector, distribution graph, all overridable
ColdcardRejects if any single face exceeds 30% of rolls when generating from dice. No check at all on the path that mixes rolls into an existing seed.
KeystoneWarns if any single face exceeds 30% of rolls, but the warning is advisory only and Confirm stays live
Seed ToolRefuses fewer than the minimum roll count
SeedSigner, KernNone beyond enforcing the roll count
AirGap VaultNone beyond the 99-roll minimum, plus an explicit refusal to hash an empty string
BlueWalletNone, and no minimum either; under-rolling silently tops up from the phone's RNG after a dialog
Gordian seedtool-cliNone, it does not enforce a roll count either, and will derive a seed from five rolls
A guard you generate under is not a guard you mix under

Where a device checks your rolls at all, it may only do so on the path that generates a seed from dice alone. Coldcard's checks do not run on the path that mixes rolls into a seed it already made, and that is the path popular third-party guides tend to point at. Mixing also costs the property dice were for, which §7 takes up.

Roll-count enforcement is the guard that has actually mattered. Keystone shipped a defect from its first dice release until version 2.5.0 in June 2026: the 24-word path had no roll-count check, so 50 rolls carrying about 129 bits could mint a phrase presented as 256-bit. Note also that Keystone requires 100 rolls for 24 words rather than 99, while its own documentation still says 99.

Why the obvious guard doesn't work

Both common approaches, a face-frequency limit and a Shannon-entropy score, measure which faces appeared. Neither sees what order they appeared in.

What you typedShannonTop faceColdcard 30%Compression
666666…0.000100%caughtcaught
121212…1.00050.5%caughtcaught
123123123…1.58533.3%caughtcaught
123456123456…2.58417.2%passescaught
a real fair sequence2.50925.3%allowedallowed

Both scoring approaches share the same gap, they measure which faces appeared, not in what order.

Krux is the exception, and only partly: alongside its Shannon meter it runs a derivative-based check that flags arithmetic progressions, so it catches the row below that the scores alone do not. A face-frequency limit or an entropy score, on its own, does not.

Rolling 1-2-3-4-5-6 repeatedly gives every face its exact fair share, so it scores essentially maximum while being entirely predictable. A compression check sees it, because repetition compresses whether or not the distribution looks uniform.

And it can't detect a biased die anyway

With only 50 or 99 samples the estimate is far too noisy. At a threshold tuned to falsely warn 1 honest user in 1,000, at 99 rolls a Shannon score catches a die favoring one face 50% more often just 3.9% of the time. A related subtlety: a fair die does not score 2.585.

Fair-die averageSpread to 0.1st pctUsable threshold
99 rolls2.5480.114 bits2.434
50 rolls2.5110.235 bits2.276

Coldcard's fixed 30% threshold shows the same tension from the other side: it falsely warns 3.4% of honest users at 50 rolls, against 0.33% at 99.

This is the detection paradox again, and it resolves itself: these checks miss exactly the biases that don't matter. A roll-quality guard should catch patterned input, not judge your dice. Compression does that better than either approach, with fewer false alarms.

7What you still have to trust

Dice very nearly remove trust from seed generation. Not entirely: no seed produced on a device somebody else built can be perfectly trustless. But what is left over is a narrow and specific residue, not the broad act of faith that “trusting your hardware wallet” usually describes. Once you have tested the device's arithmetic often enough to satisfy yourself, and checked its answer, essentially nothing about the seed itself still rests on the manufacturer's word. How many runs count as enough is a real question, and it is taken up below.

This section is about the residue, and it is deliberately unflattering about it.

The claim a dice seed makes

When a device shows you 24 words after 99 rolls, it is asserting exactly one thing:

These words are the BIP-39 encoding of SHA-256 over the 99 digits you just entered.

That assertion is falsifiable. There is one correct answer, it does not depend on anything the device knows, and anyone holding the rolls can compute it. If the device produces anything else, it is caught.

Testing the device costs you nothing

The useful consequence is that you can check the device as often as you like, with rolls that protect nothing. Type in fifty arbitrary digits, read the words off the screen, and compute the same thing somewhere else. Then do it again with different digits. The input is throwaway, so this can be done on any computer, connected, carelessly, as many times as your patience allows.

Each pass rules out a little more. A device that returns the expected answer run after run, for inputs it had no way to anticipate, is behaving as a deterministic function of what you typed and nothing else. Enough passes and this device implements the recipe faithfully stops being something you assume about the manufacturer and becomes something you measured yourself.

After enough test runs the device is not something you trust. It is a tool you have checked, running the same arithmetic any other tool runs.

This is the part people miss about dice. The value is not only that one seed can be verified. It is that the device's behavior can be verified, repeatedly and for free, without a single real seed ever leaving the room.

Why “to a rough approximation”

Test runs cannot strictly prove the run that matters, because a device only has to tell the runs apart. The cheapest version of this is to answer honestly the first few times and then defect, which costs an attacker a counter and nothing else. Two or three passes buy you very little. This is the argument for testing more than feels necessary, and for not doing all your testing in one sitting on a fresh device.

Beyond a counter, a device would need some other trigger to pick its moment: a clock, a particular roll pattern, a state it can only be in once. Each is a narrower and stranger thing to build than a device that is simply wrong, and you can narrow it further by making the real run look like all the others.

That residue does not get closed by checking your real seed somewhere else. Doing so opens a larger hole than it fills, for reasons set out below. It is accepted knowingly, in exchange for never entering the real rolls into a second machine at all.

What testing settles, and what it leaves open

QuestionWhy
Did the device use my rolls, and only my rolls?settledThe recipe has no free parameters. There is nowhere to mix in an extra byte without changing every word.
Did the device implement the recipe correctly?settledA truncation error, a remapped 6, a stray newline: each changes the output completely.
Did I enter the rolls I wrote down?settledA mistyped digit changes every word. Where the device lets you enter the rolls again, repeating them and comparing catches this without involving a second machine.
Is the device's random number generator sound?not askedA pure dice seed never touches it. That is the point of the exercise.
Are my dice fair?openNothing in the output reveals the physical dice. See §4: the cost of imperfect dice is small enough to ignore.
Did the device keep or transmit a copy of my seed?openCorrectness and confidentiality are unrelated. A device can compute the right answer and still copy it.
Will the device sign with the seed it displayed?openA separate question, answered by deriving an address independently and comparing.
Is the device running the firmware that was published?openA separate question, answered by signed releases and reproducible builds.
The limit worth stating twice

A compromised device passes this check. Verification catches a device that lies about your seed. It cannot catch one that computes your seed correctly and also keeps a copy.

Everything protecting you there is separate: no wireless hardware, an air gap you actually maintain, signed firmware, a supply chain you have some reason to believe in, and physical control of the device. Dice make the arithmetic checkable. They do not make the machine trustworthy.

Two checks that get confused

These sound alike, prove very different things, and only one of them is a good idea.

Testing the deviceChecking your real seed elsewhere
InputThrowaway rolls, or the published vectors (§9)Your actual rolls and your actual words
ProvesA property of the deviceA property of one event
How oftenAs often as you likeNot recommended at all
Cost if the checker is compromisedNothing. The input was worthless.Your seed, and everything it holds
Do not verify a real seed on a second machine

It is the obvious move, and it is a bad trade. To check the seed protecting your funds you have to type your real rolls into another computer, and that computer now knows your seed. You would be exchanging a small residual doubt about a device you have tested for a fresh and unbounded exposure to one you have not.

Working offline does not fix this. An air-gapped machine can still keep what you typed, and you have no way to know what it kept or who reads it later. The risk is not the network, it is the second copy.

This is precisely what test runs are for. They establish the device as a faithful tool using inputs worth nothing, so that the seed that matters is only ever entered once, in one place.

Verifying means trusting the checker instead

Comparing the device against a second implementation replaces one trusted program with another. That is only progress if the second one is independent and smaller, so it is worth being deliberate about:

The AI writes the tool. The tool does the checking.

Never type dice rolls into a chat prompt. Not real ones, and best not throwaway ones either, so the habit never forms. What you are asking a model for is source code, which you then run yourself on your own machine. It never needs to see a single die.

The distinction is not pedantic. A chat prompt is a network service that transmits, logs and retains. It is the worst place in this entire document to put anything touching a seed, worse than the web tools §3 tells you to download rather than visit. An AI-written checker is only independent because it runs where you are; typed into the chat, the rolls have already left.

And the seed that matters goes into neither. It is entered on the device once, and nowhere else. The checker exists to test the device, using inputs worth nothing.

Make an AI checker prove itself first

A model will produce this in seconds and can be fluently, confidently wrong. The specific failure to watch for is that it applies the 6-to-0 remap unprompted, because iancoleman's Dice mode is well represented in training data and looks like the obvious reading of “dice entropy”. It may also reach for a wallet library rather than implementing the specification, which quietly reintroduces the lineage problem you were trying to escape.

So make it earn the role. Have it reproduce the official BIP-39 test vectors before you show it a single die: a checker that cannot encode a known entropy value correctly cannot tell you anything about your rolls. Then have it reproduce the vectors in §9, and cross-check its output against a second implementation such as Trezor's python-mnemonic.

Validated that way it is a strong extra witness, and a cheap one. Taken on its word it is worse than no check at all, because it will agree with you either way.

Mixing gives the property away

Some devices offer to blend your rolls into a seed the device generated, rather than using the rolls alone. The result is then hashed from an input the device chose, so the check described in this section no longer works: you cannot reproduce a seed whose starting value you were never shown.

This is a genuine trade rather than a mistake: mixing protects you if your dice turn out to be terrible, at the cost of the one property that made dice worth using. If you want a verifiable seed, use the dice-only mode.

The counter-argument, stated fairly

Not everyone thinks the trade is worth it. Foundation, who make Passport, ship the final-word feature but advise against dice, and their then-head of strategy argued publicly in 2024 that they had heard of zero compromised seeds caused by hardware-wallet RNG failures, against repeated cases of users losing funds to botched dice procedures, one of them having used fewer than ten rolls.

The half about botched procedure stands, and it is the real objection: dice move the risk onto the human, and humans skip steps. The other half was an argument from absence of evidence, and the evidence arrived. On 1 August 2026 Wizardsardine disclosed that Coldcard had shipped a broken entropy path since 2021, across the Mk2, Mk3, Mk4, Mk5 and Q. The defect has been fully verified, wallets were drained at scale, and most of the funds that were exposed are already gone. Coinkite issued emergency firmware on 31 July, which fixes generation from that point on and repairs nothing already generated.

What survived it

The disclosure draws one exception: seeds generated from 50 or more fair dice rolls were not affected. That is this document's argument, tested against the largest hardware-wallet entropy failure to date and coming through it. A seed the device chose was compromised by a defect its owner had no way to see. A seed its owner rolled was not.

The exception is narrow and worth stating exactly. It covers the seed, not the device. The disclosure is explicit that other features remain broken and that dice rolls do not protect you there.

Stated as a personal post on a third-party forum rather than company policy. The procedural half is undiminished, and the specific failure it describes is one the better implementations already prevent by refusing to proceed below the required roll count.

The bottom line

Generating a seed on any device normally requires trusting it on two counts: that it produced a good secret, and that it kept it. Dice plus verification eliminate the first and leave the second untouched.

Verification proves the device did the right thing. It cannot prove the device did nothing else.

What is left is narrow. Not did this device make a good secret? but did it keep the one I made? That is a single, well-understood question, and it is the one an air-gapped signing device is built to answer: no wireless hardware, no persistent storage, nothing to carry a secret out on. Turning the broad question into that narrow one is the whole benefit on offer, and it is a large benefit. It is simply not the same as zero.

8Verify it yourself

By hand, no programming, about ten minutes

  1. Take the published 99-roll example:
    655152231316521321611331544441236164664431121534415633526456254462245546236542364246312613322234612
  2. Go to iancoleman.io/bip39, ideally a downloaded offline copy.
  3. Tick Show entropy details.
  4. Set the entropy type to Hex, not Dice.
  5. Paste the digits and set Mnemonic Length to 24 Words.
  6. You should get: eyebrow obvious such suggest poet seven breeze blame virtual frown dynamic donor harsh pigeon express broccoli easy apology scatter force recipe shadow claim radio
Never with a real seed

Use the published example above, or rolls of your own that protect nothing. Do not enter the rolls or words of a seed holding real funds into any second tool, offline included. Every copy is another place it can leak from, and an air-gapped machine keeps what you type just as well as a networked one.

Everything worth learning here is learnable from throwaway inputs. See §7.

With your own AI assistant

The goal is a checker you can run, not an answer from a chatbot. Ask it for code, run that code locally, and keep dice rolls out of the conversation entirely. Everything the model needs is in this page already.

Prompt

1. Implement BIP-39 from the specification, without using any wallet's code or library, and prove it works by reproducing the official BIP-39 test vectors. Show me that before going further.
2. Explain how dice rolls become seed entropy in this construction, is the input hashed as text, or converted numerically?
3. Reproduce the two test vectors in §9 with your implementation, then separately cross-check them against Trezor's python-mnemonic.
4. Check each implementation listed in §3 against its own source. Do they agree?
5. For each one, determine specifically whether it rewrites a 6 to a 0 before hashing, and show the line that does or does not.
6. Using min-entropy, compute what a biased die costs a 12- and 24-word seed, and how many rolls would be needed to detect that bias.

Step 1 is not optional. An unvalidated checker is not a second opinion, it is a second guess. Requiring the official vectors first is what makes the rest of the answer worth anything, and it catches the common failure of a model applying the 6-to-0 remap on its own initiative.

Do not let it answer step 4 with a keyword search. Searching firmware for “dice” case-insensitively drowns in the word indices; searching with word boundaries misses vendors whose dice support lives in a published PDF rather than in code. Require it to read the seed-creation path, the release notes, and the vendor's own documentation, and to say which of the four categories in §3 applies.

Tell it explicitly not to evaluate the result by testing whether the output looks random. Hashing anything produces output that passes randomness tests, so such tests cannot detect a weak seed.

What ships with this page

The backing material sits in the repository beside this document, so none of it has to be taken on description alone. Only verify_constructions.py is standard library only; the rest need pip install mnemonic embit==0.8.0 in a virtual environment.

FileWhat it establishes
evidence/verify_constructions.pyStandard library only. Reproduces five official BIP-39 vectors as a self-test before asserting anything, then recomputes both vectors in §9, the competing 6-to-0 construction, and the paper-table mapping from the addendum. Run it from evidence/; it reads the wordlist from the working directory.
evidence/wallet-dice-survey.mdThe source reading behind §3 and the addendum, with the pinned commit each classification came from, and the method any further wallet has to be surveyed by. Kern is classified from source but is not yet written up there.
dice_bias_analysis.pyThe min-entropy figures in §4.
dice_shannon_scoring.pyWhy the Shannon-scoring guard discussed in §6 does not catch a bad die.
dice_tendice_box.pyThe ten-dice-in-a-box recommendation evaluated in §4.

9Reference: the construction

There is no BIP for this. What follows is not a proposal for one. It is a description of what the implementations in §3 already do, written down so it can be checked against them.

INPUT   rolls : string of ASCII digits '1'-'6'
                len(rolls) == 50  ->  12-word seed
                len(rolls) == 99  ->  24-word seed

STEP 1  entropy = SHA256(rolls.encode('ascii'))          # 32 bytes
STEP 2  if 12-word:  entropy = entropy[0:16]             # 128 bits
STEP 3  mnemonic = bip39_encode(entropy)                 # BIP-39, English
                                                         # indices are 0-based: 'abandon' == 0

NOT     no 6 -> 0 remap; the digit 6 is hashed as the character '6'
        no base-6 or numeric conversion of the roll string
        no bit-packing or bias-correction encoding
        no separators, padding, or trailing newline in the input

Test vectors

Value
50 rolls → 12 words
rolls65515223131652132161133154444123616466443112153441
SHA-2566cb09af855050dcde6fe2adc3181c250982011e2cf17821cbed56a908ec527c3
entropy (16 B)6cb09af855050dcde6fe2adc3181c250
mnemonichole luggage safe present express tragic orbit shed switch metal identify path
99 rolls → 24 words
rolls655152231316521321611331544441236164664431121534415633526456254462245546236542364246312613322234612
SHA-256 / entropy51531761ec7a738946e0b9f46bb11320a695495430e345c14f01ad8b3b898a6d
mnemoniceyebrow obvious such suggest poet seven breeze blame virtual frown dynamic donor harsh pigeon express broccoli easy apology scatter force recipe shadow claim radio

A correct implementation reproduces both. If yours does not, the most likely cause is a 6→0 remap or a numeric conversion applied before hashing.

10Known analyses

Published analyses of these implementations that we are aware of.

Absence is not evidence

This list reflects what we know of, not what exists. An implementation missing from it has not been shown to be unreviewed, only that we are unaware of a published analysis. If you know of one, or write one, it belongs here.

We reproduced the trace's figures independently before listing it.

11Addendum: other dice methods

Everything above concerns one construction. This addendum covers the rest of the landscape, for readers checking a specific wallet rather than the recipe itself.

Ask a sharper question than “does it support dice?”

Almost every wallet lets you type in a recovery phrase, so almost every wallet can receive a dice-derived seed you worked out somewhere else. Answering yes on that basis makes the question meaningless. The useful question is what the device itself does, and there are three answers here beyond the recipe above.

This distinction is easy to get wrong, in two specific ways. Searching firmware for dice arithmetic, finding none, and concluding “no dice support” misclassifies BitBox02, Jade and Passport, all of which ship a feature built for hand-rolled seeds while two of the three vendors publish dice instructions themselves.

The second trap is subtler. Reading the seed-generation path, finding a call to the system random number generator, and stopping there misclassifies Sparrow, whose last-word calculator sits on the seed-entry path and whose own documentation describes neither of the two features that put it here. The affordance is not always where the entropy is, and it is not always written down.

Dice, but a different recipe

These take your rolls and do the arithmetic themselves, but not this arithmetic. Each is internally consistent and none is broken. They simply produce a different wallet from the same rolls, so they cannot be used to check each other.

The most common divergence is a single character. A competing convention rewrites every 6 to a 0 before hashing, so the six faces read as 0 to 5 rather than 1 to 6. That one substitution is not a subtle difference in the result: run the 99-roll example from §2 through both conventions and the two 24-word phrases have no words in common at all. They agree only if you roll no 6 in the entire sequence, which at 99 rolls happens about once in 69 million.

ImplementationWhat it does insteadSource
Keystone
Hardware
Rewrites every 6 to 0, then the same SHA-256 and truncation. Deliberately matches iancoleman's Dice mode.keystone3-firmware @ 3.0.2 (the 24-word gate is gui_model.c L497)
BlueWallet
Mobile app
No hashing at all. Packs rolls into bits, 0-indexed, and fills any shortfall from the phone's RNG.BlueWallet @ 8.0.1
iancoleman.io
Dice mode only
Rewrites 6 to 0; default sub-mode does not hash at all.iancoleman/bip39 @ de71c22
AirGap Vault
“Coldcard” mode
Rewrites 6 to 0. Coldcard does not do this, so the setting does not do what its name says.airgap-vault @ aa50b7f
Two ways to get this wrong that look like getting it right

A setting named after a wallet is not the same as that wallet. AirGap Vault's dice screen offers a mode labeled “Coldcard”. It applies the 6-to-0 rewrite, which Coldcard's firmware does not. Choosing it because you own a Coldcard gives you a seed your Coldcard will never reproduce. Its other mode is the standard recipe.

Matching roll counts prove nothing. The Elixir library RooSoft/bitcoinlib demands exactly 50 or 99 rolls, the recipe's own signature numbers, then reads the digits as a base-6 number and never hashes them. Everything visible from outside matches. The seed does not.

Dice with a paper table

A third group does no dice arithmetic at all, and still deserves to be called dice support. The method is old and needs no firmware: roll dice, look each word up in a printed table, write it down. Anything that accepts a typed recovery phrase can then receive the result.

What makes it practical is the last word. A BIP-39 phrase ends in a checksum, so most word combinations are invalid, and finding a legal final word by hand means testing candidates one at a time. These tools compute it for you, which is the whole reason the feature exists.

A printed table is the usual way to reach the first 23 words, but it is not the only one, and the group is not only hardware. A desktop wallet can offer the same calculation against words you arrived at however you like, which is what puts Sparrow here rather than in the list below.

WalletThe final wordPosition on dice
BitBox02Shows the 8 valid candidates; you choosePublishes a dice guide and a 4-page lookup table
Blockstream Jade
Two D16 and one D8, not six-sided
Shows the valid candidates; you choosePublishes an article titled Create a recovery phrase using dice
Foundation PassportPicks one itself, using the device's RNGDocuments the feature, but advises against dice
Sparrow
Desktop software
Autosuggests every checksum-valid candidate as you type the last word, since 1.7.4Ships a Border Wallets grid for choosing the first 23 words. No dice screen. Its own docs describe neither feature, and mention dice only to tell you to mix rolls into a Coldcard

BitBox02's table is the clearest published example of the method. Five dice give 10 bits: you reroll any die showing 5 or 6 until it shows 1 to 4, which makes each die worth exactly 2 bits. A coin flip supplies the eleventh. Twenty-three words later you have 253 bits, and the device supplies the last word.

Jade's published method is not a six-sided one at all. It calls for two 16-sided dice and one 8-sided die, thrown together once per word and read off a lookup table as (D1−1)×128 + (D2−1)×8 + (D3−1). That covers 16×16×8 = 2048 exactly, so there is no rerolling and no coin flip, and each throw yields a whole word rather than a partial one. It arrives where BitBox02's method arrives, by different hardware and different arithmetic. The two are not variants of one scheme, and a transcript from one means nothing to the other.

Worth noticing: the final 3 bits of a 24-word seed come from a human choosing among 8 candidates, not from the dice. Negligible against 253, but the dice do not supply everything. Passport's variant hands those bits to the device's RNG instead, so its last word is not yours at all.
Not interoperable either

The paper-table method never hashes anything, so it does not reproduce the recipe above. A BitBox02 dice transcript does not even contain the digits 5 or 6. The phrase you end up with is ordinary BIP-39 and works in any wallet; it is the route from dice to phrase that does not transfer.

No dice

These generate seeds from their own random number generator, and offer nothing for dice beyond the ordinary ability to type in a phrase you produced elsewhere:

Trezor · Ledger · KeepKey · OneKey · Bitkey · Tangem · Cypherock · NGRAVE · Ellipal · SafePal · D’CENT · Satochip · Prokey · SecuX · Arculus · Ballet · Passport Prime · Portal · Frostsnap · Electrum · Nunchuk · Liana · Wasabi · Blockstream Green · Bitcoin Core

Two footnotes. Specter DIY is not on either list because its documented feature is coin flips, not dice: it lets you set the 11 bits of any word by hand and repairs the checksum, leaving untouched words machine-generated. Bitcoin Core is a structural no rather than a policy one; it does not implement BIP-39 at all, so there is no seed for dice to feed.