Key image
La huella que deja una salida al gastarse, exactamente una vez
La key image (imagen de clave) I = x·Hp(P), donde P es la clave de un solo uso de la salida y x su clave privada. Para una salida dada la key image es siempre la misma, pero no revela de qué salida se trata. La red guarda todas las key images y rechaza cualquier transacción con una repetida.
El problema del doble gasto
En Bitcoin el doble gasto es fácil de detectar: cada entrada apunta directamente a la salida que gasta, y el nodo recuerda esa salida como gastada (el conjunto UTXO). En Monero una entrada apunta a 16 salidas, y no se sabe cuál es la real. Así que «marcar la salida gastada» es imposible. Hace falta una forma de marcar un gasto sin revelar qué se gastó.
La solución
Por qué funciona:
- Determinista.
xyPson fijos para una salida, así queIes único. Volver a gastar la salida significa publicar la mismaI. - No vinculable. Para comprobar que
Icorresponde aPhace faltax: un observador externo ve dos puntos «aleatorios»,Hp(P)eI, y no puede establecer la relación (un problema de Diffie–Hellman). - Infalsificable. La firma de anillo vinculable demuestra que
Ise calculó con el mismoxque una de las claves del anillo.
¿Por qué Hp(P) y no simplemente G? Porque entonces I = x·G = P: la key image sería igual a la clave pública de la salida y el gasto se vería al instante. Hp da un punto cuyo logaritmo nadie conoce, una «segunda base» única para cada salida.
La comprobación del subgrupo: el error de 2017
Ed25519 tiene 8 veces más puntos que el subgrupo de G. Sumar a I un punto de orden pequeño T (con 8·T = 0) da un punto distinto I' = I + T, y bajo ciertas condiciones la firma de anillo seguía verificándose. Una salida: hasta 8 key images distintas, hasta 8 gastos. En 2017 se encontró este error en el código original de CryptoNote; Monero lo corrigió antes de que se explotara, mientras que en Bytecoin sí se explotó.
La solución: el nodo comprueba que l·I = 0, es decir, que I está en el subgrupo correcto.
Key images y monederos de solo lectura
Para saber si tu salida está gastada, el monedero calcula su key image y la busca en la blockchain. Para eso hace falta x = Hs(8aR ‖ i) + b, es decir, la clave de gasto. Por eso un monedero de solo lectura no ve los gastos y muestra un saldo inflado. La solución es exportar las key images desde el monedero completo. Carrot añade una clave dedicada para esto.
Key images en FCMP++
En FCMP++ la key image se mantiene: L = x·Hp(O). Lo que cambia es cómo se demuestra su relación con la salida: en lugar de un anillo, una prueba de pertenencia al árbol de todas las salidas. Una consecuencia importante: todas las key images ya publicadas en transacciones RingCT conservan su significado, y una salida antigua no se puede gastar por segunda vez tras el cambio.