Compromisos de Pedersen
Cómo sumar importes que nadie puede ver y comprobar que el balance cuadra
Un importe v se oculta en el punto C = y·G + v·H, donde y es una «máscara» aleatoria. Los compromisos se pueden sumar: la suma de compromisos compromete a la suma de importes. La red comprueba que Σ inputs − Σ outputs − fee·H compromete a cero sin conocer ningún importe.
Qué es un compromiso
Un compromiso (commitment) es un «sobre cerrado con un número dentro». Tiene dos propiedades:
- Ocultación (hiding): no se puede saber el número mirando el sobre.
- Vinculación (binding): no se puede abrir el sobre como si contuviera otro número.
Un compromiso de Pedersen sobre una curva elíptica:
Sin la máscara y tendríamos C = v·H, y el importe sería fácil de averiguar por fuerza bruta (no hay tantos importes posibles). La máscara hace que C sea indistinguible de un punto aleatorio.
Por qué importa el segundo generador H
H se obtiene aplicando a G un hash a punto, así que nadie conoce un k tal que H = k·G. Si alguien conociera k, podría «reabrir» un compromiso: y·G + v·H = (y + k(v − v'))·G + v'·H, e imprimir dinero de la nada. La vinculación se basa precisamente en que nadie conoce k.
Homomorfismo: sumar a ciegas
La suma de dos sobres es un sobre con la suma. Así la red puede comprobar que nada se crea ni se destruye:
Solo queda demostrar que la diferencia tiene de verdad la forma z·G (y no z·G + algo·H). Basta con firmar usándola como clave pública: la firma solo funciona si conoces z y no hay componente H. La comisión es pública, así que su compromiso es simplemente fee·H, sin máscara.
Pseudo-salidas: cómo funciona esto con anillos
Hay una pega: la entrada es un anillo de 16 salidas, y no podemos decir cuál es el compromiso real. La solución de RingCT es el compromiso de pseudo-salida C̃:
- para cada entrada, el remitente crea un compromiso nuevo
C̃ = y'·G + v·Hcon el mismo importe pero una máscara nueva; - las máscaras se eligen de forma que
Σ C̃ = Σ C_out + fee·Hexactamente (el balance se comprueba con las pseudo-salidas); - en CLSAG, para cada miembro del anillo, se demuestra que
C_i − C̃compromete a cero para el miembro real:C_π − C̃ = (y − y')·G.
Así la firma de anillo demuestra a la vez la propiedad de la salida y que el importe de la pseudo-salida es igual al de la entrada real.
Cómo conoce el destinatario el importe y la máscara
Remitente y destinatario comparten el secreto Hs(8rA ‖ i) (ver direcciones de un solo uso). A partir de él derivan:
amount_enc = v ⊕ Keccak( "amount" ‖ Hs(8rA ‖ i) )[0..8]
El importe cifrado (8 bytes) va en la transacción. El destinatario descifra v, calcula y y comprueba que y·G + v·H coincide con C en la blockchain.
¿Qué impide un importe negativo?
Toda la aritmética es módulo l. «−1» es l − 1, un número enorme. Se podría crear una salida de 1000 XMR y otra de «−999 XMR»: el balance cuadraría y aparecerían 999 XMR de la nada. Los compromisos no pueden detectarlo. Por eso cada salida va acompañada de una prueba de rango.