It seems that the details were already posted all over the place over Twitter and Telegram, so here is an explanation of it: In Coldcard, there are two implementations of getting bytes from the HWRNG, in cckt and libngu. The path in libngu is used for generating seeds. This one calls the MicroPython API to get random values. The MicroPython API uses the HWRNG if enabled. The problem was that Coinkite disabled the HWRNG for MicroPython. This should not have been an issue, as libngu had a check to see if the HW RNG is enabled. However, this used ifndef, which explicitly checked *if the HW RNG enable was not configured*. It did not check if the HW RNG enable was turned off explicitly, which is what Coinkite did. This led to their code using the flawed software MicroPython RNG, which was solely based on the device boot time and a very weak manufacturing identifier. This means that there are not a lot of different seeds. In Mk4/Mk5, this issue still exists. The only difference is that 32 actually random bits (which is tiny) have been mixed into the RNG. By overly complicating their codebase, in what can only be described as “attempted security through complexity”, they have put all user funds at risk. Regarding the implications: - If you generated using dice or wordlist or another method that included non-Coldcard entropy, you are fine. - If you generated on a non-Coldcard device, you are fine. - If not, your funds are at risk. A passphrase will help slow it down but the main seed is still compromised. Multisigs: You are affected *privacy wise* if one of your members is a Coldcard-generated seed. You are only at risk if the majority of your members are CC. Secure element RNGs: These are fine. You need a proper one though from Infineon/NXP/ST, and not the crappy IoT ones. Also beware the HWW firmware can still butcher the resulting numbers.

Replies (33)

In a multisig, only one xpub of a member is required to track *spends*. (Compared to all of them for unspent outputs, which is why you MUST back it up to restore your wallet) This is because the individual pubkeys derived from each member xpub are revealed on chain, and you could just check using one xpub. Someone can bruteforce all possible seeds’ multisig xpubs to track individual wallets.
It is quoting Coinkite’s security disclosure. Do not trust AI solely on web data Rotate your keys anyway.
I’m not sure. Could be both, knowing NVK. They did make an attempt to make the Mk4/5/Q RNG more secure. But this attempt is much weaker than thought.
Commiserations to all the plebs, like me who stayed humble, who mixed and held and followed best practice only to scramble into a mass consolidated UTXO dox nightmare. When chain surveillance conspiracy?
It compresses the two secure elements’ RNGs into 32 bits, and uses that as a seed for a insecure software PRNG that is mixed into the seed
Thank you for explaining everything to us NVK. Oh wait he’s gone off the fucking grid!!
I have a seed that was likely generated by a ColdCard device prior to the Mk3. Does the Mk1 or Mk2 have this same entropy derp issue?
Your entropy is still reduced, but the number of possible combinations is increased. IOW, you all suffer from the fact the pool of private keys is (MUCH) more limited. But to move funds you'd need the right combination of three of them. (2 xprvs and all three xpubs). You are safer, but if I were in your shoes I'd CAREFULLY move the coins. A Bip 39 passphrase helps quite a bit but is one more way to complicate and therefore shoot self in foot. 😁 whatever you do take care to do it well.
I cede to your knowledge. But don't you need to guess a combination of keys rather than just one? I do not know the numberspace the borked rng drops down to, but wouldn't you need at least two xprvs (harder) and all three xpubs (not hard)?
"This should not have been an issue, as libngu had a check to see if the HW RNG is enabled. However, this used ifndef, which explicitly checked *if the HW RNG enable was not configured*. It did not check if the HW RNG enable was turned off explicitly, which is what Coinkite did." This is incompetence.
Why does this feel like fear harvesting? It start to feel like this particular when they’re saying multisig are of concern. Let me explain: the possibility for a signal MK3. With the MK3 That’s approximately 1.0995 \times 10^{12} (about 1.1 trillion). Possible seeds. There could be for example 1.2 million wallets with funds. The goal is to find funds. In a multisig. You need all three keys to rebuild the wallet to generate a public address with funds. Even with a finding two of the three keys, that was used to build a multisig that number is. 1 trillion × 1 trillion = 1,000,000,000,000,000,000,000,000 That’s 1 septillion (or 10^{24}). Breakdown: • 1 trillion = 10^{12} • 10^{12} \times 10^{12} = 10^{24}
That is not how multisig recovery works, and a single UTXO spend can be used to recover the entire multisig
Well, the guy was a graphic designer in a former life, not an engineer, iirc.
Single seed generated offline from good entropy (like dice rolls) is still a viable defense against offline signing device vulneraabilities.
You are correct the public keys are exposed in a transaction, where you send bitcoin like a purchase, and you are also returned the bitcoin back to the same wallet. This exposes the public. I learned something today.
The obscurity of this issue specifically is almost the level of Jia Tan inserting a dot to break the sandboxing enable defined in CMakeLists.txt in xz.
I am a bit annoyed personally with Infineon, especially since they like to cheap out on their crypto it seems. See EUCLEAK (32-bit masking instead of full masking) and RoCA (weird “cheaper” prime generation algorithm) Most commercial SEs also feed TRNG bytes through whitening and processing I would say the random numbers generated by it, when mixed with the OS pool, are sufficiently good
↑