/
githubmirror
/
node
Обзор
Документация
Войти
/
githubmirror
/
node
Код
Запросы
0
Пакеты
0
Релизы
0
Аналитика
Безопасность
main
benchmark/crypto/oneshot-sign.js
171 строка
4 KB
Filip Skokan
crypto: wire ML-DSA and ML-KEM for use when using BoringSSL
17 май 2026, 21:18
17 май 2026, 21:18
550f195
Код
Авторство
О чём код?
'use strict'; const common = require('../common.js'); const { hasOpenSSL } = require('../../test/common/crypto.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'); } const keyFixtures = { 'ec': readKey('ec_p256_private'), 'rsa': readKey('rsa_private_2048'), 'ed25519': readKey('ed25519_private'), }; if (hasOpenSSL(3, 5)) { keyFixtures['ml-dsa-44'] = readKey('ml_dsa_44_private'); } else if (process.features.openssl_is_boringssl) { keyFixtures['ml-dsa-44'] = readKey('ml_dsa_44_private_seed_only'); } const data = crypto.randomBytes(256); let pems; let keyObjects; const bench = common.createBenchmark(main, { keyType: Object.keys(keyFixtures), mode: ['sync', 'async', 'async-parallel'], keyFormat: ['pem', 'der', 'jwk', 'keyObject', 'keyObject.unique', 'raw-private', 'raw-seed'], n: [1e3], }, { combinationFilter(p) { // "keyObject.unique" allows to compare the result with "keyObject" to // assess whether mutexes over the key material impact the operation if (p.keyFormat === 'keyObject.unique') return p.mode === 'async-parallel'; // raw-private is not supported for rsa and ml-dsa if (p.keyFormat === 'raw-private') return p.keyType !== 'rsa' && !p.keyType.startsWith('ml-'); // raw-seed is only supported for ml-dsa if (p.keyFormat === 'raw-seed') return p.keyType.startsWith('ml-'); return true; }, }); 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); // Warm up OpenSSL's provider operation cache for each key object for (const keyObject of keyObjects) { crypto.sign(keyType === 'rsa' || keyType === 'ec' ? 'sha256' : null, data, keyObject); } let privateKey, keys, digest; switch (keyType) { case 'rsa': case 'ec': digest = 'sha256'; break; case 'ed25519': case 'ml-dsa-44': 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 'raw-private': { const exportedKey = keyObjects[0].export({ format: 'raw-private' }); const keyOpts = { key: exportedKey, format: 'raw-private', asymmetricKeyType: keyType }; if (keyType === 'ec') keyOpts.namedCurve = keyObjects[0].asymmetricKeyDetails.namedCurve; privateKey = keyOpts; break; } case 'raw-seed': { privateKey = { key: keyObjects[0].export({ format: 'raw-seed' }), format: 'raw-seed', asymmetricKeyType: keyType, }; 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; } }