@aztec/bb-prover 0.41.0 → 0.43.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/dest/bb/cli.d.ts.map +1 -1
- package/dest/bb/cli.js +24 -2
- package/dest/bb/execute.d.ts +30 -1
- package/dest/bb/execute.d.ts.map +1 -1
- package/dest/bb/execute.js +252 -60
- package/dest/config.d.ts +9 -0
- package/dest/config.d.ts.map +1 -0
- package/dest/config.js +2 -0
- package/dest/index.d.ts +2 -0
- package/dest/index.d.ts.map +1 -1
- package/dest/index.js +3 -1
- package/dest/mappings/mappings.d.ts +1 -0
- package/dest/mappings/mappings.d.ts.map +1 -1
- package/dest/mappings/mappings.js +27 -8
- package/dest/prover/bb_native_proof_creator.d.ts +2 -8
- package/dest/prover/bb_native_proof_creator.d.ts.map +1 -1
- package/dest/prover/bb_native_proof_creator.js +37 -79
- package/dest/prover/bb_prover.d.ts +33 -32
- package/dest/prover/bb_prover.d.ts.map +1 -1
- package/dest/prover/bb_prover.js +231 -162
- package/dest/stats.d.ts.map +1 -1
- package/dest/stats.js +8 -2
- package/dest/test/index.d.ts +1 -0
- package/dest/test/index.d.ts.map +1 -1
- package/dest/test/index.js +2 -1
- package/dest/test/test_circuit_prover.d.ts +9 -7
- package/dest/test/test_circuit_prover.d.ts.map +1 -1
- package/dest/test/test_circuit_prover.js +32 -16
- package/dest/test/test_verifier.d.ts +7 -0
- package/dest/test/test_verifier.d.ts.map +1 -0
- package/dest/test/test_verifier.js +10 -0
- package/dest/verification_key/verification_key_data.d.ts +8 -0
- package/dest/verification_key/verification_key_data.d.ts.map +1 -0
- package/dest/verification_key/verification_key_data.js +24 -0
- package/dest/verifier/bb_verifier.d.ts +18 -0
- package/dest/verifier/bb_verifier.d.ts.map +1 -0
- package/dest/verifier/bb_verifier.js +90 -0
- package/dest/verifier/index.d.ts +2 -0
- package/dest/verifier/index.d.ts.map +1 -0
- package/dest/verifier/index.js +2 -0
- package/package.json +6 -6
- package/src/bb/cli.ts +36 -1
- package/src/bb/execute.ts +340 -67
- package/src/config.ts +9 -0
- package/src/index.ts +2 -0
- package/src/mappings/mappings.ts +38 -12
- package/src/prover/bb_native_proof_creator.ts +49 -91
- package/src/prover/bb_prover.ts +396 -221
- package/src/stats.ts +7 -1
- package/src/test/index.ts +1 -0
- package/src/test/test_circuit_prover.ts +85 -23
- package/src/test/test_verifier.ts +12 -0
- package/src/verification_key/verification_key_data.ts +35 -0
- package/src/verifier/bb_verifier.ts +156 -0
- package/src/verifier/index.ts +1 -0
- package/dest/prover/verification_key_data.d.ts +0 -16
- package/dest/prover/verification_key_data.d.ts.map +0 -1
- package/dest/prover/verification_key_data.js +0 -5
- package/src/prover/verification_key_data.ts +0 -16
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { type AppCircuitProofOutput, type KernelProofOutput, type ProofCreator } from '@aztec/circuit-types';
|
|
2
2
|
import { type CircuitProvingStats, type CircuitWitnessGenerationStats } from '@aztec/circuit-types/stats';
|
|
3
3
|
import {
|
|
4
|
+
AGGREGATION_OBJECT_LENGTH,
|
|
4
5
|
Fr,
|
|
5
6
|
NESTED_RECURSIVE_PROOF_LENGTH,
|
|
6
7
|
type PrivateCircuitPublicInputs,
|
|
@@ -13,13 +14,12 @@ import {
|
|
|
13
14
|
Proof,
|
|
14
15
|
RECURSIVE_PROOF_LENGTH,
|
|
15
16
|
RecursiveProof,
|
|
16
|
-
type
|
|
17
|
-
|
|
17
|
+
type VerificationKeyAsFields,
|
|
18
|
+
type VerificationKeyData,
|
|
18
19
|
} from '@aztec/circuits.js';
|
|
19
20
|
import { siloNoteHash } from '@aztec/circuits.js/hash';
|
|
20
|
-
import {
|
|
21
|
+
import { runInDirectory } from '@aztec/foundation/fs';
|
|
21
22
|
import { createDebugLogger } from '@aztec/foundation/log';
|
|
22
|
-
import { type Tuple } from '@aztec/foundation/serialize';
|
|
23
23
|
import { Timer } from '@aztec/foundation/timer';
|
|
24
24
|
import {
|
|
25
25
|
ClientCircuitArtifacts,
|
|
@@ -36,7 +36,7 @@ import {
|
|
|
36
36
|
convertPrivateKernelTailOutputsFromWitnessMap,
|
|
37
37
|
convertPrivateKernelTailToPublicInputsToWitnessMap,
|
|
38
38
|
} from '@aztec/noir-protocol-circuits-types';
|
|
39
|
-
import {
|
|
39
|
+
import { WASMSimulator } from '@aztec/simulator';
|
|
40
40
|
import { type NoirCompiledCircuit } from '@aztec/types/noir';
|
|
41
41
|
|
|
42
42
|
import { serializeWitness } from '@noir-lang/noirc_abi';
|
|
@@ -47,20 +47,12 @@ import {
|
|
|
47
47
|
BB_RESULT,
|
|
48
48
|
PROOF_FIELDS_FILENAME,
|
|
49
49
|
PROOF_FILENAME,
|
|
50
|
-
VK_FIELDS_FILENAME,
|
|
51
|
-
VK_FILENAME,
|
|
52
50
|
generateKeyForNoirCircuit,
|
|
53
51
|
generateProof,
|
|
54
52
|
verifyProof,
|
|
55
53
|
} from '../bb/execute.js';
|
|
56
54
|
import { mapProtocolArtifactNameToCircuitName } from '../stats.js';
|
|
57
|
-
import {
|
|
58
|
-
AGGREGATION_OBJECT_SIZE,
|
|
59
|
-
CIRCUIT_PUBLIC_INPUTS_INDEX,
|
|
60
|
-
CIRCUIT_RECURSIVE_INDEX,
|
|
61
|
-
CIRCUIT_SIZE_INDEX,
|
|
62
|
-
type VerificationKeyData,
|
|
63
|
-
} from './verification_key_data.js';
|
|
55
|
+
import { extractVkData } from '../verification_key/verification_key_data.js';
|
|
64
56
|
|
|
65
57
|
/**
|
|
66
58
|
* This proof creator implementation uses the native bb binary.
|
|
@@ -141,16 +133,13 @@ export class BBNativeProofCreator implements ProofCreator {
|
|
|
141
133
|
}
|
|
142
134
|
|
|
143
135
|
public async createAppCircuitProof(
|
|
144
|
-
partialWitness:
|
|
136
|
+
partialWitness: WitnessMap,
|
|
145
137
|
bytecode: Buffer,
|
|
146
138
|
appCircuitName?: string,
|
|
147
139
|
): Promise<AppCircuitProofOutput> {
|
|
148
|
-
const
|
|
149
|
-
await fs.mkdir(directory, { recursive: true });
|
|
150
|
-
this.log.debug(`Created directory: ${directory}`);
|
|
151
|
-
try {
|
|
140
|
+
const operation = async (directory: string) => {
|
|
152
141
|
this.log.debug(`Proving app circuit`);
|
|
153
|
-
const proofOutput = await this.createProof(directory, partialWitness, bytecode, 'App',
|
|
142
|
+
const proofOutput = await this.createProof(directory, partialWitness, bytecode, 'App', appCircuitName);
|
|
154
143
|
if (proofOutput.proof.proof.length != RECURSIVE_PROOF_LENGTH) {
|
|
155
144
|
throw new Error(`Incorrect proof length`);
|
|
156
145
|
}
|
|
@@ -160,10 +149,9 @@ export class BBNativeProofCreator implements ProofCreator {
|
|
|
160
149
|
verificationKey: proofOutput.verificationKey,
|
|
161
150
|
};
|
|
162
151
|
return output;
|
|
163
|
-
}
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
}
|
|
152
|
+
};
|
|
153
|
+
|
|
154
|
+
return await runInDirectory(this.bbWorkingDirectory, operation);
|
|
167
155
|
}
|
|
168
156
|
|
|
169
157
|
/**
|
|
@@ -174,7 +162,7 @@ export class BBNativeProofCreator implements ProofCreator {
|
|
|
174
162
|
public async verifyProofForProtocolCircuit(circuitType: ClientProtocolArtifact, proof: Proof) {
|
|
175
163
|
const verificationKey = await this.getVerificationKeyDataForCircuit(circuitType);
|
|
176
164
|
|
|
177
|
-
this.log.debug(`Verifying with key: ${verificationKey.hash.toString()}`);
|
|
165
|
+
this.log.debug(`Verifying with key: ${verificationKey.keyAsFields.hash.toString()}`);
|
|
178
166
|
|
|
179
167
|
const logFunction = (message: string) => {
|
|
180
168
|
this.log.debug(`${circuitType} BB out - ${message}`);
|
|
@@ -195,21 +183,15 @@ export class BBNativeProofCreator implements ProofCreator {
|
|
|
195
183
|
proof: Proof,
|
|
196
184
|
logFunction: (message: string) => void = () => {},
|
|
197
185
|
) {
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
const proofFileName = `${bbWorkingDirectory}/proof`;
|
|
203
|
-
const verificationKeyPath = `${bbWorkingDirectory}/vk`;
|
|
186
|
+
const operation = async (bbWorkingDirectory: string) => {
|
|
187
|
+
const proofFileName = `${bbWorkingDirectory}/proof`;
|
|
188
|
+
const verificationKeyPath = `${bbWorkingDirectory}/vk`;
|
|
204
189
|
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
try {
|
|
190
|
+
await fs.writeFile(proofFileName, proof.buffer);
|
|
191
|
+
await fs.writeFile(verificationKeyPath, verificationKey);
|
|
209
192
|
return await verifyProof(this.bbBinaryPath, proofFileName, verificationKeyPath!, logFunction);
|
|
210
|
-
}
|
|
211
|
-
|
|
212
|
-
}
|
|
193
|
+
};
|
|
194
|
+
return await runInDirectory(this.bbWorkingDirectory, operation);
|
|
213
195
|
}
|
|
214
196
|
|
|
215
197
|
/**
|
|
@@ -231,39 +213,13 @@ export class BBNativeProofCreator implements ProofCreator {
|
|
|
231
213
|
if (result.status === BB_RESULT.FAILURE) {
|
|
232
214
|
throw new Error(`Failed to generate verification key for ${circuitType}, ${result.reason}`);
|
|
233
215
|
}
|
|
234
|
-
return
|
|
216
|
+
return extractVkData(result.vkPath!);
|
|
235
217
|
});
|
|
236
218
|
this.verificationKeys.set(circuitType, promise);
|
|
237
219
|
}
|
|
238
220
|
return await promise;
|
|
239
221
|
}
|
|
240
222
|
|
|
241
|
-
/**
|
|
242
|
-
* Reads the verification key data stored at the specified location and parses into a VerificationKeyData
|
|
243
|
-
* @param filePath - The directory containing the verification key data files
|
|
244
|
-
* @returns The verification key data
|
|
245
|
-
*/
|
|
246
|
-
private async convertVk(filePath: string): Promise<VerificationKeyData> {
|
|
247
|
-
const [rawFields, rawBinary] = await Promise.all([
|
|
248
|
-
fs.readFile(`${filePath}/${VK_FIELDS_FILENAME}`, { encoding: 'utf-8' }),
|
|
249
|
-
fs.readFile(`${filePath}/${VK_FILENAME}`),
|
|
250
|
-
]);
|
|
251
|
-
const fieldsJson = JSON.parse(rawFields);
|
|
252
|
-
const fields = fieldsJson.map(Fr.fromString);
|
|
253
|
-
// The first item is the hash, this is not part of the actual VK
|
|
254
|
-
const vkHash = fields[0];
|
|
255
|
-
const actualVk = fields.slice(1);
|
|
256
|
-
const vk: VerificationKeyData = {
|
|
257
|
-
hash: vkHash,
|
|
258
|
-
keyAsFields: actualVk as Tuple<Fr, typeof VERIFICATION_KEY_LENGTH_IN_FIELDS>,
|
|
259
|
-
keyAsBytes: rawBinary,
|
|
260
|
-
numPublicInputs: Number(actualVk[CIRCUIT_PUBLIC_INPUTS_INDEX]),
|
|
261
|
-
circuitSize: Number(actualVk[CIRCUIT_SIZE_INDEX]),
|
|
262
|
-
isRecursive: actualVk[CIRCUIT_RECURSIVE_INDEX] == Fr.ONE,
|
|
263
|
-
};
|
|
264
|
-
return vk;
|
|
265
|
-
}
|
|
266
|
-
|
|
267
223
|
/**
|
|
268
224
|
* Ensures our verification key cache includes the key data located at the specified directory
|
|
269
225
|
* @param filePath - The directory containing the verification key data files
|
|
@@ -272,7 +228,7 @@ export class BBNativeProofCreator implements ProofCreator {
|
|
|
272
228
|
private async updateVerificationKeyAfterProof(filePath: string, circuitType: ClientProtocolArtifact) {
|
|
273
229
|
let promise = this.verificationKeys.get(circuitType);
|
|
274
230
|
if (!promise) {
|
|
275
|
-
promise =
|
|
231
|
+
promise = extractVkData(filePath);
|
|
276
232
|
this.log.debug(`Updated verification key for circuit: ${circuitType}`);
|
|
277
233
|
this.verificationKeys.set(circuitType, promise);
|
|
278
234
|
}
|
|
@@ -285,15 +241,10 @@ export class BBNativeProofCreator implements ProofCreator {
|
|
|
285
241
|
convertInputs: (inputs: I) => WitnessMap,
|
|
286
242
|
convertOutputs: (outputs: WitnessMap) => O,
|
|
287
243
|
): Promise<KernelProofOutput<O>> {
|
|
288
|
-
const
|
|
289
|
-
await fs.mkdir(directory, { recursive: true });
|
|
290
|
-
this.log.debug(`Created directory: ${directory}`);
|
|
291
|
-
try {
|
|
244
|
+
const operation = async (directory: string) => {
|
|
292
245
|
return await this.generateWitnessAndCreateProof(inputs, circuitType, directory, convertInputs, convertOutputs);
|
|
293
|
-
}
|
|
294
|
-
|
|
295
|
-
this.log.debug(`Deleted directory: ${directory}`);
|
|
296
|
-
}
|
|
246
|
+
};
|
|
247
|
+
return await runInDirectory(this.bbWorkingDirectory, operation);
|
|
297
248
|
}
|
|
298
249
|
|
|
299
250
|
private async generateWitnessAndCreateProof<
|
|
@@ -314,14 +265,12 @@ export class BBNativeProofCreator implements ProofCreator {
|
|
|
314
265
|
const outputWitness = await this.simulator.simulateCircuit(witnessMap, compiledCircuit);
|
|
315
266
|
const output = convertOutputs(outputWitness);
|
|
316
267
|
|
|
317
|
-
const inputSize = inputs.toBuffer().length;
|
|
318
|
-
const outputSize = output.toBuffer().length;
|
|
319
268
|
this.log.debug(`Generated witness for ${circuitType}`, {
|
|
320
269
|
eventName: 'circuit-witness-generation',
|
|
321
270
|
circuitName: mapProtocolArtifactNameToCircuitName(circuitType),
|
|
322
271
|
duration: timer.ms(),
|
|
323
|
-
inputSize,
|
|
324
|
-
outputSize,
|
|
272
|
+
inputSize: inputs.toBuffer().length,
|
|
273
|
+
outputSize: output.toBuffer().length,
|
|
325
274
|
} satisfies CircuitWitnessGenerationStats);
|
|
326
275
|
|
|
327
276
|
const proofOutput = await this.createProof(
|
|
@@ -329,8 +278,6 @@ export class BBNativeProofCreator implements ProofCreator {
|
|
|
329
278
|
outputWitness,
|
|
330
279
|
Buffer.from(compiledCircuit.bytecode, 'base64'),
|
|
331
280
|
circuitType,
|
|
332
|
-
inputSize,
|
|
333
|
-
outputSize,
|
|
334
281
|
);
|
|
335
282
|
if (proofOutput.proof.proof.length != NESTED_RECURSIVE_PROOF_LENGTH) {
|
|
336
283
|
throw new Error(`Incorrect proof length`);
|
|
@@ -350,8 +297,6 @@ export class BBNativeProofCreator implements ProofCreator {
|
|
|
350
297
|
partialWitness: WitnessMap,
|
|
351
298
|
bytecode: Buffer,
|
|
352
299
|
circuitType: ClientProtocolArtifact | 'App',
|
|
353
|
-
inputSize: number,
|
|
354
|
-
outputSize: number,
|
|
355
300
|
appCircuitName?: string,
|
|
356
301
|
): Promise<{
|
|
357
302
|
proof: RecursiveProof<typeof RECURSIVE_PROOF_LENGTH> | RecursiveProof<typeof NESTED_RECURSIVE_PROOF_LENGTH>;
|
|
@@ -365,6 +310,10 @@ export class BBNativeProofCreator implements ProofCreator {
|
|
|
365
310
|
|
|
366
311
|
this.log.debug(`Written ${inputsWitnessFile}`);
|
|
367
312
|
|
|
313
|
+
this.log.info(`Proving ${circuitType} circuit...`);
|
|
314
|
+
|
|
315
|
+
const timer = new Timer();
|
|
316
|
+
|
|
368
317
|
const provingResult = await generateProof(
|
|
369
318
|
this.bbBinaryPath,
|
|
370
319
|
directory,
|
|
@@ -379,40 +328,45 @@ export class BBNativeProofCreator implements ProofCreator {
|
|
|
379
328
|
throw new Error(provingResult.reason);
|
|
380
329
|
}
|
|
381
330
|
|
|
331
|
+
this.log.info(
|
|
332
|
+
`Generated ${circuitType === 'App' ? appCircuitName : circuitType} circuit proof in ${timer.ms()} ms`,
|
|
333
|
+
);
|
|
334
|
+
|
|
382
335
|
if (circuitType === 'App') {
|
|
383
|
-
const vkData = await
|
|
336
|
+
const vkData = await extractVkData(directory);
|
|
384
337
|
const proof = await this.readProofAsFields<typeof RECURSIVE_PROOF_LENGTH>(directory, circuitType, vkData);
|
|
385
338
|
|
|
386
339
|
this.log.debug(`Generated proof`, {
|
|
387
340
|
eventName: 'circuit-proving',
|
|
388
341
|
circuitName: 'app-circuit',
|
|
389
342
|
duration: provingResult.duration,
|
|
390
|
-
inputSize,
|
|
391
|
-
outputSize,
|
|
343
|
+
inputSize: compressedBincodedWitness.length,
|
|
392
344
|
proofSize: proof.binaryProof.buffer.length,
|
|
393
345
|
appCircuitName,
|
|
394
346
|
circuitSize: vkData.circuitSize,
|
|
395
347
|
numPublicInputs: vkData.numPublicInputs,
|
|
396
348
|
} as CircuitProvingStats);
|
|
397
349
|
|
|
398
|
-
return { proof, verificationKey:
|
|
350
|
+
return { proof, verificationKey: vkData.keyAsFields };
|
|
399
351
|
}
|
|
400
352
|
|
|
401
353
|
const vkData = await this.updateVerificationKeyAfterProof(directory, circuitType);
|
|
354
|
+
|
|
402
355
|
const proof = await this.readProofAsFields<typeof NESTED_RECURSIVE_PROOF_LENGTH>(directory, circuitType, vkData);
|
|
403
356
|
|
|
357
|
+
await this.verifyProofForProtocolCircuit(circuitType, proof.binaryProof);
|
|
358
|
+
|
|
404
359
|
this.log.debug(`Generated proof`, {
|
|
405
360
|
circuitName: mapProtocolArtifactNameToCircuitName(circuitType),
|
|
406
361
|
duration: provingResult.duration,
|
|
407
362
|
eventName: 'circuit-proving',
|
|
408
|
-
inputSize,
|
|
409
|
-
outputSize,
|
|
363
|
+
inputSize: compressedBincodedWitness.length,
|
|
410
364
|
proofSize: proof.binaryProof.buffer.length,
|
|
411
365
|
circuitSize: vkData.circuitSize,
|
|
412
366
|
numPublicInputs: vkData.numPublicInputs,
|
|
413
367
|
} as CircuitProvingStats);
|
|
414
368
|
|
|
415
|
-
return { proof, verificationKey:
|
|
369
|
+
return { proof, verificationKey: vkData.keyAsFields };
|
|
416
370
|
}
|
|
417
371
|
|
|
418
372
|
/**
|
|
@@ -433,12 +387,16 @@ export class BBNativeProofCreator implements ProofCreator {
|
|
|
433
387
|
const json = JSON.parse(proofString);
|
|
434
388
|
const fields = json.map(Fr.fromString);
|
|
435
389
|
const numPublicInputs =
|
|
436
|
-
circuitType === 'App' ? vkData.numPublicInputs : vkData.numPublicInputs -
|
|
390
|
+
circuitType === 'App' ? vkData.numPublicInputs : vkData.numPublicInputs - AGGREGATION_OBJECT_LENGTH;
|
|
437
391
|
const fieldsWithoutPublicInputs = fields.slice(numPublicInputs);
|
|
438
392
|
this.log.debug(
|
|
439
393
|
`Circuit type: ${circuitType}, complete proof length: ${fields.length}, without public inputs: ${fieldsWithoutPublicInputs.length}, num public inputs: ${numPublicInputs}, circuit size: ${vkData.circuitSize}, is recursive: ${vkData.isRecursive}, raw length: ${binaryProof.length}`,
|
|
440
394
|
);
|
|
441
|
-
const proof = new RecursiveProof<PROOF_LENGTH>(
|
|
395
|
+
const proof = new RecursiveProof<PROOF_LENGTH>(
|
|
396
|
+
fieldsWithoutPublicInputs,
|
|
397
|
+
new Proof(binaryProof, vkData.numPublicInputs),
|
|
398
|
+
true,
|
|
399
|
+
);
|
|
442
400
|
return proof;
|
|
443
401
|
}
|
|
444
402
|
}
|