@aztec/bb-prover 0.87.3-nightly.20250528 → 0.87.3

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.
@@ -1,6 +1,5 @@
1
- import { AVM_V2_VERIFICATION_KEY_LENGTH_IN_FIELDS_PADDED } from '@aztec/constants';
1
+ import { AVM_VERIFICATION_KEY_LENGTH_IN_FIELDS } from '@aztec/constants';
2
2
  import { Fr } from '@aztec/foundation/fields';
3
- import { BufferReader } from '@aztec/foundation/serialize';
4
3
  import { hashVK } from '@aztec/stdlib/hash';
5
4
  import { VerificationKeyAsFields, VerificationKeyData } from '@aztec/stdlib/vks';
6
5
  import { strict as assert } from 'assert';
@@ -25,20 +24,21 @@ import { VK_FIELDS_FILENAME, VK_FILENAME } from '../bb/execute.js';
25
24
  const vkAsFields = new VerificationKeyAsFields(fields, vkHash);
26
25
  return new VerificationKeyData(vkAsFields, rawBinary);
27
26
  }
28
- /**
29
- * Reads the verification key data stored in a binary file at the specified directory location and parses into a VerificationKeyData.
30
- * We do not assume any JSON file available but only the binary version, contrary to the above extractVkData() method.
31
- * @param vkDirectoryPath - The directory containing the verification key binary data file.
32
- * @returns The verification key data
33
- */ export async function extractAvmVkData(vkDirectoryPath) {
34
- const rawBinary = await fs.readFile(path.join(vkDirectoryPath, VK_FILENAME));
35
- const numFields = rawBinary.length / Fr.SIZE_IN_BYTES;
36
- assert(numFields <= AVM_V2_VERIFICATION_KEY_LENGTH_IN_FIELDS_PADDED, 'Invalid AVM verification key length');
37
- const reader = BufferReader.asReader(rawBinary);
38
- const fieldsArray = reader.readArray(numFields, Fr);
39
- const fieldsArrayPadded = fieldsArray.concat(Array(AVM_V2_VERIFICATION_KEY_LENGTH_IN_FIELDS_PADDED - fieldsArray.length).fill(new Fr(0)));
40
- // Currently, we do not need the vk hash for the AVM as we are not adding in the vk tree.
41
- const vkAsFields = new VerificationKeyAsFields(fieldsArrayPadded, new Fr(0));
27
+ // TODO: This was adapted from the above function. A refactor might be needed.
28
+ export async function extractAvmVkData(vkDirectoryPath) {
29
+ const [rawFields, rawBinary] = await Promise.all([
30
+ fs.readFile(path.join(vkDirectoryPath, VK_FIELDS_FILENAME), {
31
+ encoding: 'utf-8'
32
+ }),
33
+ fs.readFile(path.join(vkDirectoryPath, VK_FILENAME))
34
+ ]);
35
+ const fieldsJson = JSON.parse(rawFields);
36
+ const fields = fieldsJson.map(Fr.fromHexString);
37
+ // The first item is the hash, this is not part of the actual VK
38
+ // TODO: is the above actually the case?
39
+ const vkHash = fields[0];
40
+ assert(fields.length === AVM_VERIFICATION_KEY_LENGTH_IN_FIELDS, 'Invalid AVM verification key length');
41
+ const vkAsFields = new VerificationKeyAsFields(fields, vkHash);
42
42
  const vk = new VerificationKeyData(vkAsFields, rawBinary);
43
43
  return vk;
44
44
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@aztec/bb-prover",
3
- "version": "0.87.3-nightly.20250528",
3
+ "version": "0.87.3",
4
4
  "type": "module",
5
5
  "exports": {
6
6
  ".": "./dest/index.js",
@@ -66,16 +66,16 @@
66
66
  ]
67
67
  },
68
68
  "dependencies": {
69
- "@aztec/bb.js": "0.87.3-nightly.20250528",
70
- "@aztec/constants": "0.87.3-nightly.20250528",
71
- "@aztec/foundation": "0.87.3-nightly.20250528",
72
- "@aztec/noir-noirc_abi": "0.87.3-nightly.20250528",
73
- "@aztec/noir-protocol-circuits-types": "0.87.3-nightly.20250528",
74
- "@aztec/noir-types": "0.87.3-nightly.20250528",
75
- "@aztec/simulator": "0.87.3-nightly.20250528",
76
- "@aztec/stdlib": "0.87.3-nightly.20250528",
77
- "@aztec/telemetry-client": "0.87.3-nightly.20250528",
78
- "@aztec/world-state": "0.87.3-nightly.20250528",
69
+ "@aztec/bb.js": "0.87.3",
70
+ "@aztec/constants": "0.87.3",
71
+ "@aztec/foundation": "0.87.3",
72
+ "@aztec/noir-noirc_abi": "0.87.3",
73
+ "@aztec/noir-protocol-circuits-types": "0.87.3",
74
+ "@aztec/noir-types": "0.87.3",
75
+ "@aztec/simulator": "0.87.3",
76
+ "@aztec/stdlib": "0.87.3",
77
+ "@aztec/telemetry-client": "0.87.3",
78
+ "@aztec/world-state": "0.87.3",
79
79
  "commander": "^12.1.0",
80
80
  "pako": "^2.1.0",
81
81
  "pidusage": "^4.0.1",
@@ -83,11 +83,11 @@
83
83
  "tslib": "^2.4.0"
84
84
  },
85
85
  "devDependencies": {
86
- "@aztec/ethereum": "0.87.3-nightly.20250528",
87
- "@aztec/kv-store": "0.87.3-nightly.20250528",
88
- "@aztec/noir-contracts.js": "0.87.3-nightly.20250528",
89
- "@aztec/noir-test-contracts.js": "0.87.3-nightly.20250528",
90
- "@aztec/protocol-contracts": "0.87.3-nightly.20250528",
86
+ "@aztec/ethereum": "0.87.3",
87
+ "@aztec/kv-store": "0.87.3",
88
+ "@aztec/noir-contracts.js": "0.87.3",
89
+ "@aztec/noir-test-contracts.js": "0.87.3",
90
+ "@aztec/protocol-contracts": "0.87.3",
91
91
  "@jest/globals": "^29.5.0",
92
92
  "@types/jest": "^29.5.0",
93
93
  "@types/node": "^22.15.17",
@@ -7,6 +7,7 @@ import { type AvmCircuitInputs, AvmCircuitPublicInputs } from '@aztec/stdlib/avm
7
7
  import { AztecAddress } from '@aztec/stdlib/aztec-address';
8
8
  import type { MerkleTreeWriteOperations } from '@aztec/stdlib/interfaces/server';
9
9
  import type { GlobalVariables } from '@aztec/stdlib/tx';
10
+ import { VerificationKeyData } from '@aztec/stdlib/vks';
10
11
  import { NativeWorldStateService } from '@aztec/world-state';
11
12
 
12
13
  import fs from 'node:fs/promises';
@@ -17,10 +18,12 @@ import {
17
18
  type BBResult,
18
19
  type BBSuccess,
19
20
  BB_RESULT,
20
- VK_FILENAME,
21
21
  generateAvmProof,
22
+ generateAvmProofV2,
22
23
  verifyAvmProof,
24
+ verifyAvmProofV2,
23
25
  } from '../bb/execute.js';
26
+ import { extractAvmVkData } from '../verification_key/verification_key_data.js';
24
27
 
25
28
  const BB_PATH = path.resolve('../../barretenberg/cpp/build/bin/bb');
26
29
 
@@ -28,19 +31,20 @@ export class AvmProvingTester extends PublicTxSimulationTester {
28
31
  constructor(
29
32
  private bbWorkingDirectory: string,
30
33
  private checkCircuitOnly: boolean,
34
+ merkleTree: MerkleTreeWriteOperations,
31
35
  contractDataSource: SimpleContractDataSource,
32
- merkleTrees: MerkleTreeWriteOperations,
33
36
  globals?: GlobalVariables,
34
37
  ) {
35
- super(merkleTrees, contractDataSource, globals);
38
+ super(merkleTree, contractDataSource, globals);
36
39
  }
37
40
 
41
+ // overriding parent class' create is a pain, so we use a different nam
38
42
  static async new(checkCircuitOnly: boolean = false, globals?: GlobalVariables) {
39
43
  const bbWorkingDirectory = await fs.mkdtemp(path.join(tmpdir(), 'bb-'));
40
44
 
41
45
  const contractDataSource = new SimpleContractDataSource();
42
46
  const merkleTrees = await (await NativeWorldStateService.tmp()).fork();
43
- return new AvmProvingTester(bbWorkingDirectory, checkCircuitOnly, contractDataSource, merkleTrees, globals);
47
+ return new AvmProvingTester(bbWorkingDirectory, checkCircuitOnly, merkleTrees, contractDataSource, globals);
44
48
  }
45
49
 
46
50
  async prove(avmCircuitInputs: AvmCircuitInputs): Promise<BBResult> {
@@ -55,36 +59,95 @@ export class AvmProvingTester extends PublicTxSimulationTester {
55
59
  if (proofRes.status === BB_RESULT.FAILURE) {
56
60
  this.logger.error(`Proof generation failed: ${proofRes.reason}`);
57
61
  }
58
- expect(proofRes.status).toEqual(BB_RESULT.SUCCESS);
59
- return proofRes as BBSuccess;
62
+ return proofRes;
60
63
  }
61
64
 
62
- async verify(proofRes: BBSuccess, publicInputs: AvmCircuitPublicInputs): Promise<BBResult> {
65
+ async verify(proofRes: BBSuccess): Promise<BBResult> {
63
66
  if (this.checkCircuitOnly) {
64
- // Skip verification if we are only checking the circuit.
65
- // Check-circuit does not generate a proof to verify.
67
+ // Skip verification if we're only checking the circuit.
68
+ // Check-circuit doesn't generate a proof to verify.
66
69
  return proofRes;
67
70
  }
71
+ // Then we test VK extraction and serialization.
72
+ const succeededRes = proofRes as BBSuccess;
73
+ const vkData = await extractAvmVkData(succeededRes.vkPath!);
74
+ VerificationKeyData.fromBuffer(vkData.toBuffer());
68
75
 
69
- return await verifyAvmProof(
70
- BB_PATH,
71
- this.bbWorkingDirectory,
72
- proofRes.proofPath!,
73
- publicInputs,
74
- path.join(proofRes.vkDirectoryPath!, VK_FILENAME),
75
- this.logger,
76
- );
76
+ // Then we verify.
77
+ const rawVkPath = path.join(succeededRes.vkPath!, 'vk');
78
+ return await verifyAvmProof(BB_PATH, succeededRes.proofPath!, rawVkPath, this.logger);
79
+ }
80
+
81
+ public async simProveVerify(
82
+ sender: AztecAddress,
83
+ setupCalls: TestEnqueuedCall[],
84
+ appCalls: TestEnqueuedCall[],
85
+ teardownCall: TestEnqueuedCall | undefined,
86
+ expectRevert: boolean | undefined,
87
+ feePayer = sender,
88
+ ) {
89
+ const simRes = await this.simulateTx(sender, setupCalls, appCalls, teardownCall, feePayer);
90
+ expect(simRes.revertCode.isOK()).toBe(expectRevert ? false : true);
91
+ const avmCircuitInputs = simRes.avmProvingRequest.inputs;
92
+ const provingRes = await this.prove(avmCircuitInputs);
93
+ expect(provingRes.status).toEqual(BB_RESULT.SUCCESS);
94
+ const verificationRes = await this.verify(provingRes as BBSuccess);
95
+ expect(verificationRes.status).toBe(BB_RESULT.SUCCESS);
77
96
  }
78
97
 
79
- public async proveVerify(avmCircuitInputs: AvmCircuitInputs) {
98
+ public async simProveVerifyAppLogic(appCall: TestEnqueuedCall, expectRevert?: boolean) {
99
+ const simRes = await this.simulateTx(/*sender=*/ AztecAddress.fromNumber(42), /*setupCalls=*/ [], [appCall]);
100
+ expect(simRes.revertCode.isOK()).toBe(expectRevert ? false : true);
101
+
102
+ const avmCircuitInputs = simRes.avmProvingRequest.inputs;
80
103
  const provingRes = await this.prove(avmCircuitInputs);
81
104
  expect(provingRes.status).toEqual(BB_RESULT.SUCCESS);
82
105
 
83
- const verificationRes = await this.verify(provingRes as BBSuccess, avmCircuitInputs.publicInputs);
106
+ const verificationRes = await this.verify(provingRes as BBSuccess);
84
107
  expect(verificationRes.status).toBe(BB_RESULT.SUCCESS);
85
108
  }
109
+ }
86
110
 
87
- public async simProveVerify(
111
+ export class AvmProvingTesterV2 extends PublicTxSimulationTester {
112
+ constructor(
113
+ private bbWorkingDirectory: string,
114
+ contractDataSource: SimpleContractDataSource,
115
+ merkleTrees: MerkleTreeWriteOperations,
116
+ globals?: GlobalVariables,
117
+ ) {
118
+ super(merkleTrees, contractDataSource, globals);
119
+ }
120
+
121
+ static async new(globals?: GlobalVariables) {
122
+ const bbWorkingDirectory = await fs.mkdtemp(path.join(tmpdir(), 'bb-'));
123
+
124
+ const contractDataSource = new SimpleContractDataSource();
125
+ const merkleTrees = await (await NativeWorldStateService.tmp()).fork();
126
+ return new AvmProvingTesterV2(bbWorkingDirectory, contractDataSource, merkleTrees, globals);
127
+ }
128
+
129
+ async proveV2(avmCircuitInputs: AvmCircuitInputs): Promise<BBResult> {
130
+ // Then we prove.
131
+ const proofRes = await generateAvmProofV2(BB_PATH, this.bbWorkingDirectory, avmCircuitInputs, this.logger);
132
+ if (proofRes.status === BB_RESULT.FAILURE) {
133
+ this.logger.error(`Proof generation failed: ${proofRes.reason}`);
134
+ }
135
+ expect(proofRes.status).toEqual(BB_RESULT.SUCCESS);
136
+ return proofRes as BBSuccess;
137
+ }
138
+
139
+ async verifyV2(proofRes: BBSuccess, publicInputs: AvmCircuitPublicInputs): Promise<BBResult> {
140
+ return await verifyAvmProofV2(
141
+ BB_PATH,
142
+ this.bbWorkingDirectory,
143
+ proofRes.proofPath!,
144
+ publicInputs,
145
+ proofRes.vkPath!,
146
+ this.logger,
147
+ );
148
+ }
149
+
150
+ public async simProveVerifyV2(
88
151
  sender: AztecAddress,
89
152
  setupCalls: TestEnqueuedCall[],
90
153
  appCalls: TestEnqueuedCall[],
@@ -96,16 +159,10 @@ export class AvmProvingTester extends PublicTxSimulationTester {
96
159
  expect(simRes.revertCode.isOK()).toBe(expectRevert ? false : true);
97
160
 
98
161
  const avmCircuitInputs = simRes.avmProvingRequest.inputs;
99
- await this.proveVerify(avmCircuitInputs);
100
- }
162
+ const provingRes = await this.proveV2(avmCircuitInputs);
163
+ expect(provingRes.status).toEqual(BB_RESULT.SUCCESS);
101
164
 
102
- public async simProveVerifyAppLogic(appCall: TestEnqueuedCall, expectRevert?: boolean) {
103
- await this.simProveVerify(
104
- /*sender=*/ AztecAddress.fromNumber(42),
105
- /*setupCalls=*/ [],
106
- [appCall],
107
- undefined,
108
- expectRevert,
109
- );
165
+ const verificationRes = await this.verifyV2(provingRes as BBSuccess, avmCircuitInputs.publicInputs);
166
+ expect(verificationRes.status).toBe(BB_RESULT.SUCCESS);
110
167
  }
111
168
  }
package/src/bb/execute.ts CHANGED
@@ -33,7 +33,7 @@ export type BBSuccess = {
33
33
  /** Full path of the public key. */
34
34
  pkPath?: string;
35
35
  /** Base directory for the VKs (raw, fields). */
36
- vkDirectoryPath?: string;
36
+ vkPath?: string;
37
37
  /** Full path of the proof. */
38
38
  proofPath?: string;
39
39
  /** Full path of the contract. */
@@ -50,6 +50,8 @@ export type BBFailure = {
50
50
 
51
51
  export type BBResult = BBSuccess | BBFailure;
52
52
 
53
+ export type VerificationFunction = typeof verifyProof | typeof verifyAvmProof;
54
+
53
55
  type BBExecResult = {
54
56
  status: BB_RESULT;
55
57
  exitCode: number;
@@ -173,7 +175,7 @@ export async function executeBbClientIvcProof(
173
175
  durationMs,
174
176
  proofPath: `${outputPath}`,
175
177
  pkPath: undefined,
176
- vkDirectoryPath: `${outputPath}`,
178
+ vkPath: `${outputPath}`,
177
179
  };
178
180
  }
179
181
  // Not a great error message here but it is difficult to decipher what comes from bb
@@ -277,7 +279,7 @@ export async function generateProof(
277
279
  durationMs: duration,
278
280
  proofPath: `${outputPath}`,
279
281
  pkPath: undefined,
280
- vkDirectoryPath: `${outputPath}`,
282
+ vkPath: `${outputPath}`,
281
283
  };
282
284
  }
283
285
  // Not a great error message here but it is difficult to decipher what comes from bb
@@ -345,7 +347,7 @@ export async function generateTubeProof(
345
347
  durationMs,
346
348
  proofPath: outputPath,
347
349
  pkPath: undefined,
348
- vkDirectoryPath: outputPath,
350
+ vkPath: outputPath,
349
351
  };
350
352
  }
351
353
  // Not a great error message here but it is difficult to decipher what comes from bb
@@ -365,16 +367,14 @@ export async function generateTubeProof(
365
367
  * @param pathToBB - The full path to the bb binary
366
368
  * @param workingDirectory - A working directory for use by bb
367
369
  * @param input - The inputs for the public function to be proven
368
- * @param logger - A logging function
369
- * @param checkCircuitOnly - A boolean to toggle a "check-circuit only" operation instead of proving.
370
+ * @param log - A logging function
370
371
  * @returns An object containing a result indication, the location of the proof and the duration taken
371
372
  */
372
- export async function generateAvmProof(
373
+ export async function generateAvmProofV2(
373
374
  pathToBB: string,
374
375
  workingDirectory: string,
375
376
  input: AvmCircuitInputs,
376
377
  logger: Logger,
377
- checkCircuitOnly: boolean = false,
378
378
  ): Promise<BBFailure | BBSuccess> {
379
379
  // Check that the working directory exists
380
380
  try {
@@ -414,12 +414,99 @@ export async function generateAvmProof(
414
414
  args.push(loggingArg);
415
415
  }
416
416
  const timer = new Timer();
417
+ const logFunction = (message: string) => {
418
+ logger.verbose(`AvmCircuit (prove) BB out - ${message}`);
419
+ };
420
+ const result = await executeBB(pathToBB, 'avm2_prove', args, logFunction);
421
+ const duration = timer.ms();
417
422
 
418
- const cmd = checkCircuitOnly ? 'avm_check_circuit' : 'avm_prove';
423
+ if (result.status == BB_RESULT.SUCCESS) {
424
+ return {
425
+ status: BB_RESULT.SUCCESS,
426
+ durationMs: duration,
427
+ proofPath: join(outputPath, PROOF_FILENAME),
428
+ pkPath: undefined,
429
+ vkPath: join(outputPath, VK_FILENAME),
430
+ };
431
+ }
432
+ // Not a great error message here but it is difficult to decipher what comes from bb
433
+ return {
434
+ status: BB_RESULT.FAILURE,
435
+ reason: `Failed to generate proof. Exit code ${result.exitCode}. Signal ${result.signal}.`,
436
+ retry: !!result.signal,
437
+ };
438
+ } catch (error) {
439
+ return { status: BB_RESULT.FAILURE, reason: `${error}` };
440
+ }
441
+ }
442
+
443
+ /**
444
+ * Used for generating AVM proofs (or doing check-circuit).
445
+ * It is assumed that the working directory is a temporary and/or random directory used solely for generating this proof.
446
+ * @param pathToBB - The full path to the bb binary
447
+ * @param workingDirectory - A working directory for use by bb
448
+ * @param bytecode - The AVM bytecode for the public function to be proven (expected to be decompressed)
449
+ * @param log - A logging function
450
+ * @returns An object containing a result indication, the location of the proof and the duration taken
451
+ */
452
+ export async function generateAvmProof(
453
+ pathToBB: string,
454
+ workingDirectory: string,
455
+ _input: AvmCircuitInputs,
456
+ logger: Logger,
457
+ checkCircuitOnly: boolean = false,
458
+ ): Promise<BBFailure | BBSuccess> {
459
+ // Check that the working directory exists
460
+ try {
461
+ await fs.access(workingDirectory);
462
+ } catch {
463
+ return { status: BB_RESULT.FAILURE, reason: `Working directory ${workingDirectory} does not exist` };
464
+ }
465
+
466
+ // Paths for the inputs
467
+ const publicInputsPath = join(workingDirectory, AVM_PUBLIC_INPUTS_FILENAME);
468
+
469
+ // The proof is written to e.g. /workingDirectory/proof
470
+ const outputPath = workingDirectory;
471
+
472
+ const filePresent = async (file: string) =>
473
+ await fs
474
+ .access(file, fs.constants.R_OK)
475
+ .then(_ => true)
476
+ .catch(_ => false);
477
+
478
+ const binaryPresent = await filePresent(pathToBB);
479
+ if (!binaryPresent) {
480
+ return { status: BB_RESULT.FAILURE, reason: `Failed to find bb binary at ${pathToBB}` };
481
+ }
482
+
483
+ try {
484
+ // Write the inputs to the working directory.
485
+
486
+ // WARNING: Not writing the inputs since VM1 is disabled!
487
+ // await fs.writeFile(publicInputsPath, input.publicInputs.toBuffer());
488
+ // if (!(await filePresent(publicInputsPath))) {
489
+ // return { status: BB_RESULT.FAILURE, reason: `Could not write publicInputs at ${publicInputsPath}` };
490
+ // }
491
+
492
+ // await fs.writeFile(avmHintsPath, input.avmHints.toBuffer());
493
+ // if (!(await filePresent(avmHintsPath))) {
494
+ // return { status: BB_RESULT.FAILURE, reason: `Could not write avmHints at ${avmHintsPath}` };
495
+ // }
496
+
497
+ const args = ['--avm-public-inputs', publicInputsPath, '-o', outputPath];
498
+ const loggingArg =
499
+ logger.level === 'debug' || logger.level === 'trace' ? '-d' : logger.level === 'verbose' ? '-v' : '';
500
+ if (loggingArg !== '') {
501
+ args.push(loggingArg);
502
+ }
503
+
504
+ const timer = new Timer();
505
+ const cmd = checkCircuitOnly ? 'check_circuit' : 'prove';
419
506
  const logFunction = (message: string) => {
420
507
  logger.verbose(`AvmCircuit (${cmd}) BB out - ${message}`);
421
508
  };
422
- const result = await executeBB(pathToBB, cmd, args, logFunction);
509
+ const result = await executeBB(pathToBB, `avm_${cmd}`, args, logFunction);
423
510
  const duration = timer.ms();
424
511
 
425
512
  if (result.status == BB_RESULT.SUCCESS) {
@@ -428,7 +515,7 @@ export async function generateAvmProof(
428
515
  durationMs: duration,
429
516
  proofPath: join(outputPath, PROOF_FILENAME),
430
517
  pkPath: undefined,
431
- vkDirectoryPath: outputPath,
518
+ vkPath: outputPath,
432
519
  };
433
520
  }
434
521
  // Not a great error message here but it is difficult to decipher what comes from bb
@@ -467,7 +554,24 @@ export async function verifyProof(
467
554
  );
468
555
  }
469
556
 
557
+ /**
558
+ * Used for verifying proofs of the AVM
559
+ * @param pathToBB - The full path to the bb binary
560
+ * @param proofFullPath - The full path to the proof to be verified
561
+ * @param verificationKeyPath - The full path to the circuit verification key
562
+ * @param log - A logging function
563
+ * @returns An object containing a result indication and duration taken
564
+ */
470
565
  export async function verifyAvmProof(
566
+ pathToBB: string,
567
+ proofFullPath: string,
568
+ verificationKeyPath: string,
569
+ logger: Logger,
570
+ ): Promise<BBFailure | BBSuccess> {
571
+ return await verifyProofInternal(pathToBB, proofFullPath, verificationKeyPath, 'avm_verify', logger);
572
+ }
573
+
574
+ export async function verifyAvmProofV2(
471
575
  pathToBB: string,
472
576
  workingDirectory: string,
473
577
  proofFullPath: string,
@@ -489,7 +593,7 @@ export async function verifyAvmProof(
489
593
  return { status: BB_RESULT.FAILURE, reason: `Could not write avm inputs to ${avmInputsPath}` };
490
594
  }
491
595
 
492
- return await verifyProofInternal(pathToBB, proofFullPath, verificationKeyPath, 'avm_verify', logger, [
596
+ return await verifyProofInternal(pathToBB, proofFullPath, verificationKeyPath, 'avm2_verify', logger, [
493
597
  '--avm-public-inputs',
494
598
  avmInputsPath,
495
599
  ]);
@@ -550,7 +654,7 @@ async function verifyProofInternal(
550
654
  pathToBB: string,
551
655
  proofFullPath: string,
552
656
  verificationKeyPath: string,
553
- command: 'verify' | 'avm_verify',
657
+ command: 'verify' | 'avm_verify' | 'avm2_verify',
554
658
  logger: Logger,
555
659
  extraArgs: string[] = [],
556
660
  ): Promise<BBFailure | BBSuccess> {
@@ -566,27 +670,24 @@ async function verifyProofInternal(
566
670
  logger.verbose(`bb-prover (verify) BB out - ${message}`);
567
671
  };
568
672
 
673
+ // take proofFullPath and remove the suffix past the / to get the directory
674
+ const proofDir = proofFullPath.substring(0, proofFullPath.lastIndexOf('/'));
675
+ const publicInputsFullPath = join(proofDir, '/public_inputs');
676
+
677
+ logger.debug(`public inputs path: ${publicInputsFullPath}`);
569
678
  try {
570
679
  let args;
571
-
680
+ // Specify the public inputs path in the case of UH verification.
572
681
  if (command == 'verify') {
573
- // Specify the public inputs path in the case of UH verification.
574
- // Take proofFullPath and remove the suffix past the / to get the directory.
575
- const proofDir = proofFullPath.substring(0, proofFullPath.lastIndexOf('/'));
576
- const publicInputsFullPath = join(proofDir, '/public_inputs');
577
- logger.debug(`public inputs path: ${publicInputsFullPath}`);
578
-
579
682
  args = ['-p', proofFullPath, '-k', verificationKeyPath, '-i', publicInputsFullPath, ...extraArgs];
580
683
  } else {
581
684
  args = ['-p', proofFullPath, '-k', verificationKeyPath, ...extraArgs];
582
685
  }
583
-
584
686
  const loggingArg =
585
687
  logger.level === 'debug' || logger.level === 'trace' ? '-d' : logger.level === 'verbose' ? '-v' : '';
586
688
  if (loggingArg !== '') {
587
689
  args.push(loggingArg);
588
690
  }
589
-
590
691
  const timer = new Timer();
591
692
  const result = await executeBB(pathToBB, command, args, logFunction);
592
693
  const duration = timer.ms();
@@ -1,5 +1,5 @@
1
1
  import {
2
- AVM_V2_PROOF_LENGTH_IN_FIELDS_PADDED,
2
+ AVM_PROOF_LENGTH_IN_FIELDS,
3
3
  NESTED_RECURSIVE_PROOF_LENGTH,
4
4
  NESTED_RECURSIVE_ROLLUP_HONK_PROOF_LENGTH,
5
5
  PAIRING_POINTS_SIZE,
@@ -37,7 +37,7 @@ import {
37
37
  import { ServerCircuitVks } from '@aztec/noir-protocol-circuits-types/server/vks';
38
38
  import type { WitnessMap } from '@aztec/noir-types';
39
39
  import { NativeACVMSimulator } from '@aztec/simulator/server';
40
- import type { AvmCircuitInputs, AvmCircuitPublicInputs } from '@aztec/stdlib/avm';
40
+ import type { AvmCircuitInputs } from '@aztec/stdlib/avm';
41
41
  import { ProvingError } from '@aztec/stdlib/errors';
42
42
  import {
43
43
  type ProofAndVerificationKey,
@@ -48,20 +48,19 @@ import {
48
48
  } from '@aztec/stdlib/interfaces/server';
49
49
  import type { BaseParityInputs, ParityPublicInputs, RootParityInputs } from '@aztec/stdlib/parity';
50
50
  import { Proof, RecursiveProof, makeRecursiveProofFromBinary } from '@aztec/stdlib/proofs';
51
- import {
52
- type BaseOrMergeRollupPublicInputs,
53
- type BlockMergeRollupInputs,
54
- type BlockRootOrBlockMergePublicInputs,
55
- type BlockRootRollupInputs,
56
- type EmptyBlockRootRollupInputs,
57
- type MergeRollupInputs,
58
- type PrivateBaseRollupInputs,
51
+ import type {
52
+ BaseOrMergeRollupPublicInputs,
53
+ BlockMergeRollupInputs,
54
+ BlockRootOrBlockMergePublicInputs,
55
+ BlockRootRollupInputs,
56
+ EmptyBlockRootRollupInputs,
57
+ MergeRollupInputs,
58
+ PrivateBaseRollupInputs,
59
59
  PublicBaseRollupInputs,
60
- type RootRollupInputs,
61
- type RootRollupPublicInputs,
62
- type SingleTxBlockRootRollupInputs,
63
- type TubeInputs,
64
- enhanceProofWithPiValidationFlag,
60
+ RootRollupInputs,
61
+ RootRollupPublicInputs,
62
+ SingleTxBlockRootRollupInputs,
63
+ TubeInputs,
65
64
  } from '@aztec/stdlib/rollup';
66
65
  import type { CircuitProvingStats, CircuitWitnessGenerationStats } from '@aztec/stdlib/stats';
67
66
  import type { VerificationKeyData } from '@aztec/stdlib/vks';
@@ -186,13 +185,9 @@ export class BBNativeRollupProver implements ServerCircuitProver {
186
185
  }))
187
186
  public async getAvmProof(
188
187
  inputs: AvmCircuitInputs,
189
- skipPublicInputsValidation: boolean = false,
190
- ): Promise<ProofAndVerificationKey<typeof AVM_V2_PROOF_LENGTH_IN_FIELDS_PADDED>> {
188
+ ): Promise<ProofAndVerificationKey<typeof AVM_PROOF_LENGTH_IN_FIELDS>> {
191
189
  const proofAndVk = await this.createAvmProof(inputs);
192
- await this.verifyAvmProof(proofAndVk.proof.binaryProof, proofAndVk.verificationKey, inputs.publicInputs);
193
-
194
- // TODO(#14234)[Unconditional PIs validation]: remove next lines and directly return proofAndVk
195
- proofAndVk.proof.proof = enhanceProofWithPiValidationFlag(proofAndVk.proof.proof, skipPublicInputsValidation);
190
+ await this.verifyAvmProof(proofAndVk.proof.binaryProof, proofAndVk.verificationKey);
196
191
  return proofAndVk;
197
192
  }
198
193
 
@@ -541,13 +536,13 @@ export class BBNativeRollupProver implements ServerCircuitProver {
541
536
 
542
537
  private async createAvmProof(
543
538
  input: AvmCircuitInputs,
544
- ): Promise<ProofAndVerificationKey<typeof AVM_V2_PROOF_LENGTH_IN_FIELDS_PADDED>> {
539
+ ): Promise<ProofAndVerificationKey<typeof AVM_PROOF_LENGTH_IN_FIELDS>> {
545
540
  const operation = async (bbWorkingDirectory: string) => {
546
541
  const provingResult = await this.generateAvmProofWithBB(input, bbWorkingDirectory);
547
542
 
548
543
  // TODO(https://github.com/AztecProtocol/aztec-packages/issues/6773): this VK data format is wrong.
549
544
  // In particular, the number of public inputs, etc will be wrong.
550
- const verificationKey = await extractAvmVkData(provingResult.vkDirectoryPath!);
545
+ const verificationKey = await extractAvmVkData(provingResult.vkPath!);
551
546
  const avmProof = await this.readAvmProofAsFields(provingResult.proofPath!, verificationKey);
552
547
 
553
548
  const circuitType = 'avm-circuit' as const;
@@ -584,7 +579,7 @@ export class BBNativeRollupProver implements ServerCircuitProver {
584
579
 
585
580
  // Read the proof as fields
586
581
  // TODO(AD): this is the only remaining use of extractVkData.
587
- const tubeVK = await extractVkData(provingResult.vkDirectoryPath!);
582
+ const tubeVK = await extractVkData(provingResult.vkPath!);
588
583
  const tubeProof = await readProofAsFields(provingResult.proofPath!, tubeVK, TUBE_PROOF_LENGTH, logger);
589
584
 
590
585
  this.instrumentation.recordDuration('provingDuration', 'tubeCircuit', provingResult.durationMs);
@@ -678,13 +673,9 @@ export class BBNativeRollupProver implements ServerCircuitProver {
678
673
  return await this.verifyWithKey(getUltraHonkFlavorForCircuit(circuitType), verificationKey, proof);
679
674
  }
680
675
 
681
- public async verifyAvmProof(
682
- proof: Proof,
683
- verificationKey: VerificationKeyData,
684
- publicInputs: AvmCircuitPublicInputs,
685
- ) {
676
+ public async verifyAvmProof(proof: Proof, verificationKey: VerificationKeyData) {
686
677
  return await this.verifyWithKeyInternal(proof, verificationKey, (proofPath, vkPath) =>
687
- verifyAvmProof(this.config.bbBinaryPath, this.config.bbWorkingDirectory, proofPath, publicInputs, vkPath, logger),
678
+ verifyAvmProof(this.config.bbBinaryPath, proofPath, vkPath, logger),
688
679
  );
689
680
  }
690
681
 
@@ -737,25 +728,16 @@ export class BBNativeRollupProver implements ServerCircuitProver {
737
728
  private async readAvmProofAsFields(
738
729
  proofFilename: string,
739
730
  vkData: VerificationKeyData,
740
- ): Promise<RecursiveProof<typeof AVM_V2_PROOF_LENGTH_IN_FIELDS_PADDED>> {
741
- const rawProofBuffer = await fs.readFile(proofFilename);
742
- const reader = BufferReader.asReader(rawProofBuffer);
743
- const proofFields = reader.readArray(rawProofBuffer.length / Fr.SIZE_IN_BYTES, Fr);
744
-
745
- // We extend to a fixed-size padded proof as during development any new AVM circuit column changes the
746
- // proof length and we do not have a mechanism to feedback a cpp constant to noir/TS.
747
- // TODO(#13390): Revive a non-padded AVM proof
748
- if (proofFields.length > AVM_V2_PROOF_LENGTH_IN_FIELDS_PADDED) {
749
- throw new Error(
750
- `Proof has ${proofFields.length} fields, expected no more than ${AVM_V2_PROOF_LENGTH_IN_FIELDS_PADDED}.`,
751
- );
752
- }
753
- const proofFieldsPadded = proofFields.concat(
754
- Array(AVM_V2_PROOF_LENGTH_IN_FIELDS_PADDED - proofFields.length).fill(new Fr(0)),
755
- );
731
+ ): Promise<RecursiveProof<typeof AVM_PROOF_LENGTH_IN_FIELDS>> {
732
+ const rawProof = await fs.readFile(proofFilename);
733
+
734
+ const reader = BufferReader.asReader(rawProof);
735
+ const fields = reader.readArray(rawProof.length / Fr.SIZE_IN_BYTES, Fr);
736
+ const fieldsWithoutPublicCols = fields.slice(-1 * AVM_PROOF_LENGTH_IN_FIELDS);
737
+
738
+ const proof = new Proof(rawProof, vkData.numPublicInputs);
756
739
 
757
- const proof = new Proof(rawProofBuffer, vkData.numPublicInputs);
758
- return new RecursiveProof(proofFieldsPadded, proof, true, AVM_V2_PROOF_LENGTH_IN_FIELDS_PADDED);
740
+ return new RecursiveProof(fieldsWithoutPublicCols, proof, true, AVM_PROOF_LENGTH_IN_FIELDS);
759
741
  }
760
742
 
761
743
  private runInDirectory<T>(fn: (dir: string) => Promise<T>) {