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.
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.
| API | File | Crypto | Scope |
|---|---|---|---|
| ngu.random.bytes | external/libngu/ngu/ngu_tests/test_random.py:11 | no | production |
| ngu.random.bytes | external/libngu/ngu/ngu_tests/test_random.py:15 | no | production |
| Possible weak entropy seeding from Date / performance / timestamp | external/micropython/ports/javascript/library.js:45 | no | production |
| Possible weak entropy seeding from Date / performance / timestamp | external/micropython/ports/javascript/wrapper.js:36 | no | production |
| yasmarang | external/micropython/ports/stm32/rng.c | no | production |
| RNG->DR | stm32/COLDCARD/rng.c | yes | production |
| ngu.random.bytes | testing/test_rng.py:27 | no | production |
Findings
| Sev | Category | Message | File |
|---|---|---|---|
| critical | weak_prng | 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. | external/libngu/ngu/ngu_tests/test_random.py:11 |
| critical | weak_prng | random.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 |
| medium | weak_entropy_source | Possible weak entropy seeding from Date / performance / timestamp | external/micropython/ports/javascript/library.js:45 |
| medium | weak_entropy_source | Possible weak entropy seeding from Date / performance / timestamp | external/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.
- NIST SP 800-22 Rev. 1a — A Statistical Test Suite for Random and Pseudorandom Number Generators (2010-04)Official STS document. Section 4 explains p-values and what a pass does and does not mean.
- NIST SP 800-90B — Recommendation for the Entropy Sources Used for Random Bit Generation (2018-01)How min-entropy of an entropy source is estimated. Our collision figure is a simplified cousin, not the full 90B estimator.
- RFC 4086 — Randomness Requirements for Security (2005-06)Why cryptographic secrets need a CSPRNG, and why statistical batteries are only a sanity check.
- FIPS 140-2 — Security Requirements for Cryptographic Modules (2002-12)Historical module standard. rngtest implements the old FIPS 140-2 continuous RNG health checks.
- Fourmilab ENT — A Pseudorandom Number Sequence Test Program (2008-01)What entropy bits/byte, chi-square, arithmetic mean, and serial correlation mean on a byte stream.
- Dieharder — A Random Number Test Suite (Robert G. Brown)Successor to Marsaglia's Diehard. Needs a large sample; we only run it at ≥ 10 MiB.
- rngtest(1) — FIPS 140-2 RNG testsMan page for the rng-tools FIPS battery we record as rngtest.fips_140_2.
- NIST STS source and user guideSoftware and notes that accompany SP 800-22.
- CWE-338 — Use of Cryptographically Weak Pseudo-Random Number Generator (2006-07)The weakness statistical tests can hint at but cannot prove is absent.
See also the methodology page.
| Suite | Test | p-value | Score | Verdict |
|---|---|---|---|---|
| ent | arithmetic_mean A fair mix of bits should average near 127.5. A large gap is a warning sign in the sample. | — | 127.5025 | pass |
| ent | chi_square This checks whether the 256 possible byte values appear about equally often. | — | 223.37 | pass |
| ent | entropy_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.999923 | pass |
| ent | serial_correlation A value near zero means neighboring bytes do not follow each other in a simple way. | — | 0.00066 | pass |
| nist_sp800_22 | BlockFrequency The sample is split into chunks. A pass means those chunks are not mostly zeros or mostly ones. | 0.7530806933241491 | — | pass |
| nist_sp800_22 | Frequency This counts zeros and ones. A pass means the mix is close enough that we did not see an obvious bias. | 0.31925014518032724 | — | pass |
| nist_sp800_22 | Runs This looks for unusually long runs of 0 or 1, which can be a sign of a stuck or simple generator. | 0.6221906326777771 | — | pass |
| rngtest | fips_140_2 A quick battery that fails if the stream looks stuck or badly biased. Passing it is a low bar. | — | 0 | pass |
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.
| Estimator | Bits / symbol | Sample size |
|---|---|---|
| collision This is a simple collision-based estimate. It is not the full NIST SP 800-90B collision estimator. | 7.99984634420366 | 2097152 |
| most_common_value If one value appears far more than the others, a guesser has an easier job. Higher bits/symbol is better. | 7.957656620206309 | 2097152 |
Theoretical notes
Coldcard 2021–2026 rng_get construction. Simulator output is not this stream.
Trezor mixes STM32 TRNG (or equivalent) with 256 bits from the host. Simulator output is firmware_sim_trng.
Caveats
- Statistical tests can only fail a generator; they never prove cryptographic security.
- Short samples can look fine even when underlying entropy is low.
- Implementation bugs (state reuse, incorrect seeding, buffer issues) frequently destroy entropy in ways pure statistical tests miss.
- True confidence requires both high-quality sources and correct design/review.
- When sample_mode=firmware_sim_trng, statistical scores describe a software simulation of the documented mixer, not the device hardware TRNG.