@aztec/bb-prover 0.0.1-commit.96bb3f7 → 0.0.1-commit.993d240
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 +13 -8
- package/dest/avm_proving_tests/avm_proving_tester.d.ts.map +1 -1
- package/dest/avm_proving_tests/avm_proving_tester.js +152 -107
- package/dest/bb/bb_js_backend.d.ts +196 -0
- package/dest/bb/bb_js_backend.d.ts.map +1 -0
- package/dest/bb/bb_js_backend.js +379 -0
- package/dest/bb/bb_js_debug.d.ts +52 -0
- package/dest/bb/bb_js_debug.d.ts.map +1 -0
- package/dest/bb/bb_js_debug.js +176 -0
- package/dest/bb/file_names.d.ts +4 -0
- package/dest/bb/file_names.d.ts.map +1 -0
- package/dest/bb/file_names.js +5 -0
- package/dest/config.d.ts +17 -1
- package/dest/config.d.ts.map +1 -1
- package/dest/index.d.ts +3 -2
- package/dest/index.d.ts.map +1 -1
- package/dest/index.js +2 -1
- package/dest/instrumentation.d.ts +1 -1
- package/dest/instrumentation.d.ts.map +1 -1
- package/dest/instrumentation.js +12 -4
- package/dest/prover/client/bb_private_kernel_prover.d.ts +10 -2
- package/dest/prover/client/bb_private_kernel_prover.d.ts.map +1 -1
- package/dest/prover/client/bb_private_kernel_prover.js +43 -7
- package/dest/prover/proof_utils.d.ts +11 -1
- package/dest/prover/proof_utils.d.ts.map +1 -1
- package/dest/prover/proof_utils.js +24 -1
- package/dest/prover/server/bb_prover.d.ts +4 -5
- package/dest/prover/server/bb_prover.d.ts.map +1 -1
- package/dest/prover/server/bb_prover.js +208 -79
- package/dest/test/delay_values.js +1 -1
- package/dest/verification_key/verification_key_data.js +1 -1
- package/dest/verifier/batch_chonk_verifier.d.ts +45 -0
- package/dest/verifier/batch_chonk_verifier.d.ts.map +1 -0
- package/dest/verifier/batch_chonk_verifier.js +232 -0
- package/dest/verifier/bb_verifier.d.ts +4 -1
- package/dest/verifier/bb_verifier.d.ts.map +1 -1
- package/dest/verifier/bb_verifier.js +134 -45
- 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 +2 -3
- package/dest/verifier/queued_chonk_verifier.d.ts.map +1 -1
- package/dest/verifier/queued_chonk_verifier.js +8 -7
- package/package.json +20 -18
- package/src/avm_proving_tests/avm_proving_tester.ts +53 -122
- package/src/bb/bb_js_backend.ts +435 -0
- package/src/bb/bb_js_debug.ts +227 -0
- package/src/bb/file_names.ts +6 -0
- package/src/config.ts +16 -0
- package/src/index.ts +2 -1
- package/src/instrumentation.ts +12 -4
- package/src/prover/client/bb_private_kernel_prover.ts +118 -5
- package/src/prover/proof_utils.ts +41 -1
- package/src/prover/server/bb_prover.ts +133 -137
- package/src/test/delay_values.ts +1 -1
- package/src/verification_key/verification_key_data.ts +1 -1
- package/src/verifier/batch_chonk_verifier.ts +276 -0
- package/src/verifier/bb_verifier.ts +66 -76
- package/src/verifier/index.ts +1 -0
- package/src/verifier/queued_chonk_verifier.ts +8 -8
- package/dest/bb/execute.d.ts +0 -107
- package/dest/bb/execute.d.ts.map +0 -1
- package/dest/bb/execute.js +0 -647
- package/src/bb/execute.ts +0 -678
|
@@ -0,0 +1,227 @@
|
|
|
1
|
+
import type { AvmStat } from '@aztec/bb.js';
|
|
2
|
+
import type { Logger } from '@aztec/foundation/log';
|
|
3
|
+
|
|
4
|
+
import { promises as fs } from 'fs';
|
|
5
|
+
import * as path from 'path';
|
|
6
|
+
import { gzipSync } from 'zlib';
|
|
7
|
+
|
|
8
|
+
import type { UltraHonkFlavor } from '../honk.js';
|
|
9
|
+
import type { BBJsApi, BBJsProofResult } from './bb_js_backend.js';
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* Maps UltraHonk flavors to the CLI flags used by the bb binary.
|
|
13
|
+
* The CLI always uses `--scheme ultra_honk`; flavors are expressed via
|
|
14
|
+
* `--oracle_hash` and `--ipa_accumulation`.
|
|
15
|
+
*/
|
|
16
|
+
function getCliFlags(flavor: UltraHonkFlavor): string {
|
|
17
|
+
const base = '--scheme ultra_honk --disable_zk';
|
|
18
|
+
switch (flavor) {
|
|
19
|
+
case 'ultra_honk':
|
|
20
|
+
return `${base} --oracle_hash poseidon2`;
|
|
21
|
+
case 'ultra_keccak_honk':
|
|
22
|
+
return `${base} --oracle_hash keccak`;
|
|
23
|
+
case 'ultra_starknet_honk':
|
|
24
|
+
return `${base} --oracle_hash starknet`;
|
|
25
|
+
case 'ultra_rollup_honk':
|
|
26
|
+
return `${base} --oracle_hash poseidon2 --ipa_accumulation`;
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
/** Concatenate an array of 32-byte field elements into a single buffer. */
|
|
31
|
+
function concatFields(fields: Uint8Array[]): Buffer {
|
|
32
|
+
const totalLen = fields.reduce((sum, f) => sum + f.length, 0);
|
|
33
|
+
const buf = Buffer.alloc(totalLen);
|
|
34
|
+
let offset = 0;
|
|
35
|
+
for (const f of fields) {
|
|
36
|
+
buf.set(f, offset);
|
|
37
|
+
offset += f.length;
|
|
38
|
+
}
|
|
39
|
+
return buf;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
/**
|
|
43
|
+
* Wraps a BBJsApi instance to write debug files and log equivalent CLI commands.
|
|
44
|
+
* Activated when BB_DEBUG_OUTPUT_DIR is set. Each operation writes its inputs
|
|
45
|
+
* and outputs to a numbered subdirectory, enabling offline reproduction.
|
|
46
|
+
*/
|
|
47
|
+
export class DebugBBJsInstance implements BBJsApi {
|
|
48
|
+
private counter = 0;
|
|
49
|
+
|
|
50
|
+
constructor(
|
|
51
|
+
private inner: BBJsApi,
|
|
52
|
+
private debugDir: string,
|
|
53
|
+
private bbPath: string,
|
|
54
|
+
private logger: Logger,
|
|
55
|
+
) {}
|
|
56
|
+
|
|
57
|
+
private nextDir(prefix: string): string {
|
|
58
|
+
this.counter++;
|
|
59
|
+
const padded = String(this.counter).padStart(3, '0');
|
|
60
|
+
return path.join(this.debugDir, `${prefix}-${padded}`);
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
/** Write a command string to both the logger and a command.sh file in the given directory. */
|
|
64
|
+
private async logCommand(dir: string, command: string): Promise<void> {
|
|
65
|
+
this.logger.info(`Executing BB with: ${command}`);
|
|
66
|
+
await fs.writeFile(path.join(dir, 'command.sh'), `#!/bin/bash\n${command}\n`, { mode: 0o755 });
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
async generateProof(
|
|
70
|
+
circuitName: string,
|
|
71
|
+
bytecode: Uint8Array,
|
|
72
|
+
verificationKey: Uint8Array,
|
|
73
|
+
witness: Uint8Array,
|
|
74
|
+
flavor: UltraHonkFlavor,
|
|
75
|
+
): Promise<BBJsProofResult> {
|
|
76
|
+
const dir = this.nextDir(circuitName);
|
|
77
|
+
await fs.mkdir(dir, { recursive: true });
|
|
78
|
+
|
|
79
|
+
const bytecodePath = path.join(dir, `${circuitName}-bytecode.gz`);
|
|
80
|
+
const vkPath = path.join(dir, `${circuitName}-vk`);
|
|
81
|
+
const witnessPath = path.join(dir, 'partial-witness.gz');
|
|
82
|
+
|
|
83
|
+
await Promise.all([
|
|
84
|
+
fs.writeFile(bytecodePath, gzipSync(bytecode)),
|
|
85
|
+
fs.writeFile(vkPath, verificationKey),
|
|
86
|
+
fs.writeFile(witnessPath, gzipSync(witness)),
|
|
87
|
+
]);
|
|
88
|
+
|
|
89
|
+
const flags = getCliFlags(flavor);
|
|
90
|
+
await this.logCommand(
|
|
91
|
+
dir,
|
|
92
|
+
`${this.bbPath} prove ${flags} -o ${dir} -b ${bytecodePath} -k ${vkPath} -w ${witnessPath}`,
|
|
93
|
+
);
|
|
94
|
+
|
|
95
|
+
const result = await this.inner.generateProof(circuitName, bytecode, verificationKey, witness, flavor);
|
|
96
|
+
|
|
97
|
+
const proofBuf = concatFields(result.proofFields);
|
|
98
|
+
const publicInputsBuf = concatFields(result.publicInputFields);
|
|
99
|
+
await Promise.all([
|
|
100
|
+
fs.writeFile(path.join(dir, 'proof'), proofBuf),
|
|
101
|
+
fs.writeFile(path.join(dir, 'public_inputs'), publicInputsBuf),
|
|
102
|
+
]);
|
|
103
|
+
|
|
104
|
+
return result;
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
async verifyProof(
|
|
108
|
+
proofFields: Uint8Array[],
|
|
109
|
+
verificationKey: Uint8Array,
|
|
110
|
+
publicInputFields: Uint8Array[],
|
|
111
|
+
flavor: UltraHonkFlavor,
|
|
112
|
+
): Promise<{ verified: boolean; durationMs: number }> {
|
|
113
|
+
const dir = this.nextDir(`verify-${flavor}`);
|
|
114
|
+
await fs.mkdir(dir, { recursive: true });
|
|
115
|
+
|
|
116
|
+
const proofPath = path.join(dir, 'proof');
|
|
117
|
+
const vkPath = path.join(dir, 'vk');
|
|
118
|
+
const publicInputsPath = path.join(dir, 'public_inputs');
|
|
119
|
+
|
|
120
|
+
const proofBuf = concatFields(proofFields);
|
|
121
|
+
const publicInputsBuf = concatFields(publicInputFields);
|
|
122
|
+
await Promise.all([
|
|
123
|
+
fs.writeFile(proofPath, proofBuf),
|
|
124
|
+
fs.writeFile(vkPath, verificationKey),
|
|
125
|
+
fs.writeFile(publicInputsPath, publicInputsBuf),
|
|
126
|
+
]);
|
|
127
|
+
|
|
128
|
+
const flags = getCliFlags(flavor);
|
|
129
|
+
await this.logCommand(dir, `${this.bbPath} verify ${flags} -p ${proofPath} -k ${vkPath} -i ${publicInputsPath}`);
|
|
130
|
+
|
|
131
|
+
return this.inner.verifyProof(proofFields, verificationKey, publicInputFields, flavor);
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
async verifyChonkProof(
|
|
135
|
+
fieldsWithPublicInputs: Uint8Array[],
|
|
136
|
+
verificationKey: Uint8Array,
|
|
137
|
+
): Promise<{ verified: boolean; durationMs: number }> {
|
|
138
|
+
const dir = this.nextDir('verify-chonk');
|
|
139
|
+
await fs.mkdir(dir, { recursive: true });
|
|
140
|
+
|
|
141
|
+
const proofPath = path.join(dir, 'proof');
|
|
142
|
+
const vkPath = path.join(dir, 'vk');
|
|
143
|
+
|
|
144
|
+
const proofBuf = concatFields(fieldsWithPublicInputs);
|
|
145
|
+
await Promise.all([fs.writeFile(proofPath, proofBuf), fs.writeFile(vkPath, verificationKey)]);
|
|
146
|
+
|
|
147
|
+
await this.logCommand(dir, `${this.bbPath} verify --scheme chonk -p ${proofPath} -k ${vkPath} -v`);
|
|
148
|
+
|
|
149
|
+
return this.inner.verifyChonkProof(fieldsWithPublicInputs, verificationKey);
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
async computeGateCount(
|
|
153
|
+
circuitName: string,
|
|
154
|
+
bytecode: Uint8Array,
|
|
155
|
+
flavor: UltraHonkFlavor | 'mega_honk',
|
|
156
|
+
): Promise<{ circuitSize: number; durationMs: number }> {
|
|
157
|
+
const dir = this.nextDir(`gates-${circuitName}`);
|
|
158
|
+
await fs.mkdir(dir, { recursive: true });
|
|
159
|
+
|
|
160
|
+
const bytecodePath = path.join(dir, `${circuitName}-bytecode.gz`);
|
|
161
|
+
await fs.writeFile(bytecodePath, gzipSync(bytecode));
|
|
162
|
+
|
|
163
|
+
if (flavor === 'mega_honk') {
|
|
164
|
+
await this.logCommand(dir, `${this.bbPath} gates --scheme chonk -b ${bytecodePath}`);
|
|
165
|
+
} else {
|
|
166
|
+
const flags = getCliFlags(flavor);
|
|
167
|
+
await this.logCommand(dir, `${this.bbPath} gates ${flags} -b ${bytecodePath}`);
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
return this.inner.computeGateCount(circuitName, bytecode, flavor);
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
async generateAvmProof(inputs: Uint8Array): Promise<{ proof: Uint8Array[]; stats: AvmStat[]; durationMs: number }> {
|
|
174
|
+
const dir = this.nextDir('avm-prove');
|
|
175
|
+
await fs.mkdir(dir, { recursive: true });
|
|
176
|
+
|
|
177
|
+
const inputsPath = path.join(dir, 'avm_inputs.bin');
|
|
178
|
+
await fs.writeFile(inputsPath, inputs);
|
|
179
|
+
|
|
180
|
+
await this.logCommand(dir, `${this.bbPath} avm_prove --avm-inputs ${inputsPath} -o ${dir}`);
|
|
181
|
+
|
|
182
|
+
const result = await this.inner.generateAvmProof(inputs);
|
|
183
|
+
|
|
184
|
+
const proofBuf = concatFields(result.proof);
|
|
185
|
+
await fs.writeFile(path.join(dir, 'proof'), proofBuf);
|
|
186
|
+
|
|
187
|
+
return result;
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
async verifyAvmProof(
|
|
191
|
+
proof: Uint8Array[],
|
|
192
|
+
publicInputs: Uint8Array,
|
|
193
|
+
): Promise<{ verified: boolean; durationMs: number }> {
|
|
194
|
+
const dir = this.nextDir('avm-verify');
|
|
195
|
+
await fs.mkdir(dir, { recursive: true });
|
|
196
|
+
|
|
197
|
+
const proofPath = path.join(dir, 'proof');
|
|
198
|
+
const publicInputsPath = path.join(dir, 'avm_public_inputs.bin');
|
|
199
|
+
|
|
200
|
+
const proofBuf = concatFields(proof);
|
|
201
|
+
await Promise.all([fs.writeFile(proofPath, proofBuf), fs.writeFile(publicInputsPath, publicInputs)]);
|
|
202
|
+
|
|
203
|
+
await this.logCommand(dir, `${this.bbPath} avm_verify -p ${proofPath} --avm-public-inputs ${publicInputsPath}`);
|
|
204
|
+
|
|
205
|
+
return this.inner.verifyAvmProof(proof, publicInputs);
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
async checkAvmCircuit(inputs: Uint8Array): Promise<{ passed: boolean; stats: AvmStat[]; durationMs: number }> {
|
|
209
|
+
const dir = this.nextDir('avm-check-circuit');
|
|
210
|
+
await fs.mkdir(dir, { recursive: true });
|
|
211
|
+
|
|
212
|
+
const inputsPath = path.join(dir, 'avm_inputs.bin');
|
|
213
|
+
await fs.writeFile(inputsPath, inputs);
|
|
214
|
+
|
|
215
|
+
await this.logCommand(dir, `${this.bbPath} avm_check_circuit --avm-inputs ${inputsPath}`);
|
|
216
|
+
|
|
217
|
+
return this.inner.checkAvmCircuit(inputs);
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
generateContract(verificationKey: Uint8Array): Promise<{ solidityCode: string; durationMs: number }> {
|
|
221
|
+
return this.inner.generateContract(verificationKey);
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
destroy(): Promise<void> {
|
|
225
|
+
return this.inner.destroy();
|
|
226
|
+
}
|
|
227
|
+
}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
// File-naming conventions used by `bb` CLI output directories. Retained for consumers that still
|
|
2
|
+
// read/write proofs to disk alongside bb-prover's in-memory bb.js flows.
|
|
3
|
+
|
|
4
|
+
export const VK_FILENAME = 'vk';
|
|
5
|
+
export const PROOF_FILENAME = 'proof';
|
|
6
|
+
export const PUBLIC_INPUTS_FILENAME = 'public_inputs';
|
package/src/config.ts
CHANGED
|
@@ -3,8 +3,24 @@ export interface BBConfig {
|
|
|
3
3
|
bbWorkingDirectory: string;
|
|
4
4
|
/** Whether to skip tmp dir cleanup for debugging purposes */
|
|
5
5
|
bbSkipCleanup: boolean;
|
|
6
|
+
/**
|
|
7
|
+
* Number of long-lived bb processes pooled by the RPC verifier (BBCircuitVerifier).
|
|
8
|
+
* Also caps concurrent verifications via the wrapping QueuedIVCVerifier.
|
|
9
|
+
*/
|
|
6
10
|
numConcurrentIVCVerifiers: number;
|
|
11
|
+
/** Thread count for the RPC IVC verifier. */
|
|
7
12
|
bbIVCConcurrency: number;
|
|
13
|
+
/**
|
|
14
|
+
* Upper bound on proofs per batch for the peer chonk batch verifier.
|
|
15
|
+
* Proofs are verified immediately as they arrive — this only caps how many
|
|
16
|
+
* can accumulate while a batch is already being processed.
|
|
17
|
+
* Default 16: at 4 cores, a full batch of 16 verifies in ~245ms wall time.
|
|
18
|
+
*/
|
|
19
|
+
bbChonkVerifyMaxBatch: number;
|
|
20
|
+
/** Thread count for the peer batch verifier parallel reduce. Default 6 to leave cores for the rest of the node. */
|
|
21
|
+
bbChonkVerifyConcurrency: number;
|
|
22
|
+
/** When set, bb.js operations write input/output files and log equivalent CLI commands to this directory. */
|
|
23
|
+
bbDebugOutputDir?: string;
|
|
8
24
|
}
|
|
9
25
|
|
|
10
26
|
export interface ACVMConfig {
|
package/src/index.ts
CHANGED
|
@@ -2,7 +2,8 @@ export * from './prover/index.js';
|
|
|
2
2
|
export * from './test/index.js';
|
|
3
3
|
export * from './verifier/index.js';
|
|
4
4
|
export * from './config.js';
|
|
5
|
-
export * from './bb/
|
|
5
|
+
export * from './bb/file_names.js';
|
|
6
|
+
export * from './bb/bb_js_backend.js';
|
|
6
7
|
export * from './honk.js';
|
|
7
8
|
export * from './verification_key/verification_key_data.js';
|
|
8
9
|
|
package/src/instrumentation.ts
CHANGED
|
@@ -58,10 +58,18 @@ export class ProverInstrumentation {
|
|
|
58
58
|
circuitName: CircuitName,
|
|
59
59
|
timerOrMS: Timer | number,
|
|
60
60
|
) {
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
61
|
+
// Simulation duration is stored in ms, while the others are stored in seconds
|
|
62
|
+
if (metric === 'simulationDuration') {
|
|
63
|
+
const ms = typeof timerOrMS === 'number' ? timerOrMS : timerOrMS.ms();
|
|
64
|
+
this[metric].record(Math.trunc(ms), {
|
|
65
|
+
[Attributes.PROTOCOL_CIRCUIT_NAME]: circuitName,
|
|
66
|
+
});
|
|
67
|
+
} else {
|
|
68
|
+
const s = typeof timerOrMS === 'number' ? timerOrMS / 1000 : timerOrMS.s();
|
|
69
|
+
this[metric].record(s, {
|
|
70
|
+
[Attributes.PROTOCOL_CIRCUIT_NAME]: circuitName,
|
|
71
|
+
});
|
|
72
|
+
}
|
|
65
73
|
}
|
|
66
74
|
|
|
67
75
|
/**
|
|
@@ -5,8 +5,16 @@ import { serializeWitness } from '@aztec/noir-noirc_abi';
|
|
|
5
5
|
import {
|
|
6
6
|
convertHidingKernelPublicInputsToWitnessMapWithAbi,
|
|
7
7
|
convertHidingKernelToRollupInputsToWitnessMapWithAbi,
|
|
8
|
+
convertPrivateKernelInit2InputsToWitnessMapWithAbi,
|
|
9
|
+
convertPrivateKernelInit2OutputsFromWitnessMapWithAbi,
|
|
10
|
+
convertPrivateKernelInit3InputsToWitnessMapWithAbi,
|
|
11
|
+
convertPrivateKernelInit3OutputsFromWitnessMapWithAbi,
|
|
8
12
|
convertPrivateKernelInitInputsToWitnessMapWithAbi,
|
|
9
13
|
convertPrivateKernelInitOutputsFromWitnessMapWithAbi,
|
|
14
|
+
convertPrivateKernelInner2InputsToWitnessMapWithAbi,
|
|
15
|
+
convertPrivateKernelInner2OutputsFromWitnessMapWithAbi,
|
|
16
|
+
convertPrivateKernelInner3InputsToWitnessMapWithAbi,
|
|
17
|
+
convertPrivateKernelInner3OutputsFromWitnessMapWithAbi,
|
|
10
18
|
convertPrivateKernelInnerInputsToWitnessMapWithAbi,
|
|
11
19
|
convertPrivateKernelInnerOutputsFromWitnessMapWithAbi,
|
|
12
20
|
convertPrivateKernelResetInputsToWitnessMapWithAbi,
|
|
@@ -32,7 +40,11 @@ import type {
|
|
|
32
40
|
HidingKernelToRollupPrivateInputs,
|
|
33
41
|
PrivateExecutionStep,
|
|
34
42
|
PrivateKernelCircuitPublicInputs,
|
|
43
|
+
PrivateKernelInit2CircuitPrivateInputs,
|
|
44
|
+
PrivateKernelInit3CircuitPrivateInputs,
|
|
35
45
|
PrivateKernelInitCircuitPrivateInputs,
|
|
46
|
+
PrivateKernelInner2CircuitPrivateInputs,
|
|
47
|
+
PrivateKernelInner3CircuitPrivateInputs,
|
|
36
48
|
PrivateKernelInnerCircuitPrivateInputs,
|
|
37
49
|
PrivateKernelResetCircuitPrivateInputs,
|
|
38
50
|
PrivateKernelSimulateOutput,
|
|
@@ -79,6 +91,50 @@ export abstract class BBPrivateKernelProver implements PrivateKernelProver {
|
|
|
79
91
|
);
|
|
80
92
|
}
|
|
81
93
|
|
|
94
|
+
public async generateInit2Output(
|
|
95
|
+
inputs: PrivateKernelInit2CircuitPrivateInputs,
|
|
96
|
+
): Promise<PrivateKernelSimulateOutput<PrivateKernelCircuitPublicInputs>> {
|
|
97
|
+
return await this.generateCircuitOutput(
|
|
98
|
+
inputs,
|
|
99
|
+
'PrivateKernelInit2Artifact',
|
|
100
|
+
convertPrivateKernelInit2InputsToWitnessMapWithAbi,
|
|
101
|
+
convertPrivateKernelInit2OutputsFromWitnessMapWithAbi,
|
|
102
|
+
);
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
public async simulateInit2(
|
|
106
|
+
inputs: PrivateKernelInit2CircuitPrivateInputs,
|
|
107
|
+
): Promise<PrivateKernelSimulateOutput<PrivateKernelCircuitPublicInputs>> {
|
|
108
|
+
return await this.simulateCircuitOutput(
|
|
109
|
+
inputs,
|
|
110
|
+
'PrivateKernelInit2Artifact',
|
|
111
|
+
convertPrivateKernelInit2InputsToWitnessMapWithAbi,
|
|
112
|
+
convertPrivateKernelInit2OutputsFromWitnessMapWithAbi,
|
|
113
|
+
);
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
public async generateInit3Output(
|
|
117
|
+
inputs: PrivateKernelInit3CircuitPrivateInputs,
|
|
118
|
+
): Promise<PrivateKernelSimulateOutput<PrivateKernelCircuitPublicInputs>> {
|
|
119
|
+
return await this.generateCircuitOutput(
|
|
120
|
+
inputs,
|
|
121
|
+
'PrivateKernelInit3Artifact',
|
|
122
|
+
convertPrivateKernelInit3InputsToWitnessMapWithAbi,
|
|
123
|
+
convertPrivateKernelInit3OutputsFromWitnessMapWithAbi,
|
|
124
|
+
);
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
public async simulateInit3(
|
|
128
|
+
inputs: PrivateKernelInit3CircuitPrivateInputs,
|
|
129
|
+
): Promise<PrivateKernelSimulateOutput<PrivateKernelCircuitPublicInputs>> {
|
|
130
|
+
return await this.simulateCircuitOutput(
|
|
131
|
+
inputs,
|
|
132
|
+
'PrivateKernelInit3Artifact',
|
|
133
|
+
convertPrivateKernelInit3InputsToWitnessMapWithAbi,
|
|
134
|
+
convertPrivateKernelInit3OutputsFromWitnessMapWithAbi,
|
|
135
|
+
);
|
|
136
|
+
}
|
|
137
|
+
|
|
82
138
|
public async generateInnerOutput(
|
|
83
139
|
inputs: PrivateKernelInnerCircuitPrivateInputs,
|
|
84
140
|
): Promise<PrivateKernelSimulateOutput<PrivateKernelCircuitPublicInputs>> {
|
|
@@ -101,6 +157,50 @@ export abstract class BBPrivateKernelProver implements PrivateKernelProver {
|
|
|
101
157
|
);
|
|
102
158
|
}
|
|
103
159
|
|
|
160
|
+
public async generateInner2Output(
|
|
161
|
+
inputs: PrivateKernelInner2CircuitPrivateInputs,
|
|
162
|
+
): Promise<PrivateKernelSimulateOutput<PrivateKernelCircuitPublicInputs>> {
|
|
163
|
+
return await this.generateCircuitOutput(
|
|
164
|
+
inputs,
|
|
165
|
+
'PrivateKernelInner2Artifact',
|
|
166
|
+
convertPrivateKernelInner2InputsToWitnessMapWithAbi,
|
|
167
|
+
convertPrivateKernelInner2OutputsFromWitnessMapWithAbi,
|
|
168
|
+
);
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
public async simulateInner2(
|
|
172
|
+
inputs: PrivateKernelInner2CircuitPrivateInputs,
|
|
173
|
+
): Promise<PrivateKernelSimulateOutput<PrivateKernelCircuitPublicInputs>> {
|
|
174
|
+
return await this.simulateCircuitOutput(
|
|
175
|
+
inputs,
|
|
176
|
+
'PrivateKernelInner2Artifact',
|
|
177
|
+
convertPrivateKernelInner2InputsToWitnessMapWithAbi,
|
|
178
|
+
convertPrivateKernelInner2OutputsFromWitnessMapWithAbi,
|
|
179
|
+
);
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
public async generateInner3Output(
|
|
183
|
+
inputs: PrivateKernelInner3CircuitPrivateInputs,
|
|
184
|
+
): Promise<PrivateKernelSimulateOutput<PrivateKernelCircuitPublicInputs>> {
|
|
185
|
+
return await this.generateCircuitOutput(
|
|
186
|
+
inputs,
|
|
187
|
+
'PrivateKernelInner3Artifact',
|
|
188
|
+
convertPrivateKernelInner3InputsToWitnessMapWithAbi,
|
|
189
|
+
convertPrivateKernelInner3OutputsFromWitnessMapWithAbi,
|
|
190
|
+
);
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
public async simulateInner3(
|
|
194
|
+
inputs: PrivateKernelInner3CircuitPrivateInputs,
|
|
195
|
+
): Promise<PrivateKernelSimulateOutput<PrivateKernelCircuitPublicInputs>> {
|
|
196
|
+
return await this.simulateCircuitOutput(
|
|
197
|
+
inputs,
|
|
198
|
+
'PrivateKernelInner3Artifact',
|
|
199
|
+
convertPrivateKernelInner3InputsToWitnessMapWithAbi,
|
|
200
|
+
convertPrivateKernelInner3OutputsFromWitnessMapWithAbi,
|
|
201
|
+
);
|
|
202
|
+
}
|
|
203
|
+
|
|
104
204
|
public async generateResetOutput(
|
|
105
205
|
inputs: PrivateKernelResetCircuitPrivateInputs,
|
|
106
206
|
): Promise<PrivateKernelSimulateOutput<PrivateKernelCircuitPublicInputs>> {
|
|
@@ -278,23 +378,36 @@ export abstract class BBPrivateKernelProver implements PrivateKernelProver {
|
|
|
278
378
|
this.log.info(`Generating ClientIVC proof...`);
|
|
279
379
|
const barretenberg = await Barretenberg.initSingleton({
|
|
280
380
|
...this.options,
|
|
281
|
-
logger: this.options.logger?.
|
|
381
|
+
logger: this.options.logger?.verbose,
|
|
282
382
|
});
|
|
283
383
|
const backend = new AztecClientBackend(
|
|
284
384
|
executionSteps.map(step => ungzip(step.bytecode)),
|
|
285
385
|
barretenberg,
|
|
386
|
+
executionSteps.map(step => step.functionName),
|
|
286
387
|
);
|
|
287
388
|
|
|
288
|
-
|
|
389
|
+
// Use compressed prove path to get both proof fields and compressed proof bytes
|
|
390
|
+
const result = await backend.prove(
|
|
289
391
|
executionSteps.map(step => ungzip(serializeWitness(step.witness))),
|
|
290
392
|
executionSteps.map(step => step.vk),
|
|
393
|
+
{ compress: true },
|
|
291
394
|
);
|
|
292
395
|
this.log.info(`Generated ClientIVC proof`, {
|
|
293
396
|
eventName: 'client-ivc-proof-generation',
|
|
294
397
|
duration: timer.ms(),
|
|
295
|
-
proofSize:
|
|
398
|
+
proofSize: result.proofFields.length,
|
|
399
|
+
compressedSize: result.compressedProof?.length,
|
|
296
400
|
});
|
|
297
|
-
|
|
401
|
+
|
|
402
|
+
// Create ChonkProofWithPublicInputs from the flat field elements
|
|
403
|
+
const proofWithPubInputs = ChonkProofWithPublicInputs.fromBufferArray(result.proofFields);
|
|
404
|
+
|
|
405
|
+
// Attach compressed proof bytes to the ChonkProof (without public inputs).
|
|
406
|
+
// The compressed bytes are for the full proof WITH public inputs from bb;
|
|
407
|
+
// when deserializing, the decompressor will strip them to match CHONK_PROOF_LENGTH.
|
|
408
|
+
proofWithPubInputs.compressedProof = result.compressedProof ? Buffer.from(result.compressedProof) : undefined;
|
|
409
|
+
|
|
410
|
+
return proofWithPubInputs;
|
|
298
411
|
}
|
|
299
412
|
|
|
300
413
|
public async computeGateCountForCircuit(_bytecode: Buffer, _circuitName: string): Promise<number> {
|
|
@@ -303,7 +416,7 @@ export abstract class BBPrivateKernelProver implements PrivateKernelProver {
|
|
|
303
416
|
...this.options,
|
|
304
417
|
logger: this.options.logger?.[(process.env.LOG_LEVEL as LogLevel) || 'verbose'],
|
|
305
418
|
});
|
|
306
|
-
const backend = new AztecClientBackend([ungzip(_bytecode)], barretenberg);
|
|
419
|
+
const backend = new AztecClientBackend([ungzip(_bytecode)], barretenberg, [_circuitName]);
|
|
307
420
|
const gateCount = await backend.gates();
|
|
308
421
|
return gateCount[0];
|
|
309
422
|
}
|
|
@@ -16,7 +16,7 @@ import assert from 'assert';
|
|
|
16
16
|
import { promises as fs } from 'fs';
|
|
17
17
|
import * as path from 'path';
|
|
18
18
|
|
|
19
|
-
import { PROOF_FILENAME, PUBLIC_INPUTS_FILENAME } from '../bb/
|
|
19
|
+
import { PROOF_FILENAME, PUBLIC_INPUTS_FILENAME } from '../bb/file_names.js';
|
|
20
20
|
|
|
21
21
|
/**
|
|
22
22
|
* Create a ChonkProof proof file.
|
|
@@ -113,3 +113,43 @@ export async function readProofsFromOutputDirectory<PROOF_LENGTH extends number>
|
|
|
113
113
|
proofLength,
|
|
114
114
|
);
|
|
115
115
|
}
|
|
116
|
+
|
|
117
|
+
/**
|
|
118
|
+
* Construct a RecursiveProof from in-memory proof and public input field arrays
|
|
119
|
+
* returned by the bb.js circuitProve API, without reading from files.
|
|
120
|
+
*
|
|
121
|
+
* @param proofFields - Proof fields as 32-byte Uint8Arrays from circuitProve.
|
|
122
|
+
* @param publicInputFields - Public input fields as 32-byte Uint8Arrays from circuitProve.
|
|
123
|
+
* @param vkData - Verification key data for the circuit.
|
|
124
|
+
* @param proofLength - Expected proof field count.
|
|
125
|
+
*/
|
|
126
|
+
export function constructRecursiveProofFromBuffers<PROOF_LENGTH extends number>(
|
|
127
|
+
proofFields: Uint8Array[],
|
|
128
|
+
publicInputFields: Uint8Array[],
|
|
129
|
+
vkData: VerificationKeyData,
|
|
130
|
+
proofLength: PROOF_LENGTH,
|
|
131
|
+
): RecursiveProof<PROOF_LENGTH> {
|
|
132
|
+
assert(
|
|
133
|
+
proofLength == NESTED_RECURSIVE_PROOF_LENGTH ||
|
|
134
|
+
proofLength == NESTED_RECURSIVE_ROLLUP_HONK_PROOF_LENGTH ||
|
|
135
|
+
proofLength == ULTRA_KECCAK_PROOF_LENGTH,
|
|
136
|
+
`Proof length must be one of the expected proof lengths, received ${proofLength}`,
|
|
137
|
+
);
|
|
138
|
+
|
|
139
|
+
// Convert Uint8Array fields to Fr instances
|
|
140
|
+
const proofFieldsFr = proofFields.map(f => Fr.fromBuffer(Buffer.from(f)));
|
|
141
|
+
|
|
142
|
+
assert(
|
|
143
|
+
proofFieldsFr.length == proofLength,
|
|
144
|
+
`Proof fields length mismatch: ${proofFieldsFr.length} != ${proofLength}`,
|
|
145
|
+
);
|
|
146
|
+
|
|
147
|
+
// Reconstruct the binary proof with public inputs prepended (same format as file-based path)
|
|
148
|
+
const binaryPublicInputs = Buffer.concat(publicInputFields.map(f => Buffer.from(f)));
|
|
149
|
+
const binaryProof = Buffer.concat(proofFields.map(f => Buffer.from(f)));
|
|
150
|
+
const binaryProofWithPublicInputs = Buffer.concat([binaryPublicInputs, binaryProof]);
|
|
151
|
+
|
|
152
|
+
const numPublicInputs = getNumCustomPublicInputs(proofLength, vkData);
|
|
153
|
+
|
|
154
|
+
return new RecursiveProof(proofFieldsFr, new Proof(binaryProofWithPublicInputs, numPublicInputs), true, proofLength);
|
|
155
|
+
}
|