Wallets / coldcard / 2026-07-31T1248-v4.2.0

coldcard 2026-07-31T1248-v4.2.0

Entropy: fail

Sample mode: firmware simulator. Statistical scores describe a software stand-in for the documented mixer, not the device hardware TRNG.

UTC date
2026-08-18Z
Commit
4845161a9887771960660473f2d6cecfadc5085a
Started
2026-08-18T16:21:31.75915Z
Status
succeeded
Wallet source
full
Source quality
weak
Construction
flawed
Sample mode
firmware_sim_trng
Sample bytes
2097152
Enrichment
not_required
Tester image
ghcr.io/409h/entropy-watch/tester:local
Verdict reason. Coldcard seed generation calls ngu.random while MICROPY_HW_ENABLE_RNG is 0 and libngu tests #ifndef (defined?), so rng_get resolves to MicroPython's Yasmarang software PRNG. Construction flaw — not a measured bit count. Entropy source is not cryptographic. Construction graded flawed.

Entropy sources

Only APIs used to generate a signing key for transaction signing (mnemonic or HD seed, private key, or keyring vault) are in-scope. Tracking, rewards, QR-sync, notifications, and UI chrome are ignored.

APIFileCryptoScope
ngu.random.bytesexternal/libngu/ngu/ngu_tests/test_random.py:11noproduction
ngu.random.bytesexternal/libngu/ngu/ngu_tests/test_random.py:15noproduction
Possible weak entropy seeding from Date / performance / timestampexternal/micropython/ports/javascript/library.js:45noproduction
Possible weak entropy seeding from Date / performance / timestampexternal/micropython/ports/javascript/wrapper.js:36noproduction
yasmarangexternal/micropython/ports/stm32/rng.cnoproduction
RNG->DRstm32/COLDCARD/rng.cyesproduction
ngu.random.bytestesting/test_rng.py:27noproduction

Findings

SevCategoryMessageFile
criticalweak_prngColdcard seed generation calls ngu.random while MICROPY_HW_ENABLE_RNG is 0 and libngu tests #ifndef (defined?), so rng_get resolves to MicroPython's Yasmarang software PRNG. Construction flaw — not a measured bit count.external/libngu/ngu/ngu_tests/test_random.py:11
criticalweak_prngrandom.random appears in Coldcard firmware Python at external/micropython/tests/extmod/urandom_extra_float.py:18; must not seed keys.external/micropython/tests/extmod/urandom_extra_float.py:18
mediumweak_entropy_sourcePossible weak entropy seeding from Date / performance / timestampexternal/micropython/ports/javascript/library.js:45
mediumweak_entropy_sourcePossible weak entropy seeding from Date / performance / timestampexternal/micropython/ports/javascript/wrapper.js:36

Test-suite references

How this wallet's own unit and integration tests exercise signing-key generation. These do not change the verdict.

No wallet tests referenced signing-key generation APIs.

Packages on the signing-key generation path

No third-party packages were imported on a signing-key generation path.

Statistical results

These checks look at a large sample of bits we generated. A pass means we did not see an obvious pattern in that sample. That cannot prove the wallet is secure. Read the linked specifications if you want the formal test definitions and how p-values are interpreted.

Specifications.How to read these suites.

See also the methodology page.

SuiteTestp-valueScoreVerdict
entarithmetic_mean
A fair mix of bits should average near 127.5. A large gap is a warning sign in the sample.
127.5025pass
entchi_square
This checks whether the 256 possible byte values appear about equally often.
223.37pass
ententropy_bits_per_byte
Near 8 bits per byte means the sample looks well mixed and hard to compress. It is not a security proof.
7.999923pass
entserial_correlation
A value near zero means neighboring bytes do not follow each other in a simple way.
0.00066pass
nist_sp800_22BlockFrequency
The sample is split into chunks. A pass means those chunks are not mostly zeros or mostly ones.
0.7530806933241491pass
nist_sp800_22Frequency
This counts zeros and ones. A pass means the mix is close enough that we did not see an obvious bias.
0.31925014518032724pass
nist_sp800_22Runs
This looks for unusually long runs of 0 or 1, which can be a sign of a stuck or simple generator.
0.6221906326777771pass
rngtestfips_140_2
A quick battery that fails if the stream looks stuck or badly biased. Passing it is a low bar.
0pass

Min-entropy

Min-entropy asks how easy the most likely value would be to guess. Higher bits per symbol is better. This still cannot prove cryptographic strength.

EstimatorBits / symbolSample size
collision
This is a simple collision-based estimate. It is not the full NIST SP 800-90B collision estimator.
7.999846344203662097152
most_common_value
If one value appears far more than the others, a guesser has an easier job. Higher bits/symbol is better.
7.9576566202063092097152

Theoretical notes

Yasmarang PRNG (libngu → MicroPython rng_get) → BIP39

Coldcard 2021–2026 rng_get construction. Simulator output is not this stream.

SHA-256(device_entropy[32] || host_entropy[32]) → BIP39

Trezor mixes STM32 TRNG (or equivalent) with 256 bits from the host. Simulator output is firmware_sim_trng.

Caveats

Download JSON · Download Markdown