From 800b9a1099187d61a4413c396e924b59821474c5 Mon Sep 17 00:00:00 2001 From: shreyas-londhe Date: Thu, 26 Sep 2024 12:26:28 +0530 Subject: [PATCH] feat: added range checks to RevealSubstring template --- .../circuits/helpers/reveal-substring.circom | 13 ++++++ .../circuits/tests/reveal-substring.test.ts | 45 +++++++++++++++++++ 2 files changed, 58 insertions(+) diff --git a/packages/circuits/helpers/reveal-substring.circom b/packages/circuits/helpers/reveal-substring.circom index e585d1d1..f3197e71 100644 --- a/packages/circuits/helpers/reveal-substring.circom +++ b/packages/circuits/helpers/reveal-substring.circom @@ -19,6 +19,19 @@ template RevealSubstring(maxLength, maxSubstringLength, shouldCheckUniqueness) { signal output substring[maxSubstringLength]; + // Substring start index should be less than maxLength + signal isSubstringStartIndexValid <== LessThan(log2Ceil(maxLength))([substringStartIndex, maxLength]); + isSubstringStartIndexValid === 1; + + // Substring length should be less than maxSubstringLength + 1 + signal isSubstringLengthValid <== LessThan(log2Ceil(maxSubstringLength + 1))([substringLength, maxSubstringLength + 1]); + isSubstringLengthValid === 1; + + // substring index + substring length should be less than maxLength + 1 + signal sum <== substringStartIndex + substringLength; + signal isSumValid <== LessThan(log2Ceil(maxLength + 1))([sum, maxLength + 1]); + isSumValid === 1; + // Extract the substring component selectSubArray = SelectSubArray(maxLength, maxSubstringLength); selectSubArray.in <== in; diff --git a/packages/circuits/tests/reveal-substring.test.ts b/packages/circuits/tests/reveal-substring.test.ts index ea035184..64861579 100644 --- a/packages/circuits/tests/reveal-substring.test.ts +++ b/packages/circuits/tests/reveal-substring.test.ts @@ -143,4 +143,49 @@ describe("RevealSubstring Circuit", () => { ...Array(13).fill(0n), ]); }); + + it("should fail when substringStartIndex is equal to maxLength", async () => { + const input = { + in: Array(256).fill(1), + substringStartIndex: 256, // Equal to maxLength + substringLength: 1, + }; + await expect(circuit.calculateWitness(input)).rejects.toThrow(); + }); + + it("should fail when substringStartIndex is greater than maxLength", async () => { + const input = { + in: Array(256).fill(1), + substringStartIndex: 257, // Greater than maxLength + substringLength: 1, + }; + await expect(circuit.calculateWitness(input)).rejects.toThrow(); + }); + + it("should fail when substringLength is equal to maxSubstringLength", async () => { + const input = { + in: Array(256).fill(1), + substringStartIndex: 0, + substringLength: 16, // Equal to maxSubstringLength + }; + await expect(circuit.calculateWitness(input)).rejects.toThrow(); + }); + + it("should fail when substringLength is greater than maxSubstringLength", async () => { + const input = { + in: Array(256).fill(1), + substringStartIndex: 0, + substringLength: 17, // Greater than maxSubstringLength + }; + await expect(circuit.calculateWitness(input)).rejects.toThrow(); + }); + + it("should fail when substringStartIndex + substringLength is greater than maxLength", async () => { + const input = { + in: Array(256).fill(1), + substringStartIndex: 250, + substringLength: 7, // 250 + 7 > 256 + }; + await expect(circuit.calculateWitness(input)).rejects.toThrow(); + }); });