Upload Kmake

This commit is contained in:
Gorochu
2026-05-26 23:36:42 -07:00
parent ba051b2f74
commit 555ec72358
41615 changed files with 13344630 additions and 1 deletions

View File

@ -0,0 +1,39 @@
'use strict';
const common = require('../common.js');
const crypto = require('crypto');
const keylen = { 'aes-128-gcm': 16, 'aes-192-gcm': 24, 'aes-256-gcm': 32 };
const bench = common.createBenchmark(main, {
n: [2500],
cipher: ['aes-128-gcm', 'aes-192-gcm', 'aes-256-gcm'],
len: [1024, 4 * 1024, 16 * 1024, 64 * 1024, 256 * 1024, 1024 * 1024],
});
function main({ n, len, cipher }) {
const message = Buffer.alloc(len, 'b');
const key = crypto.randomBytes(keylen[cipher]);
const iv = crypto.randomBytes(12);
const associate_data = Buffer.alloc(16, 'z');
bench.start();
AEAD_Bench(cipher, message, associate_data, key, iv, n, len);
}
function AEAD_Bench(cipher, message, associate_data, key, iv, n, len) {
const written = n * len;
const bits = written * 8;
const mbits = bits / (1024 * 1024);
for (let i = 0; i < n; i++) {
const alice = crypto.createCipheriv(cipher, key, iv);
alice.setAAD(associate_data);
const enc = alice.update(message);
alice.final();
const tag = alice.getAuthTag();
const bob = crypto.createDecipheriv(cipher, key, iv);
bob.setAuthTag(tag);
bob.setAAD(associate_data);
bob.update(enc);
bob.final();
}
bench.end(mbits);
}

View File

@ -0,0 +1,22 @@
'use strict';
const common = require('../common.js');
const { createHash } = require('crypto');
const assert = require('assert');
const bench = common.createBenchmark(main, {
n: [1e5],
});
function main({ n }) {
const array = [];
for (let i = 0; i < n; ++i) {
array.push(null);
}
bench.start();
for (let i = 0; i < n; ++i) {
array[i] = createHash('sha1');
}
bench.end(n);
assert.strictEqual(typeof array[n - 1], 'object');
}

View File

@ -0,0 +1,85 @@
'use strict';
const common = require('../common.js');
const crypto = require('crypto');
const fs = require('fs');
const path = require('path');
const fixtures_keydir = path.resolve(__dirname, '../../test/fixtures/keys/');
function readKey(name) {
return fs.readFileSync(`${fixtures_keydir}/${name}.pem`, 'utf8');
}
function readKeyPair(publicKeyName, privateKeyName) {
return {
publicKey: readKey(publicKeyName),
privateKey: readKey(privateKeyName),
};
}
const keyFixtures = {
ec: readKeyPair('ec_p256_public', 'ec_p256_private'),
rsa: readKeyPair('rsa_public_2048', 'rsa_private_2048'),
ed25519: readKeyPair('ed25519_public', 'ed25519_private'),
};
const bench = common.createBenchmark(main, {
keyType: ['rsa', 'ec', 'ed25519'],
keyFormat: ['pkcs8', 'spki', 'der-pkcs8', 'der-spki', 'jwk-public', 'jwk-private'],
n: [1e3],
});
function measure(n, fn, input) {
bench.start();
for (let i = 0; i < n; ++i) {
fn(input);
}
bench.end(n);
}
function main({ n, keyFormat, keyType }) {
const keyPair = {
publicKey: crypto.createPublicKey(keyFixtures[keyType].publicKey),
privateKey: crypto.createPrivateKey(keyFixtures[keyType].privateKey),
};
let key, fn;
switch (keyFormat) {
case 'spki':
key = keyPair.publicKey.export({ format: 'pem', type: 'spki' });
fn = crypto.createPublicKey;
break;
case 'pkcs8':
key = keyPair.privateKey.export({ format: 'pem', type: 'pkcs8' });
fn = crypto.createPrivateKey;
break;
case 'der-spki': {
const options = { format: 'der', type: 'spki' };
key = { ...options, key: keyPair.publicKey.export(options) };
fn = crypto.createPublicKey;
break;
}
case 'der-pkcs8': {
const options = { format: 'der', type: 'pkcs8' };
key = { ...options, key: keyPair.privateKey.export(options) };
fn = crypto.createPrivateKey;
break;
}
case 'jwk-public': {
const options = { format: 'jwk' };
key = { ...options, key: keyPair.publicKey.export(options) };
fn = crypto.createPublicKey;
break;
}
case 'jwk-private': {
const options = { format: 'jwk' };
key = { ...options, key: keyPair.privateKey.export(options) };
fn = crypto.createPrivateKey;
break;
}
default:
throw new Error('not implemented');
}
measure(n, fn, key);
}

View File

@ -0,0 +1,21 @@
'use strict';
const common = require('../common.js');
const bench = common.createBenchmark(main, {
n: [1, 500000],
v: ['crypto', 'tls'],
});
function main({ n, v }) {
const method = require(v).getCiphers;
let i = 0;
// First call to getCiphers will dominate the results
if (n > 1) {
for (; i < n; i++)
method();
}
bench.start();
for (i = 0; i < n; i++) method();
bench.end(n);
}

View File

@ -0,0 +1,78 @@
// Throughput benchmark
// creates a single hasher, then pushes a bunch of data through it
'use strict';
const common = require('../common.js');
const crypto = require('crypto');
const bench = common.createBenchmark(main, {
writes: [500],
algo: [ 'sha256', 'md5' ],
type: ['asc', 'utf', 'buf'],
out: ['hex', 'binary', 'buffer'],
len: [2, 1024, 102400, 1024 * 1024],
api: ['legacy', 'stream'],
});
function main({ api, type, len, out, writes, algo }) {
if (api === 'stream' && /^v0\.[0-8]\./.test(process.version)) {
console.error('Crypto streams not available until v0.10');
// Use the legacy, just so that we can compare them.
api = 'legacy';
}
let message;
let encoding;
switch (type) {
case 'asc':
message = 'a'.repeat(len);
encoding = 'ascii';
break;
case 'utf':
message = 'ü'.repeat(len / 2);
encoding = 'utf8';
break;
case 'buf':
message = Buffer.alloc(len, 'b');
break;
default:
throw new Error(`unknown message type: ${type}`);
}
const fn = api === 'stream' ? streamWrite : legacyWrite;
bench.start();
fn(algo, message, encoding, writes, len, out);
}
function legacyWrite(algo, message, encoding, writes, len, outEnc) {
const written = writes * len;
const bits = written * 8;
const gbits = bits / (1024 * 1024 * 1024);
while (writes-- > 0) {
const h = crypto.createHash(algo);
h.update(message, encoding);
h.digest(outEnc);
}
bench.end(gbits);
}
function streamWrite(algo, message, encoding, writes, len, outEnc) {
const written = writes * len;
const bits = written * 8;
const gbits = bits / (1024 * 1024 * 1024);
while (writes-- > 0) {
const h = crypto.createHash(algo);
if (outEnc !== 'buffer')
h.setEncoding(outEnc);
h.write(message, encoding);
h.end();
h.read();
}
bench.end(gbits);
}

View File

@ -0,0 +1,73 @@
// Throughput benchmark
// creates a single hasher, then pushes a bunch of data through it
'use strict';
const common = require('../common.js');
const crypto = require('crypto');
const bench = common.createBenchmark(main, {
writes: [500],
algo: ['sha1', 'sha256', 'sha512'],
type: ['asc', 'utf', 'buf'],
len: [2, 1024, 102400, 1024 * 1024],
api: ['legacy', 'stream'],
});
function main({ api, type, len, algo, writes }) {
if (api === 'stream' && /^v0\.[0-8]\./.test(process.version)) {
console.error('Crypto streams not available until v0.10');
// Use the legacy, just so that we can compare them.
api = 'legacy';
}
let message;
let encoding;
switch (type) {
case 'asc':
message = 'a'.repeat(len);
encoding = 'ascii';
break;
case 'utf':
message = 'ü'.repeat(len / 2);
encoding = 'utf8';
break;
case 'buf':
message = Buffer.alloc(len, 'b');
break;
default:
throw new Error(`unknown message type: ${type}`);
}
const fn = api === 'stream' ? streamWrite : legacyWrite;
bench.start();
fn(algo, message, encoding, writes, len);
}
function legacyWrite(algo, message, encoding, writes, len) {
const written = writes * len;
const bits = written * 8;
const gbits = bits / (1024 * 1024 * 1024);
const h = crypto.createHash(algo);
while (writes-- > 0)
h.update(message, encoding);
h.digest();
bench.end(gbits);
}
function streamWrite(algo, message, encoding, writes, len) {
const written = writes * len;
const bits = written * 8;
const gbits = bits / (1024 * 1024 * 1024);
const h = crypto.createHash(algo);
while (writes-- > 0)
h.write(message, encoding);
h.end();
h.read();
bench.end(gbits);
}

44
benchmark/crypto/hkdf.js Normal file
View File

@ -0,0 +1,44 @@
'use strict';
const common = require('../common.js');
const assert = require('assert');
const {
hkdf,
hkdfSync,
} = require('crypto');
const bench = common.createBenchmark(main, {
sync: [0, 1],
size: [10, 64, 1024],
key: ['a', 'secret', 'this-is-a-much-longer-secret'],
salt: ['', 'salt'],
info: ['', 'info'],
hash: ['sha256', 'sha512'],
n: [1e4],
});
function measureSync(n, size, salt, info, hash, key) {
bench.start();
for (let i = 0; i < n; ++i)
hkdfSync(hash, key, salt, info, size);
bench.end(n);
}
function measureAsync(n, size, salt, info, hash, key) {
let remaining = n;
function done(err) {
assert.ifError(err);
if (--remaining === 0)
bench.end(n);
}
bench.start();
for (let i = 0; i < n; ++i)
hkdf(hash, key, salt, info, size, done);
}
function main({ n, sync, size, salt, info, hash, key }) {
if (sync)
measureSync(n, size, salt, info, hash, key);
else
measureAsync(n, size, salt, info, hash, key);
}

View File

@ -0,0 +1,71 @@
'use strict';
const common = require('../common.js');
const assert = require('assert');
const {
generateKeyPair,
generateKeyPairSync,
} = require('crypto');
const bench = common.createBenchmark(main, {
method: ['rsaSync', 'rsaAsync', 'dsaSync', 'dsaAsync'],
n: [1e2],
});
const methods = {
rsaSync(n) {
bench.start();
for (let i = 0; i < n; ++i) {
generateKeyPairSync('rsa', {
modulusLength: 1024,
publicExponent: 0x10001,
});
}
bench.end(n);
},
rsaAsync(n) {
let remaining = n;
function done(err) {
assert.ifError(err);
if (--remaining === 0)
bench.end(n);
}
bench.start();
for (let i = 0; i < n; ++i)
generateKeyPair('rsa', {
modulusLength: 512,
publicExponent: 0x10001,
}, done);
},
dsaSync(n) {
bench.start();
for (let i = 0; i < n; ++i) {
generateKeyPairSync('dsa', {
modulusLength: 1024,
divisorLength: 160,
});
}
bench.end(n);
},
dsaAsync(n) {
let remaining = n;
function done(err) {
assert.ifError(err);
if (--remaining === 0)
bench.end(n);
}
bench.start();
for (let i = 0; i < n; ++i)
generateKeyPair('dsa', {
modulusLength: 1024,
divisorLength: 160,
}, done);
},
};
function main({ n, method }) {
methods[method](n);
}

View File

@ -0,0 +1,42 @@
'use strict';
const common = require('../common.js');
const { createHash, hash } = require('crypto');
const path = require('path');
const filepath = path.resolve(__dirname, '../../test/fixtures/snapshot/typescript.js');
const fs = require('fs');
const assert = require('assert');
const bench = common.createBenchmark(main, {
length: [1000, 100_000],
method: ['md5', 'sha1', 'sha256'],
type: ['string', 'buffer'],
n: [100_000, 1000],
}, {
combinationFilter: ({ length, n }) => {
return length * n <= 100_000 * 1000;
},
});
function main({ length, type, method, n }) {
let data = fs.readFileSync(filepath);
if (type === 'string') {
data = data.toString().slice(0, length);
} else {
data = Uint8Array.prototype.slice.call(data, 0, length);
}
const oneshotHash = hash ?
(method, input) => hash(method, input, 'hex') :
(method, input) => createHash(method).update(input).digest('hex');
const array = [];
for (let i = 0; i < n; i++) {
array.push(null);
}
bench.start();
for (let i = 0; i < n; i++) {
array[i] = oneshotHash(method, data);
}
bench.end(n);
assert.strictEqual(typeof array[n - 1], 'string');
}

View File

@ -0,0 +1,131 @@
'use strict';
const common = require('../common.js');
const crypto = require('crypto');
const fs = require('fs');
const path = require('path');
const fixtures_keydir = path.resolve(__dirname, '../../test/fixtures/keys/');
const keyFixtures = {
ec: fs.readFileSync(`${fixtures_keydir}/ec_p256_private.pem`, 'utf-8'),
rsa: fs.readFileSync(`${fixtures_keydir}/rsa_private_2048.pem`, 'utf-8'),
ed25519: fs.readFileSync(`${fixtures_keydir}/ed25519_private.pem`, 'utf-8'),
};
const data = crypto.randomBytes(256);
let pems;
let keyObjects;
const bench = common.createBenchmark(main, {
keyType: ['rsa', 'ec', 'ed25519'],
mode: ['sync', 'async', 'async-parallel'],
keyFormat: ['pem', 'der', 'jwk', 'keyObject', 'keyObject.unique'],
n: [1e3],
}, {
combinationFilter(p) {
// "keyObject.unique" allows to compare the result with "keyObject" to
// assess whether mutexes over the key material impact the operation
return p.keyFormat !== 'keyObject.unique' ||
(p.keyFormat === 'keyObject.unique' && p.mode === 'async-parallel');
},
});
function measureSync(n, digest, privateKey, keys) {
bench.start();
for (let i = 0; i < n; ++i) {
crypto.sign(
digest,
data,
privateKey || keys[i]);
}
bench.end(n);
}
function measureAsync(n, digest, privateKey, keys) {
let remaining = n;
function done() {
if (--remaining === 0)
bench.end(n);
else
one();
}
function one() {
crypto.sign(
digest,
data,
privateKey || keys[n - remaining],
done);
}
bench.start();
one();
}
function measureAsyncParallel(n, digest, privateKey, keys) {
let remaining = n;
function done() {
if (--remaining === 0)
bench.end(n);
}
bench.start();
for (let i = 0; i < n; ++i) {
crypto.sign(
digest,
data,
privateKey || keys[i],
done);
}
}
function main({ n, mode, keyFormat, keyType }) {
pems ||= [...Buffer.alloc(n)].map(() => keyFixtures[keyType]);
keyObjects ||= pems.map(crypto.createPrivateKey);
let privateKey, keys, digest;
switch (keyType) {
case 'rsa':
case 'ec':
digest = 'sha256';
break;
case 'ed25519':
break;
default:
throw new Error('not implemented');
}
switch (keyFormat) {
case 'keyObject':
privateKey = keyObjects[0];
break;
case 'pem':
privateKey = pems[0];
break;
case 'jwk': {
privateKey = { key: keyObjects[0].export({ format: 'jwk' }), format: 'jwk' };
break;
}
case 'der': {
privateKey = { key: keyObjects[0].export({ format: 'der', type: 'pkcs8' }), format: 'der', type: 'pkcs8' };
break;
}
case 'keyObject.unique':
keys = keyObjects;
break;
default:
throw new Error('not implemented');
}
switch (mode) {
case 'sync':
measureSync(n, digest, privateKey, keys);
break;
case 'async':
measureAsync(n, digest, privateKey, keys);
break;
case 'async-parallel':
measureAsyncParallel(n, digest, privateKey, keys);
break;
}
}

View File

@ -0,0 +1,151 @@
'use strict';
const common = require('../common.js');
const crypto = require('crypto');
const fs = require('fs');
const path = require('path');
const fixtures_keydir = path.resolve(__dirname, '../../test/fixtures/keys/');
function readKey(name) {
return fs.readFileSync(`${fixtures_keydir}/${name}.pem`, 'utf8');
}
function readKeyPair(publicKeyName, privateKeyName) {
return {
publicKey: readKey(publicKeyName),
privateKey: readKey(privateKeyName),
};
}
const keyFixtures = {
ec: readKeyPair('ec_p256_public', 'ec_p256_private'),
rsa: readKeyPair('rsa_public_2048', 'rsa_private_2048'),
ed25519: readKeyPair('ed25519_public', 'ed25519_private'),
};
const data = crypto.randomBytes(256);
let pems;
let keyObjects;
const bench = common.createBenchmark(main, {
keyType: ['rsa', 'ec', 'ed25519'],
mode: ['sync', 'async', 'async-parallel'],
keyFormat: ['pem', 'der', 'jwk', 'keyObject', 'keyObject.unique'],
n: [1e3],
}, {
combinationFilter(p) {
// "keyObject.unique" allows to compare the result with "keyObject" to
// assess whether mutexes over the key material impact the operation
return p.keyFormat !== 'keyObject.unique' ||
(p.keyFormat === 'keyObject.unique' && p.mode === 'async-parallel');
},
});
function measureSync(n, digest, signature, publicKey, keys) {
bench.start();
for (let i = 0; i < n; ++i) {
crypto.verify(
digest,
data,
publicKey || keys[i],
signature);
}
bench.end(n);
}
function measureAsync(n, digest, signature, publicKey, keys) {
let remaining = n;
function done() {
if (--remaining === 0)
bench.end(n);
else
one();
}
function one() {
crypto.verify(
digest,
data,
publicKey || keys[n - remaining],
signature,
done);
}
bench.start();
one();
}
function measureAsyncParallel(n, digest, signature, publicKey, keys) {
let remaining = n;
function done() {
if (--remaining === 0)
bench.end(n);
}
bench.start();
for (let i = 0; i < n; ++i) {
crypto.verify(
digest,
data,
publicKey || keys[i],
signature,
done);
}
}
function main({ n, mode, keyFormat, keyType }) {
pems ||= [...Buffer.alloc(n)].map(() => keyFixtures[keyType].publicKey);
keyObjects ||= pems.map(crypto.createPublicKey);
let publicKey, keys, digest;
switch (keyType) {
case 'rsa':
case 'ec':
digest = 'sha256';
break;
case 'ed25519':
break;
default:
throw new Error('not implemented');
}
switch (keyFormat) {
case 'keyObject':
publicKey = keyObjects[0];
break;
case 'pem':
publicKey = pems[0];
break;
case 'jwk': {
publicKey = { key: keyObjects[0].export({ format: 'jwk' }), format: 'jwk' };
break;
}
case 'der': {
publicKey = { key: keyObjects[0].export({ format: 'der', type: 'spki' }), format: 'der', type: 'spki' };
break;
}
case 'keyObject.unique':
keys = keyObjects;
break;
default:
throw new Error('not implemented');
}
const { privateKey } = keyFixtures[keyType];
const signature = crypto.sign(digest, data, privateKey);
switch (mode) {
case 'sync':
measureSync(n, digest, signature, publicKey, keys);
break;
case 'async':
measureAsync(n, digest, signature, publicKey, keys);
break;
case 'async-parallel':
measureAsyncParallel(n, digest, signature, publicKey, keys);
break;
default:
throw new Error('not implemented');
}
}

View File

@ -0,0 +1,23 @@
'use strict';
const common = require('../common.js');
const { randomBytes } = require('crypto');
// Add together with imports
const assert = require('assert');
let _cryptoResult;
const bench = common.createBenchmark(main, {
size: [64, 1024, 8 * 1024, 16 * 1024],
n: [1e5],
});
function main({ n, size }) {
bench.start();
for (let i = 0; i < n; ++i)
_cryptoResult = randomBytes(size);
bench.end(n);
// Avoid V8 deadcode (elimination)
assert.ok(_cryptoResult);
}

View File

@ -0,0 +1,38 @@
'use strict';
const common = require('../common.js');
const { randomInt } = require('crypto');
const bench = common.createBenchmark(main, {
mode: ['sync', 'async-sequential', 'async-parallel'],
min: [-(2 ** 47) + 1, -10_000, -100],
max: [100, 10_000, 2 ** 47],
n: [1e3, 1e5],
});
function main({ mode, min, max, n }) {
if (mode === 'sync') {
bench.start();
for (let i = 0; i < n; i++)
randomInt(min, max);
bench.end(n);
} else if (mode === 'async-sequential') {
bench.start();
(function next(i) {
if (i === n)
return bench.end(n);
randomInt(min, max, () => {
next(i + 1);
});
})(0);
} else {
bench.start();
let done = 0;
for (let i = 0; i < n; i++) {
randomInt(min, max, () => {
if (++done === n)
bench.end(n);
});
}
}
}

View File

@ -0,0 +1,17 @@
'use strict';
const common = require('../common.js');
const { randomUUID } = require('crypto');
const bench = common.createBenchmark(main, {
n: [1e7],
disableEntropyCache: [0, 1],
});
function main({ n, disableEntropyCache }) {
disableEntropyCache = !!disableEntropyCache;
bench.start();
for (let i = 0; i < n; ++i)
randomUUID({ disableEntropyCache });
bench.end(n);
}

View File

@ -0,0 +1,44 @@
'use strict';
// Throughput benchmark in signing and verifying
const common = require('../common.js');
const crypto = require('crypto');
const fs = require('fs');
const path = require('path');
const fixtures_keydir = path.resolve(__dirname, '../../test/fixtures/keys/');
const keylen_list = ['2048', '4096'];
const RSA_PublicPem = {};
const RSA_PrivatePem = {};
keylen_list.forEach((key) => {
RSA_PublicPem[key] =
fs.readFileSync(`${fixtures_keydir}/rsa_public_${key}.pem`);
RSA_PrivatePem[key] =
fs.readFileSync(`${fixtures_keydir}/rsa_private_${key}.pem`);
});
const bench = common.createBenchmark(main, {
n: [500],
keylen: keylen_list,
len: [16, 32, 64],
});
function main({ len, algo, keylen, n }) {
const message = Buffer.alloc(len, 'b');
bench.start();
StreamWrite(algo, keylen, message, n, len);
}
function StreamWrite(algo, keylen, message, n, len) {
const written = n * len;
const bits = written * 8;
const kbits = bits / (1024);
const privateKey = RSA_PrivatePem[keylen];
const publicKey = RSA_PublicPem[keylen];
for (let i = 0; i < n; i++) {
const enc = crypto.privateEncrypt(privateKey, message);
crypto.publicDecrypt(publicKey, enc);
}
bench.end(kbits);
}

View File

@ -0,0 +1,51 @@
'use strict';
// Throughput benchmark in signing and verifying
const common = require('../common.js');
const crypto = require('crypto');
const fs = require('fs');
const path = require('path');
const fixtures_keydir = path.resolve(__dirname, '../../test/fixtures/keys/');
const keylen_list = ['2048'];
const RSA_PublicPem = {};
const RSA_PrivatePem = {};
keylen_list.forEach((key) => {
RSA_PublicPem[key] =
fs.readFileSync(`${fixtures_keydir}/rsa_public_${key}.pem`);
RSA_PrivatePem[key] =
fs.readFileSync(`${fixtures_keydir}/rsa_private_${key}.pem`);
});
const bench = common.createBenchmark(main, {
writes: [500],
algo: ['SHA1', 'SHA224', 'SHA256', 'SHA384', 'SHA512'],
keylen: keylen_list,
len: [1024, 102400, 2 * 102400, 3 * 102400, 1024 * 1024],
});
function main({ len, algo, keylen, writes }) {
const message = Buffer.alloc(len, 'b');
bench.start();
StreamWrite(algo, keylen, message, writes, len);
}
function StreamWrite(algo, keylen, message, writes, len) {
const written = writes * len;
const bits = written * 8;
const kbits = bits / (1024);
const privateKey = RSA_PrivatePem[keylen];
const s = crypto.createSign(algo);
const v = crypto.createVerify(algo);
while (writes-- > 0) {
s.update(message);
v.update(message);
}
s.sign(privateKey, 'binary');
s.end();
v.end();
bench.end(kbits);
}

View File

@ -0,0 +1,22 @@
'use strict';
const common = require('../common.js');
const assert = require('node:assert');
const { randomBytes, timingSafeEqual } = require('node:crypto');
const bench = common.createBenchmark(main, {
n: [1e5],
bufferSize: [10, 100, 200, 2_100, 22_023],
});
function main({ n, bufferSize }) {
const bufs = [randomBytes(bufferSize), randomBytes(bufferSize)];
bench.start();
let count = 0;
for (let i = 0; i < n; i++) {
const ret = timingSafeEqual(bufs[i % 2], bufs[1]);
if (ret) count++;
}
bench.end(n);
assert.strictEqual(count, Math.floor(n / 2));
}

View File

@ -0,0 +1,53 @@
'use strict';
const common = require('../common.js');
const { createHash } = require('crypto');
const { subtle } = globalThis.crypto;
const bench = common.createBenchmark(main, {
sync: ['createHash', 'subtle'],
data: [10, 20, 50, 100],
method: ['SHA-1', 'SHA-256', 'SHA-384', 'SHA-512'],
n: [1e5],
});
const kMethods = {
'SHA-1': 'sha1',
'SHA-256': 'sha256',
'SHA-384': 'sha384',
'SHA-512': 'sha512',
};
// This benchmark only looks at clock time and ignores factors
// such as event loop delay, event loop utilization, and memory.
// As such, it is expected that the synchronous legacy method
// will always be faster in clock time.
function measureLegacy(n, data, method) {
method = kMethods[method];
bench.start();
for (let i = 0; i < n; ++i) {
createHash(method).update(data).digest();
}
bench.end(n);
}
function measureSubtle(n, data, method) {
const ec = new TextEncoder();
data = ec.encode(data);
const jobs = new Array(n);
bench.start();
for (let i = 0; i < n; i++)
jobs[i] = subtle.digest(method, data);
Promise.all(jobs).then(() => bench.end(n)).catch((err) => {
process.nextTick(() => { throw err; });
});
}
function main({ n, sync, data, method }) {
data = globalThis.crypto.getRandomValues(Buffer.alloc(data));
switch (sync) {
case 'createHash': return measureLegacy(n, data, method);
case 'subtle': return measureSubtle(n, data, method);
}
}