-
Notifications
You must be signed in to change notification settings - Fork 62
Expand file tree
/
Copy pathbench.js
More file actions
executable file
·128 lines (112 loc) · 3.17 KB
/
bench.js
File metadata and controls
executable file
·128 lines (112 loc) · 3.17 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
#!/usr/bin/env node
// Measuring elliptic curve operations for ffjavascript
import { BigBuffer, buildBn128, buildBls12381, F1Field } from "ffjavascript";
import { Bench } from "tinybench";
const curves = [buildBn128(false), buildBls12381(false)];
function bench_add_ff(F) {
const x = F.random();
const y = F.random();
return () => {
F.add(x, y);
};
}
function bench_mul_ff(F) {
const x = F.random();
const y = F.random();
return () => {
F.mul(x, y);
};
}
function bench_invert(F) {
const x = F.random();
return () => {
F.invert(x);
};
}
function bench_add_ec(G, Fr) {
const x = G.timesScalar(G.g, Fr.random());
const y = G.timesScalar(G.g, Fr.random());
return () => {
G.add(x, y);
};
}
function bench_mul_ec(G, Fr) {
const x = G.F.random();
const y = G.timesScalar(G.g, Fr.random());
return () => {
G.timesScalar(y, x);
};
}
function bench_pairing(curve) {
const x = curve.Fr.random();
const y = curve.Fr.random();
const g1 = curve.G1.timesScalar(curve.G1.g, x);
const g2 = curve.G2.timesScalar(curve.G2.g, y);
return () => {
curve.pairing(g1, g2);
};
}
function bench_fft(bench, name, F, range) {
for (var i = range[0]; i < range[1]; i++) {
const n = Math.pow(2, i);
const x = new BigBuffer(n * F.n8);
for (let i = 0; i < n; i++) {
x.set(F.random(), i * F.n8);
}
bench.add(name + "/" + n, async () => {
await F.fft(x);
});
}
}
function bench_msm(bench, name, G, Fr, range) {
for (var i = range[0]; i < range[1]; i++) {
let n = Math.pow(2, i);
const scalars = new BigBuffer(n * Fr.n8);
const bases = new BigBuffer(n * G.F.n8 * 2);
for (let i = 0; i < n; i++) {
scalars.set(Fr.random(), i * Fr.n8);
bases.set(G.toAffine(G.timesFr(G.g, Fr.random())), i * G.F.n8 * 2);
}
bench.add(name + "/" + n, async () => {
await G.multiExpAffine(bases, scalars, false, "");
});
}
}
async function run() {
const bench = new Bench();
for (const curve of curves) {
const c = await curve;
// If we do not do it like that, then the pairing operation does not work
// properly.
let name = c.name;
if (name == "bls12381") {
name = "bls12_381";
}
if (name == "bn128") {
name = "bn254";
}
bench
.add(name + "/add_ff", bench_add_ff(c.Fr))
.add(name + "/mul_ff", bench_mul_ff(c.Fr))
.add(name + "/invert", bench_invert(c.Fr))
.add(name + "/mul_G1", bench_mul_ec(c.G1, c.Fr))
.add(name + "/mul_G2", bench_mul_ec(c.G2, c.Fr))
.add(name + "/pairing", bench_pairing(c))
.add(name + "/add_G1", bench_add_ec(c.G1, c.Fr))
.add(name + "/add_G2", bench_add_ec(c.G2, c.Fr));
bench_msm(bench, name + "/msm_G1", c.G1, c.Fr, [1, 21]);
bench_msm(bench, name + "/msm_G2", c.G2, c.Fr, [1, 21]);
bench_fft(bench, name + "/fft", c.Fr, [1, 21]);
}
await bench.run();
console.table(bench.table());
const results = bench.tasks.map((x) => {
// remove samples to avoid the dataset from exploding
let { ["samples"]: unused, ...info } = x.result;
return { name: x.name, ...info };
});
process.stderr.write(JSON.stringify(results));
}
run().then(() => {
process.exit(0);
});