Key image
L’empreinte qu’une sortie laisse en étant dépensée — une seule et unique fois
La key image (image de clé) I = x·Hp(P), où P est la clé à usage unique de la sortie et x sa clé privée. Pour une sortie donnée, la key image est toujours la même, mais elle ne révèle pas de quelle sortie il s’agit. Le réseau conserve toutes les key images et rejette une transaction dont la key image est répétée.
Le problème de la double dépense
Dans Bitcoin, les doubles dépenses sont faciles à détecter : chaque entrée désigne directement la sortie qu’elle dépense, et un nœud mémorise la sortie comme dépensée (l’ensemble UTXO). Dans Monero, une entrée désigne 16 sorties, et on ignore laquelle est la vraie. « Marquer la sortie dépensée » est donc impossible. Il faut un moyen de marquer une dépense sans révéler ce qui a été dépensé.
La solution
Pourquoi cela fonctionne :
- Déterministe.
xetPsont fixes pour une sortie, doncIest unique. Dépenser à nouveau la sortie oblige à publier le mêmeI. - Non reliable. Pour vérifier que
Icorrespond àP, il fautx: un observateur voit deux points « aléatoires »Hp(P)etIet ne peut pas établir le lien (un problème de Diffie–Hellman). - Infalsifiable. La signature en anneau liable prouve que
Ia été calculé avec le mêmexque l’une des clés de l’anneau.
Pourquoi Hp(P) et pas simplement G ? On aurait alors I = x·G = P — la key image serait égale à la clé publique de la sortie et la dépense serait immédiatement visible. Hp donne un point dont personne ne connaît le logarithme — une « seconde base » propre à chaque sortie.
La vérification du sous-groupe : le bug de 2017
Ed25519 compte 8 fois plus de points que le sous-groupe de G. Ajouter à I un point d’ordre faible T (avec 8·T = 0) donne un point différent I' = I + T, et sous certaines conditions la signature en anneau restait valide. Une sortie — jusqu’à 8 key images différentes — jusqu’à 8 dépenses. En 2017, ce bug a été découvert dans le code original de CryptoNote ; Monero l’a corrigé avant toute exploitation, tandis que Bytecoin a été exploité.
Le correctif : le nœud vérifie que l·I = 0, c’est-à-dire que I appartient au bon sous-groupe.
Key images et portefeuilles en lecture seule
Pour savoir si votre sortie est dépensée, le portefeuille calcule sa key image et la cherche sur la blockchain. Cela nécessite x = Hs(8aR ‖ i) + b — c’est-à-dire la clé de dépense. Un portefeuille en lecture seule ne voit donc pas les dépenses et affiche un solde gonflé. La solution de contournement consiste à exporter les key images depuis le portefeuille complet. Carrot ajoute une clé dédiée à cet usage.
Les key images dans FCMP++
Dans FCMP++, la key image demeure : L = x·Hp(O). Ce qui change, c’est la façon de prouver son lien avec la sortie — au lieu d’un anneau, une preuve d’appartenance à l’arbre de toutes les sorties. Conséquence importante : toutes les key images déjà publiées dans des transactions RingCT conservent leur sens — une ancienne sortie ne peut pas être dépensée une seconde fois après la transition.