Skip to content

Commit 4f74be3

Browse files
panvaruyadorno
authored andcommittedAug 29, 2023
benchmark: refactor crypto oneshot
PR-URL: #48267 Reviewed-By: Tobias Nießen <tniessen@tnie.de> Reviewed-By: Yagiz Nizipli <yagiz@nizipli.com>
1 parent 211a4f8 commit 4f74be3

File tree

3 files changed

+282
-141
lines changed

3 files changed

+282
-141
lines changed
 

‎benchmark/crypto/oneshot-sign-verify.js

-141
This file was deleted.

‎benchmark/crypto/oneshot-sign.js

+131
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,131 @@
1+
'use strict';
2+
3+
const common = require('../common.js');
4+
const crypto = require('crypto');
5+
const fs = require('fs');
6+
const path = require('path');
7+
const fixtures_keydir = path.resolve(__dirname, '../../test/fixtures/keys/');
8+
9+
const keyFixtures = {
10+
ec: fs.readFileSync(`${fixtures_keydir}/ec_p256_private.pem`, 'utf-8'),
11+
rsa: fs.readFileSync(`${fixtures_keydir}/rsa_private_2048.pem`, 'utf-8'),
12+
ed25519: fs.readFileSync(`${fixtures_keydir}/ed25519_private.pem`, 'utf-8'),
13+
};
14+
15+
const data = crypto.randomBytes(256);
16+
17+
let pems;
18+
let keyObjects;
19+
20+
const bench = common.createBenchmark(main, {
21+
keyType: ['rsa', 'ec', 'ed25519'],
22+
mode: ['sync', 'async', 'async-parallel'],
23+
keyFormat: ['pem', 'der', 'jwk', 'keyObject', 'keyObject.unique'],
24+
n: [1e3],
25+
}, {
26+
combinationFilter(p) {
27+
// "keyObject.unique" allows to compare the result with "keyObject" to
28+
// assess whether mutexes over the key material impact the operation
29+
return p.keyFormat !== 'keyObject.unique' ||
30+
(p.keyFormat === 'keyObject.unique' && p.mode === 'async-parallel');
31+
},
32+
});
33+
34+
function measureSync(n, digest, privateKey, keys) {
35+
bench.start();
36+
for (let i = 0; i < n; ++i) {
37+
crypto.sign(
38+
digest,
39+
data,
40+
privateKey || keys[i]);
41+
}
42+
bench.end(n);
43+
}
44+
45+
function measureAsync(n, digest, privateKey, keys) {
46+
let remaining = n;
47+
function done() {
48+
if (--remaining === 0)
49+
bench.end(n);
50+
else
51+
one();
52+
}
53+
54+
function one() {
55+
crypto.sign(
56+
digest,
57+
data,
58+
privateKey || keys[n - remaining],
59+
done);
60+
}
61+
bench.start();
62+
one();
63+
}
64+
65+
function measureAsyncParallel(n, digest, privateKey, keys) {
66+
let remaining = n;
67+
function done() {
68+
if (--remaining === 0)
69+
bench.end(n);
70+
}
71+
bench.start();
72+
for (let i = 0; i < n; ++i) {
73+
crypto.sign(
74+
digest,
75+
data,
76+
privateKey || keys[i],
77+
done);
78+
}
79+
}
80+
81+
function main({ n, mode, keyFormat, keyType }) {
82+
pems ||= [...Buffer.alloc(n)].map(() => keyFixtures[keyType]);
83+
keyObjects ||= pems.map(crypto.createPrivateKey);
84+
85+
let privateKey, keys, digest;
86+
87+
switch (keyType) {
88+
case 'rsa':
89+
case 'ec':
90+
digest = 'sha256';
91+
break;
92+
case 'ed25519':
93+
break;
94+
default:
95+
throw new Error('not implemented');
96+
}
97+
98+
switch (keyFormat) {
99+
case 'keyObject':
100+
privateKey = keyObjects[0];
101+
break;
102+
case 'pem':
103+
privateKey = pems[0];
104+
break;
105+
case 'jwk': {
106+
privateKey = { key: keyObjects[0].export({ format: 'jwk' }), format: 'jwk' };
107+
break;
108+
}
109+
case 'der': {
110+
privateKey = { key: keyObjects[0].export({ format: 'der', type: 'pkcs8' }), format: 'der', type: 'pkcs8' };
111+
break;
112+
}
113+
case 'keyObject.unique':
114+
keys = keyObjects;
115+
break;
116+
default:
117+
throw new Error('not implemented');
118+
}
119+
120+
switch (mode) {
121+
case 'sync':
122+
measureSync(n, digest, privateKey, keys);
123+
break;
124+
case 'async':
125+
measureAsync(n, digest, privateKey, keys);
126+
break;
127+
case 'async-parallel':
128+
measureAsyncParallel(n, digest, privateKey, keys);
129+
break;
130+
}
131+
}

‎benchmark/crypto/oneshot-verify.js

+151
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,151 @@
1+
'use strict';
2+
3+
const common = require('../common.js');
4+
const crypto = require('crypto');
5+
const fs = require('fs');
6+
const path = require('path');
7+
const fixtures_keydir = path.resolve(__dirname, '../../test/fixtures/keys/');
8+
9+
function readKey(name) {
10+
return fs.readFileSync(`${fixtures_keydir}/${name}.pem`, 'utf8');
11+
}
12+
13+
function readKeyPair(publicKeyName, privateKeyName) {
14+
return {
15+
publicKey: readKey(publicKeyName),
16+
privateKey: readKey(privateKeyName),
17+
};
18+
}
19+
20+
const keyFixtures = {
21+
ec: readKeyPair('ec_p256_public', 'ec_p256_private'),
22+
rsa: readKeyPair('rsa_public_2048', 'rsa_private_2048'),
23+
ed25519: readKeyPair('ed25519_public', 'ed25519_private'),
24+
};
25+
26+
const data = crypto.randomBytes(256);
27+
28+
let pems;
29+
let keyObjects;
30+
31+
const bench = common.createBenchmark(main, {
32+
keyType: ['rsa', 'ec', 'ed25519'],
33+
mode: ['sync', 'async', 'async-parallel'],
34+
keyFormat: ['pem', 'der', 'jwk', 'keyObject', 'keyObject.unique'],
35+
n: [1e3],
36+
}, {
37+
combinationFilter(p) {
38+
// "keyObject.unique" allows to compare the result with "keyObject" to
39+
// assess whether mutexes over the key material impact the operation
40+
return p.keyFormat !== 'keyObject.unique' ||
41+
(p.keyFormat === 'keyObject.unique' && p.mode === 'async-parallel');
42+
},
43+
});
44+
45+
function measureSync(n, digest, signature, publicKey, keys) {
46+
bench.start();
47+
for (let i = 0; i < n; ++i) {
48+
crypto.verify(
49+
digest,
50+
data,
51+
publicKey || keys[i],
52+
signature);
53+
}
54+
bench.end(n);
55+
}
56+
57+
function measureAsync(n, digest, signature, publicKey, keys) {
58+
let remaining = n;
59+
function done() {
60+
if (--remaining === 0)
61+
bench.end(n);
62+
else
63+
one();
64+
}
65+
66+
function one() {
67+
crypto.verify(
68+
digest,
69+
data,
70+
publicKey || keys[n - remaining],
71+
signature,
72+
done);
73+
}
74+
bench.start();
75+
one();
76+
}
77+
78+
function measureAsyncParallel(n, digest, signature, publicKey, keys) {
79+
let remaining = n;
80+
function done() {
81+
if (--remaining === 0)
82+
bench.end(n);
83+
}
84+
bench.start();
85+
for (let i = 0; i < n; ++i) {
86+
crypto.verify(
87+
digest,
88+
data,
89+
publicKey || keys[i],
90+
signature,
91+
done);
92+
}
93+
}
94+
95+
function main({ n, mode, keyFormat, keyType }) {
96+
pems ||= [...Buffer.alloc(n)].map(() => keyFixtures[keyType].publicKey);
97+
keyObjects ||= pems.map(crypto.createPublicKey);
98+
99+
let publicKey, keys, digest;
100+
101+
switch (keyType) {
102+
case 'rsa':
103+
case 'ec':
104+
digest = 'sha256';
105+
break;
106+
case 'ed25519':
107+
break;
108+
default:
109+
throw new Error('not implemented');
110+
}
111+
112+
switch (keyFormat) {
113+
case 'keyObject':
114+
publicKey = keyObjects[0];
115+
break;
116+
case 'pem':
117+
publicKey = pems[0];
118+
break;
119+
case 'jwk': {
120+
publicKey = { key: keyObjects[0].export({ format: 'jwk' }), format: 'jwk' };
121+
break;
122+
}
123+
case 'der': {
124+
publicKey = { key: keyObjects[0].export({ format: 'der', type: 'spki' }), format: 'der', type: 'spki' };
125+
break;
126+
}
127+
case 'keyObject.unique':
128+
keys = keyObjects;
129+
break;
130+
default:
131+
throw new Error('not implemented');
132+
}
133+
134+
135+
const { privateKey } = keyFixtures[keyType];
136+
const signature = crypto.sign(digest, data, privateKey);
137+
138+
switch (mode) {
139+
case 'sync':
140+
measureSync(n, digest, signature, publicKey, keys);
141+
break;
142+
case 'async':
143+
measureAsync(n, digest, signature, publicKey, keys);
144+
break;
145+
case 'async-parallel':
146+
measureAsyncParallel(n, digest, signature, publicKey, keys);
147+
break;
148+
default:
149+
throw new Error('not implemented');
150+
}
151+
}

0 commit comments

Comments
 (0)
Please sign in to comment.