From f93d223c441c5949af14f0373f97fdee078d353d Mon Sep 17 00:00:00 2001 From: Kyrylo Riabov Date: Fri, 17 May 2024 14:06:02 +0300 Subject: [PATCH] Fix a bug when template and main component were separated (#3) * Fixed a bug when template and main component were separated * Updated versions --- package.json | 2 +- src/constants/circom.ts | 1 + src/core/CircuitASTGenerator.ts | 2 + src/core/CircuitArtifactGenerator.ts | 41 ++++++++++++++----- test/CircuitASTGenerator.test.ts | 4 +- test/CircuitArtifactGenerator.test.ts | 4 +- test/CircuitProcessor.test.ts | 2 +- test/fixture/Basic.circom | 7 +--- ...entialAtomicQueryMTPV2OnChainVoting.circom | 14 +++++++ test/fixture/data/Basic.circom | 8 ++++ ...edentialAtomicQueryMTPOnChainVoting.circom | 31 ++++---------- 11 files changed, 72 insertions(+), 44 deletions(-) create mode 100644 test/fixture/credentialAtomicQueryMTPV2OnChainVoting.circom create mode 100644 test/fixture/data/Basic.circom rename test/fixture/{ => data}/credentialAtomicQueryMTPOnChainVoting.circom (92%) diff --git a/package.json b/package.json index e47bf7a..d2a50a7 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@solarity/zktype", - "version": "0.1.0", + "version": "0.1.1", "description": "Unleash TypeScript bindings for Circom circuits", "main": "dist/src/index.js", "types": "dist/src/index.d.ts", diff --git a/src/constants/circom.ts b/src/constants/circom.ts index 9a649d8..2cc1346 100644 --- a/src/constants/circom.ts +++ b/src/constants/circom.ts @@ -9,6 +9,7 @@ export enum SignalVisibilityNames { Private = "private", } +// FIXME: Array could have any number of dimensions (e.g. bigint[2][3][4]...) export enum InternalType { BigInt = "bigint", BigIntArray = "bigint[]", diff --git a/src/core/CircuitASTGenerator.ts b/src/core/CircuitASTGenerator.ts index d263d1d..4bf436b 100644 --- a/src/core/CircuitASTGenerator.ts +++ b/src/core/CircuitASTGenerator.ts @@ -173,6 +173,8 @@ export default class CircuitASTGenerator { /** * Returns an instance of the CircomRunner with the specified arguments. + * + * FIXME: explain error handling */ private _getCircomRunner(args: string[], quiet: boolean = false): any { return new CircomRunner({ diff --git a/src/core/CircuitArtifactGenerator.ts b/src/core/CircuitArtifactGenerator.ts index b1505ff..6964e60 100644 --- a/src/core/CircuitArtifactGenerator.ts +++ b/src/core/CircuitArtifactGenerator.ts @@ -20,6 +20,7 @@ import { CircomCompilerOutput, CircuitProcessorConfig, CircuitArtifactGeneratorConfig, + Template, } from "../types"; /** @@ -130,7 +131,9 @@ export default class CircuitArtifactGenerator { signals: [], }; - for (const statement of ast.circomCompilerOutput[0].definitions[0].Template!.body.Block.stmts) { + const template = this._findTemplateForCircuit(ast.circomCompilerOutput, circuitArtifact.circuitName); + + for (const statement of template.body.Block.stmts) { if ( !statement.InitializationBlock || !this._validateInitializationBlock(ast.sourcePath, statement.InitializationBlock) || @@ -221,6 +224,33 @@ export default class CircuitArtifactGenerator { return SignalVisibilityNames.Private; } + /** + * Finds the template for the circuit based on the circuit name. + * + * @param {CircomCompilerOutput[]} compilerOutputs - The compiler outputs of the circuit. + * @param {string} circuitName - The name of the circuit. + * @returns {Template} The template for the circuit. + */ + private _findTemplateForCircuit(compilerOutputs: CircomCompilerOutput[], circuitName: string): Template { + for (const compilerOutput of compilerOutputs) { + if ( + !compilerOutput.definitions || + compilerOutput.definitions.length < 1 || + !compilerOutput.definitions[0].Template + ) { + continue; + } + + const template = compilerOutput.definitions[0].Template; + + if (template.name === circuitName) { + return template; + } + } + + throw new Error(`The template for the circuit ${circuitName} could not be found.`); + } + /** * Validates the AST of a circuit to ensure it meets the expected structure. * @@ -245,15 +275,6 @@ export default class CircuitArtifactGenerator { if (!ast.circomCompilerOutput[0].main_component[1].Call.id) { throw new Error(`The main component id is missing in the circuit AST: ${ast.sourcePath}`); } - - if ( - !ast.circomCompilerOutput[0].definitions[0].Template || - !ast.circomCompilerOutput[0].definitions[0].Template.body || - !ast.circomCompilerOutput[0].definitions[0].Template.body.Block || - !ast.circomCompilerOutput[0].definitions[0].Template.body.Block.stmts - ) { - throw new Error(`The template is missing or incomplete in the circuit AST: ${ast.sourcePath}`); - } } /** diff --git a/test/CircuitASTGenerator.test.ts b/test/CircuitASTGenerator.test.ts index acdeeb7..03b9856 100644 --- a/test/CircuitASTGenerator.test.ts +++ b/test/CircuitASTGenerator.test.ts @@ -11,7 +11,7 @@ describe("Circuit AST Generation", function () { test("it should compile the basic circuit", async function () { compiler.cleanupCircuitASTs(); - const pathToCircuit = require.resolve("./fixture/credentialAtomicQueryMTPOnChainVoting.circom"); + const pathToCircuit = require.resolve("./fixture/credentialAtomicQueryMTPV2OnChainVoting.circom"); await compiler.generateCircuitAST(pathToCircuit); @@ -20,7 +20,7 @@ describe("Circuit AST Generation", function () { path.join( compiler.projectRoot, CircuitASTGenerator.TEMP_DIR, - "fixture/credentialAtomicQueryMTPOnChainVoting.json", + "fixture/credentialAtomicQueryMTPV2OnChainVoting.json", ), ), ).toBe(true); diff --git a/test/CircuitArtifactGenerator.test.ts b/test/CircuitArtifactGenerator.test.ts index 90c4164..7d6a5b0 100644 --- a/test/CircuitArtifactGenerator.test.ts +++ b/test/CircuitArtifactGenerator.test.ts @@ -12,7 +12,7 @@ import { defaultCircuitArtifactGeneratorConfig, defaultCircuitProcessorConfig } describe("Circuit Artifact Generation", function () { const expectedGeneratedArtifacts = [ "Basic.json", - "credentialAtomicQueryMTPOnChainVoting.json", + "credentialAtomicQueryMTPV2OnChainVoting.json", "lib/BasicInLib.json", "auth/BasicInAuth.json", ]; @@ -87,7 +87,7 @@ describe("Circuit Artifact Generation", function () { fs.cpSync("test/mocks/InvalidTemplateBlock.json", `${CircuitASTGenerator.TEMP_DIR}/InvalidTemplateBlock.json`); expect(artifactGenerator.generateCircuitArtifacts()).rejects.toThrow( - "The template is missing or incomplete in the circuit AST: test/fixture/InvalidTemplateBlock.circom", + "The template for the circuit Multiplier2 could not be found.", ); }); diff --git a/test/CircuitProcessor.test.ts b/test/CircuitProcessor.test.ts index c48c7ce..4a01f40 100644 --- a/test/CircuitProcessor.test.ts +++ b/test/CircuitProcessor.test.ts @@ -13,7 +13,7 @@ import { defaultCircuitProcessorConfig } from "../src/config"; describe("Circuit Processor", function () { const validCircuitPaths = [ "fixture/Basic.circom", - "fixture/credentialAtomicQueryMTPOnChainVoting.circom", + "fixture/credentialAtomicQueryMTPV2OnChainVoting.circom", "fixture/lib/BasicInLib.circom", "fixture/auth/BasicInAuth.circom", ]; diff --git a/test/fixture/Basic.circom b/test/fixture/Basic.circom index 84c7334..5df25d0 100644 --- a/test/fixture/Basic.circom +++ b/test/fixture/Basic.circom @@ -1,10 +1,5 @@ pragma circom 2.1.8; -template Multiplier2() { - //Declaration of signals - signal input in1; - signal input in2; - signal output out <== in1 * in2; -} +include "./data/Basic.circom"; component main {public [in1,in2]} = Multiplier2(); diff --git a/test/fixture/credentialAtomicQueryMTPV2OnChainVoting.circom b/test/fixture/credentialAtomicQueryMTPV2OnChainVoting.circom new file mode 100644 index 0000000..20a094d --- /dev/null +++ b/test/fixture/credentialAtomicQueryMTPV2OnChainVoting.circom @@ -0,0 +1,14 @@ +pragma circom 2.0.0; + +include "./data/credentialAtomicQueryMTPOnChainVoting.circom"; + +component main{public [requestID, + issuerID, + issuerClaimIdenState, + issuerClaimNonRevState, + timestamp, + isRevocationChecked, + challenge, + gistRoot, + votingAddress, + commitment]} = CredentialAtomicQueryMTPOnChainVoting(40, 32, 1, 40, 64); diff --git a/test/fixture/data/Basic.circom b/test/fixture/data/Basic.circom new file mode 100644 index 0000000..96f1061 --- /dev/null +++ b/test/fixture/data/Basic.circom @@ -0,0 +1,8 @@ +pragma circom 2.1.8; + +template Multiplier2() { + //Declaration of signals + signal input in1; + signal input in2; + signal output out <== in1 * in2; +} diff --git a/test/fixture/credentialAtomicQueryMTPOnChainVoting.circom b/test/fixture/data/credentialAtomicQueryMTPOnChainVoting.circom similarity index 92% rename from test/fixture/credentialAtomicQueryMTPOnChainVoting.circom rename to test/fixture/data/credentialAtomicQueryMTPOnChainVoting.circom index 13c8439..cd77a39 100644 --- a/test/fixture/credentialAtomicQueryMTPOnChainVoting.circom +++ b/test/fixture/data/credentialAtomicQueryMTPOnChainVoting.circom @@ -1,16 +1,14 @@ pragma circom 2.0.0; -include "../../node_modules/circomlib/circuits/mux1.circom"; -include "../../node_modules/circomlib/circuits/bitify.circom"; -include "../../node_modules/circomlib/circuits/poseidon.circom"; -include "../../node_modules/circomlib/circuits/comparators.circom"; - -include "./lib/query/query.circom"; -include "./lib/utils/idUtils.circom"; -include "./lib/utils/spongeHash.circom"; -include "./lib/query/comparators.circom"; - -include "./auth/authV2.circom"; +include "../../../node_modules/circomlib/circuits/mux1.circom"; +include "../../../node_modules/circomlib/circuits/bitify.circom"; +include "../../../node_modules/circomlib/circuits/comparators.circom"; +include "../../../node_modules/circomlib/circuits/poseidon.circom"; +include "../lib/query/comparators.circom"; +include "../auth/authV2.circom"; +include "../lib/query/query.circom"; +include "../lib/utils/idUtils.circom"; +include "../lib/utils/spongeHash.circom"; /** credentialJsonLDAtomicQueryMTP.circom - query claim value and verify claim MTP @@ -274,14 +272,3 @@ template CredentialAtomicQueryMTPOnChainVoting(issuerLevels, claimLevels, valueA userID <== auth.userID; } - -component main{public [requestID, - issuerID, - issuerClaimIdenState, - issuerClaimNonRevState, - timestamp, - isRevocationChecked, - challenge, - gistRoot, - votingAddress, - commitment]} = CredentialAtomicQueryMTPOnChainVoting(40, 32, 1, 40, 64);