Skip to content
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

Feat: Body Parsing #53

Open
wants to merge 48 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
48 commits
Select commit Hold shift + click to select a range
2ec4174
feat: email_auth template with body parsing
shreyas-londhe Aug 28, 2024
a9eb5b9
chore: bump zkemail-circuits to 6.1.5
shreyas-londhe Aug 29, 2024
253a02c
feat: extracting command from body in body-parsing
shreyas-londhe Aug 30, 2024
89f39f7
feat: email_auth body parsing circuit working with tests
shreyas-londhe Sep 1, 2024
6f6a726
fix: minor test changes
shreyas-londhe Sep 1, 2024
4de8d4d
chore: update dependencies
shreyas-londhe Sep 1, 2024
8685d3a
Merge branch 'feat/body-parsing-circuit' of https://github.com/zkemai…
SoraSuegami Sep 2, 2024
885b7a5
(wip) chore: pass github workflow
Bisht13 Sep 2, 2024
c88c574
Add a verifier contract
SoraSuegami Sep 2, 2024
48605a6
Merge branch 'feat/body-parsing-circuit' of https://github.com/zkemai…
SoraSuegami Sep 2, 2024
8a69a61
Update proving key url
SoraSuegami Sep 2, 2024
f5164a5
feat: add body parsing
Bisht13 Aug 21, 2024
cfa80b0
chore: update
Bisht13 Aug 21, 2024
f4dbfce
chore: separated body parsing tests
shreyas-londhe Sep 2, 2024
7214d3b
fix: refactring in recipent_enabled test
shreyas-londhe Sep 2, 2024
eedd202
fix: minor
shreyas-londhe Sep 2, 2024
e6caddf
chore: update relayer
Bisht13 Sep 2, 2024
9ccd3b9
fix: updated command regex
shreyas-londhe Sep 3, 2024
e2ed105
chore: changed max_command_bytes to 605
shreyas-londhe Sep 3, 2024
a8f2ef0
Update verifier
SoraSuegami Sep 3, 2024
05eaba9
Merge branch 'main' of https://github.com/zkemail/ether-email-auth in…
SoraSuegami Sep 3, 2024
80bdfc7
Merge branch 'main' of https://github.com/zkemail/ether-email-auth in…
SoraSuegami Sep 3, 2024
6b84605
feat: sha precompute test
shreyas-londhe Sep 3, 2024
2587fc8
chore: update relayer utils version
Bisht13 Sep 3, 2024
54d1526
feat: command update + relayer changes
Bisht13 Sep 4, 2024
19b46df
Fix circuit name in core.py
SoraSuegami Sep 4, 2024
05225ed
Merge branch 'feat/body-parsing-circuit' of https://github.com/zkemai…
SoraSuegami Sep 4, 2024
d192781
chore: update version
Bisht13 Sep 4, 2024
4fa904d
chore: update circuit test
Bisht13 Sep 4, 2024
3f62a9b
chore: update relayer-uitls dep
shreyas-londhe Sep 4, 2024
dca6793
Update verifier
SoraSuegami Sep 4, 2024
d8eb920
Change the max header/body sizes in the body-parsing circuits.
SoraSuegami Sep 4, 2024
97094f9
Add test circuits for body parsing
SoraSuegami Sep 4, 2024
c5f4bb5
Update verifier
SoraSuegami Sep 5, 2024
648720a
Fixing integration test
SoraSuegami Sep 6, 2024
703ce4e
Update emails for integration tests
SoraSuegami Sep 6, 2024
6edbe7a
Update yarn.lock
SoraSuegami Sep 6, 2024
b51d635
Fix scripts and email for integration test
SoraSuegami Sep 6, 2024
0566f14
chore: update circuit test
Bisht13 Sep 6, 2024
fbd3844
Integration test worked
SoraSuegami Sep 6, 2024
69963ef
Merge branch 'feat/body-parsing-circuit' of https://github.com/zkemai…
SoraSuegami Sep 6, 2024
d2f59da
fix: body parsing test
Bisht13 Sep 6, 2024
74c4557
feat: complete flow
Bisht13 Sep 6, 2024
cdf17ec
Replace subject with command.
SoraSuegami Sep 7, 2024
802e284
Merge branch 'feat/body-parsing-circuit' of https://github.com/zkemai…
SoraSuegami Sep 7, 2024
776fa59
Fix compile errors in relayer
SoraSuegami Sep 7, 2024
16eaa85
Remove skipped_command_bytes
SoraSuegami Sep 7, 2024
9885c6e
chore: refactor
Bisht13 Sep 8, 2024
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
1,213 changes: 705 additions & 508 deletions Cargo.lock

Large diffs are not rendered by default.

51 changes: 51 additions & 0 deletions kubernetes/cronjob.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
apiVersion: v1
kind: ServiceAccount
metadata:
name: cronjob-service-account
namespace: ar-base-sepolia
---
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
namespace: ar-base-sepolia
name: deployment-restart-role
rules:
- apiGroups: ["apps", "extensions"]
resources: ["deployments"]
verbs: ["get", "list", "watch", "update", "patch"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: deployment-restart-rolebinding
namespace: ar-base-sepolia
subjects:
- kind: ServiceAccount
name: cronjob-service-account
namespace: ar-base-sepolia
roleRef:
kind: Role
name: deployment-restart-role
apiGroup: rbac.authorization.k8s.io
---
apiVersion: batch/v1
kind: CronJob
metadata:
name: restart-deployment
namespace: ar-base-sepolia
spec:
schedule: "0 * * * *"
jobTemplate:
spec:
template:
spec:
serviceAccountName: cronjob-service-account
containers:
- name: kubectl
image: bitnami/kubectl:latest
command:
- /bin/sh
- -c
- |
kubectl rollout restart deployment relayer-email-auth --namespace ar-base-sepolia
restartPolicy: OnFailure
19 changes: 4 additions & 15 deletions kubernetes/relayer.yml
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ data:
IC_REPLICA_URL: ""
JSON_LOGGER: ""
PEM_PATH: ""
SMTP_SERVER: ""

---
apiVersion: v1
Expand All @@ -30,12 +31,6 @@ type: Opaque
data:
PRIVATE_KEY:
DATABASE_URL:
IMAP_DOMAIN_NAME:
IMAP_PORT:
AUTH_TYPE:
SMTP_DOMAIN_NAME:
LOGIN_ID:
LOGIN_PASSWORD:
PROVER_ADDRESS:
ICPEM:

Expand Down Expand Up @@ -94,14 +89,14 @@ spec:
spec:
containers:
- name: relayer-container
image: bisht13/relayer-new-0:latest
image: bisht13/ar-relayer-base-1:latest
ports:
- containerPort: 4500
envFrom:
- configMapRef:
name: relayer-config
name: relayer-config-email-auth
- secretRef:
name: relayer-secret
name: relayer-secret-email-auth
livenessProbe:
httpGet:
path: /api/echo
Expand Down Expand Up @@ -131,12 +126,6 @@ spec:
- secretRef:
name: relayer-imap-secret
volumes:
- name: pem-volume
secret:
secretName: relayer-secret
items:
- key: ICPEM
path: ".ic.pem"
- name: pem-volume
secret:
secretName: relayer-secret-email-auth
Expand Down
48 changes: 32 additions & 16 deletions packages/circuits/helpers/email_auth.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,22 +2,38 @@ import fs from "fs";
import { promisify } from "util";
const relayerUtils = require("@zk-email/relayer-utils");

export async function genEmailAuthInput(
emailFilePath: string,
accountCode: string
export async function genEmailCircuitInput(
emailFilePath: string,
accountCode: string,
options?: {
shaPrecomputeSelector?: string;
maxHeaderLength?: number;
maxBodyLength?: number;
ignoreBodyHashCheck?: boolean;
}
): Promise<{
padded_header: string[];
public_key: string[];
signature: string[];
padded_header_len: string;
account_code: string;
from_addr_idx: number;
subject_idx: number;
domain_idx: number;
timestamp_idx: number;
code_idx: number;
padded_header: string[];
public_key: string[];
signature: string[];
padded_header_len: string;
account_code: string;
from_addr_idx: number;
subject_idx: number;
domain_idx: number;
timestamp_idx: number;
code_idx: number;
body_hash_idx: number;
precomputed_sha: string[];
padded_body: string[];
padded_body_len: string;
command_idx: number;
padded_cleaned_body: string[];
}> {
const emailRaw = await promisify(fs.readFile)(emailFilePath, "utf8");
const jsonStr = await relayerUtils.genEmailAuthInput(emailRaw, accountCode);
return JSON.parse(jsonStr);
const emailRaw = await promisify(fs.readFile)(emailFilePath, "utf8");
const jsonStr = await relayerUtils.genEmailCircuitInput(
emailRaw,
accountCode,
options
);
return JSON.parse(jsonStr);
}
9 changes: 5 additions & 4 deletions packages/circuits/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,16 @@
"version": "1.0.0",
"scripts": {
"build": "mkdir -p build && circom src/email_auth.circom --r1cs --wasm --sym -l ../../node_modules -o ./build",
"dev-setup": "NODE_OPTIONS=--max_old_space_size=8192 npx ts-node scripts/dev-setup.ts --output ./build",
"build-body": "mkdir -p build && circom src/email_auth_with_body_parsing_with_qp_encoding.circom --r1cs --wasm --sym -l ../../node_modules -o ./build",
"dev-setup": "NODE_OPTIONS=--max_old_space_size=16384 npx ts-node scripts/dev-setup.ts --output ./build",
"gen-input": "NODE_OPTIONS=--max_old_space_size=8192 npx ts-node scripts/gen_input.ts",
"verify-proofs": "NODE_OPTIONS=--max_old_space_size=8192 npx ts-node scripts/verify_proofs.ts",
"test": "NODE_OPTIONS=--max_old_space_size=8192 jest"
},
"dependencies": {
"@zk-email/circuits": "^6.1.1",
"@zk-email/circuits": "^6.1.5",
"@zk-email/zk-regex-circom": "^2.1.0",
"@zk-email/relayer-utils": "^0.2.4",
"@zk-email/relayer-utils": "^0.3.7",
"commander": "^11.0.0",
"snarkjs": "^0.7.0"
},
Expand Down Expand Up @@ -41,4 +42,4 @@
]
]
}
}
}
42 changes: 31 additions & 11 deletions packages/circuits/scripts/dev-setup.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,8 @@ program
"--output <string>",
"Path to the directory storing output files"
)
.option("--silent", "No console logs");
.option("--silent", "No console logs")
.option("--body", "Enable body parsing");

program.parse();
const args = program.opts();
Expand All @@ -40,8 +41,12 @@ if (ZKEY_BEACON == null) {
ZKEY_BEACON = "0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f";
}

const phase1Url =
let phase1Url =
"https://hermez.s3-eu-west-1.amazonaws.com/powersOfTau28_hez_final_22.ptau";
if (args.body) {
phase1Url =
"https://hermez.s3-eu-west-1.amazonaws.com/powersOfTau28_hez_final_23.ptau";
}
// const buildDir = path.join(__dirname, "../build");
// const phase1Path = path.join(buildDir, "powersOfTau28_hez_final_21.ptau");
// const r1cPath = path.join(buildDir, "wallet.r1cs");
Expand Down Expand Up @@ -135,19 +140,34 @@ async function generateKeys(

async function exec() {
const buildDir = args.output;
const phase1Path = path.join(buildDir, "powersOfTau28_hez_final_22.ptau");

await downloadPhase1(phase1Path);
log("✓ Phase 1:", phase1Path);

const emailAuthR1csPath = path.join(buildDir, "email_auth.r1cs");
if (!fs.existsSync(emailAuthR1csPath)) {
throw new Error(`${emailAuthR1csPath} does not exist.`);
if (!args.body) {
const phase1Path = path.join(buildDir, "powersOfTau28_hez_final_22.ptau");

await downloadPhase1(phase1Path);
log("✓ Phase 1:", phase1Path);

const emailAuthR1csPath = path.join(buildDir, "email_auth.r1cs");
if (!fs.existsSync(emailAuthR1csPath)) {
throw new Error(`${emailAuthR1csPath} does not exist.`);
}
await generateKeys(phase1Path, emailAuthR1csPath, path.join(buildDir, "email_auth.zkey"), path.join(buildDir, "email_auth.vkey"), path.join(buildDir, "Groth16Verifier.sol"));
log("✓ Keys for email auth circuit generated");
} else {
const phase1Path = path.join(buildDir, "powersOfTau28_hez_final_23.ptau");

await downloadPhase1(phase1Path);
log("✓ Phase 1:", phase1Path);

const emailAuthR1csPath = path.join(buildDir, "email_auth_with_body_parsing_with_qp_encoding.r1cs");
if (!fs.existsSync(emailAuthR1csPath)) {
throw new Error(`${emailAuthR1csPath} does not exist.`);
}
await generateKeys(phase1Path, emailAuthR1csPath, path.join(buildDir, "email_auth_with_body_parsing_with_qp_encoding.zkey"), path.join(buildDir, "email_auth_with_body_parsing_with_qp_encoding.vkey"), path.join(buildDir, "Groth16BodyParsingVerifier.sol"));
log("✓ Keys for email auth with body parsing circuit generated");
}
await generateKeys(phase1Path, emailAuthR1csPath, path.join(buildDir, "email_auth.zkey"), path.join(buildDir, "email_auth.vkey"), path.join(buildDir, "Groth16Verifier.sol"));
log("✓ Keys for email auth circuit generated");


}


Expand Down
53 changes: 41 additions & 12 deletions packages/circuits/scripts/gen_input.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
import { program } from "commander";
import fs from "fs";
import { promisify } from "util";
import { genEmailAuthInput } from "../helpers/email_auth";
import { genEmailCircuitInput } from "../helpers/email_auth";
import path from "path";
const snarkjs = require("snarkjs");

Expand All @@ -26,6 +26,7 @@ program
"Path of a json file to write the generated input"
)
.option("--silent", "No console logs")
.option("--body", "Enable body parsing")
.option("--prove", "Also generate proof");

program.parse();
Expand All @@ -42,21 +43,49 @@ async function generate() {
throw new Error("--input file path arg must end with .json");
}

log("Generating Inputs for:", args);
if (!args.body) {
log("Generating Inputs for:", args);

const circuitInputs = await genEmailAuthInput(args.emailFile, args.accountCode);
log("\n\nGenerated Inputs:", circuitInputs, "\n\n");
const circuitInputs = await genEmailCircuitInput(args.emailFile, args.accountCode, {
maxHeaderLength: 1024,
ignoreBodyHashCheck: true
});
log("\n\nGenerated Inputs:", circuitInputs, "\n\n");

await promisify(fs.writeFile)(args.inputFile, JSON.stringify(circuitInputs, null, 2));
await promisify(fs.writeFile)(args.inputFile, JSON.stringify(circuitInputs, null, 2));

log("Inputs written to", args.inputFile);
log("Inputs written to", args.inputFile);

if (args.prove) {
const dir = path.dirname(args.inputFile);
const { proof, publicSignals } = await snarkjs.groth16.fullProve(circuitInputs, path.join(dir, "email_auth.wasm"), path.join(dir, "email_auth.zkey"), console);
await promisify(fs.writeFile)(path.join(dir, "email_auth_proof.json"), JSON.stringify(proof, null, 2));
await promisify(fs.writeFile)(path.join(dir, "email_auth_public.json"), JSON.stringify(publicSignals, null, 2));
log("✓ Proof for email auth circuit generated");
if (args.prove) {
const dir = path.dirname(args.inputFile);
const { proof, publicSignals } = await snarkjs.groth16.fullProve(circuitInputs, path.join(dir, "email_auth.wasm"), path.join(dir, "email_auth.zkey"), console);
await promisify(fs.writeFile)(path.join(dir, "email_auth_proof.json"), JSON.stringify(proof, null, 2));
await promisify(fs.writeFile)(path.join(dir, "email_auth_public.json"), JSON.stringify(publicSignals, null, 2));
log("✓ Proof for email auth circuit generated");
}
} else {
log("Generating Inputs for:", args);

const { subject_idx, ...circuitInputs } = await genEmailCircuitInput(args.emailFile, args.accountCode, {
maxHeaderLength: 1024,
maxBodyLength: 1024,
ignoreBodyHashCheck: false,
shaPrecomputeSelector: '(<div id=3D\"[^\"]*zkemail[^\"]*\"[^>]*>)'
});
console.log(circuitInputs.padded_body.length);
log("\n\nGenerated Inputs:", circuitInputs, "\n\n");

await promisify(fs.writeFile)(args.inputFile, JSON.stringify(circuitInputs, null, 2));

log("Inputs written to", args.inputFile);

if (args.prove) {
const dir = path.dirname(args.inputFile);
const { proof, publicSignals } = await snarkjs.groth16.fullProve(circuitInputs, path.join(dir, "email_auth_with_body_parsing_with_qp_encoding.wasm"), path.join(dir, "email_auth_with_body_parsing_with_qp_encoding.zkey"), console);
await promisify(fs.writeFile)(path.join(dir, "email_auth_with_body_parsing_with_qp_encoding_proof.json"), JSON.stringify(proof, null, 2));
await promisify(fs.writeFile)(path.join(dir, "email_auth_with_body_parsing_with_qp_encoding_public.json"), JSON.stringify(publicSignals, null, 2));
log("✓ Proof for email auth circuit generated");
}
}
process.exit(0);
}
Expand Down
Loading
Loading