Skip to main content
SnarkVM uses zero-knowledge proofs to enable private, verifiable computation on the Aleo blockchain. This page explains how SnarkVM implements SNARKs, from circuit constraints to proof generation and verification.

What are Zero-Knowledge Proofs?

A zero-knowledge proof allows a prover to convince a verifier that a statement is true without revealing any information beyond the truth of the statement itself.

Properties of SNARKs

SnarkVM uses SNARKs (Succinct Non-interactive Arguments of Knowledge):
  • Succinct: Proofs are small (~few KB) regardless of computation size
  • Non-interactive: No back-and-forth between prover and verifier
  • Arguments of Knowledge: Prover must actually know the witness
  • Zero-Knowledge: Proof reveals nothing about private inputs

Use Cases in Aleo

  • Private Transactions: Transfer tokens without revealing amounts or addresses
  • Private Programs: Execute arbitrary logic with hidden inputs
  • Proof-Carrying Data: Chain proofs to create complex privacy-preserving applications
  • Verifiable Computation: Prove correct execution without re-running

R1CS Constraint Systems

Rank-1 Constraint System

SnarkVM represents circuits as R1CS (Rank-1 Constraint System), the standard representation for SNARK circuits. Each constraint has the form:
Where A, B, C are linear combinations of variables:

Variables and Witnesses

From algorithms/src/r1cs/mod.rs:54:
Variable Types:
  • Public Variables: Known to both prover and verifier (public inputs/outputs)
  • Private Variables: Known only to prover (private witness)
  • Constants: Fixed values compiled into circuit

Linear Combinations

From algorithms/src/r1cs/linear_combination.rs:
Example: The expression 3 + 2·x₁ + 5·x₂ is:

Constraint System Trait

From algorithms/src/r1cs/constraint_system.rs:23:

Circuit Construction

From Operations to Constraints

Consider the computation result = (a + b) * (c + d): Step 1: Decompose
Step 2: Generate Constraints Additions are free (linear combinations):
Multiplication requires a constraint:
Total Cost: 1 constraint (only the multiplication)

Example: Field Multiplication

From circuit/types/field/src/mul.rs:
This generates the constraint: self * other = output

Cost Model

Proof generation time is roughly linear in constraint count. Minimize multiplications and comparisons to optimize circuit performance.

Varuna SNARK System

SnarkVM uses Varuna, a polynomial-based SNARK system implementing the AHP (Algebraic Holographic Proof) framework.

Architecture

From algorithms/src/snark/varuna/mod.rs:16:

Components

1. Structured Reference String (SRS) Universal setup generating public parameters:
2. Proving Key Circuit-specific key for proof generation:
3. Verifying Key Circuit-specific key for proof verification:
4. Proof Succinct proof of computation:

Proof Generation Flow

Polynomial Commitment Scheme

Varuna uses polynomial commitments to achieve succinctness:
  1. Commit: Prover commits to witness polynomials (few KB)
  2. Query: Verifier challenges prover at random points
  3. Open: Prover provides evaluations and opening proofs
  4. Verify: Verifier checks commitments match opened values
Polynomial commitments compress large witness data into small commitments, enabling succinct proofs.

Program Execution and Proving

Stack and Process

From synthesizer/process/src/stack/mod.rs:211:
Each program function has its own proving/verifying key pair.

Execution Modes

From synthesizer/process/src/stack/mod.rs:103:
Evaluate Mode: Fast plaintext execution
Execute Mode: Generate proof

Proof Generation Steps

  1. Evaluation: Run console types to compute output
  2. Injection: Convert console values to circuit variables
  3. Synthesis: Execute circuit, generating constraints
  4. Witness Assignment: Populate all variables with values
  5. AHP Proving: Convert R1CS to algebraic holographic proof
  6. Polynomial Commitment: Commit to witness polynomials
  7. Proof Assembly: Package commitments and evaluations

Proof Verification Steps

  1. Parse Public Inputs: Extract public variables from proof
  2. Circuit Verification: Check proof against verifying key
  3. Polynomial Checks: Verify polynomial commitment openings
  4. Output Validation: Ensure outputs match public values

Cryptographic Primitives

Elliptic Curves

SnarkVM uses BLS12-377 for pairing-based cryptography:
Properties:
  • 128-bit security level
  • Efficient pairing computation
  • Edwards curve (EdDSA) compatible scalar field

Hash Functions

SnarkVM uses Poseidon hash for circuit-friendly hashing:
Benefits:
  • Designed for SNARK circuits
  • Low constraint count (~150 constraints per hash)
  • Collision-resistant and one-way

Performance Characteristics

Typical Proof Times

Proof size is nearly constant (~logarithmic growth), while proving time is linear in constraint count.

Verification Performance

  • Verification Time: ~1-10ms (independent of circuit size)
  • Verification Cost: Dominated by pairing computations
  • Batch Verification: Amortized cost for verifying multiple proofs

Optimization Strategies

Circuit-Level Optimizations

  1. Minimize Multiplications: Each multiplication = 1 constraint
  2. Reuse Computations: Cache intermediate results
  3. Algebraic Tricks: Use field properties (e.g., Fermat’s little theorem for inversion)
  4. Boolean Packing: Pack multiple booleans into field elements

System-Level Optimizations

  1. Parallel Proving: Leverage multi-core CPUs
  2. GPU Acceleration: Use CUDA for MSM and FFT
  3. Caching: Precompute proving keys for common circuits
  4. Batch Processing: Generate multiple proofs in parallel

Example: Optimized Range Proof

Naive Approach (O(bits) constraints):
Optimized Approach (O(log bits) constraints):

Security Considerations

Trusted Setup

Varuna requires a universal trusted setup:
  • One-time ceremony generating SRS
  • Universal parameters for all circuits
  • Security relies on at least one honest participant
If all trusted setup participants are malicious, they could create false proofs. The ceremony must be performed securely with multiple independent parties.

Soundness

SNARK soundness ensures:
  • Invalid proofs are rejected with overwhelming probability
  • Prover cannot convince verifier of false statements
  • Security based on cryptographic assumptions (e.g., discrete log)

Zero-Knowledge

Proofs reveal:
  • Public Inputs: Intentionally disclosed (e.g., transaction outputs)
  • Public Outputs: Computation results
  • Nothing Else: Private witnesses remain hidden

Best Practices

For Circuit Design

  1. Profile First: Measure constraint counts before optimizing
  2. Test Soundness: Verify invalid inputs are rejected
  3. Validate Ranges: Ensure integers stay within bounds
  4. Check Edge Cases: Test zero, max, and boundary values

For Program Development

  1. Minimize Circuit Operations: Use console types where possible
  2. Batch Transactions: Amortize proof costs across multiple operations
  3. Cache Proving Keys: Avoid regenerating keys repeatedly
  4. Monitor Constraint Growth: Track circuit size as programs evolve

Debugging Circuits

Constraint Counting

Witness Inspection

Constraint Checking

Further Reading

Overview

Return to core concepts overview

Console & Circuit

Understand the dual type system

Quick Start

Build your first program

API Reference

Explore the API documentation