Desarrollar tu primer circuito ZK con Circom

Desarrolla tu primer circuito ZK con Circom

En el ecosistema cripto y blockchain, las pruebas de conocimiento cero (Zero-Knowledge, ZK) se han convertido en pilares fundamentales para preservar la privacidad y la integridad de la información. Circom es una de las herramientas más populares para diseñar y compilar circuitos ZK que permiten verificar cálculos complejos sin revelar datos sensibles.

En este artículo detallado exploraremos los conceptos esenciales, la instalación, el diseño e implementación de tu primer circuito ZK utilizando Circom, así como su integración con snarkJS para generar y verificar pruebas.

Tabla de contenidos

  • Introducción a ZK y Circom
  • Preparar el entorno de desarrollo
  • Estructura y sintaxis de un circuito Circom
  • Primer circuito: “Hello, ZK!”
  • Compilación y generación de testigos
  • Generar y verificar pruebas con snarkJS
  • Buenas prácticas y optimizaciones
  • Integración en aplicaciones reales
  • Recursos y lecturas recomendadas

1. Introducción a ZK y Circom

Las pruebas de conocimiento cero permiten demostrar que conoces un secreto o que ejecutaste un cálculo sin divulgar el contenido del mismo. Circom es un lenguaje de dominio específico (DSL) diseñado para facilitar la creación de estos circuitos de manera modular y declarativa.

Circom se combina con snarkJS para la generación de testigos (witness), la configuración de parámetros de prueba (trusted setup) y la verificación de pruebas. Para profundizar, visita la documentación oficial en
docs.circom.io.

2. Preparar el entorno de desarrollo

2.1 Requisitos previos

  • Node.js v14 o superior
  • npm o Yarn
  • Go (opcional, para compilar versiones nativas de circom)
  • Terminal o shell (bash, zsh, Windows WSL)

2.2 Instalación básica

npm install -g circom
npm install -g snarkjs

Tras la instalación global, podrás invocar circom y snarkjs desde tu terminal. Verifica las versiones:

circom –version
snarkjs –version

3. Estructura y sintaxis de un circuito Circom

Un archivo .circom contiene declaraciones de templates (plantillas), signals (señales) y restricciones algebraicas. La sintaxis es parecida a JavaScript, pero con un enfoque matemático:

  • template: Define un bloque reutilizable de lógica
  • signal: Variables internas o de entrada/salida
  • component: Instancia de un template
  • ==: Declaración de restrictiva (constraint)

Ejemplo de una plantilla sencilla que multiplica dos números:

template Multiplicador() {
  signal input a
  signal input b
  signal output c

  c == a  b
}

component main = Multiplicador()

4. Primer circuito: “Hello, ZK!”

Vamos a crear un circuito que demuestre que conoces un secreto preestablecido sin revelar su valor. La lógica consistirá en comparar un hash SHA256 de la entrada con un valor público.

4.1 Definición del circuito

include circomlib/sha256.circom

template HelloZK() {
  signal input secret
  signal output isValid

  component hasher = Sha256(1)
  hasher.in[0] == secret

  // Valor público: hash precomputado (en decimal)
  signal const targetHash[8]
  targetHash[0] == 0xabcdef...
  // ... completar con las 8 palabras de 32 bits

  // Comparar palabra por palabra
  var allEq = 1
  for (var i = 0 i < 8 i  ) {
    allEq = allEq  (hasher.out[i] === targetHash[i])
  }
  isValid == allEq
}

component main = HelloZK()

Observa cómo reutilizamos el template Sha256 de circomlib (GitHub circomlib).

5. Compilación y generación de testigos

5.1 Compilar el circuito

Ejecuta:

circom HelloZK.circom –r1cs –wasm –sym -o build

Esto generará:

  • HelloZK.r1cs: descripción del circuito
  • HelloZK.wasm: código WebAssembly para calcular testigos
  • HelloZK.sym: símbolos para debugging

5.2 Crear los inputs y generar el testigo

Un archivo JSON con la entrada al circuito:

{
  secret: 1234567890
}

Genera el testigo:

node build/HelloZK_js/generate_witness.js build/HelloZK_js/HelloZK.wasm input.json witness.wtns

6. Generar y verificar pruebas con snarkJS

6.1 Trusted setup (Groth16)

  1. Generar zkey inicial:
    snarkjs groth16 setup build/HelloZK.r1cs powersOfTau28_hez_final_10.ptau HelloZK_0000.zkey
  2. Contribuir con entropía:
    snarkjs zkey contribute HelloZK_0000.zkey HelloZK_final.zkey –name=Tu contribución -v
  3. Exportar la clave de verificación:
    snarkjs zkey export verificationkey HelloZK_final.zkey verification_key.json

6.2 Generar la prueba

snarkjs groth16 prove HelloZK_final.zkey witness.wtns proof.json public.json

6.3 Verificar la prueba

snarkjs groth16 verify verification_key.json public.json proof.json

Un mensaje OK confirma que tu prueba es válida.

7. Buenas prácticas y optimizaciones

  • Minimiza variables intermedias: Menos señales implican menos restricciones.
  • Usa template para abstracción: Facilita el mantenimiento y la reutilización.
  • Aprovecha librerías optimizadas: circomlib o circomlibjs.
  • Benchmark: mide tiempo de compilación, witness y prueba para detectar cuellos de botella.
  • Trusted setup transparente: Opta por potencias de tau públicas o sistemas multisig para la fase de setup.

8. Integración en aplicaciones reales

Una vez validados los pasos anteriores, puedes exponer la verificación de pruebas en smart contracts (por ejemplo en Ethereum), usando Verifier.sol generado por snarkJS. Combínalo con librerías como hardhat o truffle para desplegar tu contrato y habilitar la autenticación ZK en tu DApp.

9. Recursos y lecturas recomendadas

Recurso Enlace
Circom Docs docs.circom.io
snarkJS GitHub github.com/iden3/snarkjs
Blog iden3 iden3.io
zkProof Foundations zkproof.org

Con este completo recorrido dispones de las herramientas y conocimientos para diseñar, compilar y verificar tus propios circuitos ZK con Circom. ¡Manos a la obra y bienvenido al mundo de la criptografía avanzada!


Comentarios

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *