@aztec/bb.js 0.0.1-alpha.0 → 0.0.1-alpha.2

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/src/main.ts CHANGED
@@ -1,16 +1,13 @@
1
1
  #!/usr/bin/env -S node --no-warnings
2
- import { Crs } from './crs/index.js';
2
+ import { Crs, BarretenbergApiAsync, newBarretenbergApiAsync, RawBuffer } from './index.js';
3
3
  import createDebug from 'debug';
4
- import { BarretenbergApiAsync, newBarretenbergApiAsync } from './factory/index.js';
5
4
  import { readFileSync, writeFileSync } from 'fs';
6
5
  import { gunzipSync } from 'zlib';
7
- import { RawBuffer } from './types/index.js';
8
6
  import { numToUInt32BE } from './serialize/serialize.js';
9
7
  import { Command } from 'commander';
10
8
 
11
9
  createDebug.log = console.error.bind(console);
12
10
  const debug = createDebug('bb.js');
13
- // createDebug.enable('*');
14
11
 
15
12
  // Maximum we support.
16
13
  const MAX_CIRCUIT_SIZE = 2 ** 19;
@@ -34,29 +31,41 @@ async function getCircuitSize(jsonPath: string, api: BarretenbergApiAsync) {
34
31
  return { exact, total, subgroup };
35
32
  }
36
33
 
37
- async function init(jsonPath: string) {
34
+ async function init(jsonPath: string, sizeHint?: number) {
38
35
  const api = await newBarretenbergApiAsync();
39
36
 
40
- // First compute circuit size.
41
- const circuitSizes = await getCircuitSize(jsonPath, api);
42
- debug(`circuit size: ${circuitSizes.total}`);
37
+ const subgroupSize = await (async () => {
38
+ if (sizeHint) {
39
+ // Round to subgroup size.
40
+ return Math.pow(2, Math.ceil(Math.log2(sizeHint)));
41
+ }
43
42
 
44
- if (circuitSizes.subgroup > MAX_CIRCUIT_SIZE) {
45
- throw new Error(`Circuit size of ${circuitSizes.subgroup} exceeds max supported of ${MAX_CIRCUIT_SIZE}`);
46
- }
43
+ // First compute circuit size.
44
+ debug(`computing circuit size (use size hint to skip)...`);
45
+ const circuitSizes = await getCircuitSize(jsonPath, api);
46
+ debug(`circuit size: ${circuitSizes.total}`);
47
+
48
+ if (circuitSizes.subgroup > MAX_CIRCUIT_SIZE) {
49
+ throw new Error(`Circuit size of ${circuitSizes.subgroup} exceeds max supported of ${MAX_CIRCUIT_SIZE}`);
50
+ }
47
51
 
52
+ return circuitSizes.subgroup;
53
+ })();
54
+
55
+ debug(`subgroup size: ${subgroupSize}`);
56
+ debug('loading crs...');
48
57
  // Plus 1 needed! (Move +1 into Crs?)
49
- const crs = await Crs.new(circuitSizes.subgroup + 1);
58
+ const crs = await Crs.new(subgroupSize + 1);
50
59
 
51
60
  // Important to init slab allocator as first thing, to ensure maximum memory efficiency.
52
- await api.commonInitSlabAllocator(circuitSizes.subgroup);
61
+ await api.commonInitSlabAllocator(subgroupSize);
53
62
 
54
63
  // Load CRS into wasm global CRS state.
55
64
  // TODO: Make RawBuffer be default behaviour, and have a specific Vector type for when wanting length prefixed.
56
65
  await api.srsInitSrs(new RawBuffer(crs.getG1Data()), crs.numPoints, new RawBuffer(crs.getG2Data()));
57
66
 
58
67
  const acirComposer = await api.acirNewAcirComposer();
59
- return { api, acirComposer, circuitSize: circuitSizes.subgroup };
68
+ return { api, acirComposer, circuitSize: subgroupSize };
60
69
  }
61
70
 
62
71
  async function initLite() {
@@ -72,24 +81,24 @@ async function initLite() {
72
81
  return { api, acirComposer };
73
82
  }
74
83
 
75
- export async function proveAndVerify(jsonPath: string, witnessPath: string, isRecursive: boolean) {
76
- const { api, acirComposer, circuitSize } = await init(jsonPath);
84
+ export async function proveAndVerify(jsonPath: string, witnessPath: string, isRecursive: boolean, sizeHint?: number) {
85
+ const { api, acirComposer } = await init(jsonPath, sizeHint);
77
86
  try {
78
- debug('initing proving key...');
87
+ // debug('initing proving key...');
79
88
  const bytecode = getBytecode(jsonPath);
80
- await api.acirInitProvingKey(acirComposer, new RawBuffer(bytecode), circuitSize);
89
+ // await api.acirInitProvingKey(acirComposer, new RawBuffer(bytecode), circuitSize);
81
90
 
82
91
  // const circuitSize = await api.acirGetExactCircuitSize(acirComposer);
83
92
  // debug(`circuit size: ${circuitSize}`);
84
93
 
85
- debug('initing verification key...');
86
- await api.acirInitVerificationKey(acirComposer);
94
+ // debug('initing verification key...');
95
+ // await api.acirInitVerificationKey(acirComposer);
87
96
 
88
97
  debug(`creating proof...`);
89
98
  const witness = getWitness(witnessPath);
90
99
  const proof = await api.acirCreateProof(acirComposer, new RawBuffer(bytecode), new RawBuffer(witness), isRecursive);
91
- debug(`done.`);
92
100
 
101
+ debug(`verifying...`);
93
102
  const verified = await api.acirVerifyProof(acirComposer, proof, isRecursive);
94
103
  console.log(`verified: ${verified}`);
95
104
  return verified;
@@ -98,12 +107,18 @@ export async function proveAndVerify(jsonPath: string, witnessPath: string, isRe
98
107
  }
99
108
  }
100
109
 
101
- export async function prove(jsonPath: string, witnessPath: string, isRecursive: boolean, outputPath: string) {
102
- const { api, acirComposer, circuitSize } = await init(jsonPath);
110
+ export async function prove(
111
+ jsonPath: string,
112
+ witnessPath: string,
113
+ isRecursive: boolean,
114
+ outputPath: string,
115
+ sizeHint?: number,
116
+ ) {
117
+ const { api, acirComposer } = await init(jsonPath, sizeHint);
103
118
  try {
104
- debug('initing proving key...');
119
+ // debug('initing proving key...');
105
120
  const bytecode = getBytecode(jsonPath);
106
- await api.acirInitProvingKey(acirComposer, new RawBuffer(bytecode), circuitSize);
121
+ // await api.acirInitProvingKey(acirComposer, new RawBuffer(bytecode), circuitSize);
107
122
 
108
123
  // const circuitSize = await api.acirGetExactCircuitSize(acirComposer);
109
124
  // debug(`circuit size: ${circuitSize}`);
@@ -130,46 +145,22 @@ export async function gateCount(jsonPath: string) {
130
145
  }
131
146
  }
132
147
 
133
- export async function verify(jsonPath: string, proofPath: string, isRecursive: boolean, vkPath?: string) {
134
- if (vkPath) {
135
- const { api, acirComposer } = await initLite();
136
- try {
137
- await api.acirLoadVerificationKey(acirComposer, new RawBuffer(readFileSync(vkPath)));
138
- const verified = await api.acirVerifyProof(acirComposer, readFileSync(proofPath), isRecursive);
139
- console.log(`verified: ${verified}`);
140
- return verified;
141
- } finally {
142
- await api.destroy();
143
- }
144
- } else {
145
- const { api, acirComposer, circuitSize } = await init(jsonPath);
146
- try {
147
- debug('initing proving key...');
148
- const bytecode = getBytecode(jsonPath);
149
- await api.acirInitProvingKey(acirComposer, new RawBuffer(bytecode), circuitSize);
150
-
151
- debug('initing verification key...');
152
- await api.acirInitVerificationKey(acirComposer);
153
-
154
- const verified = await api.acirVerifyProof(acirComposer, readFileSync(proofPath), isRecursive);
155
- console.log(`verified: ${verified}`);
156
- return verified;
157
- } finally {
158
- await api.destroy();
159
- }
148
+ export async function verify(jsonPath: string, proofPath: string, isRecursive: boolean, vkPath: string) {
149
+ const { api, acirComposer } = await initLite();
150
+ try {
151
+ await api.acirLoadVerificationKey(acirComposer, new RawBuffer(readFileSync(vkPath)));
152
+ const verified = await api.acirVerifyProof(acirComposer, readFileSync(proofPath), isRecursive);
153
+ console.log(`verified: ${verified}`);
154
+ return verified;
155
+ } finally {
156
+ await api.destroy();
160
157
  }
161
158
  }
162
159
 
163
- export async function contract(jsonPath: string, outputPath: string) {
164
- const { api, acirComposer, circuitSize } = await init(jsonPath);
160
+ export async function contract(outputPath: string, vkPath: string) {
161
+ const { api, acirComposer } = await initLite();
165
162
  try {
166
- debug('initing proving key...');
167
- const bytecode = getBytecode(jsonPath);
168
- await api.acirInitProvingKey(acirComposer, new RawBuffer(bytecode), circuitSize);
169
-
170
- debug('initing verification key...');
171
- await api.acirInitVerificationKey(acirComposer);
172
-
163
+ await api.acirLoadVerificationKey(acirComposer, new RawBuffer(readFileSync(vkPath)));
173
164
  const contract = await api.acirGetSolidityVerifier(acirComposer);
174
165
  if (outputPath === '-') {
175
166
  console.log(contract);
@@ -182,8 +173,8 @@ export async function contract(jsonPath: string, outputPath: string) {
182
173
  }
183
174
  }
184
175
 
185
- export async function writeVk(jsonPath: string, outputPath: string) {
186
- const { api, acirComposer, circuitSize } = await init(jsonPath);
176
+ export async function writeVk(jsonPath: string, outputPath: string, sizeHint?: number) {
177
+ const { api, acirComposer, circuitSize } = await init(jsonPath, sizeHint);
187
178
  try {
188
179
  debug('initing proving key...');
189
180
  const bytecode = getBytecode(jsonPath);
@@ -247,14 +238,24 @@ export async function vkAsFields(vkPath: string, vkeyOutputPath: string) {
247
238
 
248
239
  const program = new Command();
249
240
 
241
+ program.option('-v, --verbose', 'enable verbose logging', false);
242
+
243
+ function handleGlobalOptions() {
244
+ if (program.opts().verbose) {
245
+ createDebug.enable('bb.js*');
246
+ }
247
+ }
248
+
250
249
  program
251
250
  .command('prove_and_verify')
252
251
  .description('Generate a proof and verify it. Process exits with success or failure code.')
253
252
  .option('-j, --json-path <path>', 'Specify the JSON path', './target/main.json')
254
253
  .option('-w, --witness-path <path>', 'Specify the witness path', './target/witness.tr')
255
254
  .option('-r, --recursive', 'prove and verify using recursive prover and verifier', false)
256
- .action(async ({ jsonPath, witnessPath, recursive }) => {
257
- const result = await proveAndVerify(jsonPath, witnessPath, recursive);
255
+ .option('-s, --size-hint <gates>', 'provide a circuit size hint to skip calculation phase')
256
+ .action(async ({ jsonPath, witnessPath, recursive, sizeHint }) => {
257
+ handleGlobalOptions();
258
+ const result = await proveAndVerify(jsonPath, witnessPath, recursive, sizeHint);
258
259
  process.exit(result ? 0 : 1);
259
260
  });
260
261
 
@@ -264,10 +265,11 @@ program
264
265
  .option('-j, --json-path <path>', 'Specify the JSON path', './target/main.json')
265
266
  .option('-w, --witness-path <path>', 'Specify the witness path', './target/witness.tr')
266
267
  .option('-r, --recursive', 'prove using recursive prover', false)
267
- .option('-o, --output-dir <path>', 'Specify the proof output dir', './proofs')
268
- .requiredOption('-n, --name <filename>', 'Output file name.')
269
- .action(async ({ jsonPath, witnessPath, recursive, outputDir, name }) => {
270
- await prove(jsonPath, witnessPath, recursive, outputDir + '/' + name);
268
+ .option('-o, --output-path <path>', 'Specify the proof output path', './proofs/proof')
269
+ .option('-s, --size-hint <gates>', 'provide a circuit size hint to skip calculation phase')
270
+ .action(async ({ jsonPath, witnessPath, recursive, outputPath, sizeHint }) => {
271
+ handleGlobalOptions();
272
+ await prove(jsonPath, witnessPath, recursive, outputPath, sizeHint);
271
273
  });
272
274
 
273
275
  program
@@ -275,6 +277,7 @@ program
275
277
  .description('Print gate count to standard output.')
276
278
  .option('-j, --json-path <path>', 'Specify the JSON path', './target/main.json')
277
279
  .action(async ({ jsonPath }) => {
280
+ handleGlobalOptions();
278
281
  await gateCount(jsonPath);
279
282
  });
280
283
 
@@ -284,8 +287,9 @@ program
284
287
  .option('-j, --json-path <path>', 'Specify the JSON path', './target/main.json')
285
288
  .requiredOption('-p, --proof-path <path>', 'Specify the path to the proof')
286
289
  .option('-r, --recursive', 'prove using recursive prover', false)
287
- .option('-v, --vk <path>', 'path to a verification key. avoids recomputation.')
290
+ .requiredOption('-k, --vk <path>', 'path to a verification key. avoids recomputation.')
288
291
  .action(async ({ jsonPath, proofPath, recursive, vk }) => {
292
+ handleGlobalOptions();
289
293
  await verify(jsonPath, proofPath, recursive, vk);
290
294
  });
291
295
 
@@ -294,8 +298,10 @@ program
294
298
  .description('Output solidity verification key contract.')
295
299
  .option('-j, --json-path <path>', 'Specify the JSON path', './target/main.json')
296
300
  .option('-o, --output-path <path>', 'Specify the path to write the contract', '-')
297
- .action(async ({ jsonPath, outputPath }) => {
298
- await contract(jsonPath, outputPath);
301
+ .requiredOption('-k, --vk <path>', 'path to a verification key. avoids recomputation.')
302
+ .action(async ({ outputPath, vk }) => {
303
+ handleGlobalOptions();
304
+ await contract(outputPath, vk);
299
305
  });
300
306
 
301
307
  program
@@ -303,8 +309,10 @@ program
303
309
  .description('Output verification key.')
304
310
  .option('-j, --json-path <path>', 'Specify the JSON path', './target/main.json')
305
311
  .requiredOption('-o, --output-path <path>', 'Specify the path to write the key')
306
- .action(async ({ jsonPath, outputPath }) => {
307
- await writeVk(jsonPath, outputPath);
312
+ .option('-s, --size-hint <gates>', 'provide a circuit size hint to skip calculation phase')
313
+ .action(async ({ jsonPath, outputPath, sizeHint }) => {
314
+ handleGlobalOptions();
315
+ await writeVk(jsonPath, outputPath, sizeHint);
308
316
  });
309
317
 
310
318
  program
@@ -314,6 +322,7 @@ program
314
322
  .requiredOption('-n, --num-public-inputs <number>', 'Specify the number of public inputs')
315
323
  .requiredOption('-o, --output-path <path>', 'Specify the JSON path to write the proof fields')
316
324
  .action(async ({ proofPath, numPublicInputs, outputPath }) => {
325
+ handleGlobalOptions();
317
326
  await proofAsFields(proofPath, numPublicInputs, outputPath);
318
327
  });
319
328
 
@@ -323,6 +332,7 @@ program
323
332
  .requiredOption('-i, --input-path <path>', 'Specifies the vk path (output from write_vk)')
324
333
  .requiredOption('-o, --output-path <path>', 'Specify the JSON path to write the verification key fields and key hash')
325
334
  .action(async ({ inputPath, outputPath }) => {
335
+ handleGlobalOptions();
326
336
  await vkAsFields(inputPath, outputPath);
327
337
  });
328
338
 
@@ -1,3 +0,0 @@
1
- #!/usr/bin/env -S node --loader ts-node/esm --no-warnings
2
- import './main.js';
3
- //# sourceMappingURL=main-dev.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"main-dev.d.ts","sourceRoot":"","sources":["../src/main-dev.ts"],"names":[],"mappings":";AACA,OAAO,WAAW,CAAC"}
package/dest/main-dev.js DELETED
@@ -1,3 +0,0 @@
1
- #!/usr/bin/env -S node --loader ts-node/esm --no-warnings
2
- import './main.js';
3
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibWFpbi1kZXYuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi9zcmMvbWFpbi1kZXYudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IjtBQUNBLE9BQU8sV0FBVyxDQUFDIn0=
package/src/main-dev.ts DELETED
@@ -1,2 +0,0 @@
1
- #!/usr/bin/env -S node --loader ts-node/esm --no-warnings
2
- import './main.js';