@aztec/bb.js 0.12.0 → 0.13.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 (39) hide show
  1. package/README.md +14 -9
  2. package/dest/browser/barretenberg_api/index.d.ts +1 -11
  3. package/dest/browser/barretenberg_api/index.d.ts.map +1 -1
  4. package/dest/browser/index.js +1 -1
  5. package/dest/node/barretenberg_api/index.d.ts +1 -11
  6. package/dest/node/barretenberg_api/index.d.ts.map +1 -1
  7. package/dest/node/barretenberg_api/index.js +2 -42
  8. package/dest/node/barretenberg_api/pedersen.test.js +5 -62
  9. package/dest/node/barretenberg_api/schnorr.test.js +1 -2
  10. package/dest/node/barretenberg_wasm/barretenberg-threads.wasm +0 -0
  11. package/dest/node/benchmark/index.d.ts +3 -0
  12. package/dest/node/benchmark/index.d.ts.map +1 -0
  13. package/dest/node/benchmark/index.js +25 -0
  14. package/dest/node/benchmark/timer.d.ts +33 -0
  15. package/dest/node/benchmark/timer.d.ts.map +1 -0
  16. package/dest/node/benchmark/timer.js +38 -0
  17. package/dest/node/main.d.ts.map +1 -1
  18. package/dest/node/main.js +17 -4
  19. package/dest/node-cjs/barretenberg_api/index.d.ts +1 -11
  20. package/dest/node-cjs/barretenberg_api/index.d.ts.map +1 -1
  21. package/dest/node-cjs/barretenberg_api/index.js +2 -42
  22. package/dest/node-cjs/barretenberg_api/pedersen.test.js +4 -61
  23. package/dest/node-cjs/barretenberg_api/schnorr.test.js +1 -2
  24. package/dest/node-cjs/barretenberg_wasm/barretenberg-threads.wasm +0 -0
  25. package/dest/node-cjs/benchmark/index.d.ts +3 -0
  26. package/dest/node-cjs/benchmark/index.d.ts.map +1 -0
  27. package/dest/node-cjs/benchmark/index.js +30 -0
  28. package/dest/node-cjs/benchmark/timer.d.ts +33 -0
  29. package/dest/node-cjs/benchmark/timer.d.ts.map +1 -0
  30. package/dest/node-cjs/benchmark/timer.js +42 -0
  31. package/dest/node-cjs/main.d.ts.map +1 -1
  32. package/dest/node-cjs/main.js +17 -4
  33. package/package.json +1 -1
  34. package/src/barretenberg_api/index.ts +2 -60
  35. package/src/barretenberg_api/pedersen.test.ts +9 -71
  36. package/src/barretenberg_api/schnorr.test.ts +0 -1
  37. package/src/benchmark/index.ts +26 -0
  38. package/src/benchmark/timer.ts +41 -0
  39. package/src/main.ts +19 -3
@@ -1,91 +1,29 @@
1
1
  import { Barretenberg } from '../barretenberg/index.js';
2
- import { Fr } from '../types/index.js';
2
+ import { Fr, Point } from '../types/index.js';
3
3
 
4
4
  describe('pedersen', () => {
5
5
  let api: Barretenberg;
6
6
 
7
7
  beforeAll(async () => {
8
8
  api = await Barretenberg.new(1);
9
- await api.pedersenHashInit();
10
9
  }, 30000);
11
10
 
12
11
  afterAll(async () => {
13
12
  await api.destroy();
14
13
  });
15
14
 
16
- it('pedersenCompressFields', async () => {
17
- const result = await api.pedersenCompressFields(new Fr(4n), new Fr(8n));
18
- expect(result).toEqual(new Fr(1521373897829389584529155077412196627698249315427143054350987371861781120260n));
19
- });
20
-
21
- it('pedersenCompress', async () => {
22
- const result = await api.pedersenCompress([new Fr(4n), new Fr(8n), new Fr(12n)]);
23
- expect(result).toEqual(new Fr(16354408412011670665169322571938780771784319449166930406648760506154417354381n));
24
- });
25
-
26
- it('pedersenCompressWithHashIndex', async () => {
27
- const result = await api.pedersenCompressWithHashIndex([new Fr(4n), new Fr(8n)], 7);
15
+ it('pedersenHashWithHashIndex', async () => {
16
+ const result = await api.pedersenHashWithHashIndex([new Fr(4n), new Fr(8n)], 7);
28
17
  expect(result).toEqual(new Fr(2152386650411553803409271316104075950536496387580531018130718456431861859990n));
29
18
  });
30
19
 
31
- it('pedersenCompressAndHashSame', async () => {
32
- const resultCompress = await api.pedersenCompressWithHashIndex([new Fr(4n), new Fr(8n)], 7);
33
- const resultHash = await api.pedersenHashWithHashIndex([new Fr(4n), new Fr(8n)], 7);
34
- expect(resultCompress).toEqual(resultHash);
35
- });
36
-
37
- it('pedersenHashWith0IndexSameAsNoIndex', async () => {
38
- const resultHashImplicit0 = await api.pedersenHash([new Fr(4n), new Fr(8n)]);
39
- const resultCompressImplicit0 = await api.pedersenCompress([new Fr(4n), new Fr(8n)]);
40
- const resultCompressFieldsImplicit0 = await api.pedersenCompressFields(new Fr(4n), new Fr(8n));
41
- const resultHashExplicit0 = await api.pedersenHashWithHashIndex([new Fr(4n), new Fr(8n)], 0);
42
- expect(resultHashImplicit0).toEqual(resultCompressImplicit0);
43
- expect(resultHashImplicit0).toEqual(resultHashExplicit0);
44
- expect(resultHashImplicit0).toEqual(resultCompressFieldsImplicit0);
45
- });
46
-
47
- it('pedersenHashPairSameAsWith0Index', async () => {
48
- const resultHashPair = await api.pedersenHashPair(new Fr(4n), new Fr(8n));
49
- const resultHashExplicit0 = await api.pedersenHashWithHashIndex([new Fr(4n), new Fr(8n)], 0);
50
- expect(resultHashExplicit0).toEqual(resultHashPair);
51
- });
52
-
53
- it('pedersenHashMultipleSameAsWith0Index', async () => {
54
- const resultHashPair = await api.pedersenHashMultiple([new Fr(4n), new Fr(8n)]);
55
- const resultHashExplicit0 = await api.pedersenHashWithHashIndex([new Fr(4n), new Fr(8n)], 0);
56
- expect(resultHashExplicit0).toEqual(resultHashPair);
57
- });
58
-
59
20
  it('pedersenCommit', async () => {
60
21
  const result = await api.pedersenCommit([new Fr(4n), new Fr(8n), new Fr(12n)]);
61
- expect(result).toEqual(new Fr(18374309251862457296563484909553154519357910650678202211610516068880120638872n));
62
- });
63
-
64
- it('pedersenHashPair', async () => {
65
- const result = await api.pedersenHashPair(new Fr(4n), new Fr(8n));
66
- expect(result).toEqual(new Fr(1521373897829389584529155077412196627698249315427143054350987371861781120260n));
67
- });
68
-
69
- it('pedersenHashMultiple', async () => {
70
- const result = await api.pedersenHashMultiple([new Fr(4n), new Fr(8n), new Fr(12n)]);
71
- expect(result).toEqual(new Fr(16354408412011670665169322571938780771784319449166930406648760506154417354381n));
72
- });
73
-
74
- it('pedersenHashMultipleWithHashIndex', async () => {
75
- const result = await api.pedersenHashMultipleWithHashIndex([new Fr(4n), new Fr(8n)], 7);
76
- expect(result).toEqual(new Fr(2152386650411553803409271316104075950536496387580531018130718456431861859990n));
77
- });
78
-
79
- it('pedersenHashToTree', async () => {
80
- const result = await api.pedersenHashToTree([new Fr(4n), new Fr(8n), new Fr(12n), new Fr(16n)]);
81
- expect(result).toEqual([
82
- new Fr(4n),
83
- new Fr(8n),
84
- new Fr(12n),
85
- new Fr(16n),
86
- new Fr(1521373897829389584529155077412196627698249315427143054350987371861781120260n),
87
- new Fr(18350527319045519333962768191016242826584323959670139897255818770108115223653n),
88
- new Fr(5972535902427608430534212385621973704186819235181735133037695406667218179357n),
89
- ]);
22
+ expect(result).toEqual(
23
+ new Point(
24
+ new Fr(18374309251862457296563484909553154519357910650678202211610516068880120638872n),
25
+ new Fr(2572141322478528249692953821523229170092797347760799983831061874108357705739n),
26
+ ),
27
+ );
90
28
  });
91
29
  });
@@ -9,7 +9,6 @@ describe('schnorr', () => {
9
9
 
10
10
  beforeAll(async () => {
11
11
  api = await Barretenberg.new(1);
12
- await api.pedersenInit();
13
12
  }, 30000);
14
13
 
15
14
  afterAll(async () => {
@@ -0,0 +1,26 @@
1
+ import * as fs from 'fs';
2
+ export * from './timer.js';
3
+
4
+ const bfd = (() => {
5
+ const bfdStr = process.env.BENCHMARK_FD;
6
+ const bfd = bfdStr ? parseInt(bfdStr) : -1;
7
+ if (bfd >= 0 && !fs.fstatSync(bfd)) {
8
+ throw new Error('fd is not open. Did you redirect in your shell?');
9
+ }
10
+ return bfd;
11
+ })();
12
+
13
+ export function writeBenchmark<T>(name: string, value: T, labels: Record<string, any> = {}) {
14
+ if (bfd === -1) {
15
+ return;
16
+ }
17
+ const data = {
18
+ timestamp: new Date().toISOString(),
19
+ name,
20
+ type: typeof value,
21
+ value,
22
+ ...labels,
23
+ };
24
+ const jsonl = JSON.stringify(data) + '\n';
25
+ fs.writeSync(bfd, jsonl);
26
+ }
@@ -0,0 +1,41 @@
1
+ /**
2
+ * Timer class to measure time intervals in milliseconds and seconds.
3
+ * Upon instantiation, it stores the current timestamp as the starting point.
4
+ * The 'ms()' method returns the elapsed time in milliseconds,
5
+ * while the 's()' method returns the elapsed time in seconds.
6
+ *
7
+ * @example
8
+ * const timer = new Timer();
9
+ * setTimeout(() =\> \{
10
+ * console.log(`Elapsed time: ${timer.ms()} ms`);
11
+ * \}, 1000);
12
+ */
13
+ export class Timer {
14
+ private start: number;
15
+
16
+ constructor() {
17
+ this.start = new Date().getTime();
18
+ }
19
+
20
+ /**
21
+ * Returns the elapsed time in milliseconds since the Timer instance was created.
22
+ * Provides a simple and convenient way to measure the time duration between two events
23
+ * or monitor performance of specific code sections.
24
+ *
25
+ * @returns The elapsed time in milliseconds.
26
+ */
27
+ public ms() {
28
+ return new Date().getTime() - this.start;
29
+ }
30
+
31
+ /**
32
+ * Returns the time elapsed since the Timer instance was created, in seconds.
33
+ * The value is calculated by subtracting the initial start time from the current time
34
+ * and dividing the result by 1000 to convert milliseconds to seconds.
35
+ *
36
+ * @returns The elapsed time in seconds.
37
+ */
38
+ public s() {
39
+ return (new Date().getTime() - this.start) / 1000;
40
+ }
41
+ }
package/src/main.ts CHANGED
@@ -5,6 +5,8 @@ import { readFileSync, writeFileSync } from 'fs';
5
5
  import { gunzipSync } from 'zlib';
6
6
  import { Command } from 'commander';
7
7
  import { acvmInfoJson } from './info.js';
8
+ import { Timer, writeBenchmark } from './benchmark/index.js';
9
+ import path from 'path';
8
10
  createDebug.log = console.error.bind(console);
9
11
  const debug = createDebug('bb.js');
10
12
 
@@ -15,6 +17,7 @@ const debug = createDebug('bb.js');
15
17
  // aware of this discrepancy, when creating proofs in bb versus
16
18
  // creating the same proofs in the node CLI.
17
19
  const MAX_CIRCUIT_SIZE = 2 ** 19;
20
+ const threads = +process.env.HARDWARE_CONCURRENCY! || undefined;
18
21
 
19
22
  function getBytecode(bytecodePath: string) {
20
23
  const encodedCircuit = readFileSync(bytecodePath);
@@ -41,7 +44,7 @@ async function computeCircuitSize(bytecodePath: string, api: Barretenberg) {
41
44
  }
42
45
 
43
46
  async function init(bytecodePath: string, crsPath: string) {
44
- const api = await Barretenberg.new();
47
+ const api = await Barretenberg.new(threads);
45
48
 
46
49
  const circuitSize = await getGates(bytecodePath, api);
47
50
  const subgroupSize = Math.pow(2, Math.ceil(Math.log2(circuitSize)));
@@ -63,7 +66,7 @@ async function init(bytecodePath: string, crsPath: string) {
63
66
  await api.srsInitSrs(new RawBuffer(crs.getG1Data()), crs.numPoints, new RawBuffer(crs.getG2Data()));
64
67
 
65
68
  const acirComposer = await api.acirNewAcirComposer(subgroupSize);
66
- return { api, acirComposer, circuitSize: subgroupSize };
69
+ return { api, acirComposer, circuitSize, subgroupSize };
67
70
  }
68
71
 
69
72
  async function initLite() {
@@ -80,12 +83,24 @@ async function initLite() {
80
83
  }
81
84
 
82
85
  export async function proveAndVerify(bytecodePath: string, witnessPath: string, crsPath: string, isRecursive: boolean) {
83
- const { api, acirComposer } = await init(bytecodePath, crsPath);
86
+ /* eslint-disable camelcase */
87
+ const acir_test = path.basename(process.cwd());
88
+
89
+ const { api, acirComposer, circuitSize, subgroupSize } = await init(bytecodePath, crsPath);
84
90
  try {
85
91
  debug(`creating proof...`);
86
92
  const bytecode = getBytecode(bytecodePath);
87
93
  const witness = getWitness(witnessPath);
94
+
95
+ const pkTimer = new Timer();
96
+ await api.acirInitProvingKey(acirComposer, bytecode);
97
+ writeBenchmark('pk_construction_time', pkTimer.ms(), { acir_test, threads });
98
+ writeBenchmark('gate_count', circuitSize, { acir_test, threads });
99
+ writeBenchmark('subgroup_size', subgroupSize, { acir_test, threads });
100
+
101
+ const proofTimer = new Timer();
88
102
  const proof = await api.acirCreateProof(acirComposer, bytecode, witness, isRecursive);
103
+ writeBenchmark('proof_construction_time', proofTimer.ms(), { acir_test, threads });
89
104
 
90
105
  debug(`verifying...`);
91
106
  const verified = await api.acirVerifyProof(acirComposer, proof, isRecursive);
@@ -94,6 +109,7 @@ export async function proveAndVerify(bytecodePath: string, witnessPath: string,
94
109
  } finally {
95
110
  await api.destroy();
96
111
  }
112
+ /* eslint-enable camelcase */
97
113
  }
98
114
 
99
115
  export async function prove(