This week's exercises are hands-on coding exercises. Try writing the following circuits on your own. If you get stuck, you can check the solutions. We'll go over these circuits in the second Optional Session in Week 2.
If you need to look up circom language features or syntax, take a look at the circom docs. I recommend trying to build these circuits in zkREPL, for fast iteration.
I recommend doing these exercises in order, as later circuits may build on previous ones.
All signals in circom are treated as numbers modulo this big prime:
r = 21888242871839275222246405745257275088548364400416034343698204186575808495617
This is a 254-bit prime known as the BabyJubJub prime. All addition, subtraction, and multiplication in circom is implicitly happening modulo r
.
For those interested in where this number comes from: r
is the curve order for BN254, a pairing-friendly elliptic curve used by Ethereum and (formerly) ZCash. If you're very mathematically inclined, you can read more about BN254 in Jonathan Wang's excellent document here.
If you are testing your circuits using zkREPL's input comment functionality (particularly if you are using negative numbers), be aware that you'll need to surround numbers in quotations marks, and you'll need to write them as non-negative residues. This is due to the interpretation of the signal input JSON as a Javascript object, with biginteger values.
For example, testing an input signal x
with the value -1
should look like this:
"x": "21888242871839275222246405745257275088548364400416034343698204186575808495616"
Forgetting these quotation marks is a common source of failing tests.
nBits
in
b[nBits]
The output signals should be an array of bits of length nBits
equivalent to the binary representation of in
. b[0]
is the least significant bit.
in
out
Specification: If in
is zero, out
should be 1
. If in
is nonzero, out
should be 0
. This one is a little tricky!
in[2]
out
Specification: If in[0]
is equal to in[1]
, out
should be 1
. Otherwise, out
should be 0
.
nChoices
in[nChoices]
, index
out
Specification: The output out
should be equal to in[index]
. If index
is out of bounds (not in [0, nChoices)), out
should be 0
.
in[2]
. Assume that it is known ahead of time that these are at most out
Specification: If in[0]
is strictly less than in[1]
, out
should be 1
. Otherwise, out
should be 0
.
k
.NOTE: Signals are residues modulo p (the Babyjubjub prime), and there is no natural notion of “negative” numbers mod p. However, it is pretty clear that that modular arithmetic works analogously to integer arithmetic when we treat p-1
as -1
. So we define a convention: "Negative" is by convention considered to be any residue in (p/2, p-1], and nonnegative is anything in [0, p/2)
in
out
Specification: If in
is negative according to our convention, out
should be 1
. Otherwise, out
should be 0
. You are free to use the CompConstant circuit, which takes a constant parameter ct
, outputs 1
if in
(a binary array) is strictly greater than ct
when interpreted as an integer, and 0
otherwise.
NOTE: This circuit is pretty hard!
nbits
. Use assert
to assert that this is at most 126!dividend
, divisor
remainder
, quotient
Specification: First, check that the dividend
and divisor
are at most nbits
in bitlength. Next, compute and constrain remainder
and quotient
.
Solution (ignore the second parameter SQRT_P; that is extraneous)
If you want to check your understanding of ZK, try these questions from 0xPARC's ZK Topic Sampler.
Visit http://web.mit.edu/~ezyang/Public/graph/svg.html and play around with the interactive demo. This is a programmatic version of the 3-coloring example we went over in class.
Implement a non-interactive ZKP for discrete log in code! To do this, you'll need to read and understand the first section of this handout, as well as the Fiat-Shamir heuristic.
Specifically, you should implement:
If you need help, a reference implementation in Javascript with comments can be found here. This exercise may take you a few hours.
For an additional challenge, try implementing a non-interactive ZKP for proof of 3-coloring as well!
This is a preview of Core Session 3.
Create an account and post a message on zkmessage, a zkSNARK-powered anonymous message board.
If you're curious, we go much deeper into the construction of zkmessage here.