From 6085c1be8aa3d1cc8a5a0ef092311761cca5e8ff Mon Sep 17 00:00:00 2001 From: Kyryl R Date: Wed, 25 Dec 2024 15:37:50 +0200 Subject: [PATCH 1/3] Added support for parentheses --- src/utils/ExpressionHelper.ts | 9 ++++++-- test/circom-template-inputs-visitor.test.ts | 23 +++++++++++++++++++++ test/data/Math.circom | 11 ++++++++++ 3 files changed, 41 insertions(+), 2 deletions(-) create mode 100644 test/data/Math.circom diff --git a/src/utils/ExpressionHelper.ts b/src/utils/ExpressionHelper.ts index 79ef7b4..7c52510 100644 --- a/src/utils/ExpressionHelper.ts +++ b/src/utils/ExpressionHelper.ts @@ -177,8 +177,13 @@ class ExpressionVisitor extends ExtendedCircomVisitor { }; visitPParentheses = (ctx: PParenthesesContext): CircomValueType | null => { - this.addError("Parentheses are not supported", ctx); - return null; + let expressions = ctx.expressionList().expression_list(); + if (expressions.length !== 1) { + this.addError("Parentheses can only contain one expression", ctx); + return null; + } + + return this.visit(expressions[0]); }; visitPArray = (ctx: PArrayContext): CircomValueType | null => { diff --git a/test/circom-template-inputs-visitor.test.ts b/test/circom-template-inputs-visitor.test.ts index 0ea0e34..4a28ee9 100644 --- a/test/circom-template-inputs-visitor.test.ts +++ b/test/circom-template-inputs-visitor.test.ts @@ -233,4 +233,27 @@ describe("Circom Template Inputs Visitor", () => { expect(visitor.templateInputs.out.type).to.equal("output"); expect(visitor.templateInputs.out.dimension).to.deep.equal([2, 4]); }); + + it("should analyse the Math.circom circuit", () => { + const data = getData("Math.circom"); + + const visitor = new CircomTemplateInputsVisitor( + "Math.circom", + data.templates[data.mainComponentInfo.templateName!].context, + buildVariableContext( + data.templates[data.mainComponentInfo.templateName!].parameters, + data.mainComponentInfo.parameters, + ), + ); + + visitor.startParse(); + + expect(visitor.errors.length).to.equal(0); + + expect(visitor.templateInputs.out1.type).to.equal("output"); + expect(visitor.templateInputs.out1.dimension).to.deep.equal([13]); + + expect(visitor.templateInputs.out2.type).to.equal("output"); + expect(visitor.templateInputs.out2.dimension).to.deep.equal([16]); + }); }); diff --git a/test/data/Math.circom b/test/data/Math.circom new file mode 100644 index 0000000..9e44767 --- /dev/null +++ b/test/data/Math.circom @@ -0,0 +1,11 @@ +pragma circom 2.1.6; + +template Math(a, b) { + var input1 = (a + b) / 2; + var input2 = a + b / 2; + + signal output out1[input1]; + signal output out2[input2]; +} + +component main = Math(6, 20); From 4321add9b24cd3f675695b9ab6a84a22fbe43228 Mon Sep 17 00:00:00 2001 From: Kyryl R Date: Wed, 25 Dec 2024 15:38:10 +0200 Subject: [PATCH 2/3] Updated versions --- package-lock.json | 4 ++-- package.json | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index 62a7642..cf1831c 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "@distributedlab/circom-parser", - "version": "0.2.4", + "version": "0.2.5", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "@distributedlab/circom-parser", - "version": "0.2.4", + "version": "0.2.5", "license": "MIT", "dependencies": { "antlr4": "4.13.1-patch-1", diff --git a/package.json b/package.json index 09f5bbb..61e5dac 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "@distributedlab/circom-parser", "description": "Circom circuit parser built with ANTLR4", - "version": "0.2.4", + "version": "0.2.5", "main": "dist/index.js", "types": "dist/index.d.ts", "files": [ From 9f8d106bbab8c496fc701ddece16cbd8cdbbeb41 Mon Sep 17 00:00:00 2001 From: Kyryl R Date: Wed, 25 Dec 2024 16:02:47 +0200 Subject: [PATCH 3/3] Added support for QUO operation --- src/utils/ExpressionHelper.ts | 4 ++-- test/circom-template-inputs-visitor.test.ts | 17 +++++++++++++++++ test/data/Math.circom | 17 +++++++++++++++-- 3 files changed, 34 insertions(+), 4 deletions(-) diff --git a/src/utils/ExpressionHelper.ts b/src/utils/ExpressionHelper.ts index 7c52510..e64e20e 100644 --- a/src/utils/ExpressionHelper.ts +++ b/src/utils/ExpressionHelper.ts @@ -288,8 +288,8 @@ class ExpressionVisitor extends ExtendedCircomVisitor { case CircomParser.DIV: return firstExpression / secondExpression; case CircomParser.QUO: - this.addError("QUO operation is not supported", ctx); - return null; + // See: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Division + return firstExpression / secondExpression; case CircomParser.MOD: return firstExpression % secondExpression; case CircomParser.ADD: diff --git a/test/circom-template-inputs-visitor.test.ts b/test/circom-template-inputs-visitor.test.ts index 4a28ee9..9becc82 100644 --- a/test/circom-template-inputs-visitor.test.ts +++ b/test/circom-template-inputs-visitor.test.ts @@ -255,5 +255,22 @@ describe("Circom Template Inputs Visitor", () => { expect(visitor.templateInputs.out2.type).to.equal("output"); expect(visitor.templateInputs.out2.dimension).to.deep.equal([16]); + + expect(visitor.templateInputs.tmp1.type).to.equal("intermediate"); + expect(visitor.templateInputs.tmp1.dimension).to.deep.equal([6, 8, 2, 20]); + + expect(visitor.templateInputs.tmp2.type).to.equal("intermediate"); + expect(visitor.templateInputs.tmp2.dimension).to.deep.equal([6, 2, 20]); + + expect(visitor.templateInputs.tmp3.type).to.equal("intermediate"); + expect(visitor.templateInputs.tmp3.dimension).to.deep.equal([6, 2, 2, 20]); + + expect(visitor.templateInputs.tmp4.type).to.equal("intermediate"); + expect(visitor.templateInputs.tmp4.dimension).to.deep.equal([5, 2, 2, 20]); + + expect(visitor.templateInputs.powers.type).to.equal("intermediate"); + expect(visitor.templateInputs.powers.dimension).to.deep.equal([ + 2, 256, 2, 6, + ]); }); }); diff --git a/test/data/Math.circom b/test/data/Math.circom index 9e44767..f7c10b2 100644 --- a/test/data/Math.circom +++ b/test/data/Math.circom @@ -1,11 +1,24 @@ pragma circom 2.1.6; -template Math(a, b) { +template Math(a, b, c) { var input1 = (a + b) / 2; var input2 = a + b / 2; + var PRECOMPUTE_NUMBER = 2 ** c; + + signal tmp1 [a][PRECOMPUTE_NUMBER][2][b]; + + var STRIDE = 8; + var parts = a * c \ STRIDE; + + signal tmp2[a] [2] [b]; + signal tmp3[a] [2][2][b]; + signal tmp4[a - 1][2][2][b]; + + signal powers[parts][2 ** STRIDE][2][a]; + signal output out1[input1]; signal output out2[input2]; } -component main = Math(6, 20); +component main = Math(6, 20, 3);