Seyed Masoud Hosseini · Overview · Study log · Ideas · Transcript · RSS feed
Zero Knowledge Proofs · Lecture 3 of 14 · 1:41:38
Lecture 3: Programming Zero Knowledge Proofs
Study guide
What this lecture covers
This lecture answers a practical question left open by the theory: once you have an idea for a zero knowledge application, how do you actually implement it? Pratyush Mishra and Alex Ozdemir walk through the process of turning a high-level predicate into an arithmetic circuit and then into rank-1 constraint systems (R1CS), the format most SNARK provers consume.
The lecture covers three concrete approaches with live tutorials: a hardware description language (Circom), a Rust library (arkworks), and a dedicated compiled language (Zokrates), building a partial Sudoku checker in each. After watching, you should understand what R1CS is, how each tool represents constraints and computes witnesses, and the tradeoffs between the three styles.
Key ideas
- Arithmetic circuit: a directed acyclic graph of addition and multiplication gates over a prime field, used to express the predicate a zero knowledge proof will prove.
- Rank-1 constraint system (R1CS): a set of constraints of the form
alpha * beta = gamma, where each ofalpha,beta,gammais an affine (linear plus constant) combination of variables; equivalently, three matricesA,B,Csuch that(Az) * (Bz) = Cz. - Circom: a hardware description language where signals are R1CS variables and constraints are created explicitly with the
===(or<==) operator; witness values are set separately with<--. - arkworks: a Rust library where a constraint system object tracks variables and constraints, and Rust's type system and operator overloading let developers build higher-level abstractions like a
Booleantype on top of raw constraints. - Zokrates: a standalone programming language that compiles high-level code (functions, loops, arrays,
assertstatements) directly into R1CS, hiding the constraint-by-constraint bookkeeping. - Witness computation vs. constraining: setting a signal's value (so a prover can compute it) is a separate step from constraining that value to satisfy an equation; HDLs like Circom expose this distinction explicitly.
- Tradeoff pattern: HDLs give the most direct control over constraints but are hard to learn and poor at abstraction; libraries add a host language's expressiveness at the cost of needing to know that language; compiled DSLs are the easiest to learn but give up explicit control over how witnesses are computed.
Walkthrough
From idea to circuit (0:01)
The lecture opens with the gap between a high-level idea (private payments, private voting) and the arithmetic circuit or constraint system format that zero knowledge proof systems actually consume. It previews the three approaches to be covered: hardware description languages, library-based approaches, and dedicated compiled languages, plus a closing comparison.
Arithmetic circuits and R1CS (5:09)
Mishra explains arithmetic circuits as prime-field analogues of Boolean circuits, expressible either as a system of field equations or as a directed acyclic graph of gates. Ozdemir then introduces R1CS formally, with worked examples of valid and invalid constraints, the matrix formulation Az * Bz = Cz, and a step-by-step algorithm for converting any arithmetic circuit into one R1CS constraint per gate.
Circom tutorial (21:29)
Mishra introduces Circom as an HDL where wires are signals and gates are constraints, contrasting it with general-purpose programming languages. Through live coding, the tutorial builds up templates for multiplication, repeated squaring (using template arguments and compile-time loops), a non-zero check (via multiplicative inverse), and sub-circuits, then assembles a partial Sudoku checker that verifies row uniqueness, range constraints, and agreement between puzzle and solution.
arkworks tutorial (52:06)
Ozdemir explains the constraint-system-object pattern common to library-based approaches: adding variables, building linear combinations, and enforcing constraints, plus how Rust abstractions like structs and operator overloading reduce boilerplate (illustrated with a Boolean AND gadget). He then implements the same Sudoku row-uniqueness and range/match checks using the arkworks R1CS standard library, running the code to confirm it accepts valid solutions and rejects invalid ones.
Zokrates tutorial (1:18:22)
Ozdemir introduces Zokrates as a standalone language with high-level features (structs, generics, for loops, assert) that compiles directly to R1CS, noting that it cannot compute intermediate witnesses explicitly the way Circom and arkworks can. The tutorial reimplements the Sudoku checks in Zokrates and walks through the command-line pipeline: compile, setup, compute witness, generate proof, and verify, demonstrating both an accepted and a rejected solution.
Comparing the approaches (1:31:31)
The lecture closes by classifying the three tools along two axes (circuit-describing vs. program-describing, and standalone syntax vs. embedded in a host language), then summarizes each tool's pros and cons: Circom's clarity but weak abstractions, arkworks' expressiveness but need to know Rust, and Zokrates' ease of use but reduced control over witness generation. It briefly surveys other tools (gadgetlib, Bellman, Snarky, Noir, Cairo) and notes the common techniques (booleans, fixed-width integers, control flow) shared across all of them.
Before you watch
- Watch Lecture 2 first for the definitions of arithmetic circuits, SNARKs, and R1CS that this lecture builds on directly.
- Basic familiarity with a systems language like Rust helps with the arkworks section, though the lecture explains the relevant syntax as it goes.
- No prior exposure to Circom, arkworks, or Zokrates is assumed.
Check your understanding
- What is the difference between setting a signal's value and constraining it, and why does Circom separate these into
<--and===? - Why can't a single R1CS constraint contain a product of three variables, and how does the lecture's example work around this?
- Compare the three tools on how much explicit control they give a developer over witness computation.
- Why does the arkworks approach require knowledge of Rust, while Zokrates does not require knowledge of any host language?
- What common techniques does the lecture suggest are shared across Circom, arkworks, and Zokrates despite their different syntax?
From the YouTube description
Guest Lecturers: Pratyush Mishra & Alex Ozdemir
Zero Knowledge Proofs MOOC Spring '23
← Lecture 2: Overview of Modern SNARK Constructions · Lecture 4: Interactive Proofs and the Sum-Check Protocol →
