¿Qué son los zk-SNARKs y cómo permiten la privacidad en las blockchains?

¿Qué son los zk-SNARKs?
Los zk-SNARKs son pruebas criptográficas que permiten demostrar que cierta información o un cálculo es correcto, sin revelar información sensible. Gracias a ello, una blockchain puede, por ejemplo, comprobar que un pago es válido mientras los datos, como el importe o el destinatario, permanecen ocultos. Una de las blockchains más conocidas que utiliza esta tecnología es Zcash. Allí, los zk-SNARKs se utilizan para verificar transacciones mientras datos como el importe o el destinatario pueden permanecer ocultos.
El nombre zk-SNARK es una abreviatura de zero-knowledge succinct non-interactive argument of knowledge. Suena complejo, pero puede dividirse de forma sencilla en sus componentes:
- Zero-knowledge: la prueba demuestra que una afirmación es correcta, por ejemplo que una transacción es válida, sin revelar información sensible como la dirección de envío, la dirección de recepción o el importe de la transacción.
- Succinct: la prueba es breve. Por tanto, un nodo o contrato inteligente puede verificarla de forma relativamente eficiente.
- Non-interactive: una vez creada la prueba, su autor no necesita comunicarse de ida y vuelta con quien la verifica. La prueba puede generarse una sola vez y luego verificarse.
- Argument of knowledge: el autor demuestra que dispone de la información necesaria para cumplir las reglas establecidas, por ejemplo los datos con los que puede crearse una transacción válida. La seguridad se basa en supuestos criptográficos: un atacante con capacidad de cálculo limitada no puede, en la práctica, crear una prueba falsa que sea aceptada como válida. La información con la que se crea la prueba suele denominarse witness. Suponga que desea demostrar que tiene saldo suficiente para un pago. En ese caso, la witness contiene, por ejemplo, los datos con los que puede demostrar que dispone de fondos suficientes y que puede gastarlos. La blockchain no necesita ver esos datos por sí misma, pero sí puede comprobar que la prueba correspondiente es válida.
Además de la witness privada, un zk-SNARK también puede incluir entrada pública. Se trata de datos que sí pueden ser visibles y que el verificador utiliza junto con la prueba para comprobar si la afirmación es correcta.
Es importante saber que un zk-SNARK no es un único protocolo fijo, sino un término general para distintos tipos de sistemas de prueba con estas propiedades. El funcionamiento exacto puede variar según el sistema. Algunos sistemas, por ejemplo, requieren un trusted setup, mientras que otros pueden funcionar sin él.
Puntos clave
- Los zk-SNARKs demuestran que algo es correcto sin revelar información sensible.
- Los datos privados detrás de una prueba suelen denominarse witness.
- Las pruebas son breves y pueden verificarse de forma relativamente eficiente.
- Una prueba publicada puede verificarse sin contacto adicional con su autor.
- Los zk-SNARKs son una categoría de sistemas de prueba, no un único protocolo fijo.
¿Cómo funcionan los zk-SNARKs?
En un zk-SNARK, las reglas que debe cumplir una transacción o un cálculo se convierten primero en comprobaciones que un ordenador puede ejecutar. Ese conjunto de comprobaciones se denomina circuito o sistema de restricciones. En él se establece con precisión qué condiciones deben cumplirse antes de que algo se considere válido.
Tomemos como ejemplo un pago privado. El circuito puede comprobar, por ejemplo, si una persona dispone de saldo suficiente, si ese saldo no se ha gastado antes y si está autorizada para utilizarlo. Los datos sensibles necesarios para estas comprobaciones, como el saldo o los datos con los que puede gastarse, permanecen ocultos para quien verifica la prueba.
A grandes rasgos, hay tres pasos:
-
Setup En muchos zk-SNARKs clásicos, primero se generan parámetros públicos. Estos datos son necesarios para crear y verificar pruebas.
-
Proof generation El prover, es decir, la parte que quiere demostrar algo, utiliza la witness y las reglas del circuito para crear una prueba criptográfica.
-
Verificación El verifier, por ejemplo un nodo o un contrato inteligente, comprueba la prueba junto con la entrada pública. El verifier no ve la witness privada y no necesita volver a ejecutar por sí mismo todo el cálculo.
Un buen sistema zk-SNARK intenta garantizar tres propiedades importantes. En primer lugar, completitud: si la afirmación es correcta y la prueba se crea correctamente, la prueba se acepta. En segundo lugar, soundness: un atacante no puede, en la práctica, crear una prueba válida para una afirmación que no es correcta. Y en tercer lugar, zero-knowledge: la prueba no revela información sensible, salvo el hecho de que la afirmación demostrada es correcta.
Ejemplo: Suponga que debe demostrar que es mayor de 18 años sin compartir su fecha de nacimiento. Un zk-SNARK puede, en teoría, demostrar que cumple esa condición sin que quien verifica vea su fecha de nacimiento ni su edad exacta.
Sin embargo, existe una limitación importante. Un zk-SNARK solo comprueba las reglas que están definidas en el circuito. Si hay un error en esas reglas, una prueba puede ser técnicamente válida aunque el sistema permita algo que en realidad no era la intención. La criptografía no puede corregir por sí sola un circuito mal diseñado.
¿Para qué se utilizan los zk-SNARKs?
Los zk-SNARKs se utilizan cuando alguien quiere demostrar que un cálculo se ha ejecutado correctamente sin revelar toda la entrada ni los pasos intermedios. Esto hace que la técnica resulte interesante para la privacidad, pero también para aplicaciones en las que quien verifica la prueba no necesita volver a ejecutar todo el cálculo.
Algunas aplicaciones conocidas son:
- pagos privados;
- aplicaciones en las que la entrada o partes del cálculo permanecen privadas;
- pruebas de identidad y credenciales, en las que se demuestra una característica sin compartir todos los datos personales;
- proof-of-reserves, en las que una parte puede demostrar que existen determinadas reservas sin revelar todos los datos subyacentes;
- validity rollups, que procesan muchas transacciones fuera de Ethereum y luego publican en Ethereum una prueba de que el procesamiento fue correcto.
Aleo, por ejemplo, utiliza un modelo en el que un programa se ejecuta localmente. Después se crea una prueba de zero-knowledge con la que puede demostrarse que la ejecución fue correcta. Los validators no necesitan recibir toda la entrada privada ni los pasos intermedios, sino que pueden verificar la prueba.
La privacidad no aparece automáticamente solo porque en algún lugar se utilice “ZK”. Qué datos permanecen privados depende del protocolo y de lo que se haya definido en el circuito como privado o público. Si determinados datos de la transacción se hacen públicos de forma deliberada, un zk-SNARK no puede ocultarlos después.
¿Cómo apoyan los zk-SNARKs la privacidad?
Los zk-SNARKs apoyan la privacidad porque permiten demostrar que una transacción es válida sin revelar sus detalles sensibles. En un pago privado, por ejemplo, una persona puede demostrar que dispone de fondos válidos, que está autorizada para gastarlos y que no está gastando el dinero dos veces. El remitente, el destinatario y el importe no tienen por qué ser públicos.
Zcash muestra bien cómo funciona este diseño. Allí se utiliza una note para registrar de forma privada una determinada cantidad de ZEC. En la blockchain no aparece el contenido completo de esa note, sino un commitment: un registro criptográfico de la misma. Puede verse como un sobre cerrado y sellado. Todo el mundo puede ver que el sobre existe, pero no lo que contiene.
La información de la note se cifra para el destinatario. Cuando una note se gasta, aparece un nullifier único en la blockchain. Ese nullifier no muestra directamente qué note se ha gastado, pero los nodes sí pueden comprobar si el mismo nullifier ya se ha utilizado antes. De este modo, la red puede evitar el double spending sin revelar los datos privados subyacentes.
Por tanto, la privacidad aquí no significa que no quede ningún rastro en la blockchain. Los commitments y los nullifiers siguen siendo visibles. Además, datos como las direcciones IP, el timing, los metadatos de red y la información que un usuario haga pública por su cuenta no quedan ocultos automáticamente por un zk-SNARK.
¿Cómo se utilizan los zk-SNARKs para la escalabilidad?
Para la escalabilidad, los zk-SNARKs pueden utilizarse para resumir una gran cantidad de trabajo computacional en una sola prueba compacta. Esto se ve, por ejemplo, en los validity rollups: las transacciones se procesan fuera de Ethereum, se agrupan en batches y después se crea una prueba de que el procesamiento se ha realizado correctamente.
El operador de un rollup de este tipo procesa las transacciones y crea una validity proof con la que demuestra que el nuevo estado se ha calculado conforme a las reglas del rollup. Un contrato verificador en Ethereum solo acepta ese nuevo estado si la prueba es válida. De este modo, Ethereum no necesita volver a ejecutar todos los cálculos de cada transacción individual.
Con la recursión, esto puede resumirse aún más. En ese caso, una nueva prueba puede demostrar que varias pruebas anteriores son válidas. Así, al final, muchos cálculos o pruebas individuales pueden representarse mediante una sola prueba compacta.
Scroll utiliza pruebas zk para demostrar la ejecución correcta de batches de transacciones, tras lo cual la prueba puede verificarse en Ethereum.
Mina utiliza zk-SNARKs recursivos de otra manera. En lugar de que un participante tenga que verificar toda la historia de la blockchain desde el principio, la validez del estado actual de la blockchain puede demostrarse con una prueba criptográfica compacta.
Una verificación rápida no significa que todo el proceso sea barato. Crear una prueba puede requerir mucha capacidad de cálculo y memoria. Además, una validity proof no resuelve automáticamente otros problemas, como la disponibilidad de datos, la censura por parte de un operador o los riesgos relacionados con los puentes entre blockchains.
¿Qué blockchains y criptomonedas utilizan zk-SNARKs?
Varios proyectos cripto utilizan zk-SNARKs, pero a menudo con objetivos distintos. Por tanto, la técnica no se emplea solo para transacciones privadas.
- Zcash utiliza zk-SNARKs para transacciones shielded. Dentro del protocolo Orchard, se utiliza Halo 2 para demostrar criptográficamente este tipo de transacciones.
- Aleo utiliza zk-SNARKs para aplicaciones privadas y programables. Los programas pueden ejecutarse localmente, tras lo cual los validators verifican la prueba de ejecución correcta sin necesidad de ver la entrada privada ni los pasos intermedios.
- Mina utiliza zk-SNARKs recursivos para demostrar de forma compacta la validez del estado de la blockchain. El objetivo principal aquí es la verificación compacta y no, de forma automática, la privacidad de las transacciones.
- Scroll utiliza zk-SNARKs dentro de su zkEVM para demostrar el procesamiento correcto de batches de transacciones. Estas pruebas pueden verificarse posteriormente en Ethereum.
- Ethereum admite la verificación de determinados zk-SNARKs basados en pairing mediante precompiles. Esto permite que los contratos inteligentes verifiquen pruebas zk-SNARK. Ethereum no utiliza zk-SNARKs por sí mismo como mecanismo de consenso general.
Conviene distinguir entre un zk-SNARK y un zk-STARK. Ambos son sistemas de prueba criptográficos que pueden admitir zero-knowledge, pero técnicamente funcionan de manera diferente. Los zk-STARKs normalmente no requieren trusted setup, pero suelen generar pruebas más grandes que los zk-SNARKs. Por ello, un ZK-rollup no tiene por qué utilizar necesariamente un zk-SNARK.
¿Qué es un trusted setup en los zk-SNARKs?
Un trusted setup es un proceso único mediante el cual, para algunos zk-SNARKs, se generan parámetros públicos necesarios para crear y verificar pruebas. Estos parámetros suelen denominarse structured reference string (SRS) o common reference string (CRS).
La parte sensible es la información secreta aleatoria que se utiliza durante ese setup. A esto también se le llama toxic waste. Si alguien conserva esa información o puede reconstruirla más adelante, en determinados sistemas, como Groth16, podría utilizarse en teoría para crear pruebas falsas que aun así fueran aceptadas como válidas.
Por eso, algunos proyectos utilizan una ceremonia de multi-party computation. En ella, varios participantes añaden cada uno su propia aleatoriedad secreta. Mientras al menos un participante actúe honestamente y destruya realmente su contribución secreta, no podrá reconstruirse toda la información secreta del setup.
Eso reduce considerablemente el riesgo, pero sigue significando que se confía en que al menos un participante no haya sido comprometido y haya eliminado de verdad su contribución secreta.
No todos los zk-SNARKs necesitan un trusted setup. Zcash utilizó para los antiguos circuitos Sprout y Sapling Groth16, que sí requerían un trusted setup de este tipo. El protocolo Orchard posterior utiliza Halo 2 y no necesita un trusted setup con toxic waste.
¿Cuáles son las ventajas de los zk-SNARKs?
La gran ventaja de los zk-SNARKs es que la privacidad y la verificabilidad pueden ir de la mano. Puede demostrarse que se cumplen determinadas reglas sin revelar los datos sensibles detrás de esa prueba.
Las principales ventajas son:
- Privacidad con control: los datos sensibles pueden permanecer ocultos mientras los nodos siguen pudiendo comprobar si una transacción o un cálculo es válido.
- Pruebas breves: las pruebas son compactas en comparación con el cálculo que representan.
- Verificación rápida: un nodo o contrato inteligente no necesita volver a ejecutar todo el cálculo.
- Control público: una prueba puede publicarse y verificarse de forma independiente.
- Resumir muchos cálculos: con pruebas recursivas, varias transacciones, batches o pruebas anteriores pueden resumirse finalmente en una nueva prueba compacta.
En Ethereum, determinados zk-SNARKs basados en pairing también pueden verificarse en smart contracts. Esto permite, por ejemplo, que las aplicaciones hagan verificar en Ethereum pruebas de cálculos offchain o controles orientados a la privacidad.
Eso sí, conviene recordar que “breve” y “eficiente” se refieren sobre todo al tamaño de la prueba y a su verificación. Para el prover, crear una prueba de este tipo puede requerir mucha capacidad de cálculo y memoria.
¿Cuáles son las limitaciones y los riesgos de los zk-SNARKs?
Los zk-SNARKs son potentes, pero no resuelven todos los problemas de privacidad o escalabilidad. La seguridad depende de la criptografía utilizada, del circuito y de la forma en que el sistema se integra en una blockchain o aplicación.
Un riesgo importante en los sistemas que dependen de un trusted setup es la información secreta del setup. Si la toxic waste de, por ejemplo, un setup Groth16 cae en manos equivocadas, los atacantes podrían crear pruebas falsas que aun así fueran aceptadas como válidas. En un diseño de pago privado, en el peor de los casos, esto podría dar lugar a que apareciera saldo que, según las reglas normales, no debería haber existido.
Además, un zk-SNARK solo demuestra que se han cumplido las reglas del circuito. Por ello, los errores en el circuito, en el código del prover, en el código del verifier, en los parámetros utilizados o en la conexión con una blockchain pueden tener consecuencias graves. Una prueba criptográficamente correcta no ayuda si las reglas subyacentes están mal diseñadas.
La privacidad también tiene límites. En las transacciones shielded de Zcash, por ejemplo, los commitments y los nullifiers siguen siendo visibles en la blockchain, mientras que la información de las notes permanece cifrada. Además, los datos públicos, el timing, las direcciones IP y otros metadatos de red pueden, en ocasiones, seguir revelando información o haciendo visibles ciertas relaciones.
En los zk-rollups surge otro problema distinto. Una validity proof puede demostrar que un batch se ha procesado correctamente, pero no impide automáticamente que un operador retrase transacciones o censure a usuarios. También siguen existiendo riesgos relacionados con los bridges y la disponibilidad de datos.
Por último, zero-knowledge no significa automáticamente que un sistema sea resistente a futuros ataques cuánticos. Eso depende de la construcción criptográfica concreta. Los zk-SNARKs clásicos basados en pairing utilizan supuestos criptográficos distintos de los sistemas STARK transparentes, por ejemplo.
Conclusión
Los zk-SNARKs permiten demostrar que una transacción o un cálculo es correcto sin revelar los datos sensibles que hay detrás. Por ello, resultan interesantes para pagos privados, aplicaciones orientadas a la privacidad y escalabilidad mediante validity rollups. Zcash es uno de los ejemplos más conocidos de una blockchain que utiliza zk-SNARKs para hacer posibles las transacciones shielded.
La idea central es relativamente sencilla: una blockchain u otro verifier no necesita ver todos los datos subyacentes ni volver a ejecutar todo el cálculo, siempre que pueda comprobar una prueba criptográfica válida. Cuánta privacidad y seguridad ofrece esto en última instancia depende del diseño del sistema. Al final, un zk-SNARK solo es tan fiable como el circuito, la criptografía utilizada y la integración que lo rodea.