A 5-Character Commit Broke Coldcard's Entropy
A single commit message — the word "runs" — and a one-character commit "x" introduced a critical vulnerability in Coldcard firmware, disabling the hardware random number generator (RNG) and replacing it with a weak software PRNG. This caused wallet seed generation to use predictable randomness, potentially exposing funds. The story, detailed by Core-Lightning developer ddustin in a guest post, is a masterclass in how not to ship security-critical code.
The Commit That Started It All
The first problematic commit, titled "runs," changed 1534 lines of code with a comment ratio of 0.003. It imported and configured C code to make custom MicroPython work on the STM32 board. The critical line was:
#define MICROPY_HW_ENABLE_RNG (0)
This disabled the hardware RNG. The developer added an inline comment: // We have our own version of this code.
The second commit, titled "x," changed ~1000 lines with a ratio of 0.001. Together, these commits attempted to override the pyb_rng_get_obj function but failed, leading to a compiler error that was silenced by the #define.
The Failed Override Attempt
The developer tried to redefine pyb_rng_get_obj by adding a custom rng.c file with the same macro definition:
MP_DEFINE_CONST_FUN_OBJ_0(pyb_rng_get_obj, pyb_rng_get);
This caused a duplicate symbol error because the STM32 library already defined it. Instead of fixing the override, the developer set MICROPY_HW_ENABLE_RNG to 0, which removed the conflicting code and made the error disappear — for the wrong reason.
The Real Path: random.bytes() Bypasses the Override
Coldcard's application layer is Python. In version 4.0.0, the wallet creation function calls random.bytes(32):
async def make_new_wallet():
await ux_dramatic_pause('Generating...', 4)
seed = random.bytes(32) # OOPS
assert len(set(seed)) > 4
seed = ngu.hash.sha256s(seed)
await approve_word_list(seed)
This call doesn't use pyb_rng_get_obj; it uses rng_get(). With MICROPY_HW_ENABLE_RNG set to 0, rng_get() falls back to pyb_rng_yasmarang() — a weak PRNG. The override only affected pyb.rng(), not random.bytes().
The Consequences
The weak RNG means seeds could be predictable, risking theft. The developer's lack of understanding of C, MicroPython internals, and the call chain led to a catastrophic failure. The compiler error was a warning that was ignored.
Lessons for Developers
- Understand every line you ship. Especially in security-critical code.
- Write meaningful commit messages. A 5-character commit message for a 1534-line change is unacceptable.
- Verify your changes actually do what you think. Test the exact code path users will hit.
- Don't silence compiler errors with random changes. Investigate and fix the root cause.
What You Should Do Now
If you're a Coldcard user, update to the latest firmware immediately. If you're a developer, audit your own code for similar issues: check your RNG usage, commit history, and test coverage. The full technical analysis is available in the source article.
Technical Details at a Glance
- Affected firmware: Coldcard v4.0.0 (and possibly earlier)
- Root cause:
MICROPY_HW_ENABLE_RNGset to 0, disabling hardware RNG - Impact: Wallet seeds generated with weak PRNG (Yasmarang)
- Fix: Update firmware; the issue was likely resolved in later versions (per source, but not explicitly stated)




