@aztec/bb.js 0.76.4-devnet-test-rc3 → 0.77.0-testnet-ignition.4
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/README.md +10 -2
- package/dest/browser/barretenberg/backend.d.ts +5 -1
- package/dest/browser/barretenberg/backend.d.ts.map +1 -1
- package/dest/browser/barretenberg/index.d.ts +3 -1
- package/dest/browser/barretenberg/index.d.ts.map +1 -1
- package/dest/browser/barretenberg-threads.js +1 -1
- package/dest/browser/barretenberg.js +1 -1
- package/dest/browser/barretenberg_api/index.d.ts +1 -0
- package/dest/browser/barretenberg_api/index.d.ts.map +1 -1
- package/dest/browser/barretenberg_wasm/barretenberg_wasm_base/index.d.ts.map +1 -1
- package/dest/browser/barretenberg_wasm/barretenberg_wasm_main/index.d.ts.map +1 -1
- package/dest/browser/barretenberg_wasm/fetch_code/browser/index.d.ts.map +1 -1
- package/dest/browser/barretenberg_wasm/index.d.ts +2 -2
- package/dest/browser/barretenberg_wasm/index.d.ts.map +1 -1
- package/dest/browser/crs/net_crs.d.ts.map +1 -1
- package/dest/browser/crs/node/index.d.ts +6 -4
- package/dest/browser/crs/node/index.d.ts.map +1 -1
- package/dest/browser/index.js +98 -38
- package/dest/browser/retry/index.d.ts +26 -0
- package/dest/browser/retry/index.d.ts.map +1 -0
- package/dest/node/barretenberg/__snapshots__/pedersen.test.js.snap +156 -0
- package/dest/node/barretenberg/__snapshots__/poseidon.test.js.snap +40 -0
- package/dest/node/barretenberg/backend.d.ts +5 -1
- package/dest/node/barretenberg/backend.d.ts.map +1 -1
- package/dest/node/barretenberg/backend.js +21 -4
- package/dest/node/barretenberg/index.d.ts +3 -1
- package/dest/node/barretenberg/index.d.ts.map +1 -1
- package/dest/node/barretenberg/index.js +11 -12
- package/dest/node/barretenberg_api/index.d.ts +1 -0
- package/dest/node/barretenberg_api/index.d.ts.map +1 -1
- package/dest/node/barretenberg_api/index.js +25 -1
- package/dest/node/barretenberg_wasm/barretenberg-threads.wasm.gz +0 -0
- package/dest/node/barretenberg_wasm/barretenberg_wasm_base/index.d.ts.map +1 -1
- package/dest/node/barretenberg_wasm/barretenberg_wasm_base/index.js +5 -6
- package/dest/node/barretenberg_wasm/barretenberg_wasm_main/index.d.ts.map +1 -1
- package/dest/node/barretenberg_wasm/barretenberg_wasm_main/index.js +6 -7
- package/dest/node/barretenberg_wasm/fetch_code/browser/index.d.ts.map +1 -1
- package/dest/node/barretenberg_wasm/fetch_code/browser/index.js +5 -2
- package/dest/node/barretenberg_wasm/fetch_code/node/index.js +2 -2
- package/dest/node/barretenberg_wasm/index.d.ts +2 -2
- package/dest/node/barretenberg_wasm/index.d.ts.map +1 -1
- package/dest/node/barretenberg_wasm/index.js +11 -9
- package/dest/node/barretenberg_wasm/index.test.js +3 -3
- package/dest/node/crs/net_crs.d.ts.map +1 -1
- package/dest/node/crs/net_crs.js +6 -5
- package/dest/node/crs/node/index.d.ts +6 -4
- package/dest/node/crs/node/index.d.ts.map +1 -1
- package/dest/node/crs/node/index.js +16 -13
- package/dest/node/examples/simple.test.js +2 -2
- package/dest/node/main.d.ts.map +1 -1
- package/dest/node/main.js +55 -65
- package/dest/node/retry/index.d.ts +26 -0
- package/dest/node/retry/index.d.ts.map +1 -0
- package/dest/node/retry/index.js +50 -0
- package/dest/node-cjs/barretenberg/backend.d.ts +5 -1
- package/dest/node-cjs/barretenberg/backend.d.ts.map +1 -1
- package/dest/node-cjs/barretenberg/backend.js +23 -5
- package/dest/node-cjs/barretenberg/index.d.ts +3 -1
- package/dest/node-cjs/barretenberg/index.d.ts.map +1 -1
- package/dest/node-cjs/barretenberg/index.js +11 -12
- package/dest/node-cjs/barretenberg_api/index.d.ts +1 -0
- package/dest/node-cjs/barretenberg_api/index.d.ts.map +1 -1
- package/dest/node-cjs/barretenberg_api/index.js +25 -1
- package/dest/node-cjs/barretenberg_wasm/barretenberg-threads.wasm.gz +0 -0
- package/dest/node-cjs/barretenberg_wasm/barretenberg_wasm_base/index.d.ts.map +1 -1
- package/dest/node-cjs/barretenberg_wasm/barretenberg_wasm_base/index.js +5 -6
- package/dest/node-cjs/barretenberg_wasm/barretenberg_wasm_main/index.d.ts.map +1 -1
- package/dest/node-cjs/barretenberg_wasm/barretenberg_wasm_main/index.js +6 -7
- package/dest/node-cjs/barretenberg_wasm/fetch_code/browser/index.d.ts.map +1 -1
- package/dest/node-cjs/barretenberg_wasm/fetch_code/browser/index.js +5 -2
- package/dest/node-cjs/barretenberg_wasm/fetch_code/node/index.js +2 -2
- package/dest/node-cjs/barretenberg_wasm/index.d.ts +2 -2
- package/dest/node-cjs/barretenberg_wasm/index.d.ts.map +1 -1
- package/dest/node-cjs/barretenberg_wasm/index.js +11 -9
- package/dest/node-cjs/barretenberg_wasm/index.test.js +3 -3
- package/dest/node-cjs/crs/net_crs.d.ts.map +1 -1
- package/dest/node-cjs/crs/net_crs.js +6 -5
- package/dest/node-cjs/crs/node/index.d.ts +6 -4
- package/dest/node-cjs/crs/node/index.d.ts.map +1 -1
- package/dest/node-cjs/crs/node/index.js +16 -13
- package/dest/node-cjs/examples/simple.test.js +2 -2
- package/dest/node-cjs/main.d.ts.map +1 -1
- package/dest/node-cjs/main.js +55 -65
- package/dest/node-cjs/retry/index.d.ts +26 -0
- package/dest/node-cjs/retry/index.d.ts.map +1 -0
- package/dest/node-cjs/retry/index.js +56 -0
- package/package.json +3 -3
- package/src/barretenberg/backend.ts +22 -3
- package/src/barretenberg/index.ts +19 -12
- package/src/barretenberg_api/index.ts +35 -0
- package/src/barretenberg_wasm/barretenberg_wasm_base/index.ts +4 -6
- package/src/barretenberg_wasm/barretenberg_wasm_main/index.ts +5 -7
- package/src/barretenberg_wasm/fetch_code/browser/index.ts +4 -1
- package/src/barretenberg_wasm/fetch_code/node/index.ts +1 -1
- package/src/barretenberg_wasm/index.test.ts +2 -2
- package/src/barretenberg_wasm/index.ts +21 -10
- package/src/crs/net_crs.ts +18 -9
- package/src/crs/node/index.ts +31 -15
- package/src/examples/simple.test.ts +1 -1
- package/src/main.ts +59 -70
- package/src/retry/index.ts +50 -0
package/src/main.ts
CHANGED
|
@@ -22,18 +22,18 @@ const debug = createDebug('bb.js');
|
|
|
22
22
|
const MAX_ULTRAPLONK_CIRCUIT_SIZE_IN_WASM = 2 ** 19;
|
|
23
23
|
const threads = +process.env.HARDWARE_CONCURRENCY! || undefined;
|
|
24
24
|
|
|
25
|
-
function getBytecode(bytecodePath: string) {
|
|
25
|
+
function getBytecode(bytecodePath: string): Uint8Array {
|
|
26
26
|
const extension = bytecodePath.substring(bytecodePath.lastIndexOf('.') + 1);
|
|
27
27
|
|
|
28
28
|
if (extension == 'json') {
|
|
29
29
|
const encodedCircuit = JSON.parse(readFileSync(bytecodePath, 'utf8'));
|
|
30
30
|
const decompressed = gunzipSync(Buffer.from(encodedCircuit.bytecode, 'base64'));
|
|
31
|
-
return decompressed;
|
|
31
|
+
return Uint8Array.from(decompressed);
|
|
32
32
|
}
|
|
33
33
|
|
|
34
34
|
const encodedCircuit = readFileSync(bytecodePath);
|
|
35
35
|
const decompressed = gunzipSync(encodedCircuit);
|
|
36
|
-
return decompressed;
|
|
36
|
+
return Uint8Array.from(decompressed);
|
|
37
37
|
}
|
|
38
38
|
|
|
39
39
|
function base64ToUint8Array(base64: string) {
|
|
@@ -62,14 +62,14 @@ async function getGatesUltra(bytecodePath: string, recursive: boolean, honkRecur
|
|
|
62
62
|
return total;
|
|
63
63
|
}
|
|
64
64
|
|
|
65
|
-
function getWitness(witnessPath: string) {
|
|
65
|
+
function getWitness(witnessPath: string): Uint8Array {
|
|
66
66
|
const data = readFileSync(witnessPath);
|
|
67
67
|
const decompressed = gunzipSync(data);
|
|
68
|
-
return decompressed;
|
|
68
|
+
return Uint8Array.from(decompressed);
|
|
69
69
|
}
|
|
70
70
|
|
|
71
71
|
async function computeCircuitSize(bytecodePath: string, recursive: boolean, honkRecursion: boolean, api: Barretenberg) {
|
|
72
|
-
debug(`
|
|
72
|
+
debug(`Computing circuit size for ${bytecodePath}`);
|
|
73
73
|
const bytecode = getBytecode(bytecodePath);
|
|
74
74
|
const [total, subgroup] = await api.acirGetCircuitSizes(bytecode, recursive, honkRecursion);
|
|
75
75
|
return { total, subgroup };
|
|
@@ -93,9 +93,7 @@ async function initUltraPlonk(
|
|
|
93
93
|
if (subgroupSize > MAX_ULTRAPLONK_CIRCUIT_SIZE_IN_WASM) {
|
|
94
94
|
throw new Error(`Circuit size of ${subgroupSize} exceeds max supported of ${MAX_ULTRAPLONK_CIRCUIT_SIZE_IN_WASM}`);
|
|
95
95
|
}
|
|
96
|
-
debug(`circuit
|
|
97
|
-
debug(`subgroup size: ${subgroupSize}`);
|
|
98
|
-
debug('loading crs...');
|
|
96
|
+
debug(`Loading CRS for UltraPlonk with circuit-size=${circuitSize} subgroup-size=${subgroupSize}`);
|
|
99
97
|
// Plus 1 needed! (Move +1 into Crs?)
|
|
100
98
|
const crs = await Crs.new(subgroupSize + 1, crsPath);
|
|
101
99
|
|
|
@@ -119,9 +117,7 @@ async function initUltraHonk(bytecodePath: string, recursive: boolean, crsPath:
|
|
|
119
117
|
// TODO(https://github.com/AztecProtocol/barretenberg/issues/811): remove subgroupSizeOverride hack for goblin
|
|
120
118
|
const dyadicCircuitSize = Math.pow(2, Math.ceil(Math.log2(circuitSize)));
|
|
121
119
|
|
|
122
|
-
debug(`circuit
|
|
123
|
-
debug(`dyadic circuit size size: ${dyadicCircuitSize}`);
|
|
124
|
-
debug('loading crs...');
|
|
120
|
+
debug(`Loading CRS for UltraHonk with circuit-size=${circuitSize} dyadic-circuit-size=${dyadicCircuitSize}`);
|
|
125
121
|
const crs = await Crs.new(dyadicCircuitSize + 1, crsPath);
|
|
126
122
|
|
|
127
123
|
// Load CRS into wasm global CRS state.
|
|
@@ -133,7 +129,7 @@ async function initUltraHonk(bytecodePath: string, recursive: boolean, crsPath:
|
|
|
133
129
|
async function initClientIVC(crsPath: string) {
|
|
134
130
|
const api = await Barretenberg.new({ threads });
|
|
135
131
|
|
|
136
|
-
debug('
|
|
132
|
+
debug('Loading CRS for ClientIVC');
|
|
137
133
|
const crs = await Crs.new(2 ** 21 + 1, crsPath);
|
|
138
134
|
const grumpkinCrs = await GrumpkinCrs.new(2 ** 16 + 1, crsPath);
|
|
139
135
|
|
|
@@ -163,7 +159,7 @@ export async function proveAndVerify(bytecodePath: string, recursive: boolean, w
|
|
|
163
159
|
|
|
164
160
|
const { api, acirComposer, circuitSize, subgroupSize } = await initUltraPlonk(bytecodePath, recursive, crsPath);
|
|
165
161
|
try {
|
|
166
|
-
debug(`
|
|
162
|
+
debug(`Creating proof bytecode=${bytecodePath} witness=${witnessPath} recursive=${recursive}`);
|
|
167
163
|
const bytecode = getBytecode(bytecodePath);
|
|
168
164
|
const witness = getWitness(witnessPath);
|
|
169
165
|
|
|
@@ -177,9 +173,9 @@ export async function proveAndVerify(bytecodePath: string, recursive: boolean, w
|
|
|
177
173
|
const proof = await api.acirCreateProof(acirComposer, bytecode, recursive, witness);
|
|
178
174
|
writeBenchmark('proof_construction_time', proofTimer.ms(), { acir_test, threads });
|
|
179
175
|
|
|
180
|
-
debug(`
|
|
176
|
+
debug(`Proof complete. Verifying.`);
|
|
181
177
|
const verified = await api.acirVerifyProof(acirComposer, proof);
|
|
182
|
-
debug(`
|
|
178
|
+
debug(`Verification ${verified ? 'successful' : 'failed'}`);
|
|
183
179
|
return verified;
|
|
184
180
|
} finally {
|
|
185
181
|
await api.destroy();
|
|
@@ -235,7 +231,7 @@ export async function proveAndVerifyAztecClient(bytecodePath: string, witnessPat
|
|
|
235
231
|
const witness = readStack(witnessPath);
|
|
236
232
|
|
|
237
233
|
const verified = await api.acirProveAndVerifyAztecClient(bytecode, witness);
|
|
238
|
-
|
|
234
|
+
debug(`Verification ${verified ? 'successful' : 'failed'}`);
|
|
239
235
|
return verified;
|
|
240
236
|
} finally {
|
|
241
237
|
await api.destroy();
|
|
@@ -256,7 +252,7 @@ export async function foldAndVerifyProgram(
|
|
|
256
252
|
const witness = getWitness(witnessPath);
|
|
257
253
|
|
|
258
254
|
const verified = await api.acirFoldAndVerifyProgramStack(bytecode, recursive, witness);
|
|
259
|
-
debug(`
|
|
255
|
+
debug(`Verification ${verified ? 'successful' : 'failed'}`);
|
|
260
256
|
return verified;
|
|
261
257
|
} finally {
|
|
262
258
|
await api.destroy();
|
|
@@ -273,18 +269,17 @@ export async function prove(
|
|
|
273
269
|
) {
|
|
274
270
|
const { api, acirComposer } = await initUltraPlonk(bytecodePath, recursive, crsPath);
|
|
275
271
|
try {
|
|
276
|
-
debug(`
|
|
272
|
+
debug(`Creating proof bytecode=${bytecodePath} witness=${witnessPath} recursive=${recursive}`);
|
|
277
273
|
const bytecode = getBytecode(bytecodePath);
|
|
278
274
|
const witness = getWitness(witnessPath);
|
|
279
275
|
const proof = await api.acirCreateProof(acirComposer, bytecode, recursive, witness);
|
|
280
|
-
debug(`done.`);
|
|
281
276
|
|
|
282
277
|
if (outputPath === '-') {
|
|
283
278
|
process.stdout.write(proof);
|
|
284
|
-
debug(`
|
|
279
|
+
debug(`Proof written to stdout`);
|
|
285
280
|
} else {
|
|
286
281
|
writeFileSync(outputPath, proof);
|
|
287
|
-
debug(`
|
|
282
|
+
debug(`Proof written to ${outputPath}`);
|
|
288
283
|
}
|
|
289
284
|
} finally {
|
|
290
285
|
await api.destroy();
|
|
@@ -295,14 +290,14 @@ export async function gateCountUltra(bytecodePath: string, recursive: boolean, h
|
|
|
295
290
|
const api = await Barretenberg.new({ threads: 1 });
|
|
296
291
|
try {
|
|
297
292
|
const numberOfGates = await getGatesUltra(bytecodePath, recursive, honkRecursion, api);
|
|
298
|
-
debug(`
|
|
293
|
+
debug(`Number of gates: ${numberOfGates}`);
|
|
299
294
|
// Create an 8-byte buffer and write the number into it.
|
|
300
295
|
// Writing number directly to stdout will result in a variable sized
|
|
301
296
|
// input depending on the size.
|
|
302
297
|
const buffer = Buffer.alloc(8);
|
|
303
298
|
buffer.writeBigInt64LE(BigInt(numberOfGates));
|
|
304
299
|
|
|
305
|
-
process.stdout.write(buffer);
|
|
300
|
+
process.stdout.write(Uint8Array.from(buffer));
|
|
306
301
|
} finally {
|
|
307
302
|
await api.destroy();
|
|
308
303
|
}
|
|
@@ -312,8 +307,8 @@ export async function verify(proofPath: string, vkPath: string, crsPath: string)
|
|
|
312
307
|
const { api, acirComposer } = await initLite(crsPath);
|
|
313
308
|
try {
|
|
314
309
|
await api.acirLoadVerificationKey(acirComposer, new RawBuffer(readFileSync(vkPath)));
|
|
315
|
-
const verified = await api.acirVerifyProof(acirComposer, readFileSync(proofPath));
|
|
316
|
-
debug(`
|
|
310
|
+
const verified = await api.acirVerifyProof(acirComposer, Uint8Array.from(readFileSync(proofPath)));
|
|
311
|
+
debug(`Verification ${verified ? 'successful' : 'failed'}`);
|
|
317
312
|
return verified;
|
|
318
313
|
} finally {
|
|
319
314
|
await api.destroy();
|
|
@@ -323,15 +318,16 @@ export async function verify(proofPath: string, vkPath: string, crsPath: string)
|
|
|
323
318
|
export async function contract(outputPath: string, vkPath: string, crsPath: string) {
|
|
324
319
|
const { api, acirComposer } = await initLite(crsPath);
|
|
325
320
|
try {
|
|
321
|
+
debug(`Creating verifier contract vk=${vkPath}`);
|
|
326
322
|
await api.acirLoadVerificationKey(acirComposer, new RawBuffer(readFileSync(vkPath)));
|
|
327
323
|
const contract = await api.acirGetSolidityVerifier(acirComposer);
|
|
328
324
|
|
|
329
325
|
if (outputPath === '-') {
|
|
330
326
|
process.stdout.write(contract);
|
|
331
|
-
debug(`contract written to stdout`);
|
|
327
|
+
debug(`Solidity verifier contract written to stdout`);
|
|
332
328
|
} else {
|
|
333
329
|
writeFileSync(outputPath, contract);
|
|
334
|
-
debug(`contract written to
|
|
330
|
+
debug(`Solidity verifier contract written to ${outputPath}`);
|
|
335
331
|
}
|
|
336
332
|
} finally {
|
|
337
333
|
await api.destroy();
|
|
@@ -341,18 +337,17 @@ export async function contract(outputPath: string, vkPath: string, crsPath: stri
|
|
|
341
337
|
export async function contractUltraHonk(bytecodePath: string, vkPath: string, crsPath: string, outputPath: string) {
|
|
342
338
|
const { api } = await initUltraHonk(bytecodePath, false, crsPath);
|
|
343
339
|
try {
|
|
344
|
-
|
|
340
|
+
debug(`Creating UltraHonk verifier contract bytecode=${bytecodePath} vk=${vkPath}`);
|
|
345
341
|
const bytecode = getBytecode(bytecodePath);
|
|
346
|
-
console.log('vkPath', vkPath);
|
|
347
342
|
const vk = new RawBuffer(readFileSync(vkPath));
|
|
348
343
|
const contract = await api.acirHonkSolidityVerifier(bytecode, vk);
|
|
349
344
|
|
|
350
345
|
if (outputPath === '-') {
|
|
351
346
|
process.stdout.write(contract);
|
|
352
|
-
debug(`contract written to stdout`);
|
|
347
|
+
debug(`Solidity verifier contract written to stdout`);
|
|
353
348
|
} else {
|
|
354
349
|
writeFileSync(outputPath, contract);
|
|
355
|
-
debug(`contract written to
|
|
350
|
+
debug(`Solidity verifier contract written to ${outputPath}`);
|
|
356
351
|
}
|
|
357
352
|
} finally {
|
|
358
353
|
await api.destroy();
|
|
@@ -362,19 +357,19 @@ export async function contractUltraHonk(bytecodePath: string, vkPath: string, cr
|
|
|
362
357
|
export async function writeVk(bytecodePath: string, recursive: boolean, crsPath: string, outputPath: string) {
|
|
363
358
|
const { api, acirComposer } = await initUltraPlonk(bytecodePath, recursive, crsPath);
|
|
364
359
|
try {
|
|
365
|
-
debug(
|
|
360
|
+
debug(`Initializing proving key bytecode=${bytecodePath} recursive=${recursive}`);
|
|
366
361
|
const bytecode = getBytecode(bytecodePath);
|
|
367
362
|
await api.acirInitProvingKey(acirComposer, bytecode, recursive);
|
|
368
363
|
|
|
369
|
-
debug(
|
|
364
|
+
debug(`Initializing verification key`);
|
|
370
365
|
const vk = await api.acirGetVerificationKey(acirComposer);
|
|
371
366
|
|
|
372
367
|
if (outputPath === '-') {
|
|
373
368
|
process.stdout.write(vk);
|
|
374
|
-
debug(`
|
|
369
|
+
debug(`Verification key written to stdout`);
|
|
375
370
|
} else {
|
|
376
371
|
writeFileSync(outputPath, vk);
|
|
377
|
-
debug(`
|
|
372
|
+
debug(`Verification key written to ${outputPath}`);
|
|
378
373
|
}
|
|
379
374
|
} finally {
|
|
380
375
|
await api.destroy();
|
|
@@ -384,16 +379,16 @@ export async function writeVk(bytecodePath: string, recursive: boolean, crsPath:
|
|
|
384
379
|
export async function writePk(bytecodePath: string, recursive: boolean, crsPath: string, outputPath: string) {
|
|
385
380
|
const { api, acirComposer } = await initUltraPlonk(bytecodePath, recursive, crsPath);
|
|
386
381
|
try {
|
|
387
|
-
debug(
|
|
382
|
+
debug(`Initializing proving key bytecode=${bytecodePath} recursive=${recursive}`);
|
|
388
383
|
const bytecode = getBytecode(bytecodePath);
|
|
389
384
|
const pk = await api.acirGetProvingKey(acirComposer, bytecode, recursive);
|
|
390
385
|
|
|
391
386
|
if (outputPath === '-') {
|
|
392
387
|
process.stdout.write(pk);
|
|
393
|
-
debug(`
|
|
388
|
+
debug(`Proving key written to stdout`);
|
|
394
389
|
} else {
|
|
395
390
|
writeFileSync(outputPath, pk);
|
|
396
|
-
debug(`
|
|
391
|
+
debug(`Proving key written to ${outputPath}`);
|
|
397
392
|
}
|
|
398
393
|
} finally {
|
|
399
394
|
await api.destroy();
|
|
@@ -404,24 +399,22 @@ export async function proofAsFields(proofPath: string, vkPath: string, outputPat
|
|
|
404
399
|
const { api, acirComposer } = await initLite(crsPath);
|
|
405
400
|
|
|
406
401
|
try {
|
|
407
|
-
debug(
|
|
402
|
+
debug(`Serializing proof byte array into field elements proof=${proofPath} vk=${vkPath}`);
|
|
408
403
|
const numPublicInputs = readFileSync(vkPath).readUint32BE(8);
|
|
409
404
|
const proofAsFields = await api.acirSerializeProofIntoFields(
|
|
410
405
|
acirComposer,
|
|
411
|
-
readFileSync(proofPath),
|
|
406
|
+
Uint8Array.from(readFileSync(proofPath)),
|
|
412
407
|
numPublicInputs,
|
|
413
408
|
);
|
|
414
409
|
const jsonProofAsFields = JSON.stringify(proofAsFields.map(f => f.toString()));
|
|
415
410
|
|
|
416
411
|
if (outputPath === '-') {
|
|
417
412
|
process.stdout.write(jsonProofAsFields);
|
|
418
|
-
debug(`
|
|
413
|
+
debug(`Proof as fields written to stdout`);
|
|
419
414
|
} else {
|
|
420
415
|
writeFileSync(outputPath, jsonProofAsFields);
|
|
421
|
-
debug(`
|
|
416
|
+
debug(`Proof as fields written to ${outputPath}`);
|
|
422
417
|
}
|
|
423
|
-
|
|
424
|
-
debug('done.');
|
|
425
418
|
} finally {
|
|
426
419
|
await api.destroy();
|
|
427
420
|
}
|
|
@@ -431,7 +424,7 @@ export async function vkAsFields(vkPath: string, vkeyOutputPath: string, crsPath
|
|
|
431
424
|
const { api, acirComposer } = await initLite(crsPath);
|
|
432
425
|
|
|
433
426
|
try {
|
|
434
|
-
debug(
|
|
427
|
+
debug(`Serializing vk byte array into field elements vk=${vkPath}`);
|
|
435
428
|
await api.acirLoadVerificationKey(acirComposer, new RawBuffer(readFileSync(vkPath)));
|
|
436
429
|
const [vkAsFields, vkHash] = await api.acirSerializeVerificationKeyIntoFields(acirComposer);
|
|
437
430
|
const output = [vkHash, ...vkAsFields].map(f => f.toString());
|
|
@@ -439,13 +432,11 @@ export async function vkAsFields(vkPath: string, vkeyOutputPath: string, crsPath
|
|
|
439
432
|
|
|
440
433
|
if (vkeyOutputPath === '-') {
|
|
441
434
|
process.stdout.write(jsonVKAsFields);
|
|
442
|
-
debug(`
|
|
435
|
+
debug(`Verification key as fields written to stdout`);
|
|
443
436
|
} else {
|
|
444
437
|
writeFileSync(vkeyOutputPath, jsonVKAsFields);
|
|
445
|
-
debug(`
|
|
438
|
+
debug(`Verification key as fields written to ${vkeyOutputPath}`);
|
|
446
439
|
}
|
|
447
|
-
|
|
448
|
-
debug('done.');
|
|
449
440
|
} finally {
|
|
450
441
|
await api.destroy();
|
|
451
442
|
}
|
|
@@ -461,7 +452,7 @@ export async function proveUltraHonk(
|
|
|
461
452
|
) {
|
|
462
453
|
const { api } = await initUltraHonk(bytecodePath, recursive, crsPath);
|
|
463
454
|
try {
|
|
464
|
-
debug(`
|
|
455
|
+
debug(`Creating UltraHonk proof bytecode=${bytecodePath} recursive=${recursive}`);
|
|
465
456
|
const bytecode = getBytecode(bytecodePath);
|
|
466
457
|
const witness = getWitness(witnessPath);
|
|
467
458
|
|
|
@@ -469,14 +460,13 @@ export async function proveUltraHonk(
|
|
|
469
460
|
? api.acirProveUltraKeccakHonk.bind(api)
|
|
470
461
|
: api.acirProveUltraHonk.bind(api);
|
|
471
462
|
const proof = await acirProveUltraHonk(bytecode, recursive, witness);
|
|
472
|
-
debug(`done.`);
|
|
473
463
|
|
|
474
464
|
if (outputPath === '-') {
|
|
475
465
|
process.stdout.write(proof);
|
|
476
|
-
debug(`
|
|
466
|
+
debug(`Proof written to stdout`);
|
|
477
467
|
} else {
|
|
478
468
|
writeFileSync(outputPath, proof);
|
|
479
|
-
debug(`
|
|
469
|
+
debug(`Proof written to ${outputPath}`);
|
|
480
470
|
}
|
|
481
471
|
} finally {
|
|
482
472
|
await api.destroy();
|
|
@@ -493,7 +483,7 @@ export async function writeVkUltraHonk(
|
|
|
493
483
|
const { api } = await initUltraHonk(bytecodePath, recursive, crsPath);
|
|
494
484
|
try {
|
|
495
485
|
const bytecode = getBytecode(bytecodePath);
|
|
496
|
-
debug(
|
|
486
|
+
debug(`Initializing UltraHonk verification key bytecode=${bytecodePath} recursive=${recursive}`);
|
|
497
487
|
|
|
498
488
|
const acirWriteVkUltraHonk = options?.keccak
|
|
499
489
|
? api.acirWriteVkUltraKeccakHonk.bind(api)
|
|
@@ -502,10 +492,10 @@ export async function writeVkUltraHonk(
|
|
|
502
492
|
|
|
503
493
|
if (outputPath === '-') {
|
|
504
494
|
process.stdout.write(vk);
|
|
505
|
-
debug(`
|
|
495
|
+
debug(`Verification key written to stdout`);
|
|
506
496
|
} else {
|
|
507
497
|
writeFileSync(outputPath, vk);
|
|
508
|
-
debug(`
|
|
498
|
+
debug(`Verification key written to ${outputPath}`);
|
|
509
499
|
}
|
|
510
500
|
} finally {
|
|
511
501
|
await api.destroy();
|
|
@@ -523,9 +513,12 @@ export async function verifyUltraHonk(
|
|
|
523
513
|
const acirVerifyUltraHonk = options?.keccak
|
|
524
514
|
? api.acirVerifyUltraKeccakHonk.bind(api)
|
|
525
515
|
: api.acirVerifyUltraHonk.bind(api);
|
|
526
|
-
const verified = await acirVerifyUltraHonk(
|
|
516
|
+
const verified = await acirVerifyUltraHonk(
|
|
517
|
+
Uint8Array.from(readFileSync(proofPath)),
|
|
518
|
+
new RawBuffer(readFileSync(vkPath)),
|
|
519
|
+
);
|
|
527
520
|
|
|
528
|
-
debug(`
|
|
521
|
+
debug(`Verification ${verified ? 'successful' : 'failed'}`);
|
|
529
522
|
return verified;
|
|
530
523
|
} finally {
|
|
531
524
|
await api.destroy();
|
|
@@ -535,19 +528,17 @@ export async function verifyUltraHonk(
|
|
|
535
528
|
export async function proofAsFieldsUltraHonk(proofPath: string, outputPath: string, crsPath: string) {
|
|
536
529
|
const { api } = await initLite(crsPath);
|
|
537
530
|
try {
|
|
538
|
-
debug(
|
|
539
|
-
const proofAsFields = await api.acirProofAsFieldsUltraHonk(readFileSync(proofPath));
|
|
531
|
+
debug(`Outputting UltraHonk proof as vector of fields proof=${proofPath}`);
|
|
532
|
+
const proofAsFields = await api.acirProofAsFieldsUltraHonk(Uint8Array.from(readFileSync(proofPath)));
|
|
540
533
|
const jsonProofAsFields = JSON.stringify(proofAsFields.map(f => f.toString()));
|
|
541
534
|
|
|
542
535
|
if (outputPath === '-') {
|
|
543
536
|
process.stdout.write(jsonProofAsFields);
|
|
544
|
-
debug(`
|
|
537
|
+
debug(`Proof as fields written to stdout`);
|
|
545
538
|
} else {
|
|
546
539
|
writeFileSync(outputPath, jsonProofAsFields);
|
|
547
|
-
debug(`
|
|
540
|
+
debug(`Proof as fields written to ${outputPath}`);
|
|
548
541
|
}
|
|
549
|
-
|
|
550
|
-
debug('done.');
|
|
551
542
|
} finally {
|
|
552
543
|
await api.destroy();
|
|
553
544
|
}
|
|
@@ -557,19 +548,17 @@ export async function vkAsFieldsUltraHonk(vkPath: string, vkeyOutputPath: string
|
|
|
557
548
|
const { api } = await initLite(crsPath);
|
|
558
549
|
|
|
559
550
|
try {
|
|
560
|
-
debug(
|
|
551
|
+
debug(`Serializing vk byte array into field elements vk=${vkPath}`);
|
|
561
552
|
const vkAsFields = await api.acirVkAsFieldsUltraHonk(new RawBuffer(readFileSync(vkPath)));
|
|
562
553
|
const jsonVKAsFields = JSON.stringify(vkAsFields.map(f => f.toString()));
|
|
563
554
|
|
|
564
555
|
if (vkeyOutputPath === '-') {
|
|
565
556
|
process.stdout.write(jsonVKAsFields);
|
|
566
|
-
debug(`
|
|
557
|
+
debug(`Verification key as fields written to stdout`);
|
|
567
558
|
} else {
|
|
568
559
|
writeFileSync(vkeyOutputPath, jsonVKAsFields);
|
|
569
|
-
debug(`
|
|
560
|
+
debug(`Verification key as fields written to ${vkeyOutputPath}`);
|
|
570
561
|
}
|
|
571
|
-
|
|
572
|
-
debug('done.');
|
|
573
562
|
} finally {
|
|
574
563
|
await api.destroy();
|
|
575
564
|
}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Generates a backoff sequence for retrying operations with an increasing delay.
|
|
3
|
+
* The backoff sequence follows this pattern: 1, 1, 1, 2, 4, 8, 16, 32, 64, ...
|
|
4
|
+
* This generator can be used in combination with the `retry` function to perform
|
|
5
|
+
* retries with exponential backoff and capped at 64 seconds between attempts.
|
|
6
|
+
*
|
|
7
|
+
* @returns A generator that yields the next backoff value in seconds as an integer.
|
|
8
|
+
*/
|
|
9
|
+
export function* backoffGenerator() {
|
|
10
|
+
const v = [1, 1, 1, 2, 4, 8, 16, 32, 64];
|
|
11
|
+
let i = 0;
|
|
12
|
+
while (true) {
|
|
13
|
+
yield v[Math.min(i++, v.length - 1)];
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* Generates a backoff sequence based on the array of retry intervals to use with the `retry` function.
|
|
19
|
+
* @param retries - Intervals to retry (in seconds).
|
|
20
|
+
* @returns A generator sequence.
|
|
21
|
+
*/
|
|
22
|
+
export function* makeBackoff(retries: number[]) {
|
|
23
|
+
for (const retry of retries) {
|
|
24
|
+
yield retry;
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* Retry a given asynchronous function with a specific backoff strategy, until it succeeds or backoff generator ends.
|
|
30
|
+
* It logs the error and retry interval in case an error is caught. The function can be named for better log output.
|
|
31
|
+
*
|
|
32
|
+
* @param fn - The asynchronous function to be retried.
|
|
33
|
+
* @param backoff - The optional backoff generator providing the intervals in seconds between retries. Defaults to a predefined series.
|
|
34
|
+
* @returns A Promise that resolves with the successful result of the provided function, or rejects if backoff generator ends.
|
|
35
|
+
* @throws If `NoRetryError` is thrown by the `fn`, it is rethrown.
|
|
36
|
+
*/
|
|
37
|
+
export async function retry<Result>(fn: () => Promise<Result>, backoff = backoffGenerator()) {
|
|
38
|
+
while (true) {
|
|
39
|
+
try {
|
|
40
|
+
return await fn();
|
|
41
|
+
} catch (err: any) {
|
|
42
|
+
const s = backoff.next().value;
|
|
43
|
+
if (s === undefined) {
|
|
44
|
+
throw err;
|
|
45
|
+
}
|
|
46
|
+
await new Promise(resolve => setTimeout(resolve, s * 1000));
|
|
47
|
+
continue;
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
}
|