@aztec/bb-prover 4.0.0-nightly.20250907 → 4.0.0-nightly.20260107

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 (93) hide show
  1. package/dest/avm_proving_tests/avm_proving_tester.d.ts +7 -6
  2. package/dest/avm_proving_tests/avm_proving_tester.d.ts.map +1 -1
  3. package/dest/avm_proving_tests/avm_proving_tester.js +33 -13
  4. package/dest/bb/cli.d.ts +1 -1
  5. package/dest/bb/execute.d.ts +5 -13
  6. package/dest/bb/execute.d.ts.map +1 -1
  7. package/dest/bb/execute.js +30 -92
  8. package/dest/bb/index.d.ts +1 -1
  9. package/dest/config.d.ts +1 -1
  10. package/dest/honk.d.ts +2 -2
  11. package/dest/honk.js +2 -2
  12. package/dest/index.d.ts +1 -1
  13. package/dest/instrumentation.d.ts +3 -3
  14. package/dest/instrumentation.d.ts.map +1 -1
  15. package/dest/prover/client/bb_private_kernel_prover.d.ts +12 -6
  16. package/dest/prover/client/bb_private_kernel_prover.d.ts.map +1 -1
  17. package/dest/prover/client/bb_private_kernel_prover.js +36 -7
  18. package/dest/prover/client/bundle.d.ts +6 -0
  19. package/dest/prover/client/bundle.d.ts.map +1 -0
  20. package/dest/prover/client/bundle.js +7 -0
  21. package/dest/prover/client/lazy.d.ts +6 -0
  22. package/dest/prover/client/lazy.d.ts.map +1 -0
  23. package/dest/prover/client/lazy.js +7 -0
  24. package/dest/prover/index.d.ts +1 -1
  25. package/dest/prover/proof_utils.d.ts +9 -9
  26. package/dest/prover/proof_utils.d.ts.map +1 -1
  27. package/dest/prover/proof_utils.js +42 -25
  28. package/dest/prover/server/bb_prover.d.ts +23 -43
  29. package/dest/prover/server/bb_prover.d.ts.map +1 -1
  30. package/dest/prover/server/bb_prover.js +464 -165
  31. package/dest/test/delay_values.d.ts +1 -1
  32. package/dest/test/delay_values.d.ts.map +1 -1
  33. package/dest/test/delay_values.js +37 -25
  34. package/dest/test/index.d.ts +2 -1
  35. package/dest/test/index.d.ts.map +1 -1
  36. package/dest/test/index.js +1 -0
  37. package/dest/test/test_circuit_prover.d.ts +21 -31
  38. package/dest/test/test_circuit_prover.d.ts.map +1 -1
  39. package/dest/test/test_circuit_prover.js +503 -81
  40. package/dest/test/test_verifier.d.ts +3 -1
  41. package/dest/test/test_verifier.d.ts.map +1 -1
  42. package/dest/test/test_verifier.js +15 -0
  43. package/dest/verification_key/verification_key_data.d.ts +1 -1
  44. package/dest/verification_key/verification_key_data.js +1 -1
  45. package/dest/verifier/bb_verifier.d.ts +3 -5
  46. package/dest/verifier/bb_verifier.d.ts.map +1 -1
  47. package/dest/verifier/bb_verifier.js +24 -26
  48. package/dest/verifier/index.d.ts +2 -2
  49. package/dest/verifier/index.d.ts.map +1 -1
  50. package/dest/verifier/index.js +1 -1
  51. package/dest/verifier/queued_chonk_verifier.d.ts +15 -0
  52. package/dest/verifier/queued_chonk_verifier.d.ts.map +1 -0
  53. package/dest/verifier/{queued_ivc_verifier.js → queued_chonk_verifier.js} +3 -3
  54. package/package.json +23 -23
  55. package/src/avm_proving_tests/avm_proving_tester.ts +43 -19
  56. package/src/bb/execute.ts +20 -90
  57. package/src/honk.ts +1 -1
  58. package/src/instrumentation.ts +2 -2
  59. package/src/prover/client/bb_private_kernel_prover.ts +49 -10
  60. package/src/prover/client/bundle.ts +10 -0
  61. package/src/prover/client/lazy.ts +10 -0
  62. package/src/prover/proof_utils.ts +53 -31
  63. package/src/prover/server/bb_prover.ts +231 -293
  64. package/src/test/delay_values.ts +38 -24
  65. package/src/test/index.ts +1 -0
  66. package/src/test/test_circuit_prover.ts +219 -142
  67. package/src/test/test_verifier.ts +8 -0
  68. package/src/verification_key/verification_key_data.ts +1 -1
  69. package/src/verifier/bb_verifier.ts +34 -33
  70. package/src/verifier/index.ts +1 -1
  71. package/src/verifier/{queued_ivc_verifier.ts → queued_chonk_verifier.ts} +3 -3
  72. package/dest/prover/client/native/bb_native_private_kernel_prover.d.ts +0 -23
  73. package/dest/prover/client/native/bb_native_private_kernel_prover.d.ts.map +0 -1
  74. package/dest/prover/client/native/bb_native_private_kernel_prover.js +0 -66
  75. package/dest/prover/client/wasm/bb_wasm_private_kernel_prover.d.ts +0 -15
  76. package/dest/prover/client/wasm/bb_wasm_private_kernel_prover.d.ts.map +0 -1
  77. package/dest/prover/client/wasm/bb_wasm_private_kernel_prover.js +0 -48
  78. package/dest/prover/client/wasm/bundle.d.ts +0 -6
  79. package/dest/prover/client/wasm/bundle.d.ts.map +0 -1
  80. package/dest/prover/client/wasm/bundle.js +0 -8
  81. package/dest/prover/client/wasm/lazy.d.ts +0 -6
  82. package/dest/prover/client/wasm/lazy.d.ts.map +0 -1
  83. package/dest/prover/client/wasm/lazy.js +0 -8
  84. package/dest/stats.d.ts +0 -4
  85. package/dest/stats.d.ts.map +0 -1
  86. package/dest/stats.js +0 -45
  87. package/dest/verifier/queued_ivc_verifier.d.ts +0 -15
  88. package/dest/verifier/queued_ivc_verifier.d.ts.map +0 -1
  89. package/src/prover/client/native/bb_native_private_kernel_prover.ts +0 -105
  90. package/src/prover/client/wasm/bb_wasm_private_kernel_prover.ts +0 -60
  91. package/src/prover/client/wasm/bundle.ts +0 -11
  92. package/src/prover/client/wasm/lazy.ts +0 -11
  93. package/src/stats.ts +0 -47
package/src/bb/execute.ts CHANGED
@@ -1,4 +1,4 @@
1
- import { sha256 } from '@aztec/foundation/crypto';
1
+ import { sha256 } from '@aztec/foundation/crypto/sha256';
2
2
  import type { LogFn, Logger } from '@aztec/foundation/log';
3
3
  import { Timer } from '@aztec/foundation/timer';
4
4
  import type { AvmCircuitInputs, AvmCircuitPublicInputs } from '@aztec/stdlib/avm';
@@ -6,6 +6,7 @@ import type { AvmCircuitInputs, AvmCircuitPublicInputs } from '@aztec/stdlib/avm
6
6
  import * as proc from 'child_process';
7
7
  import { promises as fs } from 'fs';
8
8
  import { basename, dirname, join } from 'path';
9
+ import readline from 'readline';
9
10
 
10
11
  import type { UltraHonkFlavor } from '../honk.js';
11
12
 
@@ -15,7 +16,6 @@ export const PROOF_FILENAME = 'proof';
15
16
  export const AVM_INPUTS_FILENAME = 'avm_inputs.bin';
16
17
  export const AVM_BYTECODE_FILENAME = 'avm_bytecode.bin';
17
18
  export const AVM_PUBLIC_INPUTS_FILENAME = 'avm_public_inputs.bin';
18
- export const CLIENT_IVC_PROOF_FILE_NAME = 'proof';
19
19
 
20
20
  export enum BB_RESULT {
21
21
  SUCCESS,
@@ -86,6 +86,7 @@ export function executeBB(
86
86
  logger(`BB concurrency: ${env.HARDWARE_CONCURRENCY}`);
87
87
  logger(`Executing BB with: ${pathToBB} ${command} ${args.join(' ')}`);
88
88
  const bb = proc.spawn(pathToBB, [command, ...args], {
89
+ stdio: ['ignore', 'pipe', 'pipe'],
89
90
  env,
90
91
  });
91
92
 
@@ -100,14 +101,9 @@ export function executeBB(
100
101
  }, timeout);
101
102
  }
102
103
 
103
- bb.stdout.on('data', data => {
104
- const message = data.toString('utf-8').replace(/\n$/, '');
105
- logger(message);
106
- });
107
- bb.stderr.on('data', data => {
108
- const message = data.toString('utf-8').replace(/\n$/, '');
109
- logger(message);
110
- });
104
+ readline.createInterface({ input: bb.stdout }).on('line', logger);
105
+ readline.createInterface({ input: bb.stderr }).on('line', logger);
106
+
111
107
  bb.on('close', (exitCode: number, signal?: string) => {
112
108
  if (timeoutId) {
113
109
  clearTimeout(timeoutId);
@@ -121,7 +117,7 @@ export function executeBB(
121
117
  }).catch(_ => ({ status: BB_RESULT.FAILURE, exitCode: -1, signal: undefined }));
122
118
  }
123
119
 
124
- export async function executeBbClientIvcProof(
120
+ export async function executeBbChonkProof(
125
121
  pathToBB: string,
126
122
  workingDirectory: string,
127
123
  inputsPath: string,
@@ -154,7 +150,7 @@ export async function executeBbClientIvcProof(
154
150
  log(`bb - ${message}`);
155
151
  };
156
152
 
157
- const args = ['-o', outputPath, '--ivc_inputs_path', inputsPath, '-v', '--scheme', 'client_ivc'];
153
+ const args = ['-o', outputPath, '--ivc_inputs_path', inputsPath, '-v', '--scheme', 'chonk'];
158
154
  if (writeVk) {
159
155
  args.push('--write_vk');
160
156
  }
@@ -214,6 +210,7 @@ export async function generateProof(
214
210
  workingDirectory: string,
215
211
  circuitName: string,
216
212
  bytecode: Buffer,
213
+ verificationKey: Buffer,
217
214
  inputWitnessFile: string,
218
215
  flavor: UltraHonkFlavor,
219
216
  log: Logger,
@@ -225,8 +222,9 @@ export async function generateProof(
225
222
  return { status: BB_RESULT.FAILURE, reason: `Working directory ${workingDirectory} does not exist` };
226
223
  }
227
224
 
228
- // The bytecode is written to e.g. /workingDirectory/BaseParityArtifact-bytecode
225
+ // The bytecode is written to e.g. /workingDirectory/ParityBaseArtifact-bytecode
229
226
  const bytecodePath = `${workingDirectory}/${circuitName}-bytecode`;
227
+ const vkPath = `${workingDirectory}/${circuitName}-vk`;
230
228
 
231
229
  // The proof is written to e.g. /workingDirectory/ultra_honk/proof
232
230
  const outputPath = `${workingDirectory}`;
@@ -240,16 +238,16 @@ export async function generateProof(
240
238
  }
241
239
 
242
240
  try {
243
- // Write the bytecode to the working directory
244
- await fs.writeFile(bytecodePath, bytecode);
245
- // TODO(#15043): Avoid write_vk flag here.
241
+ // Write the bytecode and vk to the working directory
242
+ await Promise.all([fs.writeFile(bytecodePath, bytecode), fs.writeFile(vkPath, verificationKey)]);
246
243
  const args = getArgs(flavor).concat([
247
244
  '--disable_zk',
248
- '--write_vk',
249
245
  '-o',
250
246
  outputPath,
251
247
  '-b',
252
248
  bytecodePath,
249
+ '-k',
250
+ vkPath,
253
251
  '-w',
254
252
  inputWitnessFile,
255
253
  '-v',
@@ -286,74 +284,6 @@ export async function generateProof(
286
284
  }
287
285
  }
288
286
 
289
- /**
290
- * Used for generating proofs of the tube circuit
291
- * It is assumed that the working directory is a temporary and/or random directory used solely for generating this proof.
292
- *
293
- * @returns An object containing a result indication, the location of the proof and the duration taken
294
- */
295
- export async function generateTubeProof(
296
- pathToBB: string,
297
- workingDirectory: string,
298
- vkPath: string,
299
- log: LogFn,
300
- ): Promise<BBFailure | BBSuccess> {
301
- // Check that the working directory exists
302
- try {
303
- await fs.access(workingDirectory);
304
- } catch {
305
- return { status: BB_RESULT.FAILURE, reason: `Working directory ${workingDirectory} does not exist` };
306
- }
307
-
308
- // Paths for the inputs
309
- const proofPath = join(workingDirectory, CLIENT_IVC_PROOF_FILE_NAME);
310
-
311
- // The proof is written to e.g. /workingDirectory/proof
312
- const outputPath = workingDirectory;
313
- const filePresent = async (file: string) =>
314
- await fs
315
- .access(file, fs.constants.R_OK)
316
- .then(_ => true)
317
- .catch(_ => false);
318
-
319
- const binaryPresent = await filePresent(pathToBB);
320
- if (!binaryPresent) {
321
- return { status: BB_RESULT.FAILURE, reason: `Failed to find bb binary at ${pathToBB}` };
322
- }
323
-
324
- try {
325
- if (!(await filePresent(proofPath))) {
326
- return { status: BB_RESULT.FAILURE, reason: `Client IVC input files not present in ${workingDirectory}` };
327
- }
328
- const args = ['-o', outputPath, '-k', vkPath, '-v'];
329
-
330
- const timer = new Timer();
331
- const logFunction = (message: string) => {
332
- log(`TubeCircuit (prove) BB out - ${message}`);
333
- };
334
- const result = await executeBB(pathToBB, 'prove_tube', args, logFunction);
335
- const durationMs = timer.ms();
336
-
337
- if (result.status == BB_RESULT.SUCCESS) {
338
- return {
339
- status: BB_RESULT.SUCCESS,
340
- durationMs,
341
- proofPath: outputPath,
342
- pkPath: undefined,
343
- vkDirectoryPath: outputPath,
344
- };
345
- }
346
- // Not a great error message here but it is difficult to decipher what comes from bb
347
- return {
348
- status: BB_RESULT.FAILURE,
349
- reason: `Failed to generate proof. Exit code ${result.exitCode}. Signal ${result.signal}.`,
350
- retry: !!result.signal,
351
- };
352
- } catch (error) {
353
- return { status: BB_RESULT.FAILURE, reason: `${error}` };
354
- }
355
- }
356
-
357
287
  /**
358
288
  * Used for generating AVM proofs.
359
289
  * It is assumed that the working directory is a temporary and/or random directory used solely for generating this proof.
@@ -491,7 +421,7 @@ export async function verifyAvmProof(
491
421
  }
492
422
 
493
423
  /**
494
- * Verifies a ClientIvcProof
424
+ * Verifies a ChonkProof
495
425
  * TODO(#7370) The verification keys should be supplied separately
496
426
  * @param pathToBB - The full path to the bb binary
497
427
  * @param targetPath - The path to the folder with the proof, accumulator, and verification keys
@@ -499,7 +429,7 @@ export async function verifyAvmProof(
499
429
  * @param concurrency - The number of threads to use for the verification
500
430
  * @returns An object containing a result indication and duration taken
501
431
  */
502
- export async function verifyClientIvcProof(
432
+ export async function verifyChonkProof(
503
433
  pathToBB: string,
504
434
  proofPath: string,
505
435
  keyPath: string,
@@ -515,7 +445,7 @@ export async function verifyClientIvcProof(
515
445
  }
516
446
 
517
447
  try {
518
- const args = ['--scheme', 'client_ivc', '-p', proofPath, '-k', keyPath, '-v'];
448
+ const args = ['--scheme', 'chonk', '-p', proofPath, '-k', keyPath, '-v'];
519
449
  const timer = new Timer();
520
450
  const command = 'verify';
521
451
 
@@ -679,7 +609,7 @@ export async function computeGateCountForCircuit(
679
609
  return { status: BB_RESULT.FAILURE, reason: `Working directory ${workingDirectory} does not exist` };
680
610
  }
681
611
 
682
- // The bytecode is written to e.g. /workingDirectory/BaseParityArtifact-bytecode
612
+ // The bytecode is written to e.g. /workingDirectory/ParityBaseArtifact-bytecode
683
613
  const bytecodePath = `${workingDirectory}/${circuitName}-bytecode`;
684
614
 
685
615
  const binaryPresent = await fs
@@ -705,7 +635,7 @@ export async function computeGateCountForCircuit(
705
635
  const result = await executeBB(
706
636
  pathToBB,
707
637
  'gates',
708
- ['--scheme', flavor === 'mega_honk' ? 'client_ivc' : 'ultra_honk', '-b', bytecodePath, '-v'],
638
+ ['--scheme', flavor === 'mega_honk' ? 'chonk' : 'ultra_honk', '-b', bytecodePath, '-v'],
709
639
  logHandler,
710
640
  );
711
641
  const duration = timer.ms();
package/src/honk.ts CHANGED
@@ -3,7 +3,7 @@ import type { ServerProtocolArtifact } from '@aztec/noir-protocol-circuits-types
3
3
  export type UltraHonkFlavor = 'ultra_honk' | 'ultra_keccak_honk' | 'ultra_starknet_honk' | 'ultra_rollup_honk';
4
4
 
5
5
  const UltraKeccakHonkCircuits = ['RootRollupArtifact'] as const satisfies ServerProtocolArtifact[];
6
- const UltraHonkCircuits = ['BaseParityArtifact', 'RootParityArtifact'] as const satisfies ServerProtocolArtifact[];
6
+ const UltraHonkCircuits = ['ParityBaseArtifact', 'ParityRootArtifact'] as const satisfies ServerProtocolArtifact[];
7
7
 
8
8
  export type UltraKeccakHonkServerProtocolArtifact = (typeof UltraKeccakHonkCircuits)[number];
9
9
  export type UltraHonkServerProtocolArtifact = (typeof UltraHonkCircuits)[number];
@@ -86,7 +86,7 @@ export class ProverInstrumentation {
86
86
  */
87
87
  recordDuration(
88
88
  metric: 'simulationDuration' | 'witGenDuration' | 'provingDuration',
89
- circuitName: CircuitName | 'tubeCircuit',
89
+ circuitName: CircuitName,
90
90
  timerOrMS: Timer | number,
91
91
  ) {
92
92
  const s = typeof timerOrMS === 'number' ? timerOrMS / 1000 : timerOrMS.s();
@@ -116,7 +116,7 @@ export class ProverInstrumentation {
116
116
  */
117
117
  recordSize(
118
118
  metric: 'witGenInputSize' | 'witGenOutputSize' | 'proofSize' | 'circuitSize' | 'circuitPublicInputCount',
119
- circuitName: CircuitName | 'tubeCircuit',
119
+ circuitName: CircuitName,
120
120
  size: number,
121
121
  ) {
122
122
  this[metric].record(Math.ceil(size), {
@@ -1,4 +1,7 @@
1
- import { createLogger } from '@aztec/foundation/log';
1
+ import { AztecClientBackend, type BackendOptions, Barretenberg } from '@aztec/bb.js';
2
+ import { type LogLevel, type Logger, createLogger } from '@aztec/foundation/log';
3
+ import { Timer } from '@aztec/foundation/timer';
4
+ import { serializeWitness } from '@aztec/noir-noirc_abi';
2
5
  import {
3
6
  convertHidingKernelPublicInputsToWitnessMapWithAbi,
4
7
  convertHidingKernelToRollupInputsToWitnessMapWithAbi,
@@ -16,7 +19,11 @@ import {
16
19
  getPrivateKernelResetArtifactName,
17
20
  updateResetCircuitSampleInputs,
18
21
  } from '@aztec/noir-protocol-circuits-types/client';
19
- import type { ArtifactProvider, ClientProtocolArtifact } from '@aztec/noir-protocol-circuits-types/types';
22
+ import {
23
+ type ArtifactProvider,
24
+ type ClientProtocolArtifact,
25
+ mapProtocolArtifactNameToCircuitName,
26
+ } from '@aztec/noir-protocol-circuits-types/types';
20
27
  import type { Abi, WitnessMap } from '@aztec/noir-types';
21
28
  import type { CircuitSimulator } from '@aztec/simulator/client';
22
29
  import type { PrivateKernelProver } from '@aztec/stdlib/interfaces/client';
@@ -33,17 +40,22 @@ import type {
33
40
  PrivateKernelTailCircuitPublicInputs,
34
41
  } from '@aztec/stdlib/kernel';
35
42
  import type { NoirCompiledCircuitWithName } from '@aztec/stdlib/noir';
36
- import type { ClientIvcProof } from '@aztec/stdlib/proofs';
43
+ import { ChonkProofWithPublicInputs } from '@aztec/stdlib/proofs';
37
44
  import type { CircuitSimulationStats, CircuitWitnessGenerationStats } from '@aztec/stdlib/stats';
38
45
 
39
- import { mapProtocolArtifactNameToCircuitName } from '../../stats.js';
46
+ import { ungzip } from 'pako';
40
47
 
48
+ export type BBPrivateKernelProverOptions = Omit<BackendOptions, 'logger'> & { logger?: Logger };
41
49
  export abstract class BBPrivateKernelProver implements PrivateKernelProver {
50
+ private log: Logger;
51
+
42
52
  constructor(
43
53
  protected artifactProvider: ArtifactProvider,
44
54
  protected simulator: CircuitSimulator,
45
- protected log = createLogger('bb-prover'),
46
- ) {}
55
+ protected options: BBPrivateKernelProverOptions = {},
56
+ ) {
57
+ this.log = options.logger || createLogger('bb-prover:private-kernel');
58
+ }
47
59
 
48
60
  public async generateInitOutput(
49
61
  inputs: PrivateKernelInitCircuitPrivateInputs,
@@ -261,11 +273,38 @@ export abstract class BBPrivateKernelProver implements PrivateKernelProver {
261
273
  return kernelProofOutput;
262
274
  }
263
275
 
264
- public createClientIvcProof(_executionSteps: PrivateExecutionStep[]): Promise<ClientIvcProof> {
265
- throw new Error('Not implemented');
276
+ public async createChonkProof(executionSteps: PrivateExecutionStep[]): Promise<ChonkProofWithPublicInputs> {
277
+ const timer = new Timer();
278
+ this.log.info(`Generating ClientIVC proof...`);
279
+ const barretenberg = await Barretenberg.initSingleton({
280
+ ...this.options,
281
+ logger: this.options.logger?.[(process.env.LOG_LEVEL as LogLevel) || 'verbose'],
282
+ });
283
+ const backend = new AztecClientBackend(
284
+ executionSteps.map(step => ungzip(step.bytecode)),
285
+ barretenberg,
286
+ );
287
+
288
+ const [proof] = await backend.prove(
289
+ executionSteps.map(step => ungzip(serializeWitness(step.witness))),
290
+ executionSteps.map(step => step.vk),
291
+ );
292
+ this.log.info(`Generated ClientIVC proof`, {
293
+ eventName: 'client-ivc-proof-generation',
294
+ duration: timer.ms(),
295
+ proofSize: proof.length,
296
+ });
297
+ return ChonkProofWithPublicInputs.fromBufferArray(proof);
266
298
  }
267
299
 
268
- public computeGateCountForCircuit(_bytecode: Buffer, _circuitName: string): Promise<number> {
269
- throw new Error('Not implemented');
300
+ public async computeGateCountForCircuit(_bytecode: Buffer, _circuitName: string): Promise<number> {
301
+ // Note we do not pass the vk to the backend. This is unneeded for gate counts.
302
+ const barretenberg = await Barretenberg.initSingleton({
303
+ ...this.options,
304
+ logger: this.options.logger?.[(process.env.LOG_LEVEL as LogLevel) || 'verbose'],
305
+ });
306
+ const backend = new AztecClientBackend([ungzip(_bytecode)], barretenberg);
307
+ const gateCount = await backend.gates();
308
+ return gateCount[0];
270
309
  }
271
310
  }
@@ -0,0 +1,10 @@
1
+ import { BundleArtifactProvider } from '@aztec/noir-protocol-circuits-types/client/bundle';
2
+ import type { CircuitSimulator } from '@aztec/simulator/client';
3
+
4
+ import { BBPrivateKernelProver, type BBPrivateKernelProverOptions } from './bb_private_kernel_prover.js';
5
+
6
+ export class BBBundlePrivateKernelProver extends BBPrivateKernelProver {
7
+ constructor(simulator: CircuitSimulator, options: BBPrivateKernelProverOptions = {}) {
8
+ super(new BundleArtifactProvider(), simulator, options);
9
+ }
10
+ }
@@ -0,0 +1,10 @@
1
+ import { LazyArtifactProvider } from '@aztec/noir-protocol-circuits-types/client/lazy';
2
+ import type { CircuitSimulator } from '@aztec/simulator/client';
3
+
4
+ import { BBPrivateKernelProver, type BBPrivateKernelProverOptions } from './bb_private_kernel_prover.js';
5
+
6
+ export class BBLazyPrivateKernelProver extends BBPrivateKernelProver {
7
+ constructor(simulator: CircuitSimulator, options: BBPrivateKernelProverOptions = {}) {
8
+ super(new LazyArtifactProvider(), simulator, options);
9
+ }
10
+ }
@@ -1,41 +1,59 @@
1
1
  import {
2
+ CHONK_PROOF_LENGTH,
3
+ HIDING_KERNEL_IO_PUBLIC_INPUTS_SIZE,
2
4
  IPA_CLAIM_SIZE,
3
5
  NESTED_RECURSIVE_PROOF_LENGTH,
4
6
  NESTED_RECURSIVE_ROLLUP_HONK_PROOF_LENGTH,
5
7
  PAIRING_POINTS_SIZE,
6
8
  ULTRA_KECCAK_PROOF_LENGTH,
7
9
  } from '@aztec/constants';
8
- import { Fr } from '@aztec/foundation/fields';
10
+ import { Fr } from '@aztec/foundation/curves/bn254';
9
11
  import type { Logger } from '@aztec/foundation/log';
10
- import { ClientIvcProof, Proof, RecursiveProof } from '@aztec/stdlib/proofs';
12
+ import { ChonkProofWithPublicInputs, Proof, RecursiveProof } from '@aztec/stdlib/proofs';
11
13
  import type { VerificationKeyData } from '@aztec/stdlib/vks';
12
14
 
13
15
  import assert from 'assert';
14
16
  import { promises as fs } from 'fs';
15
17
  import * as path from 'path';
16
18
 
17
- import { CLIENT_IVC_PROOF_FILE_NAME, PROOF_FILENAME, PUBLIC_INPUTS_FILENAME } from '../bb/execute.js';
19
+ import { PROOF_FILENAME, PUBLIC_INPUTS_FILENAME } from '../bb/execute.js';
18
20
 
19
21
  /**
20
- * Create a ClientIvcProof proof file.
22
+ * Create a ChonkProof proof file.
21
23
  *
22
24
  * @param directory the directory to read the proof from.
23
- * @returns the encapsulated client ivc proof
25
+ * @returns the encapsulated chonk proof
24
26
  */
25
- export async function readClientIVCProofFromOutputDirectory(directory: string) {
26
- const clientIvcProofBuffer = await fs.readFile(path.join(directory, CLIENT_IVC_PROOF_FILE_NAME));
27
- return new ClientIvcProof(clientIvcProofBuffer);
27
+ export async function readChonkProofFromOutputDirectory(directory: string) {
28
+ const proofFilename = path.join(directory, PROOF_FILENAME);
29
+ const binaryProof = await fs.readFile(proofFilename);
30
+ const proofFields = splitBufferIntoFields(binaryProof);
31
+ return new ChonkProofWithPublicInputs(proofFields);
28
32
  }
29
33
 
30
34
  /**
31
- * Serialize a ClientIvcProof to a proof file.
35
+ * Serialize a ChonkProof to a proof file.
32
36
  *
33
- * @param proof the ClientIvcProof from object
37
+ * @param proof the ChonkProof from object
34
38
  * @param directory the directory to write in
35
39
  */
36
- export async function writeClientIVCProofToOutputDirectory(clientIvcProof: ClientIvcProof, directory: string) {
37
- const { clientIvcProofBuffer } = clientIvcProof;
38
- await fs.writeFile(path.join(directory, CLIENT_IVC_PROOF_FILE_NAME), clientIvcProofBuffer);
40
+ export async function writeChonkProofToPath(chonkProof: ChonkProofWithPublicInputs, outputPath: string) {
41
+ // NB: Don't use chonkProof.toBuffer here because it will include the proof length.
42
+ const fieldsBuf = Buffer.concat(chonkProof.fieldsWithPublicInputs.map(field => field.toBuffer()));
43
+ await fs.writeFile(outputPath, fieldsBuf);
44
+ }
45
+
46
+ function getNumCustomPublicInputs(proofLength: number, vkData: VerificationKeyData) {
47
+ let numPublicInputs = vkData.numPublicInputs;
48
+ if (proofLength == CHONK_PROOF_LENGTH) {
49
+ numPublicInputs -= HIDING_KERNEL_IO_PUBLIC_INPUTS_SIZE;
50
+ } else {
51
+ numPublicInputs -= PAIRING_POINTS_SIZE;
52
+ if (proofLength == NESTED_RECURSIVE_ROLLUP_HONK_PROOF_LENGTH) {
53
+ numPublicInputs -= IPA_CLAIM_SIZE;
54
+ }
55
+ }
56
+ return numPublicInputs;
39
57
  }
40
58
 
41
59
  function splitBufferIntoFields(buffer: Buffer): Fr[] {
@@ -46,43 +64,47 @@ function splitBufferIntoFields(buffer: Buffer): Fr[] {
46
64
  return fields;
47
65
  }
48
66
 
49
- export async function readProofAsFields<PROOF_LENGTH extends number>(
50
- filePath: string,
67
+ export async function readProofsFromOutputDirectory<PROOF_LENGTH extends number>(
68
+ directory: string,
51
69
  vkData: VerificationKeyData,
52
70
  proofLength: PROOF_LENGTH,
53
71
  logger: Logger,
54
72
  ): Promise<RecursiveProof<PROOF_LENGTH>> {
55
- const publicInputsFilename = path.join(filePath, PUBLIC_INPUTS_FILENAME);
56
- const proofFilename = path.join(filePath, PROOF_FILENAME);
57
-
58
- const [binaryPublicInputs, binaryProof] = await Promise.all([
59
- fs.readFile(publicInputsFilename),
60
- fs.readFile(proofFilename),
61
- ]);
62
-
63
- const fieldsWithoutPublicInputs = splitBufferIntoFields(binaryProof);
64
-
65
- let numPublicInputs = vkData.numPublicInputs - PAIRING_POINTS_SIZE;
66
73
  assert(
67
- proofLength == NESTED_RECURSIVE_PROOF_LENGTH ||
74
+ proofLength == CHONK_PROOF_LENGTH ||
75
+ proofLength == NESTED_RECURSIVE_PROOF_LENGTH ||
68
76
  proofLength == NESTED_RECURSIVE_ROLLUP_HONK_PROOF_LENGTH ||
69
77
  proofLength == ULTRA_KECCAK_PROOF_LENGTH,
70
78
  `Proof length must be one of the expected proof lengths, received ${proofLength}`,
71
79
  );
72
- if (proofLength == NESTED_RECURSIVE_ROLLUP_HONK_PROOF_LENGTH) {
73
- numPublicInputs -= IPA_CLAIM_SIZE;
80
+
81
+ const publicInputsFilename = path.join(directory, PUBLIC_INPUTS_FILENAME);
82
+ const proofFilename = path.join(directory, PROOF_FILENAME);
83
+
84
+ // Handle CHONK separately because bb outputs the proof fields with public inputs for CHONK.
85
+ const isChonk = proofLength == CHONK_PROOF_LENGTH;
86
+
87
+ const [binaryPublicInputs, binaryProof] = await Promise.all([
88
+ isChonk ? Buffer.alloc(0) : fs.readFile(publicInputsFilename),
89
+ fs.readFile(proofFilename),
90
+ ]);
91
+
92
+ const numPublicInputs = getNumCustomPublicInputs(proofLength, vkData);
93
+ let fieldsWithoutPublicInputs = splitBufferIntoFields(binaryProof);
94
+ if (isChonk) {
95
+ fieldsWithoutPublicInputs = fieldsWithoutPublicInputs.slice(numPublicInputs);
74
96
  }
75
97
 
76
98
  assert(
77
99
  fieldsWithoutPublicInputs.length == proofLength,
78
- `Proof length mismatch: ${fieldsWithoutPublicInputs.length} != ${proofLength}`,
100
+ `Proof fields length mismatch: ${fieldsWithoutPublicInputs.length} != ${proofLength}`,
79
101
  );
80
102
 
81
103
  // Concat binary public inputs and binary proof
82
104
  // This buffer will have the form: [binary public inputs, binary proof]
83
105
  const binaryProofWithPublicInputs = Buffer.concat([binaryPublicInputs, binaryProof]);
84
106
  logger.debug(
85
- `Circuit path: ${filePath}, complete proof length: ${fieldsWithoutPublicInputs.length}, num public inputs: ${numPublicInputs}, circuit size: ${vkData.circuitSize}`,
107
+ `Circuit path: ${directory}, proof fields length: ${fieldsWithoutPublicInputs.length}, num public inputs: ${numPublicInputs}, circuit size: ${vkData.circuitSize}`,
86
108
  );
87
109
  return new RecursiveProof(
88
110
  fieldsWithoutPublicInputs,