Skip to content

Commit

Permalink
Fix a bug when template and main component were separated (#3)
Browse files Browse the repository at this point in the history
* Fixed a bug when template and main component were separated

* Updated versions
  • Loading branch information
KyrylR authored May 17, 2024
1 parent bbaebce commit f93d223
Show file tree
Hide file tree
Showing 11 changed files with 72 additions and 44 deletions.
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -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",
Expand Down
1 change: 1 addition & 0 deletions src/constants/circom.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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[]",
Expand Down
2 changes: 2 additions & 0 deletions src/core/CircuitASTGenerator.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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({
Expand Down
41 changes: 31 additions & 10 deletions src/core/CircuitArtifactGenerator.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import {
CircomCompilerOutput,
CircuitProcessorConfig,
CircuitArtifactGeneratorConfig,
Template,
} from "../types";

/**
Expand Down Expand Up @@ -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) ||
Expand Down Expand Up @@ -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.
*
Expand All @@ -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}`);
}
}

/**
Expand Down
4 changes: 2 additions & 2 deletions test/CircuitASTGenerator.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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);

Expand All @@ -20,7 +20,7 @@ describe("Circuit AST Generation", function () {
path.join(
compiler.projectRoot,
CircuitASTGenerator.TEMP_DIR,
"fixture/credentialAtomicQueryMTPOnChainVoting.json",
"fixture/credentialAtomicQueryMTPV2OnChainVoting.json",
),
),
).toBe(true);
Expand Down
4 changes: 2 additions & 2 deletions test/CircuitArtifactGenerator.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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",
];
Expand Down Expand Up @@ -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.",
);
});

Expand Down
2 changes: 1 addition & 1 deletion test/CircuitProcessor.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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",
];
Expand Down
7 changes: 1 addition & 6 deletions test/fixture/Basic.circom
Original file line number Diff line number Diff line change
@@ -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();
14 changes: 14 additions & 0 deletions test/fixture/credentialAtomicQueryMTPV2OnChainVoting.circom
Original file line number Diff line number Diff line change
@@ -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);
8 changes: 8 additions & 0 deletions test/fixture/data/Basic.circom
Original file line number Diff line number Diff line change
@@ -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;
}
Original file line number Diff line number Diff line change
@@ -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
Expand Down Expand Up @@ -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);

0 comments on commit f93d223

Please sign in to comment.