Coldcard's Random Number Generator Was Reading the Clock, Not the Chip
A one-line refactor in March 2021 pointed Coldcard seed generation at a software formula instead of the hardware noise source. Five years later, roughly 594 BTC left about 500 addresses in under half an hour.
Somewhere between March 2021 and last week, a Coldcard asked for 32 random bytes to build a seed phrase. It got back a number computed from its own factory serial number and two countdown timers. The bytes looked perfect. They always do.
The seed is a number, and the number was small
The security of the whole arrangement rests on the number being genuinely unpredictable, and the word doing the work in that sentence is genuinely. A number looks equally random whether it came from physical noise or from a formula, and no statistical test worth running will tell you which one you got.
What the firmware did instead
The STM32 microcontroller inside every Coldcard has a true random number generator built in, a physical noise source, exactly the right tool. Coinkite wrote their own wrapper around it and deliberately switched off MicroPython's version so nothing else would reach for that peripheral behind their back. It was a careful decision -- and it is the one that set the trap.
Firmware 4.0.0 shipped a large migration onto Bitcoin Core's libsecp256k1. Seed generation stopped calling Coinkite's own function and started calling the equivalent from their new crypto library. A one-line change with no behavioural difference, on paper.
That call landed on a piece of code with two possible implementations behind a single name. One reads hardware noise. The other is a small software formula MicroPython ships as a courtesy for chips that have no generator of their own, fine for shuffling a list and catastrophic for minting a private key. A configuration flag decided which one you got, Coldcard set that flag to off, and the library checked whether the flag existed rather than whether it was on. It existed. The software formula won, with no compiler warning and no linker error to mark the moment.
Why a serial number is not a secret
That software formula seeds itself once, on first use, from the chip's factory unique ID and two timers.
The unique ID contributes nothing. It is a permanent, structured factory label, largely shared across devices from the same production run, and the Coldcard displays it to you as a serial number. It is a name tag, not a secret. That leaves two timers measuring the same thing -- how long the device has been powered on.
Published estimates put the result at roughly 40 bits on Mk2 v4 and Mk3, and roughly 72 bits on Mk4, Mk5 and Q. Both Coinkite and Block's independent analysis are explicit that these are upper bounds calculated under assumptions that inflate them, so the real figures are lower.
Which devices carry it
| Model | Firmware when the seed was created | Estimated entropy |
|---|---|---|
| Mk3 and Mk2 v4 | 4.0.1 through 5.0.3 | ~40 bits |
| Mk4 and Mk5 | anything before 5.6.0 | ~72 bits |
| Q | anything before 1.5.0Q | ~72 bits |
Seeds created before March 2021 on firmware 3.x sit outside that table, as do seeds you generated elsewhere and imported, and seeds built from dice rolls. Note what the table is keyed on: the firmware version at the moment of creation, which is a fact about your past, not about the device sitting in front of you now.
There is no way to test your own seed
No tool, no inspection, no clever check will tell you whether a particular set of words was born with 40 bits or 128. Provenance is the only evidence you will ever have: model, firmware version, generation method, date.
If you genuinely cannot remember, treat the seed as affected. And treat anyone offering you a seed checker as an attacker, because that is what they are.
Two things that buy you time
A strong BIP-39 passphrase sits on top of the seed and contributes its own entropy, so a passphrase-protected wallet is meaningfully harder to attack. This only counts if the passphrase is genuinely high-entropy rather than something you can recall on demand.
Multisig did its job here. The July sweep took single-signature wallets, and an attacker who reconstructs one key of a 2-of-3 still cannot spend. Rotate that key, but rotate it calmly.
Moving off an affected seed
The most common way people lose money after an incident like this is not the original attacker. It is haste.
- Rank your own exposure. Mk3 or Mk2 v4, single-sig, no strong passphrase is an active emergency, because that is precisely the profile that has already been drained. The ~72 bit devices are out of reach of any known technology and can be migrated deliberately over the coming days.
- Update the firmware from Coinkite's own site with the signature verified. Mk4 and Mk5 to 5.6.0 or later, Q to 1.5.0Q or later. Mk3 is discontinued, so check the official advisory for whether a fix exists for your model at all.
- Generate the new seed from dice. Around 99 rolls of a single D6 gives you 256 bits, about 50 gives you 128. This is the feature that exists so you never have to trust a manufacturer's generator.
- Back it up and verify the backup before a single satoshi moves, reading the words off the steel rather than off the screen.
- Test with a small amount first, confirm it arrives and confirm you can spend it back out, then move the rest.
- Retire the old seed permanently. Never receive to it again.
One caveat on step five. Sweeping every UTXO into the new wallet in one transaction publicly links your entire history, which is the exact failure mode covered in toxic change consolidation. At 40 bits, urgency beats privacy and you take the hit knowingly, then return to the habits in managing your bitcoin once the coins are safe.
Everything else that came from the same generator
Seeds were not the only output. Block's analysis lists paper wallet private keys, the random masks behind Seed XOR, ephemeral keys for cloning and encrypted USB sessions, Key Teleport temporary secrets, Web2FA TOTP material and Secure Notes passwords.
So: sweep any paper wallet generated on an affected device, treat any Seed XOR split performed on one as having a degraded margin, regenerate Web2FA, and rotate any password the device produced for you. If the old seed appears anywhere in your inheritance plan, that document needs updating too.
The fake seed checkers are already here
Within hours of any public incident come the fake support accounts, the "check if your wallet is affected" pages, the recovery services and the urgent firmware links. They will be well made and they will find you.
One rule, no exceptions: your seed words never leave your steel backup and your own device. Not into a checker, not into a support chat, not into a recovery tool. Coinkite will never ask. Nobody legitimate ever does.
What actually protected people
The chip was fine. The algorithm was fine. The hardware generator was sitting right there, unused, while three individually correct pieces of software agreed on the wrong answer between them. It stayed hidden for five years because broken entropy produces output that looks exactly like working entropy, which is the same reason the Debian OpenSSL failure of 2008 and the Android SecureRandom failure of 2013 both ran for a long time before anyone noticed.
The people who came through this untouched mostly did one of four things. They rolled dice instead of trusting the device. They spread keys across a multisig with devices from different manufacturers. They used a generated passphrase rather than a memorable one. Or they simply wrote down which device and which firmware made each seed, which is the cheapest habit on this list and the one that turns the next advisory into a five-minute question instead of a week of dread.
Once the coins are sitting in the new wallet, see what the chain is now revealing about you with the privacy analyzer, free and with no signup, run against our own Bitcoin node.
Last updated: 2026-07-31