Skip to content

DADADAVE80/metacrafters-polygon-zkEVM

Repository files navigation

zardkat 🐱 –
Logic gate verifier with zero-knowledge proofs

This is a clone of the hardhat-circom template to generate zero-knowledge circuits, proofs, and solidity verifiers

Quick Start

This template contains a circuit code for calculating the result of two numbers passed into logic gates.
PS: The circuit is named Multiplier2() but it's not a multiplier, it's just a simple example to show how logic gates are used in a circuit.

pragma circom 2.0.0;

/*This circuit takes in two values A and B, then passes it into logic gates*/

template Multiplier2 () {  

   // Signal inputs
   signal input A;
   signal input B;

   // Internal signals from gates
   signal X;
   signal Y;

   // Final signal output
   signal output Q;

   // Component gates
   component andGate = AND();
   component orGate = OR();
   component notGate = NOT();

   // Circuit logic
   // AND gate
   andGate.a <== A;
   andGate.b <== B;
   X <== andGate.out;

   // NOT gate
   notGate.in <== B;
   Y <== notGate.out;

   // OR gate
   orGate.a <== X;
   orGate.b <== Y;

   Q <== orGate.out;
}

template AND() {
    signal input a;
    signal input b;
    signal output out;

    out <== a*b;
}

template OR() {
    signal input a;
    signal input b;
    signal output out;

    out <== a + b - a*b;
}

template NOT() {
    signal input in;
    signal output out;

    out <== 1 + in - 2*in;
}

component main = Multiplier2();

Install dependencies

npm i

Compile the circuit

npx hardhat circom This will generate the out file with circuit intermediaries and geneate the MultiplierVerifier.sol contract

Prove and Deploy

npx hardhat run scripts/deploy.ts This script does 4 things

  1. Deploys the MultiplierVerifier.sol contract
  2. Generates a proof from circuit intermediaries with generateProof()
  3. Generates calldata with generateCallData()
  4. Calls verifyProof() on the verifier contract with calldata

With two commands you can compile a ZKP, generate a proof, deploy a verifier, and verify the proof 🎉

Configuration

Directory Structure

circuits

├── multiplier
│   ├── circuit.circom
│   ├── input.json
│   └── out
│       ├── circuit.wasm
│       ├── multiplier.r1cs
│       ├── multiplier.vkey
│       └── multiplier.zkey
├── new-circuit
└── powersOfTau28_hez_final_12.ptau

Each new circuit lives in it's own directory. At the top level of each circuit directory lives the circom circuit and input to the circuit. The out directory will be autogenerated and store the compiled outputs, keys, and proofs. The Powers of Tau file comes from the Polygon Hermez ceremony, which saves time by not needing a new ceremony.

contracts

contracts
└── MultiplierVerifier.sol

Verifier contracts are autogenerated and prefixed by the circuit name, in this example Multiplier

hardhat.config.ts

  circom: {
    // (optional) Base path for input files, defaults to `./circuits/`
    inputBasePath: "./circuits",
    // (required) The final ptau file, relative to inputBasePath, from a Phase 1 ceremony
    ptau: "powersOfTau28_hez_final_12.ptau",
    // (required) Each object in this array refers to a separate circuit
    circuits: JSON.parse(JSON.stringify(circuits))
  },
  networks: {
    mumbai: {
      url: process.env.MUMBAI_RPC_URL,
      accounts: [`${process.env.PRIVATE_KEY}`],
    },
    goerli: {
      url: process.env.GOERLI_RPC_URL,
      accounts: [`${process.env.PRIVATE_KEY}`],
    },
    sepolia: {
      url: process.env.SEPOLIA_RPC_URL,
      accounts: [`${process.env.PRIVATE_KEY}`],
    },
  },
  etherscan: {
    apiKey: process.env.ETHERSCAN_API_KEY,
  },

circuits.config.json

circuits configuation is separated from hardhat.config.ts for autogenerated purposes (see next section)

[
  {
    "name": "multiplier",
    "protocol": "groth16",
    "circuit": "multiplier/circuit.circom",
    "input": "multiplier/input.json",
    "wasm": "multiplier/out/circuit.wasm",
    "zkey": "multiplier/out/multiplier.zkey",
    "vkey": "multiplier/out/multiplier.vkey",
    "r1cs": "multiplier/out/multiplier.r1cs",
    "beacon": "0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f"
  }
]

adding circuits
To add a new circuit, you can run the newcircuit hardhat task to autogenerate configuration and directories i.e

npx hardhat newcircuit --name newcircuit

determinism

When you recompile the same circuit using the groth16 protocol, even with no changes, this plugin will apply a new final beacon, changing all the zkey output files. This also causes your Verifier contracts to be updated. For development builds of groth16 circuits, we provide the --deterministic flag in order to use a NON-RANDOM and UNSECURE hardcoded entropy (0x000000 by default) which will allow you to more easily inspect and catch changes in your circuits. You can adjust this default beacon by setting the beacon property on a circuit's config in your hardhat.config.js file.

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published