@aztec/bb-prover 0.66.0 → 0.67.1-devnet

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 (43) hide show
  1. package/dest/bb/cli.js +2 -2
  2. package/dest/bb/execute.d.ts +3 -3
  3. package/dest/bb/execute.d.ts.map +1 -1
  4. package/dest/bb/execute.js +3 -6
  5. package/dest/instrumentation.d.ts.map +1 -1
  6. package/dest/instrumentation.js +2 -11
  7. package/dest/prover/bb_private_kernel_prover.d.ts +4 -13
  8. package/dest/prover/bb_private_kernel_prover.d.ts.map +1 -1
  9. package/dest/prover/bb_private_kernel_prover.js +7 -72
  10. package/dest/prover/bb_prover.d.ts +1 -1
  11. package/dest/prover/bb_prover.d.ts.map +1 -1
  12. package/dest/prover/bb_prover.js +10 -9
  13. package/dest/prover/client_ivc_proof_utils.d.ts +23 -0
  14. package/dest/prover/client_ivc_proof_utils.d.ts.map +1 -0
  15. package/dest/prover/client_ivc_proof_utils.js +35 -0
  16. package/dest/prover/index.d.ts +1 -0
  17. package/dest/prover/index.d.ts.map +1 -1
  18. package/dest/prover/index.js +2 -1
  19. package/dest/test/test_avm.d.ts +4 -0
  20. package/dest/test/test_avm.d.ts.map +1 -0
  21. package/dest/test/test_avm.js +33 -0
  22. package/dest/test/test_circuit_prover.d.ts.map +1 -1
  23. package/dest/test/test_circuit_prover.js +11 -6
  24. package/dest/verification_key/verification_key_data.js +4 -4
  25. package/dest/verifier/bb_verifier.d.ts +2 -1
  26. package/dest/verifier/bb_verifier.d.ts.map +1 -1
  27. package/dest/verifier/bb_verifier.js +6 -5
  28. package/dest/wasm/index.d.ts +19 -0
  29. package/dest/wasm/index.d.ts.map +1 -0
  30. package/dest/wasm/index.js +74 -0
  31. package/package.json +17 -9
  32. package/src/bb/cli.ts +1 -1
  33. package/src/bb/execute.ts +4 -7
  34. package/src/instrumentation.ts +0 -10
  35. package/src/prover/bb_private_kernel_prover.ts +11 -135
  36. package/src/prover/bb_prover.ts +9 -8
  37. package/src/prover/client_ivc_proof_utils.ts +39 -0
  38. package/src/prover/index.ts +1 -0
  39. package/src/test/test_avm.ts +85 -0
  40. package/src/test/test_circuit_prover.ts +12 -7
  41. package/src/verification_key/verification_key_data.ts +3 -3
  42. package/src/verifier/bb_verifier.ts +6 -5
  43. package/src/wasm/index.ts +155 -0
@@ -0,0 +1,74 @@
1
+ import { AztecClientBackend } from '@aztec/bb.js';
2
+ import { ClientIvcProof, } from '@aztec/circuits.js';
3
+ import { createLogger } from '@aztec/foundation/log';
4
+ import { Timer } from '@aztec/foundation/timer';
5
+ import { ClientCircuitArtifacts, ClientCircuitVks, convertPrivateKernelInitInputsToWitnessMap, convertPrivateKernelInitOutputsFromWitnessMap, convertPrivateKernelInnerInputsToWitnessMap, convertPrivateKernelInnerOutputsFromWitnessMap, convertPrivateKernelResetInputsToWitnessMap, convertPrivateKernelResetOutputsFromWitnessMap, convertPrivateKernelTailForPublicOutputsFromWitnessMap, convertPrivateKernelTailInputsToWitnessMap, convertPrivateKernelTailOutputsFromWitnessMap, convertPrivateKernelTailToPublicInputsToWitnessMap, getPrivateKernelResetArtifactName, } from '@aztec/noir-protocol-circuits-types/client';
6
+ import { WASMSimulator } from '@aztec/simulator/client';
7
+ import { serializeWitness } from '@noir-lang/noirc_abi';
8
+ import { ungzip } from 'pako';
9
+ export class BBWasmPrivateKernelProver {
10
+ constructor(threads = 1, log = createLogger('bb-prover:wasm')) {
11
+ this.threads = threads;
12
+ this.log = log;
13
+ this.simulator = new WASMSimulator();
14
+ }
15
+ async simulateProofInit(inputs) {
16
+ return await this.simulate(inputs, 'PrivateKernelInitArtifact', convertPrivateKernelInitInputsToWitnessMap, convertPrivateKernelInitOutputsFromWitnessMap);
17
+ }
18
+ async simulateProofInner(inputs) {
19
+ return await this.simulate(inputs, 'PrivateKernelInnerArtifact', convertPrivateKernelInnerInputsToWitnessMap, convertPrivateKernelInnerOutputsFromWitnessMap);
20
+ }
21
+ async simulateProofReset(inputs) {
22
+ const variantInputs = inputs.trimToSizes();
23
+ const artifactName = getPrivateKernelResetArtifactName(inputs.dimensions);
24
+ return await this.simulate(variantInputs, artifactName, variantInputs => convertPrivateKernelResetInputsToWitnessMap(variantInputs, artifactName), output => convertPrivateKernelResetOutputsFromWitnessMap(output, artifactName));
25
+ }
26
+ async simulateProofTail(inputs) {
27
+ if (!inputs.isForPublic()) {
28
+ return await this.simulate(inputs, 'PrivateKernelTailArtifact', convertPrivateKernelTailInputsToWitnessMap, convertPrivateKernelTailOutputsFromWitnessMap);
29
+ }
30
+ return await this.simulate(inputs, 'PrivateKernelTailToPublicArtifact', convertPrivateKernelTailToPublicInputsToWitnessMap, convertPrivateKernelTailForPublicOutputsFromWitnessMap);
31
+ }
32
+ async simulate(inputs, circuitType, convertInputs, convertOutputs) {
33
+ this.log.debug(`Generating witness for ${circuitType}`);
34
+ const compiledCircuit = ClientCircuitArtifacts[circuitType];
35
+ const witnessMap = convertInputs(inputs);
36
+ const timer = new Timer();
37
+ const outputWitness = await this.simulator.simulateCircuit(witnessMap, compiledCircuit);
38
+ const output = convertOutputs(outputWitness);
39
+ this.log.debug(`Generated witness for ${circuitType}`, {
40
+ eventName: 'circuit-witness-generation',
41
+ circuitName: circuitType,
42
+ duration: timer.ms(),
43
+ inputSize: inputs.toBuffer().length,
44
+ outputSize: output.toBuffer().length,
45
+ });
46
+ const verificationKey = ClientCircuitVks[circuitType].keyAsFields;
47
+ const bytecode = Buffer.from(compiledCircuit.bytecode, 'base64');
48
+ const kernelOutput = {
49
+ publicInputs: output,
50
+ verificationKey,
51
+ outputWitness,
52
+ bytecode,
53
+ };
54
+ return kernelOutput;
55
+ }
56
+ async createClientIvcProof(acirs, witnessStack) {
57
+ const timer = new Timer();
58
+ this.log.info(`Generating ClientIVC proof...`);
59
+ const backend = new AztecClientBackend(acirs.map(acir => ungzip(acir)), { threads: this.threads });
60
+ const [proof, vk] = await backend.prove(witnessStack.map(witnessMap => ungzip(serializeWitness(witnessMap))));
61
+ await backend.destroy();
62
+ this.log.info(`Generated ClientIVC proof`, {
63
+ eventName: 'client-ivc-proof-generation',
64
+ duration: timer.ms(),
65
+ proofSize: proof.length,
66
+ vkSize: vk.length,
67
+ });
68
+ return new ClientIvcProof(Buffer.from(proof), Buffer.from(vk));
69
+ }
70
+ computeGateCountForCircuit(_bytecode, _circuitName) {
71
+ return Promise.resolve(0);
72
+ }
73
+ }
74
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvd2FzbS9pbmRleC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUUsa0JBQWtCLEVBQUUsTUFBTSxjQUFjLENBQUM7QUFFbEQsT0FBTyxFQUNMLGNBQWMsR0FPZixNQUFNLG9CQUFvQixDQUFDO0FBQzVCLE9BQU8sRUFBRSxZQUFZLEVBQUUsTUFBTSx1QkFBdUIsQ0FBQztBQUNyRCxPQUFPLEVBQUUsS0FBSyxFQUFFLE1BQU0seUJBQXlCLENBQUM7QUFDaEQsT0FBTyxFQUNMLHNCQUFzQixFQUN0QixnQkFBZ0IsRUFFaEIsMENBQTBDLEVBQzFDLDZDQUE2QyxFQUM3QywyQ0FBMkMsRUFDM0MsOENBQThDLEVBQzlDLDJDQUEyQyxFQUMzQyw4Q0FBOEMsRUFDOUMsc0RBQXNELEVBQ3RELDBDQUEwQyxFQUMxQyw2Q0FBNkMsRUFDN0Msa0RBQWtELEVBQ2xELGlDQUFpQyxHQUNsQyxNQUFNLDRDQUE0QyxDQUFDO0FBQ3BELE9BQU8sRUFBRSxhQUFhLEVBQUUsTUFBTSx5QkFBeUIsQ0FBQztBQUl4RCxPQUFPLEVBQUUsZ0JBQWdCLEVBQUUsTUFBTSxzQkFBc0IsQ0FBQztBQUN4RCxPQUFPLEVBQUUsTUFBTSxFQUFFLE1BQU0sTUFBTSxDQUFDO0FBRTlCLE1BQU0sT0FBTyx5QkFBeUI7SUFHcEMsWUFBb0IsVUFBa0IsQ0FBQyxFQUFVLE1BQU0sWUFBWSxDQUFDLGdCQUFnQixDQUFDO1FBQWpFLFlBQU8sR0FBUCxPQUFPLENBQVk7UUFBVSxRQUFHLEdBQUgsR0FBRyxDQUFpQztRQUY3RSxjQUFTLEdBQUcsSUFBSSxhQUFhLEVBQUUsQ0FBQztJQUVnRCxDQUFDO0lBRWxGLEtBQUssQ0FBQyxpQkFBaUIsQ0FDNUIsTUFBNkM7UUFFN0MsT0FBTyxNQUFNLElBQUksQ0FBQyxRQUFRLENBQ3hCLE1BQU0sRUFDTiwyQkFBMkIsRUFDM0IsMENBQTBDLEVBQzFDLDZDQUE2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
package/package.json CHANGED
@@ -1,12 +1,14 @@
1
1
  {
2
2
  "name": "@aztec/bb-prover",
3
- "version": "0.66.0",
3
+ "version": "0.67.1-devnet",
4
4
  "type": "module",
5
5
  "exports": {
6
6
  ".": "./dest/index.js",
7
+ "./wasm": "./dest/wasm/index.js",
7
8
  "./prover": "./dest/prover/index.js",
8
9
  "./verifier": "./dest/verifier/index.js",
9
- "./test": "./dest/test/index.js"
10
+ "./test": "./dest/test/index.js",
11
+ "./config": "./dest/config.js"
10
12
  },
11
13
  "bin": {
12
14
  "bb-cli": "./dest/bb/index.js"
@@ -62,20 +64,26 @@
62
64
  "summaryThreshold": 9999
63
65
  }
64
66
  ]
67
+ ],
68
+ "testTimeout": 30000,
69
+ "setupFiles": [
70
+ "../../foundation/src/jest/setup.mjs"
65
71
  ]
66
72
  },
67
73
  "dependencies": {
68
- "@aztec/circuit-types": "0.66.0",
69
- "@aztec/circuits.js": "0.66.0",
70
- "@aztec/foundation": "0.66.0",
71
- "@aztec/noir-protocol-circuits-types": "0.66.0",
72
- "@aztec/simulator": "0.66.0",
73
- "@aztec/telemetry-client": "0.66.0",
74
- "@aztec/world-state": "0.66.0",
74
+ "@aztec/bb.js": "0.67.1-devnet",
75
+ "@aztec/circuit-types": "0.67.1-devnet",
76
+ "@aztec/circuits.js": "0.67.1-devnet",
77
+ "@aztec/foundation": "0.67.1-devnet",
78
+ "@aztec/noir-protocol-circuits-types": "0.67.1-devnet",
79
+ "@aztec/simulator": "0.67.1-devnet",
80
+ "@aztec/telemetry-client": "0.67.1-devnet",
81
+ "@aztec/world-state": "0.67.1-devnet",
75
82
  "@msgpack/msgpack": "^3.0.0-beta2",
76
83
  "@noir-lang/noirc_abi": "portal:../../noir/packages/noirc_abi",
77
84
  "@noir-lang/types": "portal:../../noir/packages/types",
78
85
  "commander": "^12.1.0",
86
+ "pako": "^2.1.0",
79
87
  "source-map-support": "^0.5.21",
80
88
  "tslib": "^2.4.0"
81
89
  },
package/src/bb/cli.ts CHANGED
@@ -2,7 +2,7 @@ import { type LogFn } from '@aztec/foundation/log';
2
2
  import { type ProtocolArtifact, ProtocolCircuitArtifacts } from '@aztec/noir-protocol-circuits-types';
3
3
 
4
4
  import { Command } from 'commander';
5
- import * as fs from 'fs/promises';
5
+ import { promises as fs } from 'fs';
6
6
 
7
7
  import { generateContractForCircuit, generateKeyForNoirCircuit } from './execute.js';
8
8
 
package/src/bb/execute.ts CHANGED
@@ -1,11 +1,11 @@
1
1
  import { type AvmCircuitInputs } from '@aztec/circuits.js';
2
2
  import { sha256 } from '@aztec/foundation/crypto';
3
- import { type DebugLogger, type LogFn } from '@aztec/foundation/log';
3
+ import { type LogFn, type Logger } from '@aztec/foundation/log';
4
4
  import { Timer } from '@aztec/foundation/timer';
5
5
  import { type NoirCompiledCircuit } from '@aztec/types/noir';
6
6
 
7
7
  import * as proc from 'child_process';
8
- import * as fs from 'fs/promises';
8
+ import { promises as fs } from 'fs';
9
9
  import { basename, dirname, join } from 'path';
10
10
 
11
11
  import { type UltraHonkFlavor } from '../honk.js';
@@ -201,7 +201,6 @@ export async function executeBbClientIvcProof(
201
201
  bytecodeStackPath: string,
202
202
  witnessStackPath: string,
203
203
  log: LogFn,
204
- noAutoVerify = false,
205
204
  ): Promise<BBFailure | BBSuccess> {
206
205
  // Check that the working directory exists
207
206
  try {
@@ -238,9 +237,7 @@ export async function executeBbClientIvcProof(
238
237
  '--input_type',
239
238
  'runtime_stack',
240
239
  ];
241
- if (noAutoVerify) {
242
- args.push('--no_auto_verify');
243
- }
240
+
244
241
  const timer = new Timer();
245
242
  const logFunction = (message: string) => {
246
243
  log(`bb - ${message}`);
@@ -508,7 +505,7 @@ export async function generateAvmProof(
508
505
  pathToBB: string,
509
506
  workingDirectory: string,
510
507
  input: AvmCircuitInputs,
511
- logger: DebugLogger,
508
+ logger: Logger,
512
509
  ): Promise<BBFailure | BBSuccess> {
513
510
  // Check that the working directory exists
514
511
  try {
@@ -8,7 +8,6 @@ import {
8
8
  type TelemetryClient,
9
9
  type Tracer,
10
10
  ValueType,
11
- millisecondBuckets,
12
11
  } from '@aztec/telemetry-client';
13
12
 
14
13
  /**
@@ -36,27 +35,18 @@ export class ProverInstrumentation {
36
35
  description: 'Records how long it takes to simulate a circuit',
37
36
  unit: 'ms',
38
37
  valueType: ValueType.INT,
39
- advice: {
40
- explicitBucketBoundaries: millisecondBuckets(1), // 10ms -> ~327s
41
- },
42
38
  });
43
39
 
44
40
  this.witGenDuration = meter.createHistogram(Metrics.CIRCUIT_WITNESS_GEN_DURATION, {
45
41
  description: 'Records how long it takes to generate the partial witness for a circuit',
46
42
  unit: 'ms',
47
43
  valueType: ValueType.INT,
48
- advice: {
49
- explicitBucketBoundaries: millisecondBuckets(1),
50
- },
51
44
  });
52
45
 
53
46
  this.provingDuration = meter.createHistogram(Metrics.CIRCUIT_PROVING_DURATION, {
54
47
  unit: 'ms',
55
48
  description: 'Records how long it takes to prove a circuit',
56
49
  valueType: ValueType.INT,
57
- advice: {
58
- explicitBucketBoundaries: millisecondBuckets(2), // 100ms -> 54 minutes
59
- },
60
50
  });
61
51
 
62
52
  this.witGenInputSize = meter.createGauge(Metrics.CIRCUIT_WITNESS_GEN_INPUT_SIZE, {
@@ -1,26 +1,18 @@
1
+ import { type PrivateKernelProver, type PrivateKernelSimulateOutput } from '@aztec/circuit-types';
2
+ import { type CircuitWitnessGenerationStats } from '@aztec/circuit-types/stats';
1
3
  import {
2
- type AppCircuitSimulateOutput,
3
- type PrivateKernelProver,
4
- type PrivateKernelSimulateOutput,
5
- } from '@aztec/circuit-types';
6
- import { type CircuitSimulationStats, type CircuitWitnessGenerationStats } from '@aztec/circuit-types/stats';
7
- import {
8
- AGGREGATION_OBJECT_LENGTH,
9
- ClientIvcProof,
10
- Fr,
4
+ type ClientIvcProof,
11
5
  type PrivateKernelCircuitPublicInputs,
12
6
  type PrivateKernelInitCircuitPrivateInputs,
13
7
  type PrivateKernelInnerCircuitPrivateInputs,
14
8
  type PrivateKernelResetCircuitPrivateInputs,
15
9
  type PrivateKernelTailCircuitPrivateInputs,
16
10
  type PrivateKernelTailCircuitPublicInputs,
17
- Proof,
18
- RecursiveProof,
19
- type VerificationKeyAsFields,
11
+ type Proof,
20
12
  type VerificationKeyData,
21
13
  } from '@aztec/circuits.js';
22
14
  import { runInDirectory } from '@aztec/foundation/fs';
23
- import { type DebugLogger, createDebugLogger } from '@aztec/foundation/log';
15
+ import { type Logger, createLogger } from '@aztec/foundation/log';
24
16
  import { Timer } from '@aztec/foundation/timer';
25
17
  import {
26
18
  ClientCircuitArtifacts,
@@ -45,22 +37,15 @@ import { type NoirCompiledCircuit } from '@aztec/types/noir';
45
37
  import { encode } from '@msgpack/msgpack';
46
38
  import { serializeWitness } from '@noir-lang/noirc_abi';
47
39
  import { type WitnessMap } from '@noir-lang/types';
48
- import * as fs from 'fs/promises';
40
+ import { promises as fs } from 'fs';
49
41
  import path from 'path';
50
42
 
51
- import {
52
- BB_RESULT,
53
- PROOF_FIELDS_FILENAME,
54
- PROOF_FILENAME,
55
- computeGateCountForCircuit,
56
- computeVerificationKey,
57
- executeBbClientIvcProof,
58
- verifyProof,
59
- } from '../bb/execute.js';
43
+ import { BB_RESULT, computeGateCountForCircuit, executeBbClientIvcProof, verifyProof } from '../bb/execute.js';
60
44
  import { type BBConfig } from '../config.js';
61
45
  import { type UltraHonkFlavor, getUltraHonkFlavorForCircuit } from '../honk.js';
62
46
  import { mapProtocolArtifactNameToCircuitName } from '../stats.js';
63
47
  import { extractVkData } from '../verification_key/verification_key_data.js';
48
+ import { readFromOutputDirectory } from './client_ivc_proof_utils.js';
64
49
 
65
50
  /**
66
51
  * This proof creator implementation uses the native bb binary.
@@ -79,10 +64,10 @@ export class BBNativePrivateKernelProver implements PrivateKernelProver {
79
64
  private bbBinaryPath: string,
80
65
  private bbWorkingDirectory: string,
81
66
  private skipCleanup: boolean,
82
- private log = createDebugLogger('aztec:bb-native-prover'),
67
+ private log = createLogger('bb-prover:native'),
83
68
  ) {}
84
69
 
85
- public static async new(config: BBConfig, log?: DebugLogger) {
70
+ public static async new(config: BBConfig, log?: Logger) {
86
71
  await fs.mkdir(config.bbWorkingDirectory, { recursive: true });
87
72
  return new BBNativePrivateKernelProver(config.bbBinaryPath, config.bbWorkingDirectory, !!config.bbSkipCleanup, log);
88
73
  }
@@ -112,7 +97,7 @@ export class BBNativePrivateKernelProver implements PrivateKernelProver {
112
97
  throw new Error(provingResult.reason);
113
98
  }
114
99
 
115
- const proof = await ClientIvcProof.readFromOutputDirectory(directory);
100
+ const proof = await readFromOutputDirectory(directory);
116
101
 
117
102
  this.log.info(`Generated IVC proof`, {
118
103
  duration: provingResult.durationMs,
@@ -184,22 +169,6 @@ export class BBNativePrivateKernelProver implements PrivateKernelProver {
184
169
  );
185
170
  }
186
171
 
187
- public async computeAppCircuitVerificationKey(
188
- bytecode: Buffer,
189
- appCircuitName?: string,
190
- ): Promise<AppCircuitSimulateOutput> {
191
- const operation = async (directory: string) => {
192
- this.log.debug(`Proving app circuit`);
193
- // App circuits are always recursive; the #[recursive] attribute used to be applied automatically
194
- // by the `private` comptime macro in noir-projects/aztec-nr/aztec/src/macros/functions/mod.nr
195
- // Yet, inside `computeVerificationKey` the `mega_honk` flavor is used, which doesn't use the recursive flag.
196
- const recursive = true;
197
- return await this.computeVerificationKey(directory, bytecode, recursive, 'App', appCircuitName);
198
- };
199
-
200
- return await this.runInDirectory(operation);
201
- }
202
-
203
172
  /**
204
173
  * Verifies a proof, will generate the verification key if one is not cached internally
205
174
  * @param circuitType - The type of circuit whose proof is to be verified
@@ -313,99 +282,6 @@ export class BBNativePrivateKernelProver implements PrivateKernelProver {
313
282
  return kernelOutput;
314
283
  }
315
284
 
316
- private async computeVerificationKey(
317
- directory: string,
318
- bytecode: Buffer,
319
- recursive: boolean,
320
- circuitType: ClientProtocolArtifact | 'App',
321
- appCircuitName?: string,
322
- ): Promise<{
323
- verificationKey: VerificationKeyAsFields;
324
- }> {
325
- const dbgCircuitName = appCircuitName ? `(${appCircuitName})` : '';
326
- this.log.info(`Computing VK of ${circuitType}${dbgCircuitName} circuit...`);
327
-
328
- const timer = new Timer();
329
-
330
- const vkResult = await computeVerificationKey(
331
- this.bbBinaryPath,
332
- directory,
333
- circuitType,
334
- bytecode,
335
- recursive,
336
- circuitType === 'App' ? 'mega_honk' : getUltraHonkFlavorForCircuit(circuitType),
337
- this.log.debug,
338
- );
339
-
340
- if (vkResult.status === BB_RESULT.FAILURE) {
341
- this.log.error(`Failed to generate verification key for ${circuitType}${dbgCircuitName}: ${vkResult.reason}`);
342
- throw new Error(vkResult.reason);
343
- }
344
-
345
- this.log.info(`Generated ${circuitType}${dbgCircuitName} VK in ${Math.ceil(timer.ms())} ms`);
346
-
347
- if (circuitType === 'App') {
348
- const vkData = await extractVkData(directory);
349
-
350
- this.log.debug(`Computed verification key`, {
351
- circuitName: 'app-circuit',
352
- duration: vkResult.durationMs,
353
- eventName: 'circuit-simulation',
354
- inputSize: bytecode.length,
355
- outputSize: vkData.keyAsBytes.length,
356
- circuitSize: vkData.circuitSize,
357
- numPublicInputs: vkData.numPublicInputs,
358
- } as CircuitSimulationStats);
359
-
360
- return { verificationKey: vkData.keyAsFields };
361
- }
362
-
363
- const vkData = await this.updateVerificationKeyAfterSimulation(directory, circuitType);
364
-
365
- this.log.debug(`Computed verification key`, {
366
- circuitName: mapProtocolArtifactNameToCircuitName(circuitType),
367
- duration: vkResult.durationMs,
368
- eventName: 'circuit-simulation',
369
- inputSize: bytecode.length,
370
- outputSize: vkData.keyAsBytes.length,
371
- circuitSize: vkData.circuitSize,
372
- numPublicInputs: vkData.numPublicInputs,
373
- } as CircuitSimulationStats);
374
-
375
- return { verificationKey: vkData.keyAsFields };
376
- }
377
-
378
- /**
379
- * Parses and returns the proof data stored at the specified directory
380
- * @param filePath - The directory containing the proof data
381
- * @param circuitType - The type of circuit proven
382
- * @returns The proof
383
- */
384
- private async readProofAsFields<PROOF_LENGTH extends number>(
385
- filePath: string,
386
- circuitType: ClientProtocolArtifact | 'App',
387
- vkData: VerificationKeyData,
388
- ): Promise<RecursiveProof<PROOF_LENGTH>> {
389
- const [binaryProof, proofString] = await Promise.all([
390
- fs.readFile(`${filePath}/${PROOF_FILENAME}`),
391
- fs.readFile(`${filePath}/${PROOF_FIELDS_FILENAME}`, { encoding: 'utf-8' }),
392
- ]);
393
- const json = JSON.parse(proofString);
394
- const fields = json.map(Fr.fromString);
395
- const numPublicInputs = vkData.numPublicInputs - AGGREGATION_OBJECT_LENGTH;
396
- const fieldsWithoutPublicInputs = fields.slice(numPublicInputs);
397
- this.log.info(
398
- `Circuit type: ${circuitType}, complete proof length: ${fields.length}, without public inputs: ${fieldsWithoutPublicInputs.length}, num public inputs: ${numPublicInputs}, circuit size: ${vkData.circuitSize}, is recursive: ${vkData.isRecursive}, raw length: ${binaryProof.length}`,
399
- );
400
- const proof = new RecursiveProof<PROOF_LENGTH>(
401
- fieldsWithoutPublicInputs,
402
- new Proof(binaryProof, vkData.numPublicInputs),
403
- true,
404
- fieldsWithoutPublicInputs.length,
405
- );
406
- return proof;
407
- }
408
-
409
285
  private runInDirectory<T>(fn: (dir: string) => Promise<T>) {
410
286
  const log = this.log;
411
287
  return runInDirectory(
@@ -42,7 +42,7 @@ import {
42
42
  makeRecursiveProofFromBinary,
43
43
  } from '@aztec/circuits.js';
44
44
  import { runInDirectory } from '@aztec/foundation/fs';
45
- import { createDebugLogger } from '@aztec/foundation/log';
45
+ import { createLogger } from '@aztec/foundation/log';
46
46
  import { BufferReader } from '@aztec/foundation/serialize';
47
47
  import { Timer } from '@aztec/foundation/timer';
48
48
  import {
@@ -76,7 +76,7 @@ import { Attributes, type TelemetryClient, trackSpan } from '@aztec/telemetry-cl
76
76
  import { abiEncode } from '@noir-lang/noirc_abi';
77
77
  import { type Abi, type WitnessMap } from '@noir-lang/types';
78
78
  import crypto from 'crypto';
79
- import * as fs from 'fs/promises';
79
+ import { promises as fs } from 'fs';
80
80
  import * as path from 'path';
81
81
 
82
82
  import {
@@ -99,8 +99,9 @@ import { type UltraHonkFlavor, getUltraHonkFlavorForCircuit } from '../honk.js';
99
99
  import { ProverInstrumentation } from '../instrumentation.js';
100
100
  import { mapProtocolArtifactNameToCircuitName } from '../stats.js';
101
101
  import { extractAvmVkData, extractVkData } from '../verification_key/verification_key_data.js';
102
+ import { writeToOutputDirectory } from './client_ivc_proof_utils.js';
102
103
 
103
- const logger = createDebugLogger('aztec:bb-prover');
104
+ const logger = createLogger('bb-prover');
104
105
 
105
106
  // All `ServerCircuitArtifact` are recursive.
106
107
  const SERVER_CIRCUIT_RECURSIVE = true;
@@ -551,7 +552,7 @@ export class BBNativeRollupProver implements ServerCircuitProver {
551
552
  const hasher = crypto.createHash('sha256');
552
553
  hasher.update(input.toBuffer());
553
554
 
554
- await input.clientIVCData.writeToOutputDirectory(bbWorkingDirectory);
555
+ await writeToOutputDirectory(input.clientIVCData, bbWorkingDirectory);
555
556
  const provingResult = await generateTubeProof(this.config.bbBinaryPath, bbWorkingDirectory, logger.verbose);
556
557
 
557
558
  if (provingResult.status === BB_RESULT.FAILURE) {
@@ -795,8 +796,8 @@ export class BBNativeRollupProver implements ServerCircuitProver {
795
796
  const json = JSON.parse(proofString);
796
797
  const fields = json
797
798
  .slice(0, 3)
798
- .map(Fr.fromString)
799
- .concat(json.slice(3 + numPublicInputs).map(Fr.fromString));
799
+ .map(Fr.fromHexString)
800
+ .concat(json.slice(3 + numPublicInputs).map(Fr.fromHexString));
800
801
  return new RecursiveProof(
801
802
  fields,
802
803
  new Proof(proof.binaryProof.buffer, vk.numPublicInputs),
@@ -877,8 +878,8 @@ export class BBNativeRollupProver implements ServerCircuitProver {
877
878
 
878
879
  const fieldsWithoutPublicInputs = json
879
880
  .slice(0, 3)
880
- .map(Fr.fromString)
881
- .concat(json.slice(3 + numPublicInputs).map(Fr.fromString));
881
+ .map(Fr.fromHexString)
882
+ .concat(json.slice(3 + numPublicInputs).map(Fr.fromHexString));
882
883
  logger.debug(
883
884
  `Circuit path: ${filePath}, complete proof length: ${json.length}, num public inputs: ${numPublicInputs}, circuit size: ${vkData.circuitSize}, is recursive: ${vkData.isRecursive}, raw length: ${binaryProof.length}`,
884
885
  );
@@ -0,0 +1,39 @@
1
+ import { ClientIvcProof } from '@aztec/circuits.js';
2
+
3
+ import { promises as fs } from 'fs';
4
+ import { join } from 'path';
5
+
6
+ /**
7
+ * TODO(#7371): eventually remove client_ivc_prove_output_all_msgpack and properly handle these accumulators and VKs
8
+ * Create a ClientIvcProof from the result of client_ivc_prove_output_all or client_ivc_prove_output_all_msgpack
9
+ * @param directory the directory of results
10
+ * @returns the encapsulated client ivc proof
11
+ */
12
+ export async function readFromOutputDirectory(directory: string) {
13
+ const [clientIvcVkBuffer, clientIvcProofBuffer] = await Promise.all(
14
+ ['client_ivc_vk', 'client_ivc_proof'].map(fileName => fs.readFile(join(directory, fileName))),
15
+ );
16
+ return new ClientIvcProof(clientIvcProofBuffer, clientIvcVkBuffer);
17
+ }
18
+
19
+ /**
20
+ * TODO(#7371): eventually remove client_ivc_prove_output_all_msgpack and properly handle these accumulators and VKs
21
+ * Serialize a ClientIvcProof to the files expected by prove_tube
22
+ *
23
+ * Example usage:
24
+ * await runInDirectory(bbWorkingDirectory, async (dir: string) => {
25
+ * await privateTx.clientIvcProof!.writeToOutputDirectory(bbWorkingDirectory);
26
+ * const result = await generateTubeProof(bbPath, dir, logger.info)
27
+ * expect(result.status).toBe(BB_RESULT.SUCCESS)
28
+ * });
29
+ * @param proof the ClientIvcProof from readFromOutputDirectory
30
+ * @param directory the directory of results
31
+ */
32
+ export async function writeToOutputDirectory(clientIvcProof: ClientIvcProof, directory: string) {
33
+ const { clientIvcProofBuffer, clientIvcVkBuffer } = clientIvcProof;
34
+ const fileData = [
35
+ ['client_ivc_proof', clientIvcProofBuffer],
36
+ ['client_ivc_vk', clientIvcVkBuffer],
37
+ ] as const;
38
+ await Promise.all(fileData.map(([fileName, buffer]) => fs.writeFile(join(directory, fileName), buffer)));
39
+ }
@@ -1,2 +1,3 @@
1
1
  export * from './bb_prover.js';
2
2
  export * from './bb_private_kernel_prover.js';
3
+ export * from './client_ivc_proof_utils.js';
@@ -0,0 +1,85 @@
1
+ import {
2
+ AztecAddress,
3
+ BlockHeader,
4
+ ContractStorageRead,
5
+ ContractStorageUpdateRequest,
6
+ Gas,
7
+ GlobalVariables,
8
+ L2ToL1Message,
9
+ LogHash,
10
+ MAX_ENQUEUED_CALLS_PER_CALL,
11
+ MAX_L1_TO_L2_MSG_READ_REQUESTS_PER_CALL,
12
+ MAX_L2_TO_L1_MSGS_PER_CALL,
13
+ MAX_NOTE_HASHES_PER_CALL,
14
+ MAX_NOTE_HASH_READ_REQUESTS_PER_CALL,
15
+ MAX_NULLIFIERS_PER_CALL,
16
+ MAX_NULLIFIER_NON_EXISTENT_READ_REQUESTS_PER_CALL,
17
+ MAX_NULLIFIER_READ_REQUESTS_PER_CALL,
18
+ MAX_PUBLIC_DATA_READS_PER_CALL,
19
+ MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_CALL,
20
+ MAX_UNENCRYPTED_LOGS_PER_CALL,
21
+ NoteHash,
22
+ Nullifier,
23
+ PublicCircuitPublicInputs,
24
+ PublicInnerCallRequest,
25
+ ReadRequest,
26
+ RevertCode,
27
+ TreeLeafReadRequest,
28
+ } from '@aztec/circuits.js';
29
+ import { computeVarArgsHash } from '@aztec/circuits.js/hash';
30
+ import { padArrayEnd } from '@aztec/foundation/collection';
31
+ import { type PublicFunctionCallResult } from '@aztec/simulator';
32
+
33
+ // TODO: pub somewhere more usable - copied from abstract phase manager
34
+ export function getPublicInputs(result: PublicFunctionCallResult): PublicCircuitPublicInputs {
35
+ return PublicCircuitPublicInputs.from({
36
+ callContext: result.executionRequest.callContext,
37
+ proverAddress: AztecAddress.ZERO,
38
+ argsHash: computeVarArgsHash(result.executionRequest.args),
39
+ noteHashes: padArrayEnd(result.noteHashes, NoteHash.empty(), MAX_NOTE_HASHES_PER_CALL),
40
+ nullifiers: padArrayEnd(result.nullifiers, Nullifier.empty(), MAX_NULLIFIERS_PER_CALL),
41
+ l2ToL1Msgs: padArrayEnd(result.l2ToL1Messages, L2ToL1Message.empty(), MAX_L2_TO_L1_MSGS_PER_CALL),
42
+ startSideEffectCounter: result.startSideEffectCounter,
43
+ endSideEffectCounter: result.endSideEffectCounter,
44
+ returnsHash: computeVarArgsHash(result.returnValues),
45
+ noteHashReadRequests: padArrayEnd(
46
+ result.noteHashReadRequests,
47
+ TreeLeafReadRequest.empty(),
48
+ MAX_NOTE_HASH_READ_REQUESTS_PER_CALL,
49
+ ),
50
+ nullifierReadRequests: padArrayEnd(
51
+ result.nullifierReadRequests,
52
+ ReadRequest.empty(),
53
+ MAX_NULLIFIER_READ_REQUESTS_PER_CALL,
54
+ ),
55
+ nullifierNonExistentReadRequests: padArrayEnd(
56
+ result.nullifierNonExistentReadRequests,
57
+ ReadRequest.empty(),
58
+ MAX_NULLIFIER_NON_EXISTENT_READ_REQUESTS_PER_CALL,
59
+ ),
60
+ l1ToL2MsgReadRequests: padArrayEnd(
61
+ result.l1ToL2MsgReadRequests,
62
+ TreeLeafReadRequest.empty(),
63
+ MAX_L1_TO_L2_MSG_READ_REQUESTS_PER_CALL,
64
+ ),
65
+ contractStorageReads: padArrayEnd(
66
+ result.contractStorageReads,
67
+ ContractStorageRead.empty(),
68
+ MAX_PUBLIC_DATA_READS_PER_CALL,
69
+ ),
70
+ contractStorageUpdateRequests: padArrayEnd(
71
+ result.contractStorageUpdateRequests,
72
+ ContractStorageUpdateRequest.empty(),
73
+ MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_CALL,
74
+ ),
75
+ publicCallRequests: padArrayEnd([], PublicInnerCallRequest.empty(), MAX_ENQUEUED_CALLS_PER_CALL),
76
+ unencryptedLogsHashes: padArrayEnd(result.unencryptedLogsHashes, LogHash.empty(), MAX_UNENCRYPTED_LOGS_PER_CALL),
77
+ historicalHeader: BlockHeader.empty(),
78
+ globalVariables: GlobalVariables.empty(),
79
+ startGasLeft: Gas.from(result.startGasLeft),
80
+ endGasLeft: Gas.from(result.endGasLeft),
81
+ transactionFee: result.transactionFee,
82
+ // TODO(@just-mitch): need better mapping from simulator to revert code.
83
+ revertCode: result.reverted ? RevertCode.APP_LOGIC_REVERTED : RevertCode.OK,
84
+ });
85
+ }