Cómo zk-ASM puede ofrecer una Internet segura y sin confianza
Análisis de investigación original de Web3.com Ventures
0xPescadosósofo
Nota: Este artículo es un artículo bastante denso desde el punto de vista técnico y asume una familiaridad conceptual básica con zk-Proofs y/o zk-Rollups. Puede encontrar una introducción más general a estos principios aquí.

Introducción
Las pruebas de conocimiento cero, en particular los zk-SNARK (argumentos de conocimiento sucintos no interactivos) son quizás una de las tecnologías más importantes en las fronteras de la Web 3. Si bien la mayor parte de la atención de los medios y las inversiones en este subcampo se ha dirigido hacia zk -Rollups, soluciones de escalamiento que brindan magnitudes de escalabilidad a cadenas de bloques L1 como Ethereum, esta no es de ninguna manera la única aplicación de zk-SNARK. En este ensayo, analizaré en profundidad el concepto de código ensamblador de conocimiento cero (o zkASM), evaluando sus casos de uso tanto en zk-Rollups como más allá, explorando sus posibilidades teóricas para reinventar Internet tal como lo conocemos.
Principios técnicos
zk-ASM, como su nombre indica, contiene dos partes técnicas principales: ZK y ASM. La parte ZK se refiere a zk-SNARK, o argumentos de conocimiento sucintos no interactivos, mientras que la parte ASM se refiere al código ensamblador. Para comprender el potencial de zk-ASM, primero debemos comprender los fundamentos teóricos de estos dos conceptos aparentemente arcanos.
zk-SNARK
Los zk-SNARK son las joyas de la corona de las zk-Proofs: son una prueba sucinta de que una determinada afirmación es verdadera cuando la prueba no revela nada sobre los datos que se están demostrando. Por ejemplo, considere que alguien afirma la afirmación "Conozco un m tal que C(m) = 0", donde m es un mensaje de un gigabyte de longitud y C es una función. Un zk-SNARK sería una prueba muy corta (< 1 GB) que se puede verificar rápidamente y en la que no se revela nada sobre m (más allá de la información disponible públicamente) [1].
Entonces, ¿qué es este “C(m)”? ¿Cómo es útil? Esta función es en realidad un circuito aritmético, o una representación de Gráfico Acíclico Dirigido (DAG) de una función específica que queremos realizar, como muestra el diagrama [2]. La "m" es esencialmente los datos de entrada al circuito, y los "nodos" específicos del circuito son puertas lógicas individuales u operaciones aritméticas. Por ejemplo, un nodo "+" puede tener "2" y "3" como entradas y generar un "5" en el siguiente operador. Por tanto, una operación aritmética o lógica arbitraria puede codificarse en un "circuito aritmético".

Una vez que tengamos este circuito aritmético como representación del código en el que queremos ejecutar zk-SNARK, podemos comenzar a construir este zk-SNARK. Fundamentalmente, un zk-SNARK es posible gracias al “teorema fundamental del álgebra”, que establece que un polinomio de grado “d” tiene como máximo raíces “d” [3]. El truco matemático consta de dos pasos: (1) convertir de alguna manera la función “f(m)” que queremos demostrar en un polinomio (y seguir con eso), y (2) usar el “teorema fundamental del álgebra” para interactuar con el polinomio y proporcionar una prueba sucinta. En la jerga técnica, la primera parte se denomina "Esquema de compromiso polinómico" (PCS), y la segunda parte se denomina "Prueba polinomial interactiva de oráculo" (PIOP) [4].

Si bien las implementaciones específicas de PCS y PIOP están más allá del alcance de este artículo, hasta ahora hemos obtenido un esbozo de los pasos principales de zk-SNARK:
Tiene una función de elección (función de código, ecuación matemática, etc.) que desea ejecutar en zk-SNARK
Codifique esta función como un circuito aritmético C(m)
Ejecute un PCS para obtener una representación polinómica de este circuito aritmético
Ejecute un PIOP para obtener una prueba sucinta de tamaño logarítmico con respecto a la “m” original
Y viola, tenemos un zk-SNARK personalizado que puede demostrar que alguien conoce un mensaje determinado sin revelar cuál es ese mensaje.
Código ensamblador
La segunda pieza del rompecabezas de zk-ASM es la idea del código ensamblador. El código ensamblador es una clase de lenguajes que contienen instrucciones en muy bajo lenguaje que son fáciles de leer para una máquina pero bastante difíciles de descifrar para un humano. A diferencia de los lenguajes de nivel superior, como Python, Java o incluso C, los lenguajes ensambladores contienen funciones muy primitivas, como mover, comparar, agregar y saltar sobre una serie de registros de datos en el procesador y ubicaciones de memoria codificadas. Por ejemplo, el código Python para imprimir los números del 1 al 9 en la pantalla es 123456789:

Bastante fácil de entender, ¿verdad? Ahora aquí está la versión ensambladora x86 [5]:

Mucho más desagradable, sobre todo para una operación tan sencilla. Entonces, ¿por qué utilizar el lenguaje ensamblador? Como se indicó anteriormente, si bien estas instrucciones pueden no ser fáciles de leer para un humano, son muy fáciles de "ensamblar" en el código de bytes 110011001 para que una máquina las lea y las ejecute (esto se llama ensamblador) [6]. Comparativamente hablando, los lenguajes de nivel superior como Python y Java son mucho más fáciles de leer para los humanos, pero los programas escritos en estos lenguajes no pueden ser ejecutados directamente por un procesador. En lugar de eso, necesitamos confiar en un “compilador” que analiza el código Python o Java que escribimos y escupe un volcado de código ensamblador como el anterior para que la máquina lo ensamble y ejecute. Podemos esperar que la misma pieza de Python o Java se ejecute sin problemas en diferentes procesadores y diferentes sistemas operativos porque el compilador hace el trabajo pesado, compilando su código fuente en un lenguaje ensamblador específico para ese procesador o sistema operativo.
Debido a que todos los lenguajes se compilan en código ensamblador (que a su vez se compila en binario ejecutable), el ensamblador es esencialmente como una "madre de todos los lenguajes". Ahora supongamos que somos capaces de convertir todos los operandos en un lenguaje ensamblador (como x86 o RISC-V) en una representación de circuito aritmético, de modo que podamos proporcionar pruebas zk-SNARK de todos los operandos en este ensamblador. idioma. Esto significa que, en teoría, somos capaces de proporcionar un zk-SNARK de cualquier programa escrito en un lenguaje arbitrario de alto nivel (como Python o Java) que se compile en este lenguaje ensamblador. Y es por eso que debemos preocuparnos de pensar en los zk-ASM.
Aplicaciones prácticas
Paquetes acumulativos de zk-EVM: Polígono zk-ASM
Una de las aplicaciones más importantes de zk-ASM es la creación de zk-Rollups o zk-EVM compatibles con máquinas virtuales Ethereum. Un zk-EVM es increíblemente importante para la escalabilidad de blockchain porque permite a los programadores implementar en una cadena L2 basada en zk-Rollup sin modificar mucho (si es que modifica alguno) de su código [7]. En este campo, zk-EVM de Polygon es un estudio de caso ejemplar que demuestra cómo se puede utilizar zk-ASM para lograr este objetivo.

Cuando los programadores desarrollan en la cadena de bloques Ethereum L1, generalmente codifican en Solidity, que es un lenguaje de alto nivel similar a C. Este código de Solidity se compila en una serie de códigos de operación EVM, como ADD, SLOAD y EQ, antes de ejecutarse. en la cadena de bloques L1 [8]. De forma predeterminada, este proceso obviamente no crea ningún tipo de zk-Proof. El truco de Polygon consiste en crear un método para interpretar cada uno de los códigos de operación de EVM en su zk-ASM personalizado, que es muy compatible con zk-SNARK. Luego, su L2 zk-EVM ejecutará el zk-ASM, al mismo tiempo que creará un circuito zk-SNARK del ASM para crear una prueba de zk-SNARK [9]. Por ejemplo, el código de operación ADD en EVM se traducirá al zk-ASM de Polygon de la siguiente manera [10]:

Debido a que el juego de manos de Polygon zk-EVM ocurre en el nivel de ensamblaje, está a dos niveles del código que toca el programador promedio de Ethereum, el nivel de "Solididad". Esta es la razón por la que la mayoría de los desarrolladores pueden transferir su código EVM creado para la red principal de Ethereum directamente a Polygon zk-EVM. Además, debido a que Polygon zk-EVM "mantiene" la pila tecnológica de Ethereum hasta el nivel de código de operación, toda la infraestructura de depuración que se basa en el análisis de códigos de operación compilados se mantendrá utilizable e intacta. Esto es diferente a otros diseños de zk-EVM, como zk-Sync, que no proporciona zk-Proofs a nivel de código de operación. Por lo tanto, incluso cuando Polygon inventa y prueba su propio lenguaje ensamblador, Vitalik escribe que "todavía puede verificar el código EVM, simplemente usa una lógica interna diferente para hacerlo" [11].
Más allá de los resúmenes: zk-WASM
Los zk-EVM no son de ninguna manera la única aplicación para los zk-ASM. Recuerde nuestra afirmación anterior de que los lenguajes ensambladores son esencialmente "la madre de todos los lenguajes" y que la creación de un zk-ASM desbloqueará zk-Proofs para programas genéricos escritos en cualquier lenguaje que se compile en ese lenguaje ensamblador. Web Assembly, o WASM, es uno de los lenguajes ensambladores emergentes más importantes. Publicado por primera vez en 2018, el objetivo de WASM es crear un lenguaje ensamblador que aumente la velocidad de ejecución de las aplicaciones web y proporcione un complemento de ejecución para Javascript, el lenguaje de codificación principal detrás de la Web [12].
Esencialmente, a medida que la Web se desarrolló a lo largo de los años, el creciente tamaño y complejidad de las aplicaciones web ha significado que a menudo sea increíblemente lento para los navegadores compilar todo lo escrito en Javascript y deben depender de complejos ciclos de compilación, optimización y recarga [12]. WebAssembly, por otro lado, elimina la necesidad de depender de motores de ejecución de navegador complejos al proporcionar un lenguaje ensamblador portátil, modular y fácilmente ejecutable. Además, como lenguaje ensamblador, WASM permite a los programadores escribir directamente fragmentos de código en C, C++, Rust, Java o Ruby que se ejecutan de forma nativa en un navegador. Por lo tanto, WASM se ha convertido en una tecnología de elección para "proporcionar funciones distribuidas sin servidor" [13].
Entonces, ¿por qué y cómo entran en escena los zk-SNARK? WASM es único porque es una tecnología del lado del cliente, capaz de interactuar directamente con las entradas y datos del usuario. Debido a que a menudo esto incluye datos confidenciales como contraseñas e información personal, necesitamos una tecnología que (1) garantice que el programa se ejecute correctamente y que (2) nuestra información confidencial no se filtre. Como se describió anteriormente, un zk-SNARK es una solución perfecta para resolver ambos problemas y, por lo tanto, es una pieza importante del rompecabezas para proteger WASM [14].
Si bien el trabajo en el desarrollo de zk-WASM aún se encuentra en sus primeras etapas, recientemente ha habido algunos proyectos que han lanzado prototipos de circuitos zk-SNARK para WebAssembly. Por ejemplo, el emulador zk-SNARK “ZAWA” de Delphinus Lab presenta un método para codificar los operandos y la semántica de una máquina virtual WASM en un circuito aritmético, lo que le permite realizar pruebas de zk-SNARK [13]. A medida que pase el tiempo, los circuitos zk-WASM sin duda se optimizarán continuamente, lo que permitirá que los programas escritos en lenguajes genéricos (como C, C++, Rust y Ruby) adopten el paradigma de zk-Proofs.
Conclusión
A lo largo de este ensayo, hemos explorado los fundamentos teóricos de zk-ASM y también hemos examinado dos estudios de caso paradigmáticos de zk-ASM: el uso de zk-ASM por parte de Polygon para crear un zk-EVM a nivel de código de operación, así como la aplicación de zk -SNARK en WebAssembly para crear zk-WASM. En última instancia, la promesa de zk-ASM es combinar la interoperabilidad y la escala de la Web 2 con la falta de confianza y la seguridad de la Web 3.
Por un lado, las cadenas de bloques buscan cada vez más escalar más allá de sus actuales cuellos de botella de rendimiento y potencialmente respaldar la ejecución, mientras que, por el otro, los métodos Web 2 se han visto cada vez más atacados por proteger inadecuadamente los datos y la privacidad de los usuarios. A medida que los programadores puedan emplear paradigmas de diseño Web 3 en su código Web 2 e introducir lenguajes y códigos Web 2 en la cadena de bloques, los zk-ASM genéricos pueden representar un punto de fusión en el mundo de Web 2 y Web 3 [15]. Es en este sentido que zk-ASM puede permitirnos reimaginar una Internet más segura y sin confianza.
🐦 @0xfishylosopher
📅 17 de diciembre de 2022
Descargo de responsabilidad: la información presentada anteriormente es puramente educativa, no constituye asesoramiento financiero y representa únicamente las opiniones del autor. Delphinus Lab es una empresa de cartera de Web3.com Ventures.
Referencias
[1] https://z.cash/technology/zksnarks/
[2] https://cs251.stanford.edu/lectures/lecture14.pdf
[3] https://www.britannica.com/science/fundamental-theorem-of-algebra
[4] Creación de SNARK eficientes: https://cs251.stanford.edu/lectures/lecture15.pdf
[5] Ejemplo de: https://www.tutorialspoint.com/assembly_programming/assembly_loops.htm
[6] https://en.wikipedia.org/wiki/Assembly_language
[7] https://www.alchemy.com/overviews/zkevm
[8] Para obtener una lista de códigos de operación: https://ethereum.org/en/developers/docs/evm/opcodes/
[9] https://wiki.polygon.technology/docs/zkEVM/zkASM/introduction
[10] https://wiki.polygon.technology/docs/zkEVM/zkASM/some-examples
[11] https://vitalik.ca/general/2022/08/04/zkevm.html
[12] https://blog.developer.adobe.com/understanding-webassembly-wasm-d5b592208ecc
[13] https://jhc.sjtu.edu.cn/~hongfeifu/manuscriptb.pdf
[14] https://hyperoracle.medium.com/zkwasm-the-next-chapter-of-zk-and-zkvm-471038b1fba6
[15] https://delphinuslab.com/zk-wasm/