CirC: Compiling Programs to Circuits
Common Compiler Infrastructure for: SNARKs, SMT solvers, etc.
Alex Ozdemir, Fraser Brown, Riad Wahby
R1CS
?
Image Credits: ZK Podcast
Idea: Zero-Knowledge Bounties?
Supposedly, 𝑐 = 𝑐 + 2𝑎𝑏
(OpenSSL, CVE-2014-3570)
Codebase Owner
Bug Finder
“Inputs 𝒘 cause ”
Idea: Zero-Knowledge Bounties?
Supposedly, 𝑐 = 𝑐 + 2𝑎𝑏
(OpenSSL, CVE-2014-3570)
Codebase Owner
Bug Finder
𝜋
“I know inputs that cause ”
Zero-Knowledge: Challenges
• For ZK-proofs, you need a system of arithmetic constraints (R1CS)
1. Need compilers from high level languages to R1CS with
• Small output (efficiency)
• Accurate output (correctness)
Pequin (C)
[SBVBPW’13]
[BFRSBW’13]
[WSRBW’15]
ZoKrates
[EbeTai’18]
Zinc
circom
xJSnark
[KosPapShi’18]
PySNARK (~py)
Leo
Snarky
Cairo
R1CS
A (General) Compilation Problem
High-level languages:
• stateful
• control-flow
• uniform
Circuits:
• state-free
• non-uniform
• non-deterministic
𝑥0
𝑥1
𝑥2
𝑤0
𝑤1
Compiler
“circuits” also used in:
• SMT solving/verification
• Optimization (ILP)
• Multiparty computation
Our Approach: Common Infrastructure
Common Infrastructure for Compiling to
(Existentially Quantified) Circuits
CirC
ZoKrates
SMT Solver
Proof System
ILP?
MPC?
Design of CirC
Design Overview
C
Frontend
Optimizer
ZoKrates
Frontend
SMT
Backend
R1CS
Backend
SMT
Solver
Proof
System
a.circ
a.smt
a.c
CirC Front-Ends: Extensibility
C
Frontend
Optimizer
ZoKrates
Frontend
SMT
Backend
R1CS
Backend
Extensibility Case Study: ZoKrates
ZoKrates: Language designed to be compiled to R1CS (2018).
Compiler Reference
Lines of Code ~28,000
Development Time 3 years
Contributors 36
Output Size good
Extensibility Case Study: ZoKrates
ZoKrates: Language designed to be compiled to R1CS (2018).
Compiler Reference CirC
Lines of Code ~28,000 ~700
Development Time 3 years 1 week
Contributors 36 1
Output Size good better
ZoKrates Performance Comparison
What Does a Front-End Look Like?
A frontend is written as an
interpreter…
… with state management
abstracted out!
Automatic:
• Variables (mutation, scope, etc.)
• Data-dependent arrays
• Control Flow
CirC-IR
(SMT-like)
Python
Interpreter Snippet
Benefits of Common Infrastructure
• Easy extension to new
languages/circuits
• Built a better ZoKrates compiler in
≈ 40 × less code
• common optimizations
• Constant folding
• Memory representation
• Mix & match targets
• Automated zero-knowledge proof-
of-bug
• SMT-assisted optimization of
arithmetic circuits
CirC’s Core: Language-Agnostic
Compilation
Applications & Techniques
CirC’s Core: Language Agnostic
Compilation & Optimzation
C
Frontend
Optimizer
ZoKrates
Frontend
SMT
Backend
R1CS
Backend
Compiling to Circuits: Techniques
Challenge Approach
Variable Mutation Variable Versioning
x = y
x = x * y
x1 = y
x2 = x1 * y
Compiling to Circuits : Techniques
Challenge Approach
Variable Mutation Variable Versioning
Memory Use SMT Arrays
x[y] = z
x2 = x1[z @ y]
Compiling to Circuits : Techniques
Challenge Approach
Variable Mutation Variable Versioning
Memory Use SMT Arrays
Loops Unrolling
x = 5
for x in {0,1}:
x *= x
x1 = 5
x2 = x1 * x1
x3 = x2 * x2
Compiling to Circuits : Techniques
Challenge Approach
Variable Mutation Variable Versioning
Memory Use SMT Arrays
Loops Unrolling
Branching Guards
x = 5
if y > 0:
x *= x
x1 = 5
x2 = y > 0
? x1 * x1
: x1
Optimizations: Basic
• Constant folding
• 5 + 6 → 11
• 𝑥 ≪ 2 → 𝑥 2: ∥ [0,0]
• Operator flattening
• 𝑥 + 𝑦 + 𝑧 → 𝑥 + 𝑦 + 𝑧
• Substitution
• Peephole
• c & t | ~c & f ->
ITE(c,t,f)
Optimizations: Array Elimination
• Oblivious Arrays
• Arrays accessed at constant
indices
• Replaced with distinct terms
• Like scalar replacement
x = [y,z];
x[0] = x[1]+x[0];
y = x[0];
x01 = y1; x11 = z;
x02 = x01 + x11;
y2 = x02;
Optimizations: Routing-Based Memory
• Replace memory operations (array encoded) with the following…
access 0 load addr val
access 1 load addr val
access 2 load addr val
access 3 load addr val
access 4 load addr val
Program Order
access id load addr val
access id load addr val
access id load addr val
access id load addr val
access id load addr val
Address Order
• Check
order
• Check read-
over-write
Waksman
routing network
(existential
switch settings)
[WSRBW’15] [BCTV’14] [BCGTV’13] [BEGKN’94]
CirC Back-Ends: Applications
C
Frontend
Optimizer
ZoKrates
Frontend
SMT
Backend
R1CS
Backend
Backends
SMT (Z3)
• Support for
• Bit-vectors
• Booleans
• Floating-point
• Arrays
• (all but finite fields)
R1CS (Finite Field Equations)
• Support for
• Bit-vectors (that fit in the field)
• Booleans
• Finite Fields
• Some arrays (via memory-
checking)
Common Optimization: Constant Folding
• Define a hash 𝐻.
• Assert ∃𝑥. 𝐻 𝑥 0. . 8 = 0
• Vary:
• Length of 𝑥
• Constant folding pass
• Measure
• SMT solver time
• R1CS constraint count
e.g. 5 + 6 → 11
Common Optimization: Array Elimination
• Define a program:
• Fills an array with non-
deterministic values
• Computes the sum
• Asserts a non-zero sum
• Vary:
• array size
• array elimination pass
Common Optimization: Array Granularity
• Program:
• Represents permutations on
{0,1, . . , 𝑛} with arrays
• Applies a sequence of
permutations (via indexing)
• Vary:
• Permutation size
• % permutations fused into a single
array
Stack
𝐴0
𝐴1
𝐴2
𝐴0
𝐴1
𝐴2
vs.
coarse fine
Cross-Over Applications
Cross-over: SMT-assisted Compilation
Frontend
SMT
Backend
R1CS
Backend
Use SMT!
How many times can the loop run?
Cross-Over: Proof-of-Bug
1. Compile program & assertion
to IR
2. Lower to SMT
3. Find violation with solver
4. Lower to R1CS
5. Prove knowledge of violation
Openssl’s 𝑐 = 𝑐 + 2𝑎𝑏
(𝑐 in 3 limbs)
CirC: Compilation Infrastructure for Circuits
Different circuits can share
compiler infrastructure
Benefits:
• Easy extension
• Shared optimizations
• Cross-over opportunities
Future Directions:
• More languages, more targets
CirC
ZoKrates
SMT Solver
Proof System
ILP?
MPC?
https://ia.cr/2020/1586
Backup Slides Follow
OpenSSL Proof-of-Bug Details
Wrapper function & assertion Visualization of macro
Comparison against Pequin
• Pequin
• State-of-the-art C-to-R1CS
compiler

zkStudyClub: CirC and Compiling Programs to Circuits

  • 1.
    CirC: Compiling Programsto Circuits Common Compiler Infrastructure for: SNARKs, SMT solvers, etc. Alex Ozdemir, Fraser Brown, Riad Wahby R1CS ? Image Credits: ZK Podcast
  • 2.
    Idea: Zero-Knowledge Bounties? Supposedly,𝑐 = 𝑐 + 2𝑎𝑏 (OpenSSL, CVE-2014-3570) Codebase Owner Bug Finder “Inputs 𝒘 cause ”
  • 3.
    Idea: Zero-Knowledge Bounties? Supposedly,𝑐 = 𝑐 + 2𝑎𝑏 (OpenSSL, CVE-2014-3570) Codebase Owner Bug Finder 𝜋 “I know inputs that cause ”
  • 4.
    Zero-Knowledge: Challenges • ForZK-proofs, you need a system of arithmetic constraints (R1CS) 1. Need compilers from high level languages to R1CS with • Small output (efficiency) • Accurate output (correctness) Pequin (C) [SBVBPW’13] [BFRSBW’13] [WSRBW’15] ZoKrates [EbeTai’18] Zinc circom xJSnark [KosPapShi’18] PySNARK (~py) Leo Snarky Cairo R1CS
  • 5.
    A (General) CompilationProblem High-level languages: • stateful • control-flow • uniform Circuits: • state-free • non-uniform • non-deterministic 𝑥0 𝑥1 𝑥2 𝑤0 𝑤1 Compiler “circuits” also used in: • SMT solving/verification • Optimization (ILP) • Multiparty computation
  • 6.
    Our Approach: CommonInfrastructure Common Infrastructure for Compiling to (Existentially Quantified) Circuits CirC ZoKrates SMT Solver Proof System ILP? MPC?
  • 7.
  • 8.
  • 9.
  • 10.
    Extensibility Case Study:ZoKrates ZoKrates: Language designed to be compiled to R1CS (2018). Compiler Reference Lines of Code ~28,000 Development Time 3 years Contributors 36 Output Size good
  • 11.
    Extensibility Case Study:ZoKrates ZoKrates: Language designed to be compiled to R1CS (2018). Compiler Reference CirC Lines of Code ~28,000 ~700 Development Time 3 years 1 week Contributors 36 1 Output Size good better
  • 12.
  • 13.
    What Does aFront-End Look Like? A frontend is written as an interpreter… … with state management abstracted out! Automatic: • Variables (mutation, scope, etc.) • Data-dependent arrays • Control Flow CirC-IR (SMT-like) Python
  • 14.
  • 15.
    Benefits of CommonInfrastructure • Easy extension to new languages/circuits • Built a better ZoKrates compiler in ≈ 40 × less code • common optimizations • Constant folding • Memory representation • Mix & match targets • Automated zero-knowledge proof- of-bug • SMT-assisted optimization of arithmetic circuits
  • 16.
  • 17.
    CirC’s Core: LanguageAgnostic Compilation & Optimzation C Frontend Optimizer ZoKrates Frontend SMT Backend R1CS Backend
  • 18.
    Compiling to Circuits:Techniques Challenge Approach Variable Mutation Variable Versioning x = y x = x * y x1 = y x2 = x1 * y
  • 19.
    Compiling to Circuits: Techniques Challenge Approach Variable Mutation Variable Versioning Memory Use SMT Arrays x[y] = z x2 = x1[z @ y]
  • 20.
    Compiling to Circuits: Techniques Challenge Approach Variable Mutation Variable Versioning Memory Use SMT Arrays Loops Unrolling x = 5 for x in {0,1}: x *= x x1 = 5 x2 = x1 * x1 x3 = x2 * x2
  • 21.
    Compiling to Circuits: Techniques Challenge Approach Variable Mutation Variable Versioning Memory Use SMT Arrays Loops Unrolling Branching Guards x = 5 if y > 0: x *= x x1 = 5 x2 = y > 0 ? x1 * x1 : x1
  • 22.
    Optimizations: Basic • Constantfolding • 5 + 6 → 11 • 𝑥 ≪ 2 → 𝑥 2: ∥ [0,0] • Operator flattening • 𝑥 + 𝑦 + 𝑧 → 𝑥 + 𝑦 + 𝑧 • Substitution • Peephole • c & t | ~c & f -> ITE(c,t,f)
  • 23.
    Optimizations: Array Elimination •Oblivious Arrays • Arrays accessed at constant indices • Replaced with distinct terms • Like scalar replacement x = [y,z]; x[0] = x[1]+x[0]; y = x[0]; x01 = y1; x11 = z; x02 = x01 + x11; y2 = x02;
  • 24.
    Optimizations: Routing-Based Memory •Replace memory operations (array encoded) with the following… access 0 load addr val access 1 load addr val access 2 load addr val access 3 load addr val access 4 load addr val Program Order access id load addr val access id load addr val access id load addr val access id load addr val access id load addr val Address Order • Check order • Check read- over-write Waksman routing network (existential switch settings) [WSRBW’15] [BCTV’14] [BCGTV’13] [BEGKN’94]
  • 25.
  • 26.
    Backends SMT (Z3) • Supportfor • Bit-vectors • Booleans • Floating-point • Arrays • (all but finite fields) R1CS (Finite Field Equations) • Support for • Bit-vectors (that fit in the field) • Booleans • Finite Fields • Some arrays (via memory- checking)
  • 27.
    Common Optimization: ConstantFolding • Define a hash 𝐻. • Assert ∃𝑥. 𝐻 𝑥 0. . 8 = 0 • Vary: • Length of 𝑥 • Constant folding pass • Measure • SMT solver time • R1CS constraint count e.g. 5 + 6 → 11
  • 28.
    Common Optimization: ArrayElimination • Define a program: • Fills an array with non- deterministic values • Computes the sum • Asserts a non-zero sum • Vary: • array size • array elimination pass
  • 29.
    Common Optimization: ArrayGranularity • Program: • Represents permutations on {0,1, . . , 𝑛} with arrays • Applies a sequence of permutations (via indexing) • Vary: • Permutation size • % permutations fused into a single array Stack 𝐴0 𝐴1 𝐴2 𝐴0 𝐴1 𝐴2 vs. coarse fine
  • 30.
  • 31.
  • 32.
    Cross-Over: Proof-of-Bug 1. Compileprogram & assertion to IR 2. Lower to SMT 3. Find violation with solver 4. Lower to R1CS 5. Prove knowledge of violation Openssl’s 𝑐 = 𝑐 + 2𝑎𝑏 (𝑐 in 3 limbs)
  • 33.
    CirC: Compilation Infrastructurefor Circuits Different circuits can share compiler infrastructure Benefits: • Easy extension • Shared optimizations • Cross-over opportunities Future Directions: • More languages, more targets CirC ZoKrates SMT Solver Proof System ILP? MPC? https://ia.cr/2020/1586
  • 34.
  • 35.
    OpenSSL Proof-of-Bug Details Wrapperfunction & assertion Visualization of macro
  • 36.
    Comparison against Pequin •Pequin • State-of-the-art C-to-R1CS compiler