@aztec/bb.js 0.16.8 → 0.17.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 (71) hide show
  1. package/README.md +2 -2
  2. package/dest/browser/barretenberg/index.d.ts +8 -1
  3. package/dest/browser/barretenberg/index.d.ts.map +1 -1
  4. package/dest/browser/barretenberg_api/index.d.ts +8 -1
  5. package/dest/browser/barretenberg_api/index.d.ts.map +1 -1
  6. package/dest/browser/crs/net_crs.d.ts.map +1 -1
  7. package/dest/browser/crs/node/ignition_files_crs.d.ts +3 -2
  8. package/dest/browser/crs/node/ignition_files_crs.d.ts.map +1 -1
  9. package/dest/browser/crs/node/index.d.ts +16 -0
  10. package/dest/browser/crs/node/index.d.ts.map +1 -1
  11. package/dest/browser/index.js +1 -1
  12. package/dest/node/barretenberg/blake2s.test.js +2 -2
  13. package/dest/node/barretenberg/common.test.js +2 -2
  14. package/dest/node/barretenberg/index.d.ts +8 -1
  15. package/dest/node/barretenberg/index.d.ts.map +1 -1
  16. package/dest/node/barretenberg/index.js +3 -3
  17. package/dest/node/barretenberg/schnorr.test.js +2 -2
  18. package/dest/node/barretenberg_api/index.d.ts +8 -1
  19. package/dest/node/barretenberg_api/index.d.ts.map +1 -1
  20. package/dest/node/barretenberg_api/index.js +52 -3
  21. package/dest/node/barretenberg_wasm/barretenberg-threads.wasm +0 -0
  22. package/dest/node/barretenberg_wasm/barretenberg_wasm_main/index.js +1 -1
  23. package/dest/node/crs/net_crs.d.ts.map +1 -1
  24. package/dest/node/crs/net_crs.js +5 -11
  25. package/dest/node/crs/node/ignition_files_crs.d.ts +3 -2
  26. package/dest/node/crs/node/ignition_files_crs.d.ts.map +1 -1
  27. package/dest/node/crs/node/ignition_files_crs.js +10 -6
  28. package/dest/node/crs/node/index.d.ts +16 -0
  29. package/dest/node/crs/node/index.d.ts.map +1 -1
  30. package/dest/node/crs/node/index.js +69 -19
  31. package/dest/node/info.d.ts.map +1 -1
  32. package/dest/node/info.js +1 -2
  33. package/dest/node/main.d.ts +1 -0
  34. package/dest/node/main.d.ts.map +1 -1
  35. package/dest/node/main.js +53 -6
  36. package/dest/node-cjs/barretenberg/blake2s.test.js +2 -2
  37. package/dest/node-cjs/barretenberg/common.test.js +2 -2
  38. package/dest/node-cjs/barretenberg/index.d.ts +8 -1
  39. package/dest/node-cjs/barretenberg/index.d.ts.map +1 -1
  40. package/dest/node-cjs/barretenberg/index.js +3 -3
  41. package/dest/node-cjs/barretenberg/schnorr.test.js +2 -2
  42. package/dest/node-cjs/barretenberg_api/index.d.ts +8 -1
  43. package/dest/node-cjs/barretenberg_api/index.d.ts.map +1 -1
  44. package/dest/node-cjs/barretenberg_api/index.js +52 -3
  45. package/dest/node-cjs/barretenberg_wasm/barretenberg-threads.wasm +0 -0
  46. package/dest/node-cjs/barretenberg_wasm/barretenberg_wasm_main/index.js +1 -1
  47. package/dest/node-cjs/crs/net_crs.d.ts.map +1 -1
  48. package/dest/node-cjs/crs/net_crs.js +5 -11
  49. package/dest/node-cjs/crs/node/ignition_files_crs.d.ts +3 -2
  50. package/dest/node-cjs/crs/node/ignition_files_crs.d.ts.map +1 -1
  51. package/dest/node-cjs/crs/node/ignition_files_crs.js +11 -7
  52. package/dest/node-cjs/crs/node/index.d.ts +16 -0
  53. package/dest/node-cjs/crs/node/index.d.ts.map +1 -1
  54. package/dest/node-cjs/crs/node/index.js +69 -18
  55. package/dest/node-cjs/info.d.ts.map +1 -1
  56. package/dest/node-cjs/info.js +1 -2
  57. package/dest/node-cjs/main.d.ts +1 -0
  58. package/dest/node-cjs/main.d.ts.map +1 -1
  59. package/dest/node-cjs/main.js +55 -7
  60. package/package.json +1 -1
  61. package/src/barretenberg/blake2s.test.ts +1 -1
  62. package/src/barretenberg/common.test.ts +1 -1
  63. package/src/barretenberg/index.ts +7 -2
  64. package/src/barretenberg/schnorr.test.ts +1 -1
  65. package/src/barretenberg_api/index.ts +90 -2
  66. package/src/barretenberg_wasm/barretenberg_wasm_main/index.ts +1 -1
  67. package/src/crs/net_crs.ts +4 -11
  68. package/src/crs/node/ignition_files_crs.ts +9 -5
  69. package/src/crs/node/index.ts +75 -17
  70. package/src/info.ts +0 -1
  71. package/src/main.ts +60 -5
@@ -14,9 +14,10 @@ function getCurrentDir() {
14
14
  }
15
15
 
16
16
  /**
17
- * The path to our SRS object, assuming that we are in barretenberg/ts folder.
17
+ * The path to our SRS object, assuming that we are in e.g. barretenberg/ts/dest/node/crs/node folder.
18
18
  */
19
- export const SRS_DEV_PATH = getCurrentDir() + '/../../../cpp/srs_db/ignition/monomial';
19
+ export const SRS_DEV_PATH = getCurrentDir() + '/../../../../../cpp/srs_db/ignition/monomial';
20
+ export const GRUMPKIN_SRS_DEV_PATH = getCurrentDir() + '/../../../../../cpp/srs_db/grumpkin/monomial';
20
21
 
21
22
  /**
22
23
  * Downloader for CRS from a local file (for Node).
@@ -33,8 +34,8 @@ export class IgnitionFilesCrs {
33
34
  private path = SRS_DEV_PATH,
34
35
  ) {}
35
36
 
36
- static defaultExists() {
37
- return existsSync(SRS_DEV_PATH);
37
+ pathExists() {
38
+ return existsSync(this.path);
38
39
  }
39
40
 
40
41
  /**
@@ -49,7 +50,10 @@ export class IgnitionFilesCrs {
49
50
  const data = await readFile(this.path + '/transcript00.dat');
50
51
  this.data = data.subarray(g1Start, g1End);
51
52
 
52
- this.g2Data = await readFile(this.path + '/g2.dat');
53
+ // TODO(https://github.com/AztecProtocol/barretenberg/issues/811): proper abstraction from Grumpkin which does not have g2
54
+ if (existsSync(this.path + '/g2.dat')) {
55
+ this.g2Data = await readFile(this.path + '/g2.dat');
56
+ }
53
57
  }
54
58
 
55
59
  /**
@@ -1,8 +1,9 @@
1
1
  import { NetCrs } from '../net_crs.js';
2
- import { IgnitionFilesCrs } from './ignition_files_crs.js';
2
+ import { GRUMPKIN_SRS_DEV_PATH, IgnitionFilesCrs } from './ignition_files_crs.js';
3
3
  import { mkdirSync, readFileSync, writeFileSync } from 'fs';
4
- import { readFile } from 'fs/promises';
4
+ import { readFile, stat } from 'fs/promises';
5
5
  import createDebug from 'debug';
6
+ import { homedir } from 'os';
6
7
 
7
8
  const debug = createDebug('bb.js:crs');
8
9
 
@@ -12,7 +13,7 @@ const debug = createDebug('bb.js:crs');
12
13
  export class Crs {
13
14
  constructor(public readonly numPoints: number, public readonly path: string) {}
14
15
 
15
- static async new(numPoints: number, crsPath = './crs') {
16
+ static async new(numPoints: number, crsPath = homedir() + '/.bb-crs') {
16
17
  const crs = new Crs(numPoints, crsPath);
17
18
  await crs.init();
18
19
  return crs;
@@ -20,22 +21,24 @@ export class Crs {
20
21
 
21
22
  async init() {
22
23
  mkdirSync(this.path, { recursive: true });
23
- const size = await readFile(this.path + '/size', 'ascii').catch(() => undefined);
24
- if (size && +size >= this.numPoints) {
25
- debug(`using cached crs of size: ${size}`);
24
+
25
+ const g1FileSize = await stat(this.path + '/bn254_g1.dat')
26
+ .then(stats => stats.size)
27
+ .catch(() => 0);
28
+ const g2FileSize = await stat(this.path + '/bn254_g2.dat')
29
+ .then(stats => stats.size)
30
+ .catch(() => 0);
31
+
32
+ if (g1FileSize >= this.numPoints * 64 && g1FileSize % 64 == 0 && g2FileSize == 128) {
33
+ debug(`using cached crs of size: ${g1FileSize / 64}`);
26
34
  return;
27
35
  }
28
36
 
29
- const crs = IgnitionFilesCrs.defaultExists() ? new IgnitionFilesCrs(this.numPoints) : new NetCrs(this.numPoints);
30
- if (crs instanceof NetCrs) {
31
- debug(`downloading crs of size: ${this.numPoints}`);
32
- } else {
33
- debug(`loading igntion file crs of size: ${this.numPoints}`);
34
- }
37
+ debug(`downloading crs of size: ${this.numPoints}`);
38
+ const crs = new NetCrs(this.numPoints);
35
39
  await crs.init();
36
- writeFileSync(this.path + '/size', this.numPoints.toString());
37
- writeFileSync(this.path + '/g1.dat', crs.getG1Data());
38
- writeFileSync(this.path + '/g2.dat', crs.getG2Data());
40
+ writeFileSync(this.path + '/bn254_g1.dat', crs.getG1Data());
41
+ writeFileSync(this.path + '/bn254_g2.dat', crs.getG2Data());
39
42
  }
40
43
 
41
44
  /**
@@ -43,7 +46,7 @@ export class Crs {
43
46
  * @returns The points data.
44
47
  */
45
48
  getG1Data(): Uint8Array {
46
- return readFileSync(this.path + '/g1.dat');
49
+ return readFileSync(this.path + '/bn254_g1.dat');
47
50
  }
48
51
 
49
52
  /**
@@ -51,6 +54,61 @@ export class Crs {
51
54
  * @returns The points data.
52
55
  */
53
56
  getG2Data(): Uint8Array {
54
- return readFileSync(this.path + '/g2.dat');
57
+ return readFileSync(this.path + '/bn254_g2.dat');
58
+ }
59
+ }
60
+
61
+ /**
62
+ * Generic Grumpkin CRS finder utility class.
63
+ */
64
+ export class GrumpkinCrs {
65
+ constructor(public readonly numPoints: number, public readonly path: string) {}
66
+
67
+ static async new(numPoints: number, crsPath = './crs') {
68
+ const crs = new GrumpkinCrs(numPoints, crsPath);
69
+ await crs.init();
70
+ return crs;
71
+ }
72
+
73
+ async downloadG1Data() {
74
+ const g1Start = 28;
75
+ const g1End = g1Start + this.numPoints * 64 - 1;
76
+
77
+ const response = await fetch('https://aztec-ignition.s3.amazonaws.com/TEST%20GRUMPKIN/monomial/transcript00.dat', {
78
+ headers: {
79
+ Range: `bytes=${g1Start}-${g1End}`,
80
+ },
81
+ cache: 'force-cache',
82
+ });
83
+
84
+ return new Uint8Array(await response.arrayBuffer());
85
+ }
86
+
87
+ async init() {
88
+ mkdirSync(this.path, { recursive: true });
89
+ const size = await readFile(this.path + '/grumpkin_size', 'ascii').catch(() => undefined);
90
+ if (size && +size >= this.numPoints) {
91
+ debug(`using cached crs of size: ${size}`);
92
+ return;
93
+ }
94
+
95
+ // TODO(https://github.com/AztecProtocol/barretenberg/issues/813): implement NetCrs for Grumpkin once SRS is uploaded.
96
+ const ignitionCrs = new IgnitionFilesCrs(this.numPoints, GRUMPKIN_SRS_DEV_PATH);
97
+ if (ignitionCrs.pathExists()) {
98
+ await ignitionCrs.init();
99
+ }
100
+ const g1Data = ignitionCrs.pathExists() ? ignitionCrs.getG1Data() : await this.downloadG1Data();
101
+ debug(`loading ignition file crs of size: ${this.numPoints}`);
102
+ // await crs.init();
103
+ writeFileSync(this.path + '/grumpkin_size', this.numPoints.toString());
104
+ writeFileSync(this.path + '/grumpkin_g1.dat', g1Data);
105
+ }
106
+
107
+ /**
108
+ * G1 points data for prover key.
109
+ * @returns The points data.
110
+ */
111
+ getG1Data(): Uint8Array {
112
+ return readFileSync(this.path + '/grumpkin_g1.dat');
55
113
  }
56
114
  }
package/src/info.ts CHANGED
@@ -15,7 +15,6 @@ export const acvmInfoJson = {
15
15
  'schnorr_verify',
16
16
  'pedersen',
17
17
  'pedersen_hash',
18
- 'hash_to_field_128_security',
19
18
  'ecdsa_secp256k1',
20
19
  'ecdsa_secp256r1',
21
20
  'fixed_base_scalar_mul',
package/src/main.ts CHANGED
@@ -7,6 +7,7 @@ import { Command } from 'commander';
7
7
  import { acvmInfoJson } from './info.js';
8
8
  import { Timer, writeBenchmark } from './benchmark/index.js';
9
9
  import path from 'path';
10
+ import { GrumpkinCrs } from './crs/node/index.js';
10
11
  createDebug.log = console.error.bind(console);
11
12
  const debug = createDebug('bb.js');
12
13
 
@@ -43,11 +44,12 @@ async function computeCircuitSize(bytecodePath: string, api: Barretenberg) {
43
44
  return { exact, total, subgroup };
44
45
  }
45
46
 
46
- async function init(bytecodePath: string, crsPath: string) {
47
- const api = await Barretenberg.new(threads);
47
+ async function init(bytecodePath: string, crsPath: string, subgroupSizeOverride = -1) {
48
+ const api = await Barretenberg.new({ threads });
48
49
 
49
50
  const circuitSize = await getGates(bytecodePath, api);
50
- const subgroupSize = Math.pow(2, Math.ceil(Math.log2(circuitSize)));
51
+ // TODO(https://github.com/AztecProtocol/barretenberg/issues/811): remove subgroupSizeOverride hack for goblin
52
+ const subgroupSize = Math.max(subgroupSizeOverride, Math.pow(2, Math.ceil(Math.log2(circuitSize))));
51
53
  if (subgroupSize > MAX_CIRCUIT_SIZE) {
52
54
  throw new Error(`Circuit size of ${subgroupSize} exceeds max supported of ${MAX_CIRCUIT_SIZE}`);
53
55
  }
@@ -69,8 +71,22 @@ async function init(bytecodePath: string, crsPath: string) {
69
71
  return { api, acirComposer, circuitSize, subgroupSize };
70
72
  }
71
73
 
74
+ async function initGoblin(bytecodePath: string, crsPath: string) {
75
+ // TODO(https://github.com/AztecProtocol/barretenberg/issues/811): remove this subgroup size hack
76
+ const hardcodedGrumpkinSubgroupSizeHack = 262144;
77
+ const initData = await init(bytecodePath, crsPath, hardcodedGrumpkinSubgroupSizeHack);
78
+ const { api } = initData;
79
+
80
+ // Plus 1 needed! (Move +1 into Crs?)
81
+ // Need both grumpkin and bn254 SRS's currently
82
+ const grumpkinCrs = await GrumpkinCrs.new(hardcodedGrumpkinSubgroupSizeHack + 1, crsPath);
83
+ await api.srsInitGrumpkinSrs(new RawBuffer(grumpkinCrs.getG1Data()), grumpkinCrs.numPoints);
84
+
85
+ return initData;
86
+ }
87
+
72
88
  async function initLite() {
73
- const api = await Barretenberg.new(1);
89
+ const api = await Barretenberg.new({ threads: 1 });
74
90
 
75
91
  // Plus 1 needed! (Move +1 into Crs?)
76
92
  const crs = await Crs.new(1);
@@ -112,6 +128,34 @@ export async function proveAndVerify(bytecodePath: string, witnessPath: string,
112
128
  /* eslint-enable camelcase */
113
129
  }
114
130
 
131
+ export async function proveAndVerifyGoblin(bytecodePath: string, witnessPath: string, crsPath: string) {
132
+ /* eslint-disable camelcase */
133
+ const acir_test = path.basename(process.cwd());
134
+
135
+ const { api, acirComposer, circuitSize, subgroupSize } = await initGoblin(bytecodePath, crsPath);
136
+ try {
137
+ debug(`creating proof...`);
138
+ const bytecode = getBytecode(bytecodePath);
139
+ const witness = getWitness(witnessPath);
140
+
141
+ writeBenchmark('gate_count', circuitSize, { acir_test, threads });
142
+ writeBenchmark('subgroup_size', subgroupSize, { acir_test, threads });
143
+
144
+ const proofTimer = new Timer();
145
+ const proof = await api.acirCreateGoblinProof(acirComposer, bytecode, witness);
146
+ writeBenchmark('proof_construction_time', proofTimer.ms(), { acir_test, threads });
147
+
148
+ debug(`verifying...`);
149
+ const verified = await api.acirVerifyGoblinProof(acirComposer, proof);
150
+ debug(`verified: ${verified}`);
151
+ console.log({ verified });
152
+ return verified;
153
+ } finally {
154
+ await api.destroy();
155
+ }
156
+ /* eslint-enable camelcase */
157
+ }
158
+
115
159
  export async function prove(
116
160
  bytecodePath: string,
117
161
  witnessPath: string,
@@ -140,7 +184,7 @@ export async function prove(
140
184
  }
141
185
 
142
186
  export async function gateCount(bytecodePath: string) {
143
- const api = await Barretenberg.new(1);
187
+ const api = await Barretenberg.new({ threads: 1 });
144
188
  try {
145
189
  const numberOfGates = await getGates(bytecodePath, api);
146
190
 
@@ -312,6 +356,17 @@ program
312
356
  process.exit(result ? 0 : 1);
313
357
  });
314
358
 
359
+ program
360
+ .command('prove_and_verify_goblin')
361
+ .description('Generate a proof and verify it. Process exits with success or failure code.')
362
+ .option('-b, --bytecode-path <path>', 'Specify the bytecode path', './target/acir.gz')
363
+ .option('-w, --witness-path <path>', 'Specify the witness path', './target/witness.gz')
364
+ .action(async ({ bytecodePath, witnessPath, crsPath }) => {
365
+ handleGlobalOptions();
366
+ const result = await proveAndVerifyGoblin(bytecodePath, witnessPath, crsPath);
367
+ process.exit(result ? 0 : 1);
368
+ });
369
+
315
370
  program
316
371
  .command('prove')
317
372
  .description('Generate a proof and write it to a file.')