URGENT - If You Keep Bitcoin on a ColdCard: MOVE EVERYTHING
I use ColdCard. Or rather, I used that old ColdCard to store part of my bitcoin. I have already moved everything that was on it to a new wallet. If your seed was generated on a ColdCard since March 2021 and you cannot prove it came from safe firmware or enough external entropy, stop reading, take inventory, and get ready to move too.
I am not exaggerating for a clickbait headline. On July 29, transactions started sweeping user wallets. One consolidation address received 594.47723261 BTC across 501 outputs. That is public blockchain data, not a Telegram screenshot. Issue 416 of Bitcoin Optech, published while the case was still unfolding, already estimated losses above 1,000 BTC.
The exact number will still change. The 594 BTC cluster is directly observable; attributing every input to the same vulnerability and closing the global total requires more analysis. But the combination of victim reports, the sweep pattern, reproduction of the bug, and Coinkite’s own admission is strong enough. Waiting for a pretty forensic report while a vulnerable seed keeps receiving funds is a terrible strategy.
Do not panic and type your 24 words into the first website that promises to “check your ColdCard” either. That is the other, much easier way to lose everything. A seed never goes into a website, chat, browser extension, or online computer. First understand whether you were affected. Then migrate calmly, verifying the address on the screen of a trusted signer.
Who needs to act now
The vulnerability is in seed generation. What matters is the model and firmware used on the day those words were created, not the firmware installed today or where you imported the seed afterward.
In practice: if you own any ColdCard, move the funds to a wallet derived from a completely new seed. Better to err on the side of caution. The ranges below show where the bug has already been confirmed; they are no reason to bet your life savings on the assumption that everything else is perfect. Updating the device does not repair the old seed.
According to Coinkite’s advisory and Block’s independent analysis, treat as compromised any seed generated under these conditions:
| Device | Firmware that generated the seed | Status |
|---|---|---|
| Mk2 | 4.0.0 through 4.1.9, according to Block | Vulnerable. Migrate the seed and retire the device as a generator. |
| Mk3 | 4.0.1 through 4.1.9 in Coinkite’s advisory; Block includes 4.0.0 | Vulnerable. Install 4.2.0 or later before generating another seed. |
| Mk4 / Mk5 Standard | Earlier than 5.6.0 | Affected. Update before generating another seed. |
| Mk4 / Mk5 Edge | Earlier than 6.6.0X | Affected. Edge is a separate release track. |
| Q Standard | Earlier than 1.5.0Q | Affected. |
| Q Edge | Earlier than 6.6.0QX | Affected. |
Block includes the Mk2 running 4.x firmware in the same regression as the Mk3 and starts the vulnerable range for both at 4.0.0. Coinkite focused its advisory on the Mk3, starting at 4.0.1, and on current models. I would treat the entire 4.x line through 4.1.9 as compromised on both. If you own an Mk2, do not take comfort from its absence in the advisory headline.
There is one important exception: anyone who added at least 50 fair, independent, and private die rolls during the original setup theoretically preserved at least 128 bits from an outside source. Coinkite itself says those seeds are not at risk from this bug alone. If you do not remember exactly how many rolls you made, which flow you used, or whether those results remained private, assume you did not do it.
A seed imported from another generator was not born from this defective RNG either. It may have other problems, of course, but not this one. Updating firmware now cannot travel back in time and repair any words. You must create a new seed and transfer the UTXOs to addresses derived from it.
Restoring the same 24 words on a Trezor, Ledger, SeedSigner, or any other device is NOT a migration. You are still in danger. The hardware changed; the root and the entire universe of derived private keys remain the same. Another derivation path may display different addresses, but it adds no entropy. If the ColdCard generated that wallet using the weak RNG, importing its seed into another signer merely teaches the new device to reproduce the same vulnerable keys. Create a completely new wallet with new entropy, then make an on-chain transaction that moves the funds from the old wallet to addresses in the new one.
I would do this even with a strong passphrase. The passphrase may have placed an independent barrier in front of the attacker, but Coinkite itself recommends migrating. After a failure of this magnitude, calculating the minimum theoretically acceptable risk is saving money in the wrong place.
The bug: #ifndef does not mean “if true”
Coinkite’s technical postmortem is an embarrassing read.
In March 2021, the firmware replaced ckcc.rng_bytes() with ngu.random.bytes() during its migration to libNgU and the libsecp256k1 used by Bitcoin Core. The library choice was good. The integration was disastrous.
The build code defined:
#define MICROPY_HW_ENABLE_RNG (0)But the guard in libNgU checked this:
#ifndef MICROPY_HW_ENABLE_RNG
#error "get a HW TRNG plz"
#endif#ifndef asks whether the symbol exists, not whether its value is nonzero. The symbol existed. The build passed. In the final resolution, rng_get() pointed to MicroPython’s software fallback, a deterministic PRNG called Yasmarang, initialized with the microcontroller UID and timing registers. A UID identifies a chip. A clock measures time. Neither is a cryptographic source of randomness.
Worse, the correct TRNG implementation was inside the binary. Previous reviews looked at it and concluded everything was fine, but nobody verified the complete path between “create new wallet” and the symbol actually called in the executable. There was no integration test that failed when the seed came from the wrong generator.
On the Mk3, Coinkite’s preliminary estimate is around 40 bits of effective entropy, instead of the minimum 128 bits expected. On the Mk4, Q, and Mk5, values from the secure elements entered as a second layer, and the company estimates approximately 72 bits. Block’s analysis is harsher: only 32 bits of material from the secure elements reached the PRNG state during that reseed. The threat models and estimates are not identical. None comes close to the target.
Passing bad output through SHA-256 does not create entropy. If only 2^40 inputs exist, at most 2^40 possible hashes exist. They look nice and uniform and remain enumerable.
This sat on the most important path in the product for more than five years.
How a 120-file rewrite got us here
Zach Herbert published a timeline worth summarizing. He is a Foundation cofounder, Passport manufacturer, and Coinkite competitor, so read the interpretation with that context. The dates and commits, however, can be verified.
In July 2020, Foundation announced that its first Passport would build on ColdCard’s GPLv3 firmware. Two days later, NVK publicly complained about the “clone” and said he would change the license. In November, ColdCard added MIT plus the Commons Clause, which left the code visible but restricted derivative commercial products. In January 2021, the change formally appeared in firmware 3.2.1.
On March 1 came the First pass w/ libNgU commit: 120 files changed, removal of GPL-covered libraries derived from Trezor, replacement of the cryptographic stack, and a change to seed generation. On March 17, version 4.0.0 announced the removal of the last GPL code.
There is no way to prove how much of the haste or scope came from the license dispute. The timeline itself acknowledges other legitimate goals: adopting libsecp256k1, accelerating AES/SHA, and enabling reproducible builds. The concrete fact is simpler: the bug entered in that same massive commit, and the product went five years without an end-to-end test of its most critical path.
That is engineering incompetence. A hardware wallet can have a secure element, sealed packaging, an air gap, and a website full of explanations about sovereignty. If the function that creates the key calls the wrong RNG and nobody tests it for five years, everything else is theater.
This was a white swan, not a black swan
I have already seen people call this a “black swan,” as though a cosmic alignment of unforeseeable events had struck Coinkite. It was not.
The vulnerable code had been visible in the repository since March 2021. The commit was enormous, but not secret. The deterministic fallback was in a public submodule. The macro defined as zero was in the board configuration. The incorrect #ifndef was in the integration. What was missing was following the seed-generation call all the way to the symbol resolved in the binary and writing a test that proved where its entropy came from.
A black swan is rare, surprising, and only looks obvious afterward. This was a white swan: a known risk in the most sensitive category of the product, with an observable cause and a predictable consequence. Nobody knew the exact day someone would connect the dots and sweep the wallets. The bomb, however, had been assembled and ticking in public for five years.
And Coinkite helped reduce the number of people willing to defuse it.
In 2021, Marko Bencun from Shift/BitBox and Hugo Nguyen from Nunchuk responsibly disclosed a critical multisig flaw. Coinkite fixed the code, but its release notes did not say it was a vulnerability or communicate any urgency. Bencun’s bounty request was ignored. The company published a more explicit warning only after the researcher released the details.
The current responsible disclosure policy still leaves reward amount, eligibility, and timing to the company’s discretion. Researchers working for competitors or well-funded labs are not eligible for a bounty. The page even throws in “we are not here to make it easy for you,” as if antagonizing people who audit your vault demonstrated personality.
Zach Herbert also documented NVK’s public attacks on Foundation after it used ColdCard’s GPL code: “pure clone,” “leeches,” and “affinity scamming.” Herbert is a competitor with an interest in the dispute, but the posts and screenshots exist. My opinion of NVK as a CEO is now terrible. He cultivated hostility toward the manufacturers and researchers who had the knowledge and technical incentive to review his product.
I do not need to claim that every researcher abandoned Coinkite. Just look at the incentives. A competent white hat can spend weeks dismantling firmware. If a company minimizes findings, ignores bounties, treats competitors as enemies, and reserves the right to decide when something deserves credit, that researcher works on another product. Open code permits auditing; it does not force anyone to audit for free for a company that treats them badly.
So this was not one-in-a-billion bad luck. It was a self-fulfilling prophecy. Extreme negligence accumulated risk until someone exploited it. When the bomb went off, it did not erase a number in a Coinkite spreadsheet. It took real bitcoin that, for some victims, represented years of savings or their life’s savings.
No, “AI broke Bitcoin” my ass
Coinkite wrote that, because the firmware was public, “we have to assume” someone used AI to review old versions and found the bug. It provided no evidence. In the next paragraph, it admits that weeks earlier it had used one of the best available models to review the same code, and the model found nothing serious.
NVK later published an apology on Coinkite’s behalf. He took responsibility for the bug, told every ColdCard owner to move their funds, acknowledged that new firmware cannot repair an old seed, and said the company would have to earn back its users’ trust. That is the bare minimum, but it matters that he said it.
The problem is that he ended by trying to turn the disaster into “a sober reality of the new AI paradigm,” arguing that AI-assisted review can now find old bugs faster than seasoned experts. No. This has fuck all to do with AI. The bug was basic, visible in the code for five years, and sat in the most important function of a hardware wallet. NVK was lucky it took this long.
Do not shift the blame to AI-assisted code review to justify piss-poor code. AI may have helped someone locate or exploit the flaw. AI did not write that #ifndef, disable the TRNG, approve the 120-file rewrite, or spend five years without an end-to-end test of seed generation. Coinkite did all of that.
After disclosure, researchers reproduced the flaw with the help of frontier models. Great. That shows AI can accelerate auditing and exploitation after someone points to where they should dig. It does not mean an AI broke ECDSA, secp256k1, SHA-256, BIP39, or Bitcoin.
The attacker enumerated a keyspace that a manufacturer had reduced from at least 128 bits to something around 40. This is brute force against predictable numbers. The Bitcoin protocol did exactly what it should: it accepted valid signatures produced by the correct private keys.
AI did not break Bitcoin. Coinkite left a basic regression untested at the heart of its firmware for five years. Blaming the tool that may have helped someone read the code is a convenient way to change the subject.
What a wallet actually stores
Bitcoin does not sit “inside” a ColdCard, Ledger, or Sparrow file. The blockchain contains UTXOs locked by scripts. Your wallet stores the material needed to find those UTXOs and produce signatures that satisfy the scripts.
At the most basic level, a private key is an integer chosen within the domain of the secp256k1 curve. The public key is a point calculated from it. That path is easy to compute forward and infeasible to reverse with known computing power. Addresses are representations derived from public keys and scripts, not vaults where coins live.
I explained this foundation more carefully in [Akitando #67] Understanding Basic Cryptography Concepts - Part 1 and [Akitando #68] Understanding Basic Cryptography Concepts - Part 2.
A modern wallet does not draw an independent key for each address. It starts with a root and uses BIP32 to derive a deterministic tree of keys: accounts, receiving addresses, change, and so on. A backup of the root recovers the entire tree.
BIP39 is the layer that turns binary entropy into readable words and then converts the mnemonic plus a passphrase into a 512-bit binary seed used by BIP32. The words are a human-readable way to carry computer-generated randomness. The specification explicitly warns that it is not a method for inventing a nice phrase in your own head.
Twelve or 24 words is the wrong question
A 12-word mnemonic encodes 128 bits of entropy plus a 4-bit checksum. A 24-word mnemonic encodes 256 bits plus an 8-bit checksum. Under normal conditions, 128 bits is already beyond brute-force reach.
But “24 words” does not guarantee that 256 real bits existed at the input. Vulnerable firmware could produce a perfectly valid sequence of 24 words, correct checksum and all, from an effective space of approximately 40 bits. The attacker does not need to try every possible word combination. They reproduce plausible states of the broken RNG and compare the derived addresses.
That is why the 12-versus-24 argument misses the point. Representation length cannot rescue a predictable source. A UUID printed in gold lettering remains predictable if someone called rand() with a timestamp.
RNG, TRNG, and independent sources
RNG is the generic term for a random number generator. A PRNG takes an initial state, the seed, and expands it into a deterministic sequence. A properly designed CSPRNG remains safe as long as the initial state contains enough entropy and the algorithm does not leak that state.
A TRNG tries to harvest randomness from physical phenomena: electronic noise, oscillator jitter, and similar sources. Ledger explains its process as a TRNG inside the Secure Element generating 256 bits, which BIP39 translates into 24 words. The company says an external lab tests that generator and certifies it under AIS-31. That is much better than a timer plus serial number, but it remains one source and one implementation you have chosen to trust.
Other projects prefer to combine sources. Trezor uses entropy from the device and host. BitBox02 documents five sources: the secure chip TRNG, the microcontroller TRNG, a unique value installed at the factory, entropy supplied by the host, and a hash of the device password.
The word that matters here is independence. Two PRNGs initialized from the same clock are not two sources. Two values that come from the same secure element do not buy the independence the diagram implies either. Independent sources, combined through a correct cryptographic construction, keep the result strong even when some of them fail.
And “combined correctly” carries half the security in that sentence. XOR, hashes, and extractors have specific properties. Do not invent your own mixer in half an hour and put your net worth on top of it. Use a reviewed implementation with test vectors, and verify that the binary you execute actually calls that code. I think the reason is now obvious.
Rolling dice is not that simple
Each roll of an ideal D6 provides log2(6), about 2.585 bits. That is where the figures of 50 rolls for 128 bits and 99 rolls for approximately 256 bits come from. ColdCard’s documentation shows the calculation and the SHA-256 applied to the sequence. SeedSigner uses the same thresholds: 50 for 12 words or 99 for 24.
That calculation assumes a fair die and independent rolls. A cheap promotional plastic die may have bubbles, poorly cut faces, and a shifted center of mass. Your hand may repeat a motion, the tray may favor one position, and many people “roll again” when the die lands near an edge. Every human decision made after seeing the result introduces bias.
If I were generating a seed manually today, I would use precision casino-grade dice from more than one manufacturer or batch. BitBox itself recommends five casino-grade dice for its manual procedure. I would define the reading order ahead of time, use a tray that lets the dice bounce, and accept every valid roll according to a rule written before I started. No rerolling because it “didn’t mix properly.”
Even then, I would not trust the dice alone. I would mix independent sources: more than one set of dice, coin flips, entropy from an offline host, and a hardware TRNG when the device supports it. Making hundreds of rolls is cheap. The care lies in feeding everything to an audited mechanism that performs the cryptographic combination. Adding numbers, picking the “most random” words, or concatenating pieces of mnemonics yourself is a recipe for losing funds.
Check what your device actually implements. In Ledger’s documented new-wallet setup, the Secure Element TRNG generates the entropy. In restore mode, the words must reconstruct exactly the same keys. The TRNG cannot add secret entropy on top of the imported mnemonic because that would create another wallet and destroy the purpose of a backup. Restoring a seed made with dice therefore transfers custody and signing to the device, but it does not improve the original randomness.
With a commercial hardware wallet, I would choose one of two paths: generate a new root through the official flow of an updated device that documents how it combines independent sources, or generate BIP39 outside it through an auditable and fully offline process, then enter the words only through the signer’s screen and buttons. A seed created in MetaMask, a website, or a connected laptop and later restored into a Ledger remains a hot seed. Ledger summarizes this well: move, don’t merge.
BTC D00M Guy has a visual Portuguese-language tutorial on BIP39, dice, and recovery testing. It is a good introduction to seeing the process, but I would not literally copy the old-phone-in-airplane-mode step for serious wealth. Airplane mode does not prove the device was clean, does not physically remove its radios, and formatting flash afterward gives me no verifiable erasure guarantee. It is fine for learning and rehearsal. To create the seed for my life savings, I prefer hardware with no radio, a verified ephemeral system, or a dedicated signer.
The rolls become a secret the moment you decide to use them. Do not photograph them, dictate them out loud, keep them in a phone note, or type them into a website. SeedSigner’s documentation recommends that any verification of a real seed happen on an ephemeral system such as Tails, fully offline and discarded after the test.
More entropy does not fix a bad process either. One hundred rolls recorded by a cloud-connected camera are worth zero against someone who has the video.
Passphrase: another wallet, not another password
In BIP39, the mnemonic is the main input to PBKDF2-HMAC-SHA512. The salt is the string mnemonic concatenated with the passphrase, and the function runs 2,048 iterations. Every passphrase produces a valid wallet. One wrong character does not display “incorrect password”; it opens another, usually empty wallet.
A long, random, unique, and independent passphrase can protect an exposed or weak mnemonic. In the ColdCard case, it adds a secret that did not come from the defective RNG: the attacker must combine every mnemonic candidate with a passphrase attempt. If that passphrase has enough entropy and never leaked, the attack may become infeasible again.
But a quote, human pattern, or reused password becomes an offline dictionary attack with no rate limit. BIP39’s 2,048 iterations do not turn a weak passphrase into a strong one. And losing it is just as final as losing the words. A hardware wallet PIN does not replace a passphrase. The PIN protects the physical device; the passphrase participates in key derivation.
Store the passphrase separately from the mnemonic and test a complete recovery before depositing a meaningful amount. Record the expected fingerprint and at least one address as well. During recovery, they tell you whether you opened the correct wallet.
In the ColdCard case, do not add a passphrase to the vulnerable seed now and call that a migration. Create a new root. The passphrase may be part of the new architecture, but the bitcoin must leave scripts derived from the old root.
Sparrow, air gaps, and PSBT
Sparrow is the coordinator I use. It knows descriptors, xpubs, addresses, UTXOs, and history. It can construct a transaction, but in a watch-only configuration it has no private key with which to sign.
This is where PSBT, standardized in BIP174, comes in. Sparrow creates a Partially Signed Bitcoin Transaction with the inputs, outputs, amounts, and derivation data required. The file or QR code goes to the offline signer. The signer reviews it, adds its signature, and returns the PSBT. In multisig, the same package moves through the remaining signers until it reaches quorum. Sparrow combines, finalizes, and broadcasts it.
The air-gapped single-sig flow looks like this:
- Sparrow creates the transaction on the online computer.
- You export the PSBT through QR code or microSD.
- ColdCard, SeedSigner, or another device displays the destination, amount, and fee.
- You verify them on the signer’s screen and sign.
- Sparrow imports the signed PSBT, finalizes it, and broadcasts it.
An air gap reduces the attack surface. It is not a force field. QR codes and microSD still carry data, malicious firmware remains malicious firmware, and a compromised coordinator can try to replace the destination or change address. The signer’s screen exists so you can compare the address, amount, and fee before pressing Confirm.
And an air gap cannot improve entropy retroactively. A vulnerable ColdCard could spend its entire life without a USB cable. The key was already born weak.
2-of-3 multisig: safer and much more bureaucratic
Single-sig concentrates everything in one seed, one backup, and one implementation. Among options available today, 2-of-3 multisig with genuinely independent signers is the closest thing I know to maximum security against that single point of failure.
You create three independent seeds on signers from different manufacturers and codebases. Sparrow creates a policy requiring two signatures. One device may break or one seed may leak without immediately surrendering the funds. Two signers remain enough for recovery.
“Independent” is once again the word doing the work. Three hardware wallets fed by three child seeds from the same BIP85 root still depend on one root. Three seeds generated by the same vulnerable ColdCard repeat the risk. Use separate processes and entropy sources. I might combine, for example, a commercial signer from another manufacturer, a SeedSigner using dice, and a third device with a different architecture.
In Sparrow, the conceptual procedure is:
- Create and back up each seed separately.
- Export the fingerprint, derivation path, and xpub from each signer.
- Create a
Multi Signaturewallet, normally Native SegWit, with a 2-of-3 policy. - Import all three keystores and back up the wallet’s output descriptor.
- Record which signers correspond to which fingerprints.
- Verify one receiving address on more than one signer.
- Make a small deposit, restore and test the signers, and perform a complete trial withdrawal.
The descriptor cannot spend by itself, but it reveals every address and the full history. It is a necessary backup for reconstructing the policy and also sensitive privacy data. Keep copies in locations separate from the seeds.
When spending, Sparrow creates the PSBT; signer A signs; signer B signs; Sparrow combines and broadcasts. Every person or device must review the outputs. Multisig run by an operator who confirms everything automatically merely distributes the same mistake across three screens.
None of this is a mystery to me. I still find it bureaucratic as hell: three seeds, three backups, an output descriptor, separate locations, two devices for every spend, firmware updates, and a recovery plan that another family member must be able to execute when you are no longer around.
Every layer reduces one technical risk and creates another opportunity for the operator to make a mistake. Usability is part of security too. If the architecture becomes so annoying that you stop testing backups, stop updating signers, or cannot document inheritance, the perfect multisig diagram is not worth much.
I completely understand anyone who prefers to stay with single-sig and a strong, independent, well-stored passphrase. It is much easier to operate. Just make that choice knowing you accept more risk: you still depend on one root and one signing path. If that point fails, the entire wallet falls with it. A passphrase adds a barrier; it does not add a second independent signature.
Sparrow’s best practices guide recommends 2-of-3 using hardware wallets from different vendors and backups stored in separate locations.
If one key in your 2-of-3 came from an affected ColdCard, the attacker potentially already controls that key and can produce a signature. They still cannot spend alone, but your effective threshold has fallen: now they only need to compromise one more signer. Create a new multisig wallet with a new cosigner and move the funds. You cannot “replace one key” while keeping the same addresses; the policy changed, so the scripts change too.
Fulcrum fixes privacy, not a weak key
Sparrow needs to query the blockchain. On a public Electrum server, it requests the history of script hashes derived from your addresses. The server can correlate queries, timing, and IP address to group balances and history, even without receiving the raw xpub. To avoid that, I connect Sparrow to my own Bitcoin Core node through Fulcrum.
I showed the architecture and installation in Bitcoin on the Home Server: Sovereignty and Privacy with Coldcard, Sparrow and Fulcrum. That article remains useful, with one obvious correction: do not use a seed generated by affected ColdCard firmware.
Your node validates the blockchain. Fulcrum indexes it and responds quickly to Sparrow. That improves sovereignty and query privacy. Neither can stop an attacker from signing with a private key they reproduced from bad entropy.
How I would migrate today
Do not turn one emergency into a second accident. I would follow this order:
- Take inventory. List the model, firmware that generated the seed, accounts, passphrases, derivation paths, and every multisig in which that key participates. Do not post balances or addresses on social media.
- Treat the seed as compromised. Do not enter it into online software or accept any third-party “checker.” Keep signing on the device only for as long as it takes to leave.
- Choose the new architecture. I would not generate the new seed on a ColdCard. Use another new signer bought directly from the manufacturer, a SeedSigner, or 2-of-3 with different implementations. Do not import the old words into it. If you insist on reusing your ColdCard, first install the corrected firmware for the proper model and release track.
- Generate new entropy. Use independent sources and an audited mixer. For dice, use casino-grade material, multiple sources, and at least 99 rolls for a 24-word mnemonic. I would do more.
- Back up before receiving. Mnemonic, separate passphrase, fingerprints, and the descriptor for multisig. Never photograph any of them or store them in the cloud.
- Test recovery. Recreate the wallet and verify fingerprints and addresses. In multisig, prove that two keys can sign without depending on the third.
- Verify the address on the screen. Do not trust only what Sparrow displays on the computer monitor.
- Send a small amount. Confirm that the new wallet can receive and spend. Coinkite also recommends this test.
- Move the rest immediately afterward. Review the fee and every output. Look for balances in other accounts, passphrases, and change addresses derived from the old seed.
- Keep the old backup marked as compromised. Retain it until you are certain the migration confirmed and no delayed deposit will arrive. Never reuse an old address.
If the attacker is racing you, do not spend a week designing the perfect multisig. Create a safe, verified destination, perform the minimum test, and move the funds beyond the old key’s reach. You can reorganize UTXOs and improve the architecture later, with time to think.
So which hardware wallet do I recommend?
Today, none.
After explaining entropy generation, BIP39, passphrases, PSBT, air gaps, descriptors, and multisig, it should be clear that fully offline, hand-built self-custody is very hard. I do not expect a normal person to master the mathematical implications, audit every algorithm, and execute every step without error. Most programmers could not do it either. I will not pretend I can review the entire chain alone, from silicon to the firmware running on the device.
That is exactly why hardware wallets exist. They package complicated cryptography and procedures into an interface a person can operate. This transfers part of the responsibility to the manufacturer; it does not make trust disappear.
Leaving your life savings in an exchange account remains the worst default. You do not have the keys and depend on the company’s solvency, withdrawal policy, legal system, and account security. But a handmade setup you do not understand can also end in total loss. There is no point eliminating counterparty risk only to replace it with a ceremony nobody can restore after a fire or your own death.
For years, the hardware wallet was treated as the last safe haven between those extremes. Coinkite shook trust in the entire category. That does not mean Ledger, Trezor, BitBox, Passport, Jade, SeedSigner, and everyone else are broken or equivalent. It means a strong name, secure element, air gap, visible code, and years on the market are not enough. I can no longer point to one device and say, “buy this and sleep well.” You will have to do your homework.
NEVER buy a second-hand hardware wallet. Buy it new, directly from the manufacturer’s official store. Do not save on shipping by placing your life savings in a device that passed through a stranger’s hands. Marketplace listings, auctions, eBay, “open box,” refurbished hardware, and that unbelievable deal from a friend are all out of the question.
When the package arrives, do not tear everything open and start pressing buttons. Open the official documentation for that model and follow its supply-chain verification. ColdCard uses serialized packaging that shows evidence of opening: the number appears on the bag, an internal tab, and the device itself. Trezor documents the holographic seals for each model. BitBox combines sealed packaging with cryptographic attestation performed by its app.
Check the seal, cuts, glue, serial number, box contents, and the authenticity mechanism shown by the device or official software. Any mismatch ends the setup: do not connect a seed, do not “see whether it works,” and contact the manufacturer. The device must arrive without an initialized wallet and generate new words in front of you. A seed printed inside the box is a scam.
And watch the terminology: all of this is tamper-evident, not tamper-proof. ColdCard’s own documentation admits a bag can be attacked; BitBox says perfect packaging does not guarantee authenticity. An intact seal is one layer. I still want attestation or a genuine check, signed firmware, hash verification where available, and a complete test with a small amount of money.
I would start with these questions:
- What is the published threat model? The manufacturer must say what it protects against and, more importantly, what remains out of scope: an infected computer, stolen device, physical laboratory attack, supply chain, targeted firmware, coercion. “Military-grade security” is not a threat model.
- Where does the entropy come from, exactly? Find the sources, how they are combined, and which end-to-end tests prove the
New Walletflow reaches the promised RNG. Support for dice or external entropy helps only when the mixing mechanism is documented and audited. The ColdCard case showed that having the correct TRNG inside the binary does not mean seed generation uses it. - Is the code actually free, and does the binary correspond to it? “Source available” under a restrictive license is not FOSS. Open code permits audits, but does not prove anyone performed one. A reproducible build lets third parties rebuild the firmware and compare it bit for bit. Look for current independent verifications on WalletScrutiny, not just the manufacturer’s promise.
- How does the company treat people who find flaws? Read the disclosure policy, scope, and bounty amounts. Look for old advisories, CVEs, postmortems, and conversations with researchers. A company that publishes a vulnerability, explains its cause, fixes it quickly, and thanks the researcher deserves more trust than one with a supposedly “perfect” history. Sometimes nobody found a vulnerability because nobody competent had an incentive to look.
- What can you verify on the trusted screen? Before signing, the device should display the address, amount, fee, and change. It should verify receiving addresses on its own display, allow PIN and passphrase entry without handing them to the computer, and correctly register the multisig policy. A secure element protects a key; it cannot rescue an interface that makes you sign without understanding the outputs.
- Is there an exit route without the manufacturer? I want interoperable standards: BIP39/BIP32 where applicable, PSBT, and output descriptors. I want to export xpubs, fingerprints, and descriptors, use Sparrow, connect my node, and recover through another implementation. Mandatory accounts, proprietary clouds, and backups that open only in the company’s app are lock-in built on top of the key to your life.
- How do the hardware, firmware, and supply chain work? A secure element, ordinary microcontroller, and stateless signer make different tradeoffs. Find out what persists on the device and what a physical attacker can extract. Releases should be signed, have useful changelogs, prevent unsafe downgrades, and receive maintenance for years. Research how the device proves authenticity, how the company documents packaging and transport, what happens if the update server disappears, and which closed components exist. An air gap is not a magic seal either: QR, NFC, and microSD are input parsers and remain an attack surface.
- Can you recover without improvising? Before depositing meaningful value, generate the wallet, back it up, erase the device, and recover. Verify the fingerprint, an address, and a complete round-trip transaction. In multisig, restore the descriptor and prove the quorum works without one key. An untested backup is hope, not a backup.
I would also research the repository history, security issues, recent commits, independent audits, and the time between a vulnerability report and its fix. I would search for the model name alongside vulnerability, reproducible build, seed entropy, multisig, and responsible disclosure. An influencer review with an affiliate link is useful for seeing the screen and device size, not for deciding where to store your wealth.
For small amounts, a thoroughly researched commercial signer may be much less risky than a handmade invention. For wealth that changes your life, 2-of-3 with different manufacturers and codebases remains the reference, as Sparrow’s guide recommends. It limits the damage from one compromised vendor, but demands more backups, more testing, and a well-documented policy. Multisig you cannot restore is worse than well-maintained single-sig.
In some collaborative custody services, a company holds one key in a 2-of-3 setup. It should not be able to spend alone, but it learns information about your wallet and can disappear, deny service, or complicate recovery. A professional custodian also exchanges technical risk for legal and counterparty risk. In the end, you choose which risk you carry and which you hand to someone else.
The best recommendation I can offer is not a brand. Choose an architecture proportional to the amount and determine which failures it tolerates. Before depositing money that would hurt to lose, run the entire flow with a small amount: receive, spend, erase one signer, restore the backup, and see whether you can return on your own.
Conclusion
Self-custody removes the custodian but leaves a brutal responsibility behind. Trust remains spread across silicon, firmware, the compiler, the build process, the wallet coordinator, and your own discipline. Hardware wallets remain useful because doing everything by hand is impractical for almost everyone. The mistake is confusing the tool with a guarantee.
I do not recommend a specific brand today. I prefer to distribute risk and create ways to catch failures: independent entropy sources, free code, reproducible builds verified by third parties, rehearsed recoveries, different signers, and multisig when the amount justifies it and you accept the bureaucracy. Single-sig with a passphrase is an understandable choice. It simply does not provide the same fault tolerance. Make that choice knowing what you delegate and which risk you decided to keep.
This may become one of the worst episodes in the history of Bitcoin self-custody. Not because someone left coins on a shitty exchange, typed a seed into a phishing site, or installed a pirated wallet. Many people bought a dedicated device, wrote down 24 words, kept the backup in steel, kept everything offline, and signed through an air gap. They did exactly what Bitcoin culture taught as the correct procedure. A nasty bug still caught them at the most important moment of all: choosing the root.
In the worst cases, the RNG reduced the universe to something around
2^40. The attacker does not need to touch the ColdCard. They enumerate possible states, derive the most likely BIP32 trees and addresses, query the public blockchain, and find which candidates hold UTXOs. Once they find one, they also have the private keys needed to sign. The ColdCard may be powered off, without a battery or USB cable, and locked in a safe. It makes no difference. An air gap protects the path between signer and computer; it cannot recover entropy that never existed.
There was no visible warning. The wallet received, signed, and restored normally until the day someone else reproduced the same key. That is why 12 versus 24 words, air gap versus USB, and secure element versus microcontroller become secondary debates when nobody tested whether the New Wallet button called the correct RNG.
It also shows why I refuse to call negligence a black swan. The source was open, the path was auditable, and the culture pushed away some of the people most capable of spotting problems. It was a white swan waiting for someone to look in the right direction.
The lesson is not to abandon self-custody. It is to stop outsourcing understanding. Study the threat model, find out how entropy is generated, inspect the manufacturer’s history, rehearse recovery, and know which risks remain concentrated. Do not blindly trust a company, certification, influencer, tutorial, or article. Not even this one. Verify.
I have already moved my funds from the old ColdCard. In practice, if you own any ColdCard, do the same. There is no prize for finding out too late that your case had another undocumented exception.
Choose the new architecture using the criteria above. Generate a completely new root. Mix genuinely independent entropy. Test the backup. Verify the addresses. Move everything.