Skip to main content
The snarkvm-circuit crate provides circuit equivalents of all console types, enabling zero-knowledge proof generation through constraint system synthesis. It implements the R1CS (Rank-1 Constraint System) framework used by the Marlin proof system.

Architecture

The circuit crate mirrors the structure of the console crate:

Constraint System

R1CS Structure

The circuit crate builds an R1CS constraint system where each constraint has the form:
Where A, B, and C are linear combinations of variables:
Source: circuit/environment/src/helpers/linear_combination.rs:36-42

Variable Types

Circuit variables come in three modes:
Source: circuit/environment/src/helpers/mode.rs:21-25

Console/Circuit Synchronization

The circuit and console crates must remain synchronized. Every console type has a corresponding circuit type with identical structure and API. When modifying one, always update the other.

Inject and Eject Traits

Circuit types convert to/from console types using Inject and Eject:
Source: circuit/environment/src/traits/inject.rs:19-36, circuit/environment/src/traits/eject.rs:18-38

Constraint Counting

The environment tracks resource usage:
Source: circuit/environment/src/helpers/count.rs:26-53

Testing Constraints

Use constraint counting in tests:

R1CS Generation

Enforcing Constraints

The environment provides methods to add constraints:
Source: circuit/environment/src/environment.rs:64-108

Extracting R1CS

Extract the complete constraint system:
Source: circuit/environment/src/environment.rs:183-189, circuit/environment/src/helpers/r1cs.rs:63-71

Environment Scoping

Use scopes to organize constraint generation:
Source: circuit/environment/src/environment.rs:60-62, circuit/environment/src/environment.rs:154-163

Resource Limits

Set limits on circuit size:
Source: circuit/environment/src/environment.rs:165-175

Example: Circuit Synthesis

Best Practices

  1. Always test constraint counts - Use assert_scope! to verify expected resource usage
  2. Minimize constraint generation - Prefer constant operations when possible
  3. Keep console/circuit synchronized - Same structure, same API, same tests
  4. Use scopes for organization - Track resource usage per component
  5. Test satisfaction - Use is_satisfied() to verify constraint correctness

See Also