@aztec/bb-prover 0.0.0-test.0 → 0.0.1-commit.24de95ac

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 (105) hide show
  1. package/dest/avm_proving_tests/avm_proving_tester.d.ts +14 -17
  2. package/dest/avm_proving_tests/avm_proving_tester.d.ts.map +1 -1
  3. package/dest/avm_proving_tests/avm_proving_tester.js +128 -78
  4. package/dest/bb/execute.d.ts +13 -46
  5. package/dest/bb/execute.d.ts.map +1 -1
  6. package/dest/bb/execute.js +120 -228
  7. package/dest/config.d.ts +2 -0
  8. package/dest/config.d.ts.map +1 -1
  9. package/dest/honk.d.ts +2 -2
  10. package/dest/honk.d.ts.map +1 -1
  11. package/dest/honk.js +3 -2
  12. package/dest/index.d.ts +1 -0
  13. package/dest/index.d.ts.map +1 -1
  14. package/dest/index.js +1 -0
  15. package/dest/instrumentation.d.ts +2 -2
  16. package/dest/instrumentation.d.ts.map +1 -1
  17. package/dest/instrumentation.js +2 -4
  18. package/dest/prover/{bb_private_kernel_prover.d.ts → client/bb_private_kernel_prover.d.ts} +10 -10
  19. package/dest/prover/client/bb_private_kernel_prover.d.ts.map +1 -0
  20. package/dest/prover/{bb_private_kernel_prover.js → client/bb_private_kernel_prover.js} +21 -18
  21. package/dest/prover/client/native/bb_native_private_kernel_prover.d.ts +23 -0
  22. package/dest/prover/client/native/bb_native_private_kernel_prover.d.ts.map +1 -0
  23. package/dest/prover/{bb_native_private_kernel_prover.js → client/native/bb_native_private_kernel_prover.js} +19 -22
  24. package/dest/prover/client/wasm/bb_wasm_private_kernel_prover.d.ts +15 -0
  25. package/dest/prover/client/wasm/bb_wasm_private_kernel_prover.d.ts.map +1 -0
  26. package/dest/prover/client/wasm/bb_wasm_private_kernel_prover.js +46 -0
  27. package/dest/prover/client/wasm/bundle.d.ts +6 -0
  28. package/dest/prover/client/wasm/bundle.d.ts.map +1 -0
  29. package/dest/{wasm → prover/client/wasm}/bundle.js +2 -2
  30. package/dest/prover/client/wasm/lazy.d.ts +6 -0
  31. package/dest/prover/client/wasm/lazy.d.ts.map +1 -0
  32. package/dest/{wasm → prover/client/wasm}/lazy.js +2 -2
  33. package/dest/prover/index.d.ts +2 -3
  34. package/dest/prover/index.d.ts.map +1 -1
  35. package/dest/prover/index.js +2 -3
  36. package/dest/prover/proof_utils.d.ts +19 -0
  37. package/dest/prover/proof_utils.d.ts.map +1 -0
  38. package/dest/prover/proof_utils.js +72 -0
  39. package/dest/prover/server/bb_prover.d.ts +109 -0
  40. package/dest/prover/server/bb_prover.d.ts.map +1 -0
  41. package/dest/prover/server/bb_prover.js +339 -0
  42. package/dest/test/delay_values.d.ts.map +1 -1
  43. package/dest/test/delay_values.js +30 -18
  44. package/dest/test/test_circuit_prover.d.ts +24 -33
  45. package/dest/test/test_circuit_prover.d.ts.map +1 -1
  46. package/dest/test/test_circuit_prover.js +85 -59
  47. package/dest/test/test_verifier.d.ts +3 -2
  48. package/dest/test/test_verifier.d.ts.map +1 -1
  49. package/dest/test/test_verifier.js +8 -1
  50. package/dest/verification_key/verification_key_data.d.ts +6 -0
  51. package/dest/verification_key/verification_key_data.d.ts.map +1 -1
  52. package/dest/verification_key/verification_key_data.js +23 -29
  53. package/dest/verifier/bb_verifier.d.ts +5 -4
  54. package/dest/verifier/bb_verifier.d.ts.map +1 -1
  55. package/dest/verifier/bb_verifier.js +43 -25
  56. package/dest/verifier/index.d.ts +1 -0
  57. package/dest/verifier/index.d.ts.map +1 -1
  58. package/dest/verifier/index.js +1 -0
  59. package/dest/verifier/queued_chonk_verifier.d.ts +15 -0
  60. package/dest/verifier/queued_chonk_verifier.d.ts.map +1 -0
  61. package/dest/verifier/queued_chonk_verifier.js +132 -0
  62. package/package.json +32 -31
  63. package/src/avm_proving_tests/avm_proving_tester.ts +209 -103
  64. package/src/bb/execute.ts +98 -242
  65. package/src/config.ts +2 -0
  66. package/src/honk.ts +3 -2
  67. package/src/index.ts +1 -0
  68. package/src/instrumentation.ts +2 -4
  69. package/src/prover/{bb_private_kernel_prover.ts → client/bb_private_kernel_prover.ts} +53 -29
  70. package/src/prover/{bb_native_private_kernel_prover.ts → client/native/bb_native_private_kernel_prover.ts} +23 -37
  71. package/src/{wasm → prover/client/wasm}/bb_wasm_private_kernel_prover.ts +18 -15
  72. package/src/{wasm → prover/client/wasm}/bundle.ts +3 -3
  73. package/src/{wasm → prover/client/wasm}/lazy.ts +3 -3
  74. package/src/prover/index.ts +2 -3
  75. package/src/prover/proof_utils.ts +115 -0
  76. package/src/prover/server/bb_prover.ts +733 -0
  77. package/src/test/delay_values.ts +30 -18
  78. package/src/test/test_circuit_prover.ts +260 -147
  79. package/src/test/test_verifier.ts +7 -3
  80. package/src/verification_key/verification_key_data.ts +29 -24
  81. package/src/verifier/bb_verifier.ts +60 -32
  82. package/src/verifier/index.ts +1 -0
  83. package/src/verifier/queued_chonk_verifier.ts +140 -0
  84. package/dest/prover/bb_native_private_kernel_prover.d.ts +0 -25
  85. package/dest/prover/bb_native_private_kernel_prover.d.ts.map +0 -1
  86. package/dest/prover/bb_private_kernel_prover.d.ts.map +0 -1
  87. package/dest/prover/bb_prover.d.ts +0 -120
  88. package/dest/prover/bb_prover.d.ts.map +0 -1
  89. package/dest/prover/bb_prover.js +0 -423
  90. package/dest/prover/client_ivc_proof_utils.d.ts +0 -25
  91. package/dest/prover/client_ivc_proof_utils.d.ts.map +0 -1
  92. package/dest/prover/client_ivc_proof_utils.js +0 -43
  93. package/dest/stats.d.ts +0 -5
  94. package/dest/stats.d.ts.map +0 -1
  95. package/dest/stats.js +0 -62
  96. package/dest/wasm/bb_wasm_private_kernel_prover.d.ts +0 -17
  97. package/dest/wasm/bb_wasm_private_kernel_prover.d.ts.map +0 -1
  98. package/dest/wasm/bb_wasm_private_kernel_prover.js +0 -46
  99. package/dest/wasm/bundle.d.ts +0 -6
  100. package/dest/wasm/bundle.d.ts.map +0 -1
  101. package/dest/wasm/lazy.d.ts +0 -6
  102. package/dest/wasm/lazy.d.ts.map +0 -1
  103. package/src/prover/bb_prover.ts +0 -781
  104. package/src/prover/client_ivc_proof_utils.ts +0 -42
  105. package/src/stats.ts +0 -64
@@ -3,15 +3,12 @@ import { Timer } from '@aztec/foundation/timer';
3
3
  import * as proc from 'child_process';
4
4
  import { promises as fs } from 'fs';
5
5
  import { basename, dirname, join } from 'path';
6
- import { CLIENT_IVC_PROOF_FILE_NAME, CLIENT_IVC_VK_FILE_NAME } from '../prover/client_ivc_proof_utils.js';
7
6
  export const VK_FILENAME = 'vk';
8
- export const VK_FIELDS_FILENAME = 'vk_fields.json';
7
+ export const PUBLIC_INPUTS_FILENAME = 'public_inputs';
9
8
  export const PROOF_FILENAME = 'proof';
10
- export const PROOF_FIELDS_FILENAME = 'proof_fields.json';
11
9
  export const AVM_INPUTS_FILENAME = 'avm_inputs.bin';
12
10
  export const AVM_BYTECODE_FILENAME = 'avm_bytecode.bin';
13
11
  export const AVM_PUBLIC_INPUTS_FILENAME = 'avm_public_inputs.bin';
14
- export const AVM_HINTS_FILENAME = 'avm_hints.bin';
15
12
  export var BB_RESULT = /*#__PURE__*/ function(BB_RESULT) {
16
13
  BB_RESULT[BB_RESULT["SUCCESS"] = 0] = "SUCCESS";
17
14
  BB_RESULT[BB_RESULT["FAILURE"] = 1] = "FAILURE";
@@ -24,13 +21,21 @@ export var BB_RESULT = /*#__PURE__*/ function(BB_RESULT) {
24
21
  * @param command - The command to execute
25
22
  * @param args - The arguments to pass
26
23
  * @param logger - A log function
24
+ * @param timeout - An optional timeout before killing the BB process
27
25
  * @param resultParser - An optional handler for detecting success or failure
28
26
  * @returns The completed partial witness outputted from the circuit
29
- */ export function executeBB(pathToBB, command, args, logger, resultParser = (code)=>code === 0) {
27
+ */ export function executeBB(pathToBB, command, args, logger, concurrency, timeout, resultParser = (code)=>code === 0) {
30
28
  return new Promise((resolve)=>{
31
29
  // spawn the bb process
32
30
  const { HARDWARE_CONCURRENCY: _, ...envWithoutConcurrency } = process.env;
33
- const env = process.env.HARDWARE_CONCURRENCY ? process.env : envWithoutConcurrency;
31
+ const env = envWithoutConcurrency;
32
+ // We prioritise the concurrency argument if provided and > 0
33
+ if (concurrency && concurrency > 0) {
34
+ env.HARDWARE_CONCURRENCY = concurrency.toString();
35
+ } else if (process.env.HARDWARE_CONCURRENCY) {
36
+ env.HARDWARE_CONCURRENCY = process.env.HARDWARE_CONCURRENCY;
37
+ }
38
+ logger(`BB concurrency: ${env.HARDWARE_CONCURRENCY}`);
34
39
  logger(`Executing BB with: ${pathToBB} ${command} ${args.join(' ')}`);
35
40
  const bb = proc.spawn(pathToBB, [
36
41
  command,
@@ -38,6 +43,20 @@ export var BB_RESULT = /*#__PURE__*/ function(BB_RESULT) {
38
43
  ], {
39
44
  env
40
45
  });
46
+ let timeoutId;
47
+ if (timeout !== undefined) {
48
+ timeoutId = setTimeout(()=>{
49
+ logger(`BB execution timed out after ${timeout}ms, killing process`);
50
+ if (bb.pid) {
51
+ bb.kill('SIGKILL');
52
+ }
53
+ resolve({
54
+ status: 1,
55
+ exitCode: -1,
56
+ signal: 'TIMEOUT'
57
+ });
58
+ }, timeout);
59
+ }
41
60
  bb.stdout.on('data', (data)=>{
42
61
  const message = data.toString('utf-8').replace(/\n$/, '');
43
62
  logger(message);
@@ -47,6 +66,9 @@ export var BB_RESULT = /*#__PURE__*/ function(BB_RESULT) {
47
66
  logger(message);
48
67
  });
49
68
  bb.on('close', (exitCode, signal)=>{
69
+ if (timeoutId) {
70
+ clearTimeout(timeoutId);
71
+ }
50
72
  if (resultParser(exitCode)) {
51
73
  resolve({
52
74
  status: 0,
@@ -67,12 +89,11 @@ export var BB_RESULT = /*#__PURE__*/ function(BB_RESULT) {
67
89
  signal: undefined
68
90
  }));
69
91
  }
70
- // TODO(#7369) comment this etc (really just take inspiration from this and rewrite it all O:))
71
- export async function executeBbClientIvcProof(pathToBB, workingDirectory, bytecodeStackPath, witnessStackPath, log) {
92
+ export async function executeBbChonkProof(pathToBB, workingDirectory, inputsPath, log, writeVk = false) {
72
93
  // Check that the working directory exists
73
94
  try {
74
95
  await fs.access(workingDirectory);
75
- } catch (error) {
96
+ } catch {
76
97
  return {
77
98
  status: 1,
78
99
  reason: `Working directory ${workingDirectory} does not exist`
@@ -89,26 +110,23 @@ export async function executeBbClientIvcProof(pathToBB, workingDirectory, byteco
89
110
  }
90
111
  try {
91
112
  // Write the bytecode to the working directory
92
- log(`bytecodePath ${bytecodeStackPath}`);
93
- log(`outputPath ${outputPath}`);
113
+ log(`inputsPath ${inputsPath}`);
114
+ const timer = new Timer();
115
+ const logFunction = (message)=>{
116
+ log(`bb - ${message}`);
117
+ };
94
118
  const args = [
95
119
  '-o',
96
120
  outputPath,
97
- '-b',
98
- bytecodeStackPath,
99
- '-w',
100
- witnessStackPath,
121
+ '--ivc_inputs_path',
122
+ inputsPath,
101
123
  '-v',
102
124
  '--scheme',
103
- 'client_ivc',
104
- '--input_type',
105
- 'runtime_stack',
106
- '--write_vk'
125
+ 'chonk'
107
126
  ];
108
- const timer = new Timer();
109
- const logFunction = (message)=>{
110
- log(`bb - ${message}`);
111
- };
127
+ if (writeVk) {
128
+ args.push('--write_vk');
129
+ }
112
130
  const result = await executeBB(pathToBB, 'prove', args, logFunction);
113
131
  const durationMs = timer.ms();
114
132
  if (result.status == 0) {
@@ -117,7 +135,7 @@ export async function executeBbClientIvcProof(pathToBB, workingDirectory, byteco
117
135
  durationMs,
118
136
  proofPath: `${outputPath}`,
119
137
  pkPath: undefined,
120
- vkPath: `${outputPath}`
138
+ vkDirectoryPath: `${outputPath}`
121
139
  };
122
140
  }
123
141
  // Not a great error message here but it is difficult to decipher what comes from bb
@@ -153,6 +171,15 @@ function getArgs(flavor) {
153
171
  'keccak'
154
172
  ];
155
173
  }
174
+ case 'ultra_starknet_honk':
175
+ {
176
+ return [
177
+ '--scheme',
178
+ 'ultra_honk',
179
+ '--oracle_hash',
180
+ 'starknet'
181
+ ];
182
+ }
156
183
  case 'ultra_rollup_honk':
157
184
  {
158
185
  return [
@@ -175,18 +202,19 @@ function getArgs(flavor) {
175
202
  * @param inputWitnessFile - The circuit input witness
176
203
  * @param log - A logging function
177
204
  * @returns An object containing a result indication, the location of the proof and the duration taken
178
- */ export async function generateProof(pathToBB, workingDirectory, circuitName, bytecode, recursive, inputWitnessFile, flavor, log) {
205
+ */ export async function generateProof(pathToBB, workingDirectory, circuitName, bytecode, verificationKey, inputWitnessFile, flavor, log) {
179
206
  // Check that the working directory exists
180
207
  try {
181
208
  await fs.access(workingDirectory);
182
- } catch (error) {
209
+ } catch {
183
210
  return {
184
211
  status: 1,
185
212
  reason: `Working directory ${workingDirectory} does not exist`
186
213
  };
187
214
  }
188
- // The bytecode is written to e.g. /workingDirectory/BaseParityArtifact-bytecode
215
+ // The bytecode is written to e.g. /workingDirectory/ParityBaseArtifact-bytecode
189
216
  const bytecodePath = `${workingDirectory}/${circuitName}-bytecode`;
217
+ const vkPath = `${workingDirectory}/${circuitName}-vk`;
190
218
  // The proof is written to e.g. /workingDirectory/ultra_honk/proof
191
219
  const outputPath = `${workingDirectory}`;
192
220
  const binaryPresent = await fs.access(pathToBB, fs.constants.R_OK).then((_)=>true).catch((_)=>false);
@@ -197,26 +225,30 @@ function getArgs(flavor) {
197
225
  };
198
226
  }
199
227
  try {
200
- // Write the bytecode to the working directory
201
- await fs.writeFile(bytecodePath, bytecode);
228
+ // Write the bytecode and vk to the working directory
229
+ await Promise.all([
230
+ fs.writeFile(bytecodePath, bytecode),
231
+ fs.writeFile(vkPath, verificationKey)
232
+ ]);
202
233
  const args = getArgs(flavor).concat([
203
- '--output_format',
204
- 'bytes_and_fields',
205
- '--write_vk',
234
+ '--disable_zk',
206
235
  '-o',
207
236
  outputPath,
208
237
  '-b',
209
238
  bytecodePath,
239
+ '-k',
240
+ vkPath,
210
241
  '-w',
211
242
  inputWitnessFile,
212
243
  '-v'
213
244
  ]);
214
- if (recursive) {
215
- args.push('--init_kzg_accumulator');
245
+ const loggingArg = log.level === 'debug' || log.level === 'trace' ? '-d' : log.level === 'verbose' ? '-v' : '';
246
+ if (loggingArg !== '') {
247
+ args.push(loggingArg);
216
248
  }
217
249
  const timer = new Timer();
218
250
  const logFunction = (message)=>{
219
- log(`${circuitName} BB out - ${message}`);
251
+ log.info(`${circuitName} BB out - ${message}`);
220
252
  };
221
253
  const result = await executeBB(pathToBB, `prove`, args, logFunction);
222
254
  const duration = timer.ms();
@@ -226,80 +258,7 @@ function getArgs(flavor) {
226
258
  durationMs: duration,
227
259
  proofPath: `${outputPath}`,
228
260
  pkPath: undefined,
229
- vkPath: `${outputPath}`
230
- };
231
- }
232
- // Not a great error message here but it is difficult to decipher what comes from bb
233
- return {
234
- status: 1,
235
- reason: `Failed to generate proof. Exit code ${result.exitCode}. Signal ${result.signal}.`,
236
- retry: !!result.signal
237
- };
238
- } catch (error) {
239
- return {
240
- status: 1,
241
- reason: `${error}`
242
- };
243
- }
244
- }
245
- /**
246
- * Used for generating proofs of the tube circuit
247
- * It is assumed that the working directory is a temporary and/or random directory used solely for generating this proof.
248
- * @param pathToBB - The full path to the bb binary
249
- * @param workingDirectory - A working directory for use by bb
250
- * @param circuitName - An identifier for the circuit
251
- * @param bytecode - The compiled circuit bytecode
252
- * @param inputWitnessFile - The circuit input witness
253
- * @param log - A logging function
254
- * @returns An object containing a result indication, the location of the proof and the duration taken
255
- */ export async function generateTubeProof(pathToBB, workingDirectory, log) {
256
- // Check that the working directory exists
257
- try {
258
- await fs.access(workingDirectory);
259
- } catch (error) {
260
- return {
261
- status: 1,
262
- reason: `Working directory ${workingDirectory} does not exist`
263
- };
264
- }
265
- // // Paths for the inputs
266
- const vkPath = join(workingDirectory, CLIENT_IVC_VK_FILE_NAME);
267
- const proofPath = join(workingDirectory, CLIENT_IVC_PROOF_FILE_NAME);
268
- // The proof is written to e.g. /workingDirectory/proof
269
- const outputPath = workingDirectory;
270
- const filePresent = async (file)=>await fs.access(file, fs.constants.R_OK).then((_)=>true).catch((_)=>false);
271
- const binaryPresent = await filePresent(pathToBB);
272
- if (!binaryPresent) {
273
- return {
274
- status: 1,
275
- reason: `Failed to find bb binary at ${pathToBB}`
276
- };
277
- }
278
- try {
279
- if (!await filePresent(vkPath) || !await filePresent(proofPath)) {
280
- return {
281
- status: 1,
282
- reason: `Client IVC input files not present in ${workingDirectory}`
283
- };
284
- }
285
- const args = [
286
- '-o',
287
- outputPath,
288
- '-v'
289
- ];
290
- const timer = new Timer();
291
- const logFunction = (message)=>{
292
- log(`TubeCircuit (prove) BB out - ${message}`);
293
- };
294
- const result = await executeBB(pathToBB, 'prove_tube', args, logFunction);
295
- const durationMs = timer.ms();
296
- if (result.status == 0) {
297
- return {
298
- status: 0,
299
- durationMs,
300
- proofPath: outputPath,
301
- pkPath: undefined,
302
- vkPath: outputPath
261
+ vkDirectoryPath: `${outputPath}`
303
262
  };
304
263
  }
305
264
  // Not a great error message here but it is difficult to decipher what comes from bb
@@ -321,13 +280,14 @@ function getArgs(flavor) {
321
280
  * @param pathToBB - The full path to the bb binary
322
281
  * @param workingDirectory - A working directory for use by bb
323
282
  * @param input - The inputs for the public function to be proven
324
- * @param log - A logging function
283
+ * @param logger - A logging function
284
+ * @param checkCircuitOnly - A boolean to toggle a "check-circuit only" operation instead of proving.
325
285
  * @returns An object containing a result indication, the location of the proof and the duration taken
326
- */ export async function generateAvmProofV2(pathToBB, workingDirectory, input, logger) {
286
+ */ export async function generateAvmProof(pathToBB, workingDirectory, input, logger, checkCircuitOnly = false) {
327
287
  // Check that the working directory exists
328
288
  try {
329
289
  await fs.access(workingDirectory);
330
- } catch (error) {
290
+ } catch {
331
291
  return {
332
292
  status: 1,
333
293
  reason: `Working directory ${workingDirectory} does not exist`
@@ -354,7 +314,10 @@ function getArgs(flavor) {
354
314
  reason: `Could not write avm inputs to ${avmInputsPath}`
355
315
  };
356
316
  }
357
- const args = [
317
+ const args = checkCircuitOnly ? [
318
+ '--avm-inputs',
319
+ avmInputsPath
320
+ ] : [
358
321
  '--avm-inputs',
359
322
  avmInputsPath,
360
323
  '-o',
@@ -365,93 +328,11 @@ function getArgs(flavor) {
365
328
  args.push(loggingArg);
366
329
  }
367
330
  const timer = new Timer();
368
- const logFunction = (message)=>{
369
- logger.verbose(`AvmCircuit (prove) BB out - ${message}`);
370
- };
371
- const result = await executeBB(pathToBB, 'avm2_prove', args, logFunction);
372
- const duration = timer.ms();
373
- if (result.status == 0) {
374
- return {
375
- status: 0,
376
- durationMs: duration,
377
- proofPath: join(outputPath, PROOF_FILENAME),
378
- pkPath: undefined,
379
- vkPath: outputPath
380
- };
381
- }
382
- // Not a great error message here but it is difficult to decipher what comes from bb
383
- return {
384
- status: 1,
385
- reason: `Failed to generate proof. Exit code ${result.exitCode}. Signal ${result.signal}.`,
386
- retry: !!result.signal
387
- };
388
- } catch (error) {
389
- return {
390
- status: 1,
391
- reason: `${error}`
392
- };
393
- }
394
- }
395
- /**
396
- * Used for generating AVM proofs (or doing check-circuit).
397
- * It is assumed that the working directory is a temporary and/or random directory used solely for generating this proof.
398
- * @param pathToBB - The full path to the bb binary
399
- * @param workingDirectory - A working directory for use by bb
400
- * @param bytecode - The AVM bytecode for the public function to be proven (expected to be decompressed)
401
- * @param log - A logging function
402
- * @returns An object containing a result indication, the location of the proof and the duration taken
403
- */ export async function generateAvmProof(pathToBB, workingDirectory, _input, logger, checkCircuitOnly = false) {
404
- // Check that the working directory exists
405
- try {
406
- await fs.access(workingDirectory);
407
- } catch (error) {
408
- return {
409
- status: 1,
410
- reason: `Working directory ${workingDirectory} does not exist`
411
- };
412
- }
413
- // Paths for the inputs
414
- const publicInputsPath = join(workingDirectory, AVM_PUBLIC_INPUTS_FILENAME);
415
- const avmHintsPath = join(workingDirectory, AVM_HINTS_FILENAME);
416
- // The proof is written to e.g. /workingDirectory/proof
417
- const outputPath = workingDirectory;
418
- const filePresent = async (file)=>await fs.access(file, fs.constants.R_OK).then((_)=>true).catch((_)=>false);
419
- const binaryPresent = await filePresent(pathToBB);
420
- if (!binaryPresent) {
421
- return {
422
- status: 1,
423
- reason: `Failed to find bb binary at ${pathToBB}`
424
- };
425
- }
426
- try {
427
- // Write the inputs to the working directory.
428
- // WARNING: Not writing the inputs since VM1 is disabled!
429
- // await fs.writeFile(publicInputsPath, input.publicInputs.toBuffer());
430
- // if (!(await filePresent(publicInputsPath))) {
431
- // return { status: BB_RESULT.FAILURE, reason: `Could not write publicInputs at ${publicInputsPath}` };
432
- // }
433
- // await fs.writeFile(avmHintsPath, input.avmHints.toBuffer());
434
- // if (!(await filePresent(avmHintsPath))) {
435
- // return { status: BB_RESULT.FAILURE, reason: `Could not write avmHints at ${avmHintsPath}` };
436
- // }
437
- const args = [
438
- '--avm-public-inputs',
439
- publicInputsPath,
440
- '--avm-hints',
441
- avmHintsPath,
442
- '-o',
443
- outputPath
444
- ];
445
- const loggingArg = logger.level === 'debug' || logger.level === 'trace' ? '-d' : logger.level === 'verbose' ? '-v' : '';
446
- if (loggingArg !== '') {
447
- args.push(loggingArg);
448
- }
449
- const timer = new Timer();
450
- const cmd = checkCircuitOnly ? 'check_circuit' : 'prove';
331
+ const cmd = checkCircuitOnly ? 'avm_check_circuit' : 'avm_prove';
451
332
  const logFunction = (message)=>{
452
333
  logger.verbose(`AvmCircuit (${cmd}) BB out - ${message}`);
453
334
  };
454
- const result = await executeBB(pathToBB, `avm_${cmd}`, args, logFunction);
335
+ const result = await executeBB(pathToBB, cmd, args, logFunction);
455
336
  const duration = timer.ms();
456
337
  if (result.status == 0) {
457
338
  return {
@@ -459,14 +340,14 @@ function getArgs(flavor) {
459
340
  durationMs: duration,
460
341
  proofPath: join(outputPath, PROOF_FILENAME),
461
342
  pkPath: undefined,
462
- vkPath: outputPath
343
+ vkDirectoryPath: outputPath
463
344
  };
464
345
  }
465
346
  // Not a great error message here but it is difficult to decipher what comes from bb
466
347
  return {
467
348
  status: 1,
468
- reason: `Failed to generate proof. Exit code ${result.exitCode}. Signal ${result.signal}.`,
469
- retry: !!result.signal
349
+ reason: `Failed to generate proof. AVM proof for TX hash ${input.hints.tx.hash}. Exit code ${result.exitCode}. Signal ${result.signal}.`,
350
+ retry: result.signal === 'SIGKILL'
470
351
  };
471
352
  } catch (error) {
472
353
  return {
@@ -485,17 +366,7 @@ function getArgs(flavor) {
485
366
  */ export async function verifyProof(pathToBB, proofFullPath, verificationKeyPath, ultraHonkFlavor, log) {
486
367
  return await verifyProofInternal(pathToBB, proofFullPath, verificationKeyPath, `verify`, log, getArgs(ultraHonkFlavor));
487
368
  }
488
- /**
489
- * Used for verifying proofs of the AVM
490
- * @param pathToBB - The full path to the bb binary
491
- * @param proofFullPath - The full path to the proof to be verified
492
- * @param verificationKeyPath - The full path to the circuit verification key
493
- * @param log - A logging function
494
- * @returns An object containing a result indication and duration taken
495
- */ export async function verifyAvmProof(pathToBB, proofFullPath, verificationKeyPath, logger) {
496
- return await verifyProofInternal(pathToBB, proofFullPath, verificationKeyPath, 'avm_verify', logger);
497
- }
498
- export async function verifyAvmProofV2(pathToBB, workingDirectory, proofFullPath, publicInputs, verificationKeyPath, logger) {
369
+ export async function verifyAvmProof(pathToBB, workingDirectory, proofFullPath, publicInputs, verificationKeyPath, logger) {
499
370
  const inputsBuffer = publicInputs.serializeWithMessagePack();
500
371
  // Write the inputs to the working directory.
501
372
  const filePresent = async (file)=>await fs.access(file, fs.constants.R_OK).then((_)=>true).catch((_)=>false);
@@ -507,19 +378,20 @@ export async function verifyAvmProofV2(pathToBB, workingDirectory, proofFullPath
507
378
  reason: `Could not write avm inputs to ${avmInputsPath}`
508
379
  };
509
380
  }
510
- return await verifyProofInternal(pathToBB, proofFullPath, verificationKeyPath, 'avm2_verify', logger, [
381
+ return await verifyProofInternal(pathToBB, proofFullPath, verificationKeyPath, 'avm_verify', logger, [
511
382
  '--avm-public-inputs',
512
383
  avmInputsPath
513
384
  ]);
514
385
  }
515
386
  /**
516
- * Verifies a ClientIvcProof
387
+ * Verifies a ChonkProof
517
388
  * TODO(#7370) The verification keys should be supplied separately
518
389
  * @param pathToBB - The full path to the bb binary
519
390
  * @param targetPath - The path to the folder with the proof, accumulator, and verification keys
520
391
  * @param log - A logging function
392
+ * @param concurrency - The number of threads to use for the verification
521
393
  * @returns An object containing a result indication and duration taken
522
- */ export async function verifyClientIvcProof(pathToBB, proofPath, keyPath, log) {
394
+ */ export async function verifyChonkProof(pathToBB, proofPath, keyPath, log, concurrency = 1) {
523
395
  const binaryPresent = await fs.access(pathToBB, fs.constants.R_OK).then((_)=>true).catch((_)=>false);
524
396
  if (!binaryPresent) {
525
397
  return {
@@ -530,15 +402,16 @@ export async function verifyAvmProofV2(pathToBB, workingDirectory, proofFullPath
530
402
  try {
531
403
  const args = [
532
404
  '--scheme',
533
- 'client_ivc',
405
+ 'chonk',
534
406
  '-p',
535
407
  proofPath,
536
408
  '-k',
537
- keyPath
409
+ keyPath,
410
+ '-v'
538
411
  ];
539
412
  const timer = new Timer();
540
413
  const command = 'verify';
541
- const result = await executeBB(pathToBB, command, args, log);
414
+ const result = await executeBB(pathToBB, command, args, log, concurrency);
542
415
  const duration = timer.ms();
543
416
  if (result.status == 0) {
544
417
  return {
@@ -579,13 +452,32 @@ export async function verifyAvmProofV2(pathToBB, workingDirectory, proofFullPath
579
452
  logger.verbose(`bb-prover (verify) BB out - ${message}`);
580
453
  };
581
454
  try {
582
- const args = [
583
- '-p',
584
- proofFullPath,
585
- '-k',
586
- verificationKeyPath,
587
- ...extraArgs
588
- ];
455
+ let args;
456
+ if (command == 'verify') {
457
+ // Specify the public inputs path in the case of UH verification.
458
+ // Take proofFullPath and remove the suffix past the / to get the directory.
459
+ const proofDir = proofFullPath.substring(0, proofFullPath.lastIndexOf('/'));
460
+ const publicInputsFullPath = join(proofDir, '/public_inputs');
461
+ logger.debug(`public inputs path: ${publicInputsFullPath}`);
462
+ args = [
463
+ '-p',
464
+ proofFullPath,
465
+ '-k',
466
+ verificationKeyPath,
467
+ '-i',
468
+ publicInputsFullPath,
469
+ '--disable_zk',
470
+ ...extraArgs
471
+ ];
472
+ } else {
473
+ args = [
474
+ '-p',
475
+ proofFullPath,
476
+ '-k',
477
+ verificationKeyPath,
478
+ ...extraArgs
479
+ ];
480
+ }
589
481
  const loggingArg = logger.level === 'debug' || logger.level === 'trace' ? '-d' : logger.level === 'verbose' ? '-v' : '';
590
482
  if (loggingArg !== '') {
591
483
  args.push(loggingArg);
@@ -685,13 +577,13 @@ export async function generateContractForVerificationKey(pathToBB, vkFilePath, c
685
577
  // Check that the working directory exists
686
578
  try {
687
579
  await fs.access(workingDirectory);
688
- } catch (error) {
580
+ } catch {
689
581
  return {
690
582
  status: 1,
691
583
  reason: `Working directory ${workingDirectory} does not exist`
692
584
  };
693
585
  }
694
- // The bytecode is written to e.g. /workingDirectory/BaseParityArtifact-bytecode
586
+ // The bytecode is written to e.g. /workingDirectory/ParityBaseArtifact-bytecode
695
587
  const bytecodePath = `${workingDirectory}/${circuitName}-bytecode`;
696
588
  const binaryPresent = await fs.access(pathToBB, fs.constants.R_OK).then((_)=>true).catch((_)=>false);
697
589
  if (!binaryPresent) {
@@ -712,7 +604,7 @@ export async function generateContractForVerificationKey(pathToBB, vkFilePath, c
712
604
  const timer = new Timer();
713
605
  const result = await executeBB(pathToBB, 'gates', [
714
606
  '--scheme',
715
- flavor === 'mega_honk' ? 'client_ivc' : 'ultra_honk',
607
+ flavor === 'mega_honk' ? 'chonk' : 'ultra_honk',
716
608
  '-b',
717
609
  bytecodePath,
718
610
  '-v'
@@ -772,7 +664,7 @@ async function fsCache(dir, expectedCacheKey, logger, force, action) {
772
664
  }
773
665
  try {
774
666
  await fs.writeFile(cacheFilePath, expectedCacheKey);
775
- } catch (err) {
667
+ } catch {
776
668
  logger(`Couldn't write cache data to ${cacheFilePath}. Skipping cache...`);
777
669
  // ignore
778
670
  }
package/dest/config.d.ts CHANGED
@@ -3,6 +3,8 @@ export interface BBConfig {
3
3
  bbWorkingDirectory: string;
4
4
  /** Whether to skip tmp dir cleanup for debugging purposes */
5
5
  bbSkipCleanup: boolean;
6
+ numConcurrentIVCVerifiers: number;
7
+ bbIVCConcurrency: number;
6
8
  }
7
9
  export interface ACVMConfig {
8
10
  /** The path to the ACVM binary */
@@ -1 +1 @@
1
- {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,QAAQ;IACvB,YAAY,EAAE,MAAM,CAAC;IACrB,kBAAkB,EAAE,MAAM,CAAC;IAC3B,6DAA6D;IAC7D,aAAa,EAAE,OAAO,CAAC;CACxB;AAED,MAAM,WAAW,UAAU;IACzB,kCAAkC;IAClC,cAAc,EAAE,MAAM,CAAC;IACvB,0DAA0D;IAC1D,oBAAoB,EAAE,MAAM,CAAC;CAC9B"}
1
+ {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,QAAQ;IACvB,YAAY,EAAE,MAAM,CAAC;IACrB,kBAAkB,EAAE,MAAM,CAAC;IAC3B,6DAA6D;IAC7D,aAAa,EAAE,OAAO,CAAC;IACvB,yBAAyB,EAAE,MAAM,CAAC;IAClC,gBAAgB,EAAE,MAAM,CAAC;CAC1B;AAED,MAAM,WAAW,UAAU;IACzB,kCAAkC;IAClC,cAAc,EAAE,MAAM,CAAC;IACvB,0DAA0D;IAC1D,oBAAoB,EAAE,MAAM,CAAC;CAC9B"}
package/dest/honk.d.ts CHANGED
@@ -1,7 +1,7 @@
1
1
  import type { ServerProtocolArtifact } from '@aztec/noir-protocol-circuits-types/server';
2
- export type UltraHonkFlavor = 'ultra_honk' | 'ultra_keccak_honk' | 'ultra_rollup_honk';
2
+ export type UltraHonkFlavor = 'ultra_honk' | 'ultra_keccak_honk' | 'ultra_starknet_honk' | 'ultra_rollup_honk';
3
3
  declare const UltraKeccakHonkCircuits: ["RootRollupArtifact"];
4
- declare const UltraHonkCircuits: ["BaseParityArtifact", "RootParityArtifact"];
4
+ declare const UltraHonkCircuits: ["ParityBaseArtifact", "ParityRootArtifact"];
5
5
  export type UltraKeccakHonkServerProtocolArtifact = (typeof UltraKeccakHonkCircuits)[number];
6
6
  export type UltraHonkServerProtocolArtifact = (typeof UltraHonkCircuits)[number];
7
7
  export type UltraRollupHonkServerProtocolArtifact = Exclude<Exclude<ServerProtocolArtifact, UltraKeccakHonkServerProtocolArtifact>, UltraHonkServerProtocolArtifact>;
@@ -1 +1 @@
1
- {"version":3,"file":"honk.d.ts","sourceRoot":"","sources":["../src/honk.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,4CAA4C,CAAC;AAEzF,MAAM,MAAM,eAAe,GAAG,YAAY,GAAG,mBAAmB,GAAG,mBAAmB,CAAC;AAEvF,QAAA,MAAM,uBAAuB,wBAAqE,CAAC;AACnG,QAAA,MAAM,iBAAiB,8CAA2F,CAAC;AAEnH,MAAM,MAAM,qCAAqC,GAAG,CAAC,OAAO,uBAAuB,CAAC,CAAC,MAAM,CAAC,CAAC;AAC7F,MAAM,MAAM,+BAA+B,GAAG,CAAC,OAAO,iBAAiB,CAAC,CAAC,MAAM,CAAC,CAAC;AACjF,MAAM,MAAM,qCAAqC,GAAG,OAAO,CACzD,OAAO,CAAC,sBAAsB,EAAE,qCAAqC,CAAC,EACtE,+BAA+B,CAChC,CAAC;AAEF,wBAAgB,4BAA4B,CAAC,QAAQ,EAAE,qCAAqC,GAAG,mBAAmB,CAAC;AACnH,wBAAgB,4BAA4B,CAAC,QAAQ,EAAE,+BAA+B,GAAG,YAAY,CAAC;AACtG,wBAAgB,4BAA4B,CAAC,QAAQ,EAAE,qCAAqC,GAAG,mBAAmB,CAAC;AACnH,wBAAgB,4BAA4B,CAAC,QAAQ,EAAE,sBAAsB,GAAG,eAAe,CAAC"}
1
+ {"version":3,"file":"honk.d.ts","sourceRoot":"","sources":["../src/honk.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,4CAA4C,CAAC;AAEzF,MAAM,MAAM,eAAe,GAAG,YAAY,GAAG,mBAAmB,GAAG,qBAAqB,GAAG,mBAAmB,CAAC;AAE/G,QAAA,MAAM,uBAAuB,wBAAqE,CAAC;AACnG,QAAA,MAAM,iBAAiB,8CAA2F,CAAC;AAEnH,MAAM,MAAM,qCAAqC,GAAG,CAAC,OAAO,uBAAuB,CAAC,CAAC,MAAM,CAAC,CAAC;AAC7F,MAAM,MAAM,+BAA+B,GAAG,CAAC,OAAO,iBAAiB,CAAC,CAAC,MAAM,CAAC,CAAC;AACjF,MAAM,MAAM,qCAAqC,GAAG,OAAO,CACzD,OAAO,CAAC,sBAAsB,EAAE,qCAAqC,CAAC,EACtE,+BAA+B,CAChC,CAAC;AAEF,wBAAgB,4BAA4B,CAAC,QAAQ,EAAE,qCAAqC,GAAG,mBAAmB,CAAC;AACnH,wBAAgB,4BAA4B,CAAC,QAAQ,EAAE,+BAA+B,GAAG,YAAY,CAAC;AACtG,wBAAgB,4BAA4B,CAAC,QAAQ,EAAE,qCAAqC,GAAG,mBAAmB,CAAC;AACnH,wBAAgB,4BAA4B,CAAC,QAAQ,EAAE,sBAAsB,GAAG,eAAe,CAAC"}
package/dest/honk.js CHANGED
@@ -2,10 +2,11 @@ const UltraKeccakHonkCircuits = [
2
2
  'RootRollupArtifact'
3
3
  ];
4
4
  const UltraHonkCircuits = [
5
- 'BaseParityArtifact',
6
- 'RootParityArtifact'
5
+ 'ParityBaseArtifact',
6
+ 'ParityRootArtifact'
7
7
  ];
8
8
  export function getUltraHonkFlavorForCircuit(artifact) {
9
+ // STARKNET: how to allow for the distinction between keccak/starknet? ultra_keccak_honk is returned in both cases
9
10
  if (isUltraKeccakHonkCircuit(artifact)) {
10
11
  return 'ultra_keccak_honk';
11
12
  } else if (UltraHonkCircuits.includes(artifact)) {
package/dest/index.d.ts CHANGED
@@ -4,5 +4,6 @@ export * from './verifier/index.js';
4
4
  export * from './config.js';
5
5
  export * from './bb/execute.js';
6
6
  export * from './honk.js';
7
+ export * from './verification_key/verification_key_data.js';
7
8
  export { type ClientProtocolCircuitVerifier } from '@aztec/stdlib/interfaces/server';
8
9
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,mBAAmB,CAAC;AAClC,cAAc,iBAAiB,CAAC;AAChC,cAAc,qBAAqB,CAAC;AACpC,cAAc,aAAa,CAAC;AAC5B,cAAc,iBAAiB,CAAC;AAChC,cAAc,WAAW,CAAC;AAE1B,OAAO,EAAE,KAAK,6BAA6B,EAAE,MAAM,iCAAiC,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,mBAAmB,CAAC;AAClC,cAAc,iBAAiB,CAAC;AAChC,cAAc,qBAAqB,CAAC;AACpC,cAAc,aAAa,CAAC;AAC5B,cAAc,iBAAiB,CAAC;AAChC,cAAc,WAAW,CAAC;AAC1B,cAAc,6CAA6C,CAAC;AAE5D,OAAO,EAAE,KAAK,6BAA6B,EAAE,MAAM,iCAAiC,CAAC"}
package/dest/index.js CHANGED
@@ -4,3 +4,4 @@ export * from './verifier/index.js';
4
4
  export * from './config.js';
5
5
  export * from './bb/execute.js';
6
6
  export * from './honk.js';
7
+ export * from './verification_key/verification_key_data.js';
@@ -21,7 +21,7 @@ export declare class ProverInstrumentation {
21
21
  * @param circuitName - The name of the circuit
22
22
  * @param timerOrMS - The duration
23
23
  */
24
- recordDuration(metric: 'simulationDuration' | 'witGenDuration' | 'provingDuration', circuitName: CircuitName | 'tubeCircuit', timerOrMS: Timer | number): void;
24
+ recordDuration(metric: 'simulationDuration' | 'witGenDuration' | 'provingDuration', circuitName: CircuitName, timerOrMS: Timer | number): void;
25
25
  /**
26
26
  * Records the duration of an AVM circuit operation.
27
27
  * @param metric - The metric to record
@@ -35,7 +35,7 @@ export declare class ProverInstrumentation {
35
35
  * @param circuitName - The name of the circuit
36
36
  * @param size - The size
37
37
  */
38
- recordSize(metric: 'witGenInputSize' | 'witGenOutputSize' | 'proofSize' | 'circuitSize' | 'circuitPublicInputCount', circuitName: CircuitName | 'tubeCircuit', size: number): void;
38
+ recordSize(metric: 'witGenInputSize' | 'witGenOutputSize' | 'proofSize' | 'circuitSize' | 'circuitPublicInputCount', circuitName: CircuitName, size: number): void;
39
39
  /**
40
40
  * Records the size of an AVM circuit operation.
41
41
  * @param metric - The metric to record
@@ -1 +1 @@
1
- {"version":3,"file":"instrumentation.d.ts","sourceRoot":"","sources":["../src/instrumentation.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,yBAAyB,CAAC;AACrD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAC;AACvD,OAAO,EAKL,KAAK,eAAe,EACpB,KAAK,MAAM,EAEZ,MAAM,yBAAyB,CAAC;AAEjC;;GAEG;AACH,qBAAa,qBAAqB;IAChC,OAAO,CAAC,kBAAkB,CAAY;IACtC,OAAO,CAAC,cAAc,CAAY;IAClC,OAAO,CAAC,eAAe,CAAY;IAEnC,OAAO,CAAC,eAAe,CAAQ;IAC/B,OAAO,CAAC,gBAAgB,CAAQ;IAEhC,OAAO,CAAC,SAAS,CAAQ;IACzB,OAAO,CAAC,WAAW,CAAQ;IAC3B,OAAO,CAAC,uBAAuB,CAAQ;IAEvC,SAAgB,MAAM,EAAE,MAAM,CAAC;gBAEnB,SAAS,EAAE,eAAe,EAAE,IAAI,EAAE,MAAM;IAmDpD;;;;;OAKG;IACH,cAAc,CACZ,MAAM,EAAE,oBAAoB,GAAG,gBAAgB,GAAG,iBAAiB,EACnE,WAAW,EAAE,WAAW,GAAG,aAAa,EACxC,SAAS,EAAE,KAAK,GAAG,MAAM;IAS3B;;;;;OAKG;IACH,iBAAiB,CAAC,MAAM,EAAE,gBAAgB,GAAG,iBAAiB,EAAE,cAAc,EAAE,MAAM,EAAE,SAAS,EAAE,KAAK,GAAG,MAAM;IAOjH;;;;;OAKG;IACH,UAAU,CACR,MAAM,EAAE,iBAAiB,GAAG,kBAAkB,GAAG,WAAW,GAAG,aAAa,GAAG,yBAAyB,EACxG,WAAW,EAAE,WAAW,GAAG,aAAa,EACxC,IAAI,EAAE,MAAM;IAQd;;;;;OAKG;IACH,aAAa,CACX,MAAM,EAAE,iBAAiB,GAAG,kBAAkB,GAAG,WAAW,GAAG,aAAa,GAAG,yBAAyB,EACxG,cAAc,EAAE,MAAM,EACtB,IAAI,EAAE,MAAM;CAMf"}
1
+ {"version":3,"file":"instrumentation.d.ts","sourceRoot":"","sources":["../src/instrumentation.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,yBAAyB,CAAC;AACrD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAC;AACvD,OAAO,EAKL,KAAK,eAAe,EACpB,KAAK,MAAM,EAEZ,MAAM,yBAAyB,CAAC;AAEjC;;GAEG;AACH,qBAAa,qBAAqB;IAChC,OAAO,CAAC,kBAAkB,CAAY;IACtC,OAAO,CAAC,cAAc,CAAY;IAClC,OAAO,CAAC,eAAe,CAAY;IAEnC,OAAO,CAAC,eAAe,CAAQ;IAC/B,OAAO,CAAC,gBAAgB,CAAQ;IAEhC,OAAO,CAAC,SAAS,CAAQ;IACzB,OAAO,CAAC,WAAW,CAAQ;IAC3B,OAAO,CAAC,uBAAuB,CAAQ;IAEvC,SAAgB,MAAM,EAAE,MAAM,CAAC;gBAEnB,SAAS,EAAE,eAAe,EAAE,IAAI,EAAE,MAAM;IAmDpD;;;;;OAKG;IACH,cAAc,CACZ,MAAM,EAAE,oBAAoB,GAAG,gBAAgB,GAAG,iBAAiB,EACnE,WAAW,EAAE,WAAW,EACxB,SAAS,EAAE,KAAK,GAAG,MAAM;IAQ3B;;;;;OAKG;IACH,iBAAiB,CAAC,MAAM,EAAE,gBAAgB,GAAG,iBAAiB,EAAE,cAAc,EAAE,MAAM,EAAE,SAAS,EAAE,KAAK,GAAG,MAAM;IAOjH;;;;;OAKG;IACH,UAAU,CACR,MAAM,EAAE,iBAAiB,GAAG,kBAAkB,GAAG,WAAW,GAAG,aAAa,GAAG,yBAAyB,EACxG,WAAW,EAAE,WAAW,EACxB,IAAI,EAAE,MAAM;IAOd;;;;;OAKG;IACH,aAAa,CACX,MAAM,EAAE,iBAAiB,GAAG,kBAAkB,GAAG,WAAW,GAAG,aAAa,GAAG,yBAAyB,EACxG,cAAc,EAAE,MAAM,EACtB,IAAI,EAAE,MAAM;CAMf"}