Coldcard Hardware Wallet Firmware RNG Flaw (No CVE Assigned) Linked to $88.6M Multi-Wave Bitcoin Theft — Threadlinqs Intelligence
As of 2026-08-03, Coldcard Hardware Wallet Firmware RNG Flaw (No CVE Assigned) Linked to $88.6M Multi-Wave Bitcoin Theft is a critical-severity vulnerability threat, tracked by Threadlinqs Intelligence with 9 detection rules (Splunk SPL, Microsoft KQL, Sigma) and 24 indicators of compromise.
Threat ID: TL-2026-1835 · Severity: CRITICAL · Status: ACTIVE · Category: VULNERABILITY
A March 2021 firmware regression in Coinkite's COLDCARD Bitcoin-only hardware wallet caused wallet-seed generation to silently fall back from the on-chip STM32 hardware RNG to MicroPython's
COLDCARD hardware wallets (Coinkite Inc.) ship a dedicated hardware true-random-number generator, but a firmware regression merged in early 2021 caused builds to silently bind to MicroPython's software PRNG fallback instead. The root cause is a three-layer configuration defect: the production board config (`stm32/COLDCARD_MK4/mpconfigboard.h`, lines 77-78) defines `MICROPY_HW_ENABLE_RNG` as `0` because Coinkite supplies its own hardware-RNG wrapper; the libngu cryptographic library's availability guard in `switck/libngu/ngu/random.c` (lines 22-30) uses `#ifndef MICROPY_HW_ENABLE_RNG`, which verifies only that the macro is *defined*, not that it is *enabled* (non-zero) — so the guard passes even with the macro set to zero, and the build links against MicroPython's `rng_get()` fallback in `Coldcard/micropython/ports/stm32/rng.c` (lines 64-98) instead of the real hardware RNG. That fallback (an implementation of the Yasmarang PRNG) is initialized only from `pad = UID_low32 ^ SysTick->VAL`, `n = RTC->TR`, and `d = RTC->SSR` — the device's fixed 96-bit UID (only the low 32 bits used), a free-running down-counter (at most ~80,000 distinct values on Mk2/Mk3, ~120,000 on current devices), and RTC time registers correlated with (and potentially static relative to) boot time — none of which are cryptographically secure entropy sources, and the resulting stream is fully deterministic for a known device and timing state.
The regression first shipped in COLDCARD Mk2/Mk3 firmware v4.0.0 (commit merged 2021-03-17, tracing to a libngu macro-check change from 2021-01-28 and a seed-generation migration to libngu via commit `b18723dd` on 2021-03-01, which replaced `rng_bytes(seed)` with `seed = random.bytes(32)` routed through `ngu.random.bytes`), leaving firmware versions 4.0.1 through 4.1.9 affected until the fix in 4.2.0. Independent root-cause analysis (Block Inc. Engineering) computed the resulting search space precisely: for Mk2/Mk3 v4 firmware with a known UID and call history the keyspace collapses to 2^0 (fully deterministic); with only timers unknown it ranges from ~2^16.29 (SysTick alone) up to ~2^40.7 (all timers). Later COLDCARD Mk4, Q, and Mk5 models added a secure-element-based reseed step (`shared/mk4.py`, commit `01cb43f7`) intended to mitigate the flaw — it draws 32 bytes from one secure element via `callgate.read_rng(1)` and 8 bytes from a second via `callgate.read_rng(2)`, SHA256d-hashes them, then calls `ngu.random.reseed(n)` with only the first 4 bytes of the digest unpacked as a 32-bit integer, discarding the rest and never resetting the other Yasmarang state words. This caps the mitigated devices' effective security at ≤2^32 possible outputs (~2^31 average enumeration to a successful guess) rather than restoring 128-bit security; Coinkite's own advisory (which separately cites commit `621e808712464688584fdffad9eba132cc7c27cd` in `shared/seed.py`, lines 276-332, describing how COLDCARD hashes the device-generated seed together with any user-supplied dice rolls) states this yields ~72 bits of entropy for Mk4/Q/Mk5 versus the expected 128, and that seeds lacking 50+ independent physical dice rolls (contributing ≥128 bits) remain under-entropied regardless of firmware version.
Exploitation began July 30, 2026 — roughly a day before Coinkite's public disclosure — when an attacker drained 1,082.65-1,083 BTC (~$70.2M) from 1,196 addresses in a 41-minute window (Wave 1), using single-input sweep transactions with no change output and a uniform, well-above-market transaction fee (a hardcoded ~30 sat/vByte, a 30-75x overpay versus the ~0.4-1.0 sat/vByte prevailing median), consistent with automated/scripted tooling that offline-reconstructs candidate seeds from the constrained keyspace, derives corresponding Bitcoin addresses, and checks them against the public blockchain. Chainalysis's timing analysis of Wave 1 found the attacker extracted roughly $30M within the first ten minutes alone and $1.8M from a single victim, indicating
Weaknesses (CWE)
CWE-338, CWE-330, CWE-1241, CWE-697
Target sectors: cryptocurrency, financial services, individual consumers, self-custody bitcoin holders
Target regions: Global
Detections & IOCs
As of 2026-08-08, this threat has 9 detection rule(s) across Splunk SPL, Microsoft KQL and Sigma, and 24 indicator(s) of compromise. Detection query text and full IOC values are available to authenticated users and programmatically via the Threadlinqs MCP server (Purple tier). View plans.
VULNERABILITY, CRITICAL, threat intelligence, cybersecurity, T1596.005, T1593.003, T1592.004, T1588.006, T1587.004, T1588.002, T1583.006, T1059, T1059.006, T1552.004