11cb0ef41Sopenharmony_ci'use strict';
21cb0ef41Sopenharmony_ci
31cb0ef41Sopenharmony_ciconst common = require('../common.js');
41cb0ef41Sopenharmony_ciconst crypto = require('crypto');
51cb0ef41Sopenharmony_ciconst fs = require('fs');
61cb0ef41Sopenharmony_ciconst path = require('path');
71cb0ef41Sopenharmony_ciconst fixtures_keydir = path.resolve(__dirname, '../../test/fixtures/keys/');
81cb0ef41Sopenharmony_ci
91cb0ef41Sopenharmony_ciconst keyFixtures = {
101cb0ef41Sopenharmony_ci  ec: fs.readFileSync(`${fixtures_keydir}/ec_p256_private.pem`, 'utf-8'),
111cb0ef41Sopenharmony_ci  rsa: fs.readFileSync(`${fixtures_keydir}/rsa_private_2048.pem`, 'utf-8'),
121cb0ef41Sopenharmony_ci  ed25519: fs.readFileSync(`${fixtures_keydir}/ed25519_private.pem`, 'utf-8'),
131cb0ef41Sopenharmony_ci};
141cb0ef41Sopenharmony_ci
151cb0ef41Sopenharmony_ciconst data = crypto.randomBytes(256);
161cb0ef41Sopenharmony_ci
171cb0ef41Sopenharmony_cilet pems;
181cb0ef41Sopenharmony_cilet keyObjects;
191cb0ef41Sopenharmony_ci
201cb0ef41Sopenharmony_ciconst bench = common.createBenchmark(main, {
211cb0ef41Sopenharmony_ci  keyType: ['rsa', 'ec', 'ed25519'],
221cb0ef41Sopenharmony_ci  mode: ['sync', 'async', 'async-parallel'],
231cb0ef41Sopenharmony_ci  keyFormat: ['pem', 'der', 'jwk', 'keyObject', 'keyObject.unique'],
241cb0ef41Sopenharmony_ci  n: [1e3],
251cb0ef41Sopenharmony_ci}, {
261cb0ef41Sopenharmony_ci  combinationFilter(p) {
271cb0ef41Sopenharmony_ci    // "keyObject.unique" allows to compare the result with "keyObject" to
281cb0ef41Sopenharmony_ci    // assess whether mutexes over the key material impact the operation
291cb0ef41Sopenharmony_ci    return p.keyFormat !== 'keyObject.unique' ||
301cb0ef41Sopenharmony_ci      (p.keyFormat === 'keyObject.unique' && p.mode === 'async-parallel');
311cb0ef41Sopenharmony_ci  },
321cb0ef41Sopenharmony_ci});
331cb0ef41Sopenharmony_ci
341cb0ef41Sopenharmony_cifunction measureSync(n, digest, privateKey, keys) {
351cb0ef41Sopenharmony_ci  bench.start();
361cb0ef41Sopenharmony_ci  for (let i = 0; i < n; ++i) {
371cb0ef41Sopenharmony_ci    crypto.sign(
381cb0ef41Sopenharmony_ci      digest,
391cb0ef41Sopenharmony_ci      data,
401cb0ef41Sopenharmony_ci      privateKey || keys[i]);
411cb0ef41Sopenharmony_ci  }
421cb0ef41Sopenharmony_ci  bench.end(n);
431cb0ef41Sopenharmony_ci}
441cb0ef41Sopenharmony_ci
451cb0ef41Sopenharmony_cifunction measureAsync(n, digest, privateKey, keys) {
461cb0ef41Sopenharmony_ci  let remaining = n;
471cb0ef41Sopenharmony_ci  function done() {
481cb0ef41Sopenharmony_ci    if (--remaining === 0)
491cb0ef41Sopenharmony_ci      bench.end(n);
501cb0ef41Sopenharmony_ci    else
511cb0ef41Sopenharmony_ci      one();
521cb0ef41Sopenharmony_ci  }
531cb0ef41Sopenharmony_ci
541cb0ef41Sopenharmony_ci  function one() {
551cb0ef41Sopenharmony_ci    crypto.sign(
561cb0ef41Sopenharmony_ci      digest,
571cb0ef41Sopenharmony_ci      data,
581cb0ef41Sopenharmony_ci      privateKey || keys[n - remaining],
591cb0ef41Sopenharmony_ci      done);
601cb0ef41Sopenharmony_ci  }
611cb0ef41Sopenharmony_ci  bench.start();
621cb0ef41Sopenharmony_ci  one();
631cb0ef41Sopenharmony_ci}
641cb0ef41Sopenharmony_ci
651cb0ef41Sopenharmony_cifunction measureAsyncParallel(n, digest, privateKey, keys) {
661cb0ef41Sopenharmony_ci  let remaining = n;
671cb0ef41Sopenharmony_ci  function done() {
681cb0ef41Sopenharmony_ci    if (--remaining === 0)
691cb0ef41Sopenharmony_ci      bench.end(n);
701cb0ef41Sopenharmony_ci  }
711cb0ef41Sopenharmony_ci  bench.start();
721cb0ef41Sopenharmony_ci  for (let i = 0; i < n; ++i) {
731cb0ef41Sopenharmony_ci    crypto.sign(
741cb0ef41Sopenharmony_ci      digest,
751cb0ef41Sopenharmony_ci      data,
761cb0ef41Sopenharmony_ci      privateKey || keys[i],
771cb0ef41Sopenharmony_ci      done);
781cb0ef41Sopenharmony_ci  }
791cb0ef41Sopenharmony_ci}
801cb0ef41Sopenharmony_ci
811cb0ef41Sopenharmony_cifunction main({ n, mode, keyFormat, keyType }) {
821cb0ef41Sopenharmony_ci  pems ||= [...Buffer.alloc(n)].map(() => keyFixtures[keyType]);
831cb0ef41Sopenharmony_ci  keyObjects ||= pems.map(crypto.createPrivateKey);
841cb0ef41Sopenharmony_ci
851cb0ef41Sopenharmony_ci  let privateKey, keys, digest;
861cb0ef41Sopenharmony_ci
871cb0ef41Sopenharmony_ci  switch (keyType) {
881cb0ef41Sopenharmony_ci    case 'rsa':
891cb0ef41Sopenharmony_ci    case 'ec':
901cb0ef41Sopenharmony_ci      digest = 'sha256';
911cb0ef41Sopenharmony_ci      break;
921cb0ef41Sopenharmony_ci    case 'ed25519':
931cb0ef41Sopenharmony_ci      break;
941cb0ef41Sopenharmony_ci    default:
951cb0ef41Sopenharmony_ci      throw new Error('not implemented');
961cb0ef41Sopenharmony_ci  }
971cb0ef41Sopenharmony_ci
981cb0ef41Sopenharmony_ci  switch (keyFormat) {
991cb0ef41Sopenharmony_ci    case 'keyObject':
1001cb0ef41Sopenharmony_ci      privateKey = keyObjects[0];
1011cb0ef41Sopenharmony_ci      break;
1021cb0ef41Sopenharmony_ci    case 'pem':
1031cb0ef41Sopenharmony_ci      privateKey = pems[0];
1041cb0ef41Sopenharmony_ci      break;
1051cb0ef41Sopenharmony_ci    case 'jwk': {
1061cb0ef41Sopenharmony_ci      privateKey = { key: keyObjects[0].export({ format: 'jwk' }), format: 'jwk' };
1071cb0ef41Sopenharmony_ci      break;
1081cb0ef41Sopenharmony_ci    }
1091cb0ef41Sopenharmony_ci    case 'der': {
1101cb0ef41Sopenharmony_ci      privateKey = { key: keyObjects[0].export({ format: 'der', type: 'pkcs8' }), format: 'der', type: 'pkcs8' };
1111cb0ef41Sopenharmony_ci      break;
1121cb0ef41Sopenharmony_ci    }
1131cb0ef41Sopenharmony_ci    case 'keyObject.unique':
1141cb0ef41Sopenharmony_ci      keys = keyObjects;
1151cb0ef41Sopenharmony_ci      break;
1161cb0ef41Sopenharmony_ci    default:
1171cb0ef41Sopenharmony_ci      throw new Error('not implemented');
1181cb0ef41Sopenharmony_ci  }
1191cb0ef41Sopenharmony_ci
1201cb0ef41Sopenharmony_ci  switch (mode) {
1211cb0ef41Sopenharmony_ci    case 'sync':
1221cb0ef41Sopenharmony_ci      measureSync(n, digest, privateKey, keys);
1231cb0ef41Sopenharmony_ci      break;
1241cb0ef41Sopenharmony_ci    case 'async':
1251cb0ef41Sopenharmony_ci      measureAsync(n, digest, privateKey, keys);
1261cb0ef41Sopenharmony_ci      break;
1271cb0ef41Sopenharmony_ci    case 'async-parallel':
1281cb0ef41Sopenharmony_ci      measureAsyncParallel(n, digest, privateKey, keys);
1291cb0ef41Sopenharmony_ci      break;
1301cb0ef41Sopenharmony_ci  }
1311cb0ef41Sopenharmony_ci}
132