# Circom Workshop 1

## Descriptionβ

In this session, we introduce the Circom tool stack and how to write basic circuits.

π zk-SNARKs allow you to generate a proof that some arithmetic function $f$ evaluates to an output y given a list of values $W=[w_1,β¦,w_n]$, which is called a

witness. A circuit is uniquely defined by a series ofarithmetic constraintswhich ensure that the function f was computed correctly.zk-SNARK proofs are useful because they allow a verifier to verify that $f$ was correctly computed without needing to know all of the witness or having to check all the constraints. A valid proof (i.e. one that the verifier accepts) means that the witness has satisfied all of circuitβs constraints. This is why it is important to construct your circuit to exactly reflect function $f$.

The property of

zero-knowledgefollows from the fact that the prover can hide information in the witness from the verifier. The property ofsuccinctnessfollows from the fact that all the constraints are combined using cryptographic magic such that the verifier only needs to actually check a few constraints.

## Pre-Session Reading/Setupβ

Take a look at the circom docs: https://docs.circom.io/

## Slides Link(s)β

https://docs.google.com/presentation/d/1ri-jMmRx1l6-yjYHTVJy6ar3G5zq4k0chnLiOwdol0o/edit?usp=sharing

## Check-in Questionsβ

(1) **Constraint Forms**: In the Circom circuitβs computation trace, there are input values, intermediate values, and an OUT value. Why do we need to create intermediate values in the computation trace between inputs and OUT?

(2) **Circom Syntax**: Whatβs the difference between using β<ββ and β<==β in circom?

(3) **Example Circom Code**: What does the following Circom code do?

`template Example() {`

signal input in[2];

signal output out;

component isz = IsZero(); // checks if an input is 0

in[1] - in[0] ==> isz.in;

isz.out ==> out;

}

## Sample Answers

(1) **Constraint Forms**: SNARK constraints can only take two inputs and are modeled in the equation form βa = b + cβ (addition) or βa = b * cβ (multiplication). Thus, we need intermediate values to store computations starting from the inputs, two variables at a time.

(2) **Circom Syntax**: β<ββ is used to define a witness value. β<==β is used to define a witness value and imply an assert statement for the values on the left and right.

(3) **Example Circom Code**: Checks if two values are equal to one another. Feel free to play around with circuits more using https://zkrepl.dev/!