Implementar ZKPs en Ethereum: tutorial práctico

Implementar ZKPs en Ethereum: Tutorial Práctico

En este artículo detallado exploraremos cómo integrar Pruebas de Conocimiento Cero (ZKPs) en la blockchain de Ethereum, desde la teoría básica hasta un ejemplo completo con circom y snarkjs, incluyendo la interacción en Solidity y despliegue en testnets.

Índice

  • 1. ¿Por qué ZKPs en Ethereum
  • 2. Tipos de ZKPs: SNARK vs STARK
  • 3. Entorno de desarrollo y herramientas
  • 4. Creación de circuitos con circom
  • 5. Configuración de la fase de confianza
  • 6. Generación de pruebas y test de off-chain
  • 7. Smart contract verificador en Solidity
  • 8. Despliegue y verificación on-chain
  • 9. Buenas prácticas y optimización
  • 10. Referencias

1. ¿Por qué ZKPs en Ethereum

Las Zero-Knowledge Proofs (ZKPs) permiten demostrar la validez de una afirmación sin revelar información adicional. En Ethereum, representan una solución potente para:

  • Privacidad: ocultar datos sensibles (identidad, balances).
  • Escalabilidad: rollups zk-rollup que procesan transacciones off-chain y envían una prueba compacta on-chain.
  • Interoperabilidad: verificar datos de otras cadenas sin confianza externa.

2. Tipos de ZKPs: SNARK vs STARK

Existen varias familias de ZKPs las más populares en Ethereum son:

  • zk-SNARK: pruebas pequeñas, verificación rápida, requieren fase de confianza (trusted setup).
  • zk-STARK: sin fase de confianza, mayor transparencia, pero pruebas más grandes y más lentas de verificar.

En este tutorial nos centraremos en zk-SNARK usando circom y snarkjs.

3. Entorno de desarrollo y herramientas

Antes de comenzar, asegúrate de contar con lo siguiente:

Herramienta Versión Recomendada Instalación
Node.js npm >= 14 https://nodejs.org
circom 2.x npm install -g circom
snarkjs 0.5.x npm install -g snarkjs
Hardhat >=2.0 npm install –save-dev hardhat
Solidity ^0.8.0 Incluido en Hardhat

4. Creación de circuitos con circom

Un circuito define la relación matemática entre entradas y salidas. Vamos a desarrollar un ejemplo de prueba de preimagen de hash con MiMC.

4.1. Archivo mixtHash.circom

component main { public [out] private [in] }
template MiMCCircuit() {
    signal input in
    signal output out
    // iteraciones de MiMC
    var rounds = 91
    var c = 0
    signal x = in
    for (var i = 0 i < rounds i  ) {
        x <== (x   c)  3
        c  
    }
    out <== x
}
instantiate main = MiMCCircuit()
  

Este circuito toma un in privado y genera un out público.

4.2. Compilar el circuito

 circom mimc.circom --r1cs --wasm --sym -o build
  

Obtendrás:

  • build/mimc.r1cs: definición del circuito.
  • build/mimc.wasm: para generar el testigo.
  • build/mimc.sym: símbolos útiles para debugging.

5. Configuración de la fase de confianza

La construcción Groth16 requiere un Trusted Setup. Usaremos snarkjs:

  1. Inicialización de Phase 1 (Powers of Tau):
 snarkjs powersoftau new bn128 12 pot12_0000.ptau
 snarkjs powersoftau contribute pot12_0000.ptau pot12_0001.ptau --name=First contribution
# repetir varias contribuciones para mayor seguridad...
 snarkjs powersoftau prepare phase2 pot12_0001.ptau pot12_final.ptau
  
  1. Generación de claves específicas del circuito:
 snarkjs groth16 setup build/mimc.r1cs pot12_final.ptau mimc_0000.zkey
 snarkjs zkey contribute mimc_0000.zkey mimc_final.zkey --name=Key Contributor
 snarkjs zkey export verificationkey mimc_final.zkey verification_key.json
  

6. Generación de pruebas y test off-chain

Con las claves listas, se puede generar el testigo y la prueba:

  1. Calcular el testigo usando el WASM:
 node build/mimc_js/generate_witness.js build/mimc_js/mimc.wasm input.json witness.wtns
  

Donde input.json contiene:

{
  in: 123456
}
  
  1. Generar la prueba y los parámetros públicos:
 snarkjs groth16 prove mimc_final.zkey witness.wtns proof.json public.json
  
  • Verificar localmente:
  •  snarkjs groth16 verify verification_key.json public.json proof.json
      

    Si todo es correcto, la prueba es válida y lista para llevarse a la blockchain.

    7. Smart contract verificador en Solidity

    snarkjs puede generar un contrato de verificación:

     snarkjs zkey export solidityverifier mimc_final.zkey Verifier.sol
      

    Ejemplo de uso en Solidity:

    pragma solidity ^0.8.0
    
    import ./Verifier.sol
    
    contract MiMCSnark {
        Verifier public verifier
    
        constructor(address _verifier) {
            verifier = Verifier(_verifier)
        }
    
        function verifyProof(
            uint[2] memory a,
            uint[2][2] memory b,
            uint[2] memory c,
            uint[1] memory input
        ) external view returns (bool) {
            return verifier.verifyProof(a, b, c, input)
        }
    }
      

    8. Despliegue y verificación on-chain

    Usando Hardhat, configura el script de despliegue:

    // scripts/deploy.js
    async function main() {
      const Verifier = await ethers.getContractFactory(Verifier)
      const verifier = await Verifier.deploy()
      await verifier.deployed()
    
      const MiMCSnark = await ethers.getContractFactory(MiMCSnark)
      const mimc = await MiMCSnark.deploy(verifier.address)
      await mimc.deployed()
    
      console.log(Verifier:, verifier.address)
      console.log(MiMCSnark:, mimc.address)
    }
    main()
      

    Ejecuta:

     npx hardhat run scripts/deploy.js --network goerli
      

    Luego, desde un script o frontend puedes llamar a verifyProof pasando los datos de proof.json y public.json.

    9. Buenas prácticas y optimización

    • Minimizar inputs públicos: más valores públicos aumentan el gas.
    • Batch proofs: agrupar varias pruebas en una sola transacción.
    • Verificación off-chain: usar relayers o oráculos para disminuir costos.
    • Auditorías: revisar circuitos y contratos, especialmente la fase de confianza.

    10. Referencias

    Con este tutorial práctico tienes todas las piezas para implementar ZKPs en Ethereum: desde crear y compilar circuitos, generar la confianza, construir y desplegar contratos de verificación, hasta las recomendaciones de optimización. ¡Adelante y construye la próxima generación de dApps privadas y escalables!


    Comentarios

    Deja una respuesta

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