From 05ac39baa97bdc08b4ed6cf762b1e6d0e6919f6e Mon Sep 17 00:00:00 2001 From: shreyas-londhe Date: Fri, 6 Sep 2024 17:00:00 +0530 Subject: [PATCH 1/8] feat: added header masking --- packages/circuits/README.md | 51 ++++++++++++++++- packages/circuits/email-verifier.circom | 23 ++++++-- ...{body-masker.test.ts => byte-mask.test.ts} | 6 +- .../circuits/tests/email-verifier.test.ts | 57 ++++++++++++++++++- ...sker-test.circom => byte-mask-test.circom} | 0 .../email-verifier-no-body-test.circom | 2 +- .../test-circuits/email-verifier-test.circom | 2 +- ...email-verifier-with-body-mask-test.circom} | 2 +- ...mail-verifier-with-header-mask-test.circom | 5 ++ ...verifier-with-soft-line-breaks-test.circom | 2 +- packages/circuits/utils/bytes.circom | 22 +++---- packages/helpers/src/input-generators.ts | 13 ++++- 12 files changed, 155 insertions(+), 30 deletions(-) rename packages/circuits/tests/{body-masker.test.ts => byte-mask.test.ts} (87%) rename packages/circuits/tests/test-circuits/{body-masker-test.circom => byte-mask-test.circom} (100%) rename packages/circuits/tests/test-circuits/{email-verifier-with-mask-test.circom => email-verifier-with-body-mask-test.circom} (85%) create mode 100644 packages/circuits/tests/test-circuits/email-verifier-with-header-mask-test.circom diff --git a/packages/circuits/README.md b/packages/circuits/README.md index 232f94a6..af39cdbe 100644 --- a/packages/circuits/README.md +++ b/packages/circuits/README.md @@ -29,6 +29,9 @@ include "@zk-email/circuits/email-verifier.circom"; - `n`: Number of bits per chunk the RSA key is split into. Recommended to be 121. - `k`: Number of chunks the RSA key is split into. Recommended to be 17. - `ignoreBodyHashCheck`: Set 1 to skip body hash check in case data to prove/extract is only in the headers. + - `enableHeaderMasking`: Set 1 to turn on header masking. + - `enableBodyMasking`: Set 1 to turn on body masking. + - `removeSoftLineBreaks`: Set 1 to remove soft line breaks (`=\r\n`) from the email body. `Note`: We use these values for n and k because their product (n * k) needs to be more than 2048 (RSA constraint) and n has to be less than half of 255 to fit in a circom signal. @@ -41,10 +44,14 @@ include "@zk-email/circuits/email-verifier.circom"; - `emailBodyLength`: Length of the email body including the SHA-256 padding. - `bodyHashIndex`: Index of the body hash `bh` in the `emailHeader`. - `precomputedSHA[32]`: Precomputed SHA-256 hash of the email body till the bodyHashIndex. + - `headerMask[maxHeadersLength]`: Mask to be applied on the `emailHeader`. + - `bodyMask[maxBodyLength]`: Mask to be applied on the `emailBody`. + - `decodedEmailBody[maxBodyLength]`: Decoded email body after removing soft line breaks. **Output Signal** - `pubkeyHash`: Poseidon hash of the pubkey - Poseidon(n/2)(n/2 chunks of pubkey with k*2 bits per chunk). - + - `maskedHeader[maxHeadersLength]`: Masked email header. + - `maskedBody[maxBodyLength]`: Masked email body.
## **Libraries** @@ -257,6 +264,33 @@ DigitBytesToInt: Converts a byte array representing digits to an integer. - `out`: The output integer after conversion. +
+ +AssertBit: Asserts that a given input is binary. + + +- **[Source](utils/bytes.circom#L1-L7)** +- **Inputs**: + - `in`: An input signal, expected to be 0 or 1. +- **Outputs**: + - None. This template will throw an assertion error if the input is not binary. + +
+ +
+ +ByteMask: Masks an input array using a binary mask array. + + +- **[Source](utils/bytes.circom#L9-L25)** +- **Parameters**: + - `maxLength`: The maximum length of the input and mask arrays. +- **Inputs**: + - `in`: An array of signals representing the body to be masked. + - `mask`: An array of signals representing the binary mask. +- **Outputs**: + - `out`: An array of signals representing the masked input. +
### `utils/constants.circom` @@ -359,5 +393,20 @@ EmailNullifier: Calculates the email nullifier using Poseidon hash. - `out`: The email nullifier. +### `helpers/remove-soft-line-breaks.circom` + +
+ +RemoveSoftLineBreaks: Verifies the removal of soft line breaks from an encoded input string. + +- **[Source](helpers/remove-soft-line-breaks.circom)** +- **Parameters**: + - `maxLength`: The maximum length of the input strings. +- **Inputs**: + - `encoded[maxLength]`: An array of ASCII values representing the input string with potential soft line breaks. + - `decoded[maxLength]`: An array of ASCII values representing the expected output after removing soft line breaks. +- **Outputs**: + - `isValid`: A signal that is 1 if the decoded input correctly represents the encoded input with soft line breaks removed, 0 otherwise. +
\ No newline at end of file diff --git a/packages/circuits/email-verifier.circom b/packages/circuits/email-verifier.circom index 51a495b9..83c3dd35 100644 --- a/packages/circuits/email-verifier.circom +++ b/packages/circuits/email-verifier.circom @@ -22,8 +22,9 @@ include "./helpers/remove-soft-line-breaks.circom"; /// @param n Number of bits per chunk the RSA key is split into. Recommended to be 121. /// @param k Number of chunks the RSA key is split into. Recommended to be 17. /// @param ignoreBodyHashCheck Set 1 to skip body hash check in case data to prove/extract is only in the headers. -/// @param removeSoftLineBreaks Set 1 to remove soft line breaks from the email body. +/// @param enableHeaderMasking Set 1 to turn on header masking. /// @param enableBodyMasking Set 1 to turn on body masking. +/// @param removeSoftLineBreaks Set 1 to remove soft line breaks from the email body. /// @input emailHeader[maxHeadersLength] Email headers that are signed (ones in `DKIM-Signature` header) as ASCII int[], padded as per SHA-256 block size. /// @input emailHeaderLength Length of the email header including the SHA-256 padding. /// @input pubkey[k] RSA public key split into k chunks of n bits each. @@ -36,8 +37,9 @@ include "./helpers/remove-soft-line-breaks.circom"; /// @input mask[maxBodyLength] Mask for the email body. /// @output pubkeyHash Poseidon hash of the pubkey - Poseidon(n/2)(n/2 chunks of pubkey with k*2 bits per chunk). /// @output decodedEmailBodyOut[maxBodyLength] Decoded email body with soft line breaks removed. +/// @output maskedHeader[maxHeadersLength] Masked email header. /// @output maskedBody[maxBodyLength] Masked email body. -template EmailVerifier(maxHeadersLength, maxBodyLength, n, k, ignoreBodyHashCheck, removeSoftLineBreaks, enableBodyMasking) { +template EmailVerifier(maxHeadersLength, maxBodyLength, n, k, ignoreBodyHashCheck, enableHeaderMasking, enableBodyMasking, removeSoftLineBreaks) { assert(maxHeadersLength % 64 == 0); assert(maxBodyLength % 64 == 0); assert(n * k > 2048); // to support 2048 bit RSA @@ -89,6 +91,15 @@ template EmailVerifier(maxHeadersLength, maxBodyLength, n, k, ignoreBodyHashChec rsaVerifier.modulus <== pubkey; rsaVerifier.signature <== signature; + if (enableHeaderMasking == 1) { + signal input headerMask[maxHeadersLength]; + signal output maskedHeader[maxHeadersLength]; + component byteMask = ByteMask(maxHeadersLength); + + byteMask.in <== emailHeader; + byteMask.mask <== headerMask; + maskedHeader <== byteMask.out; + } // Calculate the SHA256 hash of the body and verify it matches the hash in the header if (ignoreBodyHashCheck != 1) { @@ -145,13 +156,13 @@ template EmailVerifier(maxHeadersLength, maxBodyLength, n, k, ignoreBodyHashChec } if (enableBodyMasking == 1) { - signal input mask[maxBodyLength]; + signal input bodyMask[maxBodyLength]; signal output maskedBody[maxBodyLength]; component byteMask = ByteMask(maxBodyLength); - byteMask.body <== emailBody; - byteMask.mask <== mask; - maskedBody <== byteMask.maskedBody; + byteMask.in <== emailBody; + byteMask.mask <== bodyMask; + maskedBody <== byteMask.out; } } diff --git a/packages/circuits/tests/body-masker.test.ts b/packages/circuits/tests/byte-mask.test.ts similarity index 87% rename from packages/circuits/tests/body-masker.test.ts rename to packages/circuits/tests/byte-mask.test.ts index c1fd513b..bafbfc4e 100644 --- a/packages/circuits/tests/body-masker.test.ts +++ b/packages/circuits/tests/byte-mask.test.ts @@ -6,7 +6,7 @@ describe("ByteMask Circuit", () => { beforeAll(async () => { circuit = await wasm_tester( - path.join(__dirname, "./test-circuits/body-masker-test.circom"), + path.join(__dirname, "./test-circuits/byte-mask-test.circom"), { recompile: true, include: path.join(__dirname, "../../../node_modules"), @@ -17,14 +17,14 @@ describe("ByteMask Circuit", () => { it("should mask the body correctly", async () => { const input = { - body: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10], + in: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10], mask: [1, 0, 1, 0, 1, 0, 1, 0, 1, 0], }; const witness = await circuit.calculateWitness(input); await circuit.checkConstraints(witness); await circuit.assertOut(witness, { - maskedBody: [1, 0, 3, 0, 5, 0, 7, 0, 9, 0], + out: [1, 0, 3, 0, 5, 0, 7, 0, 9, 0], }); }); diff --git a/packages/circuits/tests/email-verifier.test.ts b/packages/circuits/tests/email-verifier.test.ts index e5a26bf9..c520b7d1 100644 --- a/packages/circuits/tests/email-verifier.test.ts +++ b/packages/circuits/tests/email-verifier.test.ts @@ -265,7 +265,7 @@ describe("EmailVerifier : With body masking", () => { circuit = await wasm_tester( path.join( __dirname, - "./test-circuits/email-verifier-with-mask-test.circom" + "./test-circuits/email-verifier-with-body-mask-test.circom" ), { recompile: true, @@ -287,7 +287,7 @@ describe("EmailVerifier : With body masking", () => { maxBodyLength: 768, ignoreBodyHashCheck: false, enableBodyMasking: true, - mask: mask.map((value) => (value ? 1 : 0)), + bodyMask: mask.map((value) => (value ? 1 : 0)), } ); @@ -344,3 +344,56 @@ describe("EmailVerifier : With soft line breaks", () => { await circuit.checkConstraints(witness); }); }); + +describe("EmailVerifier : With header masking", () => { + jest.setTimeout(10 * 60 * 1000); // 10 minutes + + let dkimResult: DKIMVerificationResult; + let circuit: any; + + beforeAll(async () => { + const rawEmail = fs.readFileSync( + path.join(__dirname, "./test-emails/test.eml") + ); + dkimResult = await verifyDKIMSignature(rawEmail); + + circuit = await wasm_tester( + path.join( + __dirname, + "./test-circuits/email-verifier-with-header-mask-test.circom" + ), + { + recompile: true, + include: path.join(__dirname, "../../../node_modules"), + output: path.join(__dirname, "./compiled-test-circuits"), + } + ); + }); + + it("should verify email with header masking", async function () { + const mask = Array.from({ length: 640 }, (_, i) => + i > 25 && i < 50 ? 1 : 0 + ); + + const emailVerifierInputs = generateEmailVerifierInputsFromDKIMResult( + dkimResult, + { + maxHeadersLength: 640, + maxBodyLength: 768, + ignoreBodyHashCheck: false, + enableHeaderMasking: true, + headerMask: mask.map((value) => (value ? 1 : 0)), + } + ); + + const expectedMaskedHeader = emailVerifierInputs.emailHeader!.map( + (byte, i) => (mask[i] === 1 ? byte : 0) + ); + + const witness = await circuit.calculateWitness(emailVerifierInputs); + await circuit.checkConstraints(witness); + await circuit.assertOut(witness, { + maskedHeader: expectedMaskedHeader, + }); + }); +}); diff --git a/packages/circuits/tests/test-circuits/body-masker-test.circom b/packages/circuits/tests/test-circuits/byte-mask-test.circom similarity index 100% rename from packages/circuits/tests/test-circuits/body-masker-test.circom rename to packages/circuits/tests/test-circuits/byte-mask-test.circom diff --git a/packages/circuits/tests/test-circuits/email-verifier-no-body-test.circom b/packages/circuits/tests/test-circuits/email-verifier-no-body-test.circom index 39c19114..d2c0ea8e 100644 --- a/packages/circuits/tests/test-circuits/email-verifier-no-body-test.circom +++ b/packages/circuits/tests/test-circuits/email-verifier-no-body-test.circom @@ -2,4 +2,4 @@ pragma circom 2.1.6; include "../../email-verifier.circom"; -component main { public [ pubkey ] } = EmailVerifier(640, 768, 121, 17, 1, 0, 0); +component main { public [ pubkey ] } = EmailVerifier(640, 768, 121, 17, 1, 0, 0, 0); diff --git a/packages/circuits/tests/test-circuits/email-verifier-test.circom b/packages/circuits/tests/test-circuits/email-verifier-test.circom index 858a5443..af7a24c1 100644 --- a/packages/circuits/tests/test-circuits/email-verifier-test.circom +++ b/packages/circuits/tests/test-circuits/email-verifier-test.circom @@ -2,4 +2,4 @@ pragma circom 2.1.6; include "../../email-verifier.circom"; -component main { public [ pubkey ] } = EmailVerifier(640, 768, 121, 17, 0, 0, 0); +component main { public [ pubkey ] } = EmailVerifier(640, 768, 121, 17, 0, 0, 0, 0); diff --git a/packages/circuits/tests/test-circuits/email-verifier-with-mask-test.circom b/packages/circuits/tests/test-circuits/email-verifier-with-body-mask-test.circom similarity index 85% rename from packages/circuits/tests/test-circuits/email-verifier-with-mask-test.circom rename to packages/circuits/tests/test-circuits/email-verifier-with-body-mask-test.circom index 66181b39..a7c1db1b 100644 --- a/packages/circuits/tests/test-circuits/email-verifier-with-mask-test.circom +++ b/packages/circuits/tests/test-circuits/email-verifier-with-body-mask-test.circom @@ -2,4 +2,4 @@ pragma circom 2.1.6; include "../../email-verifier.circom"; -component main { public [ pubkey ] } = EmailVerifier(640, 768, 121, 17, 0, 0, 1); +component main { public [ pubkey ] } = EmailVerifier(640, 768, 121, 17, 0, 0, 1, 0); diff --git a/packages/circuits/tests/test-circuits/email-verifier-with-header-mask-test.circom b/packages/circuits/tests/test-circuits/email-verifier-with-header-mask-test.circom new file mode 100644 index 00000000..e9ac69d1 --- /dev/null +++ b/packages/circuits/tests/test-circuits/email-verifier-with-header-mask-test.circom @@ -0,0 +1,5 @@ +pragma circom 2.1.6; + +include "../../email-verifier.circom"; + +component main { public [ pubkey ] } = EmailVerifier(640, 768, 121, 17, 0, 1, 0, 0); diff --git a/packages/circuits/tests/test-circuits/email-verifier-with-soft-line-breaks-test.circom b/packages/circuits/tests/test-circuits/email-verifier-with-soft-line-breaks-test.circom index be74589d..b6e52bbd 100644 --- a/packages/circuits/tests/test-circuits/email-verifier-with-soft-line-breaks-test.circom +++ b/packages/circuits/tests/test-circuits/email-verifier-with-soft-line-breaks-test.circom @@ -2,4 +2,4 @@ pragma circom 2.1.6; include "../../email-verifier.circom"; -component main { public [ pubkey ] } = EmailVerifier(640, 1408, 121, 17, 0, 1, 0); +component main { public [ pubkey ] } = EmailVerifier(640, 1408, 121, 17, 0, 0, 0, 1); diff --git a/packages/circuits/utils/bytes.circom b/packages/circuits/utils/bytes.circom index a394ce2e..2bc0c1cf 100644 --- a/packages/circuits/utils/bytes.circom +++ b/packages/circuits/utils/bytes.circom @@ -157,29 +157,29 @@ template AssertBit() { in * (in - 1) === 0; } -// The ByteMask template masks an input body array using a binary mask array. -// Each element in the body array is multiplied by the corresponding element in the mask array. +// The ByteMask template masks an input array using a binary mask array. +// Each element in the input array is multiplied by the corresponding element in the mask array. // The mask array is validated to ensure all elements are binary (0 or 1). // // Parameters: -// - maxBodyLength: The maximum length of the body and mask arrays. +// - maxLength: The maximum length of the input and mask arrays. // // Inputs: // - body: An array of signals representing the body to be masked. // - mask: An array of signals representing the binary mask. // // Outputs: -// - maskedBody: An array of signals representing the masked body. -template ByteMask(maxBodyLength) { - signal input body[maxBodyLength]; - signal input mask[maxBodyLength]; - signal output maskedBody[maxBodyLength]; +// - out: An array of signals representing the masked input. +template ByteMask(maxLength) { + signal input in[maxLength]; + signal input mask[maxLength]; + signal output out[maxLength]; - component bit_check[maxBodyLength]; + component bit_check[maxLength]; - for (var i = 0; i < maxBodyLength; i++) { + for (var i = 0; i < maxLength; i++) { bit_check[i] = AssertBit(); bit_check[i].in <== mask[i]; - maskedBody[i] <== body[i] * mask[i]; + out[i] <== in[i] * mask[i]; } } \ No newline at end of file diff --git a/packages/helpers/src/input-generators.ts b/packages/helpers/src/input-generators.ts index c6e76c41..dea4b575 100644 --- a/packages/helpers/src/input-generators.ts +++ b/packages/helpers/src/input-generators.ts @@ -13,17 +13,20 @@ type CircuitInput = { precomputedSHA?: string[]; bodyHashIndex?: string; decodedEmailBodyIn?: string[]; - mask?: number[]; + headerMask?: number[]; + bodyMask?: number[]; }; type InputGenerationArgs = { ignoreBodyHashCheck?: boolean; + enableHeaderMasking?: boolean; enableBodyMasking?: boolean; shaPrecomputeSelector?: string; maxHeadersLength?: number; // Max length of the email header including padding maxBodyLength?: number; // Max length of the email body after shaPrecomputeSelector including padding removeSoftLineBreaks?: boolean; - mask?: number[]; + headerMask?: number[]; + bodyMask?: number[]; }; function removeSoftLineBreaks(body: string[]): string[] { @@ -95,6 +98,10 @@ export function generateEmailVerifierInputsFromDKIMResult( signature: toCircomBigIntBytes(signature), }; + if (params.enableHeaderMasking) { + circuitInputs.headerMask = params.headerMask; + } + if (!params.ignoreBodyHashCheck) { if (!body || !bodyHash) { throw new Error( @@ -132,7 +139,7 @@ export function generateEmailVerifierInputsFromDKIMResult( } if (params.enableBodyMasking) { - circuitInputs.mask = params.mask; + circuitInputs.bodyMask = params.bodyMask; } } From e74aed7384f22fc3b067bd73e0dc4139ad5d1345 Mon Sep 17 00:00:00 2001 From: shreyas-londhe Date: Fri, 6 Sep 2024 17:13:34 +0530 Subject: [PATCH 2/8] fix: removed unnecessary output in remove-soft-line-breaks --- packages/circuits/email-verifier.circom | 3 --- 1 file changed, 3 deletions(-) diff --git a/packages/circuits/email-verifier.circom b/packages/circuits/email-verifier.circom index 83c3dd35..5315b9ff 100644 --- a/packages/circuits/email-verifier.circom +++ b/packages/circuits/email-verifier.circom @@ -144,15 +144,12 @@ template EmailVerifier(maxHeadersLength, maxBodyLength, n, k, ignoreBodyHashChec if (removeSoftLineBreaks == 1) { signal input decodedEmailBodyIn[maxBodyLength]; - signal output decodedEmailBodyOut[maxBodyLength]; component qpEncodingChecker = RemoveSoftLineBreaks(maxBodyLength); qpEncodingChecker.encoded <== emailBody; qpEncodingChecker.decoded <== decodedEmailBodyIn; qpEncodingChecker.isValid === 1; - - decodedEmailBodyOut <== qpEncodingChecker.decoded; } if (enableBodyMasking == 1) { From 480a3e410dc36c2c0da40c3b8704c2e2fa7396a6 Mon Sep 17 00:00:00 2001 From: shreyas-londhe Date: Fri, 6 Sep 2024 17:20:18 +0530 Subject: [PATCH 3/8] chore: refactor email-verifier tests --- .../tests/email-verifier-no-body.test.ts | 48 +++++ .../email-verifier-with-body-mask.test.ts | 59 ++++++ .../email-verifier-with-header-mask.test.ts | 59 ++++++ ...ail-verifier-with-soft-line-breaks.test.ts | 48 +++++ .../circuits/tests/email-verifier.test.ts | 191 ------------------ 5 files changed, 214 insertions(+), 191 deletions(-) create mode 100644 packages/circuits/tests/email-verifier-no-body.test.ts create mode 100644 packages/circuits/tests/email-verifier-with-body-mask.test.ts create mode 100644 packages/circuits/tests/email-verifier-with-header-mask.test.ts create mode 100644 packages/circuits/tests/email-verifier-with-soft-line-breaks.test.ts diff --git a/packages/circuits/tests/email-verifier-no-body.test.ts b/packages/circuits/tests/email-verifier-no-body.test.ts new file mode 100644 index 00000000..21780215 --- /dev/null +++ b/packages/circuits/tests/email-verifier-no-body.test.ts @@ -0,0 +1,48 @@ +import fs from "fs"; +import { wasm as wasm_tester } from "circom_tester"; +import path from "path"; +import { DKIMVerificationResult } from "@zk-email/helpers/src/dkim"; +import { generateEmailVerifierInputsFromDKIMResult } from "@zk-email/helpers/src/input-generators"; +import { verifyDKIMSignature } from "@zk-email/helpers/src/dkim"; + +describe("EmailVerifier : Without body check", () => { + jest.setTimeout(10 * 60 * 1000); // 10 minutes + + let dkimResult: DKIMVerificationResult; + let circuit: any; + + beforeAll(async () => { + const rawEmail = fs.readFileSync( + path.join(__dirname, "./test-emails/test.eml"), + "utf8" + ); + dkimResult = await verifyDKIMSignature(rawEmail); + + circuit = await wasm_tester( + path.join( + __dirname, + "./test-circuits/email-verifier-no-body-test.circom" + ), + { + recompile: true, + include: path.join(__dirname, "../../../node_modules"), + // output: path.join(__dirname, "./compiled-test-circuits"), + } + ); + }); + + it("should verify email when ignore_body_hash_check is true", async function () { + // The result wont have shaPrecomputeSelector, maxHeadersLength, maxBodyLength, ignoreBodyHashCheck + const emailVerifierInputs = generateEmailVerifierInputsFromDKIMResult( + dkimResult, + { + maxHeadersLength: 640, + maxBodyLength: 768, + ignoreBodyHashCheck: true, + } + ); + + const witness = await circuit.calculateWitness(emailVerifierInputs); + await circuit.checkConstraints(witness); + }); +}); diff --git a/packages/circuits/tests/email-verifier-with-body-mask.test.ts b/packages/circuits/tests/email-verifier-with-body-mask.test.ts new file mode 100644 index 00000000..11427173 --- /dev/null +++ b/packages/circuits/tests/email-verifier-with-body-mask.test.ts @@ -0,0 +1,59 @@ +import fs from "fs"; +import { wasm as wasm_tester } from "circom_tester"; +import path from "path"; +import { DKIMVerificationResult } from "@zk-email/helpers/src/dkim"; +import { generateEmailVerifierInputsFromDKIMResult } from "@zk-email/helpers/src/input-generators"; +import { verifyDKIMSignature } from "@zk-email/helpers/src/dkim"; + +describe("EmailVerifier : With body masking", () => { + jest.setTimeout(10 * 60 * 1000); // 10 minutes + + let dkimResult: DKIMVerificationResult; + let circuit: any; + + beforeAll(async () => { + const rawEmail = fs.readFileSync( + path.join(__dirname, "./test-emails/test.eml") + ); + dkimResult = await verifyDKIMSignature(rawEmail); + + circuit = await wasm_tester( + path.join( + __dirname, + "./test-circuits/email-verifier-with-body-mask-test.circom" + ), + { + recompile: true, + include: path.join(__dirname, "../../../node_modules"), + output: path.join(__dirname, "./compiled-test-circuits"), + } + ); + }); + + it("should verify email with body masking", async function () { + const mask = Array.from({ length: 768 }, (_, i) => + i > 25 && i < 50 ? 1 : 0 + ); + + const emailVerifierInputs = generateEmailVerifierInputsFromDKIMResult( + dkimResult, + { + maxHeadersLength: 640, + maxBodyLength: 768, + ignoreBodyHashCheck: false, + enableBodyMasking: true, + bodyMask: mask.map((value) => (value ? 1 : 0)), + } + ); + + const expectedMaskedBody = emailVerifierInputs.emailBody!.map( + (byte, i) => (mask[i] === 1 ? byte : 0) + ); + + const witness = await circuit.calculateWitness(emailVerifierInputs); + await circuit.checkConstraints(witness); + await circuit.assertOut(witness, { + maskedBody: expectedMaskedBody, + }); + }); +}); diff --git a/packages/circuits/tests/email-verifier-with-header-mask.test.ts b/packages/circuits/tests/email-verifier-with-header-mask.test.ts new file mode 100644 index 00000000..1fac9cd5 --- /dev/null +++ b/packages/circuits/tests/email-verifier-with-header-mask.test.ts @@ -0,0 +1,59 @@ +import fs from "fs"; +import { wasm as wasm_tester } from "circom_tester"; +import path from "path"; +import { DKIMVerificationResult } from "@zk-email/helpers/src/dkim"; +import { generateEmailVerifierInputsFromDKIMResult } from "@zk-email/helpers/src/input-generators"; +import { verifyDKIMSignature } from "@zk-email/helpers/src/dkim"; + +describe("EmailVerifier : With header masking", () => { + jest.setTimeout(10 * 60 * 1000); // 10 minutes + + let dkimResult: DKIMVerificationResult; + let circuit: any; + + beforeAll(async () => { + const rawEmail = fs.readFileSync( + path.join(__dirname, "./test-emails/test.eml") + ); + dkimResult = await verifyDKIMSignature(rawEmail); + + circuit = await wasm_tester( + path.join( + __dirname, + "./test-circuits/email-verifier-with-header-mask-test.circom" + ), + { + recompile: true, + include: path.join(__dirname, "../../../node_modules"), + output: path.join(__dirname, "./compiled-test-circuits"), + } + ); + }); + + it("should verify email with header masking", async function () { + const mask = Array.from({ length: 640 }, (_, i) => + i > 25 && i < 50 ? 1 : 0 + ); + + const emailVerifierInputs = generateEmailVerifierInputsFromDKIMResult( + dkimResult, + { + maxHeadersLength: 640, + maxBodyLength: 768, + ignoreBodyHashCheck: false, + enableHeaderMasking: true, + headerMask: mask.map((value) => (value ? 1 : 0)), + } + ); + + const expectedMaskedHeader = emailVerifierInputs.emailHeader!.map( + (byte, i) => (mask[i] === 1 ? byte : 0) + ); + + const witness = await circuit.calculateWitness(emailVerifierInputs); + await circuit.checkConstraints(witness); + await circuit.assertOut(witness, { + maskedHeader: expectedMaskedHeader, + }); + }); +}); diff --git a/packages/circuits/tests/email-verifier-with-soft-line-breaks.test.ts b/packages/circuits/tests/email-verifier-with-soft-line-breaks.test.ts new file mode 100644 index 00000000..9240521e --- /dev/null +++ b/packages/circuits/tests/email-verifier-with-soft-line-breaks.test.ts @@ -0,0 +1,48 @@ +import fs from "fs"; +import { wasm as wasm_tester } from "circom_tester"; +import path from "path"; +import { DKIMVerificationResult } from "@zk-email/helpers/src/dkim"; +import { generateEmailVerifierInputsFromDKIMResult } from "@zk-email/helpers/src/input-generators"; +import { verifyDKIMSignature } from "@zk-email/helpers/src/dkim"; + +describe("EmailVerifier : With soft line breaks", () => { + jest.setTimeout(10 * 60 * 1000); // 10 minutes + + let dkimResult: DKIMVerificationResult; + let circuit: any; + + beforeAll(async () => { + const rawEmail = fs.readFileSync( + path.join(__dirname, "./test-emails/lorem_ipsum.eml"), + "utf8" + ); + dkimResult = await verifyDKIMSignature(rawEmail); + + circuit = await wasm_tester( + path.join( + __dirname, + "./test-circuits/email-verifier-with-soft-line-breaks-test.circom" + ), + { + recompile: true, + include: path.join(__dirname, "../../../node_modules"), + output: path.join(__dirname, "./compiled-test-circuits"), + } + ); + }); + + it("should verify email when removeSoftLineBreaks is true", async function () { + const emailVerifierInputs = generateEmailVerifierInputsFromDKIMResult( + dkimResult, + { + maxHeadersLength: 640, + maxBodyLength: 1408, + ignoreBodyHashCheck: false, + removeSoftLineBreaks: true, + } + ); + + const witness = await circuit.calculateWitness(emailVerifierInputs); + await circuit.checkConstraints(witness); + }); +}); diff --git a/packages/circuits/tests/email-verifier.test.ts b/packages/circuits/tests/email-verifier.test.ts index c520b7d1..93eee579 100644 --- a/packages/circuits/tests/email-verifier.test.ts +++ b/packages/circuits/tests/email-verifier.test.ts @@ -1,5 +1,4 @@ import fs from "fs"; -import { buildPoseidon } from "circomlibjs"; import { wasm as wasm_tester } from "circom_tester"; import path from "path"; import { DKIMVerificationResult } from "@zk-email/helpers/src/dkim"; @@ -207,193 +206,3 @@ describe("EmailVerifier", () => { }); }); }); - -describe("EmailVerifier : Without body check", () => { - jest.setTimeout(10 * 60 * 1000); // 10 minutes - - let dkimResult: DKIMVerificationResult; - let circuit: any; - - beforeAll(async () => { - const rawEmail = fs.readFileSync( - path.join(__dirname, "./test-emails/test.eml"), - "utf8" - ); - dkimResult = await verifyDKIMSignature(rawEmail); - - circuit = await wasm_tester( - path.join( - __dirname, - "./test-circuits/email-verifier-no-body-test.circom" - ), - { - recompile: true, - include: path.join(__dirname, "../../../node_modules"), - // output: path.join(__dirname, "./compiled-test-circuits"), - } - ); - }); - - it("should verify email when ignore_body_hash_check is true", async function () { - // The result wont have shaPrecomputeSelector, maxHeadersLength, maxBodyLength, ignoreBodyHashCheck - const emailVerifierInputs = generateEmailVerifierInputsFromDKIMResult( - dkimResult, - { - maxHeadersLength: 640, - maxBodyLength: 768, - ignoreBodyHashCheck: true, - } - ); - - const witness = await circuit.calculateWitness(emailVerifierInputs); - await circuit.checkConstraints(witness); - }); -}); - -describe("EmailVerifier : With body masking", () => { - jest.setTimeout(10 * 60 * 1000); // 10 minutes - - let dkimResult: DKIMVerificationResult; - let circuit: any; - - beforeAll(async () => { - const rawEmail = fs.readFileSync( - path.join(__dirname, "./test-emails/test.eml") - ); - dkimResult = await verifyDKIMSignature(rawEmail); - - circuit = await wasm_tester( - path.join( - __dirname, - "./test-circuits/email-verifier-with-body-mask-test.circom" - ), - { - recompile: true, - include: path.join(__dirname, "../../../node_modules"), - output: path.join(__dirname, "./compiled-test-circuits"), - } - ); - }); - - it("should verify email with body masking", async function () { - const mask = Array.from({ length: 768 }, (_, i) => - i > 25 && i < 50 ? 1 : 0 - ); - - const emailVerifierInputs = generateEmailVerifierInputsFromDKIMResult( - dkimResult, - { - maxHeadersLength: 640, - maxBodyLength: 768, - ignoreBodyHashCheck: false, - enableBodyMasking: true, - bodyMask: mask.map((value) => (value ? 1 : 0)), - } - ); - - const expectedMaskedBody = emailVerifierInputs.emailBody!.map( - (byte, i) => (mask[i] === 1 ? byte : 0) - ); - - const witness = await circuit.calculateWitness(emailVerifierInputs); - await circuit.checkConstraints(witness); - await circuit.assertOut(witness, { - maskedBody: expectedMaskedBody, - }); - }); -}); - -describe("EmailVerifier : With soft line breaks", () => { - jest.setTimeout(10 * 60 * 1000); // 10 minutes - - let dkimResult: DKIMVerificationResult; - let circuit: any; - - beforeAll(async () => { - const rawEmail = fs.readFileSync( - path.join(__dirname, "./test-emails/lorem_ipsum.eml"), - "utf8" - ); - dkimResult = await verifyDKIMSignature(rawEmail); - - circuit = await wasm_tester( - path.join( - __dirname, - "./test-circuits/email-verifier-with-soft-line-breaks-test.circom" - ), - { - recompile: true, - include: path.join(__dirname, "../../../node_modules"), - output: path.join(__dirname, "./compiled-test-circuits"), - } - ); - }); - - it("should verify email when removeSoftLineBreaks is true", async function () { - const emailVerifierInputs = generateEmailVerifierInputsFromDKIMResult( - dkimResult, - { - maxHeadersLength: 640, - maxBodyLength: 1408, - ignoreBodyHashCheck: false, - removeSoftLineBreaks: true, - } - ); - - const witness = await circuit.calculateWitness(emailVerifierInputs); - await circuit.checkConstraints(witness); - }); -}); - -describe("EmailVerifier : With header masking", () => { - jest.setTimeout(10 * 60 * 1000); // 10 minutes - - let dkimResult: DKIMVerificationResult; - let circuit: any; - - beforeAll(async () => { - const rawEmail = fs.readFileSync( - path.join(__dirname, "./test-emails/test.eml") - ); - dkimResult = await verifyDKIMSignature(rawEmail); - - circuit = await wasm_tester( - path.join( - __dirname, - "./test-circuits/email-verifier-with-header-mask-test.circom" - ), - { - recompile: true, - include: path.join(__dirname, "../../../node_modules"), - output: path.join(__dirname, "./compiled-test-circuits"), - } - ); - }); - - it("should verify email with header masking", async function () { - const mask = Array.from({ length: 640 }, (_, i) => - i > 25 && i < 50 ? 1 : 0 - ); - - const emailVerifierInputs = generateEmailVerifierInputsFromDKIMResult( - dkimResult, - { - maxHeadersLength: 640, - maxBodyLength: 768, - ignoreBodyHashCheck: false, - enableHeaderMasking: true, - headerMask: mask.map((value) => (value ? 1 : 0)), - } - ); - - const expectedMaskedHeader = emailVerifierInputs.emailHeader!.map( - (byte, i) => (mask[i] === 1 ? byte : 0) - ); - - const witness = await circuit.calculateWitness(emailVerifierInputs); - await circuit.checkConstraints(witness); - await circuit.assertOut(witness, { - maskedHeader: expectedMaskedHeader, - }); - }); -}); From a83e47631853e9c45c9322119f93b3223df81f0a Mon Sep 17 00:00:00 2001 From: shreyas-londhe Date: Fri, 13 Sep 2024 10:21:30 +0530 Subject: [PATCH 4/8] chore: increased test timeout for email-verifier --- packages/circuits/tests/email-verifier-no-body.test.ts | 2 +- packages/circuits/tests/email-verifier-with-body-mask.test.ts | 2 +- packages/circuits/tests/email-verifier-with-header-mask.test.ts | 2 +- .../circuits/tests/email-verifier-with-soft-line-breaks.test.ts | 2 +- packages/circuits/tests/email-verifier.test.ts | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/packages/circuits/tests/email-verifier-no-body.test.ts b/packages/circuits/tests/email-verifier-no-body.test.ts index 21780215..c1cb6757 100644 --- a/packages/circuits/tests/email-verifier-no-body.test.ts +++ b/packages/circuits/tests/email-verifier-no-body.test.ts @@ -6,7 +6,7 @@ import { generateEmailVerifierInputsFromDKIMResult } from "@zk-email/helpers/src import { verifyDKIMSignature } from "@zk-email/helpers/src/dkim"; describe("EmailVerifier : Without body check", () => { - jest.setTimeout(10 * 60 * 1000); // 10 minutes + jest.setTimeout(15 * 60 * 1000); // 15 minutes let dkimResult: DKIMVerificationResult; let circuit: any; diff --git a/packages/circuits/tests/email-verifier-with-body-mask.test.ts b/packages/circuits/tests/email-verifier-with-body-mask.test.ts index 11427173..b17f0410 100644 --- a/packages/circuits/tests/email-verifier-with-body-mask.test.ts +++ b/packages/circuits/tests/email-verifier-with-body-mask.test.ts @@ -6,7 +6,7 @@ import { generateEmailVerifierInputsFromDKIMResult } from "@zk-email/helpers/src import { verifyDKIMSignature } from "@zk-email/helpers/src/dkim"; describe("EmailVerifier : With body masking", () => { - jest.setTimeout(10 * 60 * 1000); // 10 minutes + jest.setTimeout(15 * 60 * 1000); // 15 minutes let dkimResult: DKIMVerificationResult; let circuit: any; diff --git a/packages/circuits/tests/email-verifier-with-header-mask.test.ts b/packages/circuits/tests/email-verifier-with-header-mask.test.ts index 1fac9cd5..f94a45f0 100644 --- a/packages/circuits/tests/email-verifier-with-header-mask.test.ts +++ b/packages/circuits/tests/email-verifier-with-header-mask.test.ts @@ -6,7 +6,7 @@ import { generateEmailVerifierInputsFromDKIMResult } from "@zk-email/helpers/src import { verifyDKIMSignature } from "@zk-email/helpers/src/dkim"; describe("EmailVerifier : With header masking", () => { - jest.setTimeout(10 * 60 * 1000); // 10 minutes + jest.setTimeout(15 * 60 * 1000); // 15 minutes let dkimResult: DKIMVerificationResult; let circuit: any; diff --git a/packages/circuits/tests/email-verifier-with-soft-line-breaks.test.ts b/packages/circuits/tests/email-verifier-with-soft-line-breaks.test.ts index 9240521e..7efac506 100644 --- a/packages/circuits/tests/email-verifier-with-soft-line-breaks.test.ts +++ b/packages/circuits/tests/email-verifier-with-soft-line-breaks.test.ts @@ -6,7 +6,7 @@ import { generateEmailVerifierInputsFromDKIMResult } from "@zk-email/helpers/src import { verifyDKIMSignature } from "@zk-email/helpers/src/dkim"; describe("EmailVerifier : With soft line breaks", () => { - jest.setTimeout(10 * 60 * 1000); // 10 minutes + jest.setTimeout(15 * 60 * 1000); // 15 minutes let dkimResult: DKIMVerificationResult; let circuit: any; diff --git a/packages/circuits/tests/email-verifier.test.ts b/packages/circuits/tests/email-verifier.test.ts index 93eee579..36718f1e 100644 --- a/packages/circuits/tests/email-verifier.test.ts +++ b/packages/circuits/tests/email-verifier.test.ts @@ -7,7 +7,7 @@ import { verifyDKIMSignature } from "@zk-email/helpers/src/dkim"; import { poseidonLarge } from "@zk-email/helpers/src/hash"; describe("EmailVerifier", () => { - jest.setTimeout(10 * 60 * 1000); // 10 minutes + jest.setTimeout(15 * 60 * 1000); // 15 minutes let dkimResult: DKIMVerificationResult; let circuit: any; From 74958f10f4577375c049f9ee4c27f69b1ffdaf8e Mon Sep 17 00:00:00 2001 From: shreyas-londhe Date: Fri, 13 Sep 2024 13:34:35 +0530 Subject: [PATCH 5/8] chore: minor change --- packages/circuits/tests/email-verifier-no-body.test.ts | 2 +- packages/circuits/tests/email-verifier-with-body-mask.test.ts | 2 +- packages/circuits/tests/email-verifier-with-header-mask.test.ts | 2 +- .../circuits/tests/email-verifier-with-soft-line-breaks.test.ts | 2 +- packages/circuits/tests/email-verifier.test.ts | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/packages/circuits/tests/email-verifier-no-body.test.ts b/packages/circuits/tests/email-verifier-no-body.test.ts index c1cb6757..21780215 100644 --- a/packages/circuits/tests/email-verifier-no-body.test.ts +++ b/packages/circuits/tests/email-verifier-no-body.test.ts @@ -6,7 +6,7 @@ import { generateEmailVerifierInputsFromDKIMResult } from "@zk-email/helpers/src import { verifyDKIMSignature } from "@zk-email/helpers/src/dkim"; describe("EmailVerifier : Without body check", () => { - jest.setTimeout(15 * 60 * 1000); // 15 minutes + jest.setTimeout(10 * 60 * 1000); // 10 minutes let dkimResult: DKIMVerificationResult; let circuit: any; diff --git a/packages/circuits/tests/email-verifier-with-body-mask.test.ts b/packages/circuits/tests/email-verifier-with-body-mask.test.ts index b17f0410..11427173 100644 --- a/packages/circuits/tests/email-verifier-with-body-mask.test.ts +++ b/packages/circuits/tests/email-verifier-with-body-mask.test.ts @@ -6,7 +6,7 @@ import { generateEmailVerifierInputsFromDKIMResult } from "@zk-email/helpers/src import { verifyDKIMSignature } from "@zk-email/helpers/src/dkim"; describe("EmailVerifier : With body masking", () => { - jest.setTimeout(15 * 60 * 1000); // 15 minutes + jest.setTimeout(10 * 60 * 1000); // 10 minutes let dkimResult: DKIMVerificationResult; let circuit: any; diff --git a/packages/circuits/tests/email-verifier-with-header-mask.test.ts b/packages/circuits/tests/email-verifier-with-header-mask.test.ts index f94a45f0..1fac9cd5 100644 --- a/packages/circuits/tests/email-verifier-with-header-mask.test.ts +++ b/packages/circuits/tests/email-verifier-with-header-mask.test.ts @@ -6,7 +6,7 @@ import { generateEmailVerifierInputsFromDKIMResult } from "@zk-email/helpers/src import { verifyDKIMSignature } from "@zk-email/helpers/src/dkim"; describe("EmailVerifier : With header masking", () => { - jest.setTimeout(15 * 60 * 1000); // 15 minutes + jest.setTimeout(10 * 60 * 1000); // 10 minutes let dkimResult: DKIMVerificationResult; let circuit: any; diff --git a/packages/circuits/tests/email-verifier-with-soft-line-breaks.test.ts b/packages/circuits/tests/email-verifier-with-soft-line-breaks.test.ts index 7efac506..9240521e 100644 --- a/packages/circuits/tests/email-verifier-with-soft-line-breaks.test.ts +++ b/packages/circuits/tests/email-verifier-with-soft-line-breaks.test.ts @@ -6,7 +6,7 @@ import { generateEmailVerifierInputsFromDKIMResult } from "@zk-email/helpers/src import { verifyDKIMSignature } from "@zk-email/helpers/src/dkim"; describe("EmailVerifier : With soft line breaks", () => { - jest.setTimeout(15 * 60 * 1000); // 15 minutes + jest.setTimeout(10 * 60 * 1000); // 10 minutes let dkimResult: DKIMVerificationResult; let circuit: any; diff --git a/packages/circuits/tests/email-verifier.test.ts b/packages/circuits/tests/email-verifier.test.ts index 36718f1e..93eee579 100644 --- a/packages/circuits/tests/email-verifier.test.ts +++ b/packages/circuits/tests/email-verifier.test.ts @@ -7,7 +7,7 @@ import { verifyDKIMSignature } from "@zk-email/helpers/src/dkim"; import { poseidonLarge } from "@zk-email/helpers/src/hash"; describe("EmailVerifier", () => { - jest.setTimeout(15 * 60 * 1000); // 15 minutes + jest.setTimeout(10 * 60 * 1000); // 10 minutes let dkimResult: DKIMVerificationResult; let circuit: any; From eb66674c5557e27885f5f82df93264661de57a03 Mon Sep 17 00:00:00 2001 From: shreyas-londhe Date: Fri, 13 Sep 2024 13:43:36 +0530 Subject: [PATCH 6/8] chore: minor change --- packages/circuits/tests/base64.test.ts | 105 +++++----- .../tests/count-substring-occurrences.test.ts | 106 ++++++++++ .../tests/email-verifier-no-body.test.ts | 2 +- .../email-verifier-with-body-mask.test.ts | 2 +- .../email-verifier-with-header-mask.test.ts | 2 +- ...ail-verifier-with-soft-line-breaks.test.ts | 2 +- .../circuits/tests/email-verifier.test.ts | 2 +- packages/circuits/tests/rsa.test.ts | 191 ++++++++++++------ .../tests/select-regex-reveal.test.ts | 64 ++++-- packages/circuits/tests/sha.test.ts | 66 +++--- 10 files changed, 368 insertions(+), 174 deletions(-) create mode 100644 packages/circuits/tests/count-substring-occurrences.test.ts diff --git a/packages/circuits/tests/base64.test.ts b/packages/circuits/tests/base64.test.ts index b4711c46..4088741e 100644 --- a/packages/circuits/tests/base64.test.ts +++ b/packages/circuits/tests/base64.test.ts @@ -1,58 +1,57 @@ import { wasm } from "circom_tester"; import path from "path"; - describe("Base64 Lookup", () => { - jest.setTimeout(10 * 60 * 1000); // 10 minutes - - let circuit: any; - - beforeAll(async () => { - circuit = await wasm( - path.join(__dirname, "./test-circuits/base64-test.circom"), - { - recompile: true, - include: path.join(__dirname, "../../../node_modules"), - // output: path.join(__dirname, "./compiled-test-circuits"), - } - ); - }); - - it("should decode valid base64 chars", async function () { - const inputs = [ - [65, 0], // A - [90, 25], // Z - [97, 26], // a - [122, 51], // z - [48, 52], // 0 - [57, 61], // 9 - [43, 62], // + - [47, 63], // / - [61, 0], // = - ] - - for (const [input, output] of inputs) { - const witness = await circuit.calculateWitness({ - in: input - }); - await circuit.checkConstraints(witness); - await circuit.assertOut(witness, { out: output }) - } - }); - - it("should fail with invalid chars", async function () { - const inputs = [34, 64, 91, 44]; - - expect.assertions(inputs.length); - for (const input of inputs) { - try { - const witness = await circuit.calculateWitness({ - in: input - }); - await circuit.checkConstraints(witness); - } catch (error) { - expect((error as Error).message).toMatch("Assert Failed"); - } - } - }); + jest.setTimeout(30 * 60 * 1000); // 30 minutes + + let circuit: any; + + beforeAll(async () => { + circuit = await wasm( + path.join(__dirname, "./test-circuits/base64-test.circom"), + { + recompile: true, + include: path.join(__dirname, "../../../node_modules"), + // output: path.join(__dirname, "./compiled-test-circuits"), + } + ); + }); + + it("should decode valid base64 chars", async function () { + const inputs = [ + [65, 0], // A + [90, 25], // Z + [97, 26], // a + [122, 51], // z + [48, 52], // 0 + [57, 61], // 9 + [43, 62], // + + [47, 63], // / + [61, 0], // = + ]; + + for (const [input, output] of inputs) { + const witness = await circuit.calculateWitness({ + in: input, + }); + await circuit.checkConstraints(witness); + await circuit.assertOut(witness, { out: output }); + } + }); + + it("should fail with invalid chars", async function () { + const inputs = [34, 64, 91, 44]; + + expect.assertions(inputs.length); + for (const input of inputs) { + try { + const witness = await circuit.calculateWitness({ + in: input, + }); + await circuit.checkConstraints(witness); + } catch (error) { + expect((error as Error).message).toMatch("Assert Failed"); + } + } + }); }); diff --git a/packages/circuits/tests/count-substring-occurrences.test.ts b/packages/circuits/tests/count-substring-occurrences.test.ts new file mode 100644 index 00000000..c84fbf7f --- /dev/null +++ b/packages/circuits/tests/count-substring-occurrences.test.ts @@ -0,0 +1,106 @@ +import { wasm as wasm_tester } from "circom_tester"; +import path from "path"; + +describe("CountSubstringOccurrences Circuit", () => { + jest.setTimeout(30 * 60 * 1000); // 30 minutes + + let circuit: any; + + beforeAll(async () => { + circuit = await wasm_tester( + path.join( + __dirname, + "./test-circuits/count-substring-occurrences-test.circom" + ), + { + recompile: true, + include: path.join(__dirname, "../../../node_modules"), + output: path.join(__dirname, "./compiled-test-circuits"), + } + ); + }); + + it("should count single occurrence at the beginning", async () => { + const input = { + in: [1, 2, 3, 4, 5, ...Array(1019).fill(0)], + substring: [1, 2, 3, ...Array(125).fill(0)], + }; + const witness = await circuit.calculateWitness(input); + await circuit.checkConstraints(witness); + expect(witness[1]).toBe(1n); + }); + + it("should count multiple occurrences", async () => { + const input = { + in: [1, 2, 3, 4, 1, 2, 3, 5, 1, 2, 3, ...Array(1013).fill(0)], + substring: [1, 2, 3, ...Array(125).fill(0)], + }; + const witness = await circuit.calculateWitness(input); + await circuit.checkConstraints(witness); + expect(witness[1]).toBe(3n); + }); + + it("should return 0 for no occurrences", async () => { + const input = { + in: [1, 2, 4, 5, 6, ...Array(1019).fill(0)], + substring: [1, 2, 3, ...Array(125).fill(0)], + }; + const witness = await circuit.calculateWitness(input); + await circuit.checkConstraints(witness); + expect(witness[1]).toBe(0n); + }); + + it("should count occurrences with overlap", async () => { + const input = { + in: [1, 1, 1, 2, 1, 1, ...Array(1018).fill(0)], + substring: [1, 1, ...Array(126).fill(0)], + }; + const witness = await circuit.calculateWitness(input); + await circuit.checkConstraints(witness); + expect(witness[1]).toBe(3n); + }); + + it("should handle full match of input", async () => { + const repeatedPattern = [1, 2, 3, 4]; + const input = { + in: Array(256) + .fill(repeatedPattern) + .flat() + .concat(Array(1024 - 256 * 4).fill(0)), + substring: [1, 2, 3, 4, ...Array(124).fill(0)], + }; + const witness = await circuit.calculateWitness(input); + await circuit.checkConstraints(witness); + expect(witness[1]).toBe(256n); + }); + + it("should handle single character substring", async () => { + const input = { + in: [1, 2, 1, 3, 1, 4, 1, ...Array(1017).fill(0)], + substring: [1, ...Array(127).fill(0)], + }; + const witness = await circuit.calculateWitness(input); + await circuit.checkConstraints(witness); + expect(witness[1]).toBe(4n); + }); + + it("should handle substring at the end of input", async () => { + const input = { + in: [...Array(1021).fill(0), 1, 2, 3], + substring: [1, 2, 3, ...Array(125).fill(0)], + }; + const witness = await circuit.calculateWitness(input); + await circuit.checkConstraints(witness); + expect(witness[1]).toBe(1n); + }); + + it("should return 0 for empty substring", async () => { + const input = { + in: [1, 2, 3, 4, 5, ...Array(1019).fill(0)], + substring: Array(128).fill(0), + }; + await expect(async () => { + await circuit.calculateWitness(input); + }).rejects.toThrow("Assert Failed"); + }); +}); diff --git a/packages/circuits/tests/email-verifier-no-body.test.ts b/packages/circuits/tests/email-verifier-no-body.test.ts index 21780215..10262130 100644 --- a/packages/circuits/tests/email-verifier-no-body.test.ts +++ b/packages/circuits/tests/email-verifier-no-body.test.ts @@ -6,7 +6,7 @@ import { generateEmailVerifierInputsFromDKIMResult } from "@zk-email/helpers/src import { verifyDKIMSignature } from "@zk-email/helpers/src/dkim"; describe("EmailVerifier : Without body check", () => { - jest.setTimeout(10 * 60 * 1000); // 10 minutes + jest.setTimeout(30 * 60 * 1000); // 30 minutes let dkimResult: DKIMVerificationResult; let circuit: any; diff --git a/packages/circuits/tests/email-verifier-with-body-mask.test.ts b/packages/circuits/tests/email-verifier-with-body-mask.test.ts index 11427173..f6c525c8 100644 --- a/packages/circuits/tests/email-verifier-with-body-mask.test.ts +++ b/packages/circuits/tests/email-verifier-with-body-mask.test.ts @@ -6,7 +6,7 @@ import { generateEmailVerifierInputsFromDKIMResult } from "@zk-email/helpers/src import { verifyDKIMSignature } from "@zk-email/helpers/src/dkim"; describe("EmailVerifier : With body masking", () => { - jest.setTimeout(10 * 60 * 1000); // 10 minutes + jest.setTimeout(30 * 60 * 1000); // 30 minutes let dkimResult: DKIMVerificationResult; let circuit: any; diff --git a/packages/circuits/tests/email-verifier-with-header-mask.test.ts b/packages/circuits/tests/email-verifier-with-header-mask.test.ts index 1fac9cd5..04f4d567 100644 --- a/packages/circuits/tests/email-verifier-with-header-mask.test.ts +++ b/packages/circuits/tests/email-verifier-with-header-mask.test.ts @@ -6,7 +6,7 @@ import { generateEmailVerifierInputsFromDKIMResult } from "@zk-email/helpers/src import { verifyDKIMSignature } from "@zk-email/helpers/src/dkim"; describe("EmailVerifier : With header masking", () => { - jest.setTimeout(10 * 60 * 1000); // 10 minutes + jest.setTimeout(30 * 60 * 1000); // 30 minutes let dkimResult: DKIMVerificationResult; let circuit: any; diff --git a/packages/circuits/tests/email-verifier-with-soft-line-breaks.test.ts b/packages/circuits/tests/email-verifier-with-soft-line-breaks.test.ts index 9240521e..106eb954 100644 --- a/packages/circuits/tests/email-verifier-with-soft-line-breaks.test.ts +++ b/packages/circuits/tests/email-verifier-with-soft-line-breaks.test.ts @@ -6,7 +6,7 @@ import { generateEmailVerifierInputsFromDKIMResult } from "@zk-email/helpers/src import { verifyDKIMSignature } from "@zk-email/helpers/src/dkim"; describe("EmailVerifier : With soft line breaks", () => { - jest.setTimeout(10 * 60 * 1000); // 10 minutes + jest.setTimeout(30 * 60 * 1000); // 30 minutes let dkimResult: DKIMVerificationResult; let circuit: any; diff --git a/packages/circuits/tests/email-verifier.test.ts b/packages/circuits/tests/email-verifier.test.ts index 93eee579..3221f9b6 100644 --- a/packages/circuits/tests/email-verifier.test.ts +++ b/packages/circuits/tests/email-verifier.test.ts @@ -7,7 +7,7 @@ import { verifyDKIMSignature } from "@zk-email/helpers/src/dkim"; import { poseidonLarge } from "@zk-email/helpers/src/hash"; describe("EmailVerifier", () => { - jest.setTimeout(10 * 60 * 1000); // 10 minutes + jest.setTimeout(30 * 60 * 1000); // 30 minutes let dkimResult: DKIMVerificationResult; let circuit: any; diff --git a/packages/circuits/tests/rsa.test.ts b/packages/circuits/tests/rsa.test.ts index 4f6481b4..273db843 100644 --- a/packages/circuits/tests/rsa.test.ts +++ b/packages/circuits/tests/rsa.test.ts @@ -4,83 +4,142 @@ import { wasm as wasm_tester } from "circom_tester"; import { generateEmailVerifierInputs } from "@zk-email/helpers/src/input-generators"; import { toCircomBigIntBytes } from "@zk-email/helpers/src/binary-format"; - describe("RSA", () => { - jest.setTimeout(10 * 60 * 1000); // 10 minutes - - let circuit: any; - let rawEmail: Buffer; + jest.setTimeout(30 * 60 * 1000); // 30 minutes - beforeAll(async () => { - circuit = await wasm_tester( - path.join(__dirname, "./test-circuits/rsa-test.circom"), - { - recompile: true, - include: path.join(__dirname, "../../../node_modules"), - // output: path.join(__dirname, "./compiled-test-circuits"), - } - ); - rawEmail = fs.readFileSync(path.join(__dirname, "./test-emails/test.eml")); - }); + let circuit: any; + let rawEmail: Buffer; - it("should verify 2048 bit rsa signature correctly", async function () { - const emailVerifierInputs = await generateEmailVerifierInputs(rawEmail, { - maxHeadersLength: 640, - maxBodyLength: 768, + beforeAll(async () => { + circuit = await wasm_tester( + path.join(__dirname, "./test-circuits/rsa-test.circom"), + { + recompile: true, + include: path.join(__dirname, "../../../node_modules"), + // output: path.join(__dirname, "./compiled-test-circuits"), + } + ); + rawEmail = fs.readFileSync( + path.join(__dirname, "./test-emails/test.eml") + ); }); + it("should verify 2048 bit rsa signature correctly", async function () { + const emailVerifierInputs = await generateEmailVerifierInputs( + rawEmail, + { + maxHeadersLength: 640, + maxBodyLength: 768, + } + ); - const witness = await circuit.calculateWitness({ - signature: emailVerifierInputs.signature, - modulus: emailVerifierInputs.pubkey, - // TODO: generate this from the input - message: ["1156466847851242602709362303526378170", "191372789510123109308037416804949834", "7204", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0"], + const witness = await circuit.calculateWitness({ + signature: emailVerifierInputs.signature, + modulus: emailVerifierInputs.pubkey, + // TODO: generate this from the input + message: [ + "1156466847851242602709362303526378170", + "191372789510123109308037416804949834", + "7204", + "0", + "0", + "0", + "0", + "0", + "0", + "0", + "0", + "0", + "0", + "0", + "0", + "0", + "0", + ], + }); + await circuit.checkConstraints(witness); + await circuit.assertOut(witness, {}); }); - await circuit.checkConstraints(witness); - await circuit.assertOut(witness, {}) - }); - it("should verify 1024 bit rsa signature correctly", async function () { - const signature = toCircomBigIntBytes( - BigInt( - 102386562682221859025549328916727857389789009840935140645361501981959969535413501251999442013082353139290537518086128904993091119534674934202202277050635907008004079788691412782712147797487593510040249832242022835902734939817209358184800954336078838331094308355388211284440290335887813714894626653613586546719n - ) - ); + it("should verify 1024 bit rsa signature correctly", async function () { + const signature = toCircomBigIntBytes( + BigInt( + 102386562682221859025549328916727857389789009840935140645361501981959969535413501251999442013082353139290537518086128904993091119534674934202202277050635907008004079788691412782712147797487593510040249832242022835902734939817209358184800954336078838331094308355388211284440290335887813714894626653613586546719n + ) + ); - const pubkey = toCircomBigIntBytes( - BigInt( - 106773687078109007595028366084970322147907086635176067918161636756354740353674098686965493426431314019237945536387044259034050617425729739578628872957481830432099721612688699974185290306098360072264136606623400336518126533605711223527682187548332314997606381158951535480830524587400401856271050333371205030999n - ) - ); + const pubkey = toCircomBigIntBytes( + BigInt( + 106773687078109007595028366084970322147907086635176067918161636756354740353674098686965493426431314019237945536387044259034050617425729739578628872957481830432099721612688699974185290306098360072264136606623400336518126533605711223527682187548332314997606381158951535480830524587400401856271050333371205030999n + ) + ); - const witness = await circuit.calculateWitness({ - signature: signature, - modulus: pubkey, - // TODO: generate this from the input - message: ["1156466847851242602709362303526378170", "191372789510123109308037416804949834", "7204", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0"], + const witness = await circuit.calculateWitness({ + signature: signature, + modulus: pubkey, + // TODO: generate this from the input + message: [ + "1156466847851242602709362303526378170", + "191372789510123109308037416804949834", + "7204", + "0", + "0", + "0", + "0", + "0", + "0", + "0", + "0", + "0", + "0", + "0", + "0", + "0", + "0", + ], + }); + await circuit.checkConstraints(witness); + await circuit.assertOut(witness, {}); }); - await circuit.checkConstraints(witness); - await circuit.assertOut(witness, {}); - }); - it("should fail when verifying with an incorrect signature", async function () { - const emailVerifierInputs = await generateEmailVerifierInputs(rawEmail, { - maxHeadersLength: 640, - maxBodyLength: 768, - }); + it("should fail when verifying with an incorrect signature", async function () { + const emailVerifierInputs = await generateEmailVerifierInputs( + rawEmail, + { + maxHeadersLength: 640, + maxBodyLength: 768, + } + ); - - expect.assertions(1); - try { - const witness = await circuit.calculateWitness({ - signature: emailVerifierInputs.signature, - modulus: emailVerifierInputs.pubkey, - message: ["1156466847851242602709362303526378171", "191372789510123109308037416804949834", "7204", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0"], - }); - await circuit.checkConstraints(witness); - await circuit.assertOut(witness, {}) - } catch (error) { - expect((error as Error).message).toMatch("Assert Failed"); - } - }); + expect.assertions(1); + try { + const witness = await circuit.calculateWitness({ + signature: emailVerifierInputs.signature, + modulus: emailVerifierInputs.pubkey, + message: [ + "1156466847851242602709362303526378171", + "191372789510123109308037416804949834", + "7204", + "0", + "0", + "0", + "0", + "0", + "0", + "0", + "0", + "0", + "0", + "0", + "0", + "0", + "0", + ], + }); + await circuit.checkConstraints(witness); + await circuit.assertOut(witness, {}); + } catch (error) { + expect((error as Error).message).toMatch("Assert Failed"); + } + }); }); diff --git a/packages/circuits/tests/select-regex-reveal.test.ts b/packages/circuits/tests/select-regex-reveal.test.ts index fdf55115..cd3f3b81 100644 --- a/packages/circuits/tests/select-regex-reveal.test.ts +++ b/packages/circuits/tests/select-regex-reveal.test.ts @@ -1,15 +1,17 @@ import { wasm } from "circom_tester"; import path from "path"; - describe("Select Regex Reveal", () => { - jest.setTimeout(10 * 60 * 1000); // 10 minutes + jest.setTimeout(30 * 60 * 1000); // 30 minutes let circuit: any; beforeAll(async () => { circuit = await wasm( - path.join(__dirname, "./test-circuits/select-regex-reveal-test.circom"), + path.join( + __dirname, + "./test-circuits/select-regex-reveal-test.circom" + ), { recompile: true, include: path.join(__dirname, "../../../node_modules"), @@ -18,9 +20,14 @@ describe("Select Regex Reveal", () => { }); it("should reveal the substring with maximum revealed length", async function () { - let input = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]; + let input = [ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, + ]; const startIndex = Math.floor(Math.random() * 24); - const revealed = Array.from("zk email").map(char => char.charCodeAt(0)); + const revealed = Array.from("zk email").map((char) => + char.charCodeAt(0) + ); for (let i = 0; i < revealed.length; i++) { input[startIndex + i] = revealed[i]; } @@ -29,13 +36,16 @@ describe("Select Regex Reveal", () => { startIndex: startIndex, }); await circuit.checkConstraints(witness); - await circuit.assertOut(witness, { out: revealed }) + await circuit.assertOut(witness, { out: revealed }); }); it("should reveal the substring with non-maximum revealed length", async function () { - let input = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]; + let input = [ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, + ]; const startIndex = 30; - const revealed = Array.from("zk").map(char => char.charCodeAt(0)); + const revealed = Array.from("zk").map((char) => char.charCodeAt(0)); for (let i = 0; i < revealed.length; i++) { input[startIndex + i] = revealed[i]; } @@ -44,11 +54,16 @@ describe("Select Regex Reveal", () => { startIndex: startIndex, }); await circuit.checkConstraints(witness); - await circuit.assertOut(witness, { out: revealed.concat([0, 0, 0, 0, 0, 0]) }) + await circuit.assertOut(witness, { + out: revealed.concat([0, 0, 0, 0, 0, 0]), + }); }); it("should fail when all zero", async function () { - let input = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]; + let input = [ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, + ]; const startIndex = Math.floor(Math.random() * 32); try { const witness = await circuit.calculateWitness({ @@ -62,9 +77,14 @@ describe("Select Regex Reveal", () => { }); it("should fail when startIndex is 0", async function () { - let input = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]; + let input = [ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, + ]; const startIndex = 1 + Math.floor(Math.random() * 24); - const revealed = Array.from("zk email").map(char => char.charCodeAt(0)); + const revealed = Array.from("zk email").map((char) => + char.charCodeAt(0) + ); for (let i = 0; i < revealed.length; i++) { input[startIndex + i] = revealed[i]; } @@ -80,9 +100,14 @@ describe("Select Regex Reveal", () => { }); it("should fail when startIndex is not before 0", async function () { - let input = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]; + let input = [ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, + ]; const startIndex = Math.floor(Math.random() * 23); - const revealed = Array.from("zk email").map(char => char.charCodeAt(0)); + const revealed = Array.from("zk email").map((char) => + char.charCodeAt(0) + ); for (let i = 0; i < revealed.length; i++) { input[startIndex + i] = revealed[i]; } @@ -98,16 +123,21 @@ describe("Select Regex Reveal", () => { }); it("should fail when startIndex is larger than max length", async function () { - let input = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]; + let input = [ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, + ]; const startIndex = Math.floor(Math.random() * 24); - const revealed = Array.from("zk email").map(char => char.charCodeAt(0)); + const revealed = Array.from("zk email").map((char) => + char.charCodeAt(0) + ); for (let i = 0; i < revealed.length; i++) { input[startIndex + i] = revealed[i]; } try { const witness = await circuit.calculateWitness({ in: input, - startIndex: 32 + startIndex: 32, }); await circuit.checkConstraints(witness); } catch (error) { diff --git a/packages/circuits/tests/sha.test.ts b/packages/circuits/tests/sha.test.ts index 82e8623d..e9281924 100644 --- a/packages/circuits/tests/sha.test.ts +++ b/packages/circuits/tests/sha.test.ts @@ -1,44 +1,44 @@ import { wasm as wasm_tester } from "circom_tester"; import path from "path"; import { sha256Pad, shaHash } from "@zk-email/helpers/src/sha-utils"; -import { Uint8ArrayToCharArray, uint8ToBits } from "@zk-email/helpers/src/binary-format"; - +import { + Uint8ArrayToCharArray, + uint8ToBits, +} from "@zk-email/helpers/src/binary-format"; describe("SHA256 for email header", () => { - jest.setTimeout(10 * 60 * 1000); // 10 minutes + jest.setTimeout(30 * 60 * 1000); // 30 minutes - let circuit: any; + let circuit: any; - beforeAll(async () => { - circuit = await wasm_tester( - path.join(__dirname, "./test-circuits/sha-test.circom"), - { - recompile: true, - include: path.join(__dirname, "../../../node_modules"), - // output: path.join(__dirname, "./compiled-test-circuits"), - } - ); - }); + beforeAll(async () => { + circuit = await wasm_tester( + path.join(__dirname, "./test-circuits/sha-test.circom"), + { + recompile: true, + include: path.join(__dirname, "../../../node_modules"), + // output: path.join(__dirname, "./compiled-test-circuits"), + } + ); + }); - it("should hash correctly", async function () { - const inputs = [ - "0", "hello world", "" - ] - for (const input of inputs) { - const [ - paddedMsg, - messageLen, - ] = sha256Pad( - Buffer.from(input, "ascii"), 640 - ) + it("should hash correctly", async function () { + const inputs = ["0", "hello world", ""]; + for (const input of inputs) { + const [paddedMsg, messageLen] = sha256Pad( + Buffer.from(input, "ascii"), + 640 + ); - const witness = await circuit.calculateWitness({ - paddedIn: Uint8ArrayToCharArray(paddedMsg), - paddedInLength: messageLen, - }); + const witness = await circuit.calculateWitness({ + paddedIn: Uint8ArrayToCharArray(paddedMsg), + paddedInLength: messageLen, + }); - await circuit.checkConstraints(witness); - await circuit.assertOut(witness, { out: [...uint8ToBits(shaHash(Buffer.from(input, "ascii")))] }) - } - }); + await circuit.checkConstraints(witness); + await circuit.assertOut(witness, { + out: [...uint8ToBits(shaHash(Buffer.from(input, "ascii")))], + }); + } + }); }); From aa10b9af3fe4547012abd48364ab0807549550b7 Mon Sep 17 00:00:00 2001 From: shreyas-londhe Date: Fri, 13 Sep 2024 13:47:33 +0530 Subject: [PATCH 7/8] chore: minor change --- .../tests/count-substring-occurrences.test.ts | 106 ------------------ 1 file changed, 106 deletions(-) delete mode 100644 packages/circuits/tests/count-substring-occurrences.test.ts diff --git a/packages/circuits/tests/count-substring-occurrences.test.ts b/packages/circuits/tests/count-substring-occurrences.test.ts deleted file mode 100644 index c84fbf7f..00000000 --- a/packages/circuits/tests/count-substring-occurrences.test.ts +++ /dev/null @@ -1,106 +0,0 @@ -import { wasm as wasm_tester } from "circom_tester"; -import path from "path"; - -describe("CountSubstringOccurrences Circuit", () => { - jest.setTimeout(30 * 60 * 1000); // 30 minutes - - let circuit: any; - - beforeAll(async () => { - circuit = await wasm_tester( - path.join( - __dirname, - "./test-circuits/count-substring-occurrences-test.circom" - ), - { - recompile: true, - include: path.join(__dirname, "../../../node_modules"), - output: path.join(__dirname, "./compiled-test-circuits"), - } - ); - }); - - it("should count single occurrence at the beginning", async () => { - const input = { - in: [1, 2, 3, 4, 5, ...Array(1019).fill(0)], - substring: [1, 2, 3, ...Array(125).fill(0)], - }; - const witness = await circuit.calculateWitness(input); - await circuit.checkConstraints(witness); - expect(witness[1]).toBe(1n); - }); - - it("should count multiple occurrences", async () => { - const input = { - in: [1, 2, 3, 4, 1, 2, 3, 5, 1, 2, 3, ...Array(1013).fill(0)], - substring: [1, 2, 3, ...Array(125).fill(0)], - }; - const witness = await circuit.calculateWitness(input); - await circuit.checkConstraints(witness); - expect(witness[1]).toBe(3n); - }); - - it("should return 0 for no occurrences", async () => { - const input = { - in: [1, 2, 4, 5, 6, ...Array(1019).fill(0)], - substring: [1, 2, 3, ...Array(125).fill(0)], - }; - const witness = await circuit.calculateWitness(input); - await circuit.checkConstraints(witness); - expect(witness[1]).toBe(0n); - }); - - it("should count occurrences with overlap", async () => { - const input = { - in: [1, 1, 1, 2, 1, 1, ...Array(1018).fill(0)], - substring: [1, 1, ...Array(126).fill(0)], - }; - const witness = await circuit.calculateWitness(input); - await circuit.checkConstraints(witness); - expect(witness[1]).toBe(3n); - }); - - it("should handle full match of input", async () => { - const repeatedPattern = [1, 2, 3, 4]; - const input = { - in: Array(256) - .fill(repeatedPattern) - .flat() - .concat(Array(1024 - 256 * 4).fill(0)), - substring: [1, 2, 3, 4, ...Array(124).fill(0)], - }; - const witness = await circuit.calculateWitness(input); - await circuit.checkConstraints(witness); - expect(witness[1]).toBe(256n); - }); - - it("should handle single character substring", async () => { - const input = { - in: [1, 2, 1, 3, 1, 4, 1, ...Array(1017).fill(0)], - substring: [1, ...Array(127).fill(0)], - }; - const witness = await circuit.calculateWitness(input); - await circuit.checkConstraints(witness); - expect(witness[1]).toBe(4n); - }); - - it("should handle substring at the end of input", async () => { - const input = { - in: [...Array(1021).fill(0), 1, 2, 3], - substring: [1, 2, 3, ...Array(125).fill(0)], - }; - const witness = await circuit.calculateWitness(input); - await circuit.checkConstraints(witness); - expect(witness[1]).toBe(1n); - }); - - it("should return 0 for empty substring", async () => { - const input = { - in: [1, 2, 3, 4, 5, ...Array(1019).fill(0)], - substring: Array(128).fill(0), - }; - await expect(async () => { - await circuit.calculateWitness(input); - }).rejects.toThrow("Assert Failed"); - }); -}); From 58f7d7368d853ef187030eb4e85824a6ffb887c2 Mon Sep 17 00:00:00 2001 From: shreyas-londhe Date: Fri, 13 Sep 2024 14:17:51 +0530 Subject: [PATCH 8/8] fix: updated test script --- packages/circuits/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/circuits/package.json b/packages/circuits/package.json index 3abef34d..a8f2f5a6 100644 --- a/packages/circuits/package.json +++ b/packages/circuits/package.json @@ -4,7 +4,7 @@ "license": "MIT", "scripts": { "publish": "yarn npm publish --access=public", - "test": "NODE_OPTIONS=--max_old_space_size=8192 jest tests" + "test": "NODE_OPTIONS=--max_old_space_size=8192 jest --runInBand --detectOpenHandles --forceExit --verbose tests" }, "dependencies": { "@zk-email/zk-regex-circom": "^2.1.0",