Last week, more than 1,400 BTC was swept out of wallets in a series of coordinated drains, with a further 2,000 BTC or so suspected and not yet confirmed. Nobody was phished. Nobody lost their seed phrase. Nobody touched the victims' devices. A five-year-old firmware bug had quietly weakened the random number generation in the Coldcard, and every seed it produced during that window was computable by anyone who read the code.
The lesson is not "Coinkite is bad." The Coldcard team is genuinely good at this, and it still happened. The lesson is that a hardware wallet's most security-critical moment, generating the number everything else depends on, happens exactly once, in silicon, where you cannot watch. You are asked to trust it, and there is no way to check.
At Lygos we build non-custodial lending precisely because "trust us" is not a security model. Your Bitcoin collateral sits behind your keys, not ours. But that guarantee is only as strong as the seed behind those keys. If the seed was predictable, non-custodial just means nobody was holding the door when the thief walked through it.
There is one seed generation method where nothing is hidden: rolling dice.
Why dice work
When you roll 100 dice and feed the results into your wallet, you are the random number generator. The device's only remaining job is arithmetic, turning your rolls into the standard 12 or 24 seed words. And arithmetic, unlike a chip's internal state, is something you can reproduce on a second machine and check.
That is the entire trick. The bug that drained those wallets lived in the step you couldn't observe. Dice delete that step.
It is worth saying plainly: seeds generated with sufficient dice rolls were unaffected by the bug, on the very same devices, running the very same broken firmware. The dice path never touched the broken code.
"But my wallet has no dice option"
This is the most common objection, and it rests on a misunderstanding.
Your wallet does not need a dice mode. Seed words follow an open standard called BIP-39, implemented identically by every serious wallet. That means the job splits cleanly in two:
- Generate the words from dice, on any tool or device built for it.
- Import those words into the wallet you actually use, through its normal "restore from recovery phrase" flow.
A Trezor cannot take your dice rolls. It will happily take the words your dice produced. The same is true for a Ledger, a BitBox, or a phone wallet. The device that creates your seed and the device that holds it do not have to be the same device.
Here is the actual landscape, so you know what you're working with:
- SeedSigner: dice are its only entropy source, it forgets everything at power off, and it's about fifty dollars of parts. Our first pick for the generation job.
- Keystone: ready-made hardware with a dice mode and a published verification guide.
- Ian Coleman's BIP39 tool: free, open source, one HTML file you download and open on an offline computer. No hardware needed at all.
- Coldcard: has a dice mode that was never affected by the bug; a fine converter if one is already in your drawer.
- BitBox02 and Blockstream Jade: support dice through printed word-lookup tables, a different but workable method.
- Trezor, Ledger, and most phone wallets: no dice input. These are import destinations, not generators.
Never a website in your normal browser, and never an app on your phone. The generation step happens offline, every time, no exceptions.
The five rules that matter
- Roll 100 times. That covers a 24-word seed on every mainstream tool with margin to spare. More than that adds nothing. Any 19mm casino dice will do; a board game die is acceptable, precision dice are better.
- Write the rolls as one unbroken line of digits. No spaces, no dashes, no neat groups. A single space silently produces a different wallet.
- Take what the dice give you. Re-rolling results that "look wrong" is how people quietly weaken their own seed.
- Verify the conversion, then the wallet. First recompute the words from your rolls with a second independent tool, which is the check that catches a compromised generator. Use the offline Ian Coleman page if you generated on hardware, or Coinkite's public-domain rolls.py script if you're comfortable with a terminal. Then confirm the first receiving address matches one derived offline, with account type, derivation path, and passphrase identical on both sides.
- Keep the words, destroy the rolls. Only after both checks pass.
We've published the full walkthrough of these steps, written for a first-timer, as How to Roll Dice for Your Bitcoin Wallet, Step by Step.
Verify, don't trust, applies to your own wallet too
The Bitcoin ethos gets quoted a lot and practiced less. What we like about dice is that they turn a slogan into a fifteen-minute procedure: generate the entropy in the open, on a table, then make two independent tools agree about what it produces before a single sat touches the result.
That is the same principle our lending protocol is built on. Discreet Log Contracts let a borrower verify, rather than trust, what can happen to their collateral. Dice let you verify, rather than trust, the keys underneath it. Both replace a promise with a check.
For the full walkthroughs, including the exact menu paths, the verification scripts, and why two popular tools disagree about how many rolls you need, see the detailed guides on my personal blog: the beginner's guide and how to use dice with a Trezor, a Ledger, or any other wallet.
Roll your own. It is the one part of your setup you can check end to end, and after last week, checking is the point.

