@aztec/bb-prover 0.60.0 → 0.62.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.
@@ -9,10 +9,10 @@ import {
9
9
  import { type CircuitProvingStats, type CircuitWitnessGenerationStats } from '@aztec/circuit-types/stats';
10
10
  import {
11
11
  AGGREGATION_OBJECT_LENGTH,
12
+ AVM_PROOF_LENGTH_IN_FIELDS,
12
13
  type AvmCircuitInputs,
13
14
  type BaseOrMergeRollupPublicInputs,
14
15
  type BaseParityInputs,
15
- type BaseRollupInputs,
16
16
  type BlockMergeRollupInputs,
17
17
  type BlockRootOrBlockMergePublicInputs,
18
18
  type BlockRootRollupInputs,
@@ -23,13 +23,11 @@ import {
23
23
  type KernelCircuitPublicInputs,
24
24
  type MergeRollupInputs,
25
25
  NESTED_RECURSIVE_PROOF_LENGTH,
26
+ type PrivateBaseRollupInputs,
26
27
  type PrivateKernelEmptyInputData,
27
28
  PrivateKernelEmptyInputs,
28
29
  Proof,
29
- type PublicKernelCircuitPrivateInputs,
30
- type PublicKernelCircuitPublicInputs,
31
- type PublicKernelInnerCircuitPrivateInputs,
32
- type PublicKernelTailCircuitPrivateInputs,
30
+ type PublicBaseRollupInputs,
33
31
  RECURSIVE_PROOF_LENGTH,
34
32
  RecursiveProof,
35
33
  RootParityInput,
@@ -38,13 +36,13 @@ import {
38
36
  type RootRollupPublicInputs,
39
37
  TUBE_PROOF_LENGTH,
40
38
  type TubeInputs,
41
- type VMCircuitPublicInputs,
42
39
  type VerificationKeyAsFields,
43
40
  type VerificationKeyData,
44
41
  makeRecursiveProofFromBinary,
45
42
  } from '@aztec/circuits.js';
46
43
  import { runInDirectory } from '@aztec/foundation/fs';
47
44
  import { createDebugLogger } from '@aztec/foundation/log';
45
+ import { BufferReader } from '@aztec/foundation/serialize';
48
46
  import { Timer } from '@aztec/foundation/timer';
49
47
  import {
50
48
  ProtocolCircuitVkIndexes,
@@ -53,8 +51,6 @@ import {
53
51
  type ServerProtocolArtifact,
54
52
  convertBaseParityInputsToWitnessMap,
55
53
  convertBaseParityOutputsFromWitnessMap,
56
- convertBaseRollupInputsToWitnessMap,
57
- convertBaseRollupOutputsFromWitnessMap,
58
54
  convertBlockMergeRollupInputsToWitnessMap,
59
55
  convertBlockMergeRollupOutputsFromWitnessMap,
60
56
  convertBlockRootRollupInputsToWitnessMap,
@@ -63,14 +59,12 @@ import {
63
59
  convertEmptyBlockRootRollupOutputsFromWitnessMap,
64
60
  convertMergeRollupInputsToWitnessMap,
65
61
  convertMergeRollupOutputsFromWitnessMap,
62
+ convertPrivateBaseRollupInputsToWitnessMap,
63
+ convertPrivateBaseRollupOutputsFromWitnessMap,
66
64
  convertPrivateKernelEmptyInputsToWitnessMap,
67
65
  convertPrivateKernelEmptyOutputsFromWitnessMap,
68
- convertPublicInnerInputsToWitnessMap,
69
- convertPublicInnerOutputFromWitnessMap,
70
- convertPublicMergeInputsToWitnessMap,
71
- convertPublicMergeOutputFromWitnessMap,
72
- convertPublicTailInputsToWitnessMap,
73
- convertPublicTailOutputFromWitnessMap,
66
+ convertPublicBaseRollupInputsToWitnessMap,
67
+ convertPublicBaseRollupOutputsFromWitnessMap,
74
68
  convertRootParityInputsToWitnessMap,
75
69
  convertRootParityOutputsFromWitnessMap,
76
70
  convertRootRollupInputsToWitnessMap,
@@ -208,77 +202,35 @@ export class BBNativeRollupProver implements ServerCircuitProver {
208
202
  @trackSpan('BBNativeRollupProver.getAvmProof', inputs => ({
209
203
  [Attributes.APP_CIRCUIT_NAME]: inputs.functionName,
210
204
  }))
211
- public async getAvmProof(inputs: AvmCircuitInputs): Promise<ProofAndVerificationKey<Proof>> {
205
+ public async getAvmProof(
206
+ inputs: AvmCircuitInputs,
207
+ ): Promise<ProofAndVerificationKey<RecursiveProof<typeof AVM_PROOF_LENGTH_IN_FIELDS>>> {
212
208
  const proofAndVk = await this.createAvmProof(inputs);
213
- await this.verifyAvmProof(proofAndVk.proof, proofAndVk.verificationKey);
209
+ await this.verifyAvmProof(proofAndVk.proof.binaryProof, proofAndVk.verificationKey);
214
210
  return proofAndVk;
215
211
  }
216
212
 
217
213
  /**
218
- * Requests that a public kernel inner circuit be executed and the proof generated
219
- * @param kernelRequest - The object encapsulating the request for a proof
220
- * @returns The requested circuit's public inputs and proof
221
- */
222
- @trackSpan('BBNativeRollupProver.getPublicKernelInnerProof', {
223
- [Attributes.PROTOCOL_CIRCUIT_NAME]: 'public-kernel-inner',
224
- })
225
- public async getPublicKernelInnerProof(
226
- inputs: PublicKernelInnerCircuitPrivateInputs,
227
- ): Promise<PublicInputsAndRecursiveProof<VMCircuitPublicInputs>> {
228
- const artifact = 'PublicKernelInnerArtifact';
229
-
230
- const { circuitOutput, proof } = await this.createRecursiveProof(
231
- inputs,
232
- artifact,
233
- NESTED_RECURSIVE_PROOF_LENGTH,
234
- convertPublicInnerInputsToWitnessMap,
235
- convertPublicInnerOutputFromWitnessMap,
236
- );
237
-
238
- const verificationKey = await this.getVerificationKeyDataForCircuit(artifact);
239
-
240
- await this.verifyProof(artifact, proof.binaryProof);
241
-
242
- return makePublicInputsAndRecursiveProof(circuitOutput, proof, verificationKey);
243
- }
244
-
245
- /**
246
- * Requests that a public kernel merge circuit be executed and the proof generated
247
- * @param kernelRequest - The object encapsulating the request for a proof
248
- * @returns The requested circuit's public inputs and proof
214
+ * Simulates the base rollup circuit from its inputs.
215
+ * @param inputs - Inputs to the circuit.
216
+ * @returns The public inputs as outputs of the simulation.
249
217
  */
250
- @trackSpan('BBNativeRollupProver.getPublicKernelMergeProof', {
251
- [Attributes.PROTOCOL_CIRCUIT_NAME]: 'public-kernel-merge',
252
- })
253
- public async getPublicKernelMergeProof(
254
- inputs: PublicKernelCircuitPrivateInputs,
255
- ): Promise<PublicInputsAndRecursiveProof<PublicKernelCircuitPublicInputs>> {
256
- const artifact = 'PublicKernelMergeArtifact';
257
-
258
- // We may need to convert the recursive proof into fields format
259
- inputs.previousKernel.proof = await this.ensureValidProof(
260
- inputs.previousKernel.proof,
261
- artifact,
262
- inputs.previousKernel.vk,
263
- );
264
-
265
- await this.verifyWithKey(
266
- getUltraHonkFlavorForCircuit(artifact),
267
- inputs.previousKernel.vk,
268
- inputs.previousKernel.proof.binaryProof,
269
- );
218
+ public async getPrivateBaseRollupProof(
219
+ inputs: PrivateBaseRollupInputs,
220
+ ): Promise<PublicInputsAndRecursiveProof<BaseOrMergeRollupPublicInputs>> {
221
+ const artifactName = 'PrivateBaseRollupArtifact';
270
222
 
271
223
  const { circuitOutput, proof } = await this.createRecursiveProof(
272
224
  inputs,
273
- artifact,
225
+ artifactName,
274
226
  NESTED_RECURSIVE_PROOF_LENGTH,
275
- convertPublicMergeInputsToWitnessMap,
276
- convertPublicMergeOutputFromWitnessMap,
227
+ convertPrivateBaseRollupInputsToWitnessMap,
228
+ convertPrivateBaseRollupOutputsFromWitnessMap,
277
229
  );
278
230
 
279
- const verificationKey = await this.getVerificationKeyDataForCircuit(artifact);
231
+ const verificationKey = await this.getVerificationKeyDataForCircuit(artifactName);
280
232
 
281
- await this.verifyProof(artifact, proof.binaryProof);
233
+ await this.verifyProof(artifactName, proof.binaryProof);
282
234
 
283
235
  return makePublicInputsAndRecursiveProof(circuitOutput, proof, verificationKey);
284
236
  }
@@ -288,52 +240,22 @@ export class BBNativeRollupProver implements ServerCircuitProver {
288
240
  * @param kernelRequest - The object encapsulating the request for a proof
289
241
  * @returns The requested circuit's public inputs and proof
290
242
  */
291
- public async getPublicTailProof(
292
- inputs: PublicKernelTailCircuitPrivateInputs,
293
- ): Promise<PublicInputsAndRecursiveProof<KernelCircuitPublicInputs>> {
294
- const { circuitOutput, proof } = await this.createRecursiveProof(
295
- inputs,
296
- 'PublicKernelTailArtifact',
297
- NESTED_RECURSIVE_PROOF_LENGTH,
298
- convertPublicTailInputsToWitnessMap,
299
- convertPublicTailOutputFromWitnessMap,
300
- );
301
-
302
- const verificationKey = await this.getVerificationKeyDataForCircuit('PublicKernelTailArtifact');
303
-
304
- await this.verifyProof('PublicKernelTailArtifact', proof.binaryProof);
305
-
306
- return makePublicInputsAndRecursiveProof(circuitOutput, proof, verificationKey);
307
- }
308
-
309
- /**
310
- * Simulates the base rollup circuit from its inputs.
311
- * @param baseRollupInput - Inputs to the circuit.
312
- * @returns The public inputs as outputs of the simulation.
313
- */
314
- public async getBaseRollupProof(
315
- baseRollupInput: BaseRollupInputs, // TODO: remove tail proof from here
243
+ public async getPublicBaseRollupProof(
244
+ inputs: PublicBaseRollupInputs,
316
245
  ): Promise<PublicInputsAndRecursiveProof<BaseOrMergeRollupPublicInputs>> {
317
- // We may need to convert the recursive proof into fields format
318
- logger.debug(`kernel Data proof: ${baseRollupInput.kernelData.proof}`);
319
- logger.debug(`Number of public inputs in baseRollupInput: ${baseRollupInput.kernelData.vk.numPublicInputs}`);
320
- baseRollupInput.kernelData.proof = await this.ensureValidProof(
321
- baseRollupInput.kernelData.proof,
322
- 'BaseRollupArtifact',
323
- baseRollupInput.kernelData.vk,
324
- );
246
+ const artifactName = 'PublicBaseRollupArtifact';
325
247
 
326
248
  const { circuitOutput, proof } = await this.createRecursiveProof(
327
- baseRollupInput, // BaseRollupInputs
328
- 'BaseRollupArtifact',
329
- NESTED_RECURSIVE_PROOF_LENGTH, // WORKTODO: this should be BASE_ROLLUP_PROOF_LENGTH or something like this
330
- convertBaseRollupInputsToWitnessMap,
331
- convertBaseRollupOutputsFromWitnessMap,
249
+ inputs,
250
+ artifactName,
251
+ NESTED_RECURSIVE_PROOF_LENGTH,
252
+ convertPublicBaseRollupInputsToWitnessMap,
253
+ convertPublicBaseRollupOutputsFromWitnessMap,
332
254
  );
333
255
 
334
- const verificationKey = await this.getVerificationKeyDataForCircuit('BaseRollupArtifact');
256
+ const verificationKey = await this.getVerificationKeyDataForCircuit(artifactName);
335
257
 
336
- await this.verifyProof('BaseRollupArtifact', proof.binaryProof);
258
+ await this.verifyProof(artifactName, proof.binaryProof);
337
259
 
338
260
  return makePublicInputsAndRecursiveProof(circuitOutput, proof, verificationKey);
339
261
  }
@@ -677,20 +599,21 @@ export class BBNativeRollupProver implements ServerCircuitProver {
677
599
  return provingResult;
678
600
  }
679
601
 
680
- private async createAvmProof(input: AvmCircuitInputs): Promise<ProofAndVerificationKey<Proof>> {
681
- const operation = async (bbWorkingDirectory: string): Promise<ProofAndVerificationKey<Proof>> => {
602
+ private async createAvmProof(
603
+ input: AvmCircuitInputs,
604
+ ): Promise<ProofAndVerificationKey<RecursiveProof<typeof AVM_PROOF_LENGTH_IN_FIELDS>>> {
605
+ const operation = async (bbWorkingDirectory: string) => {
682
606
  const provingResult = await this.generateAvmProofWithBB(input, bbWorkingDirectory);
683
607
 
684
- const rawProof = await fs.readFile(provingResult.proofPath!);
685
608
  // TODO(https://github.com/AztecProtocol/aztec-packages/issues/6773): this VK data format is wrong.
686
609
  // In particular, the number of public inputs, etc will be wrong.
687
610
  const verificationKey = await extractAvmVkData(provingResult.vkPath!);
688
- const proof = new Proof(rawProof, verificationKey.numPublicInputs);
611
+ const avmProof = await this.readAvmProofAsFields(provingResult.proofPath!, verificationKey);
689
612
 
690
613
  const circuitType = 'avm-circuit' as const;
691
614
  const appCircuitName = 'unknown' as const;
692
615
  this.instrumentation.recordAvmDuration('provingDuration', appCircuitName, provingResult.durationMs);
693
- this.instrumentation.recordAvmSize('proofSize', appCircuitName, proof.buffer.length);
616
+ this.instrumentation.recordAvmSize('proofSize', appCircuitName, avmProof.binaryProof.buffer.length);
694
617
  this.instrumentation.recordAvmSize('circuitPublicInputCount', appCircuitName, verificationKey.numPublicInputs);
695
618
  this.instrumentation.recordAvmSize('circuitSize', appCircuitName, verificationKey.circuitSize);
696
619
 
@@ -701,7 +624,7 @@ export class BBNativeRollupProver implements ServerCircuitProver {
701
624
  appCircuitName: input.functionName,
702
625
  // does not include reading the proof from disk
703
626
  duration: provingResult.durationMs,
704
- proofSize: proof.buffer.length,
627
+ proofSize: avmProof.binaryProof.buffer.length,
705
628
  eventName: 'circuit-proving',
706
629
  inputSize: input.toBuffer().length,
707
630
  circuitSize: verificationKey.circuitSize, // FIX: wrong in VK
@@ -709,7 +632,7 @@ export class BBNativeRollupProver implements ServerCircuitProver {
709
632
  } satisfies CircuitProvingStats,
710
633
  );
711
634
 
712
- return makeProofAndVerificationKey(proof, verificationKey);
635
+ return makeProofAndVerificationKey(avmProof, verificationKey);
713
636
  };
714
637
  return await this.runInDirectory(operation);
715
638
  }
@@ -724,7 +647,7 @@ export class BBNativeRollupProver implements ServerCircuitProver {
724
647
 
725
648
  // Read the proof as fields
726
649
  const tubeVK = await extractVkData(provingResult.vkPath!);
727
- const tubeProof = await this.readTubeProofAsFields(provingResult.proofPath!, tubeVK, TUBE_PROOF_LENGTH);
650
+ const tubeProof = await this.readProofAsFields(provingResult.proofPath!, tubeVK, TUBE_PROOF_LENGTH);
728
651
 
729
652
  this.instrumentation.recordDuration('provingDuration', 'tubeCircuit', provingResult.durationMs);
730
653
  this.instrumentation.recordSize('proofSize', 'tubeCircuit', tubeProof.binaryProof.buffer.length);
@@ -774,7 +697,7 @@ export class BBNativeRollupProver implements ServerCircuitProver {
774
697
  } = await this.generateProofWithBB(input, circuitType, convertInput, convertOutput, bbWorkingDirectory);
775
698
 
776
699
  // Read the proof as fields
777
- const proof = await this.readProofAsFields(provingResult.proofPath!, circuitType, proofLength);
700
+ const proof = await this.readProofAsFields(provingResult.proofPath!, vkData, proofLength);
778
701
 
779
702
  const circuitName = mapProtocolArtifactNameToCircuitName(circuitType);
780
703
  this.instrumentation.recordDuration('provingDuration', circuitName, provingResult.durationMs);
@@ -914,10 +837,11 @@ export class BBNativeRollupProver implements ServerCircuitProver {
914
837
  .slice(0, 3)
915
838
  .map(Fr.fromString)
916
839
  .concat(json.slice(3 + numPublicInputs).map(Fr.fromString));
917
- return new RecursiveProof<typeof NESTED_RECURSIVE_PROOF_LENGTH>(
840
+ return new RecursiveProof(
918
841
  fields,
919
842
  new Proof(proof.binaryProof.buffer, vk.numPublicInputs),
920
843
  true,
844
+ NESTED_RECURSIVE_PROOF_LENGTH,
921
845
  );
922
846
  };
923
847
  return await this.runInDirectory(operation);
@@ -969,15 +893,9 @@ export class BBNativeRollupProver implements ServerCircuitProver {
969
893
  return promise;
970
894
  }
971
895
 
972
- /**
973
- * Parses and returns the proof data stored at the specified directory
974
- * @param filePath - The directory containing the proof data
975
- * @param circuitType - The type of circuit proven
976
- * @returns The proof
977
- */
978
896
  private async readProofAsFields<PROOF_LENGTH extends number>(
979
897
  filePath: string,
980
- circuitType: ServerProtocolArtifact,
898
+ vkData: VerificationKeyData,
981
899
  proofLength: PROOF_LENGTH,
982
900
  ): Promise<RecursiveProof<PROOF_LENGTH>> {
983
901
  const proofFilename = path.join(filePath, PROOF_FILENAME);
@@ -987,67 +905,35 @@ export class BBNativeRollupProver implements ServerCircuitProver {
987
905
  fs.readFile(proofFilename),
988
906
  fs.readFile(proofFieldsFilename, { encoding: 'utf-8' }),
989
907
  ]);
908
+
990
909
  const json = JSON.parse(proofString);
991
- const vkData = await this.getVerificationKeyDataForCircuit(circuitType);
910
+
992
911
  const numPublicInputs = vkData.numPublicInputs - AGGREGATION_OBJECT_LENGTH;
912
+
993
913
  const fieldsWithoutPublicInputs = json
994
914
  .slice(0, 3)
995
915
  .map(Fr.fromString)
996
916
  .concat(json.slice(3 + numPublicInputs).map(Fr.fromString));
997
- logger.debug(`num pub inputs ${vkData.numPublicInputs} circuit=${circuitType}`);
998
-
999
- const proof = new RecursiveProof<PROOF_LENGTH>(
1000
- fieldsWithoutPublicInputs,
1001
- new Proof(binaryProof, numPublicInputs),
1002
- true,
917
+ logger.debug(
918
+ `Circuit path: ${filePath}, complete proof length: ${json.length}, num public inputs: ${numPublicInputs}, circuit size: ${vkData.circuitSize}, is recursive: ${vkData.isRecursive}, raw length: ${binaryProof.length}`,
1003
919
  );
1004
- if (proof.proof.length !== proofLength) {
1005
- throw new Error(`Proof length doesn't match expected length (${proof.proof.length} != ${proofLength})`);
1006
- }
1007
920
 
1008
- return proof;
921
+ return new RecursiveProof(fieldsWithoutPublicInputs, new Proof(binaryProof, numPublicInputs), true, proofLength);
1009
922
  }
1010
923
 
1011
- /**
1012
- * Parses and returns a tube proof stored in the specified directory. TODO merge wih above
1013
- * @param filePath - The directory containing the proof data
1014
- * @param circuitType - The type of circuit proven
1015
- * @returns The proof
1016
- * TODO(#7369) This is entirely redundant now with the above method, deduplicate
1017
- */
1018
- private async readTubeProofAsFields<PROOF_LENGTH extends number>(
1019
- filePath: string,
924
+ private async readAvmProofAsFields(
925
+ proofFilename: string,
1020
926
  vkData: VerificationKeyData,
1021
- proofLength: PROOF_LENGTH,
1022
- ): Promise<RecursiveProof<PROOF_LENGTH>> {
1023
- const proofFilename = path.join(filePath, PROOF_FILENAME);
1024
- const proofFieldsFilename = path.join(filePath, PROOF_FIELDS_FILENAME);
1025
-
1026
- const [binaryProof, proofString] = await Promise.all([
1027
- fs.readFile(proofFilename),
1028
- fs.readFile(proofFieldsFilename, { encoding: 'utf-8' }),
1029
- ]);
927
+ ): Promise<RecursiveProof<typeof AVM_PROOF_LENGTH_IN_FIELDS>> {
928
+ const rawProof = await fs.readFile(proofFilename);
1030
929
 
1031
- const json = JSON.parse(proofString);
930
+ const reader = BufferReader.asReader(rawProof);
931
+ const fields = reader.readArray(rawProof.length / Fr.SIZE_IN_BYTES, Fr);
932
+ const fieldsWithoutPublicCols = fields.slice(-1 * AVM_PROOF_LENGTH_IN_FIELDS);
1032
933
 
1033
- const numPublicInputs = vkData.numPublicInputs - AGGREGATION_OBJECT_LENGTH;
1034
- if (numPublicInputs === 0) {
1035
- throw new Error(`Tube proof should have public inputs (e.g. the number of public inputs from PrivateKernelTail)`);
1036
- }
1037
-
1038
- const proofFields = json
1039
- .slice(0, 3)
1040
- .map(Fr.fromString)
1041
- .concat(json.slice(3 + numPublicInputs).map(Fr.fromString));
1042
- logger.debug(
1043
- `Circuit type: tube circuit, complete proof length: ${json.length}, num public inputs: ${numPublicInputs}, circuit size: ${vkData.circuitSize}, is recursive: ${vkData.isRecursive}, raw length: ${binaryProof.length}`,
1044
- );
1045
- const proof = new RecursiveProof<PROOF_LENGTH>(proofFields, new Proof(binaryProof, numPublicInputs), true);
1046
- if (proof.proof.length !== proofLength) {
1047
- throw new Error(`Proof length doesn't match expected length (${proof.proof.length} != ${proofLength})`);
1048
- }
934
+ const proof = new Proof(rawProof, vkData.numPublicInputs);
1049
935
 
1050
- return proof;
936
+ return new RecursiveProof(fieldsWithoutPublicCols, proof, true, AVM_PROOF_LENGTH_IN_FIELDS);
1051
937
  }
1052
938
 
1053
939
  private runInDirectory<T>(fn: (dir: string) => Promise<T>) {
package/src/stats.ts CHANGED
@@ -9,8 +9,10 @@ export function mapProtocolArtifactNameToCircuitName(
9
9
  return 'base-parity';
10
10
  case 'RootParityArtifact':
11
11
  return 'root-parity';
12
- case 'BaseRollupArtifact':
13
- return 'base-rollup';
12
+ case 'PrivateBaseRollupArtifact':
13
+ return 'private-base-rollup';
14
+ case 'PublicBaseRollupArtifact':
15
+ return 'public-base-rollup';
14
16
  case 'MergeRollupArtifact':
15
17
  return 'merge-rollup';
16
18
  case 'BlockRootRollupArtifact':
@@ -21,12 +23,6 @@ export function mapProtocolArtifactNameToCircuitName(
21
23
  return 'block-merge-rollup';
22
24
  case 'RootRollupArtifact':
23
25
  return 'root-rollup';
24
- case 'PublicKernelInnerArtifact':
25
- return 'public-kernel-inner';
26
- case 'PublicKernelMergeArtifact':
27
- return 'public-kernel-merge';
28
- case 'PublicKernelTailArtifact':
29
- return 'public-kernel-tail';
30
26
  case 'PrivateKernelInitArtifact':
31
27
  return 'private-kernel-init';
32
28
  case 'PrivateKernelInnerArtifact':