@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.
- package/README.md +14 -9
- package/dest/browser/barretenberg_api/index.d.ts +1 -11
- package/dest/browser/barretenberg_api/index.d.ts.map +1 -1
- package/dest/browser/index.js +1 -1
- package/dest/node/barretenberg_api/index.d.ts +1 -11
- package/dest/node/barretenberg_api/index.d.ts.map +1 -1
- package/dest/node/barretenberg_api/index.js +2 -42
- package/dest/node/barretenberg_api/pedersen.test.js +5 -62
- package/dest/node/barretenberg_api/schnorr.test.js +1 -2
- package/dest/node/barretenberg_wasm/barretenberg-threads.wasm +0 -0
- package/dest/node/benchmark/index.d.ts +3 -0
- package/dest/node/benchmark/index.d.ts.map +1 -0
- package/dest/node/benchmark/index.js +25 -0
- package/dest/node/benchmark/timer.d.ts +33 -0
- package/dest/node/benchmark/timer.d.ts.map +1 -0
- package/dest/node/benchmark/timer.js +38 -0
- package/dest/node/main.d.ts.map +1 -1
- package/dest/node/main.js +17 -4
- package/dest/node-cjs/barretenberg_api/index.d.ts +1 -11
- package/dest/node-cjs/barretenberg_api/index.d.ts.map +1 -1
- package/dest/node-cjs/barretenberg_api/index.js +2 -42
- package/dest/node-cjs/barretenberg_api/pedersen.test.js +4 -61
- package/dest/node-cjs/barretenberg_api/schnorr.test.js +1 -2
- package/dest/node-cjs/barretenberg_wasm/barretenberg-threads.wasm +0 -0
- package/dest/node-cjs/benchmark/index.d.ts +3 -0
- package/dest/node-cjs/benchmark/index.d.ts.map +1 -0
- package/dest/node-cjs/benchmark/index.js +30 -0
- package/dest/node-cjs/benchmark/timer.d.ts +33 -0
- package/dest/node-cjs/benchmark/timer.d.ts.map +1 -0
- package/dest/node-cjs/benchmark/timer.js +42 -0
- package/dest/node-cjs/main.d.ts.map +1 -1
- package/dest/node-cjs/main.js +17 -4
- package/package.json +1 -1
- package/src/barretenberg_api/index.ts +2 -60
- package/src/barretenberg_api/pedersen.test.ts +9 -71
- package/src/barretenberg_api/schnorr.test.ts +0 -1
- package/src/benchmark/index.ts +26 -0
- package/src/benchmark/timer.ts +41 -0
- 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('
|
|
17
|
-
const result = await api.
|
|
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(
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
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
|
});
|
|
@@ -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
|
|
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
|
-
|
|
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(
|