@solarity/zkit 0.1.1 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -3,12 +3,11 @@
3
3
 
4
4
  # ZKit - Circom Zero Knowledge Kit
5
5
 
6
- **A zero knowledge kit that helps you develop circuits using Circom.**
6
+ **A zero knowledge kit that helps you interact with Circom circuits.**
7
7
 
8
- - Compile and interact with circuits without snarkjs hassle.
9
8
  - Generate and verify ZK proofs with a single line of code.
10
9
  - Render optimized Solidity verifiers.
11
- - Forget about native dependencies - everything is in TypeScript.
10
+ - Build and work with ZK witnesses.
12
11
 
13
12
  ## Installation
14
13
 
@@ -20,67 +19,42 @@ npm install --save-dev @solarity/zkit
20
19
 
21
20
  ## Usage
22
21
 
23
- ### CircomZKit
24
-
25
- ZKit is a configless package, which means you don't need to provide any configuration to use it:
26
-
27
- ```typescript
28
- import { CircomZKit } from "@solarity/zkit";
29
-
30
- async function main() {
31
- const zkit = new CircomZKit();
32
-
33
- const multiplier = zkit.getCircuit("Multiplier");
34
-
35
- // Generates artifacts in the "./zkit-artifacts" directory
36
- await multiplier.compile();
37
-
38
- // Generates ZK proof
39
- const proof = await multiplier.generateProof({ a: 2, b: 3});
40
- }
41
- ```
42
-
43
- By default, ZKit will look for the circuit file in the `./circuits` directory. However, you can change this by providing a custom one:
44
-
45
- ```typescript
46
- new CircomZKit({ circuitsDir: "./my-circuits" });
47
- ```
48
-
49
- To generate zkey, the power-of-tau file is required. ZKit automatically downloads those files from [Hermes](https://hermez.s3-eu-west-1.amazonaws.com/) to the `${HOME}/.zkit/.ptau` directory, so you don't need to re-download them every time you start a new project.
50
-
51
- You can also provide a custom path to the directory where the power-of-tau files are stored:
22
+ > [!IMPORTANT]
23
+ > The kit is not meant to be used directly as its fitness relies heavily on the environment, Circom compilation artifacts management, processing of remappings, etc. Consider using [hardhat-zkit](https://github.com/dl-solarity/hardhat-zkit) which is a complete, developer-friendly package.
52
24
 
53
- ```typescript
54
- new CircomZKit({ ptauDir: "./my-ptau" });
55
- ```
25
+ ### CircuitZKit
56
26
 
57
- > [!IMPORTANT]
58
- > Note that all the files in the `ptauDir` directory must have the `powers-of-tau-{x}.ptau` name format, where `{x}` is a maximum degree (2<sup>x</sup>) of constraints a `ptau` supports.
27
+ `CircuitZKit` is a user-friendly interface for interacting with circom circuits.
59
28
 
60
- ZKit may also ask you for the permission to download the power-of-tau files. You can enable this by toggling off the `allowDownload` option:
29
+ To create a CircuitZKit object it is necessary to pass a config:
61
30
 
62
31
  ```typescript
63
- new CircomZKit({ allowDownload: false });
32
+ CircuitZKitConfig = {
33
+ circuitName: string;
34
+ circuitArtifactsPath: string;
35
+ verifierDirPath: string;
36
+ templateType?: VerifierTemplateType;
37
+ };
64
38
  ```
65
39
 
66
- ### CircuitZKit
67
-
68
- Once you created a `CircuitZKit` instance using the `getCircuit` method, you can manage the underlying circuit using the following methods:
40
+ This config contains all the information required to work with the circuit, namely:
69
41
 
70
- > [!NOTE]
71
- > You should first compile the circuit before creating verifiers or generating proofs.
42
+ - `circuitName` - Name of the circuit file without extension
43
+ - `circuitArtifactsPath` - Full path to compilation artifacts for the desired circuit
44
+ - `verifierDirPath` - Full path to the directory where Solidity verifier file will be generated
45
+ - `templateType` - The type of template that will be used to generate the Solidity verifier contract. Right now only `groth16` is supported
72
46
 
73
- #### compile()
47
+ #### getTemplate()
74
48
 
75
- Compiles the circuit and generates the artifacts in the `./zkit-artifacts` or in the provided `artifactsDir` directory. The default output is `r1cs`, `zkey` and `vkey` files.
49
+ Static `CircuitZKit` function that returns the contents of a template file by the passed type.
76
50
 
77
51
  ```typescript
78
- await multiplier.compile();
52
+ const templateContent = CircuitZKit.getTemplate("groth16");
79
53
  ```
80
54
 
81
55
  #### createVerifier()
82
56
 
83
- Creates Solidity verifier contract in the `./contracts/verifiers` or in the provided `verifiersDir` directory.
57
+ Creates a Solidity verifier contract on `verifierDirPath` path, which was specified in the config.
84
58
 
85
59
  ```typescript
86
60
  await multiplier.createVerifier();
@@ -92,7 +66,7 @@ Generates a proof for the given inputs.
92
66
 
93
67
  ```typescript
94
68
  /// { proof: { pi_a, pi_b, pi_c, protocol, curve }, publicSignals: [6] }
95
- const proof = await multiplier.generateProof({ a: 2, b: 3});
69
+ const proof = await multiplier.generateProof({ a: 2, b: 3 });
96
70
  ```
97
71
 
98
72
  #### verifyProof()
@@ -116,5 +90,3 @@ const calldata = await multiplier.generateCalldata(proof);
116
90
  ## Known limitations
117
91
 
118
92
  - Currently, ZKit supports only the Groth16 proving system.
119
- - Zkey generation doesn't allow additional contributions.
120
- - The `compile` method may cause [issues](https://github.com/iden3/snarkjs/issues/494).
@@ -1,32 +1,19 @@
1
- import { CompileOptions } from "../config/config";
2
- import { ManagerZKit } from "./ManagerZKit";
3
- import { Calldata, Inputs, ProofStruct } from "../types/types";
1
+ import { ArtifactsFileType, Calldata, CircuitZKitConfig, Inputs, ProofStruct, VerifierTemplateType } from "../types/circuit-zkit";
4
2
  /**
5
3
  * `CircuitZKit` represents a single circuit and provides a high-level API to work with it.
6
- *
7
- * @dev This class is not meant to be used directly. Use the `CircomZKit` to create its instance.
8
4
  */
9
5
  export declare class CircuitZKit {
10
- private readonly _circuit;
11
- private readonly _manager;
6
+ private readonly _config;
7
+ constructor(_config: CircuitZKitConfig);
12
8
  /**
13
- * Creates a new instance of `CircuitZKit`.
9
+ * Returns the Solidity verifier template for the specified proving system.
14
10
  *
15
- * @param {string} _circuit - The path to the circuit.
16
- * @param {ManagerZKit} _manager - The manager that maintains the global state.
11
+ * @param {VerifierTemplateType} templateType - The template type.
12
+ * @returns {string} The Solidity verifier template.
17
13
  */
18
- constructor(_circuit: string, _manager: ManagerZKit);
14
+ static getTemplate(templateType: VerifierTemplateType): string;
19
15
  /**
20
- * Compiles the circuit and generates the artifacts.
21
- *
22
- * @dev If compilation fails, the latest valid artifacts will be preserved.
23
- * @dev Doesn't show the compilation error if `quiet` is set to `true`.
24
- *
25
- * @param {Partial<CompileOptions>} [options=defaultCompileOptions] - Compilation options.
26
- */
27
- compile(options?: Partial<CompileOptions>): Promise<void>;
28
- /**
29
- * Creates a verifier contract.
16
+ * Creates a Solidity verifier contract.
30
17
  */
31
18
  createVerifier(): Promise<void>;
32
19
  /**
@@ -58,90 +45,36 @@ export declare class CircuitZKit {
58
45
  */
59
46
  generateCalldata(proof: ProofStruct): Promise<Calldata>;
60
47
  /**
61
- * Returns the circuit ID. The circuit ID is the name of the circuit file without the extension.
62
- *
63
- * @returns {string} The circuit ID.
64
- */
65
- getCircuitId(): string;
66
- /**
67
- * Returns the verifier ID. The verifier ID is the name of the circuit file without the extension, suffixed with "Verifier".
68
- *
69
- * @returns {string} The verifier ID.
70
- */
71
- getVerifierId(): string;
72
- /**
73
- * Generates zero-knowledge key for the circuit.
74
- *
75
- * @param {CompileOptions} options - Compilation options.
76
- * @param {string} outDir - The directory to save the generated key.
77
- * @todo This method may cause issues https://github.com/iden3/snarkjs/issues/494
78
- */
79
- private _generateZKey;
80
- /**
81
- * Generates verification key for the circuit.
48
+ * Returns the circuit name. The circuit name is the name of the circuit file without the extension.
82
49
  *
83
- * @param {string} outDir - The directory to save the generated key.
50
+ * @returns {string} The circuit name.
84
51
  */
85
- private _generateVKey;
52
+ getCircuitName(): string;
86
53
  /**
87
- * Returns the arguments to compile the circuit.
54
+ * Returns the verifier name. The verifier name is the name of the circuit file without the extension, suffixed with "Verifier".
88
55
  *
89
- * @param {CompileOptions} options - Compilation options.
90
- * @param {string} outDir - The directory to save the compiled artifacts.
91
- * @returns {string[]} The arguments to compile the circuit.
56
+ * @returns {string} The verifier name.
92
57
  */
93
- private _getCompileArgs;
58
+ getVerifierName(): string;
94
59
  /**
95
- * Compiles the circuit.
60
+ * Returns the type of verifier template that was stored in the config
96
61
  *
97
- * @param {CompileOptions} options - Compilation options.
98
- * @param {string} outDir - The directory to save the compiled artifacts.
62
+ * @returns {VerifierTemplateType} The verifier template type.
99
63
  */
100
- private _compile;
64
+ getTemplateType(): VerifierTemplateType;
101
65
  /**
102
- * Returns the number of constraints in the circuit. This value is used to fetch the correct `ptau` file.
66
+ * Returns the path to the file of the given type inside artifacts directory. Throws an error if the file doesn't exist.
103
67
  *
104
- * @param {string} outDir - The directory where the compiled artifacts are saved.
105
- * @returns {Promise<number>} The number of constraints in the circuit.
106
- */
107
- _getConstraints(outDir: string): Promise<number>;
108
- /**
109
- * Returns the path to the file of the given type.
110
- *
111
- * @param {FileType} fileType - The type of the file.
112
- * @param {string | undefined} temp - The temporary directory to use.
68
+ * @param {ArtifactsFileType} fileType - The type of the file.
113
69
  * @returns {string} The path to the file.
114
70
  */
115
- private _getFile;
116
- /**
117
- * Returns the path to the directory of the given type.
118
- *
119
- * @param {DirType} dirType - The type of the directory.
120
- * @returns {string} The path to the directory.
121
- */
122
- private _getDir;
71
+ mustGetArtifactsFilePath(fileType: ArtifactsFileType): string;
123
72
  /**
124
- * Returns the path to the file of the given type. Throws an error if the file doesn't exist.
73
+ * Returns the path to the file of the given type inside artifacts directory.
125
74
  *
126
- * @param {FileType} fileType - The type of the file.
127
- * @param {string | undefined} temp - The temporary directory to use.
75
+ * @param {ArtifactsFileType} fileType - The type of the file.
128
76
  * @returns {string} The path to the file.
129
77
  */
130
- private _mustGetFile;
131
- /**
132
- * Moves the files from the temporary directory to the output directory.
133
- *
134
- * @param {string} tempDir - The temporary directory.
135
- * @param {string} outDir - The output directory.
136
- */
137
- private _moveFromTempDirToOutDir;
138
- /**
139
- * Returns a new instance of `CircomRunner`. The `CircomRunner` is used to compile the circuit.
140
- *
141
- * @param {string[]} args - The arguments to run the `circom` compiler.
142
- * @param {boolean} quiet - Whether to suppress the compilation error.
143
- * @returns {typeof CircomRunner} The `CircomRunner` instance.
144
- */
145
- private _getCircomRunner;
78
+ getArtifactsFilePath(fileType: ArtifactsFileType): string;
146
79
  }
147
80
  //# sourceMappingURL=CircuitZKit.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"CircuitZKit.d.ts","sourceRoot":"","sources":["../../src/core/CircuitZKit.ts"],"names":[],"mappings":"AAMA,OAAO,EAAyB,cAAc,EAAE,MAAM,kBAAkB,CAAC;AACzE,OAAO,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAC5C,OAAO,EAAE,QAAQ,EAAqB,MAAM,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAKlF;;;;GAIG;AACH,qBAAa,WAAW;IAQpB,OAAO,CAAC,QAAQ,CAAC,QAAQ;IACzB,OAAO,CAAC,QAAQ,CAAC,QAAQ;IAR3B;;;;;OAKG;gBAEgB,QAAQ,EAAE,MAAM,EAChB,QAAQ,EAAE,WAAW;IAGxC;;;;;;;OAOG;IACU,OAAO,CAAC,OAAO,GAAE,OAAO,CAAC,cAAc,CAAyB,GAAG,OAAO,CAAC,IAAI,CAAC;IAqB7F;;OAEG;IACU,cAAc,IAAI,OAAO,CAAC,IAAI,CAAC;IA0B5C;;;;;;;;OAQG;IACU,aAAa,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,WAAW,CAAC;IAOhE;;;;;;;;OAQG;IACU,WAAW,CAAC,KAAK,EAAE,WAAW,GAAG,OAAO,CAAC,OAAO,CAAC;IAQ9D;;;;;;OAMG;IACU,gBAAgB,CAAC,KAAK,EAAE,WAAW,GAAG,OAAO,CAAC,QAAQ,CAAC;IAMpE;;;;OAIG;IACI,YAAY,IAAI,MAAM;IAI7B;;;;OAIG;IACI,aAAa,IAAI,MAAM;IAI9B;;;;;;OAMG;YACW,aAAa;IA0B3B;;;;OAIG;YACW,aAAa;IAS3B;;;;;;OAMG;IACH,OAAO,CAAC,eAAe;IAYvB;;;;;OAKG;YACW,QAAQ;IAiBtB;;;;;OAKG;IACG,eAAe,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAkCtD;;;;;;OAMG;IACH,OAAO,CAAC,QAAQ;IAuBhB;;;;;OAKG;IACH,OAAO,CAAC,OAAO;IAef;;;;;;OAMG;IACH,OAAO,CAAC,YAAY;IAUpB;;;;;OAKG;IACH,OAAO,CAAC,wBAAwB;IAmBhC;;;;;;OAMG;IACH,OAAO,CAAC,gBAAgB;CAczB"}
1
+ {"version":3,"file":"CircuitZKit.d.ts","sourceRoot":"","sources":["../../src/core/CircuitZKit.ts"],"names":[],"mappings":"AAKA,OAAO,EACL,iBAAiB,EACjB,QAAQ,EACR,iBAAiB,EACjB,MAAM,EACN,WAAW,EACX,oBAAoB,EACrB,MAAM,uBAAuB,CAAC;AAE/B;;GAEG;AACH,qBAAa,WAAW;IACV,OAAO,CAAC,QAAQ,CAAC,OAAO;gBAAP,OAAO,EAAE,iBAAiB;IAEvD;;;;;OAKG;WACW,WAAW,CAAC,YAAY,EAAE,oBAAoB,GAAG,MAAM;IASrE;;OAEG;IACU,cAAc,IAAI,OAAO,CAAC,IAAI,CAAC;IAkB5C;;;;;;;;OAQG;IACU,aAAa,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,WAAW,CAAC;IAOhE;;;;;;;;OAQG;IACU,WAAW,CAAC,KAAK,EAAE,WAAW,GAAG,OAAO,CAAC,OAAO,CAAC;IAQ9D;;;;;;OAMG;IACU,gBAAgB,CAAC,KAAK,EAAE,WAAW,GAAG,OAAO,CAAC,QAAQ,CAAC;IAMpE;;;;OAIG;IACI,cAAc,IAAI,MAAM;IAI/B;;;;OAIG;IACI,eAAe,IAAI,MAAM;IAIhC;;;;OAIG;IACI,eAAe,IAAI,oBAAoB;IAI9C;;;;;OAKG;IACI,wBAAwB,CAAC,QAAQ,EAAE,iBAAiB,GAAG,MAAM;IAUpE;;;;;OAKG;IACI,oBAAoB,CAAC,QAAQ,EAAE,iBAAiB,GAAG,MAAM;CAgCjE"}
@@ -27,75 +27,46 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
27
27
  };
28
28
  Object.defineProperty(exports, "__esModule", { value: true });
29
29
  exports.CircuitZKit = void 0;
30
- const crypto_1 = require("crypto");
31
30
  const ejs_1 = __importDefault(require("ejs"));
32
31
  const fs_1 = __importDefault(require("fs"));
33
32
  const path_1 = __importDefault(require("path"));
34
33
  const snarkjs = __importStar(require("snarkjs"));
35
- const config_1 = require("../config/config");
36
- const utils_1 = require("../utils/utils");
37
- const { CircomRunner, bindings } = require("@distributedlab/circom2");
38
34
  /**
39
35
  * `CircuitZKit` represents a single circuit and provides a high-level API to work with it.
40
- *
41
- * @dev This class is not meant to be used directly. Use the `CircomZKit` to create its instance.
42
36
  */
43
37
  class CircuitZKit {
44
- _circuit;
45
- _manager;
46
- /**
47
- * Creates a new instance of `CircuitZKit`.
48
- *
49
- * @param {string} _circuit - The path to the circuit.
50
- * @param {ManagerZKit} _manager - The manager that maintains the global state.
51
- */
52
- constructor(_circuit, _manager) {
53
- this._circuit = _circuit;
54
- this._manager = _manager;
38
+ _config;
39
+ constructor(_config) {
40
+ this._config = _config;
55
41
  }
56
42
  /**
57
- * Compiles the circuit and generates the artifacts.
58
- *
59
- * @dev If compilation fails, the latest valid artifacts will be preserved.
60
- * @dev Doesn't show the compilation error if `quiet` is set to `true`.
43
+ * Returns the Solidity verifier template for the specified proving system.
61
44
  *
62
- * @param {Partial<CompileOptions>} [options=defaultCompileOptions] - Compilation options.
45
+ * @param {VerifierTemplateType} templateType - The template type.
46
+ * @returns {string} The Solidity verifier template.
63
47
  */
64
- async compile(options = config_1.defaultCompileOptions) {
65
- const tempDir = this._manager.getTempDir();
66
- try {
67
- const artifactDir = this._getDir("artifact");
68
- fs_1.default.mkdirSync(tempDir, { recursive: true });
69
- const overriddenOptions = { ...config_1.defaultCompileOptions, ...options };
70
- await this._compile(overriddenOptions, tempDir);
71
- await this._generateZKey(overriddenOptions, tempDir);
72
- await this._generateVKey(tempDir);
73
- this._moveFromTempDirToOutDir(tempDir, artifactDir);
74
- }
75
- finally {
76
- fs_1.default.rmSync(tempDir, { recursive: true, force: true });
48
+ static getTemplate(templateType) {
49
+ switch (templateType) {
50
+ case "groth16":
51
+ return fs_1.default.readFileSync(path_1.default.join(__dirname, "templates", "verifier_groth16.sol.ejs"), "utf8");
52
+ default:
53
+ throw new Error(`Ambiguous template type: ${templateType}.`);
77
54
  }
78
55
  }
79
56
  /**
80
- * Creates a verifier contract.
57
+ * Creates a Solidity verifier contract.
81
58
  */
82
59
  async createVerifier() {
83
- const tempDir = this._manager.getTempDir();
84
- try {
85
- const verifierDir = this._getDir("verifier");
86
- fs_1.default.mkdirSync(tempDir, { recursive: true });
87
- const vKeyFile = this._mustGetFile("vkey");
88
- const verifierFile = this._getFile("sol", tempDir);
89
- const groth16Template = this._manager.getTemplate("groth16");
90
- const templateParams = JSON.parse(fs_1.default.readFileSync(vKeyFile, "utf-8"));
91
- templateParams["verifier_id"] = this.getVerifierId();
92
- const verifierCode = ejs_1.default.render(groth16Template, templateParams);
93
- fs_1.default.writeFileSync(verifierFile, verifierCode, "utf-8");
94
- this._moveFromTempDirToOutDir(tempDir, verifierDir);
95
- }
96
- finally {
97
- fs_1.default.rmSync(tempDir, { recursive: true, force: true });
60
+ const vKeyFilePath = this.mustGetArtifactsFilePath("vkey");
61
+ const verifierFilePath = path_1.default.join(this._config.verifierDirPath, `${this.getVerifierName()}.sol`);
62
+ const verifierTemplate = CircuitZKit.getTemplate(this.getTemplateType());
63
+ if (!fs_1.default.existsSync(this._config.verifierDirPath)) {
64
+ fs_1.default.mkdirSync(this._config.verifierDirPath, { recursive: true });
98
65
  }
66
+ const templateParams = JSON.parse(fs_1.default.readFileSync(vKeyFilePath, "utf-8"));
67
+ templateParams["verifier_id"] = this.getVerifierName();
68
+ const verifierCode = ejs_1.default.render(verifierTemplate, templateParams);
69
+ fs_1.default.writeFileSync(verifierFilePath, verifierCode, "utf-8");
99
70
  }
100
71
  /**
101
72
  * Generates a proof for the given inputs.
@@ -107,8 +78,8 @@ class CircuitZKit {
107
78
  * @todo Add support for other proving systems.
108
79
  */
109
80
  async generateProof(inputs) {
110
- const zKeyFile = this._mustGetFile("zkey");
111
- const wasmFile = this._mustGetFile("wasm");
81
+ const zKeyFile = this.mustGetArtifactsFilePath("zkey");
82
+ const wasmFile = this.mustGetArtifactsFilePath("wasm");
112
83
  return (await snarkjs.groth16.fullProve(inputs, wasmFile, zKeyFile));
113
84
  }
114
85
  /**
@@ -121,7 +92,7 @@ class CircuitZKit {
121
92
  * @returns {Promise<boolean>} Whether the proof is valid.
122
93
  */
123
94
  async verifyProof(proof) {
124
- const vKeyFile = this._mustGetFile("vkey");
95
+ const vKeyFile = this.mustGetArtifactsFilePath("vkey");
125
96
  const verifier = JSON.parse(fs_1.default.readFileSync(vKeyFile).toString());
126
97
  return await snarkjs.groth16.verify(verifier, proof.publicSignals, proof.proof);
127
98
  }
@@ -137,217 +108,76 @@ class CircuitZKit {
137
108
  return JSON.parse(`[${calldata}]`);
138
109
  }
139
110
  /**
140
- * Returns the circuit ID. The circuit ID is the name of the circuit file without the extension.
111
+ * Returns the circuit name. The circuit name is the name of the circuit file without the extension.
141
112
  *
142
- * @returns {string} The circuit ID.
113
+ * @returns {string} The circuit name.
143
114
  */
144
- getCircuitId() {
145
- return path_1.default.parse(this._circuit).name;
115
+ getCircuitName() {
116
+ return this._config.circuitName;
146
117
  }
147
118
  /**
148
- * Returns the verifier ID. The verifier ID is the name of the circuit file without the extension, suffixed with "Verifier".
119
+ * Returns the verifier name. The verifier name is the name of the circuit file without the extension, suffixed with "Verifier".
149
120
  *
150
- * @returns {string} The verifier ID.
121
+ * @returns {string} The verifier name.
151
122
  */
152
- getVerifierId() {
153
- return `${path_1.default.parse(this._circuit).name}Verifier`;
123
+ getVerifierName() {
124
+ return `${this._config.circuitName}Verifier`;
154
125
  }
155
126
  /**
156
- * Generates zero-knowledge key for the circuit.
127
+ * Returns the type of verifier template that was stored in the config
157
128
  *
158
- * @param {CompileOptions} options - Compilation options.
159
- * @param {string} outDir - The directory to save the generated key.
160
- * @todo This method may cause issues https://github.com/iden3/snarkjs/issues/494
129
+ * @returns {VerifierTemplateType} The verifier template type.
161
130
  */
162
- async _generateZKey(options, outDir) {
163
- const r1csFile = this._getFile("r1cs", outDir);
164
- const zKeyFile = this._getFile("zkey", outDir);
165
- const constraints = await this._getConstraints(outDir);
166
- const ptauFile = await this._manager.fetchPtauFile(constraints);
167
- if (options.setup == "groth16") {
168
- await snarkjs.zKey.newZKey(r1csFile, ptauFile, zKeyFile);
169
- const zKeyFileNext = `${zKeyFile}.next.zkey`;
170
- for (let i = 0; i < options.contributions; ++i) {
171
- await snarkjs.zKey.contribute(zKeyFile, zKeyFileNext, `${zKeyFile}_contribution_${i}`, (0, crypto_1.randomBytes)(32).toString("hex"));
172
- fs_1.default.rmSync(zKeyFile);
173
- fs_1.default.renameSync(zKeyFileNext, zKeyFile);
174
- }
175
- }
176
- }
177
- /**
178
- * Generates verification key for the circuit.
179
- *
180
- * @param {string} outDir - The directory to save the generated key.
181
- */
182
- async _generateVKey(outDir) {
183
- const zKeyFile = this._getFile("zkey", outDir);
184
- const vKeyFile = this._getFile("vkey", outDir);
185
- const vKeyData = await snarkjs.zKey.exportVerificationKey(zKeyFile);
186
- fs_1.default.writeFileSync(vKeyFile, JSON.stringify(vKeyData));
131
+ getTemplateType() {
132
+ return this._config.templateType ?? "groth16";
187
133
  }
188
134
  /**
189
- * Returns the arguments to compile the circuit.
135
+ * Returns the path to the file of the given type inside artifacts directory. Throws an error if the file doesn't exist.
190
136
  *
191
- * @param {CompileOptions} options - Compilation options.
192
- * @param {string} outDir - The directory to save the compiled artifacts.
193
- * @returns {string[]} The arguments to compile the circuit.
194
- */
195
- _getCompileArgs(options, outDir) {
196
- let args = [this._circuit, "--r1cs", "--wasm"];
197
- options.sym && args.push("--sym");
198
- options.json && args.push("--json");
199
- options.c && args.push("--c");
200
- args.push("-o", outDir);
201
- return args;
202
- }
203
- /**
204
- * Compiles the circuit.
205
- *
206
- * @param {CompileOptions} options - Compilation options.
207
- * @param {string} outDir - The directory to save the compiled artifacts.
208
- */
209
- async _compile(options, outDir) {
210
- const args = this._getCompileArgs(options, outDir);
211
- try {
212
- await this._getCircomRunner(args, options.quiet).execute(this._manager.getCompiler());
213
- }
214
- catch (err) {
215
- if (options.quiet) {
216
- throw new Error('Compilation failed with an unknown error. Consider passing "quiet=false" flag to see the compilation error.', { cause: err });
217
- }
218
- throw new Error("Compilation failed.", { cause: err });
219
- }
220
- }
221
- /**
222
- * Returns the number of constraints in the circuit. This value is used to fetch the correct `ptau` file.
223
- *
224
- * @param {string} outDir - The directory where the compiled artifacts are saved.
225
- * @returns {Promise<number>} The number of constraints in the circuit.
137
+ * @param {ArtifactsFileType} fileType - The type of the file.
138
+ * @returns {string} The path to the file.
226
139
  */
227
- async _getConstraints(outDir) {
228
- const r1csFile = this._getFile("r1cs", outDir);
229
- const r1csDescriptor = fs_1.default.openSync(r1csFile, "r");
230
- const readBytes = (position, length) => {
231
- const buffer = Buffer.alloc(length);
232
- fs_1.default.readSync(r1csDescriptor, buffer, { length, position });
233
- return BigInt(`0x${buffer.reverse().toString("hex")}`);
234
- };
235
- /// @dev https://github.com/iden3/r1csfile/blob/d82959da1f88fbd06db0407051fde94afbf8824a/doc/r1cs_bin_format.md#format-of-the-file
236
- const numberOfSections = readBytes(8, 4);
237
- let sectionStart = 12;
238
- for (let i = 0; i < numberOfSections; ++i) {
239
- const sectionType = Number(readBytes(sectionStart, 4));
240
- const sectionSize = Number(readBytes(sectionStart + 4, 8));
241
- /// @dev Reading header section
242
- if (sectionType == 1) {
243
- const totalConstraintsOffset = 4 + 8 + 4 + 32 + 4 + 4 + 4 + 4 + 8;
244
- return Number(readBytes(sectionStart + totalConstraintsOffset, 4));
245
- }
246
- sectionStart += 4 + 8 + sectionSize;
140
+ mustGetArtifactsFilePath(fileType) {
141
+ const file = this.getArtifactsFilePath(fileType);
142
+ if (!fs_1.default.existsSync(file)) {
143
+ throw new Error(`Expected the file "${file}" to exist`);
247
144
  }
248
- throw new Error("Header section is not found.");
145
+ return file;
249
146
  }
250
147
  /**
251
- * Returns the path to the file of the given type.
148
+ * Returns the path to the file of the given type inside artifacts directory.
252
149
  *
253
- * @param {FileType} fileType - The type of the file.
254
- * @param {string | undefined} temp - The temporary directory to use.
150
+ * @param {ArtifactsFileType} fileType - The type of the file.
255
151
  * @returns {string} The path to the file.
256
152
  */
257
- _getFile(fileType, temp) {
258
- const circuitId = this.getCircuitId();
153
+ getArtifactsFilePath(fileType) {
154
+ const circuitName = this.getCircuitName();
155
+ let fileName;
156
+ let fileDir = this._config.circuitArtifactsPath;
259
157
  switch (fileType) {
260
158
  case "r1cs":
261
- return path_1.default.join(temp ?? this._getDir("artifact"), `${circuitId}.r1cs`);
159
+ fileName = `${circuitName}.r1cs`;
160
+ break;
262
161
  case "zkey":
263
- return path_1.default.join(temp ?? this._getDir("artifact"), `${circuitId}.zkey`);
162
+ fileName = `${circuitName}.zkey`;
163
+ break;
264
164
  case "vkey":
265
- return path_1.default.join(temp ?? this._getDir("artifact"), `${circuitId}.vkey.json`);
165
+ fileName = `${circuitName}.vkey.json`;
166
+ break;
266
167
  case "sym":
267
- return path_1.default.join(temp ?? this._getDir("artifact"), `${circuitId}.sym`);
168
+ fileName = `${circuitName}.sym`;
169
+ break;
268
170
  case "json":
269
- return path_1.default.join(temp ?? this._getDir("artifact"), `${circuitId}.json`);
171
+ fileName = `${circuitName}_constraints.json`;
172
+ break;
270
173
  case "wasm":
271
- return path_1.default.join(temp ?? this._getDir("artifact"), `${circuitId}_js`, `${circuitId}.wasm`);
272
- case "sol":
273
- return path_1.default.join(temp ?? this._getDir("verifier"), `${circuitId}Verifier.sol`);
174
+ fileName = `${circuitName}.wasm`;
175
+ fileDir = path_1.default.join(fileDir, `${circuitName}_js`);
176
+ break;
274
177
  default:
275
178
  throw new Error(`Ambiguous file type: ${fileType}.`);
276
179
  }
277
- }
278
- /**
279
- * Returns the path to the directory of the given type.
280
- *
281
- * @param {DirType} dirType - The type of the directory.
282
- * @returns {string} The path to the directory.
283
- */
284
- _getDir(dirType) {
285
- const circuitRelativePath = path_1.default.relative(this._manager.getCircuitsDir(), this._circuit);
286
- switch (dirType) {
287
- case "circuit":
288
- return path_1.default.join(this._manager.getCircuitsDir(), circuitRelativePath, "..");
289
- case "artifact":
290
- return path_1.default.join(this._manager.getArtifactsDir(), circuitRelativePath);
291
- case "verifier":
292
- return path_1.default.join(this._manager.getVerifiersDir(), circuitRelativePath, "..");
293
- default:
294
- throw new Error(`Ambiguous dir type: ${dirType}.`);
295
- }
296
- }
297
- /**
298
- * Returns the path to the file of the given type. Throws an error if the file doesn't exist.
299
- *
300
- * @param {FileType} fileType - The type of the file.
301
- * @param {string | undefined} temp - The temporary directory to use.
302
- * @returns {string} The path to the file.
303
- */
304
- _mustGetFile(fileType, temp) {
305
- const file = this._getFile(fileType, temp);
306
- if (!fs_1.default.existsSync(file)) {
307
- throw new Error(`Expected the file "${file}" to exist`);
308
- }
309
- return file;
310
- }
311
- /**
312
- * Moves the files from the temporary directory to the output directory.
313
- *
314
- * @param {string} tempDir - The temporary directory.
315
- * @param {string} outDir - The output directory.
316
- */
317
- _moveFromTempDirToOutDir(tempDir, outDir) {
318
- fs_1.default.mkdirSync(outDir, { recursive: true });
319
- (0, utils_1.readDirRecursively)(tempDir, (dir, file) => {
320
- const correspondingOutDir = path_1.default.join(outDir, path_1.default.relative(tempDir, dir));
321
- const correspondingOutFile = path_1.default.join(outDir, path_1.default.relative(tempDir, file));
322
- if (!fs_1.default.existsSync(correspondingOutDir)) {
323
- fs_1.default.mkdirSync(correspondingOutDir);
324
- }
325
- if (fs_1.default.existsSync(correspondingOutFile)) {
326
- fs_1.default.rmSync(correspondingOutFile);
327
- }
328
- fs_1.default.copyFileSync(file, correspondingOutFile);
329
- });
330
- }
331
- /**
332
- * Returns a new instance of `CircomRunner`. The `CircomRunner` is used to compile the circuit.
333
- *
334
- * @param {string[]} args - The arguments to run the `circom` compiler.
335
- * @param {boolean} quiet - Whether to suppress the compilation error.
336
- * @returns {typeof CircomRunner} The `CircomRunner` instance.
337
- */
338
- _getCircomRunner(args, quiet) {
339
- return new CircomRunner({
340
- args,
341
- preopens: { "/": "/" },
342
- bindings: {
343
- ...bindings,
344
- exit(code) {
345
- throw new Error(`Compilation error. Exit code: ${code}.`);
346
- },
347
- fs: fs_1.default,
348
- },
349
- quiet,
350
- });
180
+ return path_1.default.join(fileDir, fileName);
351
181
  }
352
182
  }
353
183
  exports.CircuitZKit = CircuitZKit;