COLDCARD RNG incident the public record, collected and explained
Informational only, and this site never asks for your seed words. details

Informational only. This is an open source collection of what others have published about the incident, together with an explanation of it. It is 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. Material is attributed and quoted as published; where sources disagree their scenarios are kept separate with their assumptions rather than reconciled into one answer. Everything is meant to be checked against the linked evidence rather than taken on trust. Act on your own judgement about a particular situation. Editorial standards and corrections.

Do not disclose recovery material to a website, form, message or support account. This site never asks for it, and contributions containing recovery words or private keys are not accepted.

COLDCARD firmware PR #691 patch

coldcard-firmware-pr-691-patch

https://github.com/Coldcard/firmware/pull/691.patch

Organisation
Coinkite
Evidence role
Repository patch
Published
not established
Source changes
0
Detected differences
1
Unreviewed
0
Copies held
2

Patch content for the open firmware-side full-digest proposal. Kept separately from the conversation and review-state capture.

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 .

  1. Earliest copy held
    seen · Captured here 2,044 chars
    Extracted text as captured
    From 9324b130f4e30b852e1162a7390fbe75b2f37957 Mon Sep 17 00:00:00 2001
    From: Ballance <[email protected]>
    Date: Fri, 31 Jul 2026 23:32:03 -0400
    Subject: [PATCH] fix: feed full SE digest to PRNG reseed (drop 32-bit
     truncation)
    MIME-Version: 1.0
    Content-Type: text/plain; charset=UTF-8
    Content-Transfer-Encoding: 8bit
    rng_seeding() hashed the secure-element entropy with SHA256d but then
    kept only n[0:4], handing ngu.random.reseed() a single 32-bit word. That
    throttled the secure-element contribution to 2**32 and, combined with
    reseed()'s old behaviour, left most of the generator state at fixed
    constants. Pass the whole 32-byte digest instead.
    Bumps external/libngu to a512174, which reworks random.reseed() to
    absorb a full-width seed into all generator state words.
    Ref: Block engineering disclosure, "Predictable RNG fallback and 32-bit
    reseed in COLDCARD firmware".
        Thirty-two silent bytes,
        all but four were cast aside —
        now the seed stays whole.
    ---
     external/libngu | 2 +-
     shared/mk4.py   | 6 ++++--
     2 files changed, 5 insertions(+), 3 deletions(-)
    diff --git a/external/libngu b/external/libngu
    index 537519a8..a5121743 160000
    --- a/external/libngu
    +++ b/external/libngu
    @@ -1 +1 @@
    -Subproject commit 537519a829259622ea6b0334fbafd6cae852852f
    +Subproject commit a51217432308fd9ebc7c3d54b96a5af72b71b2e9
    diff --git a/shared/mk4.py b/shared/mk4.py
    index 3a3e229d..8a4b1572 100644
    --- a/shared/mk4.py
    +++ b/shared/mk4.py
    @@ -38,13 +38,15 @@ def make_psram_fs():
     def rng_seeding():
         # seed our RNG with entropy from secure elements
    -    import callgate, ngu, ustruct
    +    import callgate, ngu

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

1 presentation-noise difference. Sidebar, ticker and other page chrome churn that our review classified as not being a change to what the source says.
  • +2 -2 Only the displayed Git patch index abbreviations gained one hexadecimal character. The patch content did not change.
How to check this yourself

The excerpts and plain unified diffs above show the text this project held and how it changed. 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.