L’alerte COLDCARD publiée fin juillet 2026 ne se résume pas à « une seed un peu moins aléatoire ». Elle révèle une chaîne de défaillances beaucoup plus instructive : un changement d’API, un générateur matériel désactivé, un fallback pseudo-aléatoire non cryptographique, un reseed tronqué à 32 bits sur les modèles récents et des tests capables de détecter des zéros — mais pas de la prévisibilité.
Le résultat était trompeur : des mots BIP-39 parfaitement valides, un wallet fonctionnel et des sorties visuellement aléatoires, alors que l’espace réel des secrets possibles pouvait être nettement inférieur à celui attendu.
Résumé opérationnel
Pour les utilisateurs, les conclusions pratiques restent simples :
- les seeds générées sur les firmwares concernés doivent être considérées comme exposées selon les critères de l’avis officiel ;
- installer un firmware corrigé protège les futures générations, mais ne répare pas une seed existante ;
- une passphrase BIP-39 forte réduit l’exposition immédiate sans corriger la faiblesse initiale ;
- au moins 50 lancers de dés privés, indépendants et correctement intégrés peuvent fournir 128 bits d’entropie indépendamment du générateur défaillant ;
- une migration doit être méthodique : nouvelle seed saine, sauvegarde vérifiée, adresse contrôlée sur l’écran, transaction test, puis transfert du solde.
L’avis officiel de Coinkite reste la référence pour les versions corrigées et la procédure utilisateur. L’analyse technique de Block Engineering apporte l’explication détaillée du chemin logiciel.
Le point de départ : un changement d’API en 2021
Selon l’analyse publiée par Block, les anciens firmwares Mk2 et Mk3 obtenaient directement des octets depuis le générateur matériel du microcontrôleur par une fonction dédiée.
En mars 2021, la génération des secrets a été redirigée vers une interface plus générique, random.bytes(32), fournie par une bibliothèque appelée libngu. Ce type de refactorisation semble anodin : on remplace une fonction locale par une abstraction commune censée fournir le même service.
Le problème est que cette abstraction ne suivait pas le chemin matériel attendu dans la configuration de production de COLDCARD.
Une condition de compilation qui ne vérifiait pas la bonne chose
La configuration MicroPython utilisée par COLDCARD définissait explicitement le générateur matériel comme désactivé :
#define MICROPY_HW_ENABLE_RNG (0)
Ce choix n’était pas nécessairement une erreur en lui-même. COLDCARD disposait de son propre wrapper pour utiliser le RNG matériel.
La subtilité venait de la façon dont une dépendance testait cette configuration. Elle vérifiait essentiellement si la macro existait, et non si sa valeur était réellement activée. Or une macro définie à 0 existe bien pour le préprocesseur.
Le code pouvait donc compiler sans alerte tout en empruntant, à l’exécution, un chemin de secours différent du générateur matériel attendu.
C’est un exemple classique de faille d’intégration : chaque composant peut sembler cohérent isolément, mais leur combinaison produit un comportement de sécurité inattendu.
Le fallback Yasmarang : variable ne veut pas dire imprévisible
Lorsque le générateur matériel n’était pas disponible, MicroPython utilisait un générateur pseudo-aléatoire appelé Yasmarang.
Yasmarang peut produire une longue suite d’octets qui paraît irrégulière. Mais il n’est pas conçu comme un générateur cryptographiquement sûr. Si son état initial est connu ou suffisamment contraint, ses sorties peuvent être reproduites.
D’après Block, cet état initial dépendait notamment :
- d’une partie de l’identifiant unique du microcontrôleur ;
- du compteur
SysTickdepuis le démarrage ; - des registres de l’horloge RTC et de ses sous-secondes ;
- de l’ordre et du nombre d’appels au générateur.
Ces valeurs apportent de la variation. Elles ne garantissent pas une entropie cryptographique. L’identifiant est fixe, les compteurs sont liés au temps de démarrage et plusieurs variables peuvent être corrélées ou partiellement observables.
Une deuxième instance déterministe était ensuite combinée au résultat. Mais combiner deux suites reproductibles ne crée pas spontanément une source de hasard indépendante.
Pourquoi le hash ne répare pas l’entropie
La sortie obtenue passait ensuite par SHA-256d avant de devenir la matière utilisée pour la seed.
Un hash cryptographique transforme une entrée en une sortie uniforme et difficile à inverser directement. En revanche, il n’augmente pas le nombre d’entrées possibles.
Si le générateur ne peut produire que N états distincts, le hash ne peut produire, dans ce contexte, que N résultats accessibles :
petit espace d’états possibles
↓ SHA-256d
sorties uniformes en apparence
mais toujours limitées au même espace
Le checksum BIP-39 ne crée pas davantage d’entropie. Il permet de détecter certaines erreurs de transcription. La spécification BIP-39 attend 128 à 256 bits d’entropie initiale avant l’ajout du checksum.
Une suite de 12 ou 24 mots peut donc être syntaxiquement parfaite tout en étant cryptographiquement plus faible que prévu.
Pourquoi les tests ont laissé passer le problème
Les tests en place vérifiaient principalement que le générateur ne renvoyait pas deux fois exactement la même valeur et que la sortie contenait suffisamment d’octets distincts.
Ces contrôles détectent un générateur bloqué, rempli de zéros ou manifestement cassé. Ils ne détectent pas un générateur déterministe qui produit une suite différente à chaque appel.
Un PRNG prévisible passe facilement un test de variété superficielle. Pour détecter le problème, il aurait fallu vérifier la provenance effective de l’entropie, tester les configurations de compilation et reproduire les sorties à partir d’états initiaux contrôlés.
C’est l’une des leçons les plus importantes de l’incident : tester que des nombres changent n’est pas tester qu’ils sont imprévisibles.
Deux profils de vulnérabilité différents
Mk2 et Mk3 : un chemin sans véritable apport cryptographique
Pour les Mk2 et Mk3 concernés, l’analyse de Block décrit un chemin où aucune source d’entropie cryptographique indépendante n’alimentait réellement cette génération.
La difficulté d’une recherche dépend alors de ce que l’attaquant connaît : identifiant de l’appareil, fenêtre de démarrage, état de l’horloge et historique des appels. Block présente plusieurs modèles théoriques, allant d’espaces très réduits lorsque certains paramètres sont connus à des bornes plus larges lorsque davantage d’incertitudes doivent être explorées.
Ces estimations ne sont pas des benchmarks universels d’exploitation. Elles montrent cependant que la sécurité ne reposait plus sur les 128 ou 256 bits attendus d’une seed saine.
Coinkite désigne officiellement les firmwares Mk2/Mk3 4.0.1 à 4.1.9 comme concernés. Block situe toutefois le changement de chemin logiciel dès la version publique 4.0.0. Par prudence, une seed créée sous 4.0.0 devrait donc aussi être traitée comme potentiellement concernée, même si cette version n’apparaît pas dans la plage officielle publiée par Coinkite.
Mk4, Mk5 et Q : de l’entropie sécurisée, mais un reseed limité
Les modèles plus récents ajoutaient des données provenant de leurs éléments sécurisés. Le défaut n’était donc pas identique à celui des Mk2/Mk3.
Selon Block, ces données étaient hachées, mais seuls quatre octets du résultat — soit 32 bits — étaient transmis à la fonction de reseed de Yasmarang. Cette fonction modifiait une partie limitée de l’état du générateur au lieu d’initialiser un DRBG cryptographique complet avec toute l’entropie disponible.
Pour un état déterministe et un historique d’appels fixés, l’apport sécurisé distinguait donc au maximum 2^32 flux liés à ce reseed. Les compteurs et timings ajoutaient d’autres inconnues, mais celles-ci ne doivent pas être confondues avec des bits d’entropie indépendants et robustes.
Coinkite résume l’impact sur Mk4, Mk5 et Q à environ 72 bits d’entropie au lieu des 128 bits attendus. Block présente de son côté des bornes théoriques dépendantes du modèle d’attaquant. Les deux chiffres décrivent des angles différents et ne constituent pas une mesure unique, garantie, du coût réel d’exploitation.
Comment une adresse ou un XPUB devient un oracle de validation
Un attaquant n’a pas besoin de reconnaître directement les bons mots parmi des millions de candidats.
Une information publique du wallet peut servir à vérifier chaque hypothèse :
- reproduire un état possible du générateur ;
- obtenir une seed candidate ;
- dériver les clés, l’XPUB ou les adresses correspondantes ;
- comparer le résultat avec une adresse ou un XPUB connu ;
- conserver le candidat lorsqu’une correspondance apparaît.
Le calcul peut être réalisé hors ligne. La blockchain, une adresse déjà utilisée ou un wallet watch-only fournit alors le point de comparaison.
Cette description explique le principe, mais pas le coût exact d’une attaque réelle. Block précise que ses premiers résultats ne constituaient pas un benchmark complet, reproductible et universel contre tous les appareils concernés.
Le problème pouvait dépasser les seules seeds BIP-39
L’analyse de Block identifie d’autres fonctions utilisant le même flux pseudo-aléatoire selon les versions :
- certaines clés privées de paper wallets ;
- des masques générés pour Seed XOR ;
- des clés temporaires utilisées par des fonctions de clonage ou de transfert ;
- des secrets Web2FA ;
- certains mots de passe ou secrets générés par l’appareil ;
- du matériel utilisé dans certains modes HSM.
Cela ne signifie pas que toutes ces fonctions ont été exploitées ni qu’elles possèdent exactement le même profil de risque. Leur exposition dépend de la version, du modèle, de l’usage, des autres secrets impliqués et de la visibilité des données publiques permettant de tester des candidats.
Cette extension du périmètre montre néanmoins pourquoi l’incident est plus profond qu’une erreur d’affichage de mots : la confiance dans une source aléatoire commune se propage à toutes les fonctions qui l’utilisent.
Chronologie de la régression
La chronologie reconstituée par Block illustre la difficulté de repérer ce type de défaut :
- janvier 2021 : la logique de détection problématique existe dans la dépendance ;
- mars 2021 : la génération de secrets COLDCARD est redirigée vers cette interface ;
- mars 2022 : le mécanisme de reseed limité est introduit pour les modèles plus récents ;
- 30 juillet 2026 : Block et Coinkite publient leurs premières alertes après des signalements et une analyse accélérée ;
- août 2026 : les firmwares corrigés sont disponibles pour les modèles et branches concernés.
La régression est donc restée visible dans du code open source pendant plusieurs années. L’open source facilite l’audit, mais ne garantit pas qu’un défaut sera immédiatement identifié. Encore faut-il que le bon chemin de compilation, les dépendances et les hypothèses d’entropie soient effectivement examinés.
Ce qui est confirmé et ce qui reste à établir
| Niveau | Éléments | |---|---| | Confirmé par Coinkite | Versions concernées, versions corrigées, impact sur les seeds existantes, exception liée aux dés, rôle de la passphrase et procédure de migration | | Détaillé par Block | Chemin du fallback, rôle de Yasmarang, reseed limité à 32 bits, modèles théoriques de recherche et autres consommateurs possibles du RNG | | Pas encore établi publiquement de manière définitive | Nombre exact de wallets exploités, montant total attribuable au défaut, coût pratique pour chaque modèle et périmètre complet des fonctions attaquées |
Coinkite présente encore son avis comme une analyse préliminaire et annonce une revue technique formelle. Tant que cette revue finale et des reproductions indépendantes complètes ne sont pas disponibles, les chiffres d’exploitation et de pertes doivent être présentés comme des estimations, pas comme des faits définitivement attribués.
Modèles et versions à traiter comme concernés
| Modèle | Génération à considérer comme concernée | Version corrigée minimale | |---|---|---| | Mk2 / Mk3 | Coinkite : 4.0.1 à 4.1.9 ; prudence également pour 4.0.0 selon l’analyse de Block | 4.2.0 | | Mk4 / Mk5 Standard | Seed générée avant la version corrigée | 5.6.0 | | Q Standard | Seed générée avant la version corrigée | 1.5.0Q | | Mk4 / Mk5 Edge | Seed générée avant la version corrigée | 6.6.0X | | Q Edge | Seed générée avant la version corrigée | 6.6.0QX |
Les branches Standard et Edge sont distinctes. TAPSIGNER, OPENDIME et SATSCARD ne sont pas concernés selon Coinkite, car ils utilisent d’autres bases de code.
Pourquoi la mise à jour ne répare pas une seed existante
La mise à jour modifie la façon dont le prochain secret sera généré. Elle ne change pas les clés déjà dérivées depuis une seed antérieure.
Importer cette seed dans un autre hardware wallet ne la renforce pas. Lui appliquer un système de sauvegarde plus robuste ne la renforce pas non plus. Le secret d’origine reste identique.
C’est pourquoi GLOV SSS peut protéger et distribuer la sauvegarde d’une nouvelle seed saine, mais ne peut pas réparer une seed initialement créée avec une entropie insuffisante. Fragmenter un secret faible produit une meilleure organisation du même secret faible.
Dés et passphrase : deux protections différentes
Coinkite indique qu’au moins 50 lancers de dé équitable, indépendants, privés et non enregistrés, ajoutés à la seed finale, fournissent à eux seuls au moins 128 bits d’entropie. Avec 99 lancers ou davantage, l’apport approche 256 bits.
Une passphrase BIP-39 forte et unique ajoute une autre barrière : même si la seed de base est retrouvée, l’attaquant doit encore découvrir la passphrase correspondant au wallet financé.
Ces protections ne doivent pas être confondues :
- les dés améliorent l’entropie de la seed lors de sa création ;
- la passphrase dérive un wallet distinct à partir de la seed ;
- le PIN protège l’accès local à l’appareil, mais n’ajoute pas de secret au wallet BIP-39.
Coinkite recommande néanmoins aux utilisateurs protégés par une passphrase forte de migrer dès que cela peut être réalisé sans précipitation.
Migrer sans créer un second incident
La migration doit réduire le risque, pas le déplacer :
- identifier le modèle et la branche Standard ou Edge ;
- installer le firmware corrigé depuis la source officielle et vérifier la version affichée ;
- générer une nouvelle seed, distincte de l’ancienne ;
- sauvegarder et vérifier la nouvelle seed avant tout dépôt ;
- contrôler une adresse de réception directement sur l’écran du hardware wallet ;
- envoyer une petite transaction test et vérifier la capacité de dépense ;
- transférer le solde restant ;
- conserver l’ancienne sauvegarde jusqu’à la confirmation complète de la migration.
Dans un multisig, remplacer une clé implique généralement de créer une nouvelle politique ou un nouveau descripteur et de déplacer les fonds. Le quorum n’annule le risque que s’il contient suffisamment de clés réellement indépendantes et saines.
Notre guide sur la migration d’un wallet potentiellement compromis détaille les contrôles opérationnels à effectuer.
Les enseignements pour une architecture de custody
Cet incident ne démontre pas l’échec de la self-custody. Il montre que la confiance ne disparaît pas : elle se déplace vers le firmware, le matériel, les dépendances, le processus de compilation et la qualité des tests.
Une architecture plus résiliente peut combiner :
- plusieurs sources d’entropie comprises et vérifiables ;
- une documentation précise du firmware utilisé lors de la génération ;
- un multisig avec des implémentations et fabricants réellement diversifiés ;
- des sauvegardes séparées des appareils ;
- des tests périodiques de restauration ;
- une procédure écrite pour les alertes et migrations ;
- un audit de sécurité crypto portant sur l’ensemble de l’architecture, pas seulement sur le modèle du hardware wallet.
GLOV Secure intervient sur cette couche d’organisation et de gouvernance sans détenir les fonds ni conserver les secrets du client.
Sources techniques
Pour examiner une seed, un multisig ou une architecture de wallets après cette alerte, vous pouvez contacter GLOV.