@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
|
@@ -9,7 +9,6 @@ import {
|
|
|
9
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,
|
|
@@ -88,24 +87,14 @@ import { VerificationKeyData } from '@aztec/stdlib/vks';
|
|
|
88
87
|
import { Attributes, type TelemetryClient, getTelemetryClient, trackSpan } from '@aztec/telemetry-client';
|
|
89
88
|
|
|
90
89
|
import { promises as fs } from 'fs';
|
|
90
|
+
import { ungzip } from 'pako';
|
|
91
91
|
import * as path from 'path';
|
|
92
92
|
|
|
93
|
-
import {
|
|
94
|
-
type BBFailure,
|
|
95
|
-
type BBSuccess,
|
|
96
|
-
BB_RESULT,
|
|
97
|
-
PROOF_FILENAME,
|
|
98
|
-
PUBLIC_INPUTS_FILENAME,
|
|
99
|
-
VK_FILENAME,
|
|
100
|
-
generateAvmProof,
|
|
101
|
-
generateProof,
|
|
102
|
-
verifyAvmProof,
|
|
103
|
-
verifyProof,
|
|
104
|
-
} from '../../bb/execute.js';
|
|
93
|
+
import { BBJsFactory, type BBJsProofResult } from '../../bb/bb_js_backend.js';
|
|
105
94
|
import type { ACVMConfig, BBConfig } from '../../config.js';
|
|
106
95
|
import { getUltraHonkFlavorForCircuit } from '../../honk.js';
|
|
107
96
|
import { ProverInstrumentation } from '../../instrumentation.js';
|
|
108
|
-
import {
|
|
97
|
+
import { constructRecursiveProofFromBuffers } from '../proof_utils.js';
|
|
109
98
|
|
|
110
99
|
const logger = createLogger('bb-prover');
|
|
111
100
|
|
|
@@ -119,12 +108,14 @@ export interface BBProverConfig extends BBConfig, ACVMConfig {
|
|
|
119
108
|
*/
|
|
120
109
|
export class BBNativeRollupProver implements ServerCircuitProver {
|
|
121
110
|
private instrumentation: ProverInstrumentation;
|
|
111
|
+
private bbJsFactory: BBJsFactory;
|
|
122
112
|
|
|
123
113
|
constructor(
|
|
124
114
|
private config: BBProverConfig,
|
|
125
115
|
telemetry: TelemetryClient,
|
|
126
116
|
) {
|
|
127
117
|
this.instrumentation = new ProverInstrumentation(telemetry, 'BBNativeRollupProver');
|
|
118
|
+
this.bbJsFactory = new BBJsFactory(config.bbBinaryPath, { logger, debugDir: config.bbDebugOutputDir });
|
|
128
119
|
}
|
|
129
120
|
|
|
130
121
|
get tracer() {
|
|
@@ -136,7 +127,7 @@ export class BBNativeRollupProver implements ServerCircuitProver {
|
|
|
136
127
|
await fs.mkdir(config.acvmWorkingDirectory, { recursive: true });
|
|
137
128
|
await fs.access(config.bbBinaryPath, fs.constants.R_OK);
|
|
138
129
|
await fs.mkdir(config.bbWorkingDirectory, { recursive: true });
|
|
139
|
-
logger.info(`Using
|
|
130
|
+
logger.info(`Using bb.js API with binary at ${config.bbBinaryPath}`);
|
|
140
131
|
logger.info(`Using native ACVM at ${config.acvmBinaryPath} and working directory ${config.acvmWorkingDirectory}`);
|
|
141
132
|
|
|
142
133
|
return new BBNativeRollupProver(config, telemetry);
|
|
@@ -453,16 +444,16 @@ export class BBNativeRollupProver implements ServerCircuitProver {
|
|
|
453
444
|
convertInput: (input: Input) => WitnessMap,
|
|
454
445
|
convertOutput: (outputWitness: WitnessMap) => Output,
|
|
455
446
|
workingDirectory: string,
|
|
456
|
-
): Promise<{ circuitOutput: Output;
|
|
457
|
-
// 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)
|
|
458
449
|
const outputWitnessFile = path.join(workingDirectory, 'partial-witness.gz');
|
|
459
450
|
|
|
460
451
|
// Generate the partial witness using the ACVM
|
|
461
|
-
// A further temp directory will be created beneath ours and then cleaned up after the partial witness has been copied to our specified location
|
|
462
452
|
const simulator = new NativeACVMSimulator(
|
|
463
453
|
this.config.acvmWorkingDirectory,
|
|
464
454
|
this.config.acvmBinaryPath,
|
|
465
455
|
outputWitnessFile,
|
|
456
|
+
logger,
|
|
466
457
|
);
|
|
467
458
|
|
|
468
459
|
const artifact = getServerCircuitArtifact(circuitType);
|
|
@@ -470,7 +461,7 @@ export class BBNativeRollupProver implements ServerCircuitProver {
|
|
|
470
461
|
logger.debug(`Generating witness data for ${circuitType}`);
|
|
471
462
|
|
|
472
463
|
const inputWitness = convertInput(input);
|
|
473
|
-
const foreignCallHandler = undefined;
|
|
464
|
+
const foreignCallHandler = undefined;
|
|
474
465
|
const witnessResult = await simulator.executeProtocolCircuit(inputWitness, artifact, foreignCallHandler);
|
|
475
466
|
const output = convertOutput(witnessResult.witness);
|
|
476
467
|
|
|
@@ -487,75 +478,80 @@ export class BBNativeRollupProver implements ServerCircuitProver {
|
|
|
487
478
|
eventName: 'circuit-witness-generation',
|
|
488
479
|
} satisfies CircuitWitnessGenerationStats);
|
|
489
480
|
|
|
490
|
-
//
|
|
491
|
-
|
|
481
|
+
// Read and decompress the witness for bb.js
|
|
482
|
+
const witnessGz = await fs.readFile(outputWitnessFile);
|
|
483
|
+
const witness = ungzip(witnessGz);
|
|
492
484
|
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
this.getVerificationKeyDataForCircuit(circuitType).keyAsBytes,
|
|
499
|
-
outputWitnessFile,
|
|
500
|
-
getUltraHonkFlavorForCircuit(circuitType),
|
|
501
|
-
logger,
|
|
502
|
-
);
|
|
485
|
+
// Decompress bytecode for bb.js
|
|
486
|
+
const bytecode = ungzip(Buffer.from(artifact.bytecode, 'base64'));
|
|
487
|
+
|
|
488
|
+
// Prove the circuit via bb.js API
|
|
489
|
+
logger.debug(`Proving ${circuitType} via bb.js...`);
|
|
503
490
|
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
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}`);
|
|
507
503
|
}
|
|
508
504
|
|
|
509
505
|
return {
|
|
510
506
|
circuitOutput: output,
|
|
511
|
-
|
|
507
|
+
proofResult,
|
|
512
508
|
};
|
|
513
509
|
}
|
|
514
510
|
|
|
515
|
-
private async generateAvmProofWithBB(input: AvmCircuitInputs, workingDirectory: string): Promise<BBSuccess> {
|
|
516
|
-
logger.info(`Proving avm-circuit for TX ${input.hints.tx.hash}...`);
|
|
517
|
-
|
|
518
|
-
const provingResult = await generateAvmProof(this.config.bbBinaryPath, workingDirectory, input, logger);
|
|
519
|
-
|
|
520
|
-
if (provingResult.status === BB_RESULT.FAILURE) {
|
|
521
|
-
logger.error(`Failed to generate AVM proof for TX ${input.hints.tx.hash}: ${provingResult.reason}`);
|
|
522
|
-
throw new ProvingError(provingResult.reason, provingResult, provingResult.retry);
|
|
523
|
-
}
|
|
524
|
-
|
|
525
|
-
return provingResult;
|
|
526
|
-
}
|
|
527
|
-
|
|
528
511
|
private async createAvmProof(
|
|
529
512
|
input: AvmCircuitInputs,
|
|
530
513
|
): Promise<RecursiveProof<typeof AVM_V2_PROOF_LENGTH_IN_FIELDS_PADDED>> {
|
|
531
|
-
|
|
532
|
-
const provingResult = await this.generateAvmProofWithBB(input, bbWorkingDirectory);
|
|
514
|
+
logger.info(`Proving avm-circuit for TX ${input.hints.tx.hash}...`);
|
|
533
515
|
|
|
534
|
-
|
|
516
|
+
const inputsBuffer = input.serializeWithMessagePack();
|
|
517
|
+
await using instance = await this.bbJsFactory.getInstance();
|
|
518
|
+
const { proof: proofFieldArrays, durationMs } = await instance.generateAvmProof(inputsBuffer);
|
|
535
519
|
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
this.instrumentation.recordAvmDuration('provingDuration', appCircuitName, provingResult.durationMs);
|
|
539
|
-
this.instrumentation.recordAvmSize('proofSize', appCircuitName, avmProof.binaryProof.buffer.length);
|
|
520
|
+
// Convert Uint8Array[] (32-byte field elements) to Fr[]
|
|
521
|
+
const proofFields = proofFieldArrays.map(f => Fr.fromBuffer(Buffer.from(f)));
|
|
540
522
|
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
appCircuitName: input.hints.tx.hash,
|
|
546
|
-
// does not include reading the proof from disk
|
|
547
|
-
duration: provingResult.durationMs,
|
|
548
|
-
proofSize: avmProof.binaryProof.buffer.length,
|
|
549
|
-
eventName: 'circuit-proving',
|
|
550
|
-
inputSize: input.serializeWithMessagePack().length,
|
|
551
|
-
circuitSize: 1 << 21,
|
|
552
|
-
numPublicInputs: 0,
|
|
553
|
-
} satisfies CircuitProvingStats,
|
|
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}.`,
|
|
554
527
|
);
|
|
528
|
+
}
|
|
529
|
+
const proofFieldsPadded = proofFields.concat(
|
|
530
|
+
Array(AVM_V2_PROOF_LENGTH_IN_FIELDS_PADDED - proofFields.length).fill(new Fr(0)),
|
|
531
|
+
);
|
|
555
532
|
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
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);
|
|
537
|
+
|
|
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);
|
|
542
|
+
|
|
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);
|
|
553
|
+
|
|
554
|
+
return avmProof;
|
|
559
555
|
}
|
|
560
556
|
|
|
561
557
|
/**
|
|
@@ -578,33 +574,38 @@ export class BBNativeRollupProver implements ServerCircuitProver {
|
|
|
578
574
|
convertInput: (input: CircuitInputType) => WitnessMap,
|
|
579
575
|
convertOutput: (outputWitness: WitnessMap) => CircuitOutputType,
|
|
580
576
|
): Promise<{ circuitOutput: CircuitOutputType; proof: RecursiveProof<PROOF_LENGTH> }> {
|
|
581
|
-
//
|
|
582
|
-
const operation = async (
|
|
583
|
-
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(
|
|
584
580
|
input,
|
|
585
581
|
circuitType,
|
|
586
582
|
convertInput,
|
|
587
583
|
convertOutput,
|
|
588
|
-
|
|
584
|
+
workingDirectory,
|
|
589
585
|
);
|
|
590
586
|
|
|
591
587
|
const vkData = this.getVerificationKeyDataForCircuit(circuitType);
|
|
592
|
-
//
|
|
593
|
-
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
|
+
);
|
|
594
595
|
|
|
595
596
|
const circuitName = mapProtocolArtifactNameToCircuitName(circuitType);
|
|
596
|
-
this.instrumentation.recordDuration('provingDuration', circuitName,
|
|
597
|
+
this.instrumentation.recordDuration('provingDuration', circuitName, proofResult.durationMs);
|
|
597
598
|
this.instrumentation.recordSize('proofSize', circuitName, proof.binaryProof.buffer.length);
|
|
598
599
|
this.instrumentation.recordSize('circuitPublicInputCount', circuitName, vkData.numPublicInputs);
|
|
599
600
|
this.instrumentation.recordSize('circuitSize', circuitName, vkData.circuitSize);
|
|
600
601
|
logger.info(
|
|
601
|
-
`Generated proof for ${circuitType} in ${Math.ceil(
|
|
602
|
+
`Generated proof for ${circuitType} in ${Math.ceil(proofResult.durationMs)} ms, size: ${
|
|
602
603
|
proof.proof.length
|
|
603
604
|
} fields`,
|
|
604
605
|
{
|
|
605
606
|
circuitName,
|
|
606
607
|
circuitSize: vkData.circuitSize,
|
|
607
|
-
duration:
|
|
608
|
+
duration: proofResult.durationMs,
|
|
608
609
|
inputSize: output.toBuffer().length,
|
|
609
610
|
proofSize: proof.binaryProof.buffer.length,
|
|
610
611
|
eventName: 'circuit-proving',
|
|
@@ -621,49 +622,58 @@ export class BBNativeRollupProver implements ServerCircuitProver {
|
|
|
621
622
|
}
|
|
622
623
|
|
|
623
624
|
/**
|
|
624
|
-
* Verifies a proof
|
|
625
|
+
* Verifies a proof via bb.js API (no temp files needed).
|
|
625
626
|
* @param circuitType - The type of circuit whose proof is to be verified
|
|
626
627
|
* @param proof - The proof to be verified
|
|
627
628
|
*/
|
|
628
629
|
public async verifyProof(circuitType: ServerProtocolArtifact, proof: Proof) {
|
|
629
630
|
const verificationKey = this.getVerificationKeyDataForCircuit(circuitType);
|
|
630
|
-
|
|
631
|
-
|
|
632
|
-
)
|
|
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
|
+
}
|
|
650
|
+
|
|
651
|
+
if (!verified) {
|
|
652
|
+
throw new ProvingError('Failed to verify proof from key!');
|
|
653
|
+
}
|
|
654
|
+
|
|
655
|
+
logger.info(`Successfully verified proof from key in ${durationMs} ms`);
|
|
633
656
|
}
|
|
634
657
|
|
|
658
|
+
/** Verify an AVM proof via bb.js API. */
|
|
635
659
|
public async verifyAvmProof(proof: Proof, publicInputs: AvmCircuitPublicInputs) {
|
|
636
|
-
|
|
637
|
-
|
|
638
|
-
|
|
639
|
-
|
|
640
|
-
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
|
|
644
|
-
) {
|
|
645
|
-
const operation = async (bbWorkingDirectory: string) => {
|
|
646
|
-
const publicInputsFileName = path.join(bbWorkingDirectory, PUBLIC_INPUTS_FILENAME);
|
|
647
|
-
const proofFileName = path.join(bbWorkingDirectory, PROOF_FILENAME);
|
|
648
|
-
const verificationKeyPath = path.join(bbWorkingDirectory, VK_FILENAME);
|
|
649
|
-
// TODO(https://github.com/AztecProtocol/aztec-packages/issues/13189): Put this proof parsing logic in the proof class.
|
|
650
|
-
await fs.writeFile(publicInputsFileName, proof.buffer.subarray(0, proof.numPublicInputs * 32));
|
|
651
|
-
await fs.writeFile(proofFileName, proof.buffer.subarray(proof.numPublicInputs * 32));
|
|
652
|
-
if (verificationKey !== undefined) {
|
|
653
|
-
await fs.writeFile(verificationKeyPath, verificationKey.keyAsBytes);
|
|
654
|
-
}
|
|
655
|
-
|
|
656
|
-
const result = await verificationFunction(proofFileName, verificationKeyPath);
|
|
657
|
-
|
|
658
|
-
if (result.status === BB_RESULT.FAILURE) {
|
|
659
|
-
const errorMessage = `Failed to verify proof from key!`;
|
|
660
|
-
throw new ProvingError(errorMessage, result, result.retry);
|
|
661
|
-
}
|
|
662
|
-
|
|
663
|
-
logger.info(`Successfully verified proof from key in ${result.durationMs} ms`);
|
|
664
|
-
};
|
|
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();
|
|
665
668
|
|
|
666
|
-
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`);
|
|
667
677
|
}
|
|
668
678
|
|
|
669
679
|
/**
|
|
@@ -679,29 +689,6 @@ export class BBNativeRollupProver implements ServerCircuitProver {
|
|
|
679
689
|
return vk;
|
|
680
690
|
}
|
|
681
691
|
|
|
682
|
-
private async readAvmProofAsFields(
|
|
683
|
-
proofFilename: string,
|
|
684
|
-
): Promise<RecursiveProof<typeof AVM_V2_PROOF_LENGTH_IN_FIELDS_PADDED>> {
|
|
685
|
-
const rawProofBuffer = await fs.readFile(proofFilename);
|
|
686
|
-
const reader = BufferReader.asReader(rawProofBuffer);
|
|
687
|
-
const proofFields = reader.readArray(rawProofBuffer.length / Fr.SIZE_IN_BYTES, Fr);
|
|
688
|
-
|
|
689
|
-
// We extend to a fixed-size padded proof as during development any new AVM circuit column changes the
|
|
690
|
-
// proof length and we do not have a mechanism to feedback a cpp constant to noir/TS.
|
|
691
|
-
// TODO(#13390): Revive a non-padded AVM proof
|
|
692
|
-
if (proofFields.length > AVM_V2_PROOF_LENGTH_IN_FIELDS_PADDED) {
|
|
693
|
-
throw new Error(
|
|
694
|
-
`Proof has ${proofFields.length} fields, expected no more than ${AVM_V2_PROOF_LENGTH_IN_FIELDS_PADDED}.`,
|
|
695
|
-
);
|
|
696
|
-
}
|
|
697
|
-
const proofFieldsPadded = proofFields.concat(
|
|
698
|
-
Array(AVM_V2_PROOF_LENGTH_IN_FIELDS_PADDED - proofFields.length).fill(new Fr(0)),
|
|
699
|
-
);
|
|
700
|
-
|
|
701
|
-
const proof = new Proof(rawProofBuffer, /*numPublicInputs=*/ 0);
|
|
702
|
-
return new RecursiveProof(proofFieldsPadded, proof, true, AVM_V2_PROOF_LENGTH_IN_FIELDS_PADDED);
|
|
703
|
-
}
|
|
704
|
-
|
|
705
692
|
private runInDirectory<T>(fn: (dir: string) => Promise<T>) {
|
|
706
693
|
return runInDirectory(
|
|
707
694
|
this.config.bbWorkingDirectory,
|
|
@@ -715,3 +702,12 @@ export class BBNativeRollupProver implements ServerCircuitProver {
|
|
|
715
702
|
);
|
|
716
703
|
}
|
|
717
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
|
@@ -35,7 +35,7 @@ export const PROOF_DELAY_MS: Record<ProvingRequestType, number> = {
|
|
|
35
35
|
[ProvingRequestType.ROOT_ROLLUP]: 93_000,
|
|
36
36
|
[ProvingRequestType.TX_MERGE_ROLLUP]: 10_000,
|
|
37
37
|
[ProvingRequestType.PUBLIC_TX_BASE_ROLLUP]: 44_500,
|
|
38
|
-
[ProvingRequestType.PUBLIC_VM]:
|
|
38
|
+
[ProvingRequestType.PUBLIC_VM]: 180_000,
|
|
39
39
|
|
|
40
40
|
// TBD
|
|
41
41
|
[ProvingRequestType.BLOCK_MERGE_ROLLUP]: 15_000,
|
|
@@ -5,7 +5,7 @@ import { VerificationKeyAsFields, VerificationKeyData } from '@aztec/stdlib/vks'
|
|
|
5
5
|
import { promises as fs } from 'fs';
|
|
6
6
|
import * as path from 'path';
|
|
7
7
|
|
|
8
|
-
import { VK_FILENAME } from '../bb/
|
|
8
|
+
import { VK_FILENAME } from '../bb/file_names.js';
|
|
9
9
|
|
|
10
10
|
/**
|
|
11
11
|
* Reads the verification key data stored at the specified location and parses into a VerificationKeyData
|