Transformación de las preguntas del QAP de conocimiento cero

Introducción: este artículo es un artículo escrito por Vitalik en diciembre de 2016 para presentar la implementación matemática de la prueba de conocimiento cero. El artículo tiene ideas claras y es fácil de entender, por lo que se ha convertido en uno de los artículos de primera elección para que el personal técnico de la industria blockchain aprenda este conocimiento.

Introducción a la terminología

Resolver un problema lleva tiempo. Se dice que un problema tiene complejidad polinómica si existe una relación polinómica entre el tiempo necesario para resolverlo y el tamaño del problema.

P-Problemas *: Se refiere a problemas que son solucionables en tiempo polinomial. *

Problema NP * (Problema polinómico no determinista, problema polinómico no determinista): se refiere a un problema que no se puede resolver dentro de un polinomio, pero se puede verificar dentro de un tiempo polinómico. *

Problema QSP * (QSP - Quadratic Span Program): Realizar la prueba y verificación de problemas NP basados ​​en circuitos booleanos. *

Problema QAP  (Programa de aritmética cuadrática): Realice la prueba y verificación de problemas NP basados ​​​​en circuitos aritméticos. En comparación con QSP, QAP tiene mejor universalidad.

traducción de texto

Últimamente ha habido mucho interés en la tecnología detrás de las zk-SNARK (pruebas de conocimiento cero), y ha habido un intento cada vez mayor de desmitificar lo que muchos llaman "matemáticas lunares" debido a su complejidad percibida. Muy incomprensible. De hecho, los zk-SNARK son bastante difíciles de entender, especialmente porque hay tantas partes móviles que es necesario ensamblar todo el sistema para funcionar, pero si desglosamos la tecnología pieza por pieza, se vuelve más fácil de entender.

Esta publicación no pretende ser una introducción completa a zk-SNARK, se supone que tiene los siguientes conocimientos previos:

1- Conoces zk-SNARKs y su principio general ;

2- Tienes suficientes conocimientos matemáticos para comprender algunos conocimientos polinomiales básicos. (Por ejemplo  if P(x)+ Q(x)=(P + Q)(x), Py Qrepresentan polinomios. Si ya estás muy familiarizado con la expresión de dichos polinomios, significa que cumples con los requisitos para continuar leyendo).

Gráfico de canalización de conocimientos de zk-SNARK, dibujado por Eran Tromer 

Como se muestra en la figura anterior, la prueba de conocimiento cero anterior se puede dividir en dos etapas de arriba a abajo. En primer lugar, los zk-SNARK no se pueden aplicar directamente a ningún problema computacional; en cambio, se debe convertir el problema a la "forma" correcta de operaciones. Esta forma se conoce como "Programa de aritmética cuadrática" (QAP), y traducir el código de la función a estos códigos es muy importante en sí mismo. Junto con el proceso de convertir el código funcional al QAP, hay otro proceso que, si hay entrada al código, crea una solución correspondiente (a veces llamada "testigo" del QAP). De eso se trata este artículo.

Después de eso, hay otro proceso bastante complicado para crear la "prueba de conocimiento cero" real para este QAP, y un proceso separado para verificar la prueba que otra persona le pasó, pero esos detalles están más allá del alcance de este artículo.

En el siguiente ejemplo, elegiremos un problema muy simple:

Encuentra la solución a una ecuación cúbica: x**3 + x + 5 == 35(pista: la respuesta es 3).

La pregunta es lo suficientemente simple como para que el QAP resultante no sea demasiado grande, pero es importante que puedas ver cómo funciona toda la funcionalidad en este ejemplo.

Las ecuaciones anteriores se describen en el lenguaje de programación de la siguiente manera:

El lenguaje de programación simple que usamos aquí admite aritmética básica (+, -, *, /), exponente de potencia constante **(x**7, pero no x**y)*** y asignación de variables, lo cual es lo suficientemente potente. teóricamente hacer cualquier cálculo en él (siempre que el número de pasos de cálculo esté limitado; no se permiten bucles). Tenga en cuenta que el módulo (%) y los operadores de comparación (<, >, ≤≥) no son compatibles, ya que no existe una forma eficiente de realizar comparaciones directas o de módulo de algoritmos de grupos cíclicos finitos (gracias; si hay alguna forma de hacer esto, entonces La velocidad de ruptura de la criptografía de curva elíptica superará la de la "búsqueda binaria" y el "teorema del resto chino").

 Puede extender el lenguaje a módulos y comparaciones a través de descomposiciones de bits, (por ejemplo: 13 = 2**3 + 2**2 + 1 = 8 + 4 + 1) como entradas auxiliares, demostrando la exactitud de estas descomposiciones y 二进制电路haciendo cálculos en ; en algoritmos de campo finito, también es factible realizar comprobaciones de igualdad (==), y En realidad, es un poco más fácil, pero no discutiremos esos dos detalles ahora. Podríamos ampliar el lenguaje para admitir condicionales (por ejemplo, convertir la declaración : if x < 5: y = 7; else: y = 9; a la forma aritmética: y = 7 * (x < 5) + 9 * (x >= 5);), pero tenga en cuenta que ambas "rutas" de la condición deben ejecutarse, lo que puede causar una gran sobrecarga si tiene muchas condiciones anidadas.

Repasemos ahora este proceso paso a paso. Si desea crear algún código usted mismo, implementé
un fragmento de código en Python aquí (solo con fines educativos; ¡todavía no estoy listo para crear QAP para zk-SNARK del mundo real!)

Paso 1: aplanar

El primer paso es un proceso de "aplanamiento", donde descomponemos el código original (que puede contener declaraciones y expresiones arbitrariamente complejas) en las expresiones más simples, que tienen dos formas:

1-  x = y (y puede ser una variable o un número)

2-  x = y(op)z (op puede ser +, -, *, /, y y z pueden ser variables, números o subexpresiones).

Puedes pensar en estas representaciones como puertas lógicas en un circuito. x**3 + x + 5El resultado del proceso de aplanamiento de la expresión anterior es el siguiente:

Puedes pensar que cada línea de declaración anterior es una puerta lógica en un circuito. En comparación con el código original, aquí hemos introducido dos variables intermedias sym_1 y  sym_2y una variable redundante que representa la salida  ~out. No es difícil ver el "aplanamiento" La siguiente secuencia de declaraciones es equivalente al código original.

Paso 2: Convertir a R1CS

Ahora lo convertimos en algo llamado R1CS(Sistema de restricciones Rand-1). R1CSes (a, b, c)una secuencia de tres vectores, R1CScuya solución es un vector sen el que sla ecuación

donde  . representa 内积la operación.

Por ejemplo, el siguiente es un R1CS satisfactorio:

(Nota del traductor: la primera 35=1*5 + 30*1, la segunda 35=35 * 1)

El ejemplo anterior es solo una restricción, y luego necesitamos convertir cada puerta lógica (es decir, cada declaración de declaración después del "aplanamiento") en una restricción (es decir, un grupo de tres vectores), y el método de conversión depende de (a, b, c)qué operación la declaración es (+,-,*,/) y los parámetros declarados son variables o números. En nuestro ejemplo, además de las cinco variables ( 'x', '~out', 'sym_1', 'y', 'sym_2') después de "aplanar", también necesitamos introducir una variable redundante en la posición del primer componente ~onepara representar el número 1. En lo que respecta a nuestro sistema, un vector corresponde a Los 6 componentes de son (pueden estar en otro orden, siempre que correspondan): 

 primera puerta

Podemos obtener el siguiente conjunto de vectores:

Si el segundo escalar del vector solución  s es 3 y el cuarto escalar es 9, esto es válido sin importar cuáles sean los otros escalares, porque: a = 3 * 1, b = 3 * 1, c = 9 * 1, es decir a * b = c. De manera similar, si el segundo escalar de s es 7 y el cuarto escalar es 49, también pasará la verificación. La primera verificación es solo para verificar la coherencia de la entrada y salida de la primera puerta.

segunda puerta 

Se puede obtener el siguiente conjunto de vectores:

tercera puerta

dando como resultado el siguiente conjunto de vectores:

cuarta puerta 

dando como resultado el siguiente conjunto de vectores:

Ahora, asumimos x = 3que según la primera puerta, obtenemos sym_1 = 9, según la segunda puerta, obtenemos y = 27, según la tercera puerta, obtenemos sym_2 = 30, según la cuarta puerta ~out = 35, entonces, según:, '~one', 'x', '~out', 'sym_1', 'y', 'sym_2'podemos obtener:

Si asume x diferente, puede obtener s diferentes, pero todas las s pueden usarse para verificar (a, b, c)

Ahora obtenemos el R1CS de cuatro restricciones, el R1CS completo es el siguiente:

 

Paso tres: de R1CS a QAP

El siguiente paso es convertir esto R1CSen QAPforma, que implementa exactamente la misma lógica, simplemente usando polinomios en lugar de productos internos. Así es como lo hacemos: de 4 conjuntos de 3 vectores de longitud 6 a 6 conjuntos de polinomios de grado 3, encontrar el polinomio en cada coordenada x representa una restricción. Es decir, si resolvemos el polinomio en x=1, obtenemos el primer conjunto de vectores, si resolvemos el polinomio en x=2, obtenemos el segundo conjunto de vectores, y así sucesivamente.

Podemos utilizar la interpolación lagrangiana para realizar esta transformación. El problema que resuelve la interpolación de Lagrange es: si tiene un conjunto de puntos (es decir, pares de coordenadas (x, y)), realice la interpolación de Lagrange en estos puntos para obtener un polinomio que pase por todos estos puntos. Hacemos esto descomponiendo el problema: para cada coordenada x, creamos un polinomio, la coordenada y deseada es la coordenada x y 0 es la coordenada y en todas las demás coordenadas x que nos interesan, y luego Para obtener el resultado final sumamos todos los polinomios.

Hagamos un ejemplo. Supongamos que queremos un polinomio que pase por (1,3), (2,2) y (3,4). Primero hacemos un polinomio, pasando por (1,3)(2,0) y (3,0). Resulta que un polinomio que "sobresalga" x = 1 y 0 a otros puntos de interés es fácil, simplemente hacemos el siguiente polinomio:

Como se muestra abajo: 

Luego, para "estirar" en la dirección del eje y, use la siguiente ecuación:

Después de terminar, obtenga:

Satisfecho de pasar por (1,3)(2,0)和(3,0)tres puntos al mismo tiempo, como se muestra en la siguiente figura:

 Sustituyendo (2,2) y (3,4) en la fórmula anterior, podemos obtener:

es la ecuación de coordenadas que queremos. El algoritmo anterior toma O(n 3) tiempo porque hay n puntos y cada punto toma O(n 2) tiempo para multiplicar los polinomios. Con un poco de reflexión, esto se puede reducir al tiempo O(n**2), con un poco más de reflexión se puede reducir aún más utilizando algoritmos rápidos de transformada de Fourier, etc. Esta es una optimización crítica cuando las funciones utilizadas en zk-spuks suelen tener decenas de miles de veces de puerta.

Aquí doy directamente la fórmula de interpolación lagrangiana: polinomio de orden n-1 que pasa por n puntos (x1,y1),(x2,y2),(x3,y3),...,(xn,yn) para:

Por ejemplo, en el ejemplo anterior, el polinomio que pasa por los puntos (1,3), (2,2), (3,4) es:

 Después de aprender a utilizar esta fórmula, podemos continuar con nuestros pasos. Ahora queremos convertir cuatro grupos de tres vectores de longitud seis en seis grupos de polinomios, cada grupo de polinomios consta de tres polinomios de tercer orden, evaluamos diferentes restricciones en cada punto x, aquí tenemos un total de cuatro restricciones, entonces evaluamos estos cuatro conjuntos de vectores con polinomios en x = 1,2,3,4 respectivamente.

Ahora usamos la fórmula de diferencia lagrangiana para convertir R1CS al formato QAP. Primero encontramos el polinomio del primer valor de cada vector correspondiente a las cuatro restricciones, es decir, usamos el teorema de interpolación de Lagrange para encontrar los puntos (1,0), (2,0), (3, 0) ,  (4,5)  , de manera similar podemos encontrar el polinomio del i-ésimo valor de cada vector correspondiente a las cuatro restricciones restantes.

Aquí, da la respuesta directamente:

Los coeficientes están ordenados en orden ascendente, por ejemplo, el primer polinomio de arriba es  0.833 * x**3 - 5 * x**2 + 9.166 * x - 5.

(Nota del traductor: el proceso de cálculo anterior: coloque (1,0), (2,0), (3,0), (4,5) en la fórmula de interpolación de Lagrange para calcular, el segundo polinomio Se calcula trayendo (1,1), (2,0), (3,1), (4,0) en la fórmula de interpolación de Lagrange, etc.)

Este conjunto de polinomios (más el polinomio Z que explico más adelante) constituye los parámetros para esta instancia QAP en particular. Tenga en cuenta que todo el trabajo hasta este punto solo debe realizarse una vez para cada función que se intenta verificar utilizando zk-SNARK; una vez que se hayan generado los parámetros QAP, se pueden reutilizar.

Intentemos evaluar todos estos polinomios en x=1. Evaluar el polinomio en x=1 solo significa sumar todos los coeficientes (1k = 1 para todo k), por lo que no es difícil. tenemos:

Si subsumimos  x=1 los dieciocho polinomios anteriores, podemos obtener los tres vectores de la primera restricción.

Como puede ver, lo que tenemos aquí es exactamente el mismo conjunto de tres vectores que creamos anteriormente para la primera puerta lógica.

(Nota del traductor: el proceso de cálculo anterior: x = 1 se sustituye en el primer polinomio0.833 * x**3 - 5 * x**2 + 9.166 * x - 5  = 0, x = 1 se sustituye en el segundo polinomio-0.666 * x**3 + 5 * x**2 - 11.333 * x + 8= 1, y así sucesivamente)

Paso cuatro: verifique el QAP

Al convertir R1CS a QAP, podemos verificar todas las restricciones al mismo tiempo mediante la operación del producto interno polinomial en lugar de verificar cada restricción individualmente como R1CS. Como se muestra abajo:

Debido a que en este caso la prueba del producto escalar es una serie de sumas y multiplicaciones de polinomios, el resultado es en sí mismo un polinomio. Si el polinomio resultante tiene un valor igual a 0 en cada una de las coordenadas x que usamos anteriormente para representar puertas lógicas, eso significa que todas las comprobaciones pasan; si el polinomio resultante tiene al menos un valor distinto de cero, entonces significa Los valores Entrar y salir de la puerta lógica son inconsistentes.

Vale la pena señalar que el polinomio resultante no tiene por qué ser cero en sí mismo y, de hecho, en la mayoría de los casos no lo es; puede tener cualquier comportamiento en puntos que no encajan en ninguna puerta lógica, siempre que en todos los puntos que Si se ajustan algunas puertas, el resultado es cero. Para verificar la corrección, no calculamos un polinomio t = A . s * B . s - C . scorrespondiente a una puerta en cada punto; en lugar de eso, dividimos t por otro polinomio Z y comprobamos que Z divide t uniformemente, es decir, la división t / Zno tiene resto.

Z se define como (x - 1) * (x - 2) * (x - 3)... - el polinomio más simple igual a 0 en todos los puntos correspondientes a las puertas lógicas. Es un hecho fundamental del álgebra que cualquier polinomio igual a cero en todos estos puntos debe ser múltiplo de este polinomio más pequeño, y si un polinomio es múltiplo de Z entonces es cero en cualquiera de estos puntos; esta equivalencia nos permite trabajar es mucho más fácil.

Ahora, hagamos la prueba del producto interno con los polinomios anteriores.

Primero, obtenemos el polinomio intermedio:

(Nota del traductor: el proceso de cálculo anterior: 43,0 = -5 * 1 + 8 * 3 + 0 * 35 - 6 * 9 + 4 * 27 - 1 * 30, -73,333 = 9,166 * 1 - 11,333 * 3 + 0 * 35 + 9,5 * 9 - 7 * 27 + 1,833 * 30,...-3 = 3 * 1 - 2 * 3 + 0 * 35 + 0 * 9 + 0 * 27 + 0 * 30...)

Después de calcular los polinomios anteriores A . s * B . s - C . s : obtenga:

A . s = [43,0, -73,333, 38,5, -5,166] = -5,166 * x 3 + 38,5 * x 2 - 73,333 * x + 43,

B . s = [-3,0, 10,333, -5,0, 0,666] = 0,666 * x 3 - 5 * x 2 + 10,333 * x - 3,0,

C . s = [-41,0, 71,666, -24,5, 2,833] = 2,833 * x 3 - 24,5 * x 2 + 71,666 * x - 41,0

A. s * B. s - C. s es el cálculo del polinomio anterior. Después del cálculo, ordene los coeficientes según la potencia de menor a mayor y obtenga: [-88.0, 592.666, -1063.777, 805.833, - 294,777, 51,5, -3,444]

El polinomio mínimo es:

 Ahora mismo: 

 Ahora calcula la división polinomial: 

 h sin ningún resto

Tenemos una solución para QAP. Si intentamos falsificar las variables en el R1CS que derivaron la solución QAP, por ejemplo, estableciendo el súltimo dígito en 31 en lugar de 30, nuestra verificación polinómica tfallará (en ciertos casos, en El resultado en x = 3 sería igual a - 1 en lugar de 0), y tno sería Zun múltiplo de ; en cambio, la división t / Zdaría un resto de [-5,0, 8,833, -4,5, 0,666].

Tenga en cuenta que lo anterior es sólo un ejemplo muy simple; en el mundo real, la suma, la resta, la multiplicación y la división a menudo involucran números no convencionales, por lo que todas las leyes algebraicas que conocemos y amamos aún se aplican, pero todas las respuestas son para algunos números finitos. conjunto de tamaño Un elemento , generalmente un número entero n en el rango de 0 a n - 1. Por ejemplo, si n = 13, entonces 1/2 = 7 (7 * 2 = 1), 3 * 5 = 2 y así sucesivamente. El uso de un algoritmo de campo finito elimina las preocupaciones sobre errores de redondeo y permite que el sistema funcione bien con curvas elípticas, lo que en última instancia es fundamental para que los protocolos zk-SNARK sean verdaderamente seguros.

 

 

 

Supongo que te gusta

Origin blog.csdn.net/xiaozhupeiqi321/article/details/125064559#comments_27454733
Recomendado
Clasificación