1'use strict';
2
3const common = require('../common.js');
4const crypto = require('crypto');
5const fs = require('fs');
6const path = require('path');
7const fixtures_keydir = path.resolve(__dirname, '../../test/fixtures/keys/');
8
9function readKey(name) {
10  return fs.readFileSync(`${fixtures_keydir}/${name}.pem`, 'utf8');
11}
12
13function readKeyPair(publicKeyName, privateKeyName) {
14  return {
15    publicKey: readKey(publicKeyName),
16    privateKey: readKey(privateKeyName),
17  };
18}
19
20const 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
26const bench = common.createBenchmark(main, {
27  keyType: ['rsa', 'ec', 'ed25519'],
28  keyFormat: ['pkcs8', 'spki', 'der-pkcs8', 'der-spki', 'jwk-public', 'jwk-private'],
29  n: [1e3],
30});
31
32function measure(n, fn, input) {
33  bench.start();
34  for (let i = 0; i < n; ++i) {
35    fn(input);
36  }
37  bench.end(n);
38}
39
40function main({ n, keyFormat, keyType }) {
41  const keyPair = {
42    publicKey: crypto.createPublicKey(keyFixtures[keyType].publicKey),
43    privateKey: crypto.createPrivateKey(keyFixtures[keyType].privateKey),
44  };
45
46  let key, fn;
47  switch (keyFormat) {
48    case 'spki':
49      key = keyPair.publicKey.export({ format: 'pem', type: 'spki' });
50      fn = crypto.createPublicKey;
51      break;
52    case 'pkcs8':
53      key = keyPair.privateKey.export({ format: 'pem', type: 'pkcs8' });
54      fn = crypto.createPrivateKey;
55      break;
56    case 'der-spki': {
57      const options = { format: 'der', type: 'spki' };
58      key = { ...options, key: keyPair.publicKey.export(options) };
59      fn = crypto.createPublicKey;
60      break;
61    }
62    case 'der-pkcs8': {
63      const options = { format: 'der', type: 'pkcs8' };
64      key = { ...options, key: keyPair.privateKey.export(options) };
65      fn = crypto.createPrivateKey;
66      break;
67    }
68    case 'jwk-public': {
69      const options = { format: 'jwk' };
70      key = { ...options, key: keyPair.publicKey.export(options) };
71      fn = crypto.createPublicKey;
72      break;
73    }
74    case 'jwk-private': {
75      const options = { format: 'jwk' };
76      key = { ...options, key: keyPair.privateKey.export(options) };
77      fn = crypto.createPrivateKey;
78      break;
79    }
80    default:
81      throw new Error('not implemented');
82  }
83
84  measure(n, fn, key);
85}
86