diff --git a/docs/MiscellaniousDocs/README.md b/docs/miscellanious-docs/README.md similarity index 100% rename from docs/MiscellaniousDocs/README.md rename to docs/miscellanious-docs/README.md diff --git a/docs/MiscellaniousDocs/twitterREADME.md b/docs/miscellanious-docs/twitterREADME.md similarity index 100% rename from docs/MiscellaniousDocs/twitterREADME.md rename to docs/miscellanious-docs/twitterREADME.md diff --git a/docs/zkEmailDocs/Installation/README.md b/docs/zk-email-docs/Installation/README.md similarity index 100% rename from docs/zkEmailDocs/Installation/README.md rename to docs/zk-email-docs/Installation/README.md diff --git a/docs/zkEmailDocs/Package Overviews/README.md b/docs/zk-email-docs/Package Overviews/README.md similarity index 100% rename from docs/zkEmailDocs/Package Overviews/README.md rename to docs/zk-email-docs/Package Overviews/README.md diff --git a/docs/zkEmailDocs/UsageGuide/README.md b/docs/zk-email-docs/UsageGuide/README.md similarity index 87% rename from docs/zkEmailDocs/UsageGuide/README.md rename to docs/zk-email-docs/UsageGuide/README.md index 84557aaeb..6858c0764 100644 --- a/docs/zkEmailDocs/UsageGuide/README.md +++ b/docs/zk-email-docs/UsageGuide/README.md @@ -108,10 +108,12 @@ To compile the circuit locally, you need to have Rust and Circom installed first ```bash circom MyCircuit.circom -o --r1cs --wasm --sym --c ``` -*Note: You can add -l to specify the directory where the directive `include` should look for the circuits indicated. For our repo use circom -l node_modules instead of circom. +*Note: You can add `-l` to specify the directory where the directive `include` should look for the circuits indicated. For our repo, use `circom -l node_modules` instead of `circom`. Additionally, we generally recommend using the `--O0` flag for optimization during compilation for beginners. However, if you're more experienced with Circom, feel free to use the `--O1` flag instead. It's important to avoid using the `--O2` flag as that is the default setting and it may lead to the deletion of additional constraints.* After running this command, the circuit will be compiled into a `.r1cs` file, a `.wasm` file, and a `.sym` file. These files are used in the next steps to generate the proving and verifying keys, and to compute the witness. + + ## Step 5: Compute the Witness The process of creating a proof involves ensuring that all signals in the file adhere to the existing constraints. This is achieved by computing the witness using the Wasm file generated during compilation. @@ -143,15 +145,20 @@ node --max-old-space-size=614400 ./../node_modules/.bin/snarkjs ### Powers of Tau -After obtaining the constraint size, find the next highest power of 2 and replace the '12' in the following command with that number. This command initiates the Powers of tau ceremony. + +Based on the amount of constraints you have, there are different ptau files that you are able to download. You can download the ptau file directly from Google Cloud Platform using the following command: ``` -snarkjs powersoftau new bn128 12 pot12_0000.ptau -v -``` +// For projects with up to 2 million constraints: +wget https://storage.googleapis.com/zkevm/ptau/powersOfTau28_hez_final_21.ptau -Then contribute to the ceremony by running: -```bash -snarkjs powersoftau contribute pot12_0000.ptau pot12_0001.ptau --name="First contribution" -v +// For projects with up to 4 million constraints: +wget https://storage.googleapis.com/zkevm/ptau/powersOfTau28_hez_final_22.ptau + +// For projects with up to 8 million constraints: +wget https://storage.googleapis.com/zkevm/ptau/powersOfTau28_hez_final_23.ptau + +Refer to this link for more details: https://github.com/iden3/snarkjs?tab=readme-ov-file#7-prepare-phase-2 ``` ### Phase 2 diff --git a/packages/circuits/README.md b/packages/circuits/README.md index 673855501..21e5631a7 100644 --- a/packages/circuits/README.md +++ b/packages/circuits/README.md @@ -45,7 +45,26 @@ This template provides functionality for performing arithmetic operations in fin ### utils.circom -This template includes a collection of utility functions used across multiple circuits, such as bit manipulation functions, comparison functions, or conversion functions. +The `utils.circom` file includes a collection of utility templates and functions that are used across multiple circuits. These utilities cover a wide range of functionalities, including bit manipulation, comparison, conversion, and arithmetic operations in finite fields. It serves as a foundational component for building complex arithmetic circuits. + +## Utility templates + +### bytes2ints.circom + +This template converts an array of bytes into an array of integers. It is designed to handle inputs of any byte size and outputs integers based on the number of bytes specified. This is particularly useful for processing large binary data within arithmetic circuits. Specifically, the template is configured to transform 31 bytes into one integer, aligning with circoms maximum field value which is a 31-byte number. It uses little endian order for representation. +### constants.circom + +This file defines a set of constants used across various templates within the `circuits` package. These constants include maximum sizes for emails, domains, and timestamps, as well as specifications for packing bytes into field elements. + +### digit2int.circom + +The `Digit2Int` template converts an array of digit characters (0-9) into their corresponding integer representation. This is useful for processing numeric data that is input as a sequence of characters. + +### hex2int.circom + +This template provides functionality for converting hexadecimal strings into their integer representation. It supports conversion of both lowercase (a-f) and uppercase (A-F) hexadecimal characters. This is essential for processing hexadecimal data within arithmetic circuits. + + ## Overview of email-verifier.circom @@ -82,3 +101,4 @@ The template performs several operations: For a more in-depth understanding, please visit our zk Email Verify repository at https://github.com/zkemail/zk-email-verify. + diff --git a/packages/circuits/emailtest.circom b/packages/circuits/emailtest.circom deleted file mode 100644 index f369daf44..000000000 --- a/packages/circuits/emailtest.circom +++ /dev/null @@ -1,128 +0,0 @@ - -pragma circom 2.1.5; - -include "circomlib/circuits/bitify.circom"; -include "circomlib/circuits/comparators.circom"; -include "circomlib/circuits/poseidon.circom"; -include "@zk-email/circuits/email-verifier.circom"; -include "@zk-email/circuits/helpers/extract.circom"; -include "@zk-email/circuits/utils/constants.circom"; -include "@zk-email/circuits/utils/email_addr_pointer.circom"; -include "@zk-email/circuits/utils/email_addr_commit.circom"; -include "@zk-email/circuits/utils/hash_sign.circom"; -include "@zk-email/circuits/utils/email_nullifier.circom"; -include "./utils/bytes2ints.circom"; -include "./utils/digit2int.circom"; -include "@zk-email/zk-regex-circom/circuits/common/from_addr_regex.circom"; -include "@zk-email/zk-regex-circom/circuits/common/email_addr_regex.circom"; -include "@zk-email/zk-regex-circom/circuits/common/email_domain_regex.circom"; -include "@zk-email/zk-regex-circom/circuits/common/subject_all_regex.circom"; -include "@zk-email/zk-regex-circom/circuits/common/timestamp_regex.circom"; - -// Verify email from user (sender) and extract subject, timestmap, recipient email (commitment), etc. -// * n - the number of bits in each chunk of the RSA public key (modulust) -// * k - the number of chunks in the RSA public key (n * k > 2048) -// * max_header_bytes - max number of bytes in the email header -// * max_subject_bytes - max number of bytes in the email subject -template EmailSender(n, k, max_header_bytes, max_subject_bytes) { - signal input in_padded[max_header_bytes]; // email data (only header part) - signal input pubkey[k]; // RSA pubkey (modulus), k parts of n bits each. - signal input signature[k]; // RSA signature, k parts of n bits each. - signal input in_padded_len; // length of in email data including the padding - signal input sender_email_idx; // Index of the from email address (= sender email address) in the email header - signal input subject_idx; // Index of the subject in the header - signal input domain_idx; // Index of the domain name in the from email address - signal input timestamp_idx; // Index of the timestamp in the header - - var email_max_bytes = email_max_bytes_const(); - var email_max_len = compute_ints_size(email_max_bytes); - - var subject_field_len = compute_ints_size(max_subject_bytes); - - var domain_len = domain_len_const(); - var domain_filed_len = compute_ints_size(domain_len); - - var k2_chunked_size = k >> 1; - if(k % 2 == 1) { - k2_chunked_size += 1; - } - var timestamp_len = timestamp_len_const(); - - signal output masked_subject_str[subject_field_len]; - signal output domain_name[domain_filed_len]; - signal output hfrom[email_max_len]; - signal output hsubject[subject_field_len]; - signal output pubkey_hash; - signal output email_nullifier; - signal output sender_pointer; - signal output timestamp; - - // Verify Email Signature - component email_verifier = EmailVerifier(max_header_bytes, 0, n, k, 1); - email_verifier.in_padded <== in_padded; - email_verifier.pubkey <== pubkey; - email_verifier.signature <== signature; - email_verifier.in_len_padded_bytes <== in_padded_len; - signal header_hash[256] <== email_verifier.sha; - pubkey_hash <== email_verifier.pubkey_hash; - - // FROM HEADER REGEX - signal from_regex_out, from_regex_reveal[max_header_bytes]; - (from_regex_out, from_regex_reveal) <== FromAddrRegex(max_header_bytes)(in_padded); - from_regex_out === 1; - signal sender_email_addr[email_max_bytes]; - sender_email_addr <== VarShiftMaskedStr(max_header_bytes, email_max_bytes)(from_regex_reveal, sender_email_idx); - hfrom <== Bytes2Ints(email_max_bytes)(sender_email_addr); - - // SUBJECT HEADER REGEX - signal subject_regex_out, subject_regex_reveal[max_header_bytes]; - (subject_regex_out, subject_regex_reveal) <== SubjectAllRegex(max_header_bytes)(in_padded); - subject_regex_out === 1; - signal subject_all[max_subject_bytes]; - subject_all <== VarShiftMaskedStr(max_header_bytes, max_subject_bytes)(subject_regex_reveal, subject_idx); - hsubject <== Bytes2Ints(max_subject_bytes)(subject_all); - - // DOMAIN NAME HEADER REGEX - signal domain_regex_out, domain_regex_reveal[email_max_bytes]; - (domain_regex_out, domain_regex_reveal) <== EmailDomainRegex(email_max_bytes)(sender_email_addr); - domain_regex_out === 1; - signal domain_name_bytes[domain_len]; - domain_name_bytes <== VarShiftMaskedStr(email_max_bytes, domain_len)(domain_regex_reveal, domain_idx); - domain_name <== Bytes2Ints(domain_len)(domain_name_bytes); - - - // Email address pointer - /* - var num_email_addr_ints = compute_ints_size(email_max_bytes); - signal sender_email_addr_ints[num_email_addr_ints] <== Bytes2Ints(email_max_bytes)(sender_email_addr); - sender_pointer <== EmailAddrPointer(num_email_addr_ints)(sender_relayer_rand, sender_email_addr_ints); -*/ - - // Email address commitment - /*signal cm_rand_input[k2_chunked_size+1]; - for(var i=0; i> 1; - if(k % 2 == 1) { - k2_chunked_size += 1; - } - signal output sign_ints[k2_chunked_size]; - - // signal pubkey_hash_input[k2_chunked_size]; - // for(var i = 0; i < k2_chunked_size; i++) { - // if(i==k2_chunked_size-1 && k2_chunked_size % 2 == 1) { - // pubkey_hash_input[i] <== pubkey[2*i]; - // } else { - // pubkey_hash_input[i] <== pubkey[2*i] + (1< { + + const emailStr = email.toString(); + + const pgpMarkers = [ + "BEGIN PGP MESSAGE", + "BEGIN PGP SIGNED MESSAGE", + ]; + + const isPGPEncoded = pgpMarkers.some(marker => emailStr.includes(marker)); + + if (isPGPEncoded) { + throw new Error("PGP encoded emails are not supported."); + } + let dkimResult = await tryVerifyDKIM(email, domain); if (dkimResult.status.result !== "pass" && tryRevertARCChanges) {