@aztec/bb-prover 0.40.1 → 0.42.0
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/bb/cli.d.ts.map +1 -1
- package/dest/bb/cli.js +24 -2
- package/dest/bb/execute.d.ts +37 -2
- package/dest/bb/execute.d.ts.map +1 -1
- package/dest/bb/execute.js +276 -75
- package/dest/config.d.ts +9 -0
- package/dest/config.d.ts.map +1 -0
- package/dest/config.js +2 -0
- package/dest/index.d.ts +2 -0
- package/dest/index.d.ts.map +1 -1
- package/dest/index.js +3 -1
- package/dest/mappings/mappings.d.ts +1 -0
- package/dest/mappings/mappings.d.ts.map +1 -1
- package/dest/mappings/mappings.js +27 -8
- package/dest/prover/bb_native_proof_creator.d.ts +4 -9
- package/dest/prover/bb_native_proof_creator.d.ts.map +1 -1
- package/dest/prover/bb_native_proof_creator.js +77 -101
- package/dest/prover/bb_prover.d.ts +35 -23
- package/dest/prover/bb_prover.d.ts.map +1 -1
- package/dest/prover/bb_prover.js +247 -155
- package/dest/stats.d.ts +2 -5
- package/dest/stats.d.ts.map +1 -1
- package/dest/stats.js +27 -26
- package/dest/test/index.d.ts +1 -0
- package/dest/test/index.d.ts.map +1 -1
- package/dest/test/index.js +2 -1
- package/dest/test/test_circuit_prover.d.ts +9 -7
- package/dest/test/test_circuit_prover.d.ts.map +1 -1
- package/dest/test/test_circuit_prover.js +31 -15
- package/dest/test/test_verifier.d.ts +7 -0
- package/dest/test/test_verifier.d.ts.map +1 -0
- package/dest/test/test_verifier.js +10 -0
- package/dest/verification_key/verification_key_data.d.ts +8 -0
- package/dest/verification_key/verification_key_data.d.ts.map +1 -0
- package/dest/verification_key/verification_key_data.js +24 -0
- package/dest/verifier/bb_verifier.d.ts +18 -0
- package/dest/verifier/bb_verifier.d.ts.map +1 -0
- package/dest/verifier/bb_verifier.js +90 -0
- package/dest/verifier/index.d.ts +2 -0
- package/dest/verifier/index.d.ts.map +1 -0
- package/dest/verifier/index.js +2 -0
- package/package.json +6 -6
- package/src/bb/cli.ts +36 -1
- package/src/bb/execute.ts +371 -83
- package/src/config.ts +9 -0
- package/src/index.ts +2 -0
- package/src/mappings/mappings.ts +38 -12
- package/src/prover/bb_native_proof_creator.ts +139 -119
- package/src/prover/bb_prover.ts +454 -242
- package/src/stats.ts +30 -45
- package/src/test/index.ts +1 -0
- package/src/test/test_circuit_prover.ts +84 -21
- package/src/test/test_verifier.ts +12 -0
- package/src/verification_key/verification_key_data.ts +35 -0
- package/src/verifier/bb_verifier.ts +156 -0
- package/src/verifier/index.ts +1 -0
- package/dest/prover/verification_key_data.d.ts +0 -16
- package/dest/prover/verification_key_data.d.ts.map +0 -1
- package/dest/prover/verification_key_data.js +0 -5
- package/src/prover/verification_key_data.ts +0 -16
package/src/stats.ts
CHANGED
|
@@ -1,45 +1,6 @@
|
|
|
1
1
|
import { type PublicKernelRequest, PublicKernelType } from '@aztec/circuit-types';
|
|
2
|
-
import type { CircuitName
|
|
3
|
-
import { type
|
|
4
|
-
import { type ServerProtocolArtifact } from '@aztec/noir-protocol-circuits-types';
|
|
5
|
-
|
|
6
|
-
export function emitCircuitWitnessGenerationStats(
|
|
7
|
-
circuitName: CircuitName,
|
|
8
|
-
duration: number,
|
|
9
|
-
inputSize: number,
|
|
10
|
-
outputSize: number,
|
|
11
|
-
logger: Logger,
|
|
12
|
-
) {
|
|
13
|
-
const stats: CircuitWitnessGenerationStats = {
|
|
14
|
-
eventName: 'circuit-witness-generation',
|
|
15
|
-
circuitName,
|
|
16
|
-
inputSize,
|
|
17
|
-
outputSize,
|
|
18
|
-
duration,
|
|
19
|
-
};
|
|
20
|
-
|
|
21
|
-
logger.debug('Circuit witness generation stats', stats);
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
export function emitCircuitProvingStats(
|
|
25
|
-
circuitName: CircuitName,
|
|
26
|
-
duration: number,
|
|
27
|
-
inputSize: number,
|
|
28
|
-
outputSize: number,
|
|
29
|
-
proofSize: number,
|
|
30
|
-
logger: Logger,
|
|
31
|
-
) {
|
|
32
|
-
const stats: CircuitProvingStats = {
|
|
33
|
-
eventName: 'circuit-proving',
|
|
34
|
-
circuitName,
|
|
35
|
-
duration,
|
|
36
|
-
inputSize,
|
|
37
|
-
outputSize,
|
|
38
|
-
proofSize,
|
|
39
|
-
};
|
|
40
|
-
|
|
41
|
-
logger.debug('Circuit proving stats', stats);
|
|
42
|
-
}
|
|
2
|
+
import type { CircuitName } from '@aztec/circuit-types/stats';
|
|
3
|
+
import { type ClientProtocolArtifact, type ServerProtocolArtifact } from '@aztec/noir-protocol-circuits-types';
|
|
43
4
|
|
|
44
5
|
export function mapPublicKernelToCircuitName(kernelType: PublicKernelRequest['type']): CircuitName {
|
|
45
6
|
switch (kernelType) {
|
|
@@ -56,8 +17,10 @@ export function mapPublicKernelToCircuitName(kernelType: PublicKernelRequest['ty
|
|
|
56
17
|
}
|
|
57
18
|
}
|
|
58
19
|
|
|
59
|
-
export function
|
|
60
|
-
|
|
20
|
+
export function mapProtocolArtifactNameToCircuitName(
|
|
21
|
+
artifact: ServerProtocolArtifact | ClientProtocolArtifact,
|
|
22
|
+
): CircuitName {
|
|
23
|
+
switch (artifact) {
|
|
61
24
|
case 'BaseParityArtifact':
|
|
62
25
|
return 'base-parity';
|
|
63
26
|
case 'RootParityArtifact':
|
|
@@ -76,7 +39,29 @@ export function circuitTypeToCircuitName(circuitType: ServerProtocolArtifact): C
|
|
|
76
39
|
return 'public-kernel-teardown';
|
|
77
40
|
case 'PublicKernelTailArtifact':
|
|
78
41
|
return 'public-kernel-tail';
|
|
79
|
-
|
|
80
|
-
|
|
42
|
+
case 'PrivateKernelInitArtifact':
|
|
43
|
+
return 'private-kernel-init';
|
|
44
|
+
case 'PrivateKernelInnerArtifact':
|
|
45
|
+
return 'private-kernel-inner';
|
|
46
|
+
case 'PrivateKernelTailArtifact':
|
|
47
|
+
return 'private-kernel-tail';
|
|
48
|
+
case 'PrivateKernelTailToPublicArtifact':
|
|
49
|
+
return 'private-kernel-tail-to-public';
|
|
50
|
+
case 'PrivateKernelResetFullArtifact':
|
|
51
|
+
return 'private-kernel-reset-full';
|
|
52
|
+
case 'PrivateKernelResetBigArtifact':
|
|
53
|
+
return 'private-kernel-reset-big';
|
|
54
|
+
case 'PrivateKernelResetMediumArtifact':
|
|
55
|
+
return 'private-kernel-reset-medium';
|
|
56
|
+
case 'PrivateKernelResetSmallArtifact':
|
|
57
|
+
return 'private-kernel-reset-small';
|
|
58
|
+
case 'EmptyNestedArtifact':
|
|
59
|
+
return 'empty-nested';
|
|
60
|
+
case 'PrivateKernelEmptyArtifact':
|
|
61
|
+
return 'private-kernel-empty';
|
|
62
|
+
default: {
|
|
63
|
+
const _foo: never = artifact;
|
|
64
|
+
throw new Error(`Unknown circuit type: ${artifact}`);
|
|
65
|
+
}
|
|
81
66
|
}
|
|
82
67
|
}
|
package/src/test/index.ts
CHANGED
|
@@ -1,18 +1,23 @@
|
|
|
1
1
|
import {
|
|
2
|
-
type
|
|
2
|
+
type ProofAndVerificationKey,
|
|
3
|
+
type PublicInputsAndRecursiveProof,
|
|
3
4
|
type PublicKernelNonTailRequest,
|
|
4
5
|
type PublicKernelTailRequest,
|
|
5
6
|
PublicKernelType,
|
|
6
7
|
type ServerCircuitProver,
|
|
7
|
-
|
|
8
|
+
makePublicInputsAndRecursiveProof,
|
|
8
9
|
} from '@aztec/circuit-types';
|
|
9
10
|
import {
|
|
11
|
+
type AvmCircuitInputs,
|
|
10
12
|
type BaseOrMergeRollupPublicInputs,
|
|
11
13
|
type BaseParityInputs,
|
|
12
14
|
type BaseRollupInputs,
|
|
15
|
+
EmptyNestedData,
|
|
13
16
|
type KernelCircuitPublicInputs,
|
|
14
17
|
type MergeRollupInputs,
|
|
15
18
|
NESTED_RECURSIVE_PROOF_LENGTH,
|
|
19
|
+
type PrivateKernelEmptyInputData,
|
|
20
|
+
PrivateKernelEmptyInputs,
|
|
16
21
|
type Proof,
|
|
17
22
|
type PublicKernelCircuitPublicInputs,
|
|
18
23
|
RECURSIVE_PROOF_LENGTH,
|
|
@@ -21,7 +26,9 @@ import {
|
|
|
21
26
|
type RootRollupInputs,
|
|
22
27
|
type RootRollupPublicInputs,
|
|
23
28
|
VerificationKeyAsFields,
|
|
29
|
+
VerificationKeyData,
|
|
24
30
|
makeEmptyProof,
|
|
31
|
+
makeEmptyRecursiveProof,
|
|
25
32
|
makeRecursiveProof,
|
|
26
33
|
} from '@aztec/circuits.js';
|
|
27
34
|
import { createDebugLogger } from '@aztec/foundation/log';
|
|
@@ -29,27 +36,30 @@ import { Timer } from '@aztec/foundation/timer';
|
|
|
29
36
|
import {
|
|
30
37
|
BaseParityArtifact,
|
|
31
38
|
MergeRollupArtifact,
|
|
39
|
+
PrivateKernelEmptyArtifact,
|
|
32
40
|
RootParityArtifact,
|
|
33
41
|
RootRollupArtifact,
|
|
34
|
-
ServerCircuitArtifacts,
|
|
35
42
|
type ServerProtocolArtifact,
|
|
36
43
|
SimulatedBaseRollupArtifact,
|
|
44
|
+
SimulatedServerCircuitArtifacts,
|
|
37
45
|
convertBaseParityInputsToWitnessMap,
|
|
38
46
|
convertBaseParityOutputsFromWitnessMap,
|
|
39
47
|
convertMergeRollupInputsToWitnessMap,
|
|
40
48
|
convertMergeRollupOutputsFromWitnessMap,
|
|
41
|
-
|
|
42
|
-
|
|
49
|
+
convertPrivateKernelEmptyInputsToWitnessMap,
|
|
50
|
+
convertPrivateKernelEmptyOutputsFromWitnessMap,
|
|
43
51
|
convertRootParityInputsToWitnessMap,
|
|
44
52
|
convertRootParityOutputsFromWitnessMap,
|
|
45
53
|
convertRootRollupInputsToWitnessMap,
|
|
46
54
|
convertRootRollupOutputsFromWitnessMap,
|
|
47
55
|
convertSimulatedBaseRollupInputsToWitnessMap,
|
|
48
56
|
convertSimulatedBaseRollupOutputsFromWitnessMap,
|
|
57
|
+
convertSimulatedPublicTailInputsToWitnessMap,
|
|
58
|
+
convertSimulatedPublicTailOutputFromWitnessMap,
|
|
49
59
|
} from '@aztec/noir-protocol-circuits-types';
|
|
50
60
|
import { type SimulationProvider, WASMSimulator, emitCircuitSimulationStats } from '@aztec/simulator';
|
|
51
61
|
|
|
52
|
-
import {
|
|
62
|
+
import { SimulatedPublicKernelArtifactMapping } from '../mappings/mappings.js';
|
|
53
63
|
import { mapPublicKernelToCircuitName } from '../stats.js';
|
|
54
64
|
|
|
55
65
|
const VERIFICATION_KEYS: Record<ServerProtocolArtifact, VerificationKeyAsFields> = {
|
|
@@ -62,6 +72,8 @@ const VERIFICATION_KEYS: Record<ServerProtocolArtifact, VerificationKeyAsFields>
|
|
|
62
72
|
BaseRollupArtifact: VerificationKeyAsFields.makeFake(),
|
|
63
73
|
MergeRollupArtifact: VerificationKeyAsFields.makeFake(),
|
|
64
74
|
RootRollupArtifact: VerificationKeyAsFields.makeFake(),
|
|
75
|
+
PrivateKernelEmptyArtifact: VerificationKeyAsFields.makeFake(),
|
|
76
|
+
EmptyNestedArtifact: VerificationKeyAsFields.makeFake(),
|
|
65
77
|
};
|
|
66
78
|
|
|
67
79
|
/**
|
|
@@ -76,6 +88,25 @@ export class TestCircuitProver implements ServerCircuitProver {
|
|
|
76
88
|
private logger = createDebugLogger('aztec:test-prover'),
|
|
77
89
|
) {}
|
|
78
90
|
|
|
91
|
+
public async getEmptyPrivateKernelProof(
|
|
92
|
+
inputs: PrivateKernelEmptyInputData,
|
|
93
|
+
): Promise<PublicInputsAndRecursiveProof<KernelCircuitPublicInputs>> {
|
|
94
|
+
const emptyNested = new EmptyNestedData(
|
|
95
|
+
makeRecursiveProof(RECURSIVE_PROOF_LENGTH),
|
|
96
|
+
VERIFICATION_KEYS['EmptyNestedArtifact'],
|
|
97
|
+
);
|
|
98
|
+
const kernelInputs = new PrivateKernelEmptyInputs(emptyNested, inputs.header, inputs.chainId, inputs.version);
|
|
99
|
+
const witnessMap = convertPrivateKernelEmptyInputsToWitnessMap(kernelInputs);
|
|
100
|
+
const witness = await this.wasmSimulator.simulateCircuit(witnessMap, PrivateKernelEmptyArtifact);
|
|
101
|
+
const result = convertPrivateKernelEmptyOutputsFromWitnessMap(witness);
|
|
102
|
+
|
|
103
|
+
return makePublicInputsAndRecursiveProof(
|
|
104
|
+
result,
|
|
105
|
+
makeRecursiveProof(NESTED_RECURSIVE_PROOF_LENGTH),
|
|
106
|
+
VerificationKeyData.makeFake(),
|
|
107
|
+
);
|
|
108
|
+
}
|
|
109
|
+
|
|
79
110
|
/**
|
|
80
111
|
* Simulates the base parity circuit from its inputs.
|
|
81
112
|
* @param inputs - Inputs to the circuit.
|
|
@@ -146,7 +177,7 @@ export class TestCircuitProver implements ServerCircuitProver {
|
|
|
146
177
|
*/
|
|
147
178
|
public async getBaseRollupProof(
|
|
148
179
|
input: BaseRollupInputs,
|
|
149
|
-
): Promise<
|
|
180
|
+
): Promise<PublicInputsAndRecursiveProof<BaseOrMergeRollupPublicInputs>> {
|
|
150
181
|
const timer = new Timer();
|
|
151
182
|
const witnessMap = convertSimulatedBaseRollupInputsToWitnessMap(input);
|
|
152
183
|
|
|
@@ -162,7 +193,11 @@ export class TestCircuitProver implements ServerCircuitProver {
|
|
|
162
193
|
result.toBuffer().length,
|
|
163
194
|
this.logger,
|
|
164
195
|
);
|
|
165
|
-
return
|
|
196
|
+
return makePublicInputsAndRecursiveProof(
|
|
197
|
+
result,
|
|
198
|
+
makeRecursiveProof(NESTED_RECURSIVE_PROOF_LENGTH),
|
|
199
|
+
VerificationKeyData.makeFake(),
|
|
200
|
+
);
|
|
166
201
|
}
|
|
167
202
|
/**
|
|
168
203
|
* Simulates the merge rollup circuit from its inputs.
|
|
@@ -171,7 +206,7 @@ export class TestCircuitProver implements ServerCircuitProver {
|
|
|
171
206
|
*/
|
|
172
207
|
public async getMergeRollupProof(
|
|
173
208
|
input: MergeRollupInputs,
|
|
174
|
-
): Promise<
|
|
209
|
+
): Promise<PublicInputsAndRecursiveProof<BaseOrMergeRollupPublicInputs>> {
|
|
175
210
|
const timer = new Timer();
|
|
176
211
|
const witnessMap = convertMergeRollupInputsToWitnessMap(input);
|
|
177
212
|
|
|
@@ -187,7 +222,11 @@ export class TestCircuitProver implements ServerCircuitProver {
|
|
|
187
222
|
result.toBuffer().length,
|
|
188
223
|
this.logger,
|
|
189
224
|
);
|
|
190
|
-
return
|
|
225
|
+
return makePublicInputsAndRecursiveProof(
|
|
226
|
+
result,
|
|
227
|
+
makeEmptyRecursiveProof(NESTED_RECURSIVE_PROOF_LENGTH),
|
|
228
|
+
VerificationKeyData.makeFake(),
|
|
229
|
+
);
|
|
191
230
|
}
|
|
192
231
|
|
|
193
232
|
/**
|
|
@@ -195,7 +234,9 @@ export class TestCircuitProver implements ServerCircuitProver {
|
|
|
195
234
|
* @param input - Inputs to the circuit.
|
|
196
235
|
* @returns The public inputs as outputs of the simulation.
|
|
197
236
|
*/
|
|
198
|
-
public async getRootRollupProof(
|
|
237
|
+
public async getRootRollupProof(
|
|
238
|
+
input: RootRollupInputs,
|
|
239
|
+
): Promise<PublicInputsAndRecursiveProof<RootRollupPublicInputs>> {
|
|
199
240
|
const timer = new Timer();
|
|
200
241
|
const witnessMap = convertRootRollupInputsToWitnessMap(input);
|
|
201
242
|
|
|
@@ -211,20 +252,27 @@ export class TestCircuitProver implements ServerCircuitProver {
|
|
|
211
252
|
result.toBuffer().length,
|
|
212
253
|
this.logger,
|
|
213
254
|
);
|
|
214
|
-
return
|
|
255
|
+
return makePublicInputsAndRecursiveProof(
|
|
256
|
+
result,
|
|
257
|
+
makeEmptyRecursiveProof(NESTED_RECURSIVE_PROOF_LENGTH),
|
|
258
|
+
VerificationKeyData.makeFake(),
|
|
259
|
+
);
|
|
215
260
|
}
|
|
216
261
|
|
|
217
262
|
public async getPublicKernelProof(
|
|
218
263
|
kernelRequest: PublicKernelNonTailRequest,
|
|
219
|
-
): Promise<
|
|
264
|
+
): Promise<PublicInputsAndRecursiveProof<PublicKernelCircuitPublicInputs>> {
|
|
220
265
|
const timer = new Timer();
|
|
221
|
-
const kernelOps =
|
|
266
|
+
const kernelOps = SimulatedPublicKernelArtifactMapping[kernelRequest.type];
|
|
222
267
|
if (kernelOps === undefined) {
|
|
223
268
|
throw new Error(`Unable to prove for kernel type ${PublicKernelType[kernelRequest.type]}`);
|
|
224
269
|
}
|
|
225
270
|
const witnessMap = kernelOps.convertInputs(kernelRequest.inputs);
|
|
226
271
|
|
|
227
|
-
const witness = await this.wasmSimulator.simulateCircuit(
|
|
272
|
+
const witness = await this.wasmSimulator.simulateCircuit(
|
|
273
|
+
witnessMap,
|
|
274
|
+
SimulatedServerCircuitArtifacts[kernelOps.artifact],
|
|
275
|
+
);
|
|
228
276
|
|
|
229
277
|
const result = kernelOps.convertOutputs(witness);
|
|
230
278
|
emitCircuitSimulationStats(
|
|
@@ -235,21 +283,25 @@ export class TestCircuitProver implements ServerCircuitProver {
|
|
|
235
283
|
this.logger,
|
|
236
284
|
);
|
|
237
285
|
|
|
238
|
-
return
|
|
286
|
+
return makePublicInputsAndRecursiveProof(
|
|
287
|
+
result,
|
|
288
|
+
makeEmptyRecursiveProof(NESTED_RECURSIVE_PROOF_LENGTH),
|
|
289
|
+
VerificationKeyData.makeFake(),
|
|
290
|
+
);
|
|
239
291
|
}
|
|
240
292
|
|
|
241
293
|
public async getPublicTailProof(
|
|
242
294
|
kernelRequest: PublicKernelTailRequest,
|
|
243
|
-
): Promise<
|
|
295
|
+
): Promise<PublicInputsAndRecursiveProof<KernelCircuitPublicInputs>> {
|
|
244
296
|
const timer = new Timer();
|
|
245
|
-
const witnessMap =
|
|
297
|
+
const witnessMap = convertSimulatedPublicTailInputsToWitnessMap(kernelRequest.inputs);
|
|
246
298
|
// use WASM here as it is faster for small circuits
|
|
247
299
|
const witness = await this.wasmSimulator.simulateCircuit(
|
|
248
300
|
witnessMap,
|
|
249
|
-
|
|
301
|
+
SimulatedServerCircuitArtifacts['PublicKernelTailArtifact'],
|
|
250
302
|
);
|
|
251
303
|
|
|
252
|
-
const result =
|
|
304
|
+
const result = convertSimulatedPublicTailOutputFromWitnessMap(witness);
|
|
253
305
|
emitCircuitSimulationStats(
|
|
254
306
|
'public-kernel-tail',
|
|
255
307
|
timer.ms(),
|
|
@@ -258,7 +310,18 @@ export class TestCircuitProver implements ServerCircuitProver {
|
|
|
258
310
|
this.logger,
|
|
259
311
|
);
|
|
260
312
|
|
|
261
|
-
return
|
|
313
|
+
return makePublicInputsAndRecursiveProof(
|
|
314
|
+
result,
|
|
315
|
+
makeEmptyRecursiveProof(NESTED_RECURSIVE_PROOF_LENGTH),
|
|
316
|
+
VerificationKeyData.makeFake(),
|
|
317
|
+
);
|
|
318
|
+
}
|
|
319
|
+
|
|
320
|
+
getAvmProof(_inputs: AvmCircuitInputs): Promise<ProofAndVerificationKey> {
|
|
321
|
+
// We can't simulate the AVM because we don't have enough context to do so (e.g., DBs).
|
|
322
|
+
// We just return an empty proof and VK data.
|
|
323
|
+
this.logger.debug('Skipping AVM simulation in TestCircuitProver.');
|
|
324
|
+
return Promise.resolve({ proof: makeEmptyProof(), verificationKey: VerificationKeyData.makeFake() });
|
|
262
325
|
}
|
|
263
326
|
|
|
264
327
|
// Not implemented for test circuits
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { type ClientProtocolCircuitVerifier, type Tx } from '@aztec/circuit-types';
|
|
2
|
+
import { type VerificationKeys, getMockVerificationKeys } from '@aztec/circuits.js';
|
|
3
|
+
|
|
4
|
+
export class TestCircuitVerifier implements ClientProtocolCircuitVerifier {
|
|
5
|
+
verifyProof(_tx: Tx): Promise<boolean> {
|
|
6
|
+
return Promise.resolve(true);
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
getVerificationKeys(): Promise<VerificationKeys> {
|
|
10
|
+
return Promise.resolve(getMockVerificationKeys());
|
|
11
|
+
}
|
|
12
|
+
}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import {
|
|
2
|
+
Fr,
|
|
3
|
+
type VERIFICATION_KEY_LENGTH_IN_FIELDS,
|
|
4
|
+
VerificationKeyAsFields,
|
|
5
|
+
VerificationKeyData,
|
|
6
|
+
} from '@aztec/circuits.js';
|
|
7
|
+
import { type Tuple } from '@aztec/foundation/serialize';
|
|
8
|
+
|
|
9
|
+
import * as fs from 'fs/promises';
|
|
10
|
+
import * as path from 'path';
|
|
11
|
+
|
|
12
|
+
import { VK_FIELDS_FILENAME, VK_FILENAME } from '../bb/execute.js';
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* Reads the verification key data stored at the specified location and parses into a VerificationKeyData
|
|
16
|
+
* @param vkDirectoryPath - The directory containing the verification key data files
|
|
17
|
+
* @returns The verification key data
|
|
18
|
+
*/
|
|
19
|
+
export async function extractVkData(vkDirectoryPath: string): Promise<VerificationKeyData> {
|
|
20
|
+
const [rawFields, rawBinary] = await Promise.all([
|
|
21
|
+
fs.readFile(path.join(vkDirectoryPath, VK_FIELDS_FILENAME), { encoding: 'utf-8' }),
|
|
22
|
+
fs.readFile(path.join(vkDirectoryPath, VK_FILENAME)),
|
|
23
|
+
]);
|
|
24
|
+
const fieldsJson = JSON.parse(rawFields);
|
|
25
|
+
const fields = fieldsJson.map(Fr.fromString);
|
|
26
|
+
// The first item is the hash, this is not part of the actual VK
|
|
27
|
+
const vkHash = fields[0];
|
|
28
|
+
const actualVk = fields.slice(1);
|
|
29
|
+
const vkAsFields = new VerificationKeyAsFields(
|
|
30
|
+
actualVk as Tuple<Fr, typeof VERIFICATION_KEY_LENGTH_IN_FIELDS>,
|
|
31
|
+
vkHash,
|
|
32
|
+
);
|
|
33
|
+
const vk = new VerificationKeyData(vkAsFields, rawBinary);
|
|
34
|
+
return vk;
|
|
35
|
+
}
|
|
@@ -0,0 +1,156 @@
|
|
|
1
|
+
import { type ClientProtocolCircuitVerifier, Tx } from '@aztec/circuit-types';
|
|
2
|
+
import { type Proof, type VerificationKeyData, type VerificationKeys } from '@aztec/circuits.js';
|
|
3
|
+
import { runInDirectory } from '@aztec/foundation/fs';
|
|
4
|
+
import { type DebugLogger, type LogFn, createDebugLogger } from '@aztec/foundation/log';
|
|
5
|
+
import {
|
|
6
|
+
type ClientProtocolArtifact,
|
|
7
|
+
type ProtocolArtifact,
|
|
8
|
+
ProtocolCircuitArtifacts,
|
|
9
|
+
} from '@aztec/noir-protocol-circuits-types';
|
|
10
|
+
|
|
11
|
+
import * as fs from 'fs/promises';
|
|
12
|
+
import * as path from 'path';
|
|
13
|
+
|
|
14
|
+
import {
|
|
15
|
+
BB_RESULT,
|
|
16
|
+
PROOF_FILENAME,
|
|
17
|
+
VK_FILENAME,
|
|
18
|
+
generateContractForCircuit,
|
|
19
|
+
generateKeyForNoirCircuit,
|
|
20
|
+
verifyProof,
|
|
21
|
+
} from '../bb/execute.js';
|
|
22
|
+
import { type BBConfig } from '../config.js';
|
|
23
|
+
import { extractVkData } from '../verification_key/verification_key_data.js';
|
|
24
|
+
|
|
25
|
+
export class BBCircuitVerifier implements ClientProtocolCircuitVerifier {
|
|
26
|
+
private constructor(
|
|
27
|
+
private config: BBConfig,
|
|
28
|
+
private verificationKeys = new Map<ProtocolArtifact, Promise<VerificationKeyData>>(),
|
|
29
|
+
private logger: DebugLogger,
|
|
30
|
+
) {}
|
|
31
|
+
|
|
32
|
+
public static async new(
|
|
33
|
+
config: BBConfig,
|
|
34
|
+
initialCircuits: ProtocolArtifact[] = [],
|
|
35
|
+
logger = createDebugLogger('aztec:bb-verifier'),
|
|
36
|
+
) {
|
|
37
|
+
const keys = new Map<ProtocolArtifact, Promise<VerificationKeyData>>();
|
|
38
|
+
for (const circuit of initialCircuits) {
|
|
39
|
+
const vkData = await this.generateVerificationKey(
|
|
40
|
+
circuit,
|
|
41
|
+
config.bbBinaryPath,
|
|
42
|
+
config.bbWorkingDirectory,
|
|
43
|
+
logger.debug,
|
|
44
|
+
);
|
|
45
|
+
keys.set(circuit, Promise.resolve(vkData));
|
|
46
|
+
}
|
|
47
|
+
return new BBCircuitVerifier(config, keys, logger);
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
private static async generateVerificationKey(
|
|
51
|
+
circuit: ProtocolArtifact,
|
|
52
|
+
bbPath: string,
|
|
53
|
+
workingDirectory: string,
|
|
54
|
+
logFn: LogFn,
|
|
55
|
+
) {
|
|
56
|
+
return await generateKeyForNoirCircuit(
|
|
57
|
+
bbPath,
|
|
58
|
+
workingDirectory,
|
|
59
|
+
circuit,
|
|
60
|
+
ProtocolCircuitArtifacts[circuit],
|
|
61
|
+
'vk',
|
|
62
|
+
logFn,
|
|
63
|
+
).then(result => {
|
|
64
|
+
if (result.status === BB_RESULT.FAILURE) {
|
|
65
|
+
throw new Error(`Failed to created verification key for ${circuit}, ${result.reason}`);
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
return extractVkData(result.vkPath!);
|
|
69
|
+
});
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
public async getVerificationKeyData(circuit: ProtocolArtifact) {
|
|
73
|
+
let promise = this.verificationKeys.get(circuit);
|
|
74
|
+
if (!promise) {
|
|
75
|
+
promise = BBCircuitVerifier.generateVerificationKey(
|
|
76
|
+
circuit,
|
|
77
|
+
this.config.bbBinaryPath,
|
|
78
|
+
this.config.bbWorkingDirectory,
|
|
79
|
+
this.logger.debug,
|
|
80
|
+
);
|
|
81
|
+
}
|
|
82
|
+
this.verificationKeys.set(circuit, promise);
|
|
83
|
+
const vk = await promise;
|
|
84
|
+
return vk.clone();
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
public async verifyProofForCircuit(circuit: ProtocolArtifact, proof: Proof) {
|
|
88
|
+
const operation = async (bbWorkingDirectory: string) => {
|
|
89
|
+
const proofFileName = path.join(bbWorkingDirectory, PROOF_FILENAME);
|
|
90
|
+
const verificationKeyPath = path.join(bbWorkingDirectory, VK_FILENAME);
|
|
91
|
+
const verificationKey = await this.getVerificationKeyData(circuit);
|
|
92
|
+
|
|
93
|
+
this.logger.debug(`${circuit} Verifying with key: ${verificationKey.keyAsFields.hash.toString()}`);
|
|
94
|
+
|
|
95
|
+
await fs.writeFile(proofFileName, proof.buffer);
|
|
96
|
+
await fs.writeFile(verificationKeyPath, verificationKey.keyAsBytes);
|
|
97
|
+
|
|
98
|
+
const logFunction = (message: string) => {
|
|
99
|
+
this.logger.debug(`${circuit} BB out - ${message}`);
|
|
100
|
+
};
|
|
101
|
+
|
|
102
|
+
const result = await verifyProof(this.config.bbBinaryPath, proofFileName, verificationKeyPath!, logFunction);
|
|
103
|
+
|
|
104
|
+
if (result.status === BB_RESULT.FAILURE) {
|
|
105
|
+
const errorMessage = `Failed to verify ${circuit} proof!`;
|
|
106
|
+
throw new Error(errorMessage);
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
this.logger.debug(`${circuit} verification successful`);
|
|
110
|
+
};
|
|
111
|
+
await runInDirectory(this.config.bbWorkingDirectory, operation);
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
public async generateSolidityContract(circuit: ProtocolArtifact, contractName: string) {
|
|
115
|
+
const result = await generateContractForCircuit(
|
|
116
|
+
this.config.bbBinaryPath,
|
|
117
|
+
this.config.bbWorkingDirectory,
|
|
118
|
+
circuit,
|
|
119
|
+
ProtocolCircuitArtifacts[circuit],
|
|
120
|
+
contractName,
|
|
121
|
+
this.logger.debug,
|
|
122
|
+
);
|
|
123
|
+
|
|
124
|
+
if (result.status === BB_RESULT.FAILURE) {
|
|
125
|
+
throw new Error(`Failed to create verifier contract for ${circuit}, ${result.reason}`);
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
return fs.readFile(result.contractPath!, 'utf-8');
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
async verifyProof(tx: Tx): Promise<boolean> {
|
|
132
|
+
const { proof, enqueuedPublicFunctionCalls } = tx;
|
|
133
|
+
const expectedCircuit: ClientProtocolArtifact =
|
|
134
|
+
enqueuedPublicFunctionCalls.length > 0 ? 'PrivateKernelTailToPublicArtifact' : 'PrivateKernelTailArtifact';
|
|
135
|
+
|
|
136
|
+
try {
|
|
137
|
+
await this.verifyProofForCircuit(expectedCircuit, proof);
|
|
138
|
+
return true;
|
|
139
|
+
} catch (err) {
|
|
140
|
+
this.logger.warn(`Failed to verify ${expectedCircuit} proof for tx ${Tx.getHash(tx)}: ${String(err)}`);
|
|
141
|
+
return false;
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
async getVerificationKeys(): Promise<VerificationKeys> {
|
|
146
|
+
const [privateKernelCircuit, privateKernelToPublicCircuit] = await Promise.all([
|
|
147
|
+
this.getVerificationKeyData('PrivateKernelTailArtifact'),
|
|
148
|
+
this.getVerificationKeyData('PrivateKernelTailToPublicArtifact'),
|
|
149
|
+
]);
|
|
150
|
+
|
|
151
|
+
return {
|
|
152
|
+
privateKernelCircuit,
|
|
153
|
+
privateKernelToPublicCircuit,
|
|
154
|
+
};
|
|
155
|
+
}
|
|
156
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './bb_verifier.js';
|
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
/// <reference types="node" resolution-mode="require"/>
|
|
2
|
-
import { type Fr, type VERIFICATION_KEY_LENGTH_IN_FIELDS } from '@aztec/circuits.js';
|
|
3
|
-
import { type Tuple } from '@aztec/foundation/serialize';
|
|
4
|
-
export declare const AGGREGATION_OBJECT_SIZE = 16;
|
|
5
|
-
export declare const CIRCUIT_SIZE_INDEX = 3;
|
|
6
|
-
export declare const CIRCUIT_PUBLIC_INPUTS_INDEX = 4;
|
|
7
|
-
export declare const CIRCUIT_RECURSIVE_INDEX = 5;
|
|
8
|
-
export type VerificationKeyData = {
|
|
9
|
-
hash: Fr;
|
|
10
|
-
keyAsFields: Tuple<Fr, typeof VERIFICATION_KEY_LENGTH_IN_FIELDS>;
|
|
11
|
-
keyAsBytes: Buffer;
|
|
12
|
-
numPublicInputs: number;
|
|
13
|
-
circuitSize: number;
|
|
14
|
-
isRecursive: boolean;
|
|
15
|
-
};
|
|
16
|
-
//# sourceMappingURL=verification_key_data.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"verification_key_data.d.ts","sourceRoot":"","sources":["../../src/prover/verification_key_data.ts"],"names":[],"mappings":";AAAA,OAAO,EAAE,KAAK,EAAE,EAAE,KAAK,iCAAiC,EAAE,MAAM,oBAAoB,CAAC;AACrF,OAAO,EAAE,KAAK,KAAK,EAAE,MAAM,6BAA6B,CAAC;AAEzD,eAAO,MAAM,uBAAuB,KAAK,CAAC;AAC1C,eAAO,MAAM,kBAAkB,IAAI,CAAC;AACpC,eAAO,MAAM,2BAA2B,IAAI,CAAC;AAC7C,eAAO,MAAM,uBAAuB,IAAI,CAAC;AAEzC,MAAM,MAAM,mBAAmB,GAAG;IAChC,IAAI,EAAE,EAAE,CAAC;IACT,WAAW,EAAE,KAAK,CAAC,EAAE,EAAE,OAAO,iCAAiC,CAAC,CAAC;IACjE,UAAU,EAAE,MAAM,CAAC;IACnB,eAAe,EAAE,MAAM,CAAC;IACxB,WAAW,EAAE,MAAM,CAAC;IACpB,WAAW,EAAE,OAAO,CAAC;CACtB,CAAC"}
|
|
@@ -1,5 +0,0 @@
|
|
|
1
|
-
export const AGGREGATION_OBJECT_SIZE = 16;
|
|
2
|
-
export const CIRCUIT_SIZE_INDEX = 3;
|
|
3
|
-
export const CIRCUIT_PUBLIC_INPUTS_INDEX = 4;
|
|
4
|
-
export const CIRCUIT_RECURSIVE_INDEX = 5;
|
|
5
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidmVyaWZpY2F0aW9uX2tleV9kYXRhLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL3Byb3Zlci92ZXJpZmljYXRpb25fa2V5X2RhdGEudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBR0EsTUFBTSxDQUFDLE1BQU0sdUJBQXVCLEdBQUcsRUFBRSxDQUFDO0FBQzFDLE1BQU0sQ0FBQyxNQUFNLGtCQUFrQixHQUFHLENBQUMsQ0FBQztBQUNwQyxNQUFNLENBQUMsTUFBTSwyQkFBMkIsR0FBRyxDQUFDLENBQUM7QUFDN0MsTUFBTSxDQUFDLE1BQU0sdUJBQXVCLEdBQUcsQ0FBQyxDQUFDIn0=
|
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
import { type Fr, type VERIFICATION_KEY_LENGTH_IN_FIELDS } from '@aztec/circuits.js';
|
|
2
|
-
import { type Tuple } from '@aztec/foundation/serialize';
|
|
3
|
-
|
|
4
|
-
export const AGGREGATION_OBJECT_SIZE = 16;
|
|
5
|
-
export const CIRCUIT_SIZE_INDEX = 3;
|
|
6
|
-
export const CIRCUIT_PUBLIC_INPUTS_INDEX = 4;
|
|
7
|
-
export const CIRCUIT_RECURSIVE_INDEX = 5;
|
|
8
|
-
|
|
9
|
-
export type VerificationKeyData = {
|
|
10
|
-
hash: Fr;
|
|
11
|
-
keyAsFields: Tuple<Fr, typeof VERIFICATION_KEY_LENGTH_IN_FIELDS>;
|
|
12
|
-
keyAsBytes: Buffer;
|
|
13
|
-
numPublicInputs: number;
|
|
14
|
-
circuitSize: number;
|
|
15
|
-
isRecursive: boolean;
|
|
16
|
-
};
|