Los Bulletproofs ZKP permiten a un probador demostrar el conocimiento de un producto interno con una prueba de tamaño logarítmico. Los Bulletproofs no requieren una configuración de confianza (trusted setup).
En los capítulos anteriores, mostramos cómo demostrar el conocimiento de un producto interno sin revelar los vectores ni el producto interno, aunque con una prueba de tamaño donde es la longitud del vector. También mostramos cómo demostrar el conocimiento de un producto interno utilizando datos de tamaño logarítmico, pero sin la propiedad de conocimiento cero.
En este capítulo, combinamos los algoritmos para demostrar el algoritmo ZK de Bulletproofs.
(Este trabajo es parte de una serie sobre ZK Bulletproofs).
Planteamiento del Problema
El probador y el verificador acuerdan dos vectores base de curva elíptica y de longitud y los puntos de curva elíptica y . Las relaciones de logaritmo discreto entre todos estos puntos son desconocidas.
El probador tiene los vectores y con un producto interno . El probador compromete y en como donde es un término de ocultamiento (blinding term). El probador compromete .
El probador envía al verificador y tiene como objetivo demostrar que y están comprometidos en y que su producto interno está comprometido en . El verificador no descubre los vectores ni el producto interno.
El tamaño de la prueba debe ser .
El Algoritmo ZK de Bulletproofs
El probador genera escalares aleatorios y vectores aleatorios y calcula los compromisos:
El probador prepara (pero no envía) polinomios de vectores:
es un compromiso a los términos constantes del polinomio de vectores, es un compromiso a los términos lineales y es un compromiso al producto interno.
El probador crea compromisos a los coeficientes de de la siguiente manera:
Tenga en cuenta que es un compromiso al coeficiente constante de , y y son compromisos a los coeficientes lineal y cuadrático de , respectivamente.
El probador envía al verificador.
El verificador responde con un valor aleatorio .
Luego, el probador evalúa los polinomios en y crea pruebas de que fueron evaluados correctamente:
Anteriormente, el probador transmitía para que el verificador pudiera comprobar que:
pero esto tendría un tamaño lineal debido a los vectores y . En su lugar, el probador compromete y como:
y envía .
Podemos reorganizar las dos primeras comprobaciones del verificador de la siguiente manera:
Observe que si establecemos , entonces este es el mismo planteamiento del problema que demostrar que contiene compromisos a dos vectores y con respecto a los vectores base y , y que y tienen un producto interno de . Por lo tanto, podemos reutilizar la prueba de tamaño logarítmico de conocimiento de la apertura de un compromiso a .
Para esta prueba, no necesitamos la confidencialidad porque y ya se hicieron públicos de todos modos en el algoritmo anterior.
Ahora que el verificador tiene todos los datos necesarios, el probador participa en una prueba interactiva para demostrar que contiene los compromisos a y y que su producto interno es :
Esa subrutina demostrará que y sin tener que enviar y . Además, solo envía datos de tamaño logarítmico. Tenga en cuenta que el algoritmo recursivo del capítulo anterior utiliza un compromiso , por lo que el verificador necesita añadir la “porción ” por sí mismo. Ahora el verificador puede estar seguro de que:
Finalmente, el verificador comprueba que:
Recuerde que y son compromisos a los términos constantes y lineales de los polinomios de vectores y , respectivamente. La primera comprobación asegura que los vectores comprometidos en son evaluaciones de esos polinomios en .
La segunda comprobación es para asegurar que se evaluó correctamente, dados los compromisos de los coeficientes , y .
No interactividad mediante la Transformada de Fiat Shamir
En la práctica, este algoritmo se hace no interactivo a través de la Transformada de Fiat Shamir. En lugar de pedirle aleatoriedad al verificador, el probador genera aleatoriedad concatenando todos los datos que ha transmitido hasta el momento y calculando su hash. Luego, el verificador vuelve a calcular el hash de los datos para asegurarse de que el probador generó la aleatoriedad correctamente.
Es fundamental que el hash incluya todas las transmisiones de datos anteriores, de lo contrario la implementación tendrá una vulnerabilidad de corazón congelado (frozen heart vulnerability).
Próximos pasos
En la práctica, los problemas de interés práctico constan de múltiples productos internos. Por ejemplo, un Sistema de Restricciones de Rango 1 (Rank 1 Constraint System):
son en realidad productos internos (por ejemplo, multiplicando por las filas de y así sucesivamente para y ) y un único producto de Hadamard. Por lo tanto, será útil conocer algunos trucos matemáticos para combinar múltiples productos internos en uno solo, de modo que no tengamos que enviar pruebas de Bulletproofs. Aprenderemos cómo lograr esto en nuestro próximo capítulo sobre combinaciones lineales aleatorias.
Además, algunos problemas útiles pueden codificarse directamente como un producto interno, notablemente la prueba de rango o el problema de suma de subconjuntos. En esas situaciones, podemos omitir la codificación del problema como un circuito aritmético y codificarlo directamente como un producto interno. Para aumentar la flexibilidad de nuestra representación de productos internos, así como para sentar las bases para entender las combinaciones lineales aleatorias, aprenderemos algo de álgebra de productos internos en el próximo capítulo.
Ejercicio: Combine los ejercicios anteriores para demostrar que donde y son vectores de longitud 4. Su prueba debe ser tanto sucinta como de conocimiento cero. Cree una prueba interactiva en aras de la simplicidad. Consulte este repositorio para los ejercicios.