[ZK Learning Group 2] Circom workshop #1
Circom serves 2 primary purposes:
Lets you define a set of constraints that implicitly is equivalent to some function.
Define at proving-time, how you should fill in the nodes of your Arithemtic circuit - intermediate variables. (witness generation).
On signals
they are not bits.
they are prime field elements. modulo p, where p is the babyjubjub prime.
On witness generation
You know some
x
that results in some publicout
, such thatf(x) = y
(y = out)For convenience, circom allows you to generate the intermediate witnesses, as opposed to having the user to supply them.
This is done with the
<--
notation
Constraints
constraints are done with
===
notationcan only use
*
or+
operatorsmust look like either"
Compilation
Comilation gives up a number of files, including the .r1cs file.
R1CS
Compiling the circuit gives us an R1CS file, that can be used with different toolstacks, that implement the Groth16 protocol.
Think of it as a IR representation; like your compiled bytecode.
.wasm file
a wasm exceutable program that implements the single arrow stuff - witness generation.
witness generation program that allows derivation of the intermediate signals (
x_squared, x_cubed
) just from the single input,x
.
vkey: verification key
goes into your smart contract for verification.
a .sol file is also created, whjich is a contract based on the vk that serves as the verification component.
.sol file would expose a
verifyProof
function
.zkey: proving key
goes into your client, Dapp Front-end.
used in proof generation.
When can't you simply just <==
for all constraints/intermediates?
<==
for all constraints/intermediates?Input signals: x1,..x4
Intermediates : y1, y2
Notice that in this example we cannot simply use <===
to combine out witness generation and constraint definition.
The reason we have to seperate is cos' of the y2 <-- y1 / x3;
In witness generation you are allowed to use arbitrary operations like division.
But in defining constraints, we can only use quadratic expressions.
So instead of
y2 <-- y1 / x3;
>>> it becomesy1 === y2 * x3;
You are only allowed quadratic constraints: a+b*c
can't do x*x*x
Include
Paranthesis
Allows you to enter values that are params
params are for dynamic parts of the circuit
like counter of a for loop
must be specified by compile time. cos the compiled circuit cannot have such dynamic parts like loops.
At compile time, circuits must be bounded.
n must be known at compile time.
For loops just serve as a kind of syntatic sugar - they get unrolled into individuals lines of code.
Last updated
Was this helpful?