Awesome
Assignment: Writing and Proving Arithmetic Circuits
In this assignment you’ll learn about:
circom
: a domain-specific language for describing arithmetic circuits, andsnarkjs
: a tool for generating and verifying zk-SNARKs for circuit satisfiability.
Setup
- Install nodejs (includes
npm
). - Install
circom
following this installation guide. Once installed, ensure that you're using the correct version ofcircom
by runningcircom --version
. You should seecircom compiler 2.1.4
or later. - Install
snarkjs
: runnpm install -g snarkjs@latest
. - Install the
mocha test runner
: runnpm install -g mocha
. - Run
npm install
in the same directory as this readme to install the dependencies for this assignment. - Run
mocha test
and verify that most of the tests fail, but not because of missing dependencies.
Assignment Details
Task 1: Implement a (simplified) floating-point addition circuit in circom
In this task, you'll be implementing a (simplified) floating-point addition circuit in circom
. This task does not assume any familiarity with floating-point arithmetic and you are not required to understand floating-point addition to complete it.
Before you begin, please go through the circom documentation and circuits/example.circom
.
The src/
directory has a python program float_add.py
that implements the floating-point addition logic. Use this file as a reference point for the set of instructions you have to translate into a circuit. We have added minimal comments in float_add.py
as they can be distracting. For curious students, we've added another file src/float_add_with_comments.py
that implements the same logic and has extensive comments explaining the floating-point representation and the addition algorithm.
The circuits/
directory has a file float_add.circom
that contains the skeleton of the circuit that you have to complete.
We've broken down the circuit into several templates such that each function in float_add.py
has a corresponding template in float_add.circom
.
Each template has comments explaining its inputs and outputs, as well as any conditions that have to be enforced by that template.
You have to implement the empty templates one-by-one in the order they appear in the file. You can independently test each template by running mocha test/[template_name_in_snake_case].js
. There's partial credit for each template.
Some useful templates are already implemented in float_add.circom
for you to use in your circuit and to serve as examples.
circom
will compile your circuits to a Rank-1 Constraint System (R1CS) instance (see Lecture 3 for definition), the primary efficiency metric for which is the number of constraints (fewer is better). You can find the number of constraints in your implementation using the testing suite. The suite also tells you the number of constraints expected from an optimized circuit implementation. There's bonus points if the number of constraints in your implementation are close to the optimized constraints.
Deliverable: completed
float_add.circom
Task 2: Generate a zk-SNARK proof using snarkjs
In this task, you will use snarkjs
to generate a Groth16
proof that proves $7 \times 17 \times 19 = 2261$ using the SmallOddFactorization
circuit implemented in circuits/example.circom
.
Follow the steps in snarkjs
README until Step 24, and you will learn how to create a Groth16
proof and verify it. You can use the powersOfTau28_hez_final_08.ptau
file in the root directory of this assignment to skip the first 9 steps.
Deliverable:
proof.json
andverification_key.json
generated while following the proof generation steps.
Testing
We’ve provided a few unit tests for the various components you have to implement to test their correctness. You can run all the tests using mocha test
.
The unit tests only check correctness of your constraint system, i.e., the constraints are satisfied given a valid witness. They do not check the soundness of your system, i.e., for all invalid witnesses, the constraints are not satisfied. To get full credit, your circuit has to be correct as well as sound.
As a sanity check, the test suite also checks the number of constraints in your circuits, and throws a warning if that number is smaller than expected. If there's a warning, it is likely that you're not appropriately constraining all the signals, and thus, your system is not sound.
Submission
Use the submission link on the course webpage to submit the deliverables (i.e., float_add.circom
, proof.json
, and verification_key.json
) in a zip file.