ℹ️ Are you a Circuit Breaker hacker? Join the Scroll telegram, find project ideas and join our telegram group by visiting our Circuit Breaker cheat sheet
Zokrates
Instalation
curl -LSfs get.zokrat.es | sh
export PATH=$PATH:/home/YOURUSERNAME/.zokrates/bin
Generate a proof
Create the zokrates circuit file.
root.zok
def main(private field a, field b) {
assert(a * a == b);
return;
}
Now compile it and generate a proof.
zokrates compile -i root.zok
zokrates setup
zokrates compute-witness -a 3 9
zokrates generate-proof
The proof is now located in proof.json
.
Verify the proof
Generate a solidity verifier.
zokrates export-verifier
This will generate the verifier.sol
contract. Now deploy it and pass it's address as constructor parameter to the following contract with custom solidity logic.
// SPDX-License-Identifier: MIT
pragma solidity >=0.7.0 <0.9.0;
library Pairing {
struct G1Point {
uint X;
uint Y;
}
struct G2Point {
uint[2] X;
uint[2] Y;
}
}
struct Proof {
Pairing.G1Point a;
Pairing.G2Point b;
Pairing.G1Point c;
}
interface IZokratesVerifier {
function verifyTx(Proof memory proof, uint[1] memory input) external view returns (bool r);
}
contract ZokratesCustomLogic {
IZokratesVerifier zokratesVerifier;
uint public publicInput;
constructor(address zokratesVeriferAddress) {
zokratesVerifier = IZokratesVerifier(zokratesVeriferAddress);
}
function sendProof(Proof memory proof, uint[1] memory input) public {
// ZK verification
zokratesVerifier.verifyTx(proof, input);
// Your custom logic
publicInput = input[0];
}
}
Noir
Instalation
On Linux
mkdir -p $HOME/.nargo/bin && \
curl -o $HOME/.nargo/bin/nargo-x86_64-unknown-linux-gnu.tar.gz -L https://github.com/noir-lang/noir/releases/download/v0.22.0/nargo-x86_64-unknown-linux-gnu.tar.gz && \
tar -xvf $HOME/.nargo/bin/nargo-x86_64-unknown-linux-gnu.tar.gz -C $HOME/.nargo/bin/ && \
echo -e '\nexport PATH=$PATH:$HOME/.nargo/bin' >> ~/.bashrc && \
source ~/.bashrc
On MacOs Apple Silicon
mkdir -p $HOME/.nargo/bin && \
curl -o $HOME/.nargo/bin/nargo-aarch64-apple-darwin.tar.gz -L https://github.com/noir-lang/noir/releases/download/v0.22.0/nargo-aarch64-apple-darwin.tar.gz && \
tar -xvf $HOME/.nargo/bin/nargo-aarch64-apple-darwin.tar.gz -C $HOME/.nargo/bin/ && \
echo '\nexport PATH=$PATH:$HOME/.nargo/bin' >> ~/.zshrc && \
source ~/.zshrc
On MacOs Intel
mkdir -p $HOME/.nargo/bin && \
curl -o $HOME/.nargo/bin/nargo-x86_64-apple-darwin.tar.gz -L https://github.com/noir-lang/noir/releases/download/v0.22.0/nargo-x86_64-apple-darwin.tar.gz && \
tar -xvf $HOME/.nargo/bin/nargo-x86_64-apple-darwin.tar.gz -C $HOME/.nargo/bin/ && \
echo '\nexport PATH=$PATH:$HOME/.nargo/bin' >> ~/.zshrc && \
source ~/.zshrc
Generate a proof
Generate a new noir project and prepare it to receive the prover inputs.
nargo new hello_world
cd hello_world
nargo check
Now put the inputs in Prover.toml
and generate the proof.
Prover.toml
x = "1"
y = "2"
nargo prove
The proof is now located at proofs/hello_world.proof
.
Verify the proof
Generate the solidity verifier.
nargo codegen-verifier
The verifier contract is now located at contract/hello_world/plonk_vk.sol
. Deploy it and send it's address as param to the following contract with custom logic.
// SPDX-License-Identifier: MIT
pragma solidity >=0.7.0 <0.9.0;
interface INoirVerifier {
function verify(bytes calldata _proof, bytes32[] calldata _publicInputs) external view returns (bool);
}
contract NoirCustomLogic {
INoirVerifier noirVerifier;
uint public publicInput;
constructor(address noirVeriferAddress) {
noirVerifier = INoirVerifier(noirVeriferAddress);
}
function sendProof(bytes calldata _proof, bytes32[] calldata _publicInputs) public {
// ZK verification
noirVerifier.verify(_proof, _publicInputs);
// Your custom logic
publicInput = uint(_publicInputs[0]);
}
}
Circom
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];
}
}
For further information visit the Zokrates, Noir, and Circom official documentation.
Thank you for reading this article!
Follow me on dev.to and on Youtube for everything related to Blockchain development.