Skip to content

Instantly share code, notes, and snippets.

@Turupawn
Created June 3, 2024 20:23
Show Gist options
  • Save Turupawn/f0671f2c83683a0a6ade4164158bde68 to your computer and use it in GitHub Desktop.
Save Turupawn/f0671f2c83683a0a6ade4164158bde68 to your computer and use it in GitHub Desktop.
Rise In: Intro to ZK Development

Tutorial

Circom

ZK Circom Logo

Installation

curl --proto '=https' --tlsv1.2 https://sh.rustup.rs -sSf | sh
git clone https://github.com/iden3/circom.git
cd circom
cargo build --release
cargo install --path circom
npm install -g snarkjs

Generate a proof

Create the circom circuit file and the inputs that will be passed to it.

multiplier2.circom

pragma circom 2.0.0;

template Multiplier2() {
    signal input a;
    signal input b;
    signal output c;
    c <== a*b;
 }

 component main = Multiplier2();

input.json

{"a": "3", "b": "11"}

Now let's generate the proof.

circom multiplier2.circom --r1cs --wasm --sym --c
node multiplier2_js/generate_witness.js multiplier2_js/multiplier2.wasm input.json witness.wtns
snarkjs powersoftau new bn128 12 pot12_0000.ptau -v
snarkjs powersoftau contribute pot12_0000.ptau pot12_0001.ptau --name="First contribution" -v
snarkjs powersoftau prepare phase2 pot12_0001.ptau pot12_final.ptau -v
snarkjs groth16 setup multiplier2.r1cs pot12_final.ptau multiplier2_0000.zkey
snarkjs zkey contribute multiplier2_0000.zkey multiplier2_0001.zkey --name="1st Contributor Name" -v
snarkjs zkey export verificationkey multiplier2_0001.zkey verification_key.json
snarkjs groth16 prove multiplier2_0001.zkey witness.wtns proof.json public.json
snarkjs groth16 verify verification_key.json public.json proof.json
snarkjs generatecall

The proof will be printed on the terminal.

Verify the proof

Generate the solidity verifier.

snarkjs zkey export solidityverifier multiplier2_0001.zkey verifier.sol

This will generate the verifier.sol contract. Deploy it and passit as constructo parameter to the following custom logic contract.

// SPDX-License-Identifier: MIT

pragma solidity >=0.7.0 <0.9.0;

interface ICircomVerifier {
    function verifyProof(uint[2] calldata _pA, uint[2][2] calldata _pB, uint[2] calldata _pC, uint[1] calldata _pubSignals) external view returns (bool);
}

contract CircomCustomLogic {
    ICircomVerifier circomVerifier;
    uint public publicInput;

    constructor(address circomVeriferAddress) {
        circomVerifier = ICircomVerifier(circomVeriferAddress);
    }

    function sendProof(uint[2] calldata _pA, uint[2][2] calldata _pB, uint[2] calldata _pC, uint[1] calldata _pubSignals) public {
        // ZK verification
        circomVerifier.verifyProof(_pA, _pB, _pC, _pubSignals);

        // Your custom logic
        publicInput = _pubSignals[0];
    }
}

Anonymous chat demo

https://github.com/Turupawn/EcrecoverInclusionProof/

Official documentation

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment