# Modern ZK Crypto - Session 2 Exercises
Today's exercises are hands-on coding exercises. Try writing the following circuits on your own. If you get stuck, you can check the solutions.
If you need to look up circom language features or syntax, take a look at the [circom docs](https://docs.circom.io/circom-language/signals/). I recommend trying to build these circuits in [zkREPL](zkrepl.dev), for fast iteration.
I recommend doing these exercises in order, as later circuits may build on previous ones.
## References
### Field Size
All signals in circom are field elements in the prime field of order
```
r = 21888242871839275222246405745257275088548364400416034343698204186575808495617
```
This is a 254-bit prime known as the BabyJubJub prime. It's the curve order for BN254, a pairing-friendly elliptic curve used by Ethereum and (formerly) ZCash. You can read more about BN254 in Jonathan Wang's excellent document [here](https://hackmd.io/@jpw/bn254).
### Recommendations and Common Issues
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.
## Exercises
### Num2Bits
- Parameters: `nBits`
- Input signal(s): `in`
- Output signal(s): `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.
[Solution](https://github.com/iden3/circomlib/blob/master/circuits/bitify.circom#L25)
### IsZero
- Parameters: none
- Input signal(s): `in`
- Output signal(s): `out`
Specification: If `in` is zero, `out` should be `1`. If `in` is nonzero, `out` should be `0`. This one is a little tricky!
[Solution](https://github.com/iden3/circomlib/blob/master/circuits/comparators.circom#L24)
### IsEqual
- Parameters: none
- Input signal(s): `in[2]`
- Output signal(s): `out`
Specification: If `in[0]` is equal to `in[1]`, `out` should be `1`. Otherwise, `out` should be `0`.
[Solution](https://github.com/iden3/circomlib/blob/master/circuits/comparators.circom#L37)
### Selector
- Parameters: `nChoices`
- Input signal(s): `in[nChoices]`, `index`
- Output: `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`.
[Solution](https://github.com/darkforest-eth/circuits/blob/master/perlin/QuinSelector.circom)
### IsNegative
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)
- Parameters: none
- Input signal(s): `in`
- Output signal(s): `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](https://github.com/iden3/circomlib/blob/master/circuits/compconstant.circom), 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.
[Solution](https://github.com/iden3/circomlib/blob/master/circuits/sign.circom#L23)
- **Understanding check**: Why can’t we just use LessThan or one of the comparator circuits from the previous exercise?
### LessThan
- Parameters: none
- Input signal(s): `in[2]`. Assume that it is known ahead of time that these are at most $2^{252} - 1$.
- Output signal(s): `out`
Specification: If `in[0]` is strictly less than `in[1]`, `out` should be `1`. Otherwise, `out` should be `0`.
- **Extension 1**: If you know that the input signals are at most 2^k - 1 (k ≤ 252), how can you reduce the total number of constraints that this circuit requires? Write a version of this circuit parametrized in `k`.
- **Extension 2**: Write LessEqThan (tests if in[0] is ≤ in[1]), GreaterThan, and GreaterEqThan
[Solution (with extension 1)](https://github.com/iden3/circomlib/blob/master/circuits/comparators.circom#L89)
### IntegerDivide
NOTE: This circuit is pretty hard!
- Parameters: `nbits`. Use `assert` to assert that this is at most 126!
- Input signal(s): `dividend`, `divisor`
- Output signal(s): `remainder`, `quotient`
Specification: First, check that the `dividend` and `divisor` are at most `nbits` in bitlength. Next, compute and constrain `remainder` and `quotient`.
- **Extension**: How would you modify the circuit to handle negative dividends?
[Solution](https://github.com/darkforest-eth/circuits/blob/master/perlin/perlin.circom#L44) (ignore the second parameter SQRT_P; that is extraneous)

Subject: [ACTION REQUIRED] Zuzalu Passport Migration Hi Zuzaluans! Last night, the .eth.limo service stopped working, taking down Ethereum-related websites including the Zuzalu Passport, multiple DeFi apps, and Vitalik's personal homepage. We've moved the Zuzalu Passport to a new domain. You'll need to re-generate your passport on the new domain in order to access the Zuzalu website and events. Get your new Zuzalu Passport here:

3/26/2023Subject: [ACTION REQUIRED] Set up your Zuzalu Passport before arrival! Hello Zuzalu residents! We’re in the final countdown of welcoming new residents to Zuzalu! Zuzalu activities are gated to Zuzalu residents. So to access Zuzalu spaces and activities, you'll need to set up your Zuzalu Passport: a simple digital pass that will grant you entry to events and spaces. Please follow the instructions in this email to set up your Zuzalu Passport; without a Passport, you won't be able to access venues in the village or the website! Your Zuzalu Passport is associated with your email address. The address you're receiving this message from is the email address we have on file for you.

3/24/2023The Zuzalu Passport is an app that lets you prove that you are a Zuzalu resident or visitor (using zero-knowledge cryptography!). You'll use it to access both digital and physical spaces at Zuzalu. For example, your Passport will generate a QR code that you can show on mobile, that can be scanned for access to Zuzalu co-working spaces. Your Passport also allows you to log into the Zuzalu website, to sign up for Zuzalu events. Once you've created your Passport, if you want to use your Passport on a device other than the one you first logged in on, you'll need to follow two easy steps. Step 1: Copy your Passport Key from your original device To do this, hit the settings icon in the top right-corner of the Passport app, and then tap "Copy Key for Sync."

3/24/2023Note: This flow is only for adding new resident emails, not visitors. Visitors should sign up on Pretix for a subevent or visitor pass, and then they will be automatically permissioned to create a Passport. First, go to the Pretix Imports spreadsheet, and navigate to the "Residents (INCOMPLETE) sheet." This sheet has been pre-populated with all residents who have incomplete {firstname, lastname, email} information. Screenshot: Pretix Imports spreadsheet Find the entry (or entries) that you want to permission as resident(s). Each entry needs an email, firstname, and lastname.

3/24/2023
Published on ** HackMD**