Coldcard-lek: hoe kon dit gebeuren?

De Coldcard van Coinkite heb ik altijd beschouwd als een mooie bitcoin-hardware wallet. Als je er niet bekend mee bent, lijkt het een beetje op een rekenmachine met wat missende knoppen. Toen het nieuws naar buiten kwam dat er bitcoin-UTXO’s naar onbekende adressen waren verstuurd, was dat wel een bominslag. Ik heb er namelijk zelf ook een.

De kwetsbaarheid ontstond in maart 2021. In die periode voerde Coinkite een grote firmware-migratie door, deels ingegeven door de overstap van de GNU GPL-licentie naar het MIT + Commons Clause Bitcoin Only License. Het was een grote rewrite, waarbij onder andere werd overgestapt op andere libraries (libngu en MicroPython). Daarbij werd er een bug geïntroduceerd waarmee de correcte aanroep van de hardware-TRNG incorrect gebeurde. Wat betekende dat de willekeurigheid (randomness) helemaal niet meer goed functioneerde. Voor wie net als ik in 2022 of later een Coldcard kocht, betekende dit dat seeds die op het apparaat zelf waren gegenereerd dus eigenlijk helemaal niet zo veilig en willekeurig waren als de verwachting van een apparaat welk primaire doel dat is.

Wat ging er technisch mis?

Een computer is in principe niet in staat om 'randomness' te genereren, daarvoor zijn er externe bronnen nodig, denk bijvoorbeeld de elektrische ruis in een computerchip of de hoeveelheid een harde schijf aan het werk is op het moment dat je je seed aanmaakt. Het aanmaken van 'entropie' of willekeurigheid is niet een eenvoudig proces, dit is ook wat er is misgegaan bij de Coldcard. In de computerwereld zijn er, om het enigszins eenvoudig te houden, twee veelgebruikte manieren om randomness aan te maken:

  1. True Random Number Generator (TRNG)
  2. Pseudo-Random Number Generator (PRNG)

Een TRNG haalt échte onvoorspelbare ruis uit de fysieke wereld, zoals elektrische ruis in de chip. Een PRNG is een softwarematig algoritme dat alleen willekeurig lijkt. Als je eenzelfde computer/apparaat opstart en het gebruikt bijvoorbeeld de opstarttijd als seed voor de randomness, dan is dit vrij triviaal te brute-forcen.

De nerd-details

Door een verkeerde check kwam ging het aanmaken van de seed voor het bewaren van je bitcoin niet door de TRNG maar door de PRNG, welke dus enigszins makkelijk te brute-forcen is. In plaats van dat de code keek of de TRNG daadwerkelijk functioneerde, keek de code alleen maar of er een TRNG aanwezig is (wat bij Coldcard wel zo is). Even super nerdy, het was dus een verschil tussen #ifndef in plaats van #if. De PRNG bij Coldcard gebruikte de chip-ID, een waarde die niet geheim is en ook makkelijk doorloopbaar is. Stel een chip heeft waarde ABC001 dan kan je dus ook de waarde ABC002 proberen en op die manier de PRNG voorspellen.

Bitcoin-seed

Daar gaat dus dit hele verhaal om, want een bitcoin-seed is niets anders dan een menselijk leesbare versie van een lange reeks willekeurige cijfers (bits). Die willekeurige bits noemen we "entropy". Hoe meer échte, onvoorspelbare entropy, hoe groter de ruimte van mogelijke seeds en hoe onmogelijk het wordt om die te raden. Als je een heel groot aantal kluisjes hebt zonder sleutel en alleen door de kluis te openen je toegang hebt tot wat daarin ligt, dan is dat bij voldoende entropy vrijwel onmogelijk omdat het aantal kluisjes waar je in kan kijken groter is dan de hele aarde bij een goed gemaakte entropy. Echter in het geval van Coldcard was het aantal kluisjes dermate klein dat iemand met genoeg rekenkracht alle kluisjes in een hele korte periode kon inzien en dus de bitcoin kon verplaatsen.

Eigen entropy

Terug naar mij Coldcard situatie. Ik heb destijds minimaal ongeveer 100 keer een dobbelsteen laten rollen en dat gebruikt voor de entropie van mijn seed, daarmee heb ik dus voldoende eigen entropy ingebracht en ben ik daardoor niet getroffen door de gebrekkige PRNG, ik was eigenlijk mijn eigen TRNG. Het blijft wel vertrouwen dat de software die dobbelsteenworpen wel op een juiste implementatie toegepast wordt op het maken van de seed. Eigen entropy is een sterke extra laag, maar geen absolute garantie als de rest van de code fouten bevat. Ik heb zelf uit voorzorg toch mijn bitcoin verplaatst naar Bitonic.

De schade en de reactie

Kevin Loaec heeft een vrij uitgebreide blogpost gemaakt over deze hele situatie. Volgens analyses van Galaxy Research en Block is er op 30 juli 2026 in circa 41 minuten 1082,65 BTC gestolen uit 1196 adressen. Dat komt neer op ongeveer €59 miljoen. De coins zijn geconsolideerd op een handvol adressen en stonden op het moment van schrijven grotendeels nog stil. Het totale aantal staat nu boven de 1300 BTC, maar omdat het lijkt dat er nu meerdere hackers bezig zijn is het tracken een stuk minder makkelijk geworden. Op deze site heeft iemand een overzicht gemaakt.

Voor de getroffen houders is dit een harde klap. Je bent bewust bezig met bitcoin en probeert dit op een goede manier in je cold storage te behouden, mensen die jarenlang zorgvuldig self-custody toepasten, zagen hun coins toch verdwijnen. Het versterkt het gevoel van kwetsbaarheid, zelfs bij wie alles “goed” leek te doen. De bitcoinprijs zelf reageerde mild (rond €54.500–€55.000), maar er stroomde meer dan 11.000 BTC naar centrale exchanges.

Wat nu?

Het allerbelangrijkste is dat als je je bitcoin-seed op een Coldcard hebt aangemaakt om je bitcoin te verplaatsen, bijvoorbeeld tijdelijk naar Bitonic. Er zijn updates beschikbaar zodat de Coldcard de TRNG gebruikt in plaats van de PRNG, maar het blijft een grote schok geven in de betrouwbaarheid van externe partijen. Mijn persoonlijke mening is dat de beste oplossing een multi-sig is met meerdere air-gapped laptops met een combinatie van Sparrow en Electrum. Je kan je bitcoin ook bij Bitonic bewaren natuurlijk. Ik denk zelf dat de bitcoin community hier wel op gaat reageren en betere oplossingen gaan verzinnen en maken om self-custody toch de beste manier van bitcoin bezitten te blijven maken.


Belangrijke thema’s in dit artikel. Klik op een thema en ontdek meer.