All Posts
Security

The Most Trusted Bitcoin Wallet Was Guessing Its Own Keys for Five Years. 1,778 BTC Later, the Only Setups Still Standing Are the Ones That Never Trusted One Device.

August 15, 20268 min read

At 01:31 UTC on Friday, July 30, 2026, bitcoin began leaving wallets that were never supposed to be reachable. Twenty-five minutes later, 594.48 BTC — roughly $38 million — had been consolidated out of about 500 separate addresses, every one of them a single-signature wallet holding more than 0.15 BTC. There was no phishing campaign, no malware, no supply-chain interception, no compromised server, because there was nothing to compromise: these were Coldcards, air-gapped hardware signers from Coinkite, the devices that Bitcoin's most security-conscious users have recommended to each other for years precisely because they never touch the internet. The sweep did not stop. By August 4, Galaxy Research was tracking at least fifteen independent attackers working the same flaw, and the running total has since passed 1,778 BTC, somewhere near $130 million depending on the hour you price it, spread across thousands of victim addresses in successive waves. Forbes found a victim who summarized the whole event in four words: "I did everything right." He had. That is the part worth sitting with.

What broke is small enough to fit in a paragraph, which is what makes it so unnerving. Coldcard's board configuration deliberately sets the macro MICROPY_HW_ENABLE_RNG to zero, because Coinkite supplies its own wrapper around the STM32 chip's true hardware random number generator rather than using MicroPython's. Reasonable. But libngu, the cryptography library Coldcard adopted for seed generation, guarded its entropy source with a preprocessor directive that checked whether that macro was defined — not whether it was set to anything other than zero. The macro was defined. The check passed. The build succeeded with no warning, and the call bound instead to MicroPython's software fallback: Yasmarang, a small non-cryptographic pseudorandom generator initialized exactly once, from the MCU's factory-set unique ID exclusive-ORed with a millisecond countdown timer, plus two real-time-clock registers. None of those is a secret. None of them is random. After that single initialization the generator collects no fresh entropy ever again — every subsequent output is a deterministic state transition. Libngu then exclusive-ORs that stream with a second Yasmarang instance whose starting state is four hardcoded constants sitting in public source code, an operation that feels like it should help and mathematically cannot: XOR of two reproducible streams is a reproducible stream. There was even a health check. It rejected adjacent identical outputs, which a deterministic PRNG sails through effortlessly. Block's engineering team, which root-caused the failure alongside anonymous researchers and published within hours, traced it to commit b18723dd on March 1, 2021, released to users in firmware v4.0.0 on March 17. On Mk2 and Mk3 devices running that branch, once an attacker knows or constrains the UID, timer state, and call history, seed generation is not merely weak — it is deterministic, with a broad hidden-timer ceiling under 2^40.7 candidates. On current Mk4, Q, and Mk5 hardware, boot does mix in secure-element entropy, then hashes it and keeps four bytes, and the reseed function overwrites exactly one 32-bit state word: at most 2^32 distinguishable output streams, roughly 2^31 trials on average. The intended standard is 128 bits. Hashing the result with SHA256d makes it look uniform without adding a single bit, and the BIP-39 checksum adds none either.

Three consequences follow that most coverage has glossed. First, exposure is determined by the firmware running at the moment your seed was created, not by your device's age or your current firmware version — upgrading is essential going forward and does absolutely nothing to repair a seed already born weak. Second, if you ever exported that seed and restored it into a different wallet, phone, or vendor's hardware, the seed is still the compromised object; changing its container changes nothing, because the thing an attacker enumerates is the phrase itself. Third, and worst, this is now a public race rather than a private exploit. The root cause, the affected firmware ranges, the search-space arithmetic, and the source-code line numbers are all published, which was the correct disclosure decision given that theft was already underway — but it means the remaining vulnerable wallets are a shrinking pool being picked over by more than a dozen unrelated actors, and a validation oracle is free: derive a candidate seed, derive its addresses, check the public blockchain for a balance. Every unmigrated wallet is a lottery ticket that somebody else is holding.

Now the part that matters most for anyone deciding what to do next. Every wallet drained in the initial sweep was single-signature, and Unchained's analysis found that not one multisig arrangement was touched. That is not luck; it is arithmetic. In a single-sig wallet, one seed is the entire authorization, so a recoverable seed is a total loss. In a 2-of-3, an attacker who reconstructs one key holds a share and nothing more — the funds do not move until an independent quorum signs. But Block's advisory attaches a caveat that deserves to be louder than the headline, and this publication is not going to bury it: a multisig composed exclusively of vulnerable devices offers no protection whatsoever. If all three of your keys came off Coldcards running the affected firmware, an attacker who can enumerate one seed can enumerate all three, and your quorum collapses in the same sweep. Threshold security is only real when the failure modes of the participants are genuinely independent. Two other things saved people: a strong BIP-39 passphrase, because it is user-supplied entropy that never passed through the broken generator and therefore sits entirely outside the searchable space — Coinkite's advisory tells Mk3 users who generated without one to treat their funds as at immediate risk — and dice, with Coinkite stating that a seed built from at least fifty fair, independent, private rolls is not endangered by this bug alone. Every survivor of this event survived by introducing entropy or authority that the failing device did not control.

There is a detail in Block's report that should stop anyone who thinks of themselves as a careful backup architect, and it has gone almost entirely unreported. The same broken ngu.random stream feeds far more than wallet creation. It generates Coldcard's paper-wallet private keys, used directly as raw secp256k1 keys with no BIP-39 or BIP-32 derivation in between and a public address published as a ready-made oracle. It generates ephemeral keys for device cloning and USB encryption. It generates Key Teleport's temporary keys and secondary password. It generates Secure Notes passwords, where invoking the generator twice for the "dense" option yields two sequential draws from the same tiny state and doubles nothing. And — this is the one — it generates the random masks used by Coldcard's Seed XOR split when you choose the random-split mode. Think about what that means. Seed XOR exists so you can break one phrase into parts that individually reveal nothing, a defense in the same family as everything this site advocates. But if the mask is drawn from a generator with at most 2^32 reachable states, then an attacker holding a single share can enumerate candidate masks, reconstruct candidate original seeds, and check each against a public address until one matches. A splitting scheme is a mathematical guarantee resting on an assumption about randomness, and when that assumption fails, the guarantee does not degrade gracefully — it inverts. Coldcard's default deterministic split mode does not use this path and is unaffected, and the paper wallet's dice option bypasses it entirely. The lesson is general and it is not about Coldcard: the entropy underneath your backup scheme must be independent of the device whose failure the scheme is supposed to survive.

Which brings this back to the framework this blog keeps returning to, because Coldcard is a textbook case of correlated failure. A secret has a lifecycle: generation, storage, and use. The Ill Bloom disclosure in July was a generation failure. The SecondFi nonce catastrophe was a use failure. Coldcard is a generation failure that quietly contaminated the storage layer too, because the same device was the generator, the signer, and — for anyone using random Seed XOR or Key Teleport — the backup mechanism. One vendor, one library, one preprocessor typo, and three supposedly independent layers of your architecture fail at the same instant. The defense is not distrust of Coinkite in particular; the team disclosed fast, shipped fixed firmware, and the bug is the kind of build-configuration mismatch that has bitten serious cryptographic projects for decades. The defense is structural: make sure the thing that generates your entropy, the thing that signs your transactions, and the thing that holds your backup are not all the same thing. Add entropy the device cannot see — dice, a passphrase held in your head. Require a quorum drawn from genuinely different hardware and different vendors. Assume any single component you cannot personally audit will eventually be found to have been broken for five years, and build so that discovering it is an inconvenience rather than an obituary.

seQRets sits in the storage layer and is honest about that boundary. It cannot strengthen a seed that was generated weakly — if your phrase came off an affected Coldcard, no splitting scheme on earth will save it, and the only remedy is to generate fresh keys on hardware whose randomness is not in question and move the funds. What seQRets does is take a well-generated secret and make sure it never again exists as one complete copy anywhere: encrypted client-side, split into QR-encoded threshold shares using randomness supplied by your own device rather than by the wallet that holds your coins, distributed across the people and places you choose, with no servers, no accounts, and nothing on our side to breach. The thousands of people migrating off vulnerable Coldcards right now are about to create the most valuable secrets of their lives under time pressure. Where those new phrases land is the one part of this entire disaster that is still fully within their control.