@aztec/bb-prover 0.0.1-commit.24de95ac → 0.0.1-commit.2606882
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 +15 -11
- package/dest/avm_proving_tests/avm_proving_tester.d.ts.map +1 -1
- package/dest/avm_proving_tests/avm_proving_tester.js +167 -108
- 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/cli.d.ts +1 -1
- 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/bb/index.d.ts +1 -1
- package/dest/config.d.ts +17 -1
- package/dest/config.d.ts.map +1 -1
- package/dest/honk.d.ts +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 +21 -43
- package/dest/prover/client/bb_private_kernel_prover.d.ts +20 -6
- package/dest/prover/client/bb_private_kernel_prover.d.ts.map +1 -1
- package/dest/prover/client/bb_private_kernel_prover.js +73 -8
- package/dest/prover/client/bundle.d.ts +6 -0
- package/dest/prover/client/bundle.d.ts.map +1 -0
- package/dest/prover/client/bundle.js +7 -0
- package/dest/prover/client/lazy.d.ts +6 -0
- package/dest/prover/client/lazy.d.ts.map +1 -0
- package/dest/prover/client/lazy.js +7 -0
- package/dest/prover/index.d.ts +1 -1
- package/dest/prover/proof_utils.d.ts +11 -1
- package/dest/prover/proof_utils.d.ts.map +1 -1
- package/dest/prover/proof_utils.js +25 -2
- package/dest/prover/server/bb_prover.d.ts +8 -21
- package/dest/prover/server/bb_prover.d.ts.map +1 -1
- package/dest/prover/server/bb_prover.js +614 -112
- 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 +29 -27
- package/dest/test/index.d.ts +2 -1
- package/dest/test/index.d.ts.map +1 -1
- package/dest/test/index.js +1 -0
- package/dest/test/test_circuit_prover.d.ts +4 -4
- package/dest/test/test_circuit_prover.d.ts.map +1 -1
- package/dest/test/test_circuit_prover.js +462 -59
- package/dest/test/test_verifier.d.ts +3 -1
- package/dest/test/test_verifier.d.ts.map +1 -1
- package/dest/test/test_verifier.js +15 -0
- package/dest/verification_key/verification_key_data.d.ts +1 -8
- package/dest/verification_key/verification_key_data.d.ts.map +1 -1
- package/dest/verification_key/verification_key_data.js +2 -21
- package/dest/verifier/batch_chonk_verifier.d.ts +56 -0
- package/dest/verifier/batch_chonk_verifier.d.ts.map +1 -0
- package/dest/verifier/batch_chonk_verifier.js +384 -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 +137 -48
- 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 +15 -45
- package/package.json +26 -23
- package/src/avm_proving_tests/avm_proving_tester.ts +69 -138
- 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 +20 -43
- package/src/prover/client/bb_private_kernel_prover.ts +158 -8
- package/src/prover/client/bundle.ts +10 -0
- package/src/prover/client/lazy.ts +10 -0
- package/src/prover/proof_utils.ts +42 -2
- package/src/prover/server/bb_prover.ts +139 -159
- package/src/test/delay_values.ts +31 -27
- package/src/test/index.ts +1 -0
- package/src/test/test_circuit_prover.ts +10 -13
- package/src/test/test_verifier.ts +8 -0
- package/src/verification_key/verification_key_data.ts +2 -27
- package/src/verifier/batch_chonk_verifier.ts +415 -0
- package/src/verifier/bb_verifier.ts +69 -80
- package/src/verifier/index.ts +1 -0
- package/src/verifier/queued_chonk_verifier.ts +15 -47
- package/dest/bb/execute.d.ts +0 -107
- package/dest/bb/execute.d.ts.map +0 -1
- package/dest/bb/execute.js +0 -672
- package/dest/prover/client/native/bb_native_private_kernel_prover.d.ts +0 -23
- package/dest/prover/client/native/bb_native_private_kernel_prover.d.ts.map +0 -1
- package/dest/prover/client/native/bb_native_private_kernel_prover.js +0 -66
- package/dest/prover/client/wasm/bb_wasm_private_kernel_prover.d.ts +0 -15
- package/dest/prover/client/wasm/bb_wasm_private_kernel_prover.d.ts.map +0 -1
- package/dest/prover/client/wasm/bb_wasm_private_kernel_prover.js +0 -46
- package/dest/prover/client/wasm/bundle.d.ts +0 -6
- package/dest/prover/client/wasm/bundle.d.ts.map +0 -1
- package/dest/prover/client/wasm/bundle.js +0 -8
- package/dest/prover/client/wasm/lazy.d.ts +0 -6
- package/dest/prover/client/wasm/lazy.d.ts.map +0 -1
- package/dest/prover/client/wasm/lazy.js +0 -8
- package/src/bb/execute.ts +0 -709
- package/src/prover/client/native/bb_native_private_kernel_prover.ts +0 -105
- package/src/prover/client/wasm/bb_wasm_private_kernel_prover.ts +0 -58
- package/src/prover/client/wasm/bundle.ts +0 -11
- package/src/prover/client/wasm/lazy.ts +0 -11
|
@@ -6,10 +6,9 @@ import {
|
|
|
6
6
|
RECURSIVE_PROOF_LENGTH,
|
|
7
7
|
ULTRA_KECCAK_PROOF_LENGTH,
|
|
8
8
|
} from '@aztec/constants';
|
|
9
|
-
import { Fr } from '@aztec/foundation/
|
|
9
|
+
import { Fr } from '@aztec/foundation/curves/bn254';
|
|
10
10
|
import { runInDirectory } from '@aztec/foundation/fs';
|
|
11
11
|
import { createLogger } from '@aztec/foundation/log';
|
|
12
|
-
import { BufferReader } from '@aztec/foundation/serialize';
|
|
13
12
|
import {
|
|
14
13
|
type ServerProtocolArtifact,
|
|
15
14
|
convertBlockMergeRollupOutputsFromWitnessMap,
|
|
@@ -55,10 +54,8 @@ import { NativeACVMSimulator } from '@aztec/simulator/server';
|
|
|
55
54
|
import type { AvmCircuitInputs, AvmCircuitPublicInputs } from '@aztec/stdlib/avm';
|
|
56
55
|
import { ProvingError } from '@aztec/stdlib/errors';
|
|
57
56
|
import {
|
|
58
|
-
type ProofAndVerificationKey,
|
|
59
57
|
type PublicInputsAndRecursiveProof,
|
|
60
58
|
type ServerCircuitProver,
|
|
61
|
-
makeProofAndVerificationKey,
|
|
62
59
|
makePublicInputsAndRecursiveProof,
|
|
63
60
|
} from '@aztec/stdlib/interfaces/server';
|
|
64
61
|
import type { ParityBasePrivateInputs, ParityPublicInputs, ParityRootPrivateInputs } from '@aztec/stdlib/parity';
|
|
@@ -84,32 +81,20 @@ import {
|
|
|
84
81
|
type RootRollupPublicInputs,
|
|
85
82
|
type TxMergeRollupPrivateInputs,
|
|
86
83
|
type TxRollupPublicInputs,
|
|
87
|
-
enhanceProofWithPiValidationFlag,
|
|
88
84
|
} from '@aztec/stdlib/rollup';
|
|
89
85
|
import type { CircuitProvingStats, CircuitWitnessGenerationStats } from '@aztec/stdlib/stats';
|
|
90
|
-
import
|
|
86
|
+
import { VerificationKeyData } from '@aztec/stdlib/vks';
|
|
91
87
|
import { Attributes, type TelemetryClient, getTelemetryClient, trackSpan } from '@aztec/telemetry-client';
|
|
92
88
|
|
|
93
89
|
import { promises as fs } from 'fs';
|
|
90
|
+
import { ungzip } from 'pako';
|
|
94
91
|
import * as path from 'path';
|
|
95
92
|
|
|
96
|
-
import {
|
|
97
|
-
type BBFailure,
|
|
98
|
-
type BBSuccess,
|
|
99
|
-
BB_RESULT,
|
|
100
|
-
PROOF_FILENAME,
|
|
101
|
-
PUBLIC_INPUTS_FILENAME,
|
|
102
|
-
VK_FILENAME,
|
|
103
|
-
generateAvmProof,
|
|
104
|
-
generateProof,
|
|
105
|
-
verifyAvmProof,
|
|
106
|
-
verifyProof,
|
|
107
|
-
} from '../../bb/execute.js';
|
|
93
|
+
import { BBJsFactory, type BBJsProofResult } from '../../bb/bb_js_backend.js';
|
|
108
94
|
import type { ACVMConfig, BBConfig } from '../../config.js';
|
|
109
|
-
import {
|
|
95
|
+
import { getUltraHonkFlavorForCircuit } from '../../honk.js';
|
|
110
96
|
import { ProverInstrumentation } from '../../instrumentation.js';
|
|
111
|
-
import {
|
|
112
|
-
import { readProofsFromOutputDirectory } from '../proof_utils.js';
|
|
97
|
+
import { constructRecursiveProofFromBuffers } from '../proof_utils.js';
|
|
113
98
|
|
|
114
99
|
const logger = createLogger('bb-prover');
|
|
115
100
|
|
|
@@ -123,12 +108,14 @@ export interface BBProverConfig extends BBConfig, ACVMConfig {
|
|
|
123
108
|
*/
|
|
124
109
|
export class BBNativeRollupProver implements ServerCircuitProver {
|
|
125
110
|
private instrumentation: ProverInstrumentation;
|
|
111
|
+
private bbJsFactory: BBJsFactory;
|
|
126
112
|
|
|
127
113
|
constructor(
|
|
128
114
|
private config: BBProverConfig,
|
|
129
115
|
telemetry: TelemetryClient,
|
|
130
116
|
) {
|
|
131
117
|
this.instrumentation = new ProverInstrumentation(telemetry, 'BBNativeRollupProver');
|
|
118
|
+
this.bbJsFactory = new BBJsFactory(config.bbBinaryPath, { logger, debugDir: config.bbDebugOutputDir });
|
|
132
119
|
}
|
|
133
120
|
|
|
134
121
|
get tracer() {
|
|
@@ -140,7 +127,7 @@ export class BBNativeRollupProver implements ServerCircuitProver {
|
|
|
140
127
|
await fs.mkdir(config.acvmWorkingDirectory, { recursive: true });
|
|
141
128
|
await fs.access(config.bbBinaryPath, fs.constants.R_OK);
|
|
142
129
|
await fs.mkdir(config.bbWorkingDirectory, { recursive: true });
|
|
143
|
-
logger.info(`Using
|
|
130
|
+
logger.info(`Using bb.js API with binary at ${config.bbBinaryPath}`);
|
|
144
131
|
logger.info(`Using native ACVM at ${config.acvmBinaryPath} and working directory ${config.acvmWorkingDirectory}`);
|
|
145
132
|
|
|
146
133
|
return new BBNativeRollupProver(config, telemetry);
|
|
@@ -192,14 +179,10 @@ export class BBNativeRollupProver implements ServerCircuitProver {
|
|
|
192
179
|
}))
|
|
193
180
|
public async getAvmProof(
|
|
194
181
|
inputs: AvmCircuitInputs,
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
// TODO(#14234)[Unconditional PIs validation]: remove next lines and directly return proofAndVk
|
|
201
|
-
proofAndVk.proof.proof = enhanceProofWithPiValidationFlag(proofAndVk.proof.proof, skipPublicInputsValidation);
|
|
202
|
-
return proofAndVk;
|
|
182
|
+
): Promise<RecursiveProof<typeof AVM_V2_PROOF_LENGTH_IN_FIELDS_PADDED>> {
|
|
183
|
+
const proof = await this.createAvmProof(inputs);
|
|
184
|
+
await this.verifyAvmProof(proof.binaryProof, inputs.publicInputs);
|
|
185
|
+
return proof;
|
|
203
186
|
}
|
|
204
187
|
|
|
205
188
|
public async getPublicChonkVerifierProof(
|
|
@@ -461,16 +444,16 @@ export class BBNativeRollupProver implements ServerCircuitProver {
|
|
|
461
444
|
convertInput: (input: Input) => WitnessMap,
|
|
462
445
|
convertOutput: (outputWitness: WitnessMap) => Output,
|
|
463
446
|
workingDirectory: string,
|
|
464
|
-
): Promise<{ circuitOutput: Output;
|
|
465
|
-
// Have the ACVM write the partial witness here
|
|
447
|
+
): Promise<{ circuitOutput: Output; proofResult: BBJsProofResult }> {
|
|
448
|
+
// Have the ACVM write the partial witness here (still needs a temp directory)
|
|
466
449
|
const outputWitnessFile = path.join(workingDirectory, 'partial-witness.gz');
|
|
467
450
|
|
|
468
451
|
// Generate the partial witness using the ACVM
|
|
469
|
-
// A further temp directory will be created beneath ours and then cleaned up after the partial witness has been copied to our specified location
|
|
470
452
|
const simulator = new NativeACVMSimulator(
|
|
471
453
|
this.config.acvmWorkingDirectory,
|
|
472
454
|
this.config.acvmBinaryPath,
|
|
473
455
|
outputWitnessFile,
|
|
456
|
+
logger,
|
|
474
457
|
);
|
|
475
458
|
|
|
476
459
|
const artifact = getServerCircuitArtifact(circuitType);
|
|
@@ -478,7 +461,7 @@ export class BBNativeRollupProver implements ServerCircuitProver {
|
|
|
478
461
|
logger.debug(`Generating witness data for ${circuitType}`);
|
|
479
462
|
|
|
480
463
|
const inputWitness = convertInput(input);
|
|
481
|
-
const foreignCallHandler = undefined;
|
|
464
|
+
const foreignCallHandler = undefined;
|
|
482
465
|
const witnessResult = await simulator.executeProtocolCircuit(inputWitness, artifact, foreignCallHandler);
|
|
483
466
|
const output = convertOutput(witnessResult.witness);
|
|
484
467
|
|
|
@@ -495,76 +478,80 @@ export class BBNativeRollupProver implements ServerCircuitProver {
|
|
|
495
478
|
eventName: 'circuit-witness-generation',
|
|
496
479
|
} satisfies CircuitWitnessGenerationStats);
|
|
497
480
|
|
|
498
|
-
//
|
|
499
|
-
|
|
481
|
+
// Read and decompress the witness for bb.js
|
|
482
|
+
const witnessGz = await fs.readFile(outputWitnessFile);
|
|
483
|
+
const witness = ungzip(witnessGz);
|
|
500
484
|
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
workingDirectory,
|
|
504
|
-
circuitType,
|
|
505
|
-
Buffer.from(artifact.bytecode, 'base64'),
|
|
506
|
-
this.getVerificationKeyDataForCircuit(circuitType).keyAsBytes,
|
|
507
|
-
outputWitnessFile,
|
|
508
|
-
getUltraHonkFlavorForCircuit(circuitType),
|
|
509
|
-
logger,
|
|
510
|
-
);
|
|
485
|
+
// Decompress bytecode for bb.js
|
|
486
|
+
const bytecode = ungzip(Buffer.from(artifact.bytecode, 'base64'));
|
|
511
487
|
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
488
|
+
// Prove the circuit via bb.js API
|
|
489
|
+
logger.debug(`Proving ${circuitType} via bb.js...`);
|
|
490
|
+
|
|
491
|
+
let proofResult: BBJsProofResult;
|
|
492
|
+
try {
|
|
493
|
+
await using instance = await this.bbJsFactory.getInstance();
|
|
494
|
+
proofResult = await instance.generateProof(
|
|
495
|
+
circuitType,
|
|
496
|
+
bytecode,
|
|
497
|
+
this.getVerificationKeyDataForCircuit(circuitType).keyAsBytes,
|
|
498
|
+
witness,
|
|
499
|
+
getUltraHonkFlavorForCircuit(circuitType),
|
|
500
|
+
);
|
|
501
|
+
} catch (error) {
|
|
502
|
+
throw new ProvingError(`Failed to generate proof for ${circuitType}: ${error}`);
|
|
515
503
|
}
|
|
516
504
|
|
|
517
505
|
return {
|
|
518
506
|
circuitOutput: output,
|
|
519
|
-
|
|
507
|
+
proofResult,
|
|
520
508
|
};
|
|
521
509
|
}
|
|
522
510
|
|
|
523
|
-
private async
|
|
511
|
+
private async createAvmProof(
|
|
512
|
+
input: AvmCircuitInputs,
|
|
513
|
+
): Promise<RecursiveProof<typeof AVM_V2_PROOF_LENGTH_IN_FIELDS_PADDED>> {
|
|
524
514
|
logger.info(`Proving avm-circuit for TX ${input.hints.tx.hash}...`);
|
|
525
515
|
|
|
526
|
-
const
|
|
516
|
+
const inputsBuffer = input.serializeWithMessagePack();
|
|
517
|
+
await using instance = await this.bbJsFactory.getInstance();
|
|
518
|
+
const { proof: proofFieldArrays, durationMs } = await instance.generateAvmProof(inputsBuffer);
|
|
527
519
|
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
throw new ProvingError(provingResult.reason, provingResult, provingResult.retry);
|
|
531
|
-
}
|
|
532
|
-
|
|
533
|
-
return provingResult;
|
|
534
|
-
}
|
|
520
|
+
// Convert Uint8Array[] (32-byte field elements) to Fr[]
|
|
521
|
+
const proofFields = proofFieldArrays.map(f => Fr.fromBuffer(Buffer.from(f)));
|
|
535
522
|
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
523
|
+
// Pad to fixed size (during development the proof length may vary)
|
|
524
|
+
if (proofFields.length > AVM_V2_PROOF_LENGTH_IN_FIELDS_PADDED) {
|
|
525
|
+
throw new Error(
|
|
526
|
+
`Proof has ${proofFields.length} fields, expected no more than ${AVM_V2_PROOF_LENGTH_IN_FIELDS_PADDED}.`,
|
|
527
|
+
);
|
|
528
|
+
}
|
|
529
|
+
const proofFieldsPadded = proofFields.concat(
|
|
530
|
+
Array(AVM_V2_PROOF_LENGTH_IN_FIELDS_PADDED - proofFields.length).fill(new Fr(0)),
|
|
531
|
+
);
|
|
541
532
|
|
|
542
|
-
|
|
543
|
-
|
|
533
|
+
// Build the binary proof from the raw field data
|
|
534
|
+
const rawProofBuffer = Buffer.concat(proofFieldArrays.map(f => Buffer.from(f)));
|
|
535
|
+
const binaryProof = new Proof(rawProofBuffer, /*numPublicInputs=*/ 0);
|
|
536
|
+
const avmProof = new RecursiveProof(proofFieldsPadded, binaryProof, true, AVM_V2_PROOF_LENGTH_IN_FIELDS_PADDED);
|
|
544
537
|
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
538
|
+
const circuitType = 'avm-circuit' as const;
|
|
539
|
+
const appCircuitName = 'unknown' as const;
|
|
540
|
+
this.instrumentation.recordAvmDuration('provingDuration', appCircuitName, durationMs);
|
|
541
|
+
this.instrumentation.recordAvmSize('proofSize', appCircuitName, avmProof.binaryProof.buffer.length);
|
|
549
542
|
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
circuitSize: 1 << 21,
|
|
561
|
-
numPublicInputs: 0,
|
|
562
|
-
} satisfies CircuitProvingStats,
|
|
563
|
-
);
|
|
543
|
+
logger.info(`Generated proof for ${circuitType}(${input.hints.tx.hash}) in ${Math.ceil(durationMs)} ms`, {
|
|
544
|
+
circuitName: circuitType,
|
|
545
|
+
appCircuitName: input.hints.tx.hash,
|
|
546
|
+
duration: durationMs,
|
|
547
|
+
proofSize: avmProof.binaryProof.buffer.length,
|
|
548
|
+
eventName: 'circuit-proving',
|
|
549
|
+
inputSize: inputsBuffer.length,
|
|
550
|
+
circuitSize: 1 << 21,
|
|
551
|
+
numPublicInputs: 0,
|
|
552
|
+
} satisfies CircuitProvingStats);
|
|
564
553
|
|
|
565
|
-
|
|
566
|
-
};
|
|
567
|
-
return await this.runInDirectory(operation);
|
|
554
|
+
return avmProof;
|
|
568
555
|
}
|
|
569
556
|
|
|
570
557
|
/**
|
|
@@ -587,33 +574,38 @@ export class BBNativeRollupProver implements ServerCircuitProver {
|
|
|
587
574
|
convertInput: (input: CircuitInputType) => WitnessMap,
|
|
588
575
|
convertOutput: (outputWitness: WitnessMap) => CircuitOutputType,
|
|
589
576
|
): Promise<{ circuitOutput: CircuitOutputType; proof: RecursiveProof<PROOF_LENGTH> }> {
|
|
590
|
-
//
|
|
591
|
-
const operation = async (
|
|
592
|
-
const {
|
|
577
|
+
// Still need runInDirectory for ACVM witness generation temp files
|
|
578
|
+
const operation = async (workingDirectory: string) => {
|
|
579
|
+
const { proofResult, circuitOutput: output } = await this.generateProofWithBB(
|
|
593
580
|
input,
|
|
594
581
|
circuitType,
|
|
595
582
|
convertInput,
|
|
596
583
|
convertOutput,
|
|
597
|
-
|
|
584
|
+
workingDirectory,
|
|
598
585
|
);
|
|
599
586
|
|
|
600
587
|
const vkData = this.getVerificationKeyDataForCircuit(circuitType);
|
|
601
|
-
//
|
|
602
|
-
const proof =
|
|
588
|
+
// Construct proof from in-memory buffers (no file I/O needed)
|
|
589
|
+
const proof = constructRecursiveProofFromBuffers(
|
|
590
|
+
proofResult.proofFields,
|
|
591
|
+
proofResult.publicInputFields,
|
|
592
|
+
vkData,
|
|
593
|
+
proofLength,
|
|
594
|
+
);
|
|
603
595
|
|
|
604
596
|
const circuitName = mapProtocolArtifactNameToCircuitName(circuitType);
|
|
605
|
-
this.instrumentation.recordDuration('provingDuration', circuitName,
|
|
597
|
+
this.instrumentation.recordDuration('provingDuration', circuitName, proofResult.durationMs);
|
|
606
598
|
this.instrumentation.recordSize('proofSize', circuitName, proof.binaryProof.buffer.length);
|
|
607
599
|
this.instrumentation.recordSize('circuitPublicInputCount', circuitName, vkData.numPublicInputs);
|
|
608
600
|
this.instrumentation.recordSize('circuitSize', circuitName, vkData.circuitSize);
|
|
609
601
|
logger.info(
|
|
610
|
-
`Generated proof for ${circuitType} in ${Math.ceil(
|
|
602
|
+
`Generated proof for ${circuitType} in ${Math.ceil(proofResult.durationMs)} ms, size: ${
|
|
611
603
|
proof.proof.length
|
|
612
604
|
} fields`,
|
|
613
605
|
{
|
|
614
606
|
circuitName,
|
|
615
607
|
circuitSize: vkData.circuitSize,
|
|
616
|
-
duration:
|
|
608
|
+
duration: proofResult.durationMs,
|
|
617
609
|
inputSize: output.toBuffer().length,
|
|
618
610
|
proofSize: proof.binaryProof.buffer.length,
|
|
619
611
|
eventName: 'circuit-proving',
|
|
@@ -630,56 +622,58 @@ export class BBNativeRollupProver implements ServerCircuitProver {
|
|
|
630
622
|
}
|
|
631
623
|
|
|
632
624
|
/**
|
|
633
|
-
* Verifies a proof
|
|
625
|
+
* Verifies a proof via bb.js API (no temp files needed).
|
|
634
626
|
* @param circuitType - The type of circuit whose proof is to be verified
|
|
635
627
|
* @param proof - The proof to be verified
|
|
636
628
|
*/
|
|
637
629
|
public async verifyProof(circuitType: ServerProtocolArtifact, proof: Proof) {
|
|
638
630
|
const verificationKey = this.getVerificationKeyDataForCircuit(circuitType);
|
|
639
|
-
|
|
640
|
-
|
|
631
|
+
const flavor = getUltraHonkFlavorForCircuit(circuitType);
|
|
632
|
+
|
|
633
|
+
// Split proof buffer into public input fields and proof fields (32-byte each)
|
|
634
|
+
const publicInputFields = splitBufferToFieldArrays(proof.buffer.subarray(0, proof.numPublicInputs * 32));
|
|
635
|
+
const proofFields = splitBufferToFieldArrays(proof.buffer.subarray(proof.numPublicInputs * 32));
|
|
636
|
+
|
|
637
|
+
let verified: boolean;
|
|
638
|
+
let durationMs: number;
|
|
639
|
+
try {
|
|
640
|
+
await using instance = await this.bbJsFactory.getInstance();
|
|
641
|
+
({ verified, durationMs } = await instance.verifyProof(
|
|
642
|
+
proofFields,
|
|
643
|
+
verificationKey.keyAsBytes,
|
|
644
|
+
publicInputFields,
|
|
645
|
+
flavor,
|
|
646
|
+
));
|
|
647
|
+
} catch (error) {
|
|
648
|
+
throw new ProvingError(`Failed to verify proof for ${circuitType}: ${error}`);
|
|
649
|
+
}
|
|
641
650
|
|
|
642
|
-
|
|
643
|
-
|
|
644
|
-
|
|
645
|
-
publicInputs: AvmCircuitPublicInputs,
|
|
646
|
-
) {
|
|
647
|
-
return await this.verifyWithKeyInternal(proof, verificationKey, (proofPath, vkPath) =>
|
|
648
|
-
verifyAvmProof(this.config.bbBinaryPath, this.config.bbWorkingDirectory, proofPath, publicInputs, vkPath, logger),
|
|
649
|
-
);
|
|
650
|
-
}
|
|
651
|
+
if (!verified) {
|
|
652
|
+
throw new ProvingError('Failed to verify proof from key!');
|
|
653
|
+
}
|
|
651
654
|
|
|
652
|
-
|
|
653
|
-
return await this.verifyWithKeyInternal(proof, verificationKey, (proofPath, vkPath) =>
|
|
654
|
-
verifyProof(this.config.bbBinaryPath, proofPath, vkPath, flavor, logger),
|
|
655
|
-
);
|
|
655
|
+
logger.info(`Successfully verified proof from key in ${durationMs} ms`);
|
|
656
656
|
}
|
|
657
657
|
|
|
658
|
-
|
|
659
|
-
|
|
660
|
-
|
|
661
|
-
|
|
662
|
-
|
|
663
|
-
const
|
|
664
|
-
|
|
665
|
-
|
|
666
|
-
|
|
667
|
-
|
|
668
|
-
await fs.writeFile(publicInputsFileName, proof.buffer.slice(0, proof.numPublicInputs * 32));
|
|
669
|
-
await fs.writeFile(proofFileName, proof.buffer.slice(proof.numPublicInputs * 32));
|
|
670
|
-
await fs.writeFile(verificationKeyPath, verificationKey.keyAsBytes);
|
|
671
|
-
|
|
672
|
-
const result = await verificationFunction(proofFileName, verificationKeyPath!);
|
|
673
|
-
|
|
674
|
-
if (result.status === BB_RESULT.FAILURE) {
|
|
675
|
-
const errorMessage = `Failed to verify proof from key!`;
|
|
676
|
-
throw new ProvingError(errorMessage, result, result.retry);
|
|
677
|
-
}
|
|
678
|
-
|
|
679
|
-
logger.info(`Successfully verified proof from key in ${result.durationMs} ms`);
|
|
680
|
-
};
|
|
658
|
+
/** Verify an AVM proof via bb.js API. */
|
|
659
|
+
public async verifyAvmProof(proof: Proof, publicInputs: AvmCircuitPublicInputs) {
|
|
660
|
+
// For AVM proofs, numPublicInputs is 0, so the full buffer is the proof.
|
|
661
|
+
const proofBuffer = proof.buffer.subarray(proof.numPublicInputs * 32);
|
|
662
|
+
// Split the raw proof buffer into 32-byte field element arrays
|
|
663
|
+
const proofFields: Uint8Array[] = [];
|
|
664
|
+
for (let i = 0; i < proofBuffer.length; i += Fr.SIZE_IN_BYTES) {
|
|
665
|
+
proofFields.push(new Uint8Array(proofBuffer.subarray(i, i + Fr.SIZE_IN_BYTES)));
|
|
666
|
+
}
|
|
667
|
+
const piBuffer = publicInputs.serializeWithMessagePack();
|
|
681
668
|
|
|
682
|
-
await this.
|
|
669
|
+
await using instance = await this.bbJsFactory.getInstance();
|
|
670
|
+
const { verified, durationMs } = await instance.verifyAvmProof(proofFields, piBuffer);
|
|
671
|
+
|
|
672
|
+
if (!verified) {
|
|
673
|
+
throw new ProvingError('Failed to verify AVM proof!');
|
|
674
|
+
}
|
|
675
|
+
|
|
676
|
+
logger.info(`Successfully verified AVM proof in ${durationMs} ms`);
|
|
683
677
|
}
|
|
684
678
|
|
|
685
679
|
/**
|
|
@@ -695,29 +689,6 @@ export class BBNativeRollupProver implements ServerCircuitProver {
|
|
|
695
689
|
return vk;
|
|
696
690
|
}
|
|
697
691
|
|
|
698
|
-
private async readAvmProofAsFields(
|
|
699
|
-
proofFilename: string,
|
|
700
|
-
): Promise<RecursiveProof<typeof AVM_V2_PROOF_LENGTH_IN_FIELDS_PADDED>> {
|
|
701
|
-
const rawProofBuffer = await fs.readFile(proofFilename);
|
|
702
|
-
const reader = BufferReader.asReader(rawProofBuffer);
|
|
703
|
-
const proofFields = reader.readArray(rawProofBuffer.length / Fr.SIZE_IN_BYTES, Fr);
|
|
704
|
-
|
|
705
|
-
// We extend to a fixed-size padded proof as during development any new AVM circuit column changes the
|
|
706
|
-
// proof length and we do not have a mechanism to feedback a cpp constant to noir/TS.
|
|
707
|
-
// TODO(#13390): Revive a non-padded AVM proof
|
|
708
|
-
if (proofFields.length > AVM_V2_PROOF_LENGTH_IN_FIELDS_PADDED) {
|
|
709
|
-
throw new Error(
|
|
710
|
-
`Proof has ${proofFields.length} fields, expected no more than ${AVM_V2_PROOF_LENGTH_IN_FIELDS_PADDED}.`,
|
|
711
|
-
);
|
|
712
|
-
}
|
|
713
|
-
const proofFieldsPadded = proofFields.concat(
|
|
714
|
-
Array(AVM_V2_PROOF_LENGTH_IN_FIELDS_PADDED - proofFields.length).fill(new Fr(0)),
|
|
715
|
-
);
|
|
716
|
-
|
|
717
|
-
const proof = new Proof(rawProofBuffer, /*numPublicInputs=*/ 0);
|
|
718
|
-
return new RecursiveProof(proofFieldsPadded, proof, true, AVM_V2_PROOF_LENGTH_IN_FIELDS_PADDED);
|
|
719
|
-
}
|
|
720
|
-
|
|
721
692
|
private runInDirectory<T>(fn: (dir: string) => Promise<T>) {
|
|
722
693
|
return runInDirectory(
|
|
723
694
|
this.config.bbWorkingDirectory,
|
|
@@ -731,3 +702,12 @@ export class BBNativeRollupProver implements ServerCircuitProver {
|
|
|
731
702
|
);
|
|
732
703
|
}
|
|
733
704
|
}
|
|
705
|
+
|
|
706
|
+
/** Split a buffer into 32-byte Uint8Array field elements. */
|
|
707
|
+
function splitBufferToFieldArrays(buffer: Buffer): Uint8Array[] {
|
|
708
|
+
const fields: Uint8Array[] = [];
|
|
709
|
+
for (let i = 0; i < buffer.length; i += 32) {
|
|
710
|
+
fields.push(new Uint8Array(buffer.subarray(i, i + 32)));
|
|
711
|
+
}
|
|
712
|
+
return fields;
|
|
713
|
+
}
|
package/src/test/delay_values.ts
CHANGED
|
@@ -1,43 +1,47 @@
|
|
|
1
1
|
import { ProvingRequestType } from '@aztec/stdlib/proofs';
|
|
2
2
|
|
|
3
3
|
export const WITGEN_DELAY_MS: Record<ProvingRequestType, number> = {
|
|
4
|
-
[ProvingRequestType.
|
|
5
|
-
[ProvingRequestType.
|
|
6
|
-
[ProvingRequestType.
|
|
7
|
-
[ProvingRequestType.
|
|
8
|
-
[ProvingRequestType.BLOCK_ROOT_EMPTY_TX_FIRST_ROLLUP]:
|
|
4
|
+
[ProvingRequestType.PUBLIC_CHONK_VERIFIER]: 60,
|
|
5
|
+
[ProvingRequestType.PARITY_BASE]: 1_600,
|
|
6
|
+
[ProvingRequestType.PARITY_ROOT]: 40,
|
|
7
|
+
[ProvingRequestType.BLOCK_ROOT_FIRST_ROLLUP]: 45,
|
|
8
|
+
[ProvingRequestType.BLOCK_ROOT_EMPTY_TX_FIRST_ROLLUP]: 18,
|
|
9
|
+
[ProvingRequestType.BLOCK_ROOT_SINGLE_TX_FIRST_ROLLUP]: 27,
|
|
10
|
+
[ProvingRequestType.CHECKPOINT_MERGE_ROLLUP]: 30,
|
|
11
|
+
[ProvingRequestType.CHECKPOINT_ROOT_SINGLE_BLOCK_ROLLUP]: 36_000,
|
|
12
|
+
[ProvingRequestType.ROOT_ROLLUP]: 35,
|
|
13
|
+
[ProvingRequestType.PUBLIC_TX_BASE_ROLLUP]: 2_500,
|
|
14
|
+
[ProvingRequestType.TX_MERGE_ROLLUP]: 25,
|
|
15
|
+
[ProvingRequestType.PUBLIC_VM]: 0,
|
|
16
|
+
|
|
17
|
+
// TBD
|
|
18
|
+
[ProvingRequestType.BLOCK_MERGE_ROLLUP]: 30,
|
|
9
19
|
[ProvingRequestType.BLOCK_ROOT_ROLLUP]: 40_000,
|
|
10
20
|
[ProvingRequestType.BLOCK_ROOT_SINGLE_TX_ROLLUP]: 20_000,
|
|
11
21
|
[ProvingRequestType.CHECKPOINT_ROOT_ROLLUP]: 40_000,
|
|
12
|
-
[ProvingRequestType.CHECKPOINT_ROOT_SINGLE_BLOCK_ROLLUP]: 20_000,
|
|
13
22
|
[ProvingRequestType.CHECKPOINT_PADDING_ROLLUP]: 0,
|
|
14
|
-
[ProvingRequestType.
|
|
15
|
-
[ProvingRequestType.TX_MERGE_ROLLUP]: 0,
|
|
16
|
-
[ProvingRequestType.PRIVATE_TX_BASE_ROLLUP]: 400_000,
|
|
17
|
-
[ProvingRequestType.PUBLIC_TX_BASE_ROLLUP]: 470_000,
|
|
18
|
-
[ProvingRequestType.PARITY_ROOT]: 100,
|
|
19
|
-
[ProvingRequestType.ROOT_ROLLUP]: 650,
|
|
20
|
-
[ProvingRequestType.PUBLIC_CHONK_VERIFIER]: 0,
|
|
21
|
-
[ProvingRequestType.PUBLIC_VM]: 0,
|
|
23
|
+
[ProvingRequestType.PRIVATE_TX_BASE_ROLLUP]: 2_500, // Guess based on public
|
|
22
24
|
};
|
|
23
25
|
|
|
24
26
|
export const PROOF_DELAY_MS: Record<ProvingRequestType, number> = {
|
|
25
|
-
[ProvingRequestType.
|
|
27
|
+
[ProvingRequestType.PUBLIC_CHONK_VERIFIER]: 16_300,
|
|
28
|
+
[ProvingRequestType.PARITY_BASE]: 15_300,
|
|
29
|
+
[ProvingRequestType.PARITY_ROOT]: 18_600,
|
|
30
|
+
[ProvingRequestType.BLOCK_ROOT_FIRST_ROLLUP]: 17_400,
|
|
31
|
+
[ProvingRequestType.BLOCK_ROOT_EMPTY_TX_FIRST_ROLLUP]: 4_500,
|
|
32
|
+
[ProvingRequestType.BLOCK_ROOT_SINGLE_TX_FIRST_ROLLUP]: 9_200,
|
|
33
|
+
[ProvingRequestType.CHECKPOINT_MERGE_ROLLUP]: 10_200,
|
|
34
|
+
[ProvingRequestType.CHECKPOINT_ROOT_SINGLE_BLOCK_ROLLUP]: 37_100,
|
|
35
|
+
[ProvingRequestType.ROOT_ROLLUP]: 93_000,
|
|
36
|
+
[ProvingRequestType.TX_MERGE_ROLLUP]: 10_000,
|
|
37
|
+
[ProvingRequestType.PUBLIC_TX_BASE_ROLLUP]: 44_500,
|
|
38
|
+
[ProvingRequestType.PUBLIC_VM]: 180_000,
|
|
39
|
+
|
|
40
|
+
// TBD
|
|
26
41
|
[ProvingRequestType.BLOCK_MERGE_ROLLUP]: 15_000,
|
|
27
|
-
[ProvingRequestType.BLOCK_ROOT_FIRST_ROLLUP]: 55_000,
|
|
28
|
-
[ProvingRequestType.BLOCK_ROOT_SINGLE_TX_FIRST_ROLLUP]: 35_000,
|
|
29
|
-
[ProvingRequestType.BLOCK_ROOT_EMPTY_TX_FIRST_ROLLUP]: 15_000,
|
|
30
42
|
[ProvingRequestType.BLOCK_ROOT_ROLLUP]: 35_000,
|
|
31
43
|
[ProvingRequestType.BLOCK_ROOT_SINGLE_TX_ROLLUP]: 15_000,
|
|
32
44
|
[ProvingRequestType.CHECKPOINT_ROOT_ROLLUP]: 35_000,
|
|
33
|
-
[ProvingRequestType.CHECKPOINT_ROOT_SINGLE_BLOCK_ROLLUP]: 15_000,
|
|
34
45
|
[ProvingRequestType.CHECKPOINT_PADDING_ROLLUP]: 0,
|
|
35
|
-
[ProvingRequestType.
|
|
36
|
-
[ProvingRequestType.TX_MERGE_ROLLUP]: 0,
|
|
37
|
-
[ProvingRequestType.PRIVATE_TX_BASE_ROLLUP]: 145_000,
|
|
38
|
-
[ProvingRequestType.PUBLIC_TX_BASE_ROLLUP]: 160_000,
|
|
39
|
-
[ProvingRequestType.PARITY_ROOT]: 30_000,
|
|
40
|
-
[ProvingRequestType.ROOT_ROLLUP]: 15_000,
|
|
41
|
-
[ProvingRequestType.PUBLIC_CHONK_VERIFIER]: 30_000,
|
|
42
|
-
[ProvingRequestType.PUBLIC_VM]: 0,
|
|
46
|
+
[ProvingRequestType.PRIVATE_TX_BASE_ROLLUP]: 22_000,
|
|
43
47
|
};
|
package/src/test/index.ts
CHANGED
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import {
|
|
2
2
|
AVM_V2_PROOF_LENGTH_IN_FIELDS_PADDED,
|
|
3
|
-
AVM_V2_VERIFICATION_KEY_LENGTH_IN_FIELDS_PADDED,
|
|
4
3
|
NESTED_RECURSIVE_PROOF_LENGTH,
|
|
5
4
|
NESTED_RECURSIVE_ROLLUP_HONK_PROOF_LENGTH,
|
|
6
5
|
RECURSIVE_PROOF_LENGTH,
|
|
@@ -51,14 +50,18 @@ import type { WitnessMap } from '@aztec/noir-types';
|
|
|
51
50
|
import { type CircuitSimulator, WASMSimulatorWithBlobs, emitCircuitSimulationStats } from '@aztec/simulator/server';
|
|
52
51
|
import type { AvmCircuitInputs } from '@aztec/stdlib/avm';
|
|
53
52
|
import {
|
|
54
|
-
type ProofAndVerificationKey,
|
|
55
53
|
type PublicInputsAndRecursiveProof,
|
|
56
54
|
type ServerCircuitProver,
|
|
57
|
-
makeProofAndVerificationKey,
|
|
58
55
|
makePublicInputsAndRecursiveProof,
|
|
59
56
|
} from '@aztec/stdlib/interfaces/server';
|
|
60
57
|
import type { ParityBasePrivateInputs, ParityPublicInputs, ParityRootPrivateInputs } from '@aztec/stdlib/parity';
|
|
61
|
-
import {
|
|
58
|
+
import {
|
|
59
|
+
type Proof,
|
|
60
|
+
ProvingRequestType,
|
|
61
|
+
RecursiveProof,
|
|
62
|
+
makeEmptyRecursiveProof,
|
|
63
|
+
makeRecursiveProof,
|
|
64
|
+
} from '@aztec/stdlib/proofs';
|
|
62
65
|
import {
|
|
63
66
|
type BlockMergeRollupPrivateInputs,
|
|
64
67
|
type BlockRollupPublicInputs,
|
|
@@ -81,7 +84,6 @@ import {
|
|
|
81
84
|
type TxMergeRollupPrivateInputs,
|
|
82
85
|
type TxRollupPublicInputs,
|
|
83
86
|
} from '@aztec/stdlib/rollup';
|
|
84
|
-
import { VerificationKeyData } from '@aztec/stdlib/vks';
|
|
85
87
|
import { type TelemetryClient, getTelemetryClient, trackSpan } from '@aztec/telemetry-client';
|
|
86
88
|
|
|
87
89
|
import { ProverInstrumentation } from '../instrumentation.js';
|
|
@@ -400,17 +402,12 @@ export class TestCircuitProver implements ServerCircuitProver {
|
|
|
400
402
|
);
|
|
401
403
|
}
|
|
402
404
|
|
|
403
|
-
public getAvmProof(
|
|
404
|
-
_inputs: AvmCircuitInputs,
|
|
405
|
-
): Promise<ProofAndVerificationKey<typeof AVM_V2_PROOF_LENGTH_IN_FIELDS_PADDED>> {
|
|
405
|
+
public getAvmProof(_inputs: AvmCircuitInputs): Promise<RecursiveProof<typeof AVM_V2_PROOF_LENGTH_IN_FIELDS_PADDED>> {
|
|
406
406
|
// We can't simulate the AVM because we don't have enough context to do so (e.g., DBs).
|
|
407
|
-
// We just return an empty proof
|
|
407
|
+
// We just return an empty proof.
|
|
408
408
|
this.logger.debug('Skipping AVM simulation in TestCircuitProver.');
|
|
409
409
|
return this.applyDelay(ProvingRequestType.PUBLIC_VM, () =>
|
|
410
|
-
|
|
411
|
-
makeEmptyRecursiveProof(AVM_V2_PROOF_LENGTH_IN_FIELDS_PADDED),
|
|
412
|
-
VerificationKeyData.makeFake(AVM_V2_VERIFICATION_KEY_LENGTH_IN_FIELDS_PADDED),
|
|
413
|
-
),
|
|
410
|
+
makeEmptyRecursiveProof(AVM_V2_PROOF_LENGTH_IN_FIELDS_PADDED),
|
|
414
411
|
);
|
|
415
412
|
}
|
|
416
413
|
|
|
@@ -2,7 +2,15 @@ import type { ClientProtocolCircuitVerifier, IVCProofVerificationResult } from '
|
|
|
2
2
|
import type { Tx } from '@aztec/stdlib/tx';
|
|
3
3
|
|
|
4
4
|
export class TestCircuitVerifier implements ClientProtocolCircuitVerifier {
|
|
5
|
+
constructor(private verificationDelayMs?: number) {}
|
|
5
6
|
verifyProof(_tx: Tx): Promise<IVCProofVerificationResult> {
|
|
7
|
+
if (this.verificationDelayMs !== undefined && this.verificationDelayMs > 0) {
|
|
8
|
+
return new Promise(resolve => {
|
|
9
|
+
setTimeout(() => {
|
|
10
|
+
resolve({ valid: true, durationMs: this.verificationDelayMs!, totalDurationMs: this.verificationDelayMs! });
|
|
11
|
+
}, this.verificationDelayMs);
|
|
12
|
+
});
|
|
13
|
+
}
|
|
6
14
|
return Promise.resolve({ valid: true, durationMs: 0, totalDurationMs: 0 });
|
|
7
15
|
}
|
|
8
16
|
|
|
@@ -1,13 +1,11 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { Fr } from '@aztec/foundation/fields';
|
|
1
|
+
import { Fr } from '@aztec/foundation/curves/bn254';
|
|
3
2
|
import { BufferReader } from '@aztec/foundation/serialize';
|
|
4
3
|
import { VerificationKeyAsFields, VerificationKeyData } from '@aztec/stdlib/vks';
|
|
5
4
|
|
|
6
|
-
import { strict as assert } from 'assert';
|
|
7
5
|
import { promises as fs } from 'fs';
|
|
8
6
|
import * as path from 'path';
|
|
9
7
|
|
|
10
|
-
import { VK_FILENAME } from '../bb/
|
|
8
|
+
import { VK_FILENAME } from '../bb/file_names.js';
|
|
11
9
|
|
|
12
10
|
/**
|
|
13
11
|
* Reads the verification key data stored at the specified location and parses into a VerificationKeyData
|
|
@@ -25,26 +23,3 @@ export async function extractVkData(vkDirectoryPath: string): Promise<Verificati
|
|
|
25
23
|
const vkAsFields = await VerificationKeyAsFields.fromKey(fields);
|
|
26
24
|
return new VerificationKeyData(vkAsFields, rawBinary);
|
|
27
25
|
}
|
|
28
|
-
|
|
29
|
-
/**
|
|
30
|
-
* Reads the verification key data stored in a binary file at the specified directory location and parses into a VerificationKeyData.
|
|
31
|
-
* We do not assume any JSON file available but only the binary version, contrary to the above extractVkData() method.
|
|
32
|
-
* @param vkDirectoryPath - The directory containing the verification key binary data file.
|
|
33
|
-
* @returns The verification key data
|
|
34
|
-
*/
|
|
35
|
-
export async function extractAvmVkData(vkDirectoryPath: string): Promise<VerificationKeyData> {
|
|
36
|
-
const rawBinary = await fs.readFile(path.join(vkDirectoryPath, VK_FILENAME));
|
|
37
|
-
|
|
38
|
-
const numFields = rawBinary.length / Fr.SIZE_IN_BYTES;
|
|
39
|
-
assert(numFields <= AVM_V2_VERIFICATION_KEY_LENGTH_IN_FIELDS_PADDED, 'Invalid AVM verification key length');
|
|
40
|
-
const reader = BufferReader.asReader(rawBinary);
|
|
41
|
-
const fieldsArray = reader.readArray(numFields, Fr);
|
|
42
|
-
|
|
43
|
-
const fieldsArrayPadded = fieldsArray.concat(
|
|
44
|
-
Array(AVM_V2_VERIFICATION_KEY_LENGTH_IN_FIELDS_PADDED - fieldsArray.length).fill(new Fr(0)),
|
|
45
|
-
);
|
|
46
|
-
const vkAsFields = await VerificationKeyAsFields.fromKey(fieldsArrayPadded);
|
|
47
|
-
// TODO(#16644): We should have a different type for AVM verification keys since we don't have circuit size or num public inputs in AVM VKs.
|
|
48
|
-
const vk = new VerificationKeyData(vkAsFields, rawBinary);
|
|
49
|
-
return vk;
|
|
50
|
-
}
|