Skip to content

feat: add build and dev-setup scripts for email auth reveal circuit #134

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Draft
wants to merge 3 commits into
base: email-recovery
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
65 changes: 58 additions & 7 deletions packages/circuits/README.md
Original file line number Diff line number Diff line change
@@ -1,13 +1,17 @@
# Circuit Architecture

## Circom Circuits

### Main Circuits

We provide one main circuit as follows.

#### `email_auth.circom`

A circuit to verify that a message in the subject is authorized by a user of an account salt, derived from an email address in the From field and a random field value called account code.

It takes as input the following data:

1. a padded email header `padded_header`.
2. the bytes of the padded email header `padded_header_len`.
3. an RSA public key `public_key`.
Expand All @@ -16,36 +20,43 @@ It takes as input the following data:
6. a starting position of the From field in the email header `from_addr_idx`.
7. a starting position of the Subject field in the email header `subject_idx`.
8. a starting position of the email domain in the email address of the From field `domain_idx`.
10. a starting position of the timestamp in the email header `timestamp_idx`.
11. a starting position of the invitation code in the email header `code_idx`.
9. a starting position of the timestamp in the email header `timestamp_idx`.
10. a starting position of the invitation code in the email header `code_idx`.

Its instances are as follows:

1. an email domain `domain_name`.
2. a Poseidon hash of the RSA public key `public_key_hash`.
3. a nullifier of the email `email_nullifier`.
4. a timestamp in the email header `timestamp`.
5. a masked subject where characters either in the email address or in the invitation code are replaced with zero `masked_subject_str`.
5. a masked subject where characters either in the email address or in the invitation code are replaced with zero `masked_subject_str`.
6. an account salt `account_salt`.
7. a flag whether the email header contains the invitation code `is_code_exist`.

## How to Use

### Build circuits

`yarn && yarn build`

### Run tests

At `packages/circuits`, make a `build` directory, download the zip file from the following link, and place its unzipped directory under `build`.
https://drive.google.com/file/d/1TChinAnHr9eV8H_OV9SVReF8Rvu6h1XH/view?usp=sharing

Then, move `email_auth.zkey` in the unzipped directory `params` to `build`.
Then, move `email_auth.zkey` in the unzipped directory `params` to `build`.

Then run the following command.
`yarn test`

### Generate proving keys and verifier contracts for main circuits

`yarn dev-setup`

## Specification

The `email_auth.circom` makes constraints and computes the public output as follows.

1. Assert that `signature` is valid for `padded_header` and `public_key`.
2. Let `public_key_hash` be `PoseidonHash(public_key)`.
3. Let `email_nullifier` be `PoseidonHash(PoseidonHash(signature))`.
Expand All @@ -57,17 +68,57 @@ The `email_auth.circom` makes constraints and computes the public output as foll
9. If `is_time_exist` is 1, let `timestamp` be an integer parsing `timestamp_str` as a digit string. Otherwise, let `timestamp` be zero.
10. Let `is_code_exist` be 1 if `padded_header` satisfies the regex of the invitation code.
11. Let `code_str` be `padded_header[code_idx:code_idx+64]`.
12. Let `embedded_code` be an integer parsing `code_str` as a hex string.
12. Let `embedded_code` be an integer parsing `code_str` as a hex string.
13. If `is_code_exist` is 1, assert that `embedded_code` is equal to `account_code`.
14. Let `account_salt` be `PoseidonHash(from_addr|0..0, account_code, 0)`.
15. Let `masked_subject` be a string that removes the invitation code with the prefix `code_str` and one email address from `subject`, if they appear in `subject`.

Note that the email address in the subject is assumbed not to overlap with the invitation code.


#### `email_auth_with_body_parsing_with_qp_encoding.circom`

A circuit to verify that a message in the email body, called command, is authorized by a user of an account salt, derived from an email address in the From field and a random field value called account code.
This is basically the same as the `email_auth.circom` described above except for the following features:

- Instead of `subject_idx`, it additionally takes as a private input a padded email body `padded_cleaned_body` and an index of the command in the email body `command_idx`.
- It extracts a substring `command` between a prefix `(<div id=3D\"[^\"]*zkemail[^\"]*\"[^>]*>)"` and a suffix `</div>` from `padded_cleaned_body`.
- It outputs `masked_command` instead of `masked_subject`, which removes the invitation code with the prefix and one email address from `command`.
- It outputs `masked_command` instead of `masked_subject`, which removes the invitation code with the prefix and one email address from `command`.

# Circuit Scripts

## Usage

### Build a Circuit

```bash
npm run build <circuit_name> [output_dir]
```

Examples:

```bash
npm run build -- email_auth # builds email_auth circuit to build/
npm run build -- email_auth_reveal # builds email_auth_reveal circuit to build/
npm run build -- email_auth_reveal reveal # builds email_auth_reveal circuit to build/reveal/
```

### Dev Setup a Circuit

```bash
npm run dev-setup -- <circuit_name> [output_dir]
```

Examples:

```bash
npm run dev-setup email_auth # dev setup for email_auth circuit to build/
npm run dev-setup email_auth_reveal # dev setup for email_auth_reveal circuit to build/
npm run dev-setup email_auth_reveal reveal # dev setup for email_auth_reveal circuit to build/reveal/
```

## Notes

- Circuit files should be placed in the `src/` directory with `.circom` extension
- Circuit name is required - you must specify which circuit to build/setup
- Default output directory is `.` (directly in build/) if not specified
- Output directories are created under `build/` folder
10 changes: 3 additions & 7 deletions packages/circuits/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,8 @@
"license": "MIT",
"version": "1.0.3",
"scripts": {
"build": "mkdir -p build && circom src/email_auth.circom --r1cs --wasm --sym --c -l ../../node_modules -o ./build",
"build-no-timestamp": "mkdir -p build/no-timestamp && circom src/email_auth_no_timestamp.circom --r1cs --wasm --sym --c -l ../../node_modules -o ./build/no-timestamp",
"build-legacy": "mkdir -p build && circom src/email_auth_legacy.circom --r1cs --wasm --sym --c -l ../../node_modules -o ./build",
"build-recipient": "mkdir -p build && circom src/email_auth_with_recipient.circom --r1cs --wasm --sym --c -l ../../node_modules -o ./build",
"dev-setup": "NODE_OPTIONS=--max_old_space_size=16384 npx ts-node scripts/dev-setup.ts --output ./build --circuit email_auth",
"dev-setup-no-timestamp": "NODE_OPTIONS=--max_old_space_size=16384 npx ts-node scripts/dev-setup.ts --output ./build/no-timestamp --circuit email_auth_no_timestamp",
"build": "NODE_OPTIONS=--max_old_space_size=16384 node -e \"const args=process.argv.slice(2); const circuit=args[0]; const output=args[1]||'.'; if(!circuit) throw new Error('Circuit name required: npm run build <circuit_name> [output_dir]'); require('child_process').execSync('mkdir -p build/'+output+' && circom src/'+circuit+'.circom --r1cs --wasm --sym --c -l ../../node_modules -o ./build/'+output, {stdio:'inherit'})\"",
"dev-setup": "NODE_OPTIONS=--max_old_space_size=16384 node -e \"const args=process.argv.slice(2); const circuit=args[0]; const output=args[1]||'.'; if(!circuit) throw new Error('Circuit name required: npm run dev-setup <circuit_name> [output_dir]'); require('child_process').execSync('NODE_OPTIONS=--max_old_space_size=16384 npx ts-node scripts/dev-setup.ts --output ./build/'+output+' --circuit '+circuit, {stdio:'inherit'})\"",
"gen-input": "NODE_OPTIONS=--max_old_space_size=8192 npx ts-node scripts/gen_input.ts",
"test": "NODE_OPTIONS=--max_old_space_size=16384 jest",
"test-large": "NODE_OPTIONS=--max_old_space_size=32768 jest --maxWorkers=1"
Expand Down Expand Up @@ -53,4 +49,4 @@
"package.json",
"README.md"
]
}
}
Loading