@aztec/bb-prover 0.0.0-test.0 → 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.
- package/dest/avm_proving_tests/avm_proving_tester.d.ts +14 -18
- package/dest/avm_proving_tests/avm_proving_tester.d.ts.map +1 -1
- package/dest/avm_proving_tests/avm_proving_tester.js +130 -79
- package/dest/bb/cli.d.ts +1 -1
- package/dest/bb/execute.d.ts +14 -47
- package/dest/bb/execute.d.ts.map +1 -1
- package/dest/bb/execute.js +132 -236
- package/dest/bb/index.d.ts +1 -1
- package/dest/config.d.ts +3 -1
- package/dest/config.d.ts.map +1 -1
- package/dest/honk.d.ts +3 -3
- package/dest/honk.d.ts.map +1 -1
- package/dest/honk.js +3 -2
- package/dest/index.d.ts +2 -1
- package/dest/index.d.ts.map +1 -1
- package/dest/index.js +1 -0
- package/dest/instrumentation.d.ts +3 -3
- package/dest/instrumentation.d.ts.map +1 -1
- package/dest/instrumentation.js +2 -4
- package/dest/prover/client/bb_private_kernel_prover.d.ts +32 -0
- package/dest/prover/client/bb_private_kernel_prover.d.ts.map +1 -0
- package/dest/prover/{bb_private_kernel_prover.js → client/bb_private_kernel_prover.js} +42 -20
- 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 +8 -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 +8 -0
- package/dest/prover/index.d.ts +3 -4
- package/dest/prover/index.d.ts.map +1 -1
- package/dest/prover/index.js +2 -3
- package/dest/prover/proof_utils.d.ts +19 -0
- package/dest/prover/proof_utils.d.ts.map +1 -0
- package/dest/prover/proof_utils.js +72 -0
- package/dest/prover/server/bb_prover.d.ts +100 -0
- package/dest/prover/server/bb_prover.d.ts.map +1 -0
- package/dest/prover/server/bb_prover.js +339 -0
- 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 +33 -21
- package/dest/test/index.d.ts +1 -1
- package/dest/test/test_circuit_prover.d.ts +25 -34
- package/dest/test/test_circuit_prover.d.ts.map +1 -1
- package/dest/test/test_circuit_prover.js +85 -59
- package/dest/test/test_verifier.d.ts +6 -3
- package/dest/test/test_verifier.d.ts.map +1 -1
- package/dest/test/test_verifier.js +23 -1
- package/dest/verification_key/verification_key_data.d.ts +7 -1
- package/dest/verification_key/verification_key_data.d.ts.map +1 -1
- package/dest/verification_key/verification_key_data.js +23 -29
- package/dest/verifier/bb_verifier.d.ts +6 -5
- package/dest/verifier/bb_verifier.d.ts.map +1 -1
- package/dest/verifier/bb_verifier.js +46 -25
- package/dest/verifier/index.d.ts +2 -1
- package/dest/verifier/index.d.ts.map +1 -1
- package/dest/verifier/index.js +1 -0
- 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_chonk_verifier.js +132 -0
- package/package.json +35 -33
- package/src/avm_proving_tests/avm_proving_tester.ts +210 -104
- package/src/bb/execute.ts +103 -250
- package/src/config.ts +2 -0
- package/src/honk.ts +3 -2
- package/src/index.ts +1 -0
- package/src/instrumentation.ts +2 -4
- package/src/prover/{bb_private_kernel_prover.ts → client/bb_private_kernel_prover.ts} +78 -30
- package/src/prover/client/bundle.ts +11 -0
- package/src/prover/client/lazy.ts +11 -0
- package/src/prover/index.ts +2 -3
- package/src/prover/proof_utils.ts +115 -0
- package/src/prover/server/bb_prover.ts +733 -0
- package/src/test/delay_values.ts +33 -21
- package/src/test/test_circuit_prover.ts +260 -147
- package/src/test/test_verifier.ts +15 -3
- package/src/verification_key/verification_key_data.ts +29 -24
- package/src/verifier/bb_verifier.ts +63 -32
- package/src/verifier/index.ts +1 -0
- package/src/verifier/queued_chonk_verifier.ts +140 -0
- package/dest/prover/bb_native_private_kernel_prover.d.ts +0 -25
- package/dest/prover/bb_native_private_kernel_prover.d.ts.map +0 -1
- package/dest/prover/bb_native_private_kernel_prover.js +0 -69
- package/dest/prover/bb_private_kernel_prover.d.ts +0 -32
- package/dest/prover/bb_private_kernel_prover.d.ts.map +0 -1
- package/dest/prover/bb_prover.d.ts +0 -120
- package/dest/prover/bb_prover.d.ts.map +0 -1
- package/dest/prover/bb_prover.js +0 -423
- package/dest/prover/client_ivc_proof_utils.d.ts +0 -25
- package/dest/prover/client_ivc_proof_utils.d.ts.map +0 -1
- package/dest/prover/client_ivc_proof_utils.js +0 -43
- package/dest/stats.d.ts +0 -5
- package/dest/stats.d.ts.map +0 -1
- package/dest/stats.js +0 -62
- package/dest/wasm/bb_wasm_private_kernel_prover.d.ts +0 -17
- package/dest/wasm/bb_wasm_private_kernel_prover.d.ts.map +0 -1
- package/dest/wasm/bb_wasm_private_kernel_prover.js +0 -46
- package/dest/wasm/bundle.d.ts +0 -6
- package/dest/wasm/bundle.d.ts.map +0 -1
- package/dest/wasm/bundle.js +0 -8
- package/dest/wasm/lazy.d.ts +0 -6
- package/dest/wasm/lazy.d.ts.map +0 -1
- package/dest/wasm/lazy.js +0 -8
- package/src/prover/bb_native_private_kernel_prover.ts +0 -119
- package/src/prover/bb_prover.ts +0 -781
- package/src/prover/client_ivc_proof_utils.ts +0 -42
- package/src/stats.ts +0 -64
- package/src/wasm/bb_wasm_private_kernel_prover.ts +0 -55
- package/src/wasm/bundle.ts +0 -11
- 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
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
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
|
-
|
|
102
|
-
export async function executeBbClientIvcProof(
|
|
120
|
+
export async function executeBbChonkProof(
|
|
103
121
|
pathToBB: string,
|
|
104
122
|
workingDirectory: string,
|
|
105
|
-
|
|
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
|
|
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(`
|
|
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
|
-
|
|
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
|
-
|
|
213
|
+
verificationKey: Buffer,
|
|
205
214
|
inputWitnessFile: string,
|
|
206
215
|
flavor: UltraHonkFlavor,
|
|
207
|
-
log:
|
|
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
|
|
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/
|
|
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
|
-
'--
|
|
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
|
-
|
|
246
|
-
|
|
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
|
-
|
|
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
|
|
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
|
|
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
|
|
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,
|
|
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
|
-
|
|
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:
|
|
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, '
|
|
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
|
|
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
|
|
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', '
|
|
448
|
+
const args = ['--scheme', 'chonk', '-p', proofPath, '-k', keyPath, '-v'];
|
|
611
449
|
const timer = new Timer();
|
|
612
450
|
const command = 'verify';
|
|
613
|
-
|
|
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'
|
|
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
|
-
|
|
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
|
|
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/
|
|
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' ? '
|
|
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
|
|
700
|
+
} catch {
|
|
848
701
|
logger(`Couldn't write cache data to ${cacheFilePath}. Skipping cache...`);
|
|
849
702
|
// ignore
|
|
850
703
|
}
|
package/src/config.ts
CHANGED
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 = ['
|
|
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';
|
package/src/instrumentation.ts
CHANGED
|
@@ -86,13 +86,12 @@ 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();
|
|
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
|
|
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
|
|