Continuamos nuestro ciclo sobre el funcionamiento de la blockchain de Monero, y el artículo de hoy se centrará en el protocolo RingCT (Transacciones Confidenciales en Anillo), que presenta transacciones confidenciales y nuevas firmas en anillo. Desafortunadamente, hay poca información en internet sobre cómo funciona, y hemos intentado llenar este vacío.

Hablaremos sobre cómo este protocolo oculta las cantidades de transferencias en la red, por qué se abandonaron las clásicas firmas en anillo de Cryptonote y cómo evolucionará esta tecnología en el futuro.
Dado que este protocolo es una de las tecnologías más complejas en Monero, el lector necesitará conocimientos básicos sobre el funcionamiento de esta blockchain y un conocimiento superficial de la criptografía sobre curvas elípticas (para refrescar estos conocimientos, se puede leer los primeros capítulos de nuestro artículo anterior sobre ).
El protocolo RingCT
Uno de los posibles ataques a las criptomonedas cryptonote es el análisis de la blockchain, basado en el conocimiento de la cantidad y el tiempo de la transacción enviada. Esto permite reducir significativamente el ámbito de búsqueda de los salidas que interesan a los atacantes. Para protegerse contra este análisis, Monero implementó un protocolo de transacciones anónimas que oculta completamente las cantidades de las transferencias en la red.
Cabe destacar que la idea de ocultar cantidades no es nueva. Uno de los primeros en describirla fue el desarrollador de Bitcoin Core, Greg Maxwell, en su . La implementación actual de RingCT es una modificación que permite el uso de firmas en anillo (¿cómo podría ser de otra manera?) y por ello recibió su nombre — Transacciones Confidenciales en Anillo.
Además, el protocolo ayuda a eliminar los problemas de mezclar salidas de polvo — salidas de pequeñas cantidades (que generalmente resultan de devoluciones de transacciones), que causaron más problemas de los que valían.
En enero de 2017, se llevó a cabo un hard fork de la red Monero que permitió el uso opcional de transacciones confidenciales. Y en septiembre de ese mismo año, a partir del hard fork de la versión 6, tales transacciones se convirtieron en las únicas permitidas en la red.
RingCT utiliza varios mecanismos: firmas grupales anónimas espontáneas vinculables y multicapa (Multilayered Linkable Spontaneous Anonymous Group Signature, en adelante — MLSAG), el esquema de compromiso (Pedersen Commitments) y las pruebas de rango (no hay una traducción establecida en ruso para este término).
El protocolo RingCT introduce dos tipos de transacciones anónimas: simple y full. La primera es generada por la billetera cuando la transacción utiliza más de una entrada, mientras que la segunda ocurre en la situación opuesta. Se diferencian en la validación de las sumas de las transacciones y en los datos firmados por la firma MLSAG (hablaremos más sobre esto más adelante). Las transacciones del tipo full se pueden generar con cualquier número de entradas; no hay una diferencia fundamental. En el libro se menciona que la decisión de limitar las transacciones full a una sola entrada fue tomada de manera apresurada y podría cambiar en el futuro.
Firma MLSAG
Recordemos cómo son las entradas firmadas de una transacción. Cada transacción gasta ciertos fondos y genera. La generación de fondos ocurre mediante la creación de salidas de transacción (una analogía directa son los billetes), y la salida que gasta la transacción (pues en la vida real gastamos precisamente billetes) se convierte en la entrada (cuidado, aquí es muy fácil confundirse).
La entrada hace referencia a varias salidas, pero gasta solo una, creando así un "velo de humo" para dificultar el análisis del historial de transferencias. Si una transacción tiene más de una entrada, esta estructura se puede representar en forma de matriz, donde las filas son las entradas y las columnas son las salidas mezcladas. Para demostrar a la red que la transacción está gastando exactamente sus salidas (conoce sus claves secretas), las entradas son firmadas con una firma circular. Esta firma garantiza que quien firma conocía las claves secretas de todos los elementos de alguna de las columnas.
Las transacciones confidenciales ya no utilizan las clásicas firmas circulares, han sido reemplazadas por MLSAG, una versión adaptada para múltiples entradas de firmas circulares similares de una sola capa, .
Se llaman multilayer porque firman varias entradas a la vez, cada una de las cuales se mezcla con varias otras, es decir, se firma una matriz y no solo una fila. Como veremos más adelante, esto ayuda a reducir el tamaño de la firma.
Veamos cómo se forma una firma circular, a partir de una transacción que gasta 2 salidas reales y usa para mezclarse m - 1 aleatorias del blockchain. Designemos las claves públicas de las salidas que gastamos como
, y las imágenes clave para ellas, respectivamente:
De esta manera, obtenemos una matriz de tamaño 2 x m. Para comenzar, necesitamos calcular los llamados challenges para cada par de salidas:

Comenzamos el cálculo con las salidas que gastamos, utilizando sus claves públicas:
y numbers aleatorios
Finalmente, obtenemos los valores:
, que utilizamos para calcular el challenge
del siguiente par de salidas (para facilitar la comprensión, hemos destacado estos valores en diferentes colores). Todos los siguientes valores se calculan en círculo siguiendo las fórmulas proporcionadas en la primera ilustración. Por último, se calcula el challenge para el par de salidas reales.
Como podemos ver, en todas las columnas, excepto en la que contiene las salidas reales, se utilizan números aleatoriamente generados.
. Para π-la columna también la necesitaremos. Transformamos
en s:
La propia firma consiste en una tupla de todos estos valores:

A continuación, estos datos se registran en la transacción.
Como podemos ver, MLSAG contiene solo un challenge c0, lo que permite ahorrar en el tamaño de la firma (que de por sí ya ocupa mucho espacio). Luego, cualquier verificador, utilizando los datos
, restaura los valores c1,…, cm y verifica que
. De esta manera, nuestro anillo se ha cerrado y la firma ha pasado la verificación.
Para transacciones RingCT del tipo full, se agrega una línea más a la matriz con las salidas mezcladas, pero de esto hablaremos más adelante.
Compromisos de Pedersen
(más comúnmente se utiliza el término en inglés — commitments) se emplean para que una parte pueda demostrar que conoce un cierto secreto (número), sin revelarlo realmente. Por ejemplo, lanzas un número en los dados, calculas el commitment y lo entregas a la parte verificadora. Así, en el momento de revelar el número secreto, el verificante calcula el commitment por sí mismo, asegurándose de que no lo has engañado.
En Monero, los commitments se utilizan para ocultar las cantidades de las transferencias y se aplica la variante más común — los compromisos de Pedersen. Por cierto, un dato curioso — al principio, los desarrolladores propusieron ocultar las cantidades mediante un simple mezclado, es decir, añadir salidas de cantidades arbitrarias para introducir incertidumbre, pero luego se cambiaron a commitments (aunque no está garantizado que ahorraron en el tamaño de la transacción, como veremos más adelante).
En general, un commitment se ve de la siguiente manera:
Donde C — el valor del commitment en sí, a — la cantidad oculta, H — un punto fijo en una curva elíptica (generador adicional), y x — una máscara arbitraria, un factor oculto, generado aleatoriamente. La máscara aquí es necesaria para que una tercera parte no pueda adivinar el valor de commitment mediante prueba y error.
Al generar una nueva salida, la billetera calcula su commitment, y al gastarla toma ya sea el valor calculado durante la generación o lo recalcula de nuevo, dependiendo del tipo de transacción.
RingCT simple
En el caso de transacciones de RingCT simple, para garantizar que la transacción ha creado salidas por un monto igual al monto de las entradas (no ha generado dinero de la nada), la suma de los commitments de las entradas y salidas debe ser la misma, es decir:

El commitment de la comisión se calcula de manera un poco diferente — sin la máscara:
, donde a — la suma de la comisión, que es públicamente accesible.
Este enfoque permite demostrar a la parte verificada que usamos los mismos montos sin revelarlos.
Para que todo sea más claro, consideremos un ejemplo. Supongamos que la transacción gasta dos salidas (es decir, se convierten en entradas) de 10 y 5 XMR y genera tres salidas por un total de 12 XMR: 3, 4 y 5 XMR. Al mismo tiempo, paga una comisión de 3 XMR. De este modo, la suma de dinero gastado más la suma generada y la comisión es igual a 15 XMR. Intentemos calcular los commitments y veamos la diferencia de sus sumas (recordemos matemáticas):

Aquí vemos que, para que la ecuación se mantenga, las sumas de las máscaras de las entradas y salidas deben ser iguales. Para ello, la billetera genera aleatoriamente x1, y1, y2 y y3, y el restante x2 se calcula así:
![]()
Usando estas máscaras, podemos demostrar a cualquier verificador que no generamos más fondos de los que gastamos, sin revelar las sumas. Original, ¿verdad?
RingCT completo
En las transacciones de RingCT completo, la verificación de las sumas de las transferencias es un poco más complicada. En estas transacciones, la billetera no recalcula los commitments para las entradas, sino que utiliza los calculados durante su generación. Hay que suponer que la diferencia de las sumas ya no será igual a cero, sino que en su lugar:

Aquí z — la diferencia entre las máscaras de las entradas y salidas. Si consideramos zG como una clave pública (que de hecho lo es), entonces z — es una clave privada. Así, conocemos la clave pública y su correspondiente clave privada. Con estos datos, podemos usarlos en la firma de anillo MLSAG junto con las claves públicas de las salidas mezcladas:

Así, una firma de anillo válida garantizará que conocemos todas las claves privadas de una de las columnas, y la clave privada en la última fila solo podemos conocerla si la transacción no genera más fondos de los que gasta. Por cierto, aquí también está la respuesta a la pregunta "¿por qué la diferencia de sumas de los commitments no da cero aquí?" — si zG = 0, entonces revelaremos la columna con las salidas reales.
¿Y cómo sabrá el destinatario cuánto dinero le han enviado? Aquí todo es simple: el remitente de la transacción y el destinatario intercambian claves mediante el protocolo de Diffie-Hellman, utilizando la clave de la transacción y la clave de vista del destinatario para calcular un secreto compartido. El remitente registra en campos especiales de la transacción los datos sobre las sumas de las salidas, encriptados con esta clave compartida.
Pruebas de rango
¿Y qué pasaría si utilizamos un número negativo como suma en los commitments? ¡Esto podría llevar a la generación de monedas adicionales! Este resultado es inaceptable, por lo que se necesita una garantía de que las sumas que utilizamos no son negativas (sin revelar estas sumas, por supuesto, de lo contrario todo el esfuerzo sería en vano). En otras palabras, debemos demostrar que la suma está en el intervalo [0, 2n — 1].
Para ello, la suma de cada salida se descompone en dígitos binarios y se calcula un commitment para cada dígito por separado. Cómo ocurre esto se puede ilustrar mejor con un ejemplo.
Supongamos que las sumas son pequeñas y caben en 4 bits (en la práctica son 64 bits), y estamos creando una salida por un monto de 5 XMR. Calculamos los commitments para cada dígito y el commitment total para toda la suma:
Luego, cada commitment se mezcla con un sustituto (Ci-2iH) y se firma por pares con una firma de anillo Borromean (otra firma de anillo), propuesta por Greg Maxwell en 2015 (puedes leer más sobre ella ):
Todo esto se llama prueba de rango y permite garantizar que en los commitments se utilizan sumas dentro del intervalo. [0, 2n — 1].
¿Qué sigue?
En la implementación actual, las pruebas de rango ocupan mucho espacio: 6176 bytes por cada salida. Esto lleva a transacciones grandes y, por lo tanto, a comisiones más altas. Para reducir el tamaño de las transacciones, los desarrolladores de Monero introducen en lugar de las firmas de Borromeo los bulletproofs, un mecanismo de prueba de rango sin compromisos bit a bit. , son capaces de reducir el tamaño de la prueba de rango hasta un 94%. Por cierto, a mediados de julio, la tecnología pasó de la empresa Kudelski Security, que no encontró deficiencias significativas ni en la tecnología misma ni en su implementación. La tecnología ya se aplica en la red de pruebas, y con el nuevo hard fork, probablemente pueda trasladarse a la red principal.
Plantee sus preguntas, sugiera temas para nuevos artículos sobre tecnologías en el ámbito de las criptomonedas y únase a nuestro grupo en , para estar al tanto de nuestros eventos y publicaciones.
Fuente: habr.com
