A comprehensive exploration of ZK proof systems, from fundamentals to production implementations
Status: Active Learning Project
Last Updated: December 2025
Goal: Master ZK systems for architect-level positions
This repository documents a deep dive into zero-knowledge proof systems, covering multiple frameworks, proof systems, and practical implementations. The project demonstrates both theoretical understanding and practical engineering skills across the ZK stack.
- ✅ Multi-Framework Mastery: Implementations in Circom (Groth16), Noir (PLONK), and Halo2 (PLONK)
- ✅ Production-Ready Circuits: Working Sudoku solver and Merkle tree membership proofs
- ✅ Comprehensive Documentation: 2000+ lines of deep technical documentation
- ✅ Framework Comparison: Quantitative analysis of Groth16 vs PLONK (99x constraint difference)
- ✅ Low-Level Understanding: Custom gates and constraint systems in Halo2
- ✅ Full Stack Integration: Solidity verifiers, Hardhat deployment, on-chain verification
Goal: Understand core ZK concepts and Groth16 protocol
- Framework: Circom (Groth16)
- Circuit: 81-cell Sudoku verification
- Features:
- Range checks (1-9)
- Row/column/block constraints
- Public puzzle, private solution
- Output: Complete workflow (compile → setup → prove → verify → deploy)
- Language: Rust (arkworks)
- Purpose: Low-level Groth16 verification implementation
- Features:
- Pairing-based verification
- G1/G2 point parsing
- Public input commitment computation
Documentation: doc/groth.md - 1800+ lines covering:
- Mathematical foundations (QAP, R1CS, pairings)
- Step-by-step protocol explanation
- Security analysis
- Interview Q&A
- Optimization strategies
Goal: Compare proof systems using the same problem
- Framework: Circom
- Circuit: Merkle membership proof (depth 3)
- Hash: Poseidon
- Constraints: 2,387
- Features:
- Full Hardhat integration
- Solidity verifier deployment
- On-chain proof verification
- Incremental Merkle tree contract
- Framework: Noir (Aztec)
- Circuit: Same Merkle proof
- Hash: Poseidon2
- Opcodes: 24
- Result: 99x fewer constraints than Groth16!
- Framework: Halo2 (low-level PLONK)
- Language: Rust
- Features:
- Custom swap gate for path selection
- Binary constraint enforcement
- Manual circuit layout
- Comprehensive test suite
Documentation: doc/plonk.md - Complete comparison guide:
- Groth16 vs PLONK analysis
- Constraint efficiency breakdown
- Use case recommendations
- Performance benchmarks
| Metric | Groth16 (Circom) | PLONK (Noir) | Winner |
|---|---|---|---|
| Constraints/Opcodes | 2,387 | 24 | PLONK (99x) |
| Proof Size | 192 bytes | ~400 bytes | Groth16 (2x) |
| Verification Time | ~5ms | ~20ms | Groth16 (4x) |
| Setup Type | Circuit-specific | Universal | PLONK |
| Custom Gates | No | Yes | PLONK |
Key Insight: PLONK's custom gates provide massive efficiency gains for operations like Poseidon hashing, while Groth16 maintains advantages in proof size and verification speed.
Full Analysis: See doc/plonk.md for detailed breakdown.
# Circom (Groth16)
npm install -g circom snarkjs
# Noir (PLONK)
curl -L https://raw.githubusercontent.com/noir-lang/noirup/main/install | bash
noirup
# Halo2 (PLONK)
cargo install --git https://github.com/zcash/halo21. Sudoku (Groth16):
cd 01-basics/sudoku
./run.sh # Compile, setup, prove, verify2. Merkle Tree (Groth16):
cd 02-merkle/02-01-circom
npm install
./setup.sh # Trusted setup
node scripts/1_deploy.js # Deploy contracts
node scripts/3_prove.js # Generate proof3. Merkle Tree (Noir):
cd 02-merkle/02-02-noir
nargo prove # Generate PLONK proof4. Merkle Tree (Halo2):
cd 02-merkle/02-03-halo2
cargo test # Run test suite-
Groth16 Deep Dive - Complete mathematical and practical guide
- R1CS → QAP transformation
- Trusted setup ceremony
- Pairing-based verification
- Security analysis
- Interview preparation
-
PLONK vs Groth16 - Comprehensive comparison
- Constraint efficiency analysis
- Use case recommendations
- Performance benchmarks
- Trade-off analysis
- Halo2 Merkle Proof - Low-level PLONK implementation
- Custom gate design
- Circuit layout
- Constraint system explanation
- Production patterns
- zk-Email - Email-based anonymous credentials
- zk-TLS - TLS certificate verification in ZK
- Recursion & zkVM Guide - Implementation roadmap for advanced topics
ZKP/
├── 00-tools/ # Setup scripts and utilities
│ ├── circom/ # Circom installation
│ └── poseidon/ # Poseidon hash contracts
│
├── 01-basics/ # Fundamentals
│ ├── groth16/ # Rust verifier implementation
│ └── sudoku/ # Complete Groth16 workflow
│
├── 02-merkle/ # Multi-framework comparison
│ ├── 02-01-circom/ # Groth16 implementation
│ ├── 02-02-noir/ # PLONK (Noir) implementation
│ └── 02-03-halo2/ # PLONK (Halo2) implementation
│
├── doc/ # Comprehensive documentation
│ ├── groth.md # Groth16 complete guide
│ └── plonk.md # PLONK vs Groth16 comparison
│
└── etc/ # Research and notes
├── zk-email.md # Email-based ZK credentials
└── zk-TLS.md # TLS verification in ZK
└── recursion.md # Proof recursion/aggregation
└── zk-vm.md # Basics of zkVM
- ✅ Mathematical Foundations: QAP, R1CS, pairings, polynomial commitments
- ✅ Protocol Design: Trusted setup ceremonies, proof generation, verification
- ✅ Security Analysis: Cryptographic assumptions, threat models, mitigations
- ✅ Optimization: Constraint minimization, proof size, gas costs
- ✅ Circuit Design: Range checks, hash functions, Merkle trees, custom gates
- ✅ Multi-Framework: Circom, Noir, Halo2 - understanding trade-offs
- ✅ Full Stack: Solidity verifiers, Hardhat deployment, on-chain verification
- ✅ Low-Level: Manual constraint systems, custom gates, circuit layout
- ✅ Gas Optimization: Understanding verification costs
- ✅ Setup Management: Trusted setup ceremonies
- ✅ Security Best Practices: Nullifiers, replay prevention, key management
- ✅ Tooling: snarkjs, circom, nargo, arkworks
Implemented a custom swap gate for conditional path selection in Merkle trees:
// Binary constraint: path_index * (1 - path_index) = 0
// Conditional selection: left = current * (1 - path_index) + sibling * path_indexThis demonstrates deep understanding of PLONK's constraint system.
Quantitative analysis showing:
- 99x constraint difference between Groth16 and PLONK for Poseidon hashing
- Trade-offs: proof size vs. circuit flexibility
- When to use which system
- Incremental Merkle trees (on-chain)
- Nullifier-based replay prevention
- Poseidon hash integration
- Solidity verifier deployment
Why: Essential for zkRollups, proof batching, and scaling ZK systems.
Recommended Implementation:
- Simple Aggregator: Verify 2-4 Groth16 proofs in a PLONK circuit
- Framework: Halo2 (cycle-friendly curves) or Plonky2
- Goal: Demonstrate proof-of-proof concept
- Complexity: Medium (requires verifier circuit)
Learning Path:
03-recursion/
├── 03-01-simple-aggregator/ # Verify 2 proofs → 1 proof
│ ├── circuits/
│ │ └── aggregator.rs # Halo2 verifier circuit
│ └── tests/
│ └── aggregation_test.rs
├── 03-02-batch-verifier/ # Verify N proofs efficiently
└── README.md # Recursion deep dive
Key Concepts:
- Verifier circuit design (~1K-30K constraints)
- Cycle-friendly curves (Pasta: Pallas/Vesta)
- Proof compression (N proofs → 1 proof)
- Gas optimization (250K → 25K per proof)
Why: Foundation of zkEVM, zkWASM, and general-purpose ZK computation.
Recommended Implementation:
- TinyVM: Simple stack-based VM (10-20 instructions)
- Instructions: ADD, MUL, PUSH, POP, JUMP, CALL
- Framework: Halo2 or Circom
- Goal: Understand VM → circuit compilation
Learning Path:
04-zkvm/
├── 04-01-tiny-vm/ # Minimal VM implementation
│ ├── src/
│ │ ├── vm.rs # VM state machine
│ │ ├── instructions.rs # Instruction set
│ │ └── circuit.rs # VM → circuit compiler
│ └── examples/
│ └── fibonacci.rs # Prove Fibonacci computation
├── 04-02-risc-v-basics/ # RISC-V subset (optional)
└── README.md # zkVM architecture guide
Key Concepts:
- Instruction encoding
- State transitions (registers, memory, stack)
- Program counter management
- Memory access patterns
- Loop unrolling vs. recursion
- Lookup tables (Plookup) - Efficient range checks
- Performance benchmarks - Actual numbers for all implementations
- More production patterns (ECDSA, range proofs)
- STARKs (transparent setup) - Alternative to SNARKs
- Nova (incremental verifiable computation) - Advanced recursion
- Custom gate optimizations - Domain-specific efficiency
- Groth16: "On the Size of Pairing-based Non-interactive Arguments" (2016)
- PLONK: "PLONK: Permutations over Lagrange-bases..." (2019)
- Poseidon: "Poseidon: A New Hash Function for Zero-Knowledge Proof Systems"
- Circom - Circuit compiler
- snarkjs - Proof generation
- Noir - High-level PLONK language
- Halo2 - Low-level PLONK framework
- arkworks - Rust ZK library
✅ Best for:
- Proof size is critical (blockchain storage)
- Verification speed matters (gas optimization)
- Circuit is stable (few updates)
- Production-ready systems
Examples: Zcash, Tornado Cash, Filecoin
✅ Best for:
- Circuit evolves frequently
- Need custom gates (efficiency)
- Multiple circuits in system
- Planning recursion/aggregation
Examples: zkSync Era, Aztec Network, Polygon zkEVM
- Groth16: Smaller proofs, faster verification, but circuit-specific setup
- PLONK: Universal setup, custom gates, but larger proofs
The choice depends on your constraints - proof size vs. circuit flexibility.
This project demonstrates:
- Depth: Understanding ZK systems from mathematical foundations to implementation
- Breadth: Multiple frameworks and proof systems
- Production Awareness: Full-stack integration, gas optimization, security
- Analytical Thinking: Quantitative comparisons, trade-off analysis
- Documentation: Comprehensive guides suitable for team knowledge sharing
✅ Completed:
- Groth16 (Circom) - Production-ready implementation
- PLONK (Noir) - High-level framework
- PLONK (Halo2) - Low-level with custom gates
- Framework comparison with quantitative analysis
- Full-stack integration (Solidity, Hardhat)
- Proof recursion/aggregation (see
etc/recursion.md) - zkVM basics (see
etc/zk-vm.md)
Note: Recursion and zkVM are documented with implementation roadmaps. These are the next logical additions for architect-level completeness.
Suitable for: ZK Architect, Senior ZK Engineer, Protocol Engineer roles
This is a personal learning project. Code examples are provided for educational purposes.
- 0xPARC - Excellent learning resources
- Circom Community - Framework and tooling
- Aztec - Noir framework
- Zcash - Halo2 framework
- All ZK researchers - Building the future of privacy
Questions or feedback? This is a learning project - always open to improvements and discussions!
"The best way to learn ZK is to build ZK."