Overview
Tornado Nova uses zkSNARK (Zero-Knowledge Succinct Non-Interactive Argument of Knowledge) verifiers to validate transaction proofs. The protocol implements two verifier contracts:- Verifier2 - Verifies proofs for transactions with 2 inputs
- Verifier16 - Verifies proofs for transactions with 16 inputs
These verifiers enable privacy by allowing users to prove they own valid inputs without revealing which specific commitments they’re spending.
IVerifier Interface
Both verifier contracts implement theIVerifier interface:
uint256[7]- For 2-input transactions (Verifier2)uint256[21]- For 16-input transactions (Verifier16)
Verifier2 Contract
Purpose
Verifier2 handles the most common transaction type with 2 input nullifiers. This is optimized for:- Standard deposits
- Simple transfers
- Small withdrawals
- Gas-efficient operations
Proof Structure
The proof verification requires 7 public inputs:Merkle Root - The root of the commitment tree, proving inputs exist in the tree
Public Amount - The amount being deposited or withdrawn, calculated from extAmount and fee
External Data Hash - Hash of the ExtData structure, binding transaction metadata to the proof
Input Nullifier 1 - First nullifier, proving ownership of first input
Input Nullifier 2 - Second nullifier, proving ownership of second input
Output Commitment 1 - First output commitment to be added to the tree
Output Commitment 2 - Second output commitment to be added to the tree
Usage in TornadoPool
The TornadoPool contract calls Verifier2 when the proof has 2 input nullifiers:Gas Efficiency
Verifier2 is the most gas-efficient verifier, typically using ~250,000-300,000 gas per verification.
Verifier16 Contract
Purpose
Verifier16 handles transactions with up to 16 input nullifiers, enabling:- Consolidation of many small notes
- Large withdrawals from multiple deposits
- Batch operations
- UTXO management
Proof Structure
The proof verification requires 21 public inputs:Usage in TornadoPool
Gas Considerations
Proof Generation
While the verifier contracts are on-chain, proof generation happens off-chain using the Circom circuits:- Circuit Definition - Defines the constraints that must be satisfied
- Witness Generation - Computes private and public inputs
- Proof Generation - Creates the zkSNARK proof using a proving key
- On-Chain Verification - Verifier contract checks the proof
What the Proof Demonstrates
The zero-knowledge proofs prove the following without revealing private data:- Input Ownership: The prover knows the private keys for the input commitments
- Merkle Membership: The inputs exist in the commitment tree
- Nullifier Correctness: Nullifiers are correctly derived from inputs
- Output Validity: Output commitments are properly constructed
- Amount Consistency: Input amounts equal output amounts plus public amount
Security Properties
Soundness
A malicious prover cannot create a valid proof for an invalid statement. The cryptographic security is based on the hardness of the discrete logarithm problem over elliptic curves.
Zero-Knowledge
The proof reveals nothing about:- Which commitments are being spent
- The amounts of individual inputs/outputs
- The relationship between transactions
- The sender’s identity
Completeness
Any valid proof will be accepted by the verifier:Elliptic Curve: BN254
Both verifiers use the BN254 (also called alt-bn128) elliptic curve, which:- Is supported natively by Ethereum’s precompiled contracts
- Provides ~128-bit security level
- Has a scalar field size of:
Verification Process Flow
Example: Verifying a 2-Input Transaction
Trusted Setup
The verifier contracts are generated from:- Circuit compilation - Circom circuits → R1CS constraints
- Powers of Tau ceremony - Generates common reference string
- Circuit-specific setup - Generates proving and verification keys
- Verifier generation - Creates Solidity verifier contract
Upgrading Verifiers
The verifier addresses are set as
immutable in the TornadoPool constructor and cannot be changed after deployment. Any verifier upgrades would require deploying a new TornadoPool contract.Performance Comparison
| Verifier | Inputs | Gas Cost | Use Case |
|---|---|---|---|
| Verifier2 | 2 | ~250-300k | Standard transactions |
| Verifier16 | 16 | ~800k-1M | Note consolidation |