Logo
Nuevos usuarios de RPC: 35% de descuento el primer mesVer oferta
OnFinality Learn
Guías de Red y Protocolo11 min de lectura

Cómo funcionan las pruebas de conocimiento cero: guía práctica del probador, el verificador y la verificación en cadena

Un recorrido técnico sobre cómo funcionan las pruebas de conocimiento cero, desde las tres propiedades requeridas y los protocolos interactivos hasta la verificación no interactiva SNARK/STARK y un arnés de prueba local reproducible.

TL;DR

Una prueba de conocimiento cero permite que un probador convenza a un verificador de que una afirmación es verdadera sin revelar el secreto que la hace verdadera. El protocolo debe cumplir tres propiedades: completitud (las afirmaciones verdaderas se aceptan), solidez (las afirmaciones falsas se rechazan) y conocimiento cero (el verificador no aprende nada más allá de la validez de la afirmación). En la práctica, la mayoría de los sistemas blockchain utilizan pruebas no interactivas derivadas de protocolos interactivos mediante la transformación Fiat-Shamir, y luego las verifican en cadena o fuera de cadena. Esta guía explica el mecanismo, muestra un arnés de verificación local ejecutable y describe cómo medir el comportamiento de generación y verificación de pruebas en tu propia infraestructura.

Respuesta directa y alcance

Una prueba de conocimiento cero (ZKP) funciona haciendo que un probador ejecute un cálculo sobre un testigo secreto y produzca un objeto de prueba que un verificador puede comprobar contra una afirmación pública. Si la prueba es válida, el verificador queda convencido de que la afirmación es verdadera, pero la prueba no revela nada sobre el testigo más allá de lo que la afirmación ya implica.

Este artículo cubre la mecánica del protocolo, la diferencia entre pruebas interactivas y no interactivas, cómo difieren SNARKs y STARKs a nivel práctico, y un procedimiento reproducible para probar la verificación de pruebas localmente y contra un endpoint RPC. No recomienda un endpoint o proveedor específico; para la selección concreta de endpoints, utiliza el Asistente RPC.

  • Probador: posee el testigo secreto y genera la prueba.
  • Verificador: comprueba la prueba contra una afirmación pública y una clave de verificación.
  • Afirmación: la declaración pública que se demuestra, como 'Conozco una preimagen de este hash'.
  • Testigo: la entrada privada que hace verdadera la afirmación.

Requisitos previos y supuestos

Debes estar familiarizado con conceptos criptográficos básicos como funciones hash y firmas de clave pública, y con la ejecución local de Node.js o Python. Los ejemplos asumen que tienes un RPC_URL funcional para una cadena compatible con EVM si deseas probar la verificación en cadena, pero el arnés local se ejecuta sin acceso a la red.

No se requiere una biblioteca ZK específica para seguir las secciones conceptuales. Los ejemplos de código utilizan valores de marcador de posición y llamadas a la biblioteca estándar para que puedas adaptarlos a tu sistema de prueba elegido.

Las tres propiedades que definen una prueba ZK

Todo sistema de prueba de conocimiento cero debe cumplir tres propiedades. La completitud significa que si la afirmación es verdadera y ambas partes siguen el protocolo honestamente, el verificador acepta. La solidez significa que si la afirmación es falsa, ningún probador tramposo puede convencer al verificador excepto con una probabilidad insignificante. El conocimiento cero significa que el verificador no aprende nada más allá de la verdad de la afirmación, formalmente capturado por la existencia de un simulador que puede producir transcripciones indistinguibles de las reales sin el testigo.

Estas propiedades son lo que separa una prueba ZK de una firma simple o un compromiso hash. Una firma prueba que posees una clave, pero no oculta el mensaje. Una prueba ZK oculta el testigo mientras sigue vinculando al verificador a la verdad de la afirmación.

Pruebas interactivas: el modelo mental de desafío-respuesta

En una prueba ZK interactiva, el probador y el verificador intercambian múltiples mensajes. La estructura clásica es compromiso-desafío-respuesta: el probador se compromete a un valor derivado del testigo, el verificador envía un desafío aleatorio y el probador responde de una manera que solo alguien con el testigo podría hacer de forma consistente a través de muchos desafíos.

Los ejemplos de la cueva de Alí Babá y el amigo daltónico ilustran la intuición. El probador demuestra repetidamente conocimiento bajo desafíos elegidos aleatoriamente; un probador tramposo tiene solo un 50% de probabilidad de adivinar correctamente en cada ronda, por lo que después de suficientes rondas la probabilidad de trampa no detectada se vuelve insignificante. El verificador nunca aprende el secreto porque cada transcripción podría haber sido simulada por alguien sin el testigo.

  • El número de rondas controla el error de solidez: cada ronda reduce a la mitad la probabilidad de trampa en los protocolos más simples.
  • La interacción es costosa en cadena porque requiere múltiples transacciones o mensajes.
  • Las pruebas interactivas son útiles para protocolos fuera de cadena donde ambas partes están en línea.

Pruebas no interactivas y la transformación Fiat-Shamir

La mayoría de las aplicaciones blockchain necesitan pruebas no interactivas: un único objeto de prueba que cualquiera pueda verificar más tarde sin hablar con el probador. La heurística de Fiat-Shamir convierte un protocolo interactivo en uno no interactivo reemplazando el desafío aleatorio del verificador por un hash del compromiso del probador y la afirmación pública.

Esto funciona porque el probador no puede predecir la salida del hash antes de comprometerse, por lo que el desafío sigue siendo impredecible. La prueba resultante es un único mensaje que vincula la afirmación, el compromiso y la respuesta. La seguridad depende de que la función hash se comporte como un oráculo aleatorio, por lo que la elección del hash y la separación de dominio importan en los sistemas de producción.

SNARKs vs STARKs: diferencias prácticas

Los ZK-SNARKs (Argumentos de Conocimiento No Interactivos Succintos) producen pruebas pequeñas y verificación rápida, pero a menudo requieren una ceremonia de configuración confiable para generar las claves de prueba y verificación. Los ZK-STARKs (Argumentos de Conocimiento Transparentes y Escalables) evitan la configuración confiable y se basan en criptografía basada en hash, lo que los hace plausiblemente resistentes a la computación cuántica, pero las pruebas suelen ser más grandes y la verificación puede ser más costosa.

La elección correcta depende de tus restricciones. Si el costo de verificación en cadena domina, a menudo se prefieren los SNARKs. Si la transparencia y los supuestos de configuración importan más, los STARKs pueden ser preferibles. Ambos son no interactivos y ambos cumplen las tres propiedades ZK cuando se implementan correctamente.

  • SNARK: tamaño de prueba pequeño, verificación rápida, posible configuración confiable.
  • STARK: configuración transparente, pruebas más grandes, supuestos de seguridad basados en hash.
  • Ambos requieren un diseño cuidadoso del circuito; un error en el circuito puede romper la solidez.

Arnés de verificación local ejecutable

El siguiente script de Node.js simula el lado del verificador de una comprobación de prueba no interactiva. No implementa un sistema de prueba real; demuestra el flujo de control que utilizarás al integrar una biblioteca de verificación real. Reemplaza la prueba de marcador de posición y la clave de verificación con las salidas de tu sistema de prueba elegido.

Ejecútalo con node verify.js después de establecer las variables de entorno. El script sale con código 0 en caso de éxito y 1 en caso de fallo, lo que facilita su integración en CI.

// verify.js
const crypto = require('crypto');

const statement = process.env.STATEMENT || 'I know the preimage of this commitment';
const proof = process.env.PROOF || 'placeholder-proof';
const vk = process.env.VERIFICATION_KEY || 'placeholder-vk';

function verify(statement, proof, vk) {
  // Replace this with a real verifier call, e.g. snarkjs.groth16.verify(vk, publicSignals, proof)
  const digest = crypto.createHash('sha256').update(statement + proof + vk).digest('hex');
  return digest.length === 64;
}

const ok = verify(statement, proof, vk);
console.log(ok ? 'PROOF ACCEPTED' : 'PROOF REJECTED');
process.exit(ok ? 0 : 1);

Procedimiento de diagnóstico: medir el comportamiento de verificación de pruebas

Para comprender cómo se comporta un sistema ZK en tu infraestructura, mide tres cosas: tiempo de generación de la prueba, tamaño de la prueba y tiempo de verificación. Realiza cada medición al menos 30 veces y registra la mediana y el percentil 95. No confíes en una sola ejecución, porque el tiempo de prueba varía con el tamaño del testigo y la carga de la máquina.

Utiliza el siguiente procedimiento para recopilar resultados en una tabla que puedas comparar entre máquinas o sistemas de prueba. La tabla a continuación es una plantilla; completa tus propios valores medidos en lugar de asumir cualquier número.

  • Paso 1: Fija el circuito y el tamaño del testigo para que las ejecuciones sean comparables.
  • Paso 2: Mide el tiempo de generación de la prueba con un reloj monotónico y registra el tamaño en bytes de la prueba.
  • Paso 3: Mide el tiempo de verificación por separado, incluido cualquier costo de deserialización.
  • Paso 4: Repite 30 veces y calcula la mediana y el p95.
  • Paso 5: Registra el tipo de máquina, la versión de la biblioteca y la función hash utilizada.
| Run | Prove time (ms) | Proof size (bytes) | Verify time (ms) |
|-----|-----------------|--------------------|------------------|
| 1   |                 |                    |                  |
| 2   |                 |                    |                  |
| ... |                 |                    |                  |
| p50 |                 |                    |                  |
| p95 |                 |                    |                  |

Verificación en cadena vía RPC

Si tu verificador es un contrato inteligente, puedes probar la verificación llamando a la función verify del contrato a través de un endpoint RPC. El siguiente ejemplo de curl utiliza un RPC_URL y una dirección de contrato de marcador de posición. Reemplázalos con tus propios valores. Para consideraciones sobre selección de endpoints y confiabilidad, consulta Precios y planes de RPC y el directorio de redes.

La llamada devuelve un booleano o un recibo de transacción dependiendo de si el verificador es una función de vista o una función que cambia el estado. Una función de vista es más barata de probar porque no requiere una transacción.

curl -X POST "$RPC_URL" \
  -H "Content-Type: application/json" \
  -d '{
    "jsonrpc": "2.0",
    "method": "eth_call",
    "params": [{
      "to": "0xYourVerifierContract",
      "data": "0xYourEncodedProofAndPublicInputs"
    }, "latest"],
    "id": 1
  }'

Resultado esperado de la verificación y solución de problemas

Una verificación exitosa devuelve true o un recibo con estado 1. Una verificación fallida devuelve false, revierte o devuelve estado 0. Si ves una reversión, decodifica el motivo de la reversión antes de asumir que la prueba no es válida; las causas comunes incluyen entradas públicas no coincidentes, una clave de verificación obsoleta o una prueba generada para una versión de circuito diferente.

Si la verificación tiene éxito localmente pero falla en cadena, verifica que las entradas públicas estén codificadas en el mismo orden y formato que espera el contrato. Si la verificación es lenta, mide el uso de gas y considera si el contrato verificador puede optimizarse o si un verificador fuera de cadena con atestación en cadena es más apropiado.

  • Entradas públicas no coincidentes: vuelve a codificar y compara byte por byte.
  • Clave de verificación incorrecta: confirma que la clave coincide con la versión del circuito y del sistema de prueba.
  • Hash no coincidente: asegúrate de que la transcripción Fiat-Shamir utilice el mismo separador de dominio.
  • Límites de gas: aumenta el límite de gas para llamadas de vista si el nodo impone uno.

Limitaciones y compensaciones

Las pruebas de conocimiento cero no son gratuitas. La prueba es computacionalmente costosa y el costo crece con la complejidad del circuito. Las configuraciones confiables introducen supuestos de ceremonia que deben gestionarse con cuidado. Los sistemas de prueba también tienen peculiaridades específicas de la versión, y una prueba generada por una versión de biblioteca puede no verificarse con otra.

Conocimiento cero no significa anónimo por defecto. La afirmación en sí puede filtrar metadatos, y el tiempo o el tamaño de las pruebas pueden correlacionarse con propiedades del testigo. Trata ZK como un componente de un diseño de privacidad, no como una solución completa.

Próximos pasos

Comienza con un circuito pequeño y un verificador local, luego pasa a la verificación en cadena una vez que el arnés local pase de manera consistente. Utiliza el procedimiento de medición anterior para establecer una línea base antes de optimizar. Cuando estés listo para probar contra una cadena en vivo, elige un endpoint a través del Asistente RPC y revisa las opciones de nodo dedicado si necesitas un rendimiento predecible.

Para obtener un contexto más amplio sobre cómo encajan los endpoints RPC en los flujos de trabajo blockchain, consulta la guía de endpoints RPC.

Nunca te preocupes por la infraestructura nuevamente

OnFinality elimina la carga pesada de DevOps para que puedas construir de forma más inteligente y rápida.

Comenzar