@aztec/bb-prover 0.0.0-test.1 → 0.0.1-commit.21caa21

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 (109) hide show
  1. package/dest/avm_proving_tests/avm_proving_tester.d.ts +14 -18
  2. package/dest/avm_proving_tests/avm_proving_tester.d.ts.map +1 -1
  3. package/dest/avm_proving_tests/avm_proving_tester.js +130 -79
  4. package/dest/bb/cli.d.ts +1 -1
  5. package/dest/bb/execute.d.ts +14 -47
  6. package/dest/bb/execute.d.ts.map +1 -1
  7. package/dest/bb/execute.js +132 -236
  8. package/dest/bb/index.d.ts +1 -1
  9. package/dest/config.d.ts +3 -1
  10. package/dest/config.d.ts.map +1 -1
  11. package/dest/honk.d.ts +3 -3
  12. package/dest/honk.d.ts.map +1 -1
  13. package/dest/honk.js +3 -2
  14. package/dest/index.d.ts +2 -1
  15. package/dest/index.d.ts.map +1 -1
  16. package/dest/index.js +1 -0
  17. package/dest/instrumentation.d.ts +3 -3
  18. package/dest/instrumentation.d.ts.map +1 -1
  19. package/dest/instrumentation.js +2 -4
  20. package/dest/prover/client/bb_private_kernel_prover.d.ts +32 -0
  21. package/dest/prover/client/bb_private_kernel_prover.d.ts.map +1 -0
  22. package/dest/prover/{bb_private_kernel_prover.js → client/bb_private_kernel_prover.js} +42 -20
  23. package/dest/prover/client/bundle.d.ts +6 -0
  24. package/dest/prover/client/bundle.d.ts.map +1 -0
  25. package/dest/prover/client/bundle.js +8 -0
  26. package/dest/prover/client/lazy.d.ts +6 -0
  27. package/dest/prover/client/lazy.d.ts.map +1 -0
  28. package/dest/prover/client/lazy.js +8 -0
  29. package/dest/prover/index.d.ts +3 -4
  30. package/dest/prover/index.d.ts.map +1 -1
  31. package/dest/prover/index.js +2 -3
  32. package/dest/prover/proof_utils.d.ts +19 -0
  33. package/dest/prover/proof_utils.d.ts.map +1 -0
  34. package/dest/prover/proof_utils.js +72 -0
  35. package/dest/prover/server/bb_prover.d.ts +100 -0
  36. package/dest/prover/server/bb_prover.d.ts.map +1 -0
  37. package/dest/prover/server/bb_prover.js +339 -0
  38. package/dest/test/delay_values.d.ts +1 -1
  39. package/dest/test/delay_values.d.ts.map +1 -1
  40. package/dest/test/delay_values.js +33 -21
  41. package/dest/test/index.d.ts +1 -1
  42. package/dest/test/test_circuit_prover.d.ts +25 -34
  43. package/dest/test/test_circuit_prover.d.ts.map +1 -1
  44. package/dest/test/test_circuit_prover.js +85 -59
  45. package/dest/test/test_verifier.d.ts +6 -3
  46. package/dest/test/test_verifier.d.ts.map +1 -1
  47. package/dest/test/test_verifier.js +23 -1
  48. package/dest/verification_key/verification_key_data.d.ts +7 -1
  49. package/dest/verification_key/verification_key_data.d.ts.map +1 -1
  50. package/dest/verification_key/verification_key_data.js +23 -29
  51. package/dest/verifier/bb_verifier.d.ts +6 -5
  52. package/dest/verifier/bb_verifier.d.ts.map +1 -1
  53. package/dest/verifier/bb_verifier.js +46 -25
  54. package/dest/verifier/index.d.ts +2 -1
  55. package/dest/verifier/index.d.ts.map +1 -1
  56. package/dest/verifier/index.js +1 -0
  57. package/dest/verifier/queued_chonk_verifier.d.ts +15 -0
  58. package/dest/verifier/queued_chonk_verifier.d.ts.map +1 -0
  59. package/dest/verifier/queued_chonk_verifier.js +132 -0
  60. package/package.json +35 -33
  61. package/src/avm_proving_tests/avm_proving_tester.ts +210 -104
  62. package/src/bb/execute.ts +103 -250
  63. package/src/config.ts +2 -0
  64. package/src/honk.ts +3 -2
  65. package/src/index.ts +1 -0
  66. package/src/instrumentation.ts +2 -4
  67. package/src/prover/{bb_private_kernel_prover.ts → client/bb_private_kernel_prover.ts} +78 -30
  68. package/src/prover/client/bundle.ts +11 -0
  69. package/src/prover/client/lazy.ts +11 -0
  70. package/src/prover/index.ts +2 -3
  71. package/src/prover/proof_utils.ts +115 -0
  72. package/src/prover/server/bb_prover.ts +733 -0
  73. package/src/test/delay_values.ts +33 -21
  74. package/src/test/test_circuit_prover.ts +260 -147
  75. package/src/test/test_verifier.ts +15 -3
  76. package/src/verification_key/verification_key_data.ts +29 -24
  77. package/src/verifier/bb_verifier.ts +63 -32
  78. package/src/verifier/index.ts +1 -0
  79. package/src/verifier/queued_chonk_verifier.ts +140 -0
  80. package/dest/prover/bb_native_private_kernel_prover.d.ts +0 -25
  81. package/dest/prover/bb_native_private_kernel_prover.d.ts.map +0 -1
  82. package/dest/prover/bb_native_private_kernel_prover.js +0 -69
  83. package/dest/prover/bb_private_kernel_prover.d.ts +0 -32
  84. package/dest/prover/bb_private_kernel_prover.d.ts.map +0 -1
  85. package/dest/prover/bb_prover.d.ts +0 -120
  86. package/dest/prover/bb_prover.d.ts.map +0 -1
  87. package/dest/prover/bb_prover.js +0 -423
  88. package/dest/prover/client_ivc_proof_utils.d.ts +0 -25
  89. package/dest/prover/client_ivc_proof_utils.d.ts.map +0 -1
  90. package/dest/prover/client_ivc_proof_utils.js +0 -43
  91. package/dest/stats.d.ts +0 -5
  92. package/dest/stats.d.ts.map +0 -1
  93. package/dest/stats.js +0 -62
  94. package/dest/wasm/bb_wasm_private_kernel_prover.d.ts +0 -17
  95. package/dest/wasm/bb_wasm_private_kernel_prover.d.ts.map +0 -1
  96. package/dest/wasm/bb_wasm_private_kernel_prover.js +0 -46
  97. package/dest/wasm/bundle.d.ts +0 -6
  98. package/dest/wasm/bundle.d.ts.map +0 -1
  99. package/dest/wasm/bundle.js +0 -8
  100. package/dest/wasm/lazy.d.ts +0 -6
  101. package/dest/wasm/lazy.d.ts.map +0 -1
  102. package/dest/wasm/lazy.js +0 -8
  103. package/src/prover/bb_native_private_kernel_prover.ts +0 -119
  104. package/src/prover/bb_prover.ts +0 -781
  105. package/src/prover/client_ivc_proof_utils.ts +0 -42
  106. package/src/stats.ts +0 -64
  107. package/src/wasm/bb_wasm_private_kernel_prover.ts +0 -55
  108. package/src/wasm/bundle.ts +0 -11
  109. package/src/wasm/lazy.ts +0 -11
package/src/bb/execute.ts CHANGED
@@ -6,18 +6,16 @@ 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
- import { CLIENT_IVC_PROOF_FILE_NAME, CLIENT_IVC_VK_FILE_NAME } from '../prover/client_ivc_proof_utils.js';
12
12
 
13
13
  export const VK_FILENAME = 'vk';
14
- export const VK_FIELDS_FILENAME = 'vk_fields.json';
14
+ export const PUBLIC_INPUTS_FILENAME = 'public_inputs';
15
15
  export const PROOF_FILENAME = 'proof';
16
- export const PROOF_FIELDS_FILENAME = 'proof_fields.json';
17
16
  export const AVM_INPUTS_FILENAME = 'avm_inputs.bin';
18
17
  export const AVM_BYTECODE_FILENAME = 'avm_bytecode.bin';
19
18
  export const AVM_PUBLIC_INPUTS_FILENAME = 'avm_public_inputs.bin';
20
- export const AVM_HINTS_FILENAME = 'avm_hints.bin';
21
19
 
22
20
  export enum BB_RESULT {
23
21
  SUCCESS,
@@ -31,7 +29,7 @@ export type BBSuccess = {
31
29
  /** Full path of the public key. */
32
30
  pkPath?: string;
33
31
  /** Base directory for the VKs (raw, fields). */
34
- vkPath?: string;
32
+ vkDirectoryPath?: string;
35
33
  /** Full path of the proof. */
36
34
  proofPath?: string;
37
35
  /** Full path of the contract. */
@@ -48,8 +46,6 @@ export type BBFailure = {
48
46
 
49
47
  export type BBResult = BBSuccess | BBFailure;
50
48
 
51
- export type VerificationFunction = typeof verifyProof | typeof verifyAvmProof;
52
-
53
49
  type BBExecResult = {
54
50
  status: BB_RESULT;
55
51
  exitCode: number;
@@ -62,6 +58,7 @@ type BBExecResult = {
62
58
  * @param command - The command to execute
63
59
  * @param args - The arguments to pass
64
60
  * @param logger - A log function
61
+ * @param timeout - An optional timeout before killing the BB process
65
62
  * @param resultParser - An optional handler for detecting success or failure
66
63
  * @returns The completed partial witness outputted from the circuit
67
64
  */
@@ -70,25 +67,47 @@ export function executeBB(
70
67
  command: string,
71
68
  args: string[],
72
69
  logger: LogFn,
70
+ concurrency?: number,
71
+ timeout?: number,
73
72
  resultParser = (code: number) => code === 0,
74
73
  ): Promise<BBExecResult> {
75
74
  return new Promise<BBExecResult>(resolve => {
76
75
  // spawn the bb process
77
76
  const { HARDWARE_CONCURRENCY: _, ...envWithoutConcurrency } = process.env;
78
- const env = process.env.HARDWARE_CONCURRENCY ? process.env : envWithoutConcurrency;
77
+
78
+ const env = envWithoutConcurrency;
79
+ // We prioritise the concurrency argument if provided and > 0
80
+ if (concurrency && concurrency > 0) {
81
+ env.HARDWARE_CONCURRENCY = concurrency.toString();
82
+ } else if (process.env.HARDWARE_CONCURRENCY) {
83
+ env.HARDWARE_CONCURRENCY = process.env.HARDWARE_CONCURRENCY;
84
+ }
85
+
86
+ logger(`BB concurrency: ${env.HARDWARE_CONCURRENCY}`);
79
87
  logger(`Executing BB with: ${pathToBB} ${command} ${args.join(' ')}`);
80
88
  const bb = proc.spawn(pathToBB, [command, ...args], {
89
+ stdio: ['ignore', 'pipe', 'pipe'],
81
90
  env,
82
91
  });
83
- bb.stdout.on('data', data => {
84
- const message = data.toString('utf-8').replace(/\n$/, '');
85
- logger(message);
86
- });
87
- bb.stderr.on('data', data => {
88
- const message = data.toString('utf-8').replace(/\n$/, '');
89
- logger(message);
90
- });
92
+
93
+ let timeoutId: NodeJS.Timeout | undefined;
94
+ if (timeout !== undefined) {
95
+ timeoutId = setTimeout(() => {
96
+ logger(`BB execution timed out after ${timeout}ms, killing process`);
97
+ if (bb.pid) {
98
+ bb.kill('SIGKILL');
99
+ }
100
+ resolve({ status: BB_RESULT.FAILURE, exitCode: -1, signal: 'TIMEOUT' });
101
+ }, timeout);
102
+ }
103
+
104
+ readline.createInterface({ input: bb.stdout }).on('line', logger);
105
+ readline.createInterface({ input: bb.stderr }).on('line', logger);
106
+
91
107
  bb.on('close', (exitCode: number, signal?: string) => {
108
+ if (timeoutId) {
109
+ clearTimeout(timeoutId);
110
+ }
92
111
  if (resultParser(exitCode)) {
93
112
  resolve({ status: BB_RESULT.SUCCESS, exitCode, signal });
94
113
  } else {
@@ -98,18 +117,17 @@ export function executeBB(
98
117
  }).catch(_ => ({ status: BB_RESULT.FAILURE, exitCode: -1, signal: undefined }));
99
118
  }
100
119
 
101
- // TODO(#7369) comment this etc (really just take inspiration from this and rewrite it all O:))
102
- export async function executeBbClientIvcProof(
120
+ export async function executeBbChonkProof(
103
121
  pathToBB: string,
104
122
  workingDirectory: string,
105
- bytecodeStackPath: string,
106
- witnessStackPath: string,
123
+ inputsPath: string,
107
124
  log: LogFn,
125
+ writeVk = false,
108
126
  ): Promise<BBFailure | BBSuccess> {
109
127
  // Check that the working directory exists
110
128
  try {
111
129
  await fs.access(workingDirectory);
112
- } catch (error) {
130
+ } catch {
113
131
  return { status: BB_RESULT.FAILURE, reason: `Working directory ${workingDirectory} does not exist` };
114
132
  }
115
133
 
@@ -126,28 +144,16 @@ export async function executeBbClientIvcProof(
126
144
 
127
145
  try {
128
146
  // Write the bytecode to the working directory
129
- log(`bytecodePath ${bytecodeStackPath}`);
130
- log(`outputPath ${outputPath}`);
131
- const args = [
132
- '-o',
133
- outputPath,
134
- '-b',
135
- bytecodeStackPath,
136
- '-w',
137
- witnessStackPath,
138
- '-v',
139
- '--scheme',
140
- 'client_ivc',
141
- '--input_type',
142
- 'runtime_stack',
143
- '--write_vk',
144
- ];
145
-
147
+ log(`inputsPath ${inputsPath}`);
146
148
  const timer = new Timer();
147
149
  const logFunction = (message: string) => {
148
150
  log(`bb - ${message}`);
149
151
  };
150
152
 
153
+ const args = ['-o', outputPath, '--ivc_inputs_path', inputsPath, '-v', '--scheme', 'chonk'];
154
+ if (writeVk) {
155
+ args.push('--write_vk');
156
+ }
151
157
  const result = await executeBB(pathToBB, 'prove', args, logFunction);
152
158
  const durationMs = timer.ms();
153
159
 
@@ -157,7 +163,7 @@ export async function executeBbClientIvcProof(
157
163
  durationMs,
158
164
  proofPath: `${outputPath}`,
159
165
  pkPath: undefined,
160
- vkPath: `${outputPath}`,
166
+ vkDirectoryPath: `${outputPath}`,
161
167
  };
162
168
  }
163
169
  // Not a great error message here but it is difficult to decipher what comes from bb
@@ -179,6 +185,9 @@ function getArgs(flavor: UltraHonkFlavor) {
179
185
  case 'ultra_keccak_honk': {
180
186
  return ['--scheme', 'ultra_honk', '--oracle_hash', 'keccak'];
181
187
  }
188
+ case 'ultra_starknet_honk': {
189
+ return ['--scheme', 'ultra_honk', '--oracle_hash', 'starknet'];
190
+ }
182
191
  case 'ultra_rollup_honk': {
183
192
  return ['--scheme', 'ultra_honk', '--oracle_hash', 'poseidon2', '--ipa_accumulation'];
184
193
  }
@@ -201,20 +210,21 @@ export async function generateProof(
201
210
  workingDirectory: string,
202
211
  circuitName: string,
203
212
  bytecode: Buffer,
204
- recursive: boolean,
213
+ verificationKey: Buffer,
205
214
  inputWitnessFile: string,
206
215
  flavor: UltraHonkFlavor,
207
- log: LogFn,
216
+ log: Logger,
208
217
  ): Promise<BBFailure | BBSuccess> {
209
218
  // Check that the working directory exists
210
219
  try {
211
220
  await fs.access(workingDirectory);
212
- } catch (error) {
221
+ } catch {
213
222
  return { status: BB_RESULT.FAILURE, reason: `Working directory ${workingDirectory} does not exist` };
214
223
  }
215
224
 
216
- // The bytecode is written to e.g. /workingDirectory/BaseParityArtifact-bytecode
225
+ // The bytecode is written to e.g. /workingDirectory/ParityBaseArtifact-bytecode
217
226
  const bytecodePath = `${workingDirectory}/${circuitName}-bytecode`;
227
+ const vkPath = `${workingDirectory}/${circuitName}-vk`;
218
228
 
219
229
  // The proof is written to e.g. /workingDirectory/ultra_honk/proof
220
230
  const outputPath = `${workingDirectory}`;
@@ -228,26 +238,28 @@ export async function generateProof(
228
238
  }
229
239
 
230
240
  try {
231
- // Write the bytecode to the working directory
232
- await fs.writeFile(bytecodePath, bytecode);
241
+ // Write the bytecode and vk to the working directory
242
+ await Promise.all([fs.writeFile(bytecodePath, bytecode), fs.writeFile(vkPath, verificationKey)]);
233
243
  const args = getArgs(flavor).concat([
234
- '--output_format',
235
- 'bytes_and_fields',
236
- '--write_vk',
244
+ '--disable_zk',
237
245
  '-o',
238
246
  outputPath,
239
247
  '-b',
240
248
  bytecodePath,
249
+ '-k',
250
+ vkPath,
241
251
  '-w',
242
252
  inputWitnessFile,
243
253
  '-v',
244
254
  ]);
245
- if (recursive) {
246
- args.push('--init_kzg_accumulator');
255
+ const loggingArg = log.level === 'debug' || log.level === 'trace' ? '-d' : log.level === 'verbose' ? '-v' : '';
256
+ if (loggingArg !== '') {
257
+ args.push(loggingArg);
247
258
  }
259
+
248
260
  const timer = new Timer();
249
261
  const logFunction = (message: string) => {
250
- log(`${circuitName} BB out - ${message}`);
262
+ log.info(`${circuitName} BB out - ${message}`);
251
263
  };
252
264
  const result = await executeBB(pathToBB, `prove`, args, logFunction);
253
265
  const duration = timer.ms();
@@ -258,80 +270,7 @@ export async function generateProof(
258
270
  durationMs: duration,
259
271
  proofPath: `${outputPath}`,
260
272
  pkPath: undefined,
261
- vkPath: `${outputPath}`,
262
- };
263
- }
264
- // Not a great error message here but it is difficult to decipher what comes from bb
265
- return {
266
- status: BB_RESULT.FAILURE,
267
- reason: `Failed to generate proof. Exit code ${result.exitCode}. Signal ${result.signal}.`,
268
- retry: !!result.signal,
269
- };
270
- } catch (error) {
271
- return { status: BB_RESULT.FAILURE, reason: `${error}` };
272
- }
273
- }
274
-
275
- /**
276
- * Used for generating proofs of the tube circuit
277
- * It is assumed that the working directory is a temporary and/or random directory used solely for generating this proof.
278
- * @param pathToBB - The full path to the bb binary
279
- * @param workingDirectory - A working directory for use by bb
280
- * @param circuitName - An identifier for the circuit
281
- * @param bytecode - The compiled circuit bytecode
282
- * @param inputWitnessFile - The circuit input witness
283
- * @param log - A logging function
284
- * @returns An object containing a result indication, the location of the proof and the duration taken
285
- */
286
- export async function generateTubeProof(
287
- pathToBB: string,
288
- workingDirectory: string,
289
- log: LogFn,
290
- ): Promise<BBFailure | BBSuccess> {
291
- // Check that the working directory exists
292
- try {
293
- await fs.access(workingDirectory);
294
- } catch (error) {
295
- return { status: BB_RESULT.FAILURE, reason: `Working directory ${workingDirectory} does not exist` };
296
- }
297
-
298
- // // Paths for the inputs
299
- const vkPath = join(workingDirectory, CLIENT_IVC_VK_FILE_NAME);
300
- const proofPath = join(workingDirectory, CLIENT_IVC_PROOF_FILE_NAME);
301
-
302
- // The proof is written to e.g. /workingDirectory/proof
303
- const outputPath = workingDirectory;
304
- const filePresent = async (file: string) =>
305
- await fs
306
- .access(file, fs.constants.R_OK)
307
- .then(_ => true)
308
- .catch(_ => false);
309
-
310
- const binaryPresent = await filePresent(pathToBB);
311
- if (!binaryPresent) {
312
- return { status: BB_RESULT.FAILURE, reason: `Failed to find bb binary at ${pathToBB}` };
313
- }
314
-
315
- try {
316
- if (!(await filePresent(vkPath)) || !(await filePresent(proofPath))) {
317
- return { status: BB_RESULT.FAILURE, reason: `Client IVC input files not present in ${workingDirectory}` };
318
- }
319
- const args = ['-o', outputPath, '-v'];
320
-
321
- const timer = new Timer();
322
- const logFunction = (message: string) => {
323
- log(`TubeCircuit (prove) BB out - ${message}`);
324
- };
325
- const result = await executeBB(pathToBB, 'prove_tube', args, logFunction);
326
- const durationMs = timer.ms();
327
-
328
- if (result.status == BB_RESULT.SUCCESS) {
329
- return {
330
- status: BB_RESULT.SUCCESS,
331
- durationMs,
332
- proofPath: outputPath,
333
- pkPath: undefined,
334
- vkPath: outputPath,
273
+ vkDirectoryPath: `${outputPath}`,
335
274
  };
336
275
  }
337
276
  // Not a great error message here but it is difficult to decipher what comes from bb
@@ -351,19 +290,21 @@ export async function generateTubeProof(
351
290
  * @param pathToBB - The full path to the bb binary
352
291
  * @param workingDirectory - A working directory for use by bb
353
292
  * @param input - The inputs for the public function to be proven
354
- * @param log - A logging function
293
+ * @param logger - A logging function
294
+ * @param checkCircuitOnly - A boolean to toggle a "check-circuit only" operation instead of proving.
355
295
  * @returns An object containing a result indication, the location of the proof and the duration taken
356
296
  */
357
- export async function generateAvmProofV2(
297
+ export async function generateAvmProof(
358
298
  pathToBB: string,
359
299
  workingDirectory: string,
360
300
  input: AvmCircuitInputs,
361
301
  logger: Logger,
302
+ checkCircuitOnly: boolean = false,
362
303
  ): Promise<BBFailure | BBSuccess> {
363
304
  // Check that the working directory exists
364
305
  try {
365
306
  await fs.access(workingDirectory);
366
- } catch (error) {
307
+ } catch {
367
308
  return { status: BB_RESULT.FAILURE, reason: `Working directory ${workingDirectory} does not exist` };
368
309
  }
369
310
 
@@ -391,107 +332,19 @@ export async function generateAvmProofV2(
391
332
  return { status: BB_RESULT.FAILURE, reason: `Could not write avm inputs to ${avmInputsPath}` };
392
333
  }
393
334
 
394
- const args = ['--avm-inputs', avmInputsPath, '-o', outputPath];
335
+ const args = checkCircuitOnly ? ['--avm-inputs', avmInputsPath] : ['--avm-inputs', avmInputsPath, '-o', outputPath];
395
336
  const loggingArg =
396
337
  logger.level === 'debug' || logger.level === 'trace' ? '-d' : logger.level === 'verbose' ? '-v' : '';
397
338
  if (loggingArg !== '') {
398
339
  args.push(loggingArg);
399
340
  }
400
341
  const timer = new Timer();
401
- const logFunction = (message: string) => {
402
- logger.verbose(`AvmCircuit (prove) BB out - ${message}`);
403
- };
404
- const result = await executeBB(pathToBB, 'avm2_prove', args, logFunction);
405
- const duration = timer.ms();
406
-
407
- if (result.status == BB_RESULT.SUCCESS) {
408
- return {
409
- status: BB_RESULT.SUCCESS,
410
- durationMs: duration,
411
- proofPath: join(outputPath, PROOF_FILENAME),
412
- pkPath: undefined,
413
- vkPath: outputPath,
414
- };
415
- }
416
- // Not a great error message here but it is difficult to decipher what comes from bb
417
- return {
418
- status: BB_RESULT.FAILURE,
419
- reason: `Failed to generate proof. Exit code ${result.exitCode}. Signal ${result.signal}.`,
420
- retry: !!result.signal,
421
- };
422
- } catch (error) {
423
- return { status: BB_RESULT.FAILURE, reason: `${error}` };
424
- }
425
- }
426
342
 
427
- /**
428
- * Used for generating AVM proofs (or doing check-circuit).
429
- * It is assumed that the working directory is a temporary and/or random directory used solely for generating this proof.
430
- * @param pathToBB - The full path to the bb binary
431
- * @param workingDirectory - A working directory for use by bb
432
- * @param bytecode - The AVM bytecode for the public function to be proven (expected to be decompressed)
433
- * @param log - A logging function
434
- * @returns An object containing a result indication, the location of the proof and the duration taken
435
- */
436
- export async function generateAvmProof(
437
- pathToBB: string,
438
- workingDirectory: string,
439
- _input: AvmCircuitInputs,
440
- logger: Logger,
441
- checkCircuitOnly: boolean = false,
442
- ): Promise<BBFailure | BBSuccess> {
443
- // Check that the working directory exists
444
- try {
445
- await fs.access(workingDirectory);
446
- } catch (error) {
447
- return { status: BB_RESULT.FAILURE, reason: `Working directory ${workingDirectory} does not exist` };
448
- }
449
-
450
- // Paths for the inputs
451
- const publicInputsPath = join(workingDirectory, AVM_PUBLIC_INPUTS_FILENAME);
452
- const avmHintsPath = join(workingDirectory, AVM_HINTS_FILENAME);
453
-
454
- // The proof is written to e.g. /workingDirectory/proof
455
- const outputPath = workingDirectory;
456
-
457
- const filePresent = async (file: string) =>
458
- await fs
459
- .access(file, fs.constants.R_OK)
460
- .then(_ => true)
461
- .catch(_ => false);
462
-
463
- const binaryPresent = await filePresent(pathToBB);
464
- if (!binaryPresent) {
465
- return { status: BB_RESULT.FAILURE, reason: `Failed to find bb binary at ${pathToBB}` };
466
- }
467
-
468
- try {
469
- // Write the inputs to the working directory.
470
-
471
- // WARNING: Not writing the inputs since VM1 is disabled!
472
- // await fs.writeFile(publicInputsPath, input.publicInputs.toBuffer());
473
- // if (!(await filePresent(publicInputsPath))) {
474
- // return { status: BB_RESULT.FAILURE, reason: `Could not write publicInputs at ${publicInputsPath}` };
475
- // }
476
-
477
- // await fs.writeFile(avmHintsPath, input.avmHints.toBuffer());
478
- // if (!(await filePresent(avmHintsPath))) {
479
- // return { status: BB_RESULT.FAILURE, reason: `Could not write avmHints at ${avmHintsPath}` };
480
- // }
481
-
482
- const args = ['--avm-public-inputs', publicInputsPath, '--avm-hints', avmHintsPath, '-o', outputPath];
483
- const loggingArg =
484
- logger.level === 'debug' || logger.level === 'trace' ? '-d' : logger.level === 'verbose' ? '-v' : '';
485
- if (loggingArg !== '') {
486
- args.push(loggingArg);
487
- }
488
-
489
- const timer = new Timer();
490
- const cmd = checkCircuitOnly ? 'check_circuit' : 'prove';
343
+ const cmd = checkCircuitOnly ? 'avm_check_circuit' : 'avm_prove';
491
344
  const logFunction = (message: string) => {
492
345
  logger.verbose(`AvmCircuit (${cmd}) BB out - ${message}`);
493
346
  };
494
- const result = await executeBB(pathToBB, `avm_${cmd}`, args, logFunction);
347
+ const result = await executeBB(pathToBB, cmd, args, logFunction);
495
348
  const duration = timer.ms();
496
349
 
497
350
  if (result.status == BB_RESULT.SUCCESS) {
@@ -500,14 +353,14 @@ export async function generateAvmProof(
500
353
  durationMs: duration,
501
354
  proofPath: join(outputPath, PROOF_FILENAME),
502
355
  pkPath: undefined,
503
- vkPath: outputPath,
356
+ vkDirectoryPath: outputPath,
504
357
  };
505
358
  }
506
359
  // Not a great error message here but it is difficult to decipher what comes from bb
507
360
  return {
508
361
  status: BB_RESULT.FAILURE,
509
- reason: `Failed to generate proof. Exit code ${result.exitCode}. Signal ${result.signal}.`,
510
- retry: !!result.signal,
362
+ reason: `Failed to generate proof. AVM proof for TX hash ${input.hints.tx.hash}. Exit code ${result.exitCode}. Signal ${result.signal}.`,
363
+ retry: result.signal === 'SIGKILL', // retry on SIGKILL because the oomkiller might have stopped the process
511
364
  };
512
365
  } catch (error) {
513
366
  return { status: BB_RESULT.FAILURE, reason: `${error}` };
@@ -539,24 +392,7 @@ export async function verifyProof(
539
392
  );
540
393
  }
541
394
 
542
- /**
543
- * Used for verifying proofs of the AVM
544
- * @param pathToBB - The full path to the bb binary
545
- * @param proofFullPath - The full path to the proof to be verified
546
- * @param verificationKeyPath - The full path to the circuit verification key
547
- * @param log - A logging function
548
- * @returns An object containing a result indication and duration taken
549
- */
550
395
  export async function verifyAvmProof(
551
- pathToBB: string,
552
- proofFullPath: string,
553
- verificationKeyPath: string,
554
- logger: Logger,
555
- ): Promise<BBFailure | BBSuccess> {
556
- return await verifyProofInternal(pathToBB, proofFullPath, verificationKeyPath, 'avm_verify', logger);
557
- }
558
-
559
- export async function verifyAvmProofV2(
560
396
  pathToBB: string,
561
397
  workingDirectory: string,
562
398
  proofFullPath: string,
@@ -578,25 +414,27 @@ export async function verifyAvmProofV2(
578
414
  return { status: BB_RESULT.FAILURE, reason: `Could not write avm inputs to ${avmInputsPath}` };
579
415
  }
580
416
 
581
- return await verifyProofInternal(pathToBB, proofFullPath, verificationKeyPath, 'avm2_verify', logger, [
417
+ return await verifyProofInternal(pathToBB, proofFullPath, verificationKeyPath, 'avm_verify', logger, [
582
418
  '--avm-public-inputs',
583
419
  avmInputsPath,
584
420
  ]);
585
421
  }
586
422
 
587
423
  /**
588
- * Verifies a ClientIvcProof
424
+ * Verifies a ChonkProof
589
425
  * TODO(#7370) The verification keys should be supplied separately
590
426
  * @param pathToBB - The full path to the bb binary
591
427
  * @param targetPath - The path to the folder with the proof, accumulator, and verification keys
592
428
  * @param log - A logging function
429
+ * @param concurrency - The number of threads to use for the verification
593
430
  * @returns An object containing a result indication and duration taken
594
431
  */
595
- export async function verifyClientIvcProof(
432
+ export async function verifyChonkProof(
596
433
  pathToBB: string,
597
434
  proofPath: string,
598
435
  keyPath: string,
599
436
  log: LogFn,
437
+ concurrency = 1,
600
438
  ): Promise<BBFailure | BBSuccess> {
601
439
  const binaryPresent = await fs
602
440
  .access(pathToBB, fs.constants.R_OK)
@@ -607,10 +445,11 @@ export async function verifyClientIvcProof(
607
445
  }
608
446
 
609
447
  try {
610
- const args = ['--scheme', 'client_ivc', '-p', proofPath, '-k', keyPath];
448
+ const args = ['--scheme', 'chonk', '-p', proofPath, '-k', keyPath, '-v'];
611
449
  const timer = new Timer();
612
450
  const command = 'verify';
613
- const result = await executeBB(pathToBB, command, args, log);
451
+
452
+ const result = await executeBB(pathToBB, command, args, log, concurrency);
614
453
  const duration = timer.ms();
615
454
  if (result.status == BB_RESULT.SUCCESS) {
616
455
  return { status: BB_RESULT.SUCCESS, durationMs: duration };
@@ -639,7 +478,7 @@ async function verifyProofInternal(
639
478
  pathToBB: string,
640
479
  proofFullPath: string,
641
480
  verificationKeyPath: string,
642
- command: 'verify' | 'avm_verify' | 'avm2_verify',
481
+ command: 'verify' | 'avm_verify',
643
482
  logger: Logger,
644
483
  extraArgs: string[] = [],
645
484
  ): Promise<BBFailure | BBSuccess> {
@@ -656,12 +495,26 @@ async function verifyProofInternal(
656
495
  };
657
496
 
658
497
  try {
659
- const args = ['-p', proofFullPath, '-k', verificationKeyPath, ...extraArgs];
498
+ let args;
499
+
500
+ if (command == 'verify') {
501
+ // Specify the public inputs path in the case of UH verification.
502
+ // Take proofFullPath and remove the suffix past the / to get the directory.
503
+ const proofDir = proofFullPath.substring(0, proofFullPath.lastIndexOf('/'));
504
+ const publicInputsFullPath = join(proofDir, '/public_inputs');
505
+ logger.debug(`public inputs path: ${publicInputsFullPath}`);
506
+
507
+ args = ['-p', proofFullPath, '-k', verificationKeyPath, '-i', publicInputsFullPath, '--disable_zk', ...extraArgs];
508
+ } else {
509
+ args = ['-p', proofFullPath, '-k', verificationKeyPath, ...extraArgs];
510
+ }
511
+
660
512
  const loggingArg =
661
513
  logger.level === 'debug' || logger.level === 'trace' ? '-d' : logger.level === 'verbose' ? '-v' : '';
662
514
  if (loggingArg !== '') {
663
515
  args.push(loggingArg);
664
516
  }
517
+
665
518
  const timer = new Timer();
666
519
  const result = await executeBB(pathToBB, command, args, logFunction);
667
520
  const duration = timer.ms();
@@ -752,11 +605,11 @@ export async function computeGateCountForCircuit(
752
605
  // Check that the working directory exists
753
606
  try {
754
607
  await fs.access(workingDirectory);
755
- } catch (error) {
608
+ } catch {
756
609
  return { status: BB_RESULT.FAILURE, reason: `Working directory ${workingDirectory} does not exist` };
757
610
  }
758
611
 
759
- // The bytecode is written to e.g. /workingDirectory/BaseParityArtifact-bytecode
612
+ // The bytecode is written to e.g. /workingDirectory/ParityBaseArtifact-bytecode
760
613
  const bytecodePath = `${workingDirectory}/${circuitName}-bytecode`;
761
614
 
762
615
  const binaryPresent = await fs
@@ -782,7 +635,7 @@ export async function computeGateCountForCircuit(
782
635
  const result = await executeBB(
783
636
  pathToBB,
784
637
  'gates',
785
- ['--scheme', flavor === 'mega_honk' ? 'client_ivc' : 'ultra_honk', '-b', bytecodePath, '-v'],
638
+ ['--scheme', flavor === 'mega_honk' ? 'chonk' : 'ultra_honk', '-b', bytecodePath, '-v'],
786
639
  logHandler,
787
640
  );
788
641
  const duration = timer.ms();
@@ -844,7 +697,7 @@ async function fsCache<T>(
844
697
 
845
698
  try {
846
699
  await fs.writeFile(cacheFilePath, expectedCacheKey);
847
- } catch (err) {
700
+ } catch {
848
701
  logger(`Couldn't write cache data to ${cacheFilePath}. Skipping cache...`);
849
702
  // ignore
850
703
  }
package/src/config.ts CHANGED
@@ -3,6 +3,8 @@ export interface BBConfig {
3
3
  bbWorkingDirectory: string;
4
4
  /** Whether to skip tmp dir cleanup for debugging purposes */
5
5
  bbSkipCleanup: boolean;
6
+ numConcurrentIVCVerifiers: number;
7
+ bbIVCConcurrency: number;
6
8
  }
7
9
 
8
10
  export interface ACVMConfig {
package/src/honk.ts CHANGED
@@ -1,9 +1,9 @@
1
1
  import type { ServerProtocolArtifact } from '@aztec/noir-protocol-circuits-types/server';
2
2
 
3
- export type UltraHonkFlavor = 'ultra_honk' | 'ultra_keccak_honk' | 'ultra_rollup_honk';
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];
@@ -17,6 +17,7 @@ export function getUltraHonkFlavorForCircuit(artifact: UltraHonkServerProtocolAr
17
17
  export function getUltraHonkFlavorForCircuit(artifact: UltraRollupHonkServerProtocolArtifact): 'ultra_rollup_honk';
18
18
  export function getUltraHonkFlavorForCircuit(artifact: ServerProtocolArtifact): UltraHonkFlavor;
19
19
  export function getUltraHonkFlavorForCircuit(artifact: ServerProtocolArtifact): UltraHonkFlavor {
20
+ // STARKNET: how to allow for the distinction between keccak/starknet? ultra_keccak_honk is returned in both cases
20
21
  if (isUltraKeccakHonkCircuit(artifact)) {
21
22
  return 'ultra_keccak_honk';
22
23
  } else if (UltraHonkCircuits.includes(artifact as UltraHonkServerProtocolArtifact)) {
package/src/index.ts CHANGED
@@ -4,5 +4,6 @@ export * from './verifier/index.js';
4
4
  export * from './config.js';
5
5
  export * from './bb/execute.js';
6
6
  export * from './honk.js';
7
+ export * from './verification_key/verification_key_data.js';
7
8
 
8
9
  export { type ClientProtocolCircuitVerifier } from '@aztec/stdlib/interfaces/server';
@@ -86,13 +86,12 @@ 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();
93
93
  this[metric].record(s, {
94
94
  [Attributes.PROTOCOL_CIRCUIT_NAME]: circuitName,
95
- [Attributes.PROTOCOL_CIRCUIT_TYPE]: 'server',
96
95
  });
97
96
  }
98
97
 
@@ -117,12 +116,11 @@ export class ProverInstrumentation {
117
116
  */
118
117
  recordSize(
119
118
  metric: 'witGenInputSize' | 'witGenOutputSize' | 'proofSize' | 'circuitSize' | 'circuitPublicInputCount',
120
- circuitName: CircuitName | 'tubeCircuit',
119
+ circuitName: CircuitName,
121
120
  size: number,
122
121
  ) {
123
122
  this[metric].record(Math.ceil(size), {
124
123
  [Attributes.PROTOCOL_CIRCUIT_NAME]: circuitName,
125
- [Attributes.PROTOCOL_CIRCUIT_TYPE]: 'server',
126
124
  });
127
125
  }
128
126