Introduction
Zero-knowledge proofs (ZKPs) enable privacy-preserving verification of information, and Circom is a popular tool for building ZK circuits. In this tutorial, we’ll create a simple circuit that takes two inputs and computes their sum and product. This hands-on approach will introduce you to key concepts like defining inputs, constraints, and generating proofs. By the end, you’ll have a solid foundation to start building more complex zero-knowledge circuits using Circom.
Revisiting Key Concepts
- Prover and Verifier: The prover generates a proof that the verifier can use to confirm a statement’s validity without learning any details.
- Proof: A piece of cryptographic evidence that convinces the verifier.
- Witness: Hidden input data used to construct the proof.
- Circuit: A set of logical steps used to create a proof. It defines how the inputs relate to the outputs.
- Constraint System: Rules combining inputs using mathematical and cryptographic operations.
- Trusted Setup: A one-time process to generate cryptographic keys for the prover and verifier to use.
The combination of these elements allows zero-knowledge proofs to provide privacy, security, and verification without revealing sensitive information.
To learn more, read this introduction
Introduction to Zero-Knowledge Proofs
Tools and Environment Setups.
To build and run ZKPs, you’ll need the following tools installed on your system:
Note: you can use zkREPL as a faster and easier web based editor with built in circom compiler.
- Node.js: JavaScript runtime to run SnarkJS scripts.
- Rust: Used to compile Circom.
- Circom: A specialized programming language for ZK circuits.
- SnarkJS: A JavaScript library for generating and verifying ZKP proofs.
Step 1: Install Prerequisites
- Install Rust
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh source $HOME/.cargo/env
rustc --version # Verify installation
- Install Circom
git clone https://github.com/iden3/circom.git
cd circom
cargo build --release
cargo install --path circom
circom --version # Verify installation
- Install Node.js and SnarkJS
sudo apt install nodejs npm # Install Node.js
npm install -g snarkjs # Install SnarkJS
Project Setup
Folder Structure
ZK-Tutorial/
├── circuits/
│ └── sumproduct.circom
├── input/
│ └── input.json
├── output/
│ └── (Generated files here)
Building the Circuit
Create a file called sumproduct.circom in the circuits/ folder.
sumproduct.circom
pragma circom 2.0;
// Define the circuit template
template SumProduct() {
// Define inputs and outputs using the 'signal' keyword
signal input a;
signal input b;
signal output sum;
signal output product;
// Define constraints for the operations
sum <== a + b; // Constrain sum to be a + b
product <== a * b; // Constrain product to be a * b
}
// Export the circuit as a component
component main = SumProduct();
Explanation of Key Elements
-
Inputs and Outputs: Inputs (a, b) and outputs (sum, product) are declared as signals. Inputs are values that the prover provides, while outputs are computed using constraints.
-
Constraints: Constraints define the relationships between inputs and outputs. Here, sum is constrained to be equal to
a + b,
and product is constrained to be equal toa * b
. -
Circuit Template: The
SumProduct
template describes the logic of the circuit, and the main component serves as the entry point for the circuit.
Basically, the prover will prove to the verifier that he/she knows an input a
and b
that will product the output sum
and product
with the given constraints.
Compiling the Circuit
Run the following command to compile the circuit:
circom circuits/sumproduct.circom --r1cs --wasm --sym -o output
Let’s look at each file:
-
–r1cs: Generates the Rank 1 Constraint System (R1CS) file.
-
–wasm: Outputs a WebAssembly file for computation.
-
–sym: Outputs a symbol file for debugging.
-
-o output/: Specifies the output directory.
Check for the following files in output/:
- sumproduct.r1cs: The constraint system file.
-
sumproduct.wasm: The WebAssembly file.
-
sumproduct.sym: The symbol file for debugging.
Generating Trusted Setup
Generate the keys for the prover and verifier:
wget https://hermez.s3-eu-west-1.amazonaws.com/powersOfTau28_hez_final_10.ptau -O outputs/pot10.ptau
snarkjs groth16 setup outputs/sum_product.r1cs outputs/pot10.ptau outputs/sum_product_final.zkey
Export the Verification Key
snarkjs zkey export verificationkey outputs/sum_product_final.zkey outputs/verification_key.json
Creating Inputs
Create an input file input/input.json
with the following content:
{
"a": "3",
"b":"4"
}
These Inputs will be used to generate the proof.
Generating the Proof
node outputs/sum_product_js/generate_witness.js outputs/sum_product_js/sum_product.wasm inputs/input.json outputs/witness.wtns
snarkjs groth16 prove outputs/sum_product_final.zkey outputs/witness.wtns outputs/proof.json outputs/public.json
snarkjs groth16 verify outputs/verification_key.json outputs/public.json outputs/proof.json
If everything is setup correctly, you should see:
snarkJS: OK!
Summary
-
Design the Circuit: Create the logic of the proof in a Circom file.
-
Compile the Circuit: Convert the logic to constraint systems and WebAssembly files.
-
Generate Trusted Setup: Produce keys for the prover and verifier.
-
Input Data: Provide the inputs for the computation.
-
Generate Witness: Produce intermediate computation results.
-
Generate Proof: Create a proof from the witness.
-
Verify Proof: Use the verifier to check the proof’s validity.
Conclusion
Congratulations! You’ve completed a hands-on implementation of zero-knowledge proofs. This process may seem complex initially, but as you create more advanced circuits, you’ll see how useful ZKPs can be for privacy-preserving computation.
We encourage you to continue your exploration of topics on zk proofs. If you’re interested in diving deeper, you can follow up on the pathway here Zero-Knowledge Proofs on the Celo Blockchain: A Comprehensive Tutorial Series - Pathways - Celo Academy
Resources
Circom docs
SnarkJS
0xparc Circom Workshop
youtube video on zk
About the author
I’m Jonathan Iheme, A full stack block-chain Developer from Nigeria. With a great passion for Zero Knowledge Technology.