@aztec/bb-prover 0.46.2 → 0.46.4

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.
Files changed (36) hide show
  1. package/dest/bb/cli.d.ts.map +1 -1
  2. package/dest/bb/cli.js +22 -1
  3. package/dest/bb/execute.d.ts +25 -0
  4. package/dest/bb/execute.d.ts.map +1 -1
  5. package/dest/bb/execute.js +185 -7
  6. package/dest/prover/bb_private_kernel_prover.d.ts +49 -0
  7. package/dest/prover/bb_private_kernel_prover.d.ts.map +1 -0
  8. package/dest/prover/bb_private_kernel_prover.js +201 -0
  9. package/dest/prover/bb_prover.d.ts +20 -5
  10. package/dest/prover/bb_prover.d.ts.map +1 -1
  11. package/dest/prover/bb_prover.js +118 -15
  12. package/dest/prover/index.d.ts +1 -1
  13. package/dest/prover/index.d.ts.map +1 -1
  14. package/dest/prover/index.js +2 -2
  15. package/dest/stats.d.ts.map +1 -1
  16. package/dest/stats.js +3 -1
  17. package/dest/test/test_circuit_prover.d.ts +6 -1
  18. package/dest/test/test_circuit_prover.d.ts.map +1 -1
  19. package/dest/test/test_circuit_prover.js +17 -3
  20. package/dest/verification_key/verification_key_data.d.ts.map +1 -1
  21. package/dest/verification_key/verification_key_data.js +2 -3
  22. package/dest/verifier/bb_verifier.d.ts.map +1 -1
  23. package/dest/verifier/bb_verifier.js +8 -7
  24. package/package.json +8 -7
  25. package/src/bb/cli.ts +32 -0
  26. package/src/bb/execute.ts +227 -7
  27. package/src/prover/{bb_native_proof_creator.ts → bb_private_kernel_prover.ts} +114 -114
  28. package/src/prover/bb_prover.ts +167 -17
  29. package/src/prover/index.ts +1 -1
  30. package/src/stats.ts +2 -0
  31. package/src/test/test_circuit_prover.ts +42 -0
  32. package/src/verification_key/verification_key_data.ts +1 -5
  33. package/src/verifier/bb_verifier.ts +7 -6
  34. package/dest/prover/bb_native_proof_creator.d.ts +0 -47
  35. package/dest/prover/bb_native_proof_creator.d.ts.map +0 -1
  36. package/dest/prover/bb_native_proof_creator.js +0 -198
@@ -1,9 +1,12 @@
1
- import { type AppCircuitProofOutput, type KernelProofOutput, type ProofCreator } from '@aztec/circuit-types';
2
- import { type CircuitProvingStats, type CircuitWitnessGenerationStats } from '@aztec/circuit-types/stats';
3
1
  import {
4
- AGGREGATION_OBJECT_LENGTH,
2
+ type AppCircuitSimulateOutput,
3
+ type PrivateKernelProver,
4
+ type PrivateKernelSimulateOutput,
5
+ } from '@aztec/circuit-types';
6
+ import { type CircuitSimulationStats, type CircuitWitnessGenerationStats } from '@aztec/circuit-types/stats';
7
+ import {
8
+ ClientIvcProof,
5
9
  Fr,
6
- NESTED_RECURSIVE_PROOF_LENGTH,
7
10
  type PrivateCircuitPublicInputs,
8
11
  type PrivateKernelCircuitPublicInputs,
9
12
  type PrivateKernelInitCircuitPrivateInputs,
@@ -12,7 +15,6 @@ import {
12
15
  type PrivateKernelTailCircuitPrivateInputs,
13
16
  type PrivateKernelTailCircuitPublicInputs,
14
17
  Proof,
15
- RECURSIVE_PROOF_LENGTH,
16
18
  RecursiveProof,
17
19
  type VerificationKeyAsFields,
18
20
  type VerificationKeyData,
@@ -40,20 +42,29 @@ import {
40
42
  import { WASMSimulator } from '@aztec/simulator';
41
43
  import { type NoirCompiledCircuit } from '@aztec/types/noir';
42
44
 
45
+ import { encode } from '@msgpack/msgpack';
43
46
  import { serializeWitness } from '@noir-lang/noirc_abi';
44
47
  import { type WitnessMap } from '@noir-lang/types';
45
48
  import * as fs from 'fs/promises';
46
- import { join } from 'path';
49
+ import path from 'path';
47
50
 
48
- import { BB_RESULT, PROOF_FIELDS_FILENAME, PROOF_FILENAME, generateProof, verifyProof } from '../bb/execute.js';
51
+ import {
52
+ BB_RESULT,
53
+ PROOF_FIELDS_FILENAME,
54
+ PROOF_FILENAME,
55
+ computeVerificationKey,
56
+ executeBbClientIvcProof,
57
+ verifyProof,
58
+ } from '../bb/execute.js';
49
59
  import { mapProtocolArtifactNameToCircuitName } from '../stats.js';
50
60
  import { extractVkData } from '../verification_key/verification_key_data.js';
51
61
 
52
62
  /**
53
63
  * This proof creator implementation uses the native bb binary.
54
64
  * This is a temporary implementation until we make the WASM version work.
65
+ * TODO(#7368): this class grew 'organically' aka it could use a look at its resposibilities
55
66
  */
56
- export class BBNativeProofCreator implements ProofCreator {
67
+ export class BBNativePrivateKernelProver implements PrivateKernelProver {
57
68
  private simulator = new WASMSimulator();
58
69
 
59
70
  private verificationKeys: Map<ClientProtocolArtifact, Promise<VerificationKeyData>> = new Map<
@@ -67,16 +78,59 @@ export class BBNativeProofCreator implements ProofCreator {
67
78
  private log = createDebugLogger('aztec:bb-native-prover'),
68
79
  ) {}
69
80
 
81
+ private async _createClientIvcProof(
82
+ directory: string,
83
+ acirs: Buffer[],
84
+ witnessStack: WitnessMap[],
85
+ ): Promise<ClientIvcProof> {
86
+ // TODO(#7371): Longer term we won't use this hacked together msgpack format
87
+ // and instead properly create the bincode serialization from rust
88
+ await fs.writeFile(path.join(directory, 'acir.msgpack'), encode(acirs));
89
+ await fs.writeFile(
90
+ path.join(directory, 'witnesses.msgpack'),
91
+ encode(witnessStack.map(map => serializeWitness(map))),
92
+ );
93
+ const provingResult = await executeBbClientIvcProof(
94
+ this.bbBinaryPath,
95
+ directory,
96
+ path.join(directory, 'acir.msgpack'),
97
+ path.join(directory, 'witnesses.msgpack'),
98
+ this.log.info,
99
+ );
100
+
101
+ if (provingResult.status === BB_RESULT.FAILURE) {
102
+ this.log.error(`Failed to generate client ivc proof`);
103
+ throw new Error(provingResult.reason);
104
+ }
105
+
106
+ const proof = await ClientIvcProof.readFromOutputDirectory(directory);
107
+
108
+ this.log.info(`Generated IVC proof`, {
109
+ duration: provingResult.durationMs,
110
+ eventName: 'circuit-proving',
111
+ });
112
+
113
+ return proof;
114
+ }
115
+
116
+ async createClientIvcProof(acirs: Buffer[], witnessStack: WitnessMap[]): Promise<ClientIvcProof> {
117
+ this.log.info(`Generating Client IVC proof`);
118
+ const operation = async (directory: string) => {
119
+ return await this._createClientIvcProof(directory, acirs, witnessStack);
120
+ };
121
+ return await runInDirectory(this.bbWorkingDirectory, operation);
122
+ }
123
+
70
124
  public getSiloedCommitments(publicInputs: PrivateCircuitPublicInputs) {
71
125
  const contractAddress = publicInputs.callContext.storageContractAddress;
72
126
 
73
127
  return Promise.resolve(publicInputs.noteHashes.map(commitment => siloNoteHash(contractAddress, commitment.value)));
74
128
  }
75
129
 
76
- public async createProofInit(
130
+ public async simulateProofInit(
77
131
  inputs: PrivateKernelInitCircuitPrivateInputs,
78
- ): Promise<KernelProofOutput<PrivateKernelCircuitPublicInputs>> {
79
- return await this.createSafeProof(
132
+ ): Promise<PrivateKernelSimulateOutput<PrivateKernelCircuitPublicInputs>> {
133
+ return await this.simulate(
80
134
  inputs,
81
135
  'PrivateKernelInitArtifact',
82
136
  convertPrivateKernelInitInputsToWitnessMap,
@@ -84,10 +138,10 @@ export class BBNativeProofCreator implements ProofCreator {
84
138
  );
85
139
  }
86
140
 
87
- public async createProofInner(
141
+ public async simulateProofInner(
88
142
  inputs: PrivateKernelInnerCircuitPrivateInputs,
89
- ): Promise<KernelProofOutput<PrivateKernelCircuitPublicInputs>> {
90
- return await this.createSafeProof(
143
+ ): Promise<PrivateKernelSimulateOutput<PrivateKernelCircuitPublicInputs>> {
144
+ return await this.simulate(
91
145
  inputs,
92
146
  'PrivateKernelInnerArtifact',
93
147
  convertPrivateKernelInnerInputsToWitnessMap,
@@ -95,10 +149,10 @@ export class BBNativeProofCreator implements ProofCreator {
95
149
  );
96
150
  }
97
151
 
98
- public async createProofReset(
152
+ public async simulateProofReset(
99
153
  inputs: PrivateKernelResetCircuitPrivateInputsVariants,
100
- ): Promise<KernelProofOutput<PrivateKernelCircuitPublicInputs>> {
101
- return await this.createSafeProof(
154
+ ): Promise<PrivateKernelSimulateOutput<PrivateKernelCircuitPublicInputs>> {
155
+ return await this.simulate(
102
156
  inputs,
103
157
  PrivateResetTagToArtifactName[inputs.sizeTag],
104
158
  convertPrivateKernelResetInputsToWitnessMap,
@@ -106,18 +160,18 @@ export class BBNativeProofCreator implements ProofCreator {
106
160
  );
107
161
  }
108
162
 
109
- public async createProofTail(
163
+ public async simulateProofTail(
110
164
  inputs: PrivateKernelTailCircuitPrivateInputs,
111
- ): Promise<KernelProofOutput<PrivateKernelTailCircuitPublicInputs>> {
165
+ ): Promise<PrivateKernelSimulateOutput<PrivateKernelTailCircuitPublicInputs>> {
112
166
  if (!inputs.isForPublic()) {
113
- return await this.createSafeProof(
167
+ return await this.simulate(
114
168
  inputs,
115
169
  'PrivateKernelTailArtifact',
116
170
  convertPrivateKernelTailInputsToWitnessMap,
117
171
  convertPrivateKernelTailOutputsFromWitnessMap,
118
172
  );
119
173
  }
120
- return await this.createSafeProof(
174
+ return await this.simulate(
121
175
  inputs,
122
176
  'PrivateKernelTailToPublicArtifact',
123
177
  convertPrivateKernelTailToPublicInputsToWitnessMap,
@@ -125,23 +179,13 @@ export class BBNativeProofCreator implements ProofCreator {
125
179
  );
126
180
  }
127
181
 
128
- public async createAppCircuitProof(
129
- partialWitness: WitnessMap,
182
+ public async computeAppCircuitVerificationKey(
130
183
  bytecode: Buffer,
131
184
  appCircuitName?: string,
132
- ): Promise<AppCircuitProofOutput> {
185
+ ): Promise<AppCircuitSimulateOutput> {
133
186
  const operation = async (directory: string) => {
134
187
  this.log.debug(`Proving app circuit`);
135
- const proofOutput = await this.createProof(directory, partialWitness, bytecode, 'App', appCircuitName);
136
- if (proofOutput.proof.proof.length != RECURSIVE_PROOF_LENGTH) {
137
- throw new Error(`Incorrect proof length`);
138
- }
139
- const proof = proofOutput.proof as RecursiveProof<typeof RECURSIVE_PROOF_LENGTH>;
140
- const output: AppCircuitProofOutput = {
141
- proof,
142
- verificationKey: proofOutput.verificationKey,
143
- };
144
- return output;
188
+ return await this.computeVerificationKey(directory, bytecode, 'App', appCircuitName);
145
189
  };
146
190
 
147
191
  return await runInDirectory(this.bbWorkingDirectory, operation);
@@ -192,7 +236,7 @@ export class BBNativeProofCreator implements ProofCreator {
192
236
  * @param filePath - The directory containing the verification key data files
193
237
  * @param circuitType - The type of circuit to which the verification key corresponds
194
238
  */
195
- private async updateVerificationKeyAfterProof(filePath: string, circuitType: ClientProtocolArtifact) {
239
+ private async updateVerificationKeyAfterSimulation(filePath: string, circuitType: ClientProtocolArtifact) {
196
240
  let promise = this.verificationKeys.get(circuitType);
197
241
  if (!promise) {
198
242
  promise = extractVkData(filePath);
@@ -202,28 +246,12 @@ export class BBNativeProofCreator implements ProofCreator {
202
246
  return await promise;
203
247
  }
204
248
 
205
- private async createSafeProof<I extends { toBuffer: () => Buffer }, O extends { toBuffer: () => Buffer }>(
206
- inputs: I,
207
- circuitType: ClientProtocolArtifact,
208
- convertInputs: (inputs: I) => WitnessMap,
209
- convertOutputs: (outputs: WitnessMap) => O,
210
- ): Promise<KernelProofOutput<O>> {
211
- const operation = async (directory: string) => {
212
- return await this.generateWitnessAndCreateProof(inputs, circuitType, directory, convertInputs, convertOutputs);
213
- };
214
- return await runInDirectory(this.bbWorkingDirectory, operation);
215
- }
216
-
217
- private async generateWitnessAndCreateProof<
218
- I extends { toBuffer: () => Buffer },
219
- O extends { toBuffer: () => Buffer },
220
- >(
249
+ private async simulate<I extends { toBuffer: () => Buffer }, O extends { toBuffer: () => Buffer }>(
221
250
  inputs: I,
222
251
  circuitType: ClientProtocolArtifact,
223
- directory: string,
224
252
  convertInputs: (inputs: I) => WitnessMap,
225
253
  convertOutputs: (outputs: WitnessMap) => O,
226
- ): Promise<KernelProofOutput<O>> {
254
+ ): Promise<PrivateKernelSimulateOutput<O>> {
227
255
  this.log.debug(`Generating witness for ${circuitType}`);
228
256
  const compiledCircuit: NoirCompiledCircuit = ClientCircuitArtifacts[circuitType];
229
257
 
@@ -240,99 +268,69 @@ export class BBNativeProofCreator implements ProofCreator {
240
268
  outputSize: output.toBuffer().length,
241
269
  } satisfies CircuitWitnessGenerationStats);
242
270
 
243
- const proofOutput = await this.createProof(
244
- directory,
245
- outputWitness,
246
- Buffer.from(compiledCircuit.bytecode, 'base64'),
247
- circuitType,
271
+ // TODO(#7410) we dont need to generate vk's for these circuits, they are in the vk tree
272
+ const { verificationKey } = await runInDirectory(this.bbWorkingDirectory, dir =>
273
+ this.computeVerificationKey(dir, Buffer.from(compiledCircuit.bytecode, 'base64'), circuitType),
248
274
  );
249
- if (proofOutput.proof.proof.length != NESTED_RECURSIVE_PROOF_LENGTH) {
250
- throw new Error(`Incorrect proof length`);
251
- }
252
- const nestedProof = proofOutput.proof as RecursiveProof<typeof NESTED_RECURSIVE_PROOF_LENGTH>;
253
-
254
- const kernelOutput: KernelProofOutput<O> = {
275
+ const kernelOutput: PrivateKernelSimulateOutput<O> = {
255
276
  publicInputs: output,
256
- proof: nestedProof,
257
- verificationKey: proofOutput.verificationKey,
277
+ verificationKey,
278
+ outputWitness,
258
279
  };
259
280
  return kernelOutput;
260
281
  }
261
282
 
262
- private async createProof(
283
+ private async computeVerificationKey(
263
284
  directory: string,
264
- partialWitness: WitnessMap,
265
285
  bytecode: Buffer,
266
286
  circuitType: ClientProtocolArtifact | 'App',
267
287
  appCircuitName?: string,
268
288
  ): Promise<{
269
- proof: RecursiveProof<typeof RECURSIVE_PROOF_LENGTH> | RecursiveProof<typeof NESTED_RECURSIVE_PROOF_LENGTH>;
270
289
  verificationKey: VerificationKeyAsFields;
271
290
  }> {
272
- const compressedBincodedWitness = serializeWitness(partialWitness);
273
-
274
- const inputsWitnessFile = join(directory, 'witness.gz');
275
-
276
- await fs.writeFile(inputsWitnessFile, compressedBincodedWitness);
277
-
278
- this.log.debug(`Written ${inputsWitnessFile}`);
279
-
280
291
  const dbgCircuitName = appCircuitName ? `(${appCircuitName})` : '';
281
- this.log.info(`Proving ${circuitType}${dbgCircuitName} circuit...`);
292
+ this.log.info(`Computing VK of ${circuitType}${dbgCircuitName} circuit...`);
282
293
 
283
294
  const timer = new Timer();
284
295
 
285
- const provingResult = await generateProof(
286
- this.bbBinaryPath,
287
- directory,
288
- circuitType,
289
- bytecode,
290
- inputsWitnessFile,
291
- this.log.debug,
292
- );
296
+ const vkResult = await computeVerificationKey(this.bbBinaryPath, directory, circuitType, bytecode, this.log.debug);
293
297
 
294
- if (provingResult.status === BB_RESULT.FAILURE) {
295
- this.log.error(`Failed to generate proof for ${circuitType}${dbgCircuitName}: ${provingResult.reason}`);
296
- throw new Error(provingResult.reason);
298
+ if (vkResult.status === BB_RESULT.FAILURE) {
299
+ this.log.error(`Failed to generate proof for ${circuitType}${dbgCircuitName}: ${vkResult.reason}`);
300
+ throw new Error(vkResult.reason);
297
301
  }
298
302
 
299
- this.log.info(`Generated ${circuitType}${dbgCircuitName} circuit proof in ${Math.ceil(timer.ms())} ms`);
303
+ this.log.info(`Generated ${circuitType}${dbgCircuitName} VK in ${Math.ceil(timer.ms())} ms`);
300
304
 
301
305
  if (circuitType === 'App') {
302
306
  const vkData = await extractVkData(directory);
303
- const proof = await this.readProofAsFields<typeof RECURSIVE_PROOF_LENGTH>(directory, circuitType, vkData);
304
307
 
305
- this.log.debug(`Generated proof`, {
306
- eventName: 'circuit-proving',
308
+ this.log.debug(`Computed verification key`, {
307
309
  circuitName: 'app-circuit',
308
- duration: provingResult.durationMs,
309
- inputSize: compressedBincodedWitness.length,
310
- proofSize: proof.binaryProof.buffer.length,
311
- appCircuitName,
310
+ duration: vkResult.durationMs,
311
+ eventName: 'circuit-simulation',
312
+ inputSize: bytecode.length,
313
+ outputSize: vkData.keyAsBytes.length,
312
314
  circuitSize: vkData.circuitSize,
313
315
  numPublicInputs: vkData.numPublicInputs,
314
- } as CircuitProvingStats);
316
+ } as CircuitSimulationStats);
315
317
 
316
- return { proof, verificationKey: vkData.keyAsFields };
318
+ return { verificationKey: vkData.keyAsFields };
317
319
  }
318
320
 
319
- const vkData = await this.updateVerificationKeyAfterProof(directory, circuitType);
320
-
321
- const proof = await this.readProofAsFields<typeof NESTED_RECURSIVE_PROOF_LENGTH>(directory, circuitType, vkData);
321
+ const vkData = await this.updateVerificationKeyAfterSimulation(directory, circuitType);
322
322
 
323
- await this.verifyProofForProtocolCircuit(circuitType, proof.binaryProof);
324
-
325
- this.log.debug(`Generated proof`, {
323
+ this.log.debug(`Computed verification key`, {
326
324
  circuitName: mapProtocolArtifactNameToCircuitName(circuitType),
327
- duration: provingResult.durationMs,
328
- eventName: 'circuit-proving',
329
- inputSize: compressedBincodedWitness.length,
330
- proofSize: proof.binaryProof.buffer.length,
325
+ duration: vkResult.durationMs,
326
+ eventName: 'circuit-simulation',
327
+ inputSize: bytecode.length,
328
+ outputSize: vkData.keyAsBytes.length,
331
329
  circuitSize: vkData.circuitSize,
332
330
  numPublicInputs: vkData.numPublicInputs,
333
- } as CircuitProvingStats);
331
+ } as CircuitSimulationStats);
334
332
 
335
- return { proof, verificationKey: vkData.keyAsFields };
333
+ return { verificationKey: vkData.keyAsFields };
336
334
  }
337
335
 
338
336
  /**
@@ -352,10 +350,12 @@ export class BBNativeProofCreator implements ProofCreator {
352
350
  ]);
353
351
  const json = JSON.parse(proofString);
354
352
  const fields = json.map(Fr.fromString);
355
- const numPublicInputs =
356
- circuitType === 'App' ? vkData.numPublicInputs : vkData.numPublicInputs - AGGREGATION_OBJECT_LENGTH;
353
+ const numPublicInputs = vkData.numPublicInputs;
354
+ // const numPublicInputs =
355
+ // TODO(https://github.com/AztecProtocol/barretenberg/issues/1044): Reinstate aggregation
356
+ // circuitType === 'App' ? vkData.numPublicInputs : vkData.numPublicInputs - AGGREGATION_OBJECT_LENGTH;
357
357
  const fieldsWithoutPublicInputs = fields.slice(numPublicInputs);
358
- this.log.debug(
358
+ this.log.info(
359
359
  `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}`,
360
360
  );
361
361
  const proof = new RecursiveProof<PROOF_LENGTH>(