@aztec/bb-prover 0.0.1-commit.d431d1c → 0.0.1-commit.d58ff9d0

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 (68) hide show
  1. package/dest/avm_proving_tests/avm_proving_tester.d.ts +16 -10
  2. package/dest/avm_proving_tests/avm_proving_tester.d.ts.map +1 -1
  3. package/dest/avm_proving_tests/avm_proving_tester.js +178 -111
  4. package/dest/bb/bb_js_backend.d.ts +196 -0
  5. package/dest/bb/bb_js_backend.d.ts.map +1 -0
  6. package/dest/bb/bb_js_backend.js +379 -0
  7. package/dest/bb/bb_js_debug.d.ts +52 -0
  8. package/dest/bb/bb_js_debug.d.ts.map +1 -0
  9. package/dest/bb/bb_js_debug.js +176 -0
  10. package/dest/bb/file_names.d.ts +4 -0
  11. package/dest/bb/file_names.d.ts.map +1 -0
  12. package/dest/bb/file_names.js +5 -0
  13. package/dest/config.d.ts +17 -1
  14. package/dest/config.d.ts.map +1 -1
  15. package/dest/index.d.ts +3 -2
  16. package/dest/index.d.ts.map +1 -1
  17. package/dest/index.js +2 -1
  18. package/dest/instrumentation.d.ts +1 -1
  19. package/dest/instrumentation.d.ts.map +1 -1
  20. package/dest/instrumentation.js +12 -4
  21. package/dest/prover/client/bb_private_kernel_prover.d.ts +21 -5
  22. package/dest/prover/client/bb_private_kernel_prover.d.ts.map +1 -1
  23. package/dest/prover/client/bb_private_kernel_prover.js +79 -15
  24. package/dest/prover/proof_utils.d.ts +11 -1
  25. package/dest/prover/proof_utils.d.ts.map +1 -1
  26. package/dest/prover/proof_utils.js +24 -1
  27. package/dest/prover/server/bb_prover.d.ts +6 -7
  28. package/dest/prover/server/bb_prover.d.ts.map +1 -1
  29. package/dest/prover/server/bb_prover.js +207 -80
  30. package/dest/test/delay_values.js +1 -1
  31. package/dest/test/test_circuit_prover.d.ts +3 -3
  32. package/dest/test/test_circuit_prover.d.ts.map +1 -1
  33. package/dest/test/test_circuit_prover.js +2 -2
  34. package/dest/verification_key/verification_key_data.js +1 -1
  35. package/dest/verifier/batch_chonk_verifier.d.ts +56 -0
  36. package/dest/verifier/batch_chonk_verifier.d.ts.map +1 -0
  37. package/dest/verifier/batch_chonk_verifier.js +384 -0
  38. package/dest/verifier/bb_verifier.d.ts +4 -1
  39. package/dest/verifier/bb_verifier.d.ts.map +1 -1
  40. package/dest/verifier/bb_verifier.js +134 -45
  41. package/dest/verifier/index.d.ts +2 -1
  42. package/dest/verifier/index.d.ts.map +1 -1
  43. package/dest/verifier/index.js +1 -0
  44. package/dest/verifier/queued_chonk_verifier.d.ts +2 -3
  45. package/dest/verifier/queued_chonk_verifier.d.ts.map +1 -1
  46. package/dest/verifier/queued_chonk_verifier.js +8 -7
  47. package/package.json +19 -17
  48. package/src/avm_proving_tests/avm_proving_tester.ts +85 -126
  49. package/src/bb/bb_js_backend.ts +435 -0
  50. package/src/bb/bb_js_debug.ts +227 -0
  51. package/src/bb/file_names.ts +6 -0
  52. package/src/config.ts +16 -0
  53. package/src/index.ts +2 -1
  54. package/src/instrumentation.ts +12 -4
  55. package/src/prover/client/bb_private_kernel_prover.ts +242 -21
  56. package/src/prover/proof_utils.ts +41 -1
  57. package/src/prover/server/bb_prover.ts +127 -141
  58. package/src/test/delay_values.ts +1 -1
  59. package/src/test/test_circuit_prover.ts +3 -5
  60. package/src/verification_key/verification_key_data.ts +1 -1
  61. package/src/verifier/batch_chonk_verifier.ts +415 -0
  62. package/src/verifier/bb_verifier.ts +66 -76
  63. package/src/verifier/index.ts +1 -0
  64. package/src/verifier/queued_chonk_verifier.ts +8 -8
  65. package/dest/bb/execute.d.ts +0 -107
  66. package/dest/bb/execute.d.ts.map +0 -1
  67. package/dest/bb/execute.js +0 -647
  68. package/src/bb/execute.ts +0 -678
@@ -1,5 +1,5 @@
1
1
  import {
2
- AVM_V2_PROOF_LENGTH_IN_FIELDS_PADDED,
2
+ AVM_V2_PROOF_LENGTH_IN_FIELDS,
3
3
  NESTED_RECURSIVE_PROOF_LENGTH,
4
4
  NESTED_RECURSIVE_ROLLUP_HONK_PROOF_LENGTH,
5
5
  PAIRING_POINTS_SIZE,
@@ -9,7 +9,6 @@ import {
9
9
  import { Fr } from '@aztec/foundation/curves/bn254';
10
10
  import { runInDirectory } from '@aztec/foundation/fs';
11
11
  import { createLogger } from '@aztec/foundation/log';
12
- import { BufferReader } from '@aztec/foundation/serialize';
13
12
  import {
14
13
  type ServerProtocolArtifact,
15
14
  convertBlockMergeRollupOutputsFromWitnessMap,
@@ -88,24 +87,14 @@ import { VerificationKeyData } from '@aztec/stdlib/vks';
88
87
  import { Attributes, type TelemetryClient, getTelemetryClient, trackSpan } from '@aztec/telemetry-client';
89
88
 
90
89
  import { promises as fs } from 'fs';
90
+ import { ungzip } from 'pako';
91
91
  import * as path from 'path';
92
92
 
93
- import {
94
- type BBFailure,
95
- type BBSuccess,
96
- BB_RESULT,
97
- PROOF_FILENAME,
98
- PUBLIC_INPUTS_FILENAME,
99
- VK_FILENAME,
100
- generateAvmProof,
101
- generateProof,
102
- verifyAvmProof,
103
- verifyProof,
104
- } from '../../bb/execute.js';
93
+ import { BBJsFactory, type BBJsProofResult } from '../../bb/bb_js_backend.js';
105
94
  import type { ACVMConfig, BBConfig } from '../../config.js';
106
95
  import { getUltraHonkFlavorForCircuit } from '../../honk.js';
107
96
  import { ProverInstrumentation } from '../../instrumentation.js';
108
- import { readProofsFromOutputDirectory } from '../proof_utils.js';
97
+ import { constructRecursiveProofFromBuffers } from '../proof_utils.js';
109
98
 
110
99
  const logger = createLogger('bb-prover');
111
100
 
@@ -119,12 +108,14 @@ export interface BBProverConfig extends BBConfig, ACVMConfig {
119
108
  */
120
109
  export class BBNativeRollupProver implements ServerCircuitProver {
121
110
  private instrumentation: ProverInstrumentation;
111
+ private bbJsFactory: BBJsFactory;
122
112
 
123
113
  constructor(
124
114
  private config: BBProverConfig,
125
115
  telemetry: TelemetryClient,
126
116
  ) {
127
117
  this.instrumentation = new ProverInstrumentation(telemetry, 'BBNativeRollupProver');
118
+ this.bbJsFactory = new BBJsFactory(config.bbBinaryPath, { logger, debugDir: config.bbDebugOutputDir });
128
119
  }
129
120
 
130
121
  get tracer() {
@@ -136,7 +127,7 @@ export class BBNativeRollupProver implements ServerCircuitProver {
136
127
  await fs.mkdir(config.acvmWorkingDirectory, { recursive: true });
137
128
  await fs.access(config.bbBinaryPath, fs.constants.R_OK);
138
129
  await fs.mkdir(config.bbWorkingDirectory, { recursive: true });
139
- logger.info(`Using native BB at ${config.bbBinaryPath} and working directory ${config.bbWorkingDirectory}`);
130
+ logger.info(`Using bb.js API with binary at ${config.bbBinaryPath}`);
140
131
  logger.info(`Using native ACVM at ${config.acvmBinaryPath} and working directory ${config.acvmWorkingDirectory}`);
141
132
 
142
133
  return new BBNativeRollupProver(config, telemetry);
@@ -186,9 +177,7 @@ export class BBNativeRollupProver implements ServerCircuitProver {
186
177
  @trackSpan('BBNativeRollupProver.getAvmProof', inputs => ({
187
178
  [Attributes.APP_CIRCUIT_NAME]: inputs.hints.tx.hash,
188
179
  }))
189
- public async getAvmProof(
190
- inputs: AvmCircuitInputs,
191
- ): Promise<RecursiveProof<typeof AVM_V2_PROOF_LENGTH_IN_FIELDS_PADDED>> {
180
+ public async getAvmProof(inputs: AvmCircuitInputs): Promise<RecursiveProof<typeof AVM_V2_PROOF_LENGTH_IN_FIELDS>> {
192
181
  const proof = await this.createAvmProof(inputs);
193
182
  await this.verifyAvmProof(proof.binaryProof, inputs.publicInputs);
194
183
  return proof;
@@ -453,16 +442,16 @@ export class BBNativeRollupProver implements ServerCircuitProver {
453
442
  convertInput: (input: Input) => WitnessMap,
454
443
  convertOutput: (outputWitness: WitnessMap) => Output,
455
444
  workingDirectory: string,
456
- ): Promise<{ circuitOutput: Output; provingResult: BBSuccess }> {
457
- // Have the ACVM write the partial witness here
445
+ ): Promise<{ circuitOutput: Output; proofResult: BBJsProofResult }> {
446
+ // Have the ACVM write the partial witness here (still needs a temp directory)
458
447
  const outputWitnessFile = path.join(workingDirectory, 'partial-witness.gz');
459
448
 
460
449
  // Generate the partial witness using the ACVM
461
- // A further temp directory will be created beneath ours and then cleaned up after the partial witness has been copied to our specified location
462
450
  const simulator = new NativeACVMSimulator(
463
451
  this.config.acvmWorkingDirectory,
464
452
  this.config.acvmBinaryPath,
465
453
  outputWitnessFile,
454
+ logger,
466
455
  );
467
456
 
468
457
  const artifact = getServerCircuitArtifact(circuitType);
@@ -470,7 +459,7 @@ export class BBNativeRollupProver implements ServerCircuitProver {
470
459
  logger.debug(`Generating witness data for ${circuitType}`);
471
460
 
472
461
  const inputWitness = convertInput(input);
473
- const foreignCallHandler = undefined; // We don't handle foreign calls in the native ACVM simulator
462
+ const foreignCallHandler = undefined;
474
463
  const witnessResult = await simulator.executeProtocolCircuit(inputWitness, artifact, foreignCallHandler);
475
464
  const output = convertOutput(witnessResult.witness);
476
465
 
@@ -487,75 +476,72 @@ export class BBNativeRollupProver implements ServerCircuitProver {
487
476
  eventName: 'circuit-witness-generation',
488
477
  } satisfies CircuitWitnessGenerationStats);
489
478
 
490
- // Now prove the circuit from the generated witness
491
- logger.debug(`Proving ${circuitType}...`);
479
+ // Read and decompress the witness for bb.js
480
+ const witnessGz = await fs.readFile(outputWitnessFile);
481
+ const witness = ungzip(witnessGz);
492
482
 
493
- const provingResult = await generateProof(
494
- this.config.bbBinaryPath,
495
- workingDirectory,
496
- circuitType,
497
- Buffer.from(artifact.bytecode, 'base64'),
498
- this.getVerificationKeyDataForCircuit(circuitType).keyAsBytes,
499
- outputWitnessFile,
500
- getUltraHonkFlavorForCircuit(circuitType),
501
- logger,
502
- );
483
+ // Decompress bytecode for bb.js
484
+ const bytecode = ungzip(Buffer.from(artifact.bytecode, 'base64'));
485
+
486
+ // Prove the circuit via bb.js API
487
+ logger.debug(`Proving ${circuitType} via bb.js...`);
503
488
 
504
- if (provingResult.status === BB_RESULT.FAILURE) {
505
- logger.error(`Failed to generate proof for ${circuitType}: ${provingResult.reason}`);
506
- throw new ProvingError(provingResult.reason, provingResult, provingResult.retry);
489
+ let proofResult: BBJsProofResult;
490
+ try {
491
+ await using instance = await this.bbJsFactory.getInstance();
492
+ proofResult = await instance.generateProof(
493
+ circuitType,
494
+ bytecode,
495
+ this.getVerificationKeyDataForCircuit(circuitType).keyAsBytes,
496
+ witness,
497
+ getUltraHonkFlavorForCircuit(circuitType),
498
+ );
499
+ } catch (error) {
500
+ throw new ProvingError(`Failed to generate proof for ${circuitType}: ${error}`);
507
501
  }
508
502
 
509
503
  return {
510
504
  circuitOutput: output,
511
- provingResult,
505
+ proofResult,
512
506
  };
513
507
  }
514
508
 
515
- private async generateAvmProofWithBB(input: AvmCircuitInputs, workingDirectory: string): Promise<BBSuccess> {
509
+ private async createAvmProof(input: AvmCircuitInputs): Promise<RecursiveProof<typeof AVM_V2_PROOF_LENGTH_IN_FIELDS>> {
516
510
  logger.info(`Proving avm-circuit for TX ${input.hints.tx.hash}...`);
517
511
 
518
- const provingResult = await generateAvmProof(this.config.bbBinaryPath, workingDirectory, input, logger);
512
+ const inputsBuffer = input.serializeWithMessagePack();
513
+ await using instance = await this.bbJsFactory.getInstance();
514
+ const { proof: proofFieldArrays, durationMs } = await instance.generateAvmProof(inputsBuffer);
519
515
 
520
- if (provingResult.status === BB_RESULT.FAILURE) {
521
- logger.error(`Failed to generate AVM proof for TX ${input.hints.tx.hash}: ${provingResult.reason}`);
522
- throw new ProvingError(provingResult.reason, provingResult, provingResult.retry);
523
- }
524
-
525
- return provingResult;
526
- }
516
+ // Convert Uint8Array[] (32-byte field elements) to Fr[]
517
+ const proofFields = proofFieldArrays.map(f => Fr.fromBuffer(Buffer.from(f)));
527
518
 
528
- private async createAvmProof(
529
- input: AvmCircuitInputs,
530
- ): Promise<RecursiveProof<typeof AVM_V2_PROOF_LENGTH_IN_FIELDS_PADDED>> {
531
- const operation = async (bbWorkingDirectory: string) => {
532
- const provingResult = await this.generateAvmProofWithBB(input, bbWorkingDirectory);
519
+ if (proofFields.length !== AVM_V2_PROOF_LENGTH_IN_FIELDS) {
520
+ throw new Error(`Proof has ${proofFields.length} fields, expected exactly ${AVM_V2_PROOF_LENGTH_IN_FIELDS}.`);
521
+ }
533
522
 
534
- const avmProof = await this.readAvmProofAsFields(provingResult.proofPath!);
523
+ // Build the binary proof from the raw field data
524
+ const rawProofBuffer = Buffer.concat(proofFieldArrays.map(f => Buffer.from(f)));
525
+ const binaryProof = new Proof(rawProofBuffer, /*numPublicInputs=*/ 0);
526
+ const avmProof = new RecursiveProof(proofFields, binaryProof, true, AVM_V2_PROOF_LENGTH_IN_FIELDS);
535
527
 
536
- const circuitType = 'avm-circuit' as const;
537
- const appCircuitName = 'unknown' as const;
538
- this.instrumentation.recordAvmDuration('provingDuration', appCircuitName, provingResult.durationMs);
539
- this.instrumentation.recordAvmSize('proofSize', appCircuitName, avmProof.binaryProof.buffer.length);
528
+ const circuitType = 'avm-circuit' as const;
529
+ const appCircuitName = 'unknown' as const;
530
+ this.instrumentation.recordAvmDuration('provingDuration', appCircuitName, durationMs);
531
+ this.instrumentation.recordAvmSize('proofSize', appCircuitName, avmProof.binaryProof.buffer.length);
540
532
 
541
- logger.info(
542
- `Generated proof for ${circuitType}(${input.hints.tx.hash}) in ${Math.ceil(provingResult.durationMs)} ms`,
543
- {
544
- circuitName: circuitType,
545
- appCircuitName: input.hints.tx.hash,
546
- // does not include reading the proof from disk
547
- duration: provingResult.durationMs,
548
- proofSize: avmProof.binaryProof.buffer.length,
549
- eventName: 'circuit-proving',
550
- inputSize: input.serializeWithMessagePack().length,
551
- circuitSize: 1 << 21,
552
- numPublicInputs: 0,
553
- } satisfies CircuitProvingStats,
554
- );
533
+ logger.info(`Generated proof for ${circuitType}(${input.hints.tx.hash}) in ${Math.ceil(durationMs)} ms`, {
534
+ circuitName: circuitType,
535
+ appCircuitName: input.hints.tx.hash,
536
+ duration: durationMs,
537
+ proofSize: avmProof.binaryProof.buffer.length,
538
+ eventName: 'circuit-proving',
539
+ inputSize: inputsBuffer.length,
540
+ circuitSize: 1 << 21,
541
+ numPublicInputs: 0,
542
+ } satisfies CircuitProvingStats);
555
543
 
556
- return avmProof;
557
- };
558
- return await this.runInDirectory(operation);
544
+ return avmProof;
559
545
  }
560
546
 
561
547
  /**
@@ -578,33 +564,38 @@ export class BBNativeRollupProver implements ServerCircuitProver {
578
564
  convertInput: (input: CircuitInputType) => WitnessMap,
579
565
  convertOutput: (outputWitness: WitnessMap) => CircuitOutputType,
580
566
  ): Promise<{ circuitOutput: CircuitOutputType; proof: RecursiveProof<PROOF_LENGTH> }> {
581
- // this probably is gonna need to call chonk
582
- const operation = async (bbWorkingDirectory: string) => {
583
- const { provingResult, circuitOutput: output } = await this.generateProofWithBB(
567
+ // Still need runInDirectory for ACVM witness generation temp files
568
+ const operation = async (workingDirectory: string) => {
569
+ const { proofResult, circuitOutput: output } = await this.generateProofWithBB(
584
570
  input,
585
571
  circuitType,
586
572
  convertInput,
587
573
  convertOutput,
588
- bbWorkingDirectory,
574
+ workingDirectory,
589
575
  );
590
576
 
591
577
  const vkData = this.getVerificationKeyDataForCircuit(circuitType);
592
- // Read the proof as fields
593
- const proof = await readProofsFromOutputDirectory(provingResult.proofPath!, vkData, proofLength, logger);
578
+ // Construct proof from in-memory buffers (no file I/O needed)
579
+ const proof = constructRecursiveProofFromBuffers(
580
+ proofResult.proofFields,
581
+ proofResult.publicInputFields,
582
+ vkData,
583
+ proofLength,
584
+ );
594
585
 
595
586
  const circuitName = mapProtocolArtifactNameToCircuitName(circuitType);
596
- this.instrumentation.recordDuration('provingDuration', circuitName, provingResult.durationMs);
587
+ this.instrumentation.recordDuration('provingDuration', circuitName, proofResult.durationMs);
597
588
  this.instrumentation.recordSize('proofSize', circuitName, proof.binaryProof.buffer.length);
598
589
  this.instrumentation.recordSize('circuitPublicInputCount', circuitName, vkData.numPublicInputs);
599
590
  this.instrumentation.recordSize('circuitSize', circuitName, vkData.circuitSize);
600
591
  logger.info(
601
- `Generated proof for ${circuitType} in ${Math.ceil(provingResult.durationMs)} ms, size: ${
592
+ `Generated proof for ${circuitType} in ${Math.ceil(proofResult.durationMs)} ms, size: ${
602
593
  proof.proof.length
603
594
  } fields`,
604
595
  {
605
596
  circuitName,
606
597
  circuitSize: vkData.circuitSize,
607
- duration: provingResult.durationMs,
598
+ duration: proofResult.durationMs,
608
599
  inputSize: output.toBuffer().length,
609
600
  proofSize: proof.binaryProof.buffer.length,
610
601
  eventName: 'circuit-proving',
@@ -621,49 +612,58 @@ export class BBNativeRollupProver implements ServerCircuitProver {
621
612
  }
622
613
 
623
614
  /**
624
- * Verifies a proof, will generate the verification key if one is not cached internally
615
+ * Verifies a proof via bb.js API (no temp files needed).
625
616
  * @param circuitType - The type of circuit whose proof is to be verified
626
617
  * @param proof - The proof to be verified
627
618
  */
628
619
  public async verifyProof(circuitType: ServerProtocolArtifact, proof: Proof) {
629
620
  const verificationKey = this.getVerificationKeyDataForCircuit(circuitType);
630
- return await this.verifyInternal(proof, verificationKey, (proofPath, vkPath) =>
631
- verifyProof(this.config.bbBinaryPath, proofPath, vkPath, getUltraHonkFlavorForCircuit(circuitType), logger),
632
- );
621
+ const flavor = getUltraHonkFlavorForCircuit(circuitType);
622
+
623
+ // Split proof buffer into public input fields and proof fields (32-byte each)
624
+ const publicInputFields = splitBufferToFieldArrays(proof.buffer.subarray(0, proof.numPublicInputs * 32));
625
+ const proofFields = splitBufferToFieldArrays(proof.buffer.subarray(proof.numPublicInputs * 32));
626
+
627
+ let verified: boolean;
628
+ let durationMs: number;
629
+ try {
630
+ await using instance = await this.bbJsFactory.getInstance();
631
+ ({ verified, durationMs } = await instance.verifyProof(
632
+ proofFields,
633
+ verificationKey.keyAsBytes,
634
+ publicInputFields,
635
+ flavor,
636
+ ));
637
+ } catch (error) {
638
+ throw new ProvingError(`Failed to verify proof for ${circuitType}: ${error}`);
639
+ }
640
+
641
+ if (!verified) {
642
+ throw new ProvingError('Failed to verify proof from key!');
643
+ }
644
+
645
+ logger.info(`Successfully verified proof from key in ${durationMs} ms`);
633
646
  }
634
647
 
648
+ /** Verify an AVM proof via bb.js API. */
635
649
  public async verifyAvmProof(proof: Proof, publicInputs: AvmCircuitPublicInputs) {
636
- return await this.verifyInternal(proof, /*verificationKey=*/ undefined, (proofPath, /*unused*/ _vkPath) =>
637
- verifyAvmProof(this.config.bbBinaryPath, this.config.bbWorkingDirectory, proofPath, publicInputs, logger),
638
- );
639
- }
640
- private async verifyInternal(
641
- proof: Proof,
642
- verificationKey: { keyAsBytes: Buffer } | undefined,
643
- verificationFunction: (proofPath: string, vkPath: string) => Promise<BBFailure | BBSuccess>,
644
- ) {
645
- const operation = async (bbWorkingDirectory: string) => {
646
- const publicInputsFileName = path.join(bbWorkingDirectory, PUBLIC_INPUTS_FILENAME);
647
- const proofFileName = path.join(bbWorkingDirectory, PROOF_FILENAME);
648
- const verificationKeyPath = path.join(bbWorkingDirectory, VK_FILENAME);
649
- // TODO(https://github.com/AztecProtocol/aztec-packages/issues/13189): Put this proof parsing logic in the proof class.
650
- await fs.writeFile(publicInputsFileName, proof.buffer.subarray(0, proof.numPublicInputs * 32));
651
- await fs.writeFile(proofFileName, proof.buffer.subarray(proof.numPublicInputs * 32));
652
- if (verificationKey !== undefined) {
653
- await fs.writeFile(verificationKeyPath, verificationKey.keyAsBytes);
654
- }
655
-
656
- const result = await verificationFunction(proofFileName, verificationKeyPath);
657
-
658
- if (result.status === BB_RESULT.FAILURE) {
659
- const errorMessage = `Failed to verify proof from key!`;
660
- throw new ProvingError(errorMessage, result, result.retry);
661
- }
662
-
663
- logger.info(`Successfully verified proof from key in ${result.durationMs} ms`);
664
- };
650
+ // For AVM proofs, numPublicInputs is 0, so the full buffer is the proof.
651
+ const proofBuffer = proof.buffer.subarray(proof.numPublicInputs * 32);
652
+ // Split the raw proof buffer into 32-byte field element arrays
653
+ const proofFields: Uint8Array[] = [];
654
+ for (let i = 0; i < proofBuffer.length; i += Fr.SIZE_IN_BYTES) {
655
+ proofFields.push(new Uint8Array(proofBuffer.subarray(i, i + Fr.SIZE_IN_BYTES)));
656
+ }
657
+ const piBuffer = publicInputs.serializeWithMessagePack();
665
658
 
666
- await this.runInDirectory(operation);
659
+ await using instance = await this.bbJsFactory.getInstance();
660
+ const { verified, durationMs } = await instance.verifyAvmProof(proofFields, piBuffer);
661
+
662
+ if (!verified) {
663
+ throw new ProvingError('Failed to verify AVM proof!');
664
+ }
665
+
666
+ logger.info(`Successfully verified AVM proof in ${durationMs} ms`);
667
667
  }
668
668
 
669
669
  /**
@@ -679,29 +679,6 @@ export class BBNativeRollupProver implements ServerCircuitProver {
679
679
  return vk;
680
680
  }
681
681
 
682
- private async readAvmProofAsFields(
683
- proofFilename: string,
684
- ): Promise<RecursiveProof<typeof AVM_V2_PROOF_LENGTH_IN_FIELDS_PADDED>> {
685
- const rawProofBuffer = await fs.readFile(proofFilename);
686
- const reader = BufferReader.asReader(rawProofBuffer);
687
- const proofFields = reader.readArray(rawProofBuffer.length / Fr.SIZE_IN_BYTES, Fr);
688
-
689
- // We extend to a fixed-size padded proof as during development any new AVM circuit column changes the
690
- // proof length and we do not have a mechanism to feedback a cpp constant to noir/TS.
691
- // TODO(#13390): Revive a non-padded AVM proof
692
- if (proofFields.length > AVM_V2_PROOF_LENGTH_IN_FIELDS_PADDED) {
693
- throw new Error(
694
- `Proof has ${proofFields.length} fields, expected no more than ${AVM_V2_PROOF_LENGTH_IN_FIELDS_PADDED}.`,
695
- );
696
- }
697
- const proofFieldsPadded = proofFields.concat(
698
- Array(AVM_V2_PROOF_LENGTH_IN_FIELDS_PADDED - proofFields.length).fill(new Fr(0)),
699
- );
700
-
701
- const proof = new Proof(rawProofBuffer, /*numPublicInputs=*/ 0);
702
- return new RecursiveProof(proofFieldsPadded, proof, true, AVM_V2_PROOF_LENGTH_IN_FIELDS_PADDED);
703
- }
704
-
705
682
  private runInDirectory<T>(fn: (dir: string) => Promise<T>) {
706
683
  return runInDirectory(
707
684
  this.config.bbWorkingDirectory,
@@ -715,3 +692,12 @@ export class BBNativeRollupProver implements ServerCircuitProver {
715
692
  );
716
693
  }
717
694
  }
695
+
696
+ /** Split a buffer into 32-byte Uint8Array field elements. */
697
+ function splitBufferToFieldArrays(buffer: Buffer): Uint8Array[] {
698
+ const fields: Uint8Array[] = [];
699
+ for (let i = 0; i < buffer.length; i += 32) {
700
+ fields.push(new Uint8Array(buffer.subarray(i, i + 32)));
701
+ }
702
+ return fields;
703
+ }
@@ -35,7 +35,7 @@ export const PROOF_DELAY_MS: Record<ProvingRequestType, number> = {
35
35
  [ProvingRequestType.ROOT_ROLLUP]: 93_000,
36
36
  [ProvingRequestType.TX_MERGE_ROLLUP]: 10_000,
37
37
  [ProvingRequestType.PUBLIC_TX_BASE_ROLLUP]: 44_500,
38
- [ProvingRequestType.PUBLIC_VM]: 10_000,
38
+ [ProvingRequestType.PUBLIC_VM]: 180_000,
39
39
 
40
40
  // TBD
41
41
  [ProvingRequestType.BLOCK_MERGE_ROLLUP]: 15_000,
@@ -1,5 +1,5 @@
1
1
  import {
2
- AVM_V2_PROOF_LENGTH_IN_FIELDS_PADDED,
2
+ AVM_V2_PROOF_LENGTH_IN_FIELDS,
3
3
  NESTED_RECURSIVE_PROOF_LENGTH,
4
4
  NESTED_RECURSIVE_ROLLUP_HONK_PROOF_LENGTH,
5
5
  RECURSIVE_PROOF_LENGTH,
@@ -402,13 +402,11 @@ export class TestCircuitProver implements ServerCircuitProver {
402
402
  );
403
403
  }
404
404
 
405
- public getAvmProof(_inputs: AvmCircuitInputs): Promise<RecursiveProof<typeof AVM_V2_PROOF_LENGTH_IN_FIELDS_PADDED>> {
405
+ public getAvmProof(_inputs: AvmCircuitInputs): Promise<RecursiveProof<typeof AVM_V2_PROOF_LENGTH_IN_FIELDS>> {
406
406
  // We can't simulate the AVM because we don't have enough context to do so (e.g., DBs).
407
407
  // We just return an empty proof.
408
408
  this.logger.debug('Skipping AVM simulation in TestCircuitProver.');
409
- return this.applyDelay(ProvingRequestType.PUBLIC_VM, () =>
410
- makeEmptyRecursiveProof(AVM_V2_PROOF_LENGTH_IN_FIELDS_PADDED),
411
- );
409
+ return this.applyDelay(ProvingRequestType.PUBLIC_VM, () => makeEmptyRecursiveProof(AVM_V2_PROOF_LENGTH_IN_FIELDS));
412
410
  }
413
411
 
414
412
  private async applyDelay<F extends () => any>(type: ProvingRequestType, fn: F): Promise<Awaited<ReturnType<F>>> {
@@ -5,7 +5,7 @@ import { VerificationKeyAsFields, VerificationKeyData } from '@aztec/stdlib/vks'
5
5
  import { promises as fs } from 'fs';
6
6
  import * as path from 'path';
7
7
 
8
- import { VK_FILENAME } from '../bb/execute.js';
8
+ import { VK_FILENAME } from '../bb/file_names.js';
9
9
 
10
10
  /**
11
11
  * Reads the verification key data stored at the specified location and parses into a VerificationKeyData