Skip to content
Cutaway cross-section of a hardware wallet board: the hardware random number generator die sits dark with its bond wires ending at bare pads, while a small brass counter wheel is wired into its place and the seed register beside it stays mostly empty.
exploitsAugust 3, 20264 min read

Coldcard's $88.6M Entropy Failure: Five Years of Guessable Bitcoin Seeds

Aron Turner
Aron TurnerCo-Founder & CTO

Updated on August 3, 2026

TL;DR

Between 01:10 and 01:51 UTC on July 30, 2026, someone swept 1,082.65 BTC out of 1,196 Bitcoin addresses in a single 41-minute window, according to Galaxy Research's on-chain mapping. Two further waves followed. As of August 2 the running total stands at 1,367.05 BTC, roughly $88.6 million, across 4,585 addresses, and the figure has risen with every fresh analysis. The cause traces back to a single firmware change Coinkite made in March 2021: seed generation was pointed at a software pseudorandom number generator instead of the Coldcard's hardware RNG. Devices kept producing twelve-word seed phrases that looked completely normal and were drawn from a search space small enough to enumerate. Nobody had to touch a wallet. Every other security property of a hardware wallet sits downstream of one number being unguessable, and for five years that number was guessable.


What Actually Happened to Coldcard Users?

Nothing the victims did was wrong.

Coldcard is an air-gapped Bitcoin hardware wallet made by Coinkite. It is the device you buy when you have decided to take custody seriously: no USB data path required, a secure element, open firmware, reproducible builds. Its users are the people who read the documentation and learned to verify a signature. That population is exactly who lost money here.

On July 30, Coinkite published a security advisory warning that seeds generated on affected devices may be compromised. The affected ranges are wide. Mk2 and Mk3 devices running firmware 4.0.1 through 4.1.9 inclusive, all Mk4 and Mk5 firmware before 5.6.0 standard or 6.6.0X Edge, and all Q firmware before 1.5.0Q standard or 6.6.0QX Edge. Coinkite's own estimate of the damage to key strength is blunt: seeds on Mk4, Q and Mk5 carry "about 72 bits of entropy rather than the expected 128 bits," and the backgrounder puts Mk2 and Mk3 at "about 40 bits."

A twelve-word BIP-39 seed is supposed to represent 128 bits of entropy, which puts it permanently beyond enumeration. At 40 bits the search becomes tractable on rented hardware.

The advisory itself makes no claim about stolen funds. Coinkite has not stated that the entropy defect caused the thefts, and its investigation is described as ongoing.


How Does a Hardware Wallet's Entropy Actually Fail?

Entropy is the amount of genuine unpredictability behind a key. A hardware wallet earns its price by drawing that unpredictability from a physical source, in this case the STM32 chip's hardware random number generator, rather than from anything a program could recompute later. Take that physical source away and substitute a deterministic algorithm seeded from ordinary device state, and the wallet still hands you a valid looking seed phrase. It just hands out phrases from a menu.

The substitution happened during a library migration. Coinkite's technical backgrounder describes the move from ckcc.rng_bytes() to ngu.random.bytes() as part of the libNgU integration, and that new path "resolved rng_get() to MicroPython's software fallback instead of COLDCARD's hardware RNG implementation."

The build should have caught it. Two things stopped it from doing so.

First, the developer set MICROPY_HW_ENABLE_RNG to zero, intending to disable both implementations. The preprocessor guard tested with #ifndef rather than checking whether the value was nonzero, so setting the flag to zero still counted as defined, and the fallback PRNG compiled in anyway. Second, the fallback shared a function signature with the intended hardware implementation, so "the build completed without identifying the wrong implementation." The hardware RNG code stayed in the binary the whole time. It was simply never the thing being called.

That is the entire defect. A correctly signed, correctly linked, silently wrong implementation, sitting inside firmware that was open source and reproducibly built for five years.

On the affected Mk2 and Mk3 units the replacement PRNG was "seeded primarily from device and timing state," which is why Bitcoin Core developer Gregory Sanders was able to reproduce the attack using setup button press counts. The seed was a function of how a person pressed buttons during setup. Later models fared better only because the SE1 and SE2 secure elements mixed in extra material, which is where the 72-bit figure comes from.


The Attack, Step by Step

#StageWhat happened
1March 2021A library migration repoints seed generation from ckcc.rng_bytes() to ngu.random.bytes(); the #ifndef guard lets the software PRNG compile in.
22021 to 2026Every seed generated on affected firmware is drawn from a reduced search space, roughly 40 bits on Mk2/Mk3 and 72 bits on Mk4/Mk5/Q. Devices show no symptom.
3Offline, date unknownAn attacker enumerates candidate seeds, derives the addresses each would produce, and matches them against funded addresses on the public chain. No device access, no phishing, no user interaction.
4July 30, 01:10:20 to 01:51:26 UTCWave one: 1,082.65 BTC swept from 1,196 addresses across blocks 960,183 to 960,191, every sweep paying an identical 30.0 sat/vB fee with no change output.
5July 30 to 31, after the sweepCoinkite publishes its advisory and ships emergency firmware: 4.2.0 for Mk2/Mk3, 5.6.0 and 1.5.0Q standard, 6.6.0X and 6.6.0QX Edge.
6August 1 to 2Two further waves. Galaxy Research revises the total to 1,367.05 BTC across 4,585 addresses, the last wave targeting far smaller balances.

Note what is absent from that table. There is no compromised update server, no malicious dependency, no stolen signing key, no tricked user. Note the order, too. The sweep came first and Coinkite's warning followed it, so the attacker was not racing a public advisory. They found the defect independently, built tooling for it, and chose when to move.


Why Did the Loss Figure Keep Changing?

Four different numbers circulated in four days, and the spread is worth explaining because it tells you how this kind of incident gets measured.

The earliest reports put it at roughly $38 million from about 500 wallets in 25 minutes, a figure that also appeared as approximately 594 BTC. That was a first pass over the most visible sweeps. Fuller on-chain mapping by Galaxy Research expanded wave one alone to 1,082.65 BTC from 1,196 addresses, around $70.2 million, which is where CoinDesk's initial account landed. Then two more waves arrived, taking the total to 1,367.05 BTC and about $88.6 million across 4,585 addresses.

None of those figures were wrong when published. They are successive lower bounds on a set that gets larger as analysts identify more addresses derived from vulnerable seeds. Treat 1,367.05 BTC as the confirmed floor as of August 2, not the final loss.

The victim distribution deserves more attention than the headline. Most affected wallets held less than 1 BTC, while the majority of the stolen value came from the larger ones. So the money is concentrated and the damage is not. Several thousand people who bought a reputable device and followed the instructions lost a small position each.


What Does the Attacker's Tradecraft Tell Us?

The sweeps carry a clear operational signature. Galaxy Research found that "every sweep paid an identical hardcoded 30.0 sat/vB fee, a 30-to-75x overpay versus the 0.4-to-1.0 sat/vB median that week, and left no change output."

Three things follow from that. The tooling was automated and written in advance, since no human picks the same fee 1,196 times. The operator optimized for confirmation speed over cost, which is what you do when you expect a disclosure to trigger a race. And the absence of change outputs means each address was emptied in full, so the tool was working from a list of known compromised keys rather than probing.

The waves also show a playbook adapting. Wave one took the large balances. The final wave took roughly 208 BTC from 1,912 addresses, an average near 0.1 BTC, using transaction patterns Galaxy described as more complex and harder to trace. Having exhausted the profitable targets, the operator went down market and improved their laundering hygiene at the same time.

Attribution stops short of certainty, and the analysts say so. Galaxy believes each wave is the work of a single operator but cannot determine whether the same party is behind all three, since the chain does not reveal whether separate sweeps are coordinated. Most of the coins remain parked in a handful of addresses under the attacker's control, and TFTC's account of Galaxy's tracking puts roughly 600 suspected attacker addresses in the hands of federal investigators. No public report has the coins reaching a mixer or an exchange, so for now the trail ends at addresses rather than at a cash-out, which is unusual at this size and worth watching.

One honesty note that matters. The causal chain from entropy defect to these specific thefts is strongly supported and not formally demonstrated in public. Coinkite has confirmed the defect. Sanders reproduced the seed derivation on test devices. Galaxy reports that all compromised addresses were created after the vulnerable firmware shipped in March 2021. But no public report has reconstructed a victim's seed and matched it to a drained address, and no brute force benchmark has been published showing what a 40-bit or 72-bit search actually costs in practice. Treat the mechanism as confirmed and the end-to-end proof as still outstanding.


Why Open Source and Reproducible Builds Did Not Save Anyone

There is a comfortable belief in this industry that sufficiently public code is safe code. Coldcard had every property that belief rewards. The firmware is open. The builds are reproducible. The user base is unusually technical and unusually motivated. The defect still lived in shipped firmware for five years and three device generations.

It survived because it was invisible to every check that was actually running. A reproducible build proves the binary matches the source. It does not prove the source calls the function you meant. A code review sees ngu.random.bytes() and reads it as a random number call, which it is, just not the one anyone intended. The output of a broken PRNG looks exactly like the output of a good one. There is no failing test, no crash, no warning, no visible symptom anywhere on the device.

This class has a long lineage. In 2008, a Debian specific patch cut OpenSSL's entropy source down to the process ID, leaving only 32,767 possible outcomes for a given key type and size. In August 2013, a weakness in Android's SecureRandom left Bitcoin wallet apps generating repeated values inside their signatures, exposing the private keys behind them to anyone reading the chain, which bitcoin.org warned about at the time. Same failure mode each time: a random source quietly stops being random, everything downstream keeps working, and the loss surfaces years later as money leaving addresses.

The control that catches this lives in the build itself: a known-answer test on the entropy path, asserting that the hardware source is the thing being called and that its output passes statistical checks before a seed is ever derived. Review alone does not reach it. That test is cheap. Its absence cost 1,367 BTC.


What Should Operators and Holders Do Now?

  1. Rotate any seed generated on affected firmware, regardless of balance. Update to 4.2.0, 5.6.0, 1.5.0Q, 6.6.0X or 6.6.0QX as applicable, generate a fresh seed on the patched device, send a small test transaction, and only then move the remainder. A seed generated on vulnerable firmware stays vulnerable forever, because the weakness is baked into the key rather than the device.
  2. Check whether your seed had an independent entropy source. Coinkite states that a seed built with at least 50 fair, independent, private dice rolls is not at risk from this bug alone, and that a strong BIP-39 passphrase produces a separate wallet. If you used dice or a passphrase, verify the specifics before you relax.
  3. Treat firmware provenance as custody metadata. Record which device and which firmware version minted every seed you hold. Almost no one does this, which is why the current advisory forces thousands of people to guess. Any change to an RNG code path in a wallet you depend on should be treated as a rotation event, and our key compromise runbook covers the sequence for doing that under pressure.
  4. Add entropy source health checks to any build that touches key generation. A known-answer test that fails when the hardware RNG is not the active source would have caught this in March 2021. Pair it with a statistical check on generator output in CI.
  5. Monitor for sweep signatures if you hold at scale. An identical hardcoded fee across hundreds of unrelated addresses inside one hour is a detectable pattern. For custodians and treasury operators, that alert buys minutes to move unaffected reserves. It is worth being clear about what it does not buy.

That last point deserves the honesty it demands. Runtime monitoring would not have saved an individual holder here. The key was reconstructed offline, the sweep was a single confirmed transaction, and there was no window between the attacker's decision and the loss. Monitoring is a detection layer for this incident, not a prevention layer. The prevention layer was a test in a firmware build pipeline five years ago. When we review key management and wallet firmware, the build configuration and the sourcing of cryptographic primitives are the parts that carry this risk, which sits outside the application logic a standard contract audit scopes. Anyone selling you monitoring as the answer to this particular failure is selling you the wrong product.


Frequently Asked Questions

Which Coldcard devices are affected? Mk2 and Mk3 on firmware 4.0.1 through 4.1.9 inclusive, Mk4 and Mk5 on anything before 5.6.0 standard or 6.6.0X Edge, and Q on anything before 1.5.0Q standard or 6.6.0QX Edge. Coinkite's advisory is the authoritative list.

If my Coldcard was never connected to anything, am I safe? No. The weakness is in the seed the device generated, not in any connection it made. An attacker reconstructs candidate seeds offline and checks them against the public blockchain, so an air-gapped device that never touched a computer is equally exposed.

Is updating the firmware enough? No. Updating fixes future seed generation. Any seed already created on vulnerable firmware must be replaced and the funds moved to a wallet derived from a new seed.

How much entropy did the affected seeds actually have? Coinkite estimates roughly 40 bits on Mk2 and Mk3 and about 72 bits on Mk4, Mk5 and Q, against the 128 bits a twelve-word BIP-39 seed should carry.

Has anyone proved the entropy flaw caused these specific thefts? Not publicly, end to end. The defect is confirmed by Coinkite and the derivation has been reproduced on test devices, and every drained address was created after the vulnerable firmware shipped. No public report has yet reconstructed a specific victim's seed and matched it to a drained address.


Sources / References

Aron Turner
Aron Turner

Co-Founder & CTO

CTO of SigIntZero. Engineering leadership, infrastructure architecture, and security tooling.