current commit
260917.14 · crypto: use names for asymmetric key algorithms
'use strict';

const common = require('../common.js');
const { hasOpenSSL, hasFIPS, isBoringSSL } = require('../../test/common/crypto.js');
const fixtures = require('../../test/common/fixtures.js');
const { createPrivateKey, createPublicKey } = require('crypto');

const keys = {
  'rsa': 'rsa_private_2048',
  'rsa-pss': 'rsa_pss_private_2048',
  'p-256': 'ec_p256_private',
  'p-384': 'ec_p384_private',
  'p-521': 'ec_p521_private',
  'ed25519': 'ed25519_private',
  'x25519': 'x25519_private',
};
if (!isBoringSSL) {
  keys.ed448 = 'ed448_private';
  keys.x448 = 'x448_private';
  if (!hasFIPS()) keys['rsa-multiprime'] = 'rsa_private_2048_3_primes';
}
if (hasOpenSSL(3, 5) || isBoringSSL) {
  keys['ml-dsa-44'] = 'ml_dsa_44_private_seed_only';
  keys['ml-dsa-87'] = 'ml_dsa_87_private_seed_only';
  keys['ml-kem-768'] = 'ml_kem_768_private_seed_only';
  keys['ml-kem-1024'] = 'ml_kem_1024_private_seed_only';
}
if (hasOpenSSL(3, 5)) {
  keys['slh-dsa-sha2-128s'] = 'slh_dsa_sha2_128s_private';
  keys['slh-dsa-shake-256s'] = 'slh_dsa_shake_256s_private';
}

const bench = common.createBenchmark(main, {
  // Keep one size per family by default; other fixtures remain available via keyType.
  keyType: ['rsa', 'rsa-pss', 'p-256', 'ed25519', 'x25519',
            'ml-dsa-44', 'ml-kem-768', 'slh-dsa-sha2-128s'].filter((type) => keys[type]),
  operation: ['import', 'export'],
  // PEM can be selected with format=pem; DER covers ASN.1 encoding by default.
  format: ['jwk', 'der', 'raw-public', 'raw-private', 'raw-seed'],
  type: ['public', 'private'],
  n: [1e4],
}, {
  combinationFilter({ keyType, format, type }) {
    if (format === 'jwk') return keyType !== 'rsa-pss';
    if (!format.startsWith('raw-')) return true;
    if (keyType.startsWith('rsa')) return false;
    if (format === 'raw-public') return type === 'public';
    if (format === 'raw-private') return type === 'private' && !keyType.startsWith('ml-');
    return type === 'private' && keyType.startsWith('ml-');
  },
});

function main({ keyType, operation, format, type, n }) {
  const privateKey = createPrivateKey(fixtures.readKey(`${keys[keyType]}.pem`));
  const key = type === 'private' ? privateKey : createPublicKey(privateKey);
  const options = { format };
  if (format === 'pem' || format === 'der') {
    options.type = type === 'private' ? 'pkcs8' : 'spki';
  }
  let run;
  if (operation === 'export') {
    run = () => key.export(options);
  } else {
    const input = { ...options, key: key.export(options) };
    if (format.startsWith('raw-')) {
      input.asymmetricKeyType = key.asymmetricKeyType;
      if (input.asymmetricKeyType === 'ec') {
        input.namedCurve = key.asymmetricKeyDetails.namedCurve;
      }
    }
    const importKey = type === 'private' ? createPrivateKey : createPublicKey;
    run = () => importKey(input);
  }
  // Resolve provider operations and warm the JS path before timing.
  for (let i = 0; i < 100; i++) run();
  bench.start();
  for (let i = 0; i < n; i++) run();
  bench.end(n);
}