Logo
Nuevos usuarios de RPC: 35% de descuento el primer mesVer oferta
OnFinality Learn
Integración y Desarrollo11 min de lectura

Protocolo de conocimiento cero: de los sistemas de prueba a los flujos de trabajo verificables en cadena

Una guía práctica sobre los protocolos de conocimiento cero: cómo se generan y verifican las pruebas, cómo probar un verificador localmente y cómo medir la latencia de generación y verificación de pruebas sin inventar benchmarks.

TL;DR

Un protocolo de conocimiento cero permite que un probador convenza a un verificador de que una afirmación es verdadera sin revelar el testigo que la respalda. Este artículo separa las garantías del protocolo (completitud, solidez, conocimiento cero) de las decisiones de ingeniería en torno a los sistemas de prueba, la configuración y la verificación en cadena. Luego recorre un bucle local ejecutable de prueba y verificación y un procedimiento de medición reproducible para la latencia de generación y verificación de pruebas. Úsalo para diseñar, probar y solucionar problemas de integraciones ZK antes de elegir cualquier proveedor de RPC o nodo para la capa de verificación.

Alcance y la respuesta directa

Un protocolo de conocimiento cero es un método mediante el cual una parte, el probador, convence a otra parte, el verificador, de que una afirmación es verdadera sin transmitir nada más allá de la veracidad de esa afirmación. En la práctica, la mayoría de las discusiones de ingeniería se refieren a una prueba de conocimiento de conocimiento cero: el probador demuestra conocimiento de un testigo secreto que satisface una relación pública, como conocer una clave privada para una clave pública o conocer entradas que producen un hash hacia un compromiso publicado.

La distinción de ingeniería importante es entre las garantías matemáticas del protocolo y el sistema que lo rodea. El protocolo define qué es una prueba válida. El sistema define cómo se generan las pruebas, dónde se verifican, qué suposiciones de configuración existen y cuánta latencia y costo agrega el flujo de trabajo. Este artículo se centra en la segunda parte: cómo construir, probar y medir un flujo de trabajo de conocimiento cero sin tratar ninguna biblioteca o cadena en particular como la única respuesta correcta.

  • Completitud: un probador honesto con un testigo válido puede convencer al verificador.
  • Solidez: un probador sin un testigo válido no puede convencer al verificador excepto con probabilidad despreciable.
  • Conocimiento cero: el verificador no aprende nada más allá de la verdad de la afirmación, formalizado por la existencia de un simulador que produce transcripciones indistinguibles.

Requisitos previos y suposiciones

Los ejemplos a continuación asumen un entorno de desarrollo local con Node.js 20 o posterior y Python 3.10 o posterior. Utilizan un RPC_URL de marcador de posición para cualquier endpoint JSON-RPC que controles, y no asumen un sistema de prueba específico. El objetivo es un bucle reproducible que puedas adaptar a Groth16, PLONK, STARKs o una biblioteca como snarkjs, arkworks o una cadena de herramientas zkVM.

También deberías tener una forma de ejecutar un contrato verificador o un binario verificador nativo. Si planeas verificar en cadena, necesitas una cuenta de desarrollo con fondos y una red de prueba. Para la selección de endpoints y la disponibilidad de la red, utiliza el servicio API de OnFinality y el directorio de redes compatibles en lugar de codificar un endpoint público.

  • Un circuito o programa que codifica la afirmación y el testigo.
  • Un artefacto de configuración confiable o configuración transparente, según el sistema de prueba.
  • Un verificador que comprueba la prueba contra las entradas públicas.
  • Un arnés de medición que registra el tiempo de reloj de pared y el uso de recursos.

Modelo mental: afirmación, testigo y entradas públicas

Todo protocolo de conocimiento cero tiene tres partes móviles. La afirmación es lo que declaras, por ejemplo 'Conozco una preimagen x tal que H(x) = y'. El testigo es la x secreta. Las entradas públicas son los valores que ve el verificador, como y y el identificador del circuito. La prueba es un objeto corto que vincula las entradas públicas con la existencia de un testigo.

Esta separación importa porque la mayoría de los errores de integración provienen de entradas públicas desajustadas, no de criptografía rota. Si al verificador se le da un hash diferente, una raíz de Merkle diferente o un separador de dominio diferente al que usó el probador, la verificación falla aunque la prueba en sí sea válida para las entradas del probador. Trata las entradas públicas como un contrato de API: serialízalas de forma determinista, documenta su orden y pruébalas independientemente de la prueba.

  • Probador: toma el testigo y las entradas públicas, produce una prueba.
  • Verificador: toma la prueba y las entradas públicas, produce aceptar o rechazar.
  • Configuración: produce claves de prueba y verificación; sus suposiciones de confianza dependen del sistema de prueba.
  • Transcripción: los protocolos interactivos pueden hacerse no interactivos con la transformación Fiat-Shamir, que aplica hash a la transcripción para convertirla en un desafío.

Protocolos interactivos versus no interactivos

Los protocolos interactivos intercambian mensajes entre probador y verificador, a menudo con un desafío elegido por el verificador. Son útiles para la enseñanza y para entornos donde ambas partes están en línea, como la computación multipartita y algunos flujos de autenticación. Las pruebas no interactivas comprimen la interacción en un solo mensaje, que es lo que hace práctica la verificación en cadena.

La heurística de Fiat-Shamir reemplaza el desafío aleatorio del verificador con un hash de la transcripción. Esta es una decisión de ingeniería real, no una formalidad: el hash debe cubrir cada elemento que influye en la afirmación, incluido el identificador del circuito y todas las entradas públicas. Omitir un campo puede permitir la maleabilidad de la prueba o la confusión de dominio. Cuando revises una integración ZK, verifica la definición de la transcripción antes de revisar la aritmética de curvas.

Bucle local ejecutable de prueba y verificación

El siguiente script de Node.js es un arnés, no una implementación criptográfica. Define una interfaz de probador y verificador, ejecuta un vector de prueba determinista y registra el tiempo. Reemplaza las funciones de marcador de posición con llamadas a la biblioteca que elijas. La estructura es lo que importa: generar una prueba, verificarla y afirmar que las entradas públicas manipuladas son rechazadas.

Ejecútalo con node zk-harness.mjs. El script sale con un código distinto de cero si la verificación falla o si se acepta una entrada manipulada, lo que lo hace adecuado para CI.

// zk-harness.mjs
import { performance } from 'node:perf_hooks';

// Replace these with your library's real functions.
async function prove(witness, publicInputs) {
  // Example shape only. Do not use as cryptography.
  return { proof: 'PROOF_PLACEHOLDER', publicInputs };
}

async function verify(proof, publicInputs) {
  // Example shape only. Replace with real verifier.
  return proof.publicInputs.hash === publicInputs.hash;
}

const witness = { secret: 'WITNESS_PLACEHOLDER' };
const publicInputs = { hash: 'PUBLIC_HASH_PLACEHOLDER', circuitId: 'demo-v1' };

const t0 = performance.now();
const proof = await prove(witness, publicInputs);
const t1 = performance.now();
const ok = await verify(proof, publicInputs);
const t2 = performance.now();

console.log(JSON.stringify({
  proveMs: t1 - t0,
  verifyMs: t2 - t1,
  accepted: ok
}, null, 2));

if (!ok) process.exit(1);

const tampered = { ...publicInputs, hash: 'TAMPERED_HASH' };
const tamperedOk = await verify(proof, tampered);
if (tamperedOk) {
  console.error('Verifier accepted tampered public inputs');
  process.exit(1);
}
console.log('Tampered input rejected as expected');

Verificar una prueba a través de JSON-RPC

Si tu verificador es un contrato, la prueba y las entradas públicas se codifican en una transacción o en una eth_call. Usa eth_call primero para comprobar el valor de retorno del verificador sin gastar gas. El ejemplo de curl a continuación utiliza un RPC_URL de marcador de posición y datos de llamada de marcador de posición; genera los datos de llamada con el codificador ABI de tu biblioteca.

Para el tráfico de verificación en producción, elige un endpoint con latencia predecible y límites de velocidad suficientes. La página de precios de RPC de OnFinality explica las dimensiones del plan, y la opción de nodo dedicado es apropiada cuando la verificación es sensible a la latencia o de gran volumen.

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

Resultado de verificación esperado y firmas de fallo

Un verificador correcto devuelve true o un estado distinto de cero para una prueba válida y false o una reversión para una inválida. En el arnés local, la salida esperada es un objeto JSON con valores proveMs y verifyMs y accepted: true, seguido del mensaje de que la entrada manipulada fue rechazada. En el ejemplo de RPC, una eth_call exitosa devuelve un valor booleano o de estado codificado en hexadecimal; una reversión generalmente significa que la prueba o las entradas públicas no coincidían con las expectativas del verificador.

No trates una sola ejecución exitosa como evidencia de corrección. Ejecuta el arnés contra al menos tres casos: una prueba válida, una prueba con una entrada pública cambiada y una prueba generada para un identificador de circuito diferente. El tercer caso detecta errores de separación de dominio que el segundo caso pasa por alto.

  • El verificador revierte sin razón: a menudo datos de llamada mal formados u orden ABI incorrecto.
  • El verificador devuelve false: las entradas públicas no coinciden o la prueba se generó para una clave diferente.
  • La generación de la prueba tiene éxito pero la verificación falla: revisa los artefactos de configuración y la versión del circuito.
  • Fallos intermitentes: revisa la gestión de nonces y el orden de las transacciones si la verificación es en cadena.

Procedimiento de medición reproducible

Las mediciones solo son útiles si son reproducibles. Registra el sistema de prueba, el tamaño del circuito, la versión de la biblioteca, el hardware y si el probador se ejecutó en un navegador, un servidor o un binario nativo. Ejecuta cada caso al menos 30 veces después de un calentamiento y reporta la mediana y el p95 en lugar de una sola ejecución. Mantén el testigo y las entradas públicas fijos entre ejecuciones para que estés midiendo el sistema, no la varianza de las entradas.

La siguiente tabla es una plantilla. Rellénala con tus propios valores medidos; no copies números de otro proyecto. El procedimiento es el entregable, no un benchmark declarado.

  • Calentamiento: 5 ejecuciones descartadas.
  • Ejecuciones medidas: 30 por caso.
  • Reporte: mediana, p95, mínimo, máximo y desviación estándar.
  • Entorno: modelo de CPU, RAM, SO, commit de la biblioteca y parámetros del sistema de prueba.

Plantilla de tabla de resultados

CasoSistema de pruebaRestricciones del circuitoMediana de prueba (ms)p95 de prueba (ms)Mediana de verificación (ms)p95 de verificación (ms)Aceptado
Prueba válidaYOUR_SYSTEMYOUR_COUNTMEASUREDMEASUREDMEASUREDMEASUREDtrue
Entrada manipuladaYOUR_SYSTEMYOUR_COUNTn/an/aMEASUREDMEASUREDfalse
ID de circuito incorrectoYOUR_SYSTEMYOUR_COUNTMEASUREDMEASUREDMEASUREDMEASUREDfalse

Si verificas en cadena, agrega una segunda tabla para el gas utilizado y la latencia de confirmación. El gas es determinista para un verificador y tamaño de entrada dados, mientras que la latencia de confirmación depende de la red y el endpoint. Mide ambos por separado para poder atribuir las regresiones correctamente.

Solución de problemas y limitaciones

Los fallos de integración más comunes no son rupturas criptográficas. Son entradas públicas desajustadas, artefactos de configuración obsoletos, serialización no determinista y contratos verificadores desplegados contra la versión incorrecta del circuito. Fija tu circuito, clave de prueba y dirección del verificador juntos en un manifiesto, y haz que CI falle cuando cualquiera de ellos cambie sin un aumento de versión correspondiente.

Los protocolos de conocimiento cero también tienen limitaciones reales. La generación de pruebas puede ser costosa en CPU y memoria, las configuraciones confiables introducen suposiciones que deben gestionarse y las configuraciones transparentes intercambian la confianza en la configuración por pruebas más grandes o verificación más lenta. El conocimiento cero no oculta metadatos como el tiempo, las direcciones IP o los patrones del grafo de transacciones. Si tu modelo de amenaza incluye esos, necesitas técnicas de privacidad adicionales.

  • Fija las versiones del circuito, la clave y el verificador en un manifiesto.
  • Prueba entradas manipuladas y separadores de dominio incorrectos en CI.
  • Mide la generación de pruebas y la verificación por separado.
  • Documenta las suposiciones de configuración y quién puede influir en ellas.
  • No asumas que el conocimiento cero implica anonimato.

Próximos pasos para una integración en producción

Comienza con el arnés local, luego traslada la verificación a una red de prueba usando un endpoint RPC controlado. Compara la latencia de verificación entre configuraciones de endpoints y registra los resultados en tu propia tabla. Si el volumen de verificación crece, evalúa un nodo dedicado para que las comprobaciones de pruebas no compitan con tráfico no relacionado. Para la elección de endpoints y proveedores, la guía del Asistente RPC sobre alojamiento de nodos blockchain y endpoints RPC multicadena es un complemento útil para esta metodología.

Finalmente, trata el protocolo de conocimiento cero como un componente en un pipeline verificable más grande. La prueba es tan confiable como el circuito, la configuración, el despliegue del verificador y los datos que alimentan las entradas públicas. Revisa cada capa de forma independiente y mantén el arnés de medición en el control de versiones para que los cambios futuros puedan compararse con una línea base conocida.

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