@aztec/bb-prover 0.0.0-test.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.
Files changed (97) hide show
  1. package/dest/avm_proving_tests/avm_proving_tester.d.ts +25 -0
  2. package/dest/avm_proving_tests/avm_proving_tester.d.ts.map +1 -0
  3. package/dest/avm_proving_tests/avm_proving_tester.js +105 -0
  4. package/dest/bb/cli.d.ts +12 -0
  5. package/dest/bb/cli.d.ts.map +1 -0
  6. package/dest/bb/cli.js +19 -0
  7. package/dest/bb/execute.d.ts +140 -0
  8. package/dest/bb/execute.d.ts.map +1 -0
  9. package/dest/bb/execute.js +780 -0
  10. package/dest/bb/index.d.ts +3 -0
  11. package/dest/bb/index.d.ts.map +1 -0
  12. package/dest/bb/index.js +16 -0
  13. package/dest/config.d.ts +13 -0
  14. package/dest/config.d.ts.map +1 -0
  15. package/dest/config.js +1 -0
  16. package/dest/honk.d.ts +13 -0
  17. package/dest/honk.d.ts.map +1 -0
  18. package/dest/honk.js +18 -0
  19. package/dest/index.d.ts +8 -0
  20. package/dest/index.d.ts.map +1 -0
  21. package/dest/index.js +6 -0
  22. package/dest/instrumentation.d.ts +47 -0
  23. package/dest/instrumentation.d.ts.map +1 -0
  24. package/dest/instrumentation.js +100 -0
  25. package/dest/prover/bb_native_private_kernel_prover.d.ts +25 -0
  26. package/dest/prover/bb_native_private_kernel_prover.d.ts.map +1 -0
  27. package/dest/prover/bb_native_private_kernel_prover.js +69 -0
  28. package/dest/prover/bb_private_kernel_prover.d.ts +32 -0
  29. package/dest/prover/bb_private_kernel_prover.d.ts.map +1 -0
  30. package/dest/prover/bb_private_kernel_prover.js +109 -0
  31. package/dest/prover/bb_prover.d.ts +120 -0
  32. package/dest/prover/bb_prover.d.ts.map +1 -0
  33. package/dest/prover/bb_prover.js +423 -0
  34. package/dest/prover/client_ivc_proof_utils.d.ts +25 -0
  35. package/dest/prover/client_ivc_proof_utils.d.ts.map +1 -0
  36. package/dest/prover/client_ivc_proof_utils.js +43 -0
  37. package/dest/prover/index.d.ts +4 -0
  38. package/dest/prover/index.d.ts.map +1 -0
  39. package/dest/prover/index.js +3 -0
  40. package/dest/stats.d.ts +5 -0
  41. package/dest/stats.d.ts.map +1 -0
  42. package/dest/stats.js +62 -0
  43. package/dest/test/delay_values.d.ts +4 -0
  44. package/dest/test/delay_values.d.ts.map +1 -0
  45. package/dest/test/delay_values.js +29 -0
  46. package/dest/test/index.d.ts +3 -0
  47. package/dest/test/index.d.ts.map +1 -0
  48. package/dest/test/index.js +2 -0
  49. package/dest/test/test_circuit_prover.d.ts +81 -0
  50. package/dest/test/test_circuit_prover.d.ts.map +1 -0
  51. package/dest/test/test_circuit_prover.js +175 -0
  52. package/dest/test/test_verifier.d.ts +6 -0
  53. package/dest/test/test_verifier.d.ts.map +1 -0
  54. package/dest/test/test_verifier.js +5 -0
  55. package/dest/verification_key/verification_key_data.d.ts +9 -0
  56. package/dest/verification_key/verification_key_data.d.ts.map +1 -0
  57. package/dest/verification_key/verification_key_data.js +44 -0
  58. package/dest/verifier/bb_verifier.d.ts +17 -0
  59. package/dest/verifier/bb_verifier.d.ts.map +1 -0
  60. package/dest/verifier/bb_verifier.js +86 -0
  61. package/dest/verifier/index.d.ts +2 -0
  62. package/dest/verifier/index.d.ts.map +1 -0
  63. package/dest/verifier/index.js +1 -0
  64. package/dest/wasm/bb_wasm_private_kernel_prover.d.ts +17 -0
  65. package/dest/wasm/bb_wasm_private_kernel_prover.d.ts.map +1 -0
  66. package/dest/wasm/bb_wasm_private_kernel_prover.js +46 -0
  67. package/dest/wasm/bundle.d.ts +6 -0
  68. package/dest/wasm/bundle.d.ts.map +1 -0
  69. package/dest/wasm/bundle.js +8 -0
  70. package/dest/wasm/lazy.d.ts +6 -0
  71. package/dest/wasm/lazy.d.ts.map +1 -0
  72. package/dest/wasm/lazy.js +8 -0
  73. package/package.json +111 -0
  74. package/src/avm_proving_tests/avm_proving_tester.ts +170 -0
  75. package/src/bb/cli.ts +32 -0
  76. package/src/bb/execute.ts +853 -0
  77. package/src/bb/index.ts +23 -0
  78. package/src/config.ts +13 -0
  79. package/src/honk.ts +30 -0
  80. package/src/index.ts +8 -0
  81. package/src/instrumentation.ts +144 -0
  82. package/src/prover/bb_native_private_kernel_prover.ts +119 -0
  83. package/src/prover/bb_private_kernel_prover.ts +249 -0
  84. package/src/prover/bb_prover.ts +781 -0
  85. package/src/prover/client_ivc_proof_utils.ts +42 -0
  86. package/src/prover/index.ts +3 -0
  87. package/src/stats.ts +64 -0
  88. package/src/test/delay_values.ts +31 -0
  89. package/src/test/index.ts +2 -0
  90. package/src/test/test_circuit_prover.ts +368 -0
  91. package/src/test/test_verifier.ts +8 -0
  92. package/src/verification_key/verification_key_data.ts +45 -0
  93. package/src/verifier/bb_verifier.ts +114 -0
  94. package/src/verifier/index.ts +1 -0
  95. package/src/wasm/bb_wasm_private_kernel_prover.ts +55 -0
  96. package/src/wasm/bundle.ts +11 -0
  97. package/src/wasm/lazy.ts +11 -0
@@ -0,0 +1,42 @@
1
+ import { ClientIvcProof } from '@aztec/stdlib/proofs';
2
+
3
+ import { promises as fs } from 'fs';
4
+ import { join } from 'path';
5
+
6
+ export const CLIENT_IVC_VK_FILE_NAME = 'vk';
7
+ export const CLIENT_IVC_PROOF_FILE_NAME = 'proof';
8
+
9
+ /**
10
+ * TODO(#7371): eventually remove client_ivc_prove_output_all_msgpack and properly handle these accumulators and VKs
11
+ * Create a ClientIvcProof from the result of client_ivc_prove_output_all or client_ivc_prove_output_all_msgpack
12
+ * @param directory the directory of results
13
+ * @returns the encapsulated client ivc proof
14
+ */
15
+ export async function readFromOutputDirectory(directory: string) {
16
+ const [clientIvcVkBuffer, clientIvcProofBuffer] = await Promise.all(
17
+ [CLIENT_IVC_VK_FILE_NAME, CLIENT_IVC_PROOF_FILE_NAME].map(fileName => fs.readFile(join(directory, fileName))),
18
+ );
19
+ return new ClientIvcProof(clientIvcProofBuffer, clientIvcVkBuffer);
20
+ }
21
+
22
+ /**
23
+ * TODO(#7371): eventually remove client_ivc_prove_output_all_msgpack and properly handle these accumulators and VKs
24
+ * Serialize a ClientIvcProof to the files expected by prove_tube
25
+ *
26
+ * Example usage:
27
+ * await runInDirectory(bbWorkingDirectory, async (dir: string) => {
28
+ * await privateTx.clientIvcProof!.writeToOutputDirectory(bbWorkingDirectory);
29
+ * const result = await generateTubeProof(bbPath, dir, logger.info)
30
+ * expect(result.status).toBe(BB_RESULT.SUCCESS)
31
+ * });
32
+ * @param proof the ClientIvcProof from readFromOutputDirectory
33
+ * @param directory the directory of results
34
+ */
35
+ export async function writeToOutputDirectory(clientIvcProof: ClientIvcProof, directory: string) {
36
+ const { clientIvcProofBuffer, clientIvcVkBuffer } = clientIvcProof;
37
+ const fileData = [
38
+ [CLIENT_IVC_PROOF_FILE_NAME, clientIvcProofBuffer],
39
+ [CLIENT_IVC_VK_FILE_NAME, clientIvcVkBuffer],
40
+ ] as const;
41
+ await Promise.all(fileData.map(([fileName, buffer]) => fs.writeFile(join(directory, fileName), buffer)));
42
+ }
@@ -0,0 +1,3 @@
1
+ export * from './bb_prover.js';
2
+ export * from './bb_native_private_kernel_prover.js';
3
+ export * from './client_ivc_proof_utils.js';
package/src/stats.ts ADDED
@@ -0,0 +1,64 @@
1
+ import type { ProtocolArtifact } from '@aztec/noir-protocol-circuits-types/types';
2
+ import type { CircuitName } from '@aztec/stdlib/stats';
3
+
4
+ export function mapProtocolArtifactNameToCircuitName(artifact: ProtocolArtifact): CircuitName {
5
+ switch (artifact) {
6
+ case 'BaseParityArtifact':
7
+ return 'base-parity';
8
+ case 'RootParityArtifact':
9
+ return 'root-parity';
10
+ case 'PrivateBaseRollupArtifact':
11
+ return 'private-base-rollup';
12
+ case 'PublicBaseRollupArtifact':
13
+ return 'public-base-rollup';
14
+ case 'MergeRollupArtifact':
15
+ return 'merge-rollup';
16
+ case 'BlockRootRollupArtifact':
17
+ return 'block-root-rollup';
18
+ case 'SingleTxBlockRootRollupArtifact':
19
+ return 'single-tx-block-root-rollup';
20
+ case 'EmptyBlockRootRollupArtifact':
21
+ return 'empty-block-root-rollup';
22
+ case 'BlockMergeRollupArtifact':
23
+ return 'block-merge-rollup';
24
+ case 'RootRollupArtifact':
25
+ return 'root-rollup';
26
+ case 'PrivateKernelInitArtifact':
27
+ return 'private-kernel-init';
28
+ case 'PrivateKernelInnerArtifact':
29
+ return 'private-kernel-inner';
30
+ case 'PrivateKernelTailArtifact':
31
+ return 'private-kernel-tail';
32
+ case 'PrivateKernelTailToPublicArtifact':
33
+ return 'private-kernel-tail-to-public';
34
+ default: {
35
+ if (artifact.startsWith('PrivateKernelReset')) {
36
+ return 'private-kernel-reset';
37
+ }
38
+ throw new Error(`Unknown circuit type: ${artifact}`);
39
+ }
40
+ }
41
+ }
42
+
43
+ export function isProtocolArtifactRecursive(artifact: ProtocolArtifact): boolean {
44
+ switch (artifact) {
45
+ case 'BaseParityArtifact':
46
+ case 'RootParityArtifact':
47
+ case 'PrivateBaseRollupArtifact':
48
+ case 'PublicBaseRollupArtifact':
49
+ case 'MergeRollupArtifact':
50
+ case 'BlockRootRollupArtifact':
51
+ case 'SingleTxBlockRootRollupArtifact':
52
+ case 'EmptyBlockRootRollupArtifact':
53
+ case 'BlockMergeRollupArtifact':
54
+ case 'RootRollupArtifact':
55
+ return true;
56
+ default: {
57
+ if (artifact.startsWith('PrivateKernel')) {
58
+ // The kernel prover, where these are used, eventually calls `createClientIvcProof`, which is recursive.
59
+ return true;
60
+ }
61
+ throw new Error(`Unknown circuit type: ${artifact}`);
62
+ }
63
+ }
64
+ }
@@ -0,0 +1,31 @@
1
+ import { ProvingRequestType } from '@aztec/stdlib/proofs';
2
+
3
+ export const WITGEN_DELAY_MS: Record<ProvingRequestType, number> = {
4
+ [ProvingRequestType.BASE_PARITY]: 60,
5
+ [ProvingRequestType.BLOCK_MERGE_ROLLUP]: 650,
6
+ [ProvingRequestType.BLOCK_ROOT_ROLLUP]: 60_000,
7
+ [ProvingRequestType.EMPTY_BLOCK_ROOT_ROLLUP]: 0,
8
+ [ProvingRequestType.MERGE_ROLLUP]: 0,
9
+ [ProvingRequestType.PRIVATE_BASE_ROLLUP]: 400_000,
10
+ [ProvingRequestType.SINGLE_TX_BLOCK_ROOT_ROLLUP]: 0, // TBD
11
+ [ProvingRequestType.PUBLIC_BASE_ROLLUP]: 470_000,
12
+ [ProvingRequestType.ROOT_PARITY]: 100,
13
+ [ProvingRequestType.ROOT_ROLLUP]: 650,
14
+ [ProvingRequestType.TUBE_PROOF]: 0,
15
+ [ProvingRequestType.PUBLIC_VM]: 0,
16
+ };
17
+
18
+ export const PROOF_DELAY_MS: Record<ProvingRequestType, number> = {
19
+ [ProvingRequestType.BASE_PARITY]: 3_000,
20
+ [ProvingRequestType.BLOCK_MERGE_ROLLUP]: 15_000,
21
+ [ProvingRequestType.BLOCK_ROOT_ROLLUP]: 55_000,
22
+ [ProvingRequestType.EMPTY_BLOCK_ROOT_ROLLUP]: 0,
23
+ [ProvingRequestType.MERGE_ROLLUP]: 0,
24
+ [ProvingRequestType.PRIVATE_BASE_ROLLUP]: 145_000,
25
+ [ProvingRequestType.SINGLE_TX_BLOCK_ROOT_ROLLUP]: 0, // TBD
26
+ [ProvingRequestType.PUBLIC_BASE_ROLLUP]: 160_000,
27
+ [ProvingRequestType.ROOT_PARITY]: 30_000,
28
+ [ProvingRequestType.ROOT_ROLLUP]: 15_000,
29
+ [ProvingRequestType.TUBE_PROOF]: 30_000,
30
+ [ProvingRequestType.PUBLIC_VM]: 0,
31
+ };
@@ -0,0 +1,2 @@
1
+ export * from './test_circuit_prover.js';
2
+ export * from './test_verifier.js';
@@ -0,0 +1,368 @@
1
+ import {
2
+ AVM_PROOF_LENGTH_IN_FIELDS,
3
+ AVM_VERIFICATION_KEY_LENGTH_IN_FIELDS,
4
+ NESTED_RECURSIVE_PROOF_LENGTH,
5
+ NESTED_RECURSIVE_ROLLUP_HONK_PROOF_LENGTH,
6
+ RECURSIVE_PROOF_LENGTH,
7
+ TUBE_PROOF_LENGTH,
8
+ } from '@aztec/constants';
9
+ import { createLogger } from '@aztec/foundation/log';
10
+ import { sleep } from '@aztec/foundation/sleep';
11
+ import { Timer } from '@aztec/foundation/timer';
12
+ import {
13
+ type ServerProtocolArtifact,
14
+ SimulatedServerCircuitArtifacts,
15
+ convertBaseParityInputsToWitnessMap,
16
+ convertBaseParityOutputsFromWitnessMap,
17
+ convertBlockMergeRollupInputsToWitnessMap,
18
+ convertBlockMergeRollupOutputsFromWitnessMap,
19
+ convertEmptyBlockRootRollupInputsToWitnessMap,
20
+ convertEmptyBlockRootRollupOutputsFromWitnessMap,
21
+ convertMergeRollupInputsToWitnessMap,
22
+ convertMergeRollupOutputsFromWitnessMap,
23
+ convertRootParityInputsToWitnessMap,
24
+ convertRootParityOutputsFromWitnessMap,
25
+ convertRootRollupInputsToWitnessMap,
26
+ convertRootRollupOutputsFromWitnessMap,
27
+ convertSimulatedBlockRootRollupInputsToWitnessMap,
28
+ convertSimulatedBlockRootRollupOutputsFromWitnessMap,
29
+ convertSimulatedPrivateBaseRollupInputsToWitnessMap,
30
+ convertSimulatedPrivateBaseRollupOutputsFromWitnessMap,
31
+ convertSimulatedPublicBaseRollupInputsToWitnessMap,
32
+ convertSimulatedPublicBaseRollupOutputsFromWitnessMap,
33
+ convertSimulatedSingleTxBlockRootRollupInputsToWitnessMap,
34
+ convertSimulatedSingleTxBlockRootRollupOutputsFromWitnessMap,
35
+ } from '@aztec/noir-protocol-circuits-types/server';
36
+ import { ProtocolCircuitVks } from '@aztec/noir-protocol-circuits-types/server/vks';
37
+ import { type SimulationProvider, WASMSimulatorWithBlobs, emitCircuitSimulationStats } from '@aztec/simulator/server';
38
+ import type { AvmCircuitInputs } from '@aztec/stdlib/avm';
39
+ import {
40
+ type ProofAndVerificationKey,
41
+ type PublicInputsAndRecursiveProof,
42
+ type ServerCircuitProver,
43
+ makeProofAndVerificationKey,
44
+ makePublicInputsAndRecursiveProof,
45
+ } from '@aztec/stdlib/interfaces/server';
46
+ import type { BaseParityInputs, ParityPublicInputs, RootParityInputs } from '@aztec/stdlib/parity';
47
+ import { type Proof, ProvingRequestType, makeEmptyRecursiveProof, makeRecursiveProof } from '@aztec/stdlib/proofs';
48
+ import type {
49
+ BaseOrMergeRollupPublicInputs,
50
+ BlockMergeRollupInputs,
51
+ BlockRootOrBlockMergePublicInputs,
52
+ BlockRootRollupInputs,
53
+ EmptyBlockRootRollupInputs,
54
+ MergeRollupInputs,
55
+ PrivateBaseRollupInputs,
56
+ PublicBaseRollupInputs,
57
+ RootRollupInputs,
58
+ RootRollupPublicInputs,
59
+ SingleTxBlockRootRollupInputs,
60
+ TubeInputs,
61
+ } from '@aztec/stdlib/rollup';
62
+ import { VerificationKeyData } from '@aztec/stdlib/vks';
63
+ import { type TelemetryClient, getTelemetryClient, trackSpan } from '@aztec/telemetry-client';
64
+
65
+ import type { WitnessMap } from '@noir-lang/types';
66
+
67
+ import { ProverInstrumentation } from '../instrumentation.js';
68
+ import { mapProtocolArtifactNameToCircuitName } from '../stats.js';
69
+ import { PROOF_DELAY_MS, WITGEN_DELAY_MS } from './delay_values.js';
70
+
71
+ type TestDelay =
72
+ | {
73
+ proverTestDelayType: 'fixed';
74
+ proverTestDelayMs?: number;
75
+ }
76
+ | {
77
+ proverTestDelayType: 'realistic';
78
+ proverTestDelayFactor?: number;
79
+ };
80
+
81
+ /**
82
+ * A class for use in testing situations (e2e, unit test, etc) and temporarily for assembling a block in the sequencer.
83
+ * Simulates circuits using the most efficient method and performs no proving.
84
+ */
85
+ export class TestCircuitProver implements ServerCircuitProver {
86
+ private wasmSimulator = new WASMSimulatorWithBlobs();
87
+ private instrumentation: ProverInstrumentation;
88
+ private logger = createLogger('bb-prover:test-prover');
89
+
90
+ constructor(
91
+ private simulationProvider?: SimulationProvider,
92
+ private opts: TestDelay = { proverTestDelayType: 'fixed', proverTestDelayMs: 0 },
93
+ telemetry: TelemetryClient = getTelemetryClient(),
94
+ ) {
95
+ this.instrumentation = new ProverInstrumentation(telemetry, 'TestCircuitProver');
96
+ }
97
+
98
+ get tracer() {
99
+ return this.instrumentation.tracer;
100
+ }
101
+
102
+ /**
103
+ * Simulates the base parity circuit from its inputs.
104
+ * @param inputs - Inputs to the circuit.
105
+ * @returns The public inputs of the parity circuit.
106
+ */
107
+ @trackSpan('TestCircuitProver.getBaseParityProof')
108
+ public getBaseParityProof(
109
+ inputs: BaseParityInputs,
110
+ ): Promise<PublicInputsAndRecursiveProof<ParityPublicInputs, typeof RECURSIVE_PROOF_LENGTH>> {
111
+ return this.applyDelay(ProvingRequestType.BASE_PARITY, () =>
112
+ this.simulate(
113
+ inputs,
114
+ 'BaseParityArtifact',
115
+ RECURSIVE_PROOF_LENGTH,
116
+ convertBaseParityInputsToWitnessMap,
117
+ convertBaseParityOutputsFromWitnessMap,
118
+ ),
119
+ );
120
+ }
121
+
122
+ /**
123
+ * Simulates the root parity circuit from its inputs.
124
+ * @param inputs - Inputs to the circuit.
125
+ * @returns The public inputs of the parity circuit.
126
+ */
127
+ @trackSpan('TestCircuitProver.getRootParityProof')
128
+ public getRootParityProof(
129
+ inputs: RootParityInputs,
130
+ ): Promise<PublicInputsAndRecursiveProof<ParityPublicInputs, typeof NESTED_RECURSIVE_PROOF_LENGTH>> {
131
+ return this.applyDelay(ProvingRequestType.ROOT_PARITY, () =>
132
+ this.simulate(
133
+ inputs,
134
+ 'RootParityArtifact',
135
+ NESTED_RECURSIVE_PROOF_LENGTH,
136
+ convertRootParityInputsToWitnessMap,
137
+ convertRootParityOutputsFromWitnessMap,
138
+ ),
139
+ );
140
+ }
141
+
142
+ public getTubeProof(_tubeInput: TubeInputs): Promise<ProofAndVerificationKey<typeof TUBE_PROOF_LENGTH>> {
143
+ return this.applyDelay(ProvingRequestType.TUBE_PROOF, () =>
144
+ makeProofAndVerificationKey(makeEmptyRecursiveProof(TUBE_PROOF_LENGTH), VerificationKeyData.makeFakeRollupHonk()),
145
+ );
146
+ }
147
+
148
+ @trackSpan('TestCircuitProver.getPrivateBaseRollupProof')
149
+ public getPrivateBaseRollupProof(
150
+ inputs: PrivateBaseRollupInputs,
151
+ ): Promise<
152
+ PublicInputsAndRecursiveProof<BaseOrMergeRollupPublicInputs, typeof NESTED_RECURSIVE_ROLLUP_HONK_PROOF_LENGTH>
153
+ > {
154
+ return this.applyDelay(ProvingRequestType.PRIVATE_BASE_ROLLUP, () =>
155
+ this.simulate(
156
+ inputs,
157
+ 'PrivateBaseRollupArtifact',
158
+ NESTED_RECURSIVE_ROLLUP_HONK_PROOF_LENGTH,
159
+ convertSimulatedPrivateBaseRollupInputsToWitnessMap,
160
+ convertSimulatedPrivateBaseRollupOutputsFromWitnessMap,
161
+ ),
162
+ );
163
+ }
164
+
165
+ @trackSpan('TestCircuitProver.getPublicBaseRollupProof')
166
+ public getPublicBaseRollupProof(
167
+ inputs: PublicBaseRollupInputs,
168
+ ): Promise<
169
+ PublicInputsAndRecursiveProof<BaseOrMergeRollupPublicInputs, typeof NESTED_RECURSIVE_ROLLUP_HONK_PROOF_LENGTH>
170
+ > {
171
+ return this.applyDelay(ProvingRequestType.PUBLIC_BASE_ROLLUP, () =>
172
+ this.simulate(
173
+ inputs,
174
+ 'PublicBaseRollupArtifact',
175
+ NESTED_RECURSIVE_ROLLUP_HONK_PROOF_LENGTH,
176
+ convertSimulatedPublicBaseRollupInputsToWitnessMap,
177
+ convertSimulatedPublicBaseRollupOutputsFromWitnessMap,
178
+ ),
179
+ );
180
+ }
181
+
182
+ /**
183
+ * Simulates the merge rollup circuit from its inputs.
184
+ * @param input - Inputs to the circuit.
185
+ * @returns The public inputs as outputs of the simulation.
186
+ */
187
+ @trackSpan('TestCircuitProver.getMergeRollupProof')
188
+ public getMergeRollupProof(
189
+ input: MergeRollupInputs,
190
+ ): Promise<
191
+ PublicInputsAndRecursiveProof<BaseOrMergeRollupPublicInputs, typeof NESTED_RECURSIVE_ROLLUP_HONK_PROOF_LENGTH>
192
+ > {
193
+ return this.applyDelay(ProvingRequestType.MERGE_ROLLUP, () =>
194
+ this.simulate(
195
+ input,
196
+ 'MergeRollupArtifact',
197
+ NESTED_RECURSIVE_ROLLUP_HONK_PROOF_LENGTH,
198
+ convertMergeRollupInputsToWitnessMap,
199
+ convertMergeRollupOutputsFromWitnessMap,
200
+ ),
201
+ );
202
+ }
203
+
204
+ /**
205
+ * Simulates the block root rollup circuit from its inputs.
206
+ * @param input - Inputs to the circuit.
207
+ * @returns The public inputs as outputs of the simulation.
208
+ */
209
+ @trackSpan('TestCircuitProver.getBlockRootRollupProof')
210
+ public getBlockRootRollupProof(
211
+ input: BlockRootRollupInputs,
212
+ ): Promise<
213
+ PublicInputsAndRecursiveProof<BlockRootOrBlockMergePublicInputs, typeof NESTED_RECURSIVE_ROLLUP_HONK_PROOF_LENGTH>
214
+ > {
215
+ return this.applyDelay(ProvingRequestType.BLOCK_ROOT_ROLLUP, () =>
216
+ this.simulate(
217
+ input,
218
+ 'BlockRootRollupArtifact',
219
+ NESTED_RECURSIVE_ROLLUP_HONK_PROOF_LENGTH,
220
+ convertSimulatedBlockRootRollupInputsToWitnessMap,
221
+ convertSimulatedBlockRootRollupOutputsFromWitnessMap,
222
+ ),
223
+ );
224
+ }
225
+
226
+ @trackSpan('TestCircuitProver.getSingleTxBlockRootRollupProof')
227
+ public async getSingleTxBlockRootRollupProof(
228
+ input: SingleTxBlockRootRollupInputs,
229
+ ): Promise<
230
+ PublicInputsAndRecursiveProof<BlockRootOrBlockMergePublicInputs, typeof NESTED_RECURSIVE_ROLLUP_HONK_PROOF_LENGTH>
231
+ > {
232
+ return await this.applyDelay(ProvingRequestType.SINGLE_TX_BLOCK_ROOT_ROLLUP, () =>
233
+ this.simulate(
234
+ input,
235
+ 'SingleTxBlockRootRollupArtifact',
236
+ NESTED_RECURSIVE_ROLLUP_HONK_PROOF_LENGTH,
237
+ convertSimulatedSingleTxBlockRootRollupInputsToWitnessMap,
238
+ convertSimulatedSingleTxBlockRootRollupOutputsFromWitnessMap,
239
+ ),
240
+ );
241
+ }
242
+
243
+ /**
244
+ * Simulates the empty block root rollup circuit from its inputs.
245
+ * @param input - Inputs to the circuit.
246
+ * @returns The public inputs as outputs of the simulation.
247
+ */
248
+ @trackSpan('TestCircuitProver.getEmptyBlockRootRollupProof')
249
+ public getEmptyBlockRootRollupProof(
250
+ input: EmptyBlockRootRollupInputs,
251
+ ): Promise<
252
+ PublicInputsAndRecursiveProof<BlockRootOrBlockMergePublicInputs, typeof NESTED_RECURSIVE_ROLLUP_HONK_PROOF_LENGTH>
253
+ > {
254
+ return this.applyDelay(ProvingRequestType.EMPTY_BLOCK_ROOT_ROLLUP, () =>
255
+ this.simulate(
256
+ input,
257
+ 'EmptyBlockRootRollupArtifact',
258
+ NESTED_RECURSIVE_ROLLUP_HONK_PROOF_LENGTH,
259
+ convertEmptyBlockRootRollupInputsToWitnessMap,
260
+ convertEmptyBlockRootRollupOutputsFromWitnessMap,
261
+ ),
262
+ );
263
+ }
264
+
265
+ /**
266
+ * Simulates the block merge rollup circuit from its inputs.
267
+ * @param input - Inputs to the circuit.
268
+ * @returns The public inputs as outputs of the simulation.
269
+ */
270
+ @trackSpan('TestCircuitProver.getBlockMergeRollupProof')
271
+ public getBlockMergeRollupProof(
272
+ input: BlockMergeRollupInputs,
273
+ ): Promise<
274
+ PublicInputsAndRecursiveProof<BlockRootOrBlockMergePublicInputs, typeof NESTED_RECURSIVE_ROLLUP_HONK_PROOF_LENGTH>
275
+ > {
276
+ return this.applyDelay(ProvingRequestType.BLOCK_MERGE_ROLLUP, () =>
277
+ this.simulate(
278
+ input,
279
+ 'BlockMergeRollupArtifact',
280
+ NESTED_RECURSIVE_ROLLUP_HONK_PROOF_LENGTH,
281
+ convertBlockMergeRollupInputsToWitnessMap,
282
+ convertBlockMergeRollupOutputsFromWitnessMap,
283
+ ),
284
+ );
285
+ }
286
+
287
+ /**
288
+ * Simulates the root rollup circuit from its inputs.
289
+ * @param input - Inputs to the circuit.
290
+ * @returns The public inputs as outputs of the simulation.
291
+ */
292
+ @trackSpan('TestCircuitProver.getRootRollupProof')
293
+ public getRootRollupProof(input: RootRollupInputs): Promise<PublicInputsAndRecursiveProof<RootRollupPublicInputs>> {
294
+ return this.applyDelay(ProvingRequestType.ROOT_ROLLUP, () =>
295
+ this.simulate(
296
+ input,
297
+ 'RootRollupArtifact',
298
+ NESTED_RECURSIVE_PROOF_LENGTH,
299
+ convertRootRollupInputsToWitnessMap,
300
+ convertRootRollupOutputsFromWitnessMap,
301
+ ),
302
+ );
303
+ }
304
+
305
+ public getAvmProof(_inputs: AvmCircuitInputs): Promise<ProofAndVerificationKey<typeof AVM_PROOF_LENGTH_IN_FIELDS>> {
306
+ // We can't simulate the AVM because we don't have enough context to do so (e.g., DBs).
307
+ // We just return an empty proof and VK data.
308
+ this.logger.debug('Skipping AVM simulation in TestCircuitProver.');
309
+ return this.applyDelay(ProvingRequestType.PUBLIC_VM, () =>
310
+ makeProofAndVerificationKey(
311
+ makeEmptyRecursiveProof(AVM_PROOF_LENGTH_IN_FIELDS),
312
+ VerificationKeyData.makeFake(AVM_VERIFICATION_KEY_LENGTH_IN_FIELDS),
313
+ ),
314
+ );
315
+ }
316
+
317
+ private async applyDelay<F extends () => any>(type: ProvingRequestType, fn: F): Promise<Awaited<ReturnType<F>>> {
318
+ const timer = new Timer();
319
+ const res = await fn();
320
+ const duration = timer.ms();
321
+ if (this.opts.proverTestDelayType === 'fixed') {
322
+ await sleep(Math.max(0, (this.opts.proverTestDelayMs ?? 0) - duration));
323
+ } else if (this.opts.proverTestDelayType === 'realistic') {
324
+ const delay = WITGEN_DELAY_MS[type] + PROOF_DELAY_MS[type];
325
+ await sleep(Math.max(0, delay * (this.opts.proverTestDelayFactor ?? 1) - duration));
326
+ }
327
+
328
+ return res;
329
+ }
330
+
331
+ // Not implemented for test circuits
332
+ public verifyProof(_1: ServerProtocolArtifact, _2: Proof): Promise<void> {
333
+ return Promise.reject(new Error('Method not implemented.'));
334
+ }
335
+
336
+ private async simulate<
337
+ PROOF_LENGTH extends number,
338
+ CircuitInputType extends { toBuffer: () => Buffer },
339
+ CircuitOutputType extends { toBuffer: () => Buffer },
340
+ >(
341
+ input: CircuitInputType,
342
+ artifactName: ServerProtocolArtifact,
343
+ proofLength: PROOF_LENGTH,
344
+ convertInput: (input: CircuitInputType) => WitnessMap,
345
+ convertOutput: (outputWitness: WitnessMap) => CircuitOutputType,
346
+ ) {
347
+ const timer = new Timer();
348
+ const witnessMap = convertInput(input);
349
+ const circuitName = mapProtocolArtifactNameToCircuitName(artifactName);
350
+
351
+ let simulationProvider = this.simulationProvider ?? this.wasmSimulator;
352
+ if (['BlockRootRollupArtifact', 'SingleTxBlockRootRollupArtifact'].includes(artifactName)) {
353
+ // TODO(#10323): temporarily force block root to use wasm while we simulate
354
+ // the blob operations with an oracle. Appears to be no way to provide nativeACVM with a foreign call hander.
355
+ simulationProvider = this.wasmSimulator;
356
+ }
357
+ const witness = await simulationProvider.executeProtocolCircuit(
358
+ witnessMap,
359
+ SimulatedServerCircuitArtifacts[artifactName],
360
+ );
361
+
362
+ const result = convertOutput(witness);
363
+
364
+ this.instrumentation.recordDuration('simulationDuration', circuitName, timer);
365
+ emitCircuitSimulationStats(circuitName, timer.ms(), input.toBuffer().length, result.toBuffer().length, this.logger);
366
+ return makePublicInputsAndRecursiveProof(result, makeRecursiveProof(proofLength), ProtocolCircuitVks[artifactName]);
367
+ }
368
+ }
@@ -0,0 +1,8 @@
1
+ import type { ClientProtocolCircuitVerifier } from '@aztec/stdlib/interfaces/server';
2
+ import type { Tx } from '@aztec/stdlib/tx';
3
+
4
+ export class TestCircuitVerifier implements ClientProtocolCircuitVerifier {
5
+ verifyProof(_tx: Tx): Promise<boolean> {
6
+ return Promise.resolve(true);
7
+ }
8
+ }
@@ -0,0 +1,45 @@
1
+ import { AVM_VERIFICATION_KEY_LENGTH_IN_FIELDS } from '@aztec/constants';
2
+ import { Fr } from '@aztec/foundation/fields';
3
+ import { hashVK } from '@aztec/stdlib/hash';
4
+ import { VerificationKeyAsFields, VerificationKeyData } from '@aztec/stdlib/vks';
5
+
6
+ import { strict as assert } from 'assert';
7
+ import { promises as fs } from 'fs';
8
+ import * as path from 'path';
9
+
10
+ import { VK_FIELDS_FILENAME, VK_FILENAME } from '../bb/execute.js';
11
+
12
+ /**
13
+ * Reads the verification key data stored at the specified location and parses into a VerificationKeyData
14
+ * @param vkDirectoryPath - The directory containing the verification key data files
15
+ * @returns The verification key data
16
+ */
17
+ export async function extractVkData(vkDirectoryPath: string): Promise<VerificationKeyData> {
18
+ const [rawFields, rawBinary] = await Promise.all([
19
+ fs.readFile(path.join(vkDirectoryPath, VK_FIELDS_FILENAME), { encoding: 'utf-8' }),
20
+ fs.readFile(path.join(vkDirectoryPath, VK_FILENAME)),
21
+ ]);
22
+ const fieldsJson = JSON.parse(rawFields);
23
+ const fields = fieldsJson.map(Fr.fromHexString);
24
+ // The hash is not included in the BB response
25
+ const vkHash = await hashVK(fields);
26
+ const vkAsFields = new VerificationKeyAsFields(fields, vkHash);
27
+ return new VerificationKeyData(vkAsFields, rawBinary);
28
+ }
29
+
30
+ // TODO: This was adapted from the above function. A refactor might be needed.
31
+ export async function extractAvmVkData(vkDirectoryPath: string): Promise<VerificationKeyData> {
32
+ const [rawFields, rawBinary] = await Promise.all([
33
+ fs.readFile(path.join(vkDirectoryPath, VK_FIELDS_FILENAME), { encoding: 'utf-8' }),
34
+ fs.readFile(path.join(vkDirectoryPath, VK_FILENAME)),
35
+ ]);
36
+ const fieldsJson = JSON.parse(rawFields);
37
+ const fields = fieldsJson.map(Fr.fromHexString);
38
+ // The first item is the hash, this is not part of the actual VK
39
+ // TODO: is the above actually the case?
40
+ const vkHash = fields[0];
41
+ assert(fields.length === AVM_VERIFICATION_KEY_LENGTH_IN_FIELDS, 'Invalid AVM verification key length');
42
+ const vkAsFields = new VerificationKeyAsFields(fields, vkHash);
43
+ const vk = new VerificationKeyData(vkAsFields, rawBinary);
44
+ return vk;
45
+ }
@@ -0,0 +1,114 @@
1
+ import { runInDirectory } from '@aztec/foundation/fs';
2
+ import { type Logger, createLogger } from '@aztec/foundation/log';
3
+ import { ServerCircuitVks } from '@aztec/noir-protocol-circuits-types/server/vks';
4
+ import type { ClientProtocolArtifact, ServerProtocolArtifact } from '@aztec/noir-protocol-circuits-types/types';
5
+ import type { ClientProtocolCircuitVerifier } from '@aztec/stdlib/interfaces/server';
6
+ import type { Proof } from '@aztec/stdlib/proofs';
7
+ import type { CircuitVerificationStats } from '@aztec/stdlib/stats';
8
+ import { Tx } from '@aztec/stdlib/tx';
9
+ import type { VerificationKeyData } from '@aztec/stdlib/vks';
10
+
11
+ import { promises as fs } from 'fs';
12
+ import * as path from 'path';
13
+
14
+ import { BB_RESULT, PROOF_FILENAME, VK_FILENAME, verifyClientIvcProof, verifyProof } from '../bb/execute.js';
15
+ import type { BBConfig } from '../config.js';
16
+ import { getUltraHonkFlavorForCircuit } from '../honk.js';
17
+ import { writeToOutputDirectory } from '../prover/client_ivc_proof_utils.js';
18
+ import { mapProtocolArtifactNameToCircuitName } from '../stats.js';
19
+
20
+ export class BBCircuitVerifier implements ClientProtocolCircuitVerifier {
21
+ private constructor(private config: BBConfig, private logger: Logger) {}
22
+
23
+ public static async new(config: BBConfig, logger = createLogger('bb-prover:verifier')) {
24
+ await fs.mkdir(config.bbWorkingDirectory, { recursive: true });
25
+ return new BBCircuitVerifier(config, logger);
26
+ }
27
+
28
+ public getVerificationKeyData(circuitType: ServerProtocolArtifact): VerificationKeyData {
29
+ const vk = ServerCircuitVks[circuitType];
30
+ if (vk === undefined) {
31
+ throw new Error('Could not find VK for server artifact ' + circuitType);
32
+ }
33
+ return vk;
34
+ }
35
+
36
+ public async verifyProofForCircuit(circuit: ServerProtocolArtifact, proof: Proof) {
37
+ const operation = async (bbWorkingDirectory: string) => {
38
+ const proofFileName = path.join(bbWorkingDirectory, PROOF_FILENAME);
39
+ const verificationKeyPath = path.join(bbWorkingDirectory, VK_FILENAME);
40
+ const verificationKey = this.getVerificationKeyData(circuit);
41
+
42
+ this.logger.debug(`${circuit} Verifying with key: ${verificationKey.keyAsFields.hash.toString()}`);
43
+
44
+ await fs.writeFile(proofFileName, proof.buffer);
45
+ await fs.writeFile(verificationKeyPath, verificationKey.keyAsBytes);
46
+
47
+ const result = await verifyProof(
48
+ this.config.bbBinaryPath,
49
+ proofFileName,
50
+ verificationKeyPath!,
51
+ getUltraHonkFlavorForCircuit(circuit),
52
+ this.logger,
53
+ );
54
+
55
+ if (result.status === BB_RESULT.FAILURE) {
56
+ const errorMessage = `Failed to verify ${circuit} proof!`;
57
+ throw new Error(errorMessage);
58
+ }
59
+
60
+ this.logger.debug(`${circuit} verification successful`, {
61
+ circuitName: mapProtocolArtifactNameToCircuitName(circuit),
62
+ duration: result.durationMs,
63
+ eventName: 'circuit-verification',
64
+ proofType: 'ultra-honk',
65
+ } satisfies CircuitVerificationStats);
66
+ };
67
+ await runInDirectory(this.config.bbWorkingDirectory, operation, this.config.bbSkipCleanup, this.logger);
68
+ }
69
+
70
+ public async verifyProof(tx: Tx): Promise<boolean> {
71
+ try {
72
+ // TODO(#7370) The verification keys should be supplied separately and based on the expectedCircuit
73
+ // rather than read from the tx object itself. We also need the vks for the translator and ecc, which
74
+ // are not being saved along the other vks yet. Reuse the 'verifyProofForCircuit' method above once
75
+ // we have all the verification keys available.
76
+ const expectedCircuit: ClientProtocolArtifact = tx.data.forPublic
77
+ ? 'PrivateKernelTailToPublicArtifact'
78
+ : 'PrivateKernelTailArtifact';
79
+ const circuit = 'ClientIVC';
80
+
81
+ // Block below is almost copy-pasted from verifyProofForCircuit
82
+ const operation = async (bbWorkingDirectory: string) => {
83
+ const logFunction = (message: string) => {
84
+ this.logger.debug(`${circuit} BB out - ${message}`);
85
+ };
86
+
87
+ await writeToOutputDirectory(tx.clientIvcProof, bbWorkingDirectory);
88
+ const result = await verifyClientIvcProof(
89
+ this.config.bbBinaryPath,
90
+ bbWorkingDirectory.concat('/proof'),
91
+ bbWorkingDirectory.concat('/vk'),
92
+ logFunction,
93
+ );
94
+
95
+ if (result.status === BB_RESULT.FAILURE) {
96
+ const errorMessage = `Failed to verify ${circuit} proof!`;
97
+ throw new Error(errorMessage);
98
+ }
99
+
100
+ this.logger.debug(`${circuit} verification successful`, {
101
+ circuitName: mapProtocolArtifactNameToCircuitName(expectedCircuit),
102
+ duration: result.durationMs,
103
+ eventName: 'circuit-verification',
104
+ proofType: 'client-ivc',
105
+ } satisfies CircuitVerificationStats);
106
+ };
107
+ await runInDirectory(this.config.bbWorkingDirectory, operation, this.config.bbSkipCleanup, this.logger);
108
+ return true;
109
+ } catch (err) {
110
+ this.logger.warn(`Failed to verify ClientIVC proof for tx ${Tx.getHash(tx)}: ${String(err)}`);
111
+ return false;
112
+ }
113
+ }
114
+ }