COLDCARD vulnerability what happened, and what to do
Informational only, and this site never asks for your recovery words. details

Informational only. This is independent analysis and an evidence-backed explainer, not financial, security or legal advice, and not a substitute for professional advice about your own situation. It is not affiliated with, endorsed by, or speaking for Coinkite, Block, or any other party named here. Published estimates are attributed, and differing scenarios are kept separate with their assumptions. Act on your own judgement. Editorial standards and corrections.

Do not disclose recovery material to a website, form, message or support account. This site never asks for it. Deliberate recovery on independently verified offline equipment is a separate operation. Seed-word safety.

COLDCARD Mk3 entropy reference

keychainx-reference

https://keychainx.io/reference/coldcard-mk3-entropy/

Organisation
KeychainX
Evidence role
Secondary analysis
Published
not established
Source changes
0
Detected differences
0
Unreviewed
0
Copies held
1

Reference write-up carrying 594.48 BTC (~US$38M) confirmed and 1,082.59 BTC if the earlier set is linked. KeychainX is a wallet-recovery firm and says so on the page; that commercial context applies to their framing, not to the figures, which restate Hamilton and Block.

Every check is recorded, including checks that found no text change. A detected edit is therefore bounded between two checks. The publisher's exact save time is not observable from this record. Last checked 2 Aug 2026, 01:00 UTC.

  1. Earliest copy held Current
    seen 1 Aug 2026, 02:53 UTC · Captured here text sha256 43b3ca07529cbdc3334ef489 23,424 chars
    Extracted text as captured
    Skip to content
    home
    services
    FAQ
    wallets
    case studies
    references
    blog
    contact
    The Coldcard Mk3 Entropy Flaw: How a Skipped Hardware RNG Exposed BIP39 Seeds
    The Coldcard Mk3 Entropy Flaw: How a Skipped Hardware RNG Exposed BIP39 Seeds
    TL;DR: A firmware integration mistake caused affected Coldcard devices to generate wallet seeds from a predictable software random-number generator instead of the intended hardware one. The weak randomness entered production in firmware 4.0.0 (March 2021). On Mk3, effective entropy collapsed to roughly 40 bits — low enough to brute-force. Newer Mk4, Q and Mk5 are better but still fall short of the 128-bit target (~72 bits by the maker’s own estimate). On 30 July 2026, about 594 BTC was swept from ~500 single-signature wallets in roughly 25 minutes; researchers suspect, but have not proven, that the two are linked, and the total may be larger. A BIP-39 passphrase or a seed built from real dice rolls is considered safe from this specific flaw. If neither applies to your seed, treat it as at risk and migrate.
    This entry documents what is currently known about the Coldcard seed-generation entropy flaw disclosed on 30 July 2026. It sits in our reference catalogue alongside Randstorm, MilkSad, the Trust Wallet LCG bug and the 2014 Ethereum presale key-generation flaws — all members of the same family: a cryptocurrency wallet whose private keys were derived from a random-number generator that was not actually random. This is an evolving disclosure; figures and attribution below are current to 31 July 2026 and will be updated as Coinkite’s formal technical review and further on-chain analysis land.
    What is entropy, and why does a weak RNG break a wallet?
    A BIP-39 seed phrase is a human-readable encoding of a random number. A 12-word phrase encodes 128 bits of entropy; a 24-word phrase encodes 256. The security of every key derived from that seed rests entirely on that number being genuinely unpredictable. 128 bits of real entropy is unsearchable — there is not enough energy in the observable universe to enumerate 2128 possibilities.
    But if the generator that produced that number can only ever emit, say, 240 distinct outputs, then the seed — no matter how it looks written on the card — is one of about a trillion possibilities. An attacker who understands the generator can produce every candidate offline, derive each candidate’s public addresses, and check them against the blockchain. When a match is found, the funds are theirs. The wallet’s cryptography was never broken; the randomness feeding it was. This is the exact mechanism behind Randstorm, MilkSad and the Trust Wallet LCG bug, and it is the mechanism here.
    The July 2026 sweep: what happened on-chain
    Between roughly 01:31 and 01:56 UTC on 30 July 2026 — a window of about 25 minutes spanning Bitcoin blocks 960188 to 960191 — approximately 594.48 BTC (about $38 million at the time) was swept out of around 500 single-signature addresses. AnchorWatch co-founder Rob Hamilton, who published an early on-chain breakdown, counted 1,324 spent outputs moved across roughly 500 transactions inside that three-block window, with about 562 BTC then consolidated into a single address that has not moved since. Hamilton’s first-pass read was that the pattern pointed to flawed entropy in wallet generation somewhere along the path.
    Three details make the event look automated rather than manual, and consistent with an entropy attack. First, the extreme compression — hundreds of independent single-sig wallets drained in one tight window — is what a script firing against a pre-computed list of vulnerable keys looks like. Second, the drained wallets clustered in a narrow balance band, reportedly roughly 0.15 to 0.26 BTC each: the operator set a value floor and worked by expected payoff, which is rational when each candidate key costs compute to test. The affected coins spanned 2021 to 2026 — almost exactly the lifetime of the flaw. Third, researchers including Wizardsardine’s Kevin Loaec noted the sweep concentrated on BIP-84 native SegWit derivation paths, and Jameson Lopp reported that some wallets were only partially drained — consistent with a tool enumerating a limited derivation-path space rather than exhaustively emptying every address. The practical corollary, which Loaec flagged, is that a partially-drained wallet is not a safe wallet: the remaining balance can be taken in a later pass.
    The number may not be final. Block security engineer Clay Garrett reported 695 earlier transactions carrying the same on-chain fingerprint as the confirmed set, accounting for a further 488.11 BTC. If those are part of the same operation, the total would rise to about 1,082.59 BTC (on the order of $70 million). That linkage is not confirmed, and neither Coinkite nor any researcher has established definitive public proof that the sweep exploited the Coldcard flaw specifically rather than another weak-entropy source. The timing and the technical fit are strong; the causal chain is not yet proven.
    How the disclosure unfolded
    The response happened in public and fast, over a single day, which is worth recording because it shaped the early reporting:
    01:31–01:56 UTC, 30 July: the sweep executes across blocks 960188–960191; 562 BTC is consolidated to one address.
    Midday, 30 July: the first affected users report drained wallets publicly.
    ~17:35 UTC: Wizardsardine’s Kevin Loaec asks Coldcard holders to check their balances, following up that it was not a false alarm.
    ~18:10 UTC: Coinkite CEO Rodolfo Novak (NVK) responds publicly, initially attributing the reports to an individual compromised or leaked seed rather than a device-wide flaw — the assessment the company would revise within hours.
    Later, 30 July: Coinkite publishes its Mk3 Security Advisory, scoping the risk to Mk3 firmware 4.0.1–5.0.3 and stating Mk4/Q/Mk5 appeared unaffected on early analysis.
    30–31 July: Block’s Bitcoin Engineering and Security team independently root-causes the bug, discloses privately to Coinkite, then publishes. Coinkite follows with a technical backgrounder that expands the scope to Mk4/Q/Mk5 (~72-bit) and ships emergency hotfix firmware — 5.6.0 for Mk4/Mk5 and 1.5.0Q for Q.
    The takeaway for anyone reading older coverage: the initial “Mk3-only, newer models safe” framing — which several outlets captured — was superseded the same day. Treat any account that still says Mk4/Q/Mk5 are unaffected as out of date.
    Root cause: the wrong random-number generator came along for the ride
    The technical mechanism is now documented in Coinkite’s own backgrounder and in an independent report from Block’s Bitcoin Engineering and Security team. It is a chain of small, individually plausible mistakes that combined into a serious one.
    Coldcard’s firmware is built on MicroPython, which ships two random-number implementations behind a single function name: the STM32 chip’s true hardware RNG, and a deterministic software fallback (a Yasmarang-family PRNG) for boards that lack hardware support. Which one compiles in is chosen by a build macro, MICROPY_HW_ENABLE_RNG. Because Coldcard provides its own separate hardware-RNG wrapper, the maker set that macro to zero, intending to use neither MicroPython path. Setting it to zero, however, does not disable MicroPython’s generator — it selects the software fallback.
    That alone should have been caught, and there was a guard meant to catch it. But the guard in the supporting library (libngu) was written with #ifndef — it checked only whether the macro was defined, not whether it was enabled. A macro defined as 0 is still defined, so the guard passed, the build succeeded with no error, and the wallet-generation path silently bound to MicroPython’s software fallback. The carefully written hardware-RNG code the maker intended to use was still present in the binary — it was simply, by accident, only being used for less important things. Prior security review had confirmed the correct code existed in the firmware; it had not verified which implementation the seed-generation path actually reached across the two submodules.
    What was the fallback seeded from? On first use it initialised from the MCU’s unique ID (fixed factory metadata, partly exposed as the device’s USB serial number) XOR’d with the SysTick counter, plus two real-time-clock registers. None of these is a cryptographic secret. The UID is fixed and readable; the timer values are constrained, correlated, and on some cold boots effectively static. After that single initialisation, no fresh entropy was collected — every subsequent output was a deterministic step from that state. So for a known device and call history, the entire seed was reproducible.
    Both Coinkite and Block describe their analyses as preliminary. Block published its report before completing full empirical testing of exploitability, stating plainly that it did so because active exploitation was already under way, and it defers to Coinkite’s forthcoming definitive technical review. Block also noted that none of its own products or customers — including its Bitkey wallet — are affected, since they do not share this codebase. Independent corroboration arrived quickly: Bitcoin Core contributor instagibbs reproduced the Mk2/Mk3 path on a fresh device, and multiple researchers converged on the same weak-entropy conclusion.
    Why the numbers differ: 40 bits vs 72 bits
    The severity depends on the device generation, because Coldcard’s later hardware mixed in a little extra material:
    Mk2 / Mk3 (firmware 4.x through 5.0.3): no cryptographic entropy reached the generator at all. For a known UID, timer state and call history the output is fully deterministic. Coinkite’s preliminary estimate of the effective search space is about 40 bits; Block’s loose upper bound with hidden timers is under 241. Either way, this is inside brute-force range.
    Mk4 / Q / Mk5: these devices added secure-element entropy from SE1 and SE2 at boot — but the reseed kept only four bytes of the hashed result and overwrote just a single 32-bit word of the generator’s state. That caps the securely-distinguished search space at 232 (about 231 on average), roughly 72 bits under the maker’s framing. Meaningfully harder than the Mk3, still far below the 128-bit standard, and a target that a well-resourced adversary cannot be assumed unable to reach. Hashing the output with SHA-256d and adding the BIP-39 checksum does not help: deterministic post-processing cannot manufacture entropy that was never in the input.
    Upgrading the firmware does not repair a seed that a vulnerable version already generated. Exposure tracks the firmware that was running when the seed was created, not the device’s manufacture or purchase date, and not its current firmware. The only fix for an affected seed is to generate a new one correctly and move the funds.

    Excerpt only. The complete copy is held offline and backs quotations on this site. The original publication remains the canonical public source.

How to check this yourself

Each copy above is identified by the SHA-256 of its extracted text, shown beside it, and the diffs are plain unified diffs. To verify a quotation, compare it against the page itself or against the Internet Archive's copies, which are independent of this project.

Complete captures are held offline rather than mirrored here, so this page shows diffs and excerpts. If a quotation is ever disputed, the full copy can be produced. Ask.