@solarity/zkit 0.1.1 → 0.2.1
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 +23 -51
- package/dist/core/CircuitZKit.d.ts +30 -89
- package/dist/core/CircuitZKit.d.ts.map +1 -1
- package/dist/core/CircuitZKit.js +80 -235
- package/dist/core/CircuitZKit.js.map +1 -1
- package/dist/index.d.ts +1 -4
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -6
- package/dist/index.js.map +1 -1
- package/dist/types/circuit-zkit.d.ts +43 -0
- package/dist/types/circuit-zkit.d.ts.map +1 -0
- package/dist/types/circuit-zkit.js +3 -0
- package/dist/types/circuit-zkit.js.map +1 -0
- package/package.json +21 -10
- package/src/core/CircuitZKit.ts +88 -283
- package/src/index.ts +1 -6
- package/src/types/{types.ts → circuit-zkit.ts} +8 -12
- package/src/config/config.ts +0 -43
- package/src/core/CircomZKit.ts +0 -110
- package/src/core/ManagerZKit.ts +0 -231
- package/src/utils/utils.ts +0 -60
package/src/core/CircuitZKit.ts
CHANGED
|
@@ -1,89 +1,71 @@
|
|
|
1
|
-
import { randomBytes } from "crypto";
|
|
2
1
|
import ejs from "ejs";
|
|
3
2
|
import fs from "fs";
|
|
4
3
|
import path from "path";
|
|
5
4
|
import * as snarkjs from "snarkjs";
|
|
6
5
|
|
|
7
|
-
import {
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
6
|
+
import {
|
|
7
|
+
ArtifactsFileType,
|
|
8
|
+
Calldata,
|
|
9
|
+
CircuitZKitConfig,
|
|
10
|
+
Inputs,
|
|
11
|
+
ProofStruct,
|
|
12
|
+
VerifierTemplateType,
|
|
13
|
+
} from "../types/circuit-zkit";
|
|
13
14
|
|
|
14
15
|
/**
|
|
15
16
|
* `CircuitZKit` represents a single circuit and provides a high-level API to work with it.
|
|
16
|
-
*
|
|
17
|
-
* @dev This class is not meant to be used directly. Use the `CircomZKit` to create its instance.
|
|
18
17
|
*/
|
|
19
18
|
export class CircuitZKit {
|
|
20
|
-
|
|
21
|
-
* Creates a new instance of `CircuitZKit`.
|
|
22
|
-
*
|
|
23
|
-
* @param {string} _circuit - The path to the circuit.
|
|
24
|
-
* @param {ManagerZKit} _manager - The manager that maintains the global state.
|
|
25
|
-
*/
|
|
26
|
-
constructor(
|
|
27
|
-
private readonly _circuit: string,
|
|
28
|
-
private readonly _manager: ManagerZKit,
|
|
29
|
-
) {}
|
|
19
|
+
constructor(private readonly _config: CircuitZKitConfig) {}
|
|
30
20
|
|
|
31
21
|
/**
|
|
32
|
-
*
|
|
22
|
+
* Returns the Solidity verifier template for the specified proving system.
|
|
33
23
|
*
|
|
34
|
-
* @
|
|
35
|
-
* @
|
|
36
|
-
*
|
|
37
|
-
* @param {Partial<CompileOptions>} [options=defaultCompileOptions] - Compilation options.
|
|
24
|
+
* @param {VerifierTemplateType} templateType - The template type.
|
|
25
|
+
* @returns {string} The Solidity verifier template.
|
|
38
26
|
*/
|
|
39
|
-
public
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
fs.mkdirSync(tempDir, { recursive: true });
|
|
46
|
-
|
|
47
|
-
const overriddenOptions: CompileOptions = { ...defaultCompileOptions, ...options };
|
|
48
|
-
|
|
49
|
-
await this._compile(overriddenOptions, tempDir);
|
|
50
|
-
|
|
51
|
-
await this._generateZKey(overriddenOptions, tempDir);
|
|
52
|
-
await this._generateVKey(tempDir);
|
|
53
|
-
|
|
54
|
-
this._moveFromTempDirToOutDir(tempDir, artifactDir);
|
|
55
|
-
} finally {
|
|
56
|
-
fs.rmSync(tempDir, { recursive: true, force: true });
|
|
27
|
+
public static getTemplate(templateType: VerifierTemplateType): string {
|
|
28
|
+
switch (templateType) {
|
|
29
|
+
case "groth16":
|
|
30
|
+
return fs.readFileSync(path.join(__dirname, "templates", "verifier_groth16.sol.ejs"), "utf8");
|
|
31
|
+
default:
|
|
32
|
+
throw new Error(`Ambiguous template type: ${templateType}.`);
|
|
57
33
|
}
|
|
58
34
|
}
|
|
59
35
|
|
|
60
36
|
/**
|
|
61
|
-
* Creates a verifier contract.
|
|
37
|
+
* Creates a Solidity verifier contract.
|
|
62
38
|
*/
|
|
63
39
|
public async createVerifier(): Promise<void> {
|
|
64
|
-
const
|
|
65
|
-
|
|
66
|
-
try {
|
|
67
|
-
const verifierDir = this._getDir("verifier");
|
|
40
|
+
const vKeyFilePath: string = this.mustGetArtifactsFilePath("vkey");
|
|
41
|
+
const verifierFilePath = path.join(this._config.verifierDirPath, `${this.getVerifierName()}.sol`);
|
|
68
42
|
|
|
69
|
-
|
|
43
|
+
const verifierTemplate: string = CircuitZKit.getTemplate(this.getTemplateType());
|
|
70
44
|
|
|
71
|
-
|
|
72
|
-
|
|
45
|
+
if (!fs.existsSync(this._config.verifierDirPath)) {
|
|
46
|
+
fs.mkdirSync(this._config.verifierDirPath, { recursive: true });
|
|
47
|
+
}
|
|
73
48
|
|
|
74
|
-
|
|
49
|
+
const templateParams = JSON.parse(fs.readFileSync(vKeyFilePath, "utf-8"));
|
|
50
|
+
templateParams["verifier_id"] = this.getVerifierName();
|
|
75
51
|
|
|
76
|
-
|
|
77
|
-
templateParams["verifier_id"] = this.getVerifierId();
|
|
52
|
+
const verifierCode = ejs.render(verifierTemplate, templateParams);
|
|
78
53
|
|
|
79
|
-
|
|
54
|
+
fs.writeFileSync(verifierFilePath, verifierCode, "utf-8");
|
|
55
|
+
}
|
|
80
56
|
|
|
81
|
-
|
|
57
|
+
/**
|
|
58
|
+
* Creates a witness for the given inputs.
|
|
59
|
+
*
|
|
60
|
+
* @dev The `inputs` should be in the same order as the circuit expects them.
|
|
61
|
+
*
|
|
62
|
+
* @param {Inputs} inputs - The inputs for the circuit.
|
|
63
|
+
*/
|
|
64
|
+
public async createWitness(inputs: Inputs): Promise<void> {
|
|
65
|
+
const wasmFile = this.mustGetArtifactsFilePath("wasm");
|
|
66
|
+
const wtnsFile = this.getArtifactsFilePath("wtns");
|
|
82
67
|
|
|
83
|
-
|
|
84
|
-
} finally {
|
|
85
|
-
fs.rmSync(tempDir, { recursive: true, force: true });
|
|
86
|
-
}
|
|
68
|
+
await snarkjs.wtns.calculate(inputs, wasmFile, wtnsFile);
|
|
87
69
|
}
|
|
88
70
|
|
|
89
71
|
/**
|
|
@@ -96,8 +78,8 @@ export class CircuitZKit {
|
|
|
96
78
|
* @todo Add support for other proving systems.
|
|
97
79
|
*/
|
|
98
80
|
public async generateProof(inputs: Inputs): Promise<ProofStruct> {
|
|
99
|
-
const zKeyFile = this.
|
|
100
|
-
const wasmFile = this.
|
|
81
|
+
const zKeyFile = this.mustGetArtifactsFilePath("zkey");
|
|
82
|
+
const wasmFile = this.mustGetArtifactsFilePath("wasm");
|
|
101
83
|
|
|
102
84
|
return (await snarkjs.groth16.fullProve(inputs, wasmFile, zKeyFile)) as ProofStruct;
|
|
103
85
|
}
|
|
@@ -112,7 +94,7 @@ export class CircuitZKit {
|
|
|
112
94
|
* @returns {Promise<boolean>} Whether the proof is valid.
|
|
113
95
|
*/
|
|
114
96
|
public async verifyProof(proof: ProofStruct): Promise<boolean> {
|
|
115
|
-
const vKeyFile = this.
|
|
97
|
+
const vKeyFile = this.mustGetArtifactsFilePath("vkey");
|
|
116
98
|
|
|
117
99
|
const verifier = JSON.parse(fs.readFileSync(vKeyFile).toString());
|
|
118
100
|
|
|
@@ -133,264 +115,87 @@ export class CircuitZKit {
|
|
|
133
115
|
}
|
|
134
116
|
|
|
135
117
|
/**
|
|
136
|
-
* Returns the circuit
|
|
118
|
+
* Returns the circuit name. The circuit name is the name of the circuit file without the extension.
|
|
137
119
|
*
|
|
138
|
-
* @returns {string} The circuit
|
|
120
|
+
* @returns {string} The circuit name.
|
|
139
121
|
*/
|
|
140
|
-
public
|
|
141
|
-
return
|
|
122
|
+
public getCircuitName(): string {
|
|
123
|
+
return this._config.circuitName;
|
|
142
124
|
}
|
|
143
125
|
|
|
144
126
|
/**
|
|
145
|
-
* Returns the verifier
|
|
127
|
+
* Returns the verifier name. The verifier name is the name of the circuit file without the extension, suffixed with "Verifier".
|
|
146
128
|
*
|
|
147
|
-
* @returns {string} The verifier
|
|
129
|
+
* @returns {string} The verifier name.
|
|
148
130
|
*/
|
|
149
|
-
public
|
|
150
|
-
return `${
|
|
131
|
+
public getVerifierName(): string {
|
|
132
|
+
return `${this._config.circuitName}Verifier`;
|
|
151
133
|
}
|
|
152
134
|
|
|
153
135
|
/**
|
|
154
|
-
*
|
|
136
|
+
* Returns the type of verifier template that was stored in the config
|
|
155
137
|
*
|
|
156
|
-
* @
|
|
157
|
-
* @param {string} outDir - The directory to save the generated key.
|
|
158
|
-
* @todo This method may cause issues https://github.com/iden3/snarkjs/issues/494
|
|
138
|
+
* @returns {VerifierTemplateType} The verifier template type.
|
|
159
139
|
*/
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
const zKeyFile = this._getFile("zkey", outDir);
|
|
163
|
-
|
|
164
|
-
const constraints = await this._getConstraints(outDir);
|
|
165
|
-
const ptauFile = await this._manager.fetchPtauFile(constraints);
|
|
166
|
-
|
|
167
|
-
if (options.setup == "groth16") {
|
|
168
|
-
await snarkjs.zKey.newZKey(r1csFile, ptauFile, zKeyFile);
|
|
169
|
-
|
|
170
|
-
const zKeyFileNext = `${zKeyFile}.next.zkey`;
|
|
171
|
-
|
|
172
|
-
for (let i = 0; i < options.contributions; ++i) {
|
|
173
|
-
await snarkjs.zKey.contribute(
|
|
174
|
-
zKeyFile,
|
|
175
|
-
zKeyFileNext,
|
|
176
|
-
`${zKeyFile}_contribution_${i}`,
|
|
177
|
-
randomBytes(32).toString("hex"),
|
|
178
|
-
);
|
|
179
|
-
|
|
180
|
-
fs.rmSync(zKeyFile);
|
|
181
|
-
fs.renameSync(zKeyFileNext, zKeyFile);
|
|
182
|
-
}
|
|
183
|
-
}
|
|
184
|
-
}
|
|
185
|
-
|
|
186
|
-
/**
|
|
187
|
-
* Generates verification key for the circuit.
|
|
188
|
-
*
|
|
189
|
-
* @param {string} outDir - The directory to save the generated key.
|
|
190
|
-
*/
|
|
191
|
-
private async _generateVKey(outDir: string): Promise<void> {
|
|
192
|
-
const zKeyFile = this._getFile("zkey", outDir);
|
|
193
|
-
const vKeyFile = this._getFile("vkey", outDir);
|
|
194
|
-
|
|
195
|
-
const vKeyData = await snarkjs.zKey.exportVerificationKey(zKeyFile);
|
|
196
|
-
|
|
197
|
-
fs.writeFileSync(vKeyFile, JSON.stringify(vKeyData));
|
|
198
|
-
}
|
|
199
|
-
|
|
200
|
-
/**
|
|
201
|
-
* Returns the arguments to compile the circuit.
|
|
202
|
-
*
|
|
203
|
-
* @param {CompileOptions} options - Compilation options.
|
|
204
|
-
* @param {string} outDir - The directory to save the compiled artifacts.
|
|
205
|
-
* @returns {string[]} The arguments to compile the circuit.
|
|
206
|
-
*/
|
|
207
|
-
private _getCompileArgs(options: CompileOptions, outDir: string): string[] {
|
|
208
|
-
let args = [this._circuit, "--r1cs", "--wasm"];
|
|
209
|
-
|
|
210
|
-
options.sym && args.push("--sym");
|
|
211
|
-
options.json && args.push("--json");
|
|
212
|
-
options.c && args.push("--c");
|
|
213
|
-
|
|
214
|
-
args.push("-o", outDir);
|
|
215
|
-
|
|
216
|
-
return args;
|
|
140
|
+
public getTemplateType(): VerifierTemplateType {
|
|
141
|
+
return this._config.templateType ?? "groth16";
|
|
217
142
|
}
|
|
218
143
|
|
|
219
144
|
/**
|
|
220
|
-
*
|
|
145
|
+
* Returns the path to the file of the given type inside artifacts directory. Throws an error if the file doesn't exist.
|
|
221
146
|
*
|
|
222
|
-
* @param {
|
|
223
|
-
* @
|
|
224
|
-
*/
|
|
225
|
-
private async _compile(options: CompileOptions, outDir: string): Promise<void> {
|
|
226
|
-
const args = this._getCompileArgs(options, outDir);
|
|
227
|
-
|
|
228
|
-
try {
|
|
229
|
-
await this._getCircomRunner(args, options.quiet).execute(this._manager.getCompiler());
|
|
230
|
-
} catch (err) {
|
|
231
|
-
if (options.quiet) {
|
|
232
|
-
throw new Error(
|
|
233
|
-
'Compilation failed with an unknown error. Consider passing "quiet=false" flag to see the compilation error.',
|
|
234
|
-
{ cause: err },
|
|
235
|
-
);
|
|
236
|
-
}
|
|
237
|
-
|
|
238
|
-
throw new Error("Compilation failed.", { cause: err });
|
|
239
|
-
}
|
|
240
|
-
}
|
|
241
|
-
|
|
242
|
-
/**
|
|
243
|
-
* Returns the number of constraints in the circuit. This value is used to fetch the correct `ptau` file.
|
|
244
|
-
*
|
|
245
|
-
* @param {string} outDir - The directory where the compiled artifacts are saved.
|
|
246
|
-
* @returns {Promise<number>} The number of constraints in the circuit.
|
|
147
|
+
* @param {ArtifactsFileType} fileType - The type of the file.
|
|
148
|
+
* @returns {string} The path to the file.
|
|
247
149
|
*/
|
|
248
|
-
|
|
249
|
-
const
|
|
250
|
-
|
|
251
|
-
const r1csDescriptor = fs.openSync(r1csFile, "r");
|
|
252
|
-
|
|
253
|
-
const readBytes = (position: number, length: number): bigint => {
|
|
254
|
-
const buffer = Buffer.alloc(length);
|
|
255
|
-
|
|
256
|
-
fs.readSync(r1csDescriptor, buffer, { length, position });
|
|
150
|
+
public mustGetArtifactsFilePath(fileType: ArtifactsFileType): string {
|
|
151
|
+
const file = this.getArtifactsFilePath(fileType);
|
|
257
152
|
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
/// @dev https://github.com/iden3/r1csfile/blob/d82959da1f88fbd06db0407051fde94afbf8824a/doc/r1cs_bin_format.md#format-of-the-file
|
|
262
|
-
const numberOfSections = readBytes(8, 4);
|
|
263
|
-
let sectionStart = 12;
|
|
264
|
-
|
|
265
|
-
for (let i = 0; i < numberOfSections; ++i) {
|
|
266
|
-
const sectionType = Number(readBytes(sectionStart, 4));
|
|
267
|
-
const sectionSize = Number(readBytes(sectionStart + 4, 8));
|
|
268
|
-
|
|
269
|
-
/// @dev Reading header section
|
|
270
|
-
if (sectionType == 1) {
|
|
271
|
-
const totalConstraintsOffset = 4 + 8 + 4 + 32 + 4 + 4 + 4 + 4 + 8;
|
|
272
|
-
|
|
273
|
-
return Number(readBytes(sectionStart + totalConstraintsOffset, 4));
|
|
274
|
-
}
|
|
275
|
-
|
|
276
|
-
sectionStart += 4 + 8 + sectionSize;
|
|
153
|
+
if (!fs.existsSync(file)) {
|
|
154
|
+
throw new Error(`Expected the file "${file}" to exist`);
|
|
277
155
|
}
|
|
278
156
|
|
|
279
|
-
|
|
157
|
+
return file;
|
|
280
158
|
}
|
|
281
159
|
|
|
282
160
|
/**
|
|
283
|
-
* Returns the path to the file of the given type.
|
|
161
|
+
* Returns the path to the file of the given type inside artifacts directory.
|
|
284
162
|
*
|
|
285
|
-
* @param {
|
|
286
|
-
* @param {string | undefined} temp - The temporary directory to use.
|
|
163
|
+
* @param {ArtifactsFileType} fileType - The type of the file.
|
|
287
164
|
* @returns {string} The path to the file.
|
|
288
165
|
*/
|
|
289
|
-
|
|
290
|
-
const
|
|
166
|
+
public getArtifactsFilePath(fileType: ArtifactsFileType): string {
|
|
167
|
+
const circuitName = this.getCircuitName();
|
|
168
|
+
|
|
169
|
+
let fileName: string;
|
|
170
|
+
let fileDir: string = this._config.circuitArtifactsPath;
|
|
291
171
|
|
|
292
172
|
switch (fileType) {
|
|
293
173
|
case "r1cs":
|
|
294
|
-
|
|
174
|
+
fileName = `${circuitName}.r1cs`;
|
|
175
|
+
break;
|
|
295
176
|
case "zkey":
|
|
296
|
-
|
|
177
|
+
fileName = `${circuitName}.zkey`;
|
|
178
|
+
break;
|
|
297
179
|
case "vkey":
|
|
298
|
-
|
|
180
|
+
fileName = `${circuitName}.vkey.json`;
|
|
181
|
+
break;
|
|
299
182
|
case "sym":
|
|
300
|
-
|
|
183
|
+
fileName = `${circuitName}.sym`;
|
|
184
|
+
break;
|
|
301
185
|
case "json":
|
|
302
|
-
|
|
186
|
+
fileName = `${circuitName}_constraints.json`;
|
|
187
|
+
break;
|
|
188
|
+
case "wtns":
|
|
189
|
+
fileName = `${circuitName}.wtns`;
|
|
190
|
+
break;
|
|
303
191
|
case "wasm":
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
192
|
+
fileName = `${circuitName}.wasm`;
|
|
193
|
+
fileDir = path.join(fileDir, `${circuitName}_js`);
|
|
194
|
+
break;
|
|
307
195
|
default:
|
|
308
196
|
throw new Error(`Ambiguous file type: ${fileType}.`);
|
|
309
197
|
}
|
|
310
|
-
}
|
|
311
|
-
|
|
312
|
-
/**
|
|
313
|
-
* Returns the path to the directory of the given type.
|
|
314
|
-
*
|
|
315
|
-
* @param {DirType} dirType - The type of the directory.
|
|
316
|
-
* @returns {string} The path to the directory.
|
|
317
|
-
*/
|
|
318
|
-
private _getDir(dirType: DirType): string {
|
|
319
|
-
const circuitRelativePath = path.relative(this._manager.getCircuitsDir(), this._circuit);
|
|
320
|
-
|
|
321
|
-
switch (dirType) {
|
|
322
|
-
case "circuit":
|
|
323
|
-
return path.join(this._manager.getCircuitsDir(), circuitRelativePath, "..");
|
|
324
|
-
case "artifact":
|
|
325
|
-
return path.join(this._manager.getArtifactsDir(), circuitRelativePath);
|
|
326
|
-
case "verifier":
|
|
327
|
-
return path.join(this._manager.getVerifiersDir(), circuitRelativePath, "..");
|
|
328
|
-
default:
|
|
329
|
-
throw new Error(`Ambiguous dir type: ${dirType}.`);
|
|
330
|
-
}
|
|
331
|
-
}
|
|
332
|
-
|
|
333
|
-
/**
|
|
334
|
-
* Returns the path to the file of the given type. Throws an error if the file doesn't exist.
|
|
335
|
-
*
|
|
336
|
-
* @param {FileType} fileType - The type of the file.
|
|
337
|
-
* @param {string | undefined} temp - The temporary directory to use.
|
|
338
|
-
* @returns {string} The path to the file.
|
|
339
|
-
*/
|
|
340
|
-
private _mustGetFile(fileType: FileType, temp?: string): string {
|
|
341
|
-
const file = this._getFile(fileType, temp);
|
|
342
|
-
|
|
343
|
-
if (!fs.existsSync(file)) {
|
|
344
|
-
throw new Error(`Expected the file "${file}" to exist`);
|
|
345
|
-
}
|
|
346
|
-
|
|
347
|
-
return file;
|
|
348
|
-
}
|
|
349
198
|
|
|
350
|
-
|
|
351
|
-
* Moves the files from the temporary directory to the output directory.
|
|
352
|
-
*
|
|
353
|
-
* @param {string} tempDir - The temporary directory.
|
|
354
|
-
* @param {string} outDir - The output directory.
|
|
355
|
-
*/
|
|
356
|
-
private _moveFromTempDirToOutDir(tempDir: string, outDir: string): void {
|
|
357
|
-
fs.mkdirSync(outDir, { recursive: true });
|
|
358
|
-
|
|
359
|
-
readDirRecursively(tempDir, (dir: string, file: string) => {
|
|
360
|
-
const correspondingOutDir = path.join(outDir, path.relative(tempDir, dir));
|
|
361
|
-
const correspondingOutFile = path.join(outDir, path.relative(tempDir, file));
|
|
362
|
-
|
|
363
|
-
if (!fs.existsSync(correspondingOutDir)) {
|
|
364
|
-
fs.mkdirSync(correspondingOutDir);
|
|
365
|
-
}
|
|
366
|
-
|
|
367
|
-
if (fs.existsSync(correspondingOutFile)) {
|
|
368
|
-
fs.rmSync(correspondingOutFile);
|
|
369
|
-
}
|
|
370
|
-
|
|
371
|
-
fs.copyFileSync(file, correspondingOutFile);
|
|
372
|
-
});
|
|
373
|
-
}
|
|
374
|
-
|
|
375
|
-
/**
|
|
376
|
-
* Returns a new instance of `CircomRunner`. The `CircomRunner` is used to compile the circuit.
|
|
377
|
-
*
|
|
378
|
-
* @param {string[]} args - The arguments to run the `circom` compiler.
|
|
379
|
-
* @param {boolean} quiet - Whether to suppress the compilation error.
|
|
380
|
-
* @returns {typeof CircomRunner} The `CircomRunner` instance.
|
|
381
|
-
*/
|
|
382
|
-
private _getCircomRunner(args: string[], quiet: boolean): typeof CircomRunner {
|
|
383
|
-
return new CircomRunner({
|
|
384
|
-
args,
|
|
385
|
-
preopens: { "/": "/" },
|
|
386
|
-
bindings: {
|
|
387
|
-
...bindings,
|
|
388
|
-
exit(code: number) {
|
|
389
|
-
throw new Error(`Compilation error. Exit code: ${code}.`);
|
|
390
|
-
},
|
|
391
|
-
fs,
|
|
392
|
-
},
|
|
393
|
-
quiet,
|
|
394
|
-
});
|
|
199
|
+
return path.join(fileDir, fileName);
|
|
395
200
|
}
|
|
396
201
|
}
|
package/src/index.ts
CHANGED
|
@@ -1,7 +1,2 @@
|
|
|
1
|
-
export * from "./core/CircomZKit";
|
|
2
1
|
export * from "./core/CircuitZKit";
|
|
3
|
-
export * from "./
|
|
4
|
-
|
|
5
|
-
export { NumericString, PublicSignals, Groth16Proof, Calldata, ProofStruct, Inputs, CircuitInfo } from "./types/types";
|
|
6
|
-
|
|
7
|
-
export { CompileOptions, ManagerZKitConfig, defaultCompileOptions, defaultManagerOptions } from "./config/config";
|
|
2
|
+
export * from "./types/circuit-zkit";
|
|
@@ -28,16 +28,12 @@ export type InputLike = NumberLike | ArrayLike;
|
|
|
28
28
|
|
|
29
29
|
export type Inputs = Record<string, InputLike>;
|
|
30
30
|
|
|
31
|
-
export type
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
export type PtauInfo = {
|
|
41
|
-
file: string;
|
|
42
|
-
url: string | null;
|
|
31
|
+
export type ArtifactsFileType = "r1cs" | "zkey" | "vkey" | "sym" | "json" | "wasm" | "wtns";
|
|
32
|
+
export type VerifierTemplateType = "groth16";
|
|
33
|
+
|
|
34
|
+
export type CircuitZKitConfig = {
|
|
35
|
+
circuitName: string;
|
|
36
|
+
circuitArtifactsPath: string;
|
|
37
|
+
verifierDirPath: string;
|
|
38
|
+
templateType?: VerifierTemplateType;
|
|
43
39
|
};
|
package/src/config/config.ts
DELETED
|
@@ -1,43 +0,0 @@
|
|
|
1
|
-
import { TemplateType } from "../types/types";
|
|
2
|
-
|
|
3
|
-
const { Context } = require("@distributedlab/circom2");
|
|
4
|
-
|
|
5
|
-
export type ManagerZKitConfig = {
|
|
6
|
-
circuitsDir: string;
|
|
7
|
-
artifactsDir: string;
|
|
8
|
-
verifiersDir: string;
|
|
9
|
-
ptauDir: string;
|
|
10
|
-
allowDownload: boolean;
|
|
11
|
-
};
|
|
12
|
-
|
|
13
|
-
export const defaultManagerOptions: Partial<ManagerZKitConfig> = {
|
|
14
|
-
circuitsDir: "circuits",
|
|
15
|
-
artifactsDir: "zkit-artifacts",
|
|
16
|
-
verifiersDir: "contracts/verifiers",
|
|
17
|
-
allowDownload: true,
|
|
18
|
-
};
|
|
19
|
-
|
|
20
|
-
export type CompileOptions = {
|
|
21
|
-
sym: boolean;
|
|
22
|
-
json: boolean;
|
|
23
|
-
c: boolean;
|
|
24
|
-
quiet: boolean;
|
|
25
|
-
setup: TemplateType;
|
|
26
|
-
contributions: number;
|
|
27
|
-
};
|
|
28
|
-
|
|
29
|
-
export const defaultCompileOptions: CompileOptions = {
|
|
30
|
-
sym: false,
|
|
31
|
-
json: false,
|
|
32
|
-
c: false,
|
|
33
|
-
quiet: false,
|
|
34
|
-
setup: "groth16",
|
|
35
|
-
contributions: 5,
|
|
36
|
-
};
|
|
37
|
-
|
|
38
|
-
export type ManagerZKitPrivateConfig = ManagerZKitConfig & {
|
|
39
|
-
compiler: typeof Context;
|
|
40
|
-
templates: {
|
|
41
|
-
groth16: string;
|
|
42
|
-
};
|
|
43
|
-
};
|
package/src/core/CircomZKit.ts
DELETED
|
@@ -1,110 +0,0 @@
|
|
|
1
|
-
import os from "os";
|
|
2
|
-
import path from "path";
|
|
3
|
-
|
|
4
|
-
import { CircuitZKit } from "./CircuitZKit";
|
|
5
|
-
import { ManagerZKit } from "./ManagerZKit";
|
|
6
|
-
import { CircuitInfo } from "../types/types";
|
|
7
|
-
import { readDirRecursively } from "../utils/utils";
|
|
8
|
-
import { defaultManagerOptions, ManagerZKitConfig } from "../config/config";
|
|
9
|
-
|
|
10
|
-
/**
|
|
11
|
-
* `CircomZKit` acts as a factory for `CircuitZKit` instances.
|
|
12
|
-
*/
|
|
13
|
-
export class CircomZKit {
|
|
14
|
-
private readonly _manager: ManagerZKit;
|
|
15
|
-
|
|
16
|
-
/**
|
|
17
|
-
* Creates a new `CircomZKit` instance.
|
|
18
|
-
*
|
|
19
|
-
* @param {Partial<ManagerZKitConfig>} [options=defaultManagerOptions] - The configuration options to use.
|
|
20
|
-
*/
|
|
21
|
-
constructor(options: Partial<ManagerZKitConfig> = defaultManagerOptions) {
|
|
22
|
-
this._manager = new ManagerZKit({ ...defaultManagerOptions, ...options });
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
/**
|
|
26
|
-
* Returns a `CircuitZKit` instance for the specified circuit.
|
|
27
|
-
*
|
|
28
|
-
* @dev If the circuit id is not unique, the path to the circuit file must be provided.
|
|
29
|
-
*
|
|
30
|
-
* @param {string} circuit - The path to the circuit file or the circuit id (filename without extension).
|
|
31
|
-
* @returns {CircomZKit} The `CircuitZKit` instance.
|
|
32
|
-
*/
|
|
33
|
-
public getCircuit(circuit: string): CircuitZKit {
|
|
34
|
-
const circuits = this._getAllCircuits();
|
|
35
|
-
|
|
36
|
-
const candidates = circuits.filter((file) => {
|
|
37
|
-
if (circuit.endsWith(".circom")) {
|
|
38
|
-
return file == path.normalize(circuit);
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
return path.basename(file) == `${circuit}.circom`;
|
|
42
|
-
});
|
|
43
|
-
|
|
44
|
-
if (candidates.length == 0) {
|
|
45
|
-
throw Error(`No circuits with name \"${circuit}\" found`);
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
if (candidates.length > 1) {
|
|
49
|
-
throw Error(
|
|
50
|
-
`Found multiple entries for the circuit "${circuit}".
|
|
51
|
-
|
|
52
|
-
\rConsider replacing \"${circuit}\" with one of the valid paths:
|
|
53
|
-
\r${candidates.map((candidate) => `"${candidate}"`).join(os.EOL)}`,
|
|
54
|
-
);
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
return new CircuitZKit(path.join(this._manager.getCircuitsDir(), candidates[0]), this._manager);
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
/**
|
|
61
|
-
* Returns an array of all circuits available in the circuits directory.
|
|
62
|
-
*
|
|
63
|
-
* @dev If a circuit id is not unique, the id will be set to `null`.
|
|
64
|
-
*
|
|
65
|
-
* @returns {CircuitInfo[]} An array of circuit information objects.
|
|
66
|
-
*/
|
|
67
|
-
public getCircuits(): CircuitInfo[] {
|
|
68
|
-
const circuits = this._getAllCircuits();
|
|
69
|
-
|
|
70
|
-
let circuitsCount = {} as Record<string, number>;
|
|
71
|
-
|
|
72
|
-
for (const circuit of circuits) {
|
|
73
|
-
const circuitId = path.parse(circuit).name;
|
|
74
|
-
|
|
75
|
-
circuitsCount[circuitId] = (circuitsCount[circuitId] || 0) + 1;
|
|
76
|
-
}
|
|
77
|
-
|
|
78
|
-
let result = [] as CircuitInfo[];
|
|
79
|
-
|
|
80
|
-
for (const circuit of circuits) {
|
|
81
|
-
const circuitId = path.parse(circuit).name;
|
|
82
|
-
|
|
83
|
-
result.push({
|
|
84
|
-
path: circuit,
|
|
85
|
-
id: circuitsCount[circuitId] > 1 ? null : circuitId,
|
|
86
|
-
});
|
|
87
|
-
}
|
|
88
|
-
|
|
89
|
-
return result;
|
|
90
|
-
}
|
|
91
|
-
|
|
92
|
-
/**
|
|
93
|
-
* Returns an array of all circuits paths available in the circuits directory.
|
|
94
|
-
*
|
|
95
|
-
* @returns {string[]} An array of circuit paths.
|
|
96
|
-
*/
|
|
97
|
-
private _getAllCircuits(): string[] {
|
|
98
|
-
const circuitsDir = this._manager.getCircuitsDir();
|
|
99
|
-
|
|
100
|
-
let circuits = [] as string[];
|
|
101
|
-
|
|
102
|
-
readDirRecursively(circuitsDir, (_dir: string, file: string) => {
|
|
103
|
-
if (path.extname(file) == ".circom") {
|
|
104
|
-
circuits.push(path.relative(circuitsDir, file));
|
|
105
|
-
}
|
|
106
|
-
});
|
|
107
|
-
|
|
108
|
-
return circuits;
|
|
109
|
-
}
|
|
110
|
-
}
|