Coinkite warned on July 30, 2026, that seeds created by several Coldcard hardware-wallet models on affected firmware may be exposed because seed generation used a general-purpose pseudorandom generator. The company said fixed firmware is available for every affected model and release track, but an update cannot repair a seed that was generated earlier.

The incident was not described as malicious code running on the device or a compromise of its firmware-signing system. The failure occurred when the firmware created the secret seed from which wallet keys and addresses are derived. A seed built from a small, predictable search space can still look valid and operate normally while allowing an attacker to calculate candidate keys away from the device.

A disabled feature still supplied the active function

Coldcard's design was meant to use a hardware true random-number generator for seed creation. The firmware set the MicroPython option MICROPY_HW_ENABLE_RNG to zero because Coldcard supplied its own hardware-backed implementation. Zero disabled MicroPython's hardware route, but it did not prevent a software implementation with the same interface from entering the build.

Coinkite's technical account says the 2021 migration to the libNgU library changed seed generation from ckcc.rng_bytes() to ngu.random.bytes(), and the resulting rng_get() symbol resolved to MicroPython's Yasmarang generator. Yasmarang was a general-purpose pseudorandom generator, not the hardware source Coldcard intended to use for cryptographic seed generation.

A related preprocessor check used #ifndef MICROPY_HW_ENABLE_RNG. That condition asks whether the macro exists, not whether its value is nonzero. Because the macro existed with a value of zero, the guard did not stop the build. The software fallback and the intended board-specific implementation also exposed the same function signature, allowing compilation and linking to finish without an obvious error.

Flow diagram showing a zero-valued build flag leading seed generation to a low-entropy software random-number generator

The output looked random while the search space shrank

A pseudorandom generator can produce bytes that appear evenly distributed even when its internal state came from predictable inputs. Hashing those bytes can change their appearance and remove statistical bias, but it cannot create information that was absent from the input. An observer who can reconstruct the small set of possible starting states can generate the same candidate seeds and test which ones control funded addresses.

Coinkite estimated that affected Mk2 and Mk3 seeds had about 40 bits of effective search space under its attack assumptions. It estimated about 72 bits for Mk4, Mk5 and Q because later models mixed in entropy from two secure elements. The company labeled those figures preliminary, and APPI News has not independently reproduced them. They should be read as the vendor's current risk model rather than final measurements.

The US National Institute of Standards and Technology's SP 800-90B sets out design principles, validation requirements and health tests for entropy sources used with deterministic random-bit generators. This separation matters: a test of output format or apparent randomness does not by itself prove that the input supplied enough unpredictable information.

Diagram comparing the intended hardware randomness path with a rarely examined software path

Review checked the right code but not the executed path

The intended hardware implementation was present in the firmware binary, according to Coinkite. Earlier review confirmed that implementation but did not verify which definition of rng_get() the seed-generation call actually reached across the linked components. Reading either codebase alone would not necessarily reveal the path selected in the finished artifact.

This is a build-integrity failure as much as a source-code defect. Security review that stops at individual functions can miss symbol resolution, compile-time flags and dependency defaults. Reproducible builds show that a published binary matches source and configuration; they do not prove that the configuration selects the security mechanism engineers intended.

Coinkite said its hotfix excludes the MicroPython fallback object and adds a build-time symbol check. The build now fails unless the board-specific object defines the global rng_get() symbol and the upstream fallback contributes no symbols. That converts an architectural assumption into a property the toolchain must verify.

Security-sensitive fallback should fail visibly

The incident points to three checks for systems that generate keys, tokens or identifiers. First, a missing cryptographic entropy source should stop the operation instead of selecting a weaker generator. Second, boot and integration tests should identify the implementation that actually serves the request. Third, release review should cover compiled configuration, linked symbols and call reachability, not only source-level algorithms.

These checks address different stages of the same failure. A build-time assertion prevents the wrong object from shipping. An integration test exercises the production call path. A runtime health test detects failures after deployment. None can infer lost entropy by looking only at well-formatted output after the fact.

Diagram of three controls: rejecting silent degradation, testing the entropy source at startup and reviewing build configuration

Affected versions require a new seed, not only an update

The affected Mk2 and Mk3 range is firmware 4.0.1 through 4.1.9, with version 4.2.0 or later listed as fixed. For Mk4 and Mk5, the fixed releases are standard version 5.6.0 or later and Edge version 6.6.0X or later. For Q, they are standard version 1.5.0Q or later and Edge version 6.6.0QX or later. Coinkite cautions that standard and Edge are separate release tracks.

The vendor's migration guidance is to install the correct fixed firmware, generate a new seed, verify the backup, wallet fingerprint and receive address, and send a small test transaction before moving the remaining funds. It also says to retain the old backup until migration is confirmed. Updating the firmware without replacing an affected seed leaves the original key material unchanged.

Coinkite says seeds created with at least 50 fair, independent and private dice rolls are not at risk from this random-number issue alone. A strong, unique BIP-39 passphrase supplies a separate barrier, but the company still advises migration because the passphrase does not repair the seed. TAPSIGNER, OPENDIME and SATSCARD use different codebases and are not covered by the advisory.

The broader failure mode extends beyond wallets

Any system that depends on unpredictable values can fail in the same quiet way. Authentication tokens, password-reset links, cryptographic nonces and pseudonymous identifiers may remain syntactically correct when a weak generator supplies them. The practical question is not whether the output resembles random data, but whether the deployed call path reaches a validated entropy source with the expected security properties.

Coldcard's five-year exposure followed a March 2021 integration change, not a runtime hardware failure. The build kept succeeding, the intended function remained present and generated wallets continued to operate. That combination explains why ordinary functional testing offered little warning: every visible feature worked while the security margin depended on a different implementation than reviewers believed.