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.

Collision demonstration and firmware guard scanner

nobuxpt-entropy-test-readme

https://raw.githubusercontent.com/nobuxpt/coldcard-entropy-test/master/README.md

Organisation
nobuxpt
Evidence role
Independent primary analysis
Published
2026-08-01
Source changes
0
Detected differences
0
Unreviewed
0
Copies held
1

Two offline tools: a collision simulation over the reduced search space, and a static scanner that flags the defined-ness guard in a firmware source tree. The scanner reads source directories rather than wallets, and neither tool accepts a seed or extended key. ISC licensed, with reference commits cited for the reimplemented generator.

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 2 Aug 2026, 00:26 UTC · Captured here text sha256 92b899b7e9b14db7a796b1c7 4,336 chars
    Extracted text as captured
    # COLDCARD Weak-RNG Entropy Test
    Regression tests for the COLDCARD seed-generation entropy bug (July 2026
    advisory). Two tools:
    1. **`simulate.py`** — collision test that reproduces the "duplicate wallet
       found in seconds" demo: the affected RNG chain produces duplicate seeds
       within millions of generations, while a secure RNG produces none.
    2. **`check_firmware.py`** — static source scan that flags the `#ifndef`
       guard regression in any firmware tree (e.g. the [Coldcard firmware repo]
       (https://github.com/Coldcard/firmware)).
    This is **defensive, educational security tooling**: it demonstrates *why*
    the seed space was weak. It does not contact the Bitcoin network, derive
    wallet balances, or scan for funds.
    ## Background
    Between March 2021 and the July 30 2026 advisory, COLDCARD wallet seeds were
    generated from the wrong random source. In short:
    - `generate_seed()` (`shared/seed.py`) calls `ngu.random.bytes(32)`.
    - libngu (`external/libngu/ngu/random.c`) reads a `rng_get()` symbol.
    - Its build guard is `#ifndef MICROPY_HW_ENABLE_RNG` — it tests whether the
      macro is *defined*, not whether it is *enabled*.
    - The board config defines `MICROPY_HW_ENABLE_RNG (0)`, so the guard passes
      and the build binds to **MicroPython's Yasmarang software PRNG** fallback
      (`ports/stm32/rng.c`) instead of the STM32 hardware TRNG.
    - Yasmarang seeds once from `UID_low32 ^ SysTick->VAL`, `RTC->TR`,
      `RTC->SSR` — none of which are cryptographic entropy.
    - libngu then XORs that stream with its *own* Yasmarang seeded from public
      hardcoded constants, so it stays deterministic.
    Effective entropy: ~40 bits on Mk2/Mk3 (Block engineering estimate), ~72 bits
    on Mk4/Q/Mk5.
    ## `simulate.py`
    Faithfully reimplements the full vulnerable RNG chain:
    ```
    MicroPython yasmarang fallback  ─┐
            (UID ^ SysTick, RTC)     │  XOR  ─> 32 bytes  ─> sha256d  = seed
    libngu yasmarang (public consts) ─┘
    ```
    ### Usage
    ```bash
    # ~40-bit state space (Block's estimate) -> collisions by ~1.5M generations
    python3 simulate.py --mode 40bit --count 1500000
    # Worst case: attacker knows UID + RTC, only SysTick varies (~80,000 values)

    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.