@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.
- package/dest/avm_proving_tests/avm_proving_tester.d.ts +7 -6
- package/dest/avm_proving_tests/avm_proving_tester.d.ts.map +1 -1
- package/dest/avm_proving_tests/avm_proving_tester.js +33 -13
- package/dest/bb/cli.d.ts +1 -1
- package/dest/bb/execute.d.ts +5 -13
- package/dest/bb/execute.d.ts.map +1 -1
- package/dest/bb/execute.js +30 -92
- package/dest/bb/index.d.ts +1 -1
- package/dest/config.d.ts +1 -1
- package/dest/honk.d.ts +2 -2
- package/dest/honk.js +2 -2
- package/dest/index.d.ts +1 -1
- package/dest/instrumentation.d.ts +3 -3
- package/dest/instrumentation.d.ts.map +1 -1
- package/dest/prover/client/bb_private_kernel_prover.d.ts +12 -6
- package/dest/prover/client/bb_private_kernel_prover.d.ts.map +1 -1
- package/dest/prover/client/bb_private_kernel_prover.js +36 -7
- package/dest/prover/client/bundle.d.ts +6 -0
- package/dest/prover/client/bundle.d.ts.map +1 -0
- package/dest/prover/client/bundle.js +7 -0
- package/dest/prover/client/lazy.d.ts +6 -0
- package/dest/prover/client/lazy.d.ts.map +1 -0
- package/dest/prover/client/lazy.js +7 -0
- package/dest/prover/index.d.ts +1 -1
- package/dest/prover/proof_utils.d.ts +9 -9
- package/dest/prover/proof_utils.d.ts.map +1 -1
- package/dest/prover/proof_utils.js +42 -25
- package/dest/prover/server/bb_prover.d.ts +23 -43
- package/dest/prover/server/bb_prover.d.ts.map +1 -1
- package/dest/prover/server/bb_prover.js +464 -165
- package/dest/test/delay_values.d.ts +1 -1
- package/dest/test/delay_values.d.ts.map +1 -1
- package/dest/test/delay_values.js +37 -25
- package/dest/test/index.d.ts +2 -1
- package/dest/test/index.d.ts.map +1 -1
- package/dest/test/index.js +1 -0
- package/dest/test/test_circuit_prover.d.ts +21 -31
- package/dest/test/test_circuit_prover.d.ts.map +1 -1
- package/dest/test/test_circuit_prover.js +503 -81
- package/dest/test/test_verifier.d.ts +3 -1
- package/dest/test/test_verifier.d.ts.map +1 -1
- package/dest/test/test_verifier.js +15 -0
- package/dest/verification_key/verification_key_data.d.ts +1 -1
- package/dest/verification_key/verification_key_data.js +1 -1
- package/dest/verifier/bb_verifier.d.ts +3 -5
- package/dest/verifier/bb_verifier.d.ts.map +1 -1
- package/dest/verifier/bb_verifier.js +24 -26
- package/dest/verifier/index.d.ts +2 -2
- package/dest/verifier/index.d.ts.map +1 -1
- package/dest/verifier/index.js +1 -1
- package/dest/verifier/queued_chonk_verifier.d.ts +15 -0
- package/dest/verifier/queued_chonk_verifier.d.ts.map +1 -0
- package/dest/verifier/{queued_ivc_verifier.js → queued_chonk_verifier.js} +3 -3
- package/package.json +23 -23
- package/src/avm_proving_tests/avm_proving_tester.ts +43 -19
- package/src/bb/execute.ts +20 -90
- package/src/honk.ts +1 -1
- package/src/instrumentation.ts +2 -2
- package/src/prover/client/bb_private_kernel_prover.ts +49 -10
- package/src/prover/client/bundle.ts +10 -0
- package/src/prover/client/lazy.ts +10 -0
- package/src/prover/proof_utils.ts +53 -31
- package/src/prover/server/bb_prover.ts +231 -293
- package/src/test/delay_values.ts +38 -24
- package/src/test/index.ts +1 -0
- package/src/test/test_circuit_prover.ts +219 -142
- package/src/test/test_verifier.ts +8 -0
- package/src/verification_key/verification_key_data.ts +1 -1
- package/src/verifier/bb_verifier.ts +34 -33
- package/src/verifier/index.ts +1 -1
- package/src/verifier/{queued_ivc_verifier.ts → queued_chonk_verifier.ts} +3 -3
- package/dest/prover/client/native/bb_native_private_kernel_prover.d.ts +0 -23
- package/dest/prover/client/native/bb_native_private_kernel_prover.d.ts.map +0 -1
- package/dest/prover/client/native/bb_native_private_kernel_prover.js +0 -66
- package/dest/prover/client/wasm/bb_wasm_private_kernel_prover.d.ts +0 -15
- package/dest/prover/client/wasm/bb_wasm_private_kernel_prover.d.ts.map +0 -1
- package/dest/prover/client/wasm/bb_wasm_private_kernel_prover.js +0 -48
- package/dest/prover/client/wasm/bundle.d.ts +0 -6
- package/dest/prover/client/wasm/bundle.d.ts.map +0 -1
- package/dest/prover/client/wasm/bundle.js +0 -8
- package/dest/prover/client/wasm/lazy.d.ts +0 -6
- package/dest/prover/client/wasm/lazy.d.ts.map +0 -1
- package/dest/prover/client/wasm/lazy.js +0 -8
- package/dest/stats.d.ts +0 -4
- package/dest/stats.d.ts.map +0 -1
- package/dest/stats.js +0 -45
- package/dest/verifier/queued_ivc_verifier.d.ts +0 -15
- package/dest/verifier/queued_ivc_verifier.d.ts.map +0 -1
- package/src/prover/client/native/bb_native_private_kernel_prover.ts +0 -105
- package/src/prover/client/wasm/bb_wasm_private_kernel_prover.ts +0 -60
- package/src/prover/client/wasm/bundle.ts +0 -11
- package/src/prover/client/wasm/lazy.ts +0 -11
- 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('
|
|
104
|
-
|
|
105
|
-
|
|
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
|
|
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', '
|
|
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/
|
|
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
|
|
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
|
|
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', '
|
|
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/
|
|
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' ? '
|
|
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 = ['
|
|
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];
|
package/src/instrumentation.ts
CHANGED
|
@@ -86,7 +86,7 @@ export class ProverInstrumentation {
|
|
|
86
86
|
*/
|
|
87
87
|
recordDuration(
|
|
88
88
|
metric: 'simulationDuration' | 'witGenDuration' | 'provingDuration',
|
|
89
|
-
circuitName: CircuitName
|
|
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
|
|
119
|
+
circuitName: CircuitName,
|
|
120
120
|
size: number,
|
|
121
121
|
) {
|
|
122
122
|
this[metric].record(Math.ceil(size), {
|
|
@@ -1,4 +1,7 @@
|
|
|
1
|
-
import {
|
|
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
|
|
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
|
|
43
|
+
import { ChonkProofWithPublicInputs } from '@aztec/stdlib/proofs';
|
|
37
44
|
import type { CircuitSimulationStats, CircuitWitnessGenerationStats } from '@aztec/stdlib/stats';
|
|
38
45
|
|
|
39
|
-
import {
|
|
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
|
|
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
|
|
265
|
-
|
|
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
|
-
|
|
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/
|
|
10
|
+
import { Fr } from '@aztec/foundation/curves/bn254';
|
|
9
11
|
import type { Logger } from '@aztec/foundation/log';
|
|
10
|
-
import {
|
|
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 {
|
|
19
|
+
import { PROOF_FILENAME, PUBLIC_INPUTS_FILENAME } from '../bb/execute.js';
|
|
18
20
|
|
|
19
21
|
/**
|
|
20
|
-
* Create a
|
|
22
|
+
* Create a ChonkProof proof file.
|
|
21
23
|
*
|
|
22
24
|
* @param directory the directory to read the proof from.
|
|
23
|
-
* @returns the encapsulated
|
|
25
|
+
* @returns the encapsulated chonk proof
|
|
24
26
|
*/
|
|
25
|
-
export async function
|
|
26
|
-
const
|
|
27
|
-
|
|
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
|
|
35
|
+
* Serialize a ChonkProof to a proof file.
|
|
32
36
|
*
|
|
33
|
-
* @param proof the
|
|
37
|
+
* @param proof the ChonkProof from object
|
|
34
38
|
* @param directory the directory to write in
|
|
35
39
|
*/
|
|
36
|
-
export async function
|
|
37
|
-
|
|
38
|
-
|
|
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
|
|
50
|
-
|
|
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 ==
|
|
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
|
-
|
|
73
|
-
|
|
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: ${
|
|
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,
|