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.

SatSigner PR #468: entropy audit and hardening

satsigner-pr-468

https://github.com/satsigner/satsigner/pull/468

Latest reviewed change

source content difference between and

A referenced commit was added, resolving translation-key conflicts and adopting the entropy coin and dice descriptions from this pull request.

seen +12 -0 full history below
 fix/entropy
 branch
 August 3, 2026 18:41
+pedromvpg
+added a commit
+that referenced
+this pull request
+Aug 4, 2026

First lines only. The complete diff is in the timeline below.

Organisation
SatSigner
Evidence role
Repository pull request
Published
not established
Source changes
4
Detected differences
6
Unreviewed
0
Copies held
7

Open downstream response prompted by the COLDCARD disclosure. The author reports that SatSigner's default path was sound and proposes fixes for separate optional dice and coin paths.

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. source content difference between and source content +12 -0

    A referenced commit was added, resolving translation-key conflicts and adopting the entropy coin and dice descriptions from this pull request.

    seen · Captured here 13,616 chars
    What changed from the previous capture 12 lines
     fix/entropy
     branch
     August 3, 2026 18:41
    +pedromvpg
    +added a commit
    +that referenced
    +this pull request
    +Aug 4, 2026
    +Merge remote-tracking branch 'upstream/master' into explorer-phase2
    +…
    +2f94e6f
    +Resolve en.json conflicts by taking the union of both sides' i18n keys:
    +- Dedupe the ark section that both branches added independently
    +- Adopt master's newer entropy coin/dice descriptions (PR #468)
    +- Keep our explorer.block.title ("Block") for sibling-title consistency
     This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
     Learn more about bidirectional Unicode characters
     Show hidden characters
    
    Extracted text as captured
    Skip to content
    Navigation Menu
    Toggle navigation
    Sign in
    Appearance settings
    Platform
    AI CODE CREATION
    GitHub CopilotWrite better code with AI
    GitHub Copilot appDirect agents from issue to merge
    MCP RegistryIntegrate external tools
    DEVELOPER WORKFLOWS
    ActionsAutomate any workflow
    CodespacesInstant dev environments
    IssuesPlan and track work
    Code ReviewManage code changes
    Code QualityEnforce quality at merge
    APPLICATION SECURITY
    GitHub Advanced SecurityFind and fix vulnerabilities
    Code securitySecure your code as you build
    Secret protectionStop leaks before they start
    EXPLORE
    Why GitHub
    Documentation
    Blog
    Changelog
    Marketplace
    View all features
    Solutions
    BY COMPANY SIZE
    Enterprises
    Small and medium teams
    Startups
    Nonprofits
    BY USE CASE
    App Modernization
    DevSecOps
    DevOps
    CI/CD
    View all use cases
    BY INDUSTRY

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

  2. source content difference between and source content +33 -9

    The entropy-hardening PR was merged: pedromvpg approved, Psycarlo merged 9 commits into master on Aug 3 and deleted the fix/entropy branch. Two late commits ("fix: fixes", "fix: lint") were added since the previous capture.

    seen · Captured here 13,195 chars
    What changed from the previous capture 42 lines
     Insights
     Audit and Harden seed phrase entropy generation - #468
     #468
    -Open
    -Psycarlo wants to merge 7 commits into
    +Merged
    +Psycarlo merged 9 commits into
     mastersatsigner/satsigner:masterfrom
     fix/entropysatsigner/satsigner:fix/entropyCopy head branch name to clipboard
    -ConversationCommits7 (7)ChecksFiles changed
    -Open
    +Aug 3, 2026
    +ConversationCommits9 (9)ChecksFiles changed
    +Merged
     Audit and Harden seed phrase entropy generation#468
    -Psycarlo wants to merge 7 commits into
    +Psycarlo merged 9 commits into
     mastersatsigner/satsigner:masterfrom
     fix/entropysatsigner/satsigner:fix/entropyCopy head branch name to clipboard
     Conversation
     Audit and Harden seed phrase entropy generation
     Jul 31, 2026
     pedromvpg
    -added 6 commits
    +and others
    +added 8 commits
     August 3, 2026 13:44
     Merge branch 'master' into fix/entropy
     4b7824f
     9299478
     Opt-in Jest harness for chi-square, bit balance, serial correlation,
     and a restricted-byte canary across CSPRNG, dice, coin, and mix paths.
    +fix: fixes
    +f30e648
    +fix: lint
    +7cdd96f
    +pedromvpg
    +approved these changes
    +Aug 3, 2026
    +View reviewed changes
    +Hide details
    +View details
    +Psycarlo
    +merged commit 5a8b186
    +into
    +master
    +Aug 3, 2026
    +1 check passed
    +Uh oh!
    +There was an error while loading. Please reload this page.
    +Psycarlo
    +deleted the
    +fix/entropy
    +branch
    +August 3, 2026 18:41
     This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
     Learn more about bidirectional Unicode characters
     Show hidden characters
     Already have an account?
     Sign in to comment
     Reviewers
    +pedromvpg
    +pedromvpg approved these changes
     v4v2
     Awaiting requested review from v4v2
    -pedromvpg
    -Awaiting requested review from pedromvpg
    -At least 1 approving review is required to merge this pull request.
     Assignees
     No one assigned
     Labels
    
    Extracted text as captured
    Skip to content
    Navigation Menu
    Toggle navigation
    Sign in
    Appearance settings
    Platform
    AI CODE CREATION
    GitHub CopilotWrite better code with AI
    GitHub Copilot appDirect agents from issue to merge
    MCP RegistryIntegrate external tools
    DEVELOPER WORKFLOWS
    ActionsAutomate any workflow
    CodespacesInstant dev environments
    IssuesPlan and track work
    Code ReviewManage code changes
    Code QualityEnforce quality at merge
    APPLICATION SECURITY
    GitHub Advanced SecurityFind and fix vulnerabilities
    Code securitySecure your code as you build
    Secret protectionStop leaks before they start
    EXPLORE
    Why GitHub
    Documentation
    Blog
    Changelog
    Marketplace
    View all features
    Solutions
    BY COMPANY SIZE
    Enterprises
    Small and medium teams
    Startups
    Nonprofits
    BY USE CASE
    App Modernization
    DevSecOps
    DevOps
    CI/CD
    View all use cases
    BY INDUSTRY

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

  3. source content difference between and source content +85 -30

    The pull request grew from 2 commits to 7, and its commit tab and file counts changed with it.

    seen · Captured here 12,933 chars
    What changed from the previous capture 115 lines
     Audit and Harden seed phrase entropy generation - #468
     #468
     Open
    -Psycarlo wants to merge 2 commits into
    +Psycarlo wants to merge 7 commits into
     mastersatsigner/satsigner:masterfrom
     fix/entropysatsigner/satsigner:fix/entropyCopy head branch name to clipboard
    -ConversationCommits2 (2)ChecksFiles changed
    +ConversationCommits7 (7)ChecksFiles changed
     Open
     Audit and Harden seed phrase entropy generation#468
    -Psycarlo wants to merge 2 commits into
    +Psycarlo wants to merge 7 commits into
     mastersatsigner/satsigner:masterfrom
     fix/entropysatsigner/satsigner:fix/entropyCopy head branch name to clipboard
     Conversation
     Psycarlo
     commented
     Jul 31, 2026
    +•
    +edited by pedromvpg
    +Loading
    +Uh oh!
    +There was an error while loading. Please reload this page.
     Copy link
     Copy Markdown
     Collaborator
     Fixes & closes #465
     Summary
    -Audit of all randomness feeding BIP39 seed generation in apps/mobile, prompted by
    -the Coldcard Mk3 entropy disclosure. Nine findings, all fixed.
    -The default path was already sound. Native bdk_ffi → ThreadRng → OsRng →
    -getrandom(2), confirmed by disassembling the shipped .so. No Math.random in any
    -key path. Coldcard Mk3 was a hardware TRNG conditioning flaw with no analogue here.
    -The optional dice and coin paths were broken. One hard-blocked users; the other
    -silently under-delivered entropy.
    -Findings
    +Audit of all randomness feeding BIP39 seed generation in apps/mobile, prompted by the Coldcard Mk3 entropy disclosure. Nine original findings fixed, plus follow-up hardening for weak manual input, seededRandom, and a large-N statistical audit suite.
    +The default path was already sound. Native bdk_ffi → ThreadRng → OsRng → getrandom(2), confirmed by disassembling the shipped .so. No Math.random in any key path.
    +The optional dice and coin paths were broken. One hard-blocked users; the other silently under-delivered entropy. They now use SHA-512 conditioning with optional device mixing (default on).
    +Findings (original audit)
     #
     Severity
     Finding
     9
     Low
     No distribution tests. Existing coverage used '0'.repeat(128) — uniform inputs can't catch a distribution bug, which is why 1–3 shipped.
    -Figures derived analytically and cross-validated by Monte Carlo (200k–300k trials):
    -Changes
    -New utils/entropy.ts — SHA-512 conditioning, CSPRNG mixing, rejection-sampled
    -randomIndex, bias detection. Findings 2–5 shared one root cause (conditioning
    -implemented ad hoc inside React components) and are fixed together.
    +Figures derived analytically and cross-validated by Monte Carlo (200k–300k trials).
    +Changes (original)
    +New utils/entropy.ts — SHA-512 conditioning, CSPRNG mixing, rejection-sampled randomIndex, bias detection. Findings 2–5 shared one root cause (conditioning implemented ad hoc inside React components) and are fixed together.
     entropy/dice.tsx — terminates on roll count; buttons pass the printed face; undo; bias warning; mix toggle
     entropy/coin.tsx — hashed conditioning; visually distinct 0/1 faces; undo; bias warning; mix toggle
     utils/crypto.ts — randomNum divides by 2^32; randomIv uses randomBytes(16)
     config/entropy.ts — drawing removed, dead case blocks deleted from both flows
     locales/en.json — new keys; dice/coin descriptions corrected
     __mocks__/react-native-quick-crypto.ts — createHash/randomBytes delegate to node:crypto
    +Follow-up hardening
    +Additional review findings addressed on top of the original audit:
    +Severity
    +Change
    +High
    +Weak / patterned input (not only first-order bias) is detected; unmixed continue requires an explicit confirmation. Copy no longer claims hashing "rescues" entropy when mix is off.
    +High
    +Preview uses the real bit width and is labeled so it is not mistaken for the final seed (especially when mix is on).
    +Medium
    +Helpers enforce minimum roll/flip counts (allowPartial only for live preview).
    +Medium
    +Recorded dice/coin log is shown for the paper-trail path; undo remains available after completion.
    +Medium
    +seededRandom uses the same [0, 1) contract as randomNum (divide by 2^32) to avoid Fisher–Yates holes in coin selection.
    +Medium
    +Mix folds crypto.getRandomValues (same CSPRNG surface as randomIndex / randomNum).
    +Low
    +Frozen hash KATs, mix byte-count coverage, pattern/weak helper tests.
    +Low
    +Multisig generate passes 'english' explicitly; generateMnemonic documents the English (BDK native) vs non-English (getRandomValues) split.
    +Large-N entropy audit
    +New opt-in suite under apps/mobile/tests/entropy-audit/:
    +Sources: CSPRNG, dice, biased dice, coin, biased coin, mix, and a deliberately broken restricted-byte canary
    +Checks: byte χ², bit balance, serial correlation, collisions (skipped for biased input generators)
    +Commands: pnpm test:entropy · pnpm entropy:audit (ENTROPY_AUDIT_SAMPLES, default 5k for the audit script)
    +Default path note: English new Mnemonic() still uses native BDK RNG (Jest mocks BDK, so CI does not exercise that .so path). Non-English and mix paths are covered by the JS CSPRNG samplers.
     Design decisions
    -Hashing over arithmetic conditioning. Lossless base-6 → base-2 needs rejection
    -sampling, which discards user rolls. SHA-512 is uniform by construction and matches
    -Coldcard and Sparrow.
    -Dice buttons pass the printed face (1–6), not the index. Digit conversion happens
    -inside entropyFromDiceRolls, so the sequence the user writes down is the sequence
    -hashed. Keeps the feature auditable, which is its purpose.
    -Device mixing defaults on, but is a visible toggle. Mixing means the seed can't be
    -reproduced from the paper log. Some users pick dice for exactly that verifiability, so
    -the trade-off is surfaced rather than decided silently.
    +Hashing over arithmetic conditioning. Lossless base-6 → base-2 needs rejection sampling, which discards user rolls. SHA-512 is uniform by construction and matches Coldcard and Sparrow. Hashing does not add entropy — unmixed seeds are only as strong as the user's input.
    +Dice buttons pass the printed face (1–6), not the index. Digit conversion happens inside entropyFromDiceRolls, so the sequence the user writes down is the sequence hashed. Offline format: SHA-512("dice:" + rolls.join(","))[0 .. bits/8] (and "coin:" + concatenated flips).
    +Device mixing defaults on, but is a visible toggle. Mixing means the seed can't be reproduced from the paper log. Some users pick dice for exactly that verifiability, so the trade-off is surfaced rather than decided silently. Weak unmixed input now requires confirmation.
     Beyond audit scope
    -Locale roll counts were wrong. 18 words needs 75 rolls (said 74), 24 needs 100
    -(said 99) — ceil(256 / log2(6)) = 100. Strings now derive from the same arithmetic
    -as the code.
    -The quick-crypto mock returned a fake 32-byte digest. Conditioning tests are
    -meaningless against a stub hash, and 32 bytes can't cover 256-bit output.
    +Locale roll counts were wrong. 18 words needs 75 rolls (said 74), 24 needs 100 (said 99) — ceil(256 / log2(6)) = 100. Strings now derive from the same arithmetic as the code.
    +The quick-crypto mock returned a fake 32-byte digest. Conditioning tests are meaningless against a stub hash, and 32 bytes can't cover 256-bit output.
    +Test plan
    +Generate 12/24-word seed with entropy none (English and another wordlist)
    +Dice: complete required rolls, confirm recorded log, continue with mix on
    +Dice: turn mix off, enter patterned/biased input, confirm Alert, verify warning copy
    +Coin: same as dice for mix on/off and weak input
    +Undo after completion still works
    +pnpm --filter @satsigner/mobile typecheck
    +pnpm run check
    +pnpm --filter @satsigner/mobile test:unit
    +pnpm --filter @satsigner/mobile test:entropy
     Sorry, something went wrong.
     Uh oh!
     There was an error while loading. Please reload this page.
     Aaudit and Harden seed phrase entropy generation
     Audit and Harden seed phrase entropy generation
     Jul 31, 2026
    +pedromvpg
    +added 6 commits
    +August 3, 2026 13:44
     Merge branch 'master' into fix/entropy
     4b7824f
    +fix: harden entropy helpers against weak and short input
    +…
    +c931e1e
    +Enforce minimum roll/flip counts, detect patterned sequences, document
    +the hash construction, and add KATs plus mix-strength coverage.
    +fix: keep seededRandom in [0, 1) like randomNum
    +…
    +b631b55
    +Divide by 2^32 so a maximal uint32 draw cannot return 1.0 and create
    +holes in Fisher-Yates shuffles used by coin selection.
    +docs: clarify mnemonic RNG paths and multisig wordlist
    +…
    +5b92473
    +Document the English BDK native vs getRandomValues split, and pass
    +english explicitly on multisig generate.
    +fix: warn and confirm on weak unmixed dice/coin input
    +…
    +f54013d
    +Surface patterned or biased input, require confirmation when mix is off,
    +show the recorded log, and label the preview so it is not mistaken for
    +the final seed.
    +test: add large-N entropy audit suite
    +…
    +9299478
    +Opt-in Jest harness for chi-square, bit balance, serial correlation,
    +and a restricted-byte canary across CSPRNG, dice, coin, and mix paths.
     This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
     Learn more about bidirectional Unicode characters
     Show hidden characters
    
    Extracted text as captured
    Skip to content
    Navigation Menu
    Toggle navigation
    Sign in
    Appearance settings
    Platform
    AI CODE CREATION
    GitHub CopilotWrite better code with AI
    GitHub Copilot appDirect agents from issue to merge
    MCP RegistryIntegrate external tools
    DEVELOPER WORKFLOWS
    ActionsAutomate any workflow
    CodespacesInstant dev environments
    IssuesPlan and track work
    Code ReviewManage code changes
    Code QualityEnforce quality at merge
    APPLICATION SECURITY
    GitHub Advanced SecurityFind and fix vulnerabilities
    Code securitySecure your code as you build
    Secret protectionStop leaks before they start
    EXPLORE
    Why GitHub
    Documentation
    Blog
    Changelog
    Marketplace
    View all features
    Solutions
    BY COMPANY SIZE
    Enterprises
    Small and medium teams
    Startups
    Nonprofits
    BY USE CASE
    App Modernization
    DevSecOps
    DevOps
    CI/CD
    View all use cases
    BY INDUSTRY

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

  4. source content difference between and source content +6 -4

    Pull request 468 went from one commit to two: a merge of master into the fix/entropy branch (commit 4b7824f) was added on top of the original entropy-hardening commit, and the participant count rose from one to two. The PR remains open.

    seen · Captured here 9,416 chars
    What changed from the previous capture 10 lines
     Audit and Harden seed phrase entropy generation - #468
     #468
     Open
    -Psycarlo wants to merge 1 commit into
    +Psycarlo wants to merge 2 commits into
     mastersatsigner/satsigner:masterfrom
     fix/entropysatsigner/satsigner:fix/entropyCopy head branch name to clipboard
    -ConversationCommits1 (1)ChecksFiles changed
    +ConversationCommits2 (2)ChecksFiles changed
     Open
     Audit and Harden seed phrase entropy generation#468
    -Psycarlo wants to merge 1 commit into
    +Psycarlo wants to merge 2 commits into
     mastersatsigner/satsigner:masterfrom
     fix/entropysatsigner/satsigner:fix/entropyCopy head branch name to clipboard
     Conversation
     Aaudit and Harden seed phrase entropy generation
     Audit and Harden seed phrase entropy generation
     Jul 31, 2026
    +Merge branch 'master' into fix/entropy
    +4b7824f
     This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
     Learn more about bidirectional Unicode characters
     Show hidden characters
     Investigate Entropy
     Uh oh!
     There was an error while loading. Please reload this page.
    -1 participant
    +2 participants
     Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
     Footer
     © 2026 GitHub, Inc.
    
    Extracted text as captured
    Skip to content
    Navigation Menu
    Toggle navigation
    Sign in
    Appearance settings
    Platform
    AI CODE CREATION
    GitHub CopilotWrite better code with AI
    GitHub Copilot appDirect agents from issue to merge
    MCP RegistryIntegrate external tools
    DEVELOPER WORKFLOWS
    ActionsAutomate any workflow
    CodespacesInstant dev environments
    IssuesPlan and track work
    Code ReviewManage code changes
    Code QualityEnforce quality at merge
    APPLICATION SECURITY
    GitHub Advanced SecurityFind and fix vulnerabilities
    Code securitySecure your code as you build
    Secret protectionStop leaks before they start
    EXPLORE
    Why GitHub
    Documentation
    Blog
    Changelog
    Marketplace
    View all features
    Solutions
    BY COMPANY SIZE
    Enterprises
    Small and medium teams
    Startups
    Nonprofits
    BY USE CASE
    App Modernization
    DevSecOps
    DevOps
    CI/CD
    View all use cases
    BY INDUSTRY

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

  5. Earliest copy held
    seen · Captured here 9,366 chars
    Extracted text as captured
    Skip to content
    Navigation Menu
    Toggle navigation
    Sign in
    Appearance settings
    Platform
    AI CODE CREATION
    GitHub CopilotWrite better code with AI
    GitHub Copilot appDirect agents from issue to merge
    MCP RegistryIntegrate external tools
    DEVELOPER WORKFLOWS
    ActionsAutomate any workflow
    CodespacesInstant dev environments
    IssuesPlan and track work
    Code ReviewManage code changes
    Code QualityEnforce quality at merge
    APPLICATION SECURITY
    GitHub Advanced SecurityFind and fix vulnerabilities
    Code securitySecure your code as you build
    Secret protectionStop leaks before they start
    EXPLORE
    Why GitHub
    Documentation
    Blog
    Changelog
    Marketplace
    View all features
    Solutions
    BY COMPANY SIZE
    Enterprises
    Small and medium teams
    Startups
    Nonprofits
    BY USE CASE
    App Modernization
    DevSecOps
    DevOps
    CI/CD
    View all use cases
    BY INDUSTRY

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

2 presentation-noise differences. Sidebar, ticker and other page chrome churn that our review classified as not being changes to what the source says.
  • +5 -3 Only GitHub header chrome changed. The 'Sign in' and 'Appearance settings' labels split onto separate lines, and the search prompt changed from 'Type / to search' to 'Search/'. The pull request content was unchanged.
  • +3 -23 Only GitHub navigation and search-dialog chrome rendered differently. The pull request 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.