Reference · Bitcoin seed generation

Dice to seed

How to roll a seed you can verify: what actually costs you entropy, what is not worth worrying about, and what each wallet does with the rolls once you hand them over.

First published
2026-08-03
Updated
2026-08-21
Scope
Dice → BIP-39
Charted
17 implementations
Method
Source-read
Status
Living document
The short version

Use the dice you have, roll the count your wallet asks for, and you are done.

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, its RNG. You are then trusting that RNG and there is nothing in its output you can inspect to tell whether it did its job (see: the 2026 Coldcard incident, §20).

Dice are one answer 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.

You have to trust a seed a device creates for you. You can verify a seed you rolled yourself.

Convenience against verifiability

These methods trade against each other rather than ranking cleanly. Three dimensions separate them: what you have to obtain before you start, what you have to do once you have it, and how much of the result you can check afterward.

MethodSetupProcedureWhat to verify
On device Device RNGwhat most wallets do None Automatic, instant Input can't be verified
Camera imageSeedSigner's camera None Aim, review, accept No external verification
Dice, hasheddevice calcs words Grab some dice 99 rolls, typed in Full mnemonic
By hand Coin flipsbinary to words Coins + worksheet Lookups or binary math Just the final word
Dice worksheetrolls to words Dice + worksheet Rolls, rerolls, lookups Just the final word
Word pickingdraw from 2048 slips Cut out 2048 slips Draw, then type in Just the final word

  no cost   minor cost   a real cost   the method's weak point

The vertical brackets on the left indicate where the work happens. Hashed dice sit in neither group: the rolls happen in the real world but the device plays an integral role.

No route here is machine-free. A BIP-39 phrase ends in a checksum word, so that word gets computed however you reached the other twenty-three (§12). The last column is what each method leaves you to verify.

Which column matters most is yours to decide, and reasonable people land in different rows. But one row never drops below easy.

Dice is a reasonable compromise that holds up well enough in all three columns. The dice are ones you already own, the procedure adds nothing to the rolling beyond typing the digits in, and the result reproduces anywhere from what you wrote down. Every other method on this chart offsets its strengths with a drawback somewhere: a costly setup, an awkward procedure, or a result nobody can check.

2Does dice quality matter?

Not enough to change anything you do. A biased die does cost you bits, so the only question is how many.

Every figure below is a worst case rather than an estimate. A real die does better.

How unfair is a cheap die, really?

Not much has been published on this. These two studies are the most substantial we found.

MeasurementDiceRollsWorst case found
Labby, 200912 cheap plastic315,672one face 1.3% high
Iversen et al., 197158 cheap, 161 precision4,380,000cheap dice 1.4% high on even faces; precision dice, nothing

Two studies, four decades apart, measuring different things, both landing near 1.4%. This page works from 2%, which deliberately exaggerates both. §17 has the links and the caveats.

24-word seed, 99 rolls    12-word seed, 50 rolls

A perfectly fair die

255.9 bits128.0 bits

A cheap die, one to three faces 2% high

253.1 bits127.8 bits

One face 8% high, four times the working figure

244.9 bits123.7 bits

20% more often, visibly odd

229.9 bits116.1 bits

50% more often, obviously defective

198.0 bits100.0 bits
Bars scaled to 256 bits. Solid line: 128 bits, what NIST requires from 2031. Dashed line: 112 bits, its floor today. §17 sources both. Only the second row is grounded in measurement, and it assumes a worse die than either study found; everything below it is hypothetical and no published measurement of an ordinary die comes close even to the 8% row.

Any bias large enough to matter is large enough to notice casually. The one that has actually been measured took a machine and 315,672 rolls to pin down.

Save your money

Casino dice do not matter here. They are provably better, but not in a way that makes any difference to the entropy you end up with. The measurement is in the appendix.

3Why not roll more?

Extra rolls are not necessary. Advice to roll 120 or 150 times circulates on the theory that they buy margin against an imperfect die. They would, but §2 leaves no such die to guard against: a real one costs almost nothing, and one skewed far enough to matter would be so obviously bad you would not have used it in the first place.

There is a ceiling. A seed holds a fixed number of bits, 128 for a 12-word phrase and 256 for a 24-word one. 99 rolls already deliver 255.9 of that 256. Roll 150 times and the surplus has nowhere to go.

The real cost of insisting on extra rolls

Spreading FUD. Someone who has convinced themselves that 120 rolls are necessary goes on to tell everyone who “only” rolled 99 that their seed is deficient.

Doubt spreads faster than the correction does and it lands on people who did nothing wrong.

A seed rolled to the count its wallet asks for is complete. Nobody who rolled that way has anything to fix.

The roll count is not a floor to exceed for safety. It is the number that fills the seed.

4What to actually do

  1. Use the dice you have. Buying better dice does not buy a better seed.
  2. Testing your dice is almost certainly a waste of your time. The imperfections of cheap dice are too small to matter (§2).
  3. Choosing 12 or 24 words has a bigger impact on your backup strategy than on your security. A 24-word phrase is twice as much to write down and stamp into metal.
  4. Every roll needs a thorough tumble. The one thing here measured to matter.
  5. Use the dice-in-a-box method. Faster and it tumbles better.

How you throw matters more than what you throw

A die remembers where it started. Kapitaniak and colleagues found that the face which starts at the bottom is the one most likely to finish there, and that how much depends almost entirely on bouncing (§17).

How the die landsChance it keeps its starting face
Dropped on a soft surface, no bounce54.8%
Thrown from a hand or cup, 4 to 5 bounces19.9%
A perfectly fair die16.7%

Their conclusion is worth quoting: “It is not enough for a die which is fair by symmetry to be fair by dynamics.”

So make sure every roll gets a real tumble, several bounces before it settles, whether that comes from your hand or from a box. It is the one thing here that can genuinely weaken a seed, and the easiest to get right.

This is where casino practice stops being a useful guide. A craps table makes dice hit a studded back wall to stop a player from exploiting this determinism for money. You are not trying to stop yourself from cheating. You only need the dice to bounce, which is a much easier thing to arrange.

The dice-in-a-box method

Put a handful of dice in a box, shake, and read them left to right. Use a box with enough room for the dice to tumble properly and shake it long enough that they do.

If that handful happens to be a mix of different dice, so much the better: different flaws partly cancel each other (§17). The gain is far too small to go shopping for, so just use whatever you happen to have, even if they all come from the same set.

What the box is for

Speed. Ten dice give you ten rolls per shake, so 99 rolls takes ten shakes instead of 99 separate throws.

Tumbling. A closed box bounces the dice off the walls and off each other, which is the part a hand throw has to get right and often does not. The box does it every time, with no technique to learn.

5Don’t trust, verify: the seed it shows you

Dice nearly remove trust from seed generation. Not entirely, but what is left is narrow and specific rather than the broad act of faith that “trusting your hardware wallet” usually describes.

If you read nothing else here

Check your device against at least one independent tool. Roll a full test set, enter it, and confirm that an independent implementation of the same method turns those rolls into the same words (§15). Do that a couple of times, with a fresh test set each time, before you roll the seed you mean to keep.

The rolls have to be a test set, because the ones used to create your real seed should never be typed into a second machine.

The claim a dice seed makes

When a device turns your rolls into a phrase, it is asserting exactly one thing: that these words are what its published method produces from those digits. For the hashed construction of §8 that reads:

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

Every construction in this catalog substitutes its own formula, and none of them leaves anything for the device to choose, so the method and the rolls fix the answer between them.

That assertion is falsifiable: one correct answer, computable by anyone holding the rolls, depending on nothing the device knows. A device that shows you anything else either has a bug or is deliberately trying to deceive you. Either way, it is caught the moment you check.

Testing the device costs you nothing

The useful consequence is that you can check the device as often as you like, with test rolls. Nothing is at stake in a test set, so it can be done on any computer, connected, carelessly, as many times as your patience allows.

Roll a test set for real, exactly as you would one you meant to keep. Digits you made up instead of rolling are not a rehearsal of anything. They can trip the pattern guards in §14, so the run never exercises the path your real seed will take, and typing numbers you did not roll is not a habit to build. What makes a test run free is that the seed is disposable, not that the process is.

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 working from what you typed and nothing else.

A device could answer honestly through every test and then lie on the run that matters, but it would have to guess which run that is, and nothing in your rolls tells it.

After enough test runs the device is not something you trust. It is a tool you have checked, doing exactly what its method says it should.

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.

That is what test runs are for: the seed that matters is entered once, in one place.

What to check with

Two browser tools cover most of what is in this catalog: iancoleman.io and Seed Tool from bitcoiner.guide. Either one will turn a set of test rolls into words you can hold up against your device, and §15 walks through it click by click. For most people that is the whole job.

An AI can also write you a checker from scratch, sharing no lineage with either tool. §15 has a prompt to copy.

Not everyone thinks this trade is worth making. §20 sets out the strongest objection to dice and the 2026 disclosure that tested it.

6Don’t trust, verify: the code it runs

Checking the arithmetic establishes that the device turned your rolls into the right words. It says nothing about whether the machine kept a copy of them, or whether the firmware on it is the firmware the vendor published. Those are separate questions, and they are not answered by trust either.

You do not have to take the code on faith

Where a project is open source, the code that turns your rolls into a seed can be read by anyone, including you. It is a short and unusually readable piece of any wallet: collect the digits, apply the published formula, encode the result.

You do not have to be a programmer to get something out of this. Ask an AI to find the dice code in your wallet's repository and explain what it does with your rolls, then ask it what else it does with them.

Reading the source tells you what the published code does. Three further steps connect that code to the device in your hand, and none of them asks you to take anyone’s word for it:

Each is a subject in its own right and this page does not try to teach any of them. What matters here is that they exist, and that using them is not someone else's job.

“Open source” is not the same as “reviewed.” The entropy defect in §20 sat in published code from 2021 until 2026 before anyone caught it. Public code protects you only when somebody actually reads it, and that has meant waiting for a specialist with the time to look.

That is the part that has changed. An AI will read a firmware repository alongside you and answer questions about what it does, which puts a real look at the code within reach of someone who could not have managed it alone. You need no permission and no expertise to point one at your wallet's dice routine and ask what it touches.

7The methods and who uses which

These methods are not interchangeable. Two implementations agree only when they use the same method.

Click any column heading for how that method works.

What the implementation does with your rolls
Hash the rolls as typed Rewrite each 6 to a 0, then hash Pack into bits, never hash Read as a base-6 number Completes a hand-built phrase Vendor publishes a dice worksheet Adds the device's own entropy What you roll
Signing devices and wallets, where seeds get generated
BitBox02 · · · · 1 · dice, coin
Blockstream Jade · · · · 2 · 2 × D16, D8
Coldcard · · · 3 · 4 dice
Foundation Passport · · · · 5 ·6 5 your choice
Kern · · · 3 · · dice
Keystone · 7 · · ? · · dice
Krux 8 · · · 3 · · dice, D20
SeedSigner · · · 9 · · dice
SparrowDesktop software · · · · 10 · · your choice
Specter DIY · · · · 11 · 11 coin
Software tools and apps, for generating or independently checking one
AirGap Vault 12 13 · · ? · · dice
BlueWalletMobile app · · · ? · 14 coin, dice, D20
Gordian Seed TooliOS app 15 · · · ? · · dice, coin
Gordian seedtool-cli 16 · · · ? · · dice
iancoleman.io 17 18 18 · ? · · dice
Seed Toolbitcoiner.guide 19 · 19 · ? · · dice
Libraries
RooSoft/bitcoinlibElixir · · · 20 ? · · dice
24 more walletsTrezor, Ledger, and the rest of §13 · · · · · · · nothing

yes, read from source yes, with the limit in the note · no ? not established here

  1. Five dice per word, each rerolled until it shows 1 to 4, plus one coin flip for the eleventh bit. The device offers the 8 valid final words.
  2. A 17-page guide: two 16-sided dice and one 8-sided, thrown together, one whole word per throw.
  3. Typing a phrase in, the last word is offered only as checksum-valid choices.
  4. A separate option hashes rolls on top of a seed the device generated.
  5. The device picks the final word with its own RNG instead of showing you the valid ones.
  6. Documents the final-word feature and names dice, but advises against dice and publishes no table.
  7. Requires 100 rolls for 24 words, not 99, while its own documentation still says 99.
  8. D20 rolls are joined with dashes before hashing, so a D20 transcript reproduces only on Krux.
  9. Its Calc Final Word tool takes the last word's spare bits from coin flips, a BIP-39 word you pick, or zeros. Not from a dice table. A coin-flip routine for a whole seed exists in the code but no menu reaches it, so the chart records dice only.
  10. Autosuggests every checksum-valid last word; ships a Border Wallets grid, not a dice table.
  11. You set any word's 11 bits by hand and the checksum is repaired; words you do not set stay device RNG.
  12. 99 rolls and 24 words only, with no 50-roll path.
  13. The mode labeled “Coldcard” applies the rewrite. Coldcard does not.
  14. Any shortfall below the target length is filled from the phone's RNG after a dialog.
  15. Truncates to 16 bytes unconditionally, so dice give 12 words however many times you roll.
  16. Enforces no roll count at all and will derive a seed from five rolls.
  17. Base 10 mode. Hex mode takes a digest you computed elsewhere.
  18. Dice mode, hashed when a word count is fixed and unhashed in its default raw sub-mode.
  19. Hashed mode by default; its “raw” mode packs the rolls into bits instead.
  20. Demands exactly 50 or 99 rolls, the same counts as the hashed method, then never hashes them.
The final-word and worksheet columns were surveyed on the signing devices, where a seed is generated and the question matters. For the software tools they were not established and those cells say so rather than guessing. Marks are read from source at the pinned commits in §18, except the worksheet procedures, which are read from the vendors' own published tables.

One column the chart does not carry: whether an implementation looks at the rolls you typed and tries to judge them. Most do not, and the few that try disagree about how. §14 is what each one checks and what the check is worth.

The chart records what each implementation does with your rolls, read from source. It is not an audit of the software and appearing in it is not a recommendation. §18 sets out what was established and what was not.

8Hash the rolls as typed

50 rolls makes a 12-word seed. 99 rolls makes a 24-word seed. The rolls are hashed as text, exactly as you wrote them down, and the resulting hash is the seed's entropy.

Check this method yourself: ten minutes, no programming, with the published test vectors.

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 wordlist

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

Each group is a number from 0 to 2047. The +1 accounts for printed wordlists, 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 method 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.

A correct implementation reproduces the published vectors in §15. If yours does not, the most likely cause is that it implements §9, §10, or §11 instead.

Coldcard also offers a separate mode that hashes your rolls on top of a seed the device generated. Nothing from that mode reproduces anywhere, because the starting value was never shown to you. It is a real trade rather than a mistake, protecting you if your dice turn out to be terrible, at the cost of the one property that made dice worth using.

9Rewrite every 6 to a 0, then hash

The same shape as the hashed method of §8, over a different alphabet. Every 6 is rewritten to a 0 before hashing, so the six faces read as 0 to 5 rather than 1 to 6. Everything after that is identical: one SHA-256, truncate, encode.

Check this method yourself: the same tool as §8 with one setting changed and that setting decides which method you get.

One substitution, and it is not a subtle difference in the result. Run the 99-roll example from §8 through both 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.

ImplementationWhere it applies and what else differs
Keystone
Hardware
The whole dice path. Requires 100 rolls for 24 words rather than 99, hard-enforced, while its own documentation still says 99. The 24-word gate is gui_model.c L497.
iancoleman.io
Dice mode
Applies the rewrite, then hashes only if you fix a word count. Its default sub-mode does not hash at all, which puts it in §10 as well.
AirGap Vault
“Coldcard” mode
Applies the rewrite. Coldcard does not do this, so the setting does not do what its name says.
A setting named after a wallet is not 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 method in §8.

10Pack the rolls into bits, never hash

This method never hashes anything. Each face contributes bits directly and the packed bits are the seed entropy.

Check this method yourself: only against itself, because the implementations do not agree with each other.

Because six is not a power of two, the encoding is variable-length: four of the faces carry two bits each and the remaining two carry one, which is what keeps the result unbiased. A six-sided die therefore averages about 1.67 bits rather than the 2.585 an ideal encoder would extract, so filling a 24-word seed's 256 bits takes roughly 154 rolls. Needing more rolls than a hashed method is a property of this encoding, not a sign that your dice are worse.

ImplementationWhat it does
BlueWallet
Mobile app
Packs rolls into bits, 0-indexed, with no minimum roll count. Any shortfall is filled from the phone's RNG after a dialog, so a short session produces a seed that is partly the device's and reproduces nowhere.
iancoleman.io
Dice mode, default sub-mode
Rewrites 6 to 0 first, then packs. The word count varies with how many times you rolled.
Seed Tool
“Raw” mode
Packs rolls into bits without the rewrite, so its table and iancoleman's disagree with each other even though both are “raw dice.”

No two of the three produce the same seed from the same rolls, which is worth stating plainly. iancoleman rewrites every 6 to a 0 before packing and the other two do not; BlueWallet and Seed Tool share a face-to-bits table but differ in what they do with a roll count that under- or overshoots. There is no shared convention here to check against, which §15 sets out as the one method where cross-checking cannot help.

11Read the rolls as a base-6 number

The oldest and most literal reading: the roll string is one long number written in base 6, so the digits are parsed as an integer and written back out as bytes. No hash anywhere.

Check this method yourself: the conversion is checkable with a pencil on a short sequence.

It is internally consistent and it is not broken. It is also the method most likely to look correct from outside while producing something else entirely.

Matching roll counts prove nothing

The Elixir library RooSoft/bitcoinlib demands exactly 50 or 99 rolls, the counts that everywhere else in this catalog signal a hashed construction (§8), then reads the digits as a base-6 number and never hashes them. Everything visible from outside matches. The seed does not.

SeedSigner itself used this method until February 2022, along with the 6-to-0 rewrite, which is why old rolls do not reproduce old seeds on a current release. The release history in the companion analysis gives the formula for each era. §15 has the steps for checking the conversion.

12BIP-39 wordlist worksheets

A whole group of implementations 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.

Check this method yourself: the lookup table is the only thing that can be wrong and checking it needs nothing but the wordlist.

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 implementations 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. Coin flips do the same job eleven bits at a time and a desktop wallet can offer the same calculation against words you arrived at however you like, which is what puts Sparrow here.

Two different things are worth separating and the chart gives them separate columns. One is whether a device will finish a phrase you built yourself. The other is whether its vendor publishes the worksheet that makes the dice route practical, which is a statement about what the vendor recommends rather than about what the device can do.

Only BitBox02 and Jade do both. The rest of this group has the capability without the worksheet, which means the method works there but you supply the table.

ImplementationWhat the device contributesWorksheet the vendor publishes
BitBox02Shows the 8 valid final words; you chooseA dice how-to and a 4-page lookup table
Blockstream JadeShows the valid final words; you chooseA 17-page guide: two 16-sided dice and one 8-sided, one word per throw
Foundation PassportPicks the final word itself, using the device's RNGNone. Documents the feature and names dice, but advises against it
Sparrow
Desktop software
Autosuggests every checksum-valid candidate as you type the last word, since 1.7.4None for dice. Ships a Border Wallets grid and its own docs describe neither feature
Specter DIYAn 11-bit keypad sets any word by hand and the checksum is repaired. Words you do not set stay device RNGNone. Its documented input is coin flips, not dice
SeedSignerA Calc Final Word tool: enter 11 or 23 words, then give the spare bits as coin flips, a word you pick, or zerosNone
Coldcard, Krux, KernOffer only checksum-valid choices for the last word of a phrase you type inNone. The capability falls out of ordinary seed entry
This method is available on more devices than advertise it

BitBox02, Jade, and Passport built the final-word feature deliberately for hand-made seeds, and two of the three publish the lookup table to go with it. BitBox02's source says so in a comment: the special case exists “so that users can generate a seed using only the device and no external software, allowing seed generation via dice throws.”

But the same affordance turns up elsewhere without being advertised. All four devices that implement the hashed method of §8 will also complete a hand-built phrase, verified from source in each case: Coldcard, Krux, and Kern by restricting the last word during ordinary seed entry, SeedSigner through a dedicated tool built for word or coin-flip entry rather than for dice.

So if you have a printed table and one of those devices, the worksheet method works. You are using a capability rather than following a supported procedure and the difference matters mostly in where you get the table and who has checked it.

BitBox02's table is the clearest published example of the method. It calls for five ordinary dice and a coin, rerolling any die that shows a 5 or a 6. 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, with no rerolling and no coin flip needed. 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.

Both Passports hand those 3 bits to the device's RNG instead, so the last word is not yours at all. That is the difference between their half marks in the chart and BitBox02's full one.

Not interoperable and not trying to be

The worksheet method never hashes anything, so it reproduces none of the machine constructions in this catalog. 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.

In exchange it is the only method here you can carry out with a pencil. The arithmetic that needs a machine has been reduced to one word.

Worksheets no vendor publishes

The table is the hard part of this method and it does not have to come from a wallet vendor. Several people have published their own. These were surveyed on 2026-08-15 and anyone can publish another, so read this as the ones found rather than the ones that exist.

WorksheetWhat it calls forHow it covers all 2048 words
DiceBIP39Ordinary diceOne roll picks half the chart, five more are read as 1 to 4, rerolling any 5 or 6
bip39_diceD16, D8, D4, or a coinFour tables. Each die contributes whole bits, so the throw is the word number in binary
Bip39-dicewareA coin and four ordinary diceHeads reaches the first 1296 words, tails the remaining 752, rerolling tails above 4362
SeedPicker342 paper tickets and one dieTicket and die give 2052 cells; the four spare ones say draw again
RudeFoxAny source of bitsA grid of 128 rows and 16 columns, read as 11 bits

Every one of them addresses all 2048 words evenly, which is the property that matters and the one worth checking. Each construction was verified against the wordlist for this page; the survey records the pinned sources, the file hashes, and how far each table was checked. §15 gives the steps for checking a table yourself, which is worth doing before trusting any of them.

A cosmetic flaw, and the one that would not be

Three of the five print a word with the wrong capitalization. reardencode's four tables print TRUE where the wordlist has true, RudeFox prints TRUE and FALSE, and SeedPicker prints March and October.

These are spreadsheet artifacts: a sheet coerced true into a boolean and autocapitalized two month names. reardencode's README says outright that its tables were built in Google Sheets.

Nothing follows from it. BIP-39 words are lowercase, you will type the lowercase word, and an implementation handed True rejects it as not being in the wordlist rather than deriving anything from it.

The defect worth checking a table for is the other kind: a wrong word that is still a real BIP-39 word, which nothing downstream would question and which would substitute silently. None turned up in any table surveyed, though the survey records how far each one was checked.

Drawing the words instead

Take the dice out of this method and it still works. Draw the words themselves from a complete physical set, one at a time, and the device completes the phrase exactly as it does from a worksheet. What changes is the selector, not the method.

SeedPicker is the case where both are present at once: you draw a paper ticket and roll a die, the pair addressing one word between them.

That technique has its own reference: Drawing BIP-39 words, covering what makes a draw fair, what goes wrong with the set itself, and the sets available. It is a work in progress.

Related and out of scope

codex32 (BIP-93) is the other worksheet-driven scheme that belongs in this conversation and it is a much larger subject than a paragraph. It is left out because its output is a BIP-32 master seed rather than a BIP-39 phrase, so nothing in this catalog applies to it. The BIP carries a section titled “Not BIP-0039 Entropy” explaining that choice.

A worksheet is specific to one wordlist and a finished phrase does not say which list produced it. SLIP-39 uses 1024 words rather than 2048. Of those, 553 are also BIP-39 words sitting at different positions. Electrum is the sharper case: its English wordlist is the BIP-39 list byte for byte, but a version 2 Electrum seed is validated by a different checksum entirely, and Electrum discards any seed of its own that would also pass as BIP-39.

Everything on this page ends in a BIP-39 phrase.

13Wallets that offer nothing for dice

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

Trezor1 · Ledger2 · KeepKey · OneKey · Bitkey · Tangem · Cypherock · NGRAVE · Ellipal · SafePal · D’CENT · Satochip · Prokey · SecuX · Arculus · Ballet · Portal · Frostsnap · Electrum · Nunchuk3 · Liana · Wasabi · Blockstream Green · Bitcoin Core4

  1. Trezor mixes its internal RNG into seed generation unconditionally, so even a custom host tool feeding it dice bytes cannot produce a seed derived from the rolls alone.
  2. Ledger is the weakest entry here. Its onboarding firmware is closed source, so this rests on first-party documentation rather than a source read.
  3. Nunchuk's iOS app is closed source too and is inferred from the shared core rather than read.
  4. 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.

14Detecting bad rolls

Whichever construction an implementation uses, it faces a separate problem: someone who types the same digit fifty times, or an obvious pattern, rather than rolling. Implementations differ on whether they try to catch that at all, and the differences do not follow the method they use.

ImplementationWhat it checks
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 on the path that mixes rolls into an existing seed
KeystoneWarns if any single face exceeds 30% of rolls, but the warning is advisory and Confirm stays live
Seed Tool, SeedSigner, Kern, RooSoft/bitcoinlibEnforces the roll count and nothing else
AirGap VaultNothing beyond the 99-roll minimum, plus an explicit refusal to hash an empty string
iancoleman.ioNo minimum. Warns that the phrase “will appear more secure than it really is” and generates it anyway
Gordian Seed ToolNothing and no roll count either
Gordian seedtool-cliNothing, no roll count, and it will derive a seed from five rolls
BlueWalletNothing and no minimum. Under-rolling silently tops up from the phone's RNG after a dialog
BitBox02, Jade, both Passports, Sparrow, Specter DIYNot applicable. These never see your rolls, so there is nothing for them to check

Roll-count enforcement is the guard that has actually mattered. One roll leaves six candidate seeds and two leaves 36, and wallets sitting in a space that small get found and emptied.

This is not hypothetical. In October 2023 Crypto Guide went looking for exactly those wallets, searching the chain for seeds built from low dice-roll counts, reported that funds had already been taken from them, and demonstrated the same thing still being possible on a Coldcard Mk4 running the firmware current at the time. (A separate and older problem than the 2026 RNG failure in §20.)

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.56220.2%allowedallowed

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.

Krux is the partial exception: alongside its Shannon meter it runs a derivative-based check that flags arithmetic progressions, so it catches that row where the scores alone do not.

And it can't detect a biased die anyway

With only 50 or 99 samples the estimate is far too noisy. Tuned to warn 1 honest user in 1,000, a Shannon score at 99 rolls catches a die favoring one face 50% more often just 4.9% of the time. Coldcard's fixed 30% limit shows the same tension from the other side, falsely warning 3.4% of honest users at 50 rolls. §17 has the thresholds and the arithmetic.

It resolves itself, because these checks miss exactly the biases that do not matter: a bias small enough to hide in 99 rolls is far too small to cost a seed anything (§2). A roll-quality guard should catch patterned input, not judge your dice. Compression does that better than either approach, with fewer false alarms.

15Check it yourself

What you can check depends on which method your wallet uses, and each method's own section links into its walkthrough here. The worksheet route of §12 needs nothing but the wordlist. Anything ending in a hash needs a machine, and what matters is that the machine is not the device you are checking.

Never with a real seed

Use the published vectors or test rolls of your own. 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 test rolls. See §5.

The hashed method, against the published vectors

Ten minutes, no programming. This reproduces §8.

  1. Take the published 99-roll example:
    655152231316521321611331544441236164664431121534415633526456254462245546236542364246312613322234612
  2. Go to iancoleman.io/bip39. The hosted page is fine here; when to download it instead.
  3. Tick Show entropy details.
  4. Set the entropy type to Hex, not Dice. Dice selects a different construction, the one in §15's walkthrough.
  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

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

The construction, written down

There is no BIP for this. What follows is not a proposal for one. It is a description of what the nine implementations 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

The 6-to-0 remap and the one setting that decides it

Ten minutes, no programming. This reproduces §9, the construction Keystone uses and the one behind AirGap Vault's “Coldcard” mode.

  1. Take the published 99-roll example:
    655152231316521321611331544441236164664431121534415633526456254462245546236542364246312613322234612
  2. Go to iancoleman.io/bip39. The hosted page is fine here; when to download it instead.
  3. Tick Show entropy details and set the entropy type to Dice.
  4. Paste the digits and set Mnemonic Length to 24 Words. This is the step that decides which method you are testing. iancoleman's Dice mode hashes only when a word count is fixed; left on its default it packs the bits instead, which is §10.
  5. You should get: police guard reject concert debate curtain width great miss uncover lift kitten observe soap fun dog always spirit camera ten grant rate across engage
The warning you will see here is a false alarm

Setting 24 words makes the page report “The mnemonic will appear more secure than it really is” and rate the rolls as good for only 15 words. Nothing has gone wrong, and the seed is not weak.

That warning is measured against the tool's own bit-packing conversion, which reads a die at about 1.69 bits and turns 99 rolls into 167 bits: enough for 15 words, short of the 256 that 24 words need.

Fixing a word count is precisely what takes that conversion out of the picture. In that state the page hashes the digit string instead. Your 99 rolls carry 255.9 bits into that hash. The scoring above the field is describing a path the code did not take. The source hashes entropy.cleanStr when a length is set, while the warning tests entropy.binaryStr.length.

The same rolls in Hex mode raise no warning at all, because hex reads 4 bits a character, so 99 characters convert to 396 bits and clear the threshold outright.

If the phrase comes out different, check the word count before anything else. Leaving Mnemonic Length unset is the common failure here: the tool switches to packing bits without saying so, and returns a perfectly valid phrase built by a different method.

This checks the construction rather than any particular device. A Keystone will not accept the vector at all, because it enforces 100 rolls for 24 words rather than 99.

Bit-packing and base-6, where checking runs out

§10 cannot be cross-checked at all. The three implementations map faces to different bit strings and one rewrites a 6 first, so there is no shared answer to compare against. The most you can establish is that an implementation reproduces itself: enter the same rolls twice and confirm the phrase comes back the same.

§11 is checkable in principle and tedious in practice. Reading 99 digits as one base-6 integer and writing it back out as bytes is machine work. Do it once on a short sequence with a pencil, because the point worth seeing is what is absent: no hash appears anywhere in the conversion.

A worksheet's lookup table, before you use it

The worksheet method needs no arithmetic, which leaves the table itself as the only thing that can be wrong. What you are looking for is a cell holding a real BIP-39 word that belongs at a different index, since nothing downstream would question it. The capitalization artifacts found in three of the five worksheets in §12 are harmless by comparison.

  1. Get the canonical English wordlist. Its sha256, newline-terminated, is 2f5eed53a4727b4bf8880d8f3f199efc90e58503646d9ff8eff3a2ed3b24dbda.
  2. Check that the table has 2048 entries and that each index carries the word the list carries at that position. Off-by-one is the failure to expect, since some tables number from 1 and the specification numbers from 0.
  3. Look for TRUE, FALSE, and capitalized month names. Harmless in themselves, but they are what a spreadsheet does to true, false, march and october, so one of them tells you the table was never compared against the wordlist.
  4. Confirm the scheme addresses every word evenly: the outcomes have to be a multiple of 2048, with any surplus sent back to a reroll rather than folded into a word.

The two vendor constructions, written down

Both reach all 2048 words exactly, by different arithmetic.

BitBox02   5 dice, each rerolled until it shows 1-4   -> 2 bits per die = 10 bits
           1 coin flip                                 ->  1 bit
           11 bits per word; 23 words = 253 bits; the device supplies word 24

Jade       2 x D16 + 1 x D8, thrown together once per word
           index = (D1-1)*128 + (D2-1)*8 + (D3-1)
           16 x 16 x 8 = 2048 exactly: no rerolling, no coin flip

A table that fails any of these was never compared against the wordlist by whoever published it. The survey records how far each one was checked here.

The web tools and when to download them

Two of the implementations in §7 are browser tools and the walkthroughs in this section reach for one of them. Each ships a signed standalone build alongside the hosted page. iancoleman's releases carry bip39-standalone.html beside signature.txt.asc, and Seed Tool's carry index.html beside signature.txt.

No real rolls ever go into any of these tools. They exist for one purpose: to establish that a device turns rolls into the seed the published method says it should. The rolls you use to create a seed you intend to keep are entered on that device and nowhere else, as §5 sets out.

The hosted pages are fine for that. A test run uses rolls you are discarding and vectors that are already public, so there is nothing for a server to learn.

Downloading the signed build is an optional extra. A hosted page can serve different code on every visit and can serve it to you alone, so in principle a checker could be changed under you and made to agree with a device that is wrong. A file you have checked against its signature is the same code every time you open it. That is a precaution against a narrow attack rather than a prerequisite for checking anything.

With your own AI assistant

The goal is a checker you can run, not an answer from a chatbot. Copy the prompt below as it stands, run the program it gives you on your own machine, and keep your rolls out of the conversation.

Prompt
I want a small Python program I can run offline that turns dice rolls into a
BIP-39 recovery phrase, so I can check what my hardware wallet produced.

Start by reading this page:
https://kdmukai-bot.github.io/seedsigner-ai-analysis/dice/standard.html

Wallets do not agree on how to turn rolls into a seed. Section 7 charts which
implementation uses which method, and sections 8 to 12 describe each method.

1. Ask me which wallet or tool I am using.
2. Look it up in that chart and tell me which method it uses before you write
   any code. If it is the bit-packing method, stop and say so: no two
   implementations of that one agree, so there is nothing to check against.
3. Implement BIP-39 from the specification. Do not import a wallet library.
4. Prove the encoding is right by reproducing the official BIP-39 test
   vectors, and show me that before going further.
5. Implement my wallet's method exactly as that page describes it, then
   reproduce the published test vector for it from section 15.

Do not judge the result by testing whether the output looks random. Hashing
always produces output that passes randomness tests, so that proves nothing.

Step 4 is not optional. A model that cannot encode a known entropy value correctly cannot tell you anything about your rolls, and a wrong one will be fluent and confident about it.

Step 2 is what stops it guessing. Making the model name your wallet's method before it writes any code heads off the common failure, which is applying the 6-to-0 remap unprompted: iancoleman's Dice mode is well represented in training data and looks like the obvious reading of “dice entropy”. The other failure is reaching for a wallet library rather than the specification, which quietly reintroduces the shared lineage you were trying to escape.

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 §8, the competing 6-to-0 construction from §9, and the worksheet mapping from §12. Run it from evidence/; it reads the wordlist from the working directory.
evidence/wallet-dice-survey.mdThe source reading behind the chart in §7, with the pinned commit each classification came from, the third-party worksheet survey, and the method any further wallet has to be surveyed by.
dice_bias_analysis.pyThe min-entropy figures in §2.
dice_shannon_scoring.pyWhy the Shannon-scoring guard discussed in §14 does not catch a bad die.
dice_tendice_box.pyThe dice-in-a-box pool-size sweep in §2.

16Known analyses

Published analyses of these implementations that we are aware of. Where one reports figures, they were reproduced independently before it was listed.

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.

Appendix

The evidence behind this page

Everything above is the document. What follows is what it rests on: the measurements behind the dice figures, where every mark in the chart came from, and how to establish a mark for a wallet that is not in it yet, and the strongest case against the whole exercise. It is written to be checked rather than read, which in practice means a model checking it. Pointing one at these sections is the fastest way to audit a claim or add a row.

The route in for a human is the source table: every implementation, with the pinned commit its classification was read at.

17The dice-fairness measurements

The figures in §2 are other people's measurements, converted into seed bits here. This section is the detail behind them: what was measured, by whom, how thin the evidence is, what the conversion assumes, and where the thresholds they are judged against come from.

Read this before citing either figure

Only one of the two measurements is per-face. Labby's gives a full distribution and can be converted into seed bits directly, but it rests on twelve dice that all shared the same defect in the same direction, which is what a single mold produces. Twelve dice from one bag are not twelve independent samples of the world's dice.

Iversen's has the sample size Labby's lacks, 58 cheap dice tested individually, but records only odd against even, so its 1.44% is a per-face figure only under the assumption that the excess is spread evenly across the three even faces. That assumption follows from the mechanism they propose and is not measured.

Why that assumption does not carry much weight. Min-entropy reads only the single most likely face, so the number of elevated faces never enters the arithmetic. A die with one face 2% high and a die with all three even faces 2% high are worth the same 253.1 bits at 24 words. Iversen's pattern, at 1.44% a face, costs less than either at 253.9. The 2% working figure bounds the odd-even result however the excess turns out to be distributed, which is what makes it safe to quote a per-face number from a study that never measured one.

What is missing is a modern per-face study across many brands and many individual dice. We are not aware of one. What makes the gap tolerable is that the conclusion is insensitive to the number: Robustness to the estimate being wrong applies the same conversion to a ladder of worse dice, and the bias has to reach several times either measurement before a 24-word seed loses even five bits.

Labby 2009, the per-face figures

Zacariah Labby, “Weldon's Dice, Automated”, CHANCE 22(4), 2009. An apparatus of solenoids, a webcam, and pip-counting software repeated Weldon's 1894 experiment: 26,306 throws of 12 dice, 315,672 individual rolls. The dice are described in the paper as “inexpensive, standard white plastic dice with hollowed-out pips and a drop of black paint inside each pip.”

Face123456
Observed0.16860.16510.16620.16580.16550.1688
Fair0.16670.16670.16670.16670.16670.1667

Weldon 1894, the experiment being repeated

W. F. R. Weldon reported 26,306 throws of 12 dice to Francis Galton in a letter dated 2 February 1894, recording only whether each die showed a five or six. Karl Pearson used the data in the 1900 paper that introduced the chi-square goodness-of-fit test.

Iversen and Longcor 1971, the odd-even study

Iversen, Longcor, Mosteller, Gilbert, and Youtz, “Bias and runs in dice throwing and recording”, Psychometrika 36(1), 1971. Willard Longcor threw 219 dice, one block of 20,000 throws each, 4,380,000 throws, recording only whether the up-face was odd or even.

The dice are described but the brands are not named. The paper calls them A, B, C, and X:

BrandTypeSizeDice
APrecision0.77 in100
BPrecision0.71 in30
CPrecision0.75 in31
X“the usual inexpensive drilled plastic dice”0.61 in58

The precision dice are described as having “sharp edges meeting at 90° angles” with pips “either lightly painted or constructed from extremely thin disks, the whole object being polished beautifully,” shipped in plastic cases in foam-cut slots, and costing about $1.25 a pair at the time. Brand X is the five-and-dime-store die with drilled pips and a drop of paint in each hole.

Two studies, two different physical causes

The papers disagree about why cheap dice are biased, which is worth knowing before citing either as the explanation.

Iversen attributes brand X's bias to pip weight: the even faces carry 2+4+6 = 12 pips against the odd faces' 1+3+5 = 9, so drilling them out leaves the even faces lighter and they land up more often. Labby tested exactly that prediction on his dice and rejected it, then found a dimensional cause instead, the 1–6 axis being 0.2% short.

Both can be true of different dice and the two studies are blind to each other's defect. Iversen's paper says so itself: a bias where “the probabilities of opposite sides are equally inflated and other opposites equally deflated, as they might be if the die were a rectangular parallelepiped instead of a cube” would not be detected by odd-even recording. A short 1–6 axis raises faces 1 and 6 together, one odd and one even, so it cancels in exactly that way.

What survives both is the magnitude. Two experiments, two mechanisms, two eras, both landing near 1.4%.

Why the hobby literature sounds more alarming

Most modern dice-fairness testing is about twenty-sided dice and it does report widespread failure. Campbell and Miller at Western Kentucky University, whose 2024 abstract opens “Dice are cursed or blessed; that is, they roll low or high, but they are never fair,” report that roughly one plastic-mold die in four tests fair over 3,000 rolls.

Two things to hold onto before importing that conclusion here. A twenty-sided die has far smaller faces and far more of them, which the same authors note makes it more susceptible to manufacturing imperfection than a d6. And failing a fairness test is a statement about detectability at a given roll count, not about effect size: it says the bias is big enough to see, not that it is big enough to matter to a seed.

Sourced from the published abstracts rather than the full papers, which were not retrievable. The related finding that a die's chi-square correlates with the spread of its measured diameters is consistent with Labby's micrometer result, and is worth checking properly if this section is ever revised.

The salt-water float test

The usual alternative to rolling, and the one the hobby recommends: dissolve salt into warm water until a die floats, then spin it repeatedly and watch whether the same face keeps surfacing. It is a real test, and it is far quicker than the roll counts in the conversion. It also answers a narrower question than it appears to.

None of that changes the advice, because the advice never depended on bias being hard to find. A die whose bias needs salt water to reveal is a die whose bias costs a seed nothing.

The dice-in-a-box simulation

The claim in §4 that a mixed handful beats a matched set is ours, not a measurement, and it is computed by dice_tendice_box.py. Each of 4,000 trials draws ten dice whose per-face weights are perturbed by a gaussian of a given severity; a pool of n reads the first n of those ten, so the columns compare the same dice rather than independent redraws. Min-entropy in bits per roll, against 2.585 for a perfect die.

Worst face12345678910Gain
2% unfair2.5582.5662.5692.5712.5732.5742.5752.5752.5762.576+0.019
6% unfair2.4952.5212.5332.5402.5442.5482.5512.5532.5552.556+0.061
13% unfair2.4122.4612.4832.4962.5052.5122.5182.5222.5262.529+0.117
26% unfair2.2652.3492.3902.4132.4302.4432.4532.4612.4672.472+0.207

The throwing-dynamics figures

M. Kapitaniak, J. Strzalko, J. Grabski and T. Kapitaniak, “The three-dimensional dynamics of the die throw”, Chaos 22(4), 047504, 2012. A three-dimensional model of a die bouncing on a table with dissipation, compared against high-speed camera observation.

The figures quoted in §4 are from their basin-of-attraction analysis for a cubic die, where they define the average probability that the die lands on the face which was lowest at the start:

These are model results checked against experiment, not a throw-count measurement, which is a weaker kind of evidence than the dice-fairness counts. The direction of the effect, that insufficient bouncing preserves the starting orientation, is the robust part.

Why §4 does not convert this into seed bits. The probability is conditional on the starting orientation. If that orientation is itself uniformly random, the marginal distribution over faces stays uniform and no entropy is lost. The loss appears only through correlation: if the way you handle the die between throws makes each starting position a function of the previous result, the rolls stop being independent, and it is the independence rather than the per-roll distribution that the seed arithmetic assumes. We are not aware of a published measurement of how strong that correlation is for real human rolling and that is the honest gap here.

Converting a distribution into seed bits

This part is ours and it is the part to attack. dice_bias_analysis.py carries the measured distribution as a literal and prints every figure quoted in §2.

h    = -log2(max p_face)                 # min-entropy per roll, the worst case
bits = min(seed_size, num_rolls * h)     # SHA-256 treated as an ideal extractor

measured worst face 0.1688  ->  h = 2.566 bits/roll
  24-word: min(256, 99 * 2.566) = 254.1   ->  costs 1.9 bits
  12-word: min(128, 50 * 2.566) = 128.0   ->  costs nothing, 50 rolls carry 128.3

2% rounded up, used in §2  ->  h = 2.556 bits/roll
  24-word: min(256, 99 * 2.556) = 253.1   ->  costs 2.9 bits
  12-word: min(128, 50 * 2.556) = 127.8   ->  costs 0.2 bits
fair face   0.16667         ->  h = 2.585 bits/roll
  24-word: 255.9    12-word: 128.0

Robustness to the estimate being wrong

Every row below is the same conversion applied to a worse die. This is the table that makes the thin evidence base tolerable: the answer does not turn on getting the estimate right.

Worst face runsBits per roll24-word seed12-word seed
1.0% high2.571254.5, costs 1.5128.0, costs nothing
1.3% high, the measurement2.566254.1, costs 1.9128.0, costs nothing
2% high, what §2 uses2.556253.1, costs 2.9127.8, costs 0.2
3% high2.542251.7, costs 4.3127.1, costs 0.9
5% high2.515248.9, costs 7.1125.7, costs 2.3
8% high2.474244.9, costs 11.1123.7, costs 4.3

Where the chart's lines are actually crossed. Against a fair share of 16.7%, a 24-word seed does not fall to 128 bits until one face lands 40.8% of the time, and does not reach the 112-bit floor until 45.7%. A 12-word seed, carrying half as much, reaches that floor at 21.2%. All four are printed by dice_bias_analysis.py.

What would change this. A modern per-face study across many brands and many individual dice. We are not aware of one and its absence is the honest gap in §2. If you know of one or run one, the conversion is three lines and the ladder can be re-anchored immediately.

The two thresholds on the chart

The chart in §2 draws two lines. Neither is ours.

112 bits, the dashed line. NIST SP 800-57 Part 1 Rev. 5, Table 4: a security strength below 112 bits is disallowed for applying cryptographic protection, 112 is acceptable through 2030, and the accompanying text sets the expectation at “at least 128 bits in 2031.” Earlier drafts of this page used a 100-bit “practical floor” instead, which was invented rather than cited.

128 bits, the solid line. It is where NIST arrives in 2031, and it is also the point past which a Bitcoin key stops getting stronger. Pieter Wuille, on the recurring 12-or-24-words question, first the claim:

“cryptographically speaking, there is no benefit to private keys having more than 128 bits of entropy, as long as there is no pattern in them (e.g. don't use just 128 bit numbers as private keys, that's broken, but using the hash of 128 bit numbers appears to be just fine). The reason for suggesting more is just defense in depth.”

Then the reason:

“24 words = 256 bits, 12 words = 128 bits. But finding a private key given the public key already costs only 2128 operations (using e.g. Pollard's rho algorithm, not using brute force of course). So if an attacker can just attack the private keys that come out directly, there is no reason to try to find the seed.”

What a 50- or 99-roll guard can detect

The guards in §14 score the rolls the user just typed, which is a sample of 50 or 99. That is far too small a sample to characterize a die, and both common guard designs inherit the problem. Computed by dice_shannon_scoring.py and dice_coldcard_crosscheck.py, both seeded, so they reproduce exactly.

A fair die does not score 2.585. A Shannon estimate over a short sample runs low, by about (K−1)/(2N ln 2), so a threshold has to sit below the fair-die average by enough to clear its spread as well:

Fair-die averageSpread to the 0.1st pctUsable threshold
99 rolls2.5480.109 bits2.439
50 rolls2.5110.232 bits2.279

18Where each row was read

Each was read from source at a pinned commit, not from documentation, except where the method is a document: the worksheet procedures are first-party PDFs and help articles, cited as such.

What the chart was checked against

This is a source read, not an audit. Each row records the arithmetic an implementation applies to your rolls, traced in the code at the commit pinned for it in the table that follows. The code around it was not reviewed and nothing in a row is a judgment about the software as a whole.

Nothing here was run on the hardware. The constructions were checked by recomputing them with an independent BIP-39 encoder written for the purpose and validated against the official test vectors. That establishes what the published code does, not what a particular build on a particular device does.

Sharing a column is not a promise that two implementations interchange. They agree only where the roll count and the word length agree too. Several are narrower than their row suggests: Krux matches on its D6 path and not its D20 one, Seed Tool on its hashed mode and not its raw one, Gordian Seed Tool for iOS at 12 words with no 24-word path at all. The survey carries the qualification row by row.

And some rows cannot be source-verified by anyone outside the vendor. Ledger's onboarding code is closed, Nunchuk's iOS repository returns 404, and seedtool.info's dice behavior sits inside a WASM build that was not disassembled.

Appearing in this chart 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 hashed method 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 §20, 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 recorded here is what an implementation does with your rolls. Nothing about that speaks to the rest of a device, its firmware, or the parts of it a dice roll never touches.

ImplementationLanguageSource
Signing devices
SeedSignerPythonSeedSigner @ 0.8.7 and tools_views.py for the final word
ColdcardMicroPythonColdcard/firmware @ 3238f6fd
KruxMicroPythonselfcustody/krux @ 7ea3f95
KernCodudex/Kern @ 0.0.15 and manual_input.c for the final word
KeystoneCkeystone3-firmware @ 3.0.2
BitBox02Rust and a PDFbitbox02-firmware @ v9.26.4, plus the vendor's lookup table
Blockstream JadeC and a help articleBlockstream/Jade @ 1.0.40, plus its dice article and the 17-page guide it links
Foundation PassportMicroPython and RustCore: passport2 @ v2.3.11. Prime: KeyOS @ v1.3.1, a separate codebase reaching the same behavior
SparrowJavasparrowwallet/sparrow @ 2.5.3
Specter DIYMicroPythonspecter-diy @ v1.10.4
Software tools and apps
AirGap VaultTypeScriptairgap-vault @ aa50b7f
Gordian Seed ToolSwiftGordianSeedTool-iOS @ 1.6
Gordian seedtool-cliC++BlockchainCommons/seedtool-cli
Seed ToolJavaScriptBitcoinQnA/seedtool, web or signed download
iancoleman.ioJavaScriptiancoleman/bip39 @ de71c22, web or signed download
BlueWalletTypeScriptBlueWallet @ 8.0.1
Libraries
RooSoft/bitcoinlibElixirRooSoft/bitcoinlib @ a998a61

The full reading, including the wallets that turned out to offer nothing and the traps that produce wrong answers in both directions, is in evidence/wallet-dice-survey.md beside this document.

19Surveying a wallet that is not here

This section is written for whoever adds the next row, which in practice is often a model. Pointing one at this section and at the chart in §7 is the fastest way to get a wallet classified correctly and the method is short enough to be worth reading yourself if you want to know how much a row is worth.

A row has to answer seven questions, one per column: which of the four constructions the implementation applies to your rolls, whether it will complete a phrase you built by hand, whether its vendor publishes the worksheet that method needs, and whether anything the device generated is blended in.

The two traps

Both of these produced wrong answers in the survey behind this document and each was caught only after the wrong answer had been written down.

Searching firmware for dice arithmetic, finding none, and concluding “no dice support” misclassifies BitBox02, Jade, and Passport. All three ship a feature built for hand-made seeds and two of the three publish dice instructions themselves. Their firmware contains no dice arithmetic because the arithmetic is the user's job. The feature is a lookup table in a PDF plus a checksum solver in the device.

Reading the seed-generation path, finding a call to the system RNG, and stopping there misclassifies Sparrow. Its last-word calculator sits on the seed-entry path, not the generation path, and its own documentation describes neither of the two features that put it in the chart. The affordance is not always where the entropy is and it is not always written down.

Why grep alone answers wrongly in both directions

The only method that gets both directions right is to read the seed-creation path, the release notes, and the vendor's own documentation. Any one of the three alone will be wrong about some wallet in the chart.

What a new row has to carry

  1. A pinned tag or commit and the specific lines that do the arithmetic. Not a branch, so the line numbers stay true.
  2. Which column or columns, with the one-line reason. More than one is common and a mode name usually belongs in the reason.
  3. The limits: enforced roll counts, available word lengths, and whether extra rolls are accepted. These are where implementations of the same construction stop being interchangeable.
  4. What you roll, since not every method is six-sided.
  5. What could not be established, stated as such. The chart carries a mark for that and an honest blank is worth more than a guess.

Two negative findings in §13 show the standard being applied to itself: Ledger's onboarding firmware is closed source and Nunchuk's iOS app is closed, so both entries rest on documentation rather than a source read, and both say so.

20The case against dice, and what happened to it

Not everyone thinks the trade is worth it. Foundation, who make Passport, ship the final-word feature but advise against dice. Their then-head of strategy argued publicly in 2024, in a personal post on a third-party forum rather than as company policy, 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 and wallets were drained at scale. 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, in these words: “Coinkite sets the exception at at least 50 fair, independent and private rolls, and considers such a seed not at risk from this RNG issue alone.” 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.

All three qualifiers are things this page already asks of you. Fair is §2, where the answer is that the dice you already own qualify. Independent is the thorough tumble of §4. Private the disclosure glosses itself: “nobody watched, filmed or logged the rolls, because entropy that someone else saw is not entropy any more.”

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.

The procedural half of that objection is undiminished and the specific failure it describes is one the better implementations already prevent, by refusing to proceed below the required roll count.

21Corrections

Substantive changes made after publication are recorded here, with what changed and why. Revisions made while drafting are not corrections and are not listed.