summaryrefslogtreecommitdiff
path: root/benchmark/crypto/cipher-stream.js
blob: f426a32769d0dd3aecbcd1755a4de1bb95a9d697 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
'use strict';
const common = require('../common.js');

const bench = common.createBenchmark(main, {
  writes: [500],
  cipher: [ 'AES192', 'AES256' ],
  type: ['asc', 'utf', 'buf'],
  len: [2, 1024, 102400, 1024 * 1024],
  api: ['legacy', 'stream']
});

function main({ api, cipher, type, len, writes }) {
  // Default cipher for tests.
  if (cipher === '')
    cipher = 'AES192';
  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';
  }

  const crypto = require('crypto');
  const assert = require('assert');
  const alice = crypto.getDiffieHellman('modp5');
  const bob = crypto.getDiffieHellman('modp5');

  alice.generateKeys();
  bob.generateKeys();


  const pubEnc = /^v0\.[0-8]/.test(process.version) ? 'binary' : null;
  const alice_secret = alice.computeSecret(bob.getPublicKey(), pubEnc, 'hex');
  const bob_secret = bob.computeSecret(alice.getPublicKey(), pubEnc, 'hex');

  // alice_secret and bob_secret should be the same
  assert(alice_secret === bob_secret);

  const alice_cipher = crypto.createCipher(cipher, alice_secret);
  const bob_cipher = crypto.createDecipher(cipher, bob_secret);

  var message;
  var 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;

  // Write data as fast as possible to alice, and have bob decrypt.
  // use old API for comparison to v0.8
  bench.start();
  fn(alice_cipher, bob_cipher, message, encoding, writes);
}

function streamWrite(alice, bob, message, encoding, writes) {
  var written = 0;
  bob.on('data', (c) => {
    written += c.length;
  });

  bob.on('end', () => {
    // Gbits
    const bits = written * 8;
    const gbits = bits / (1024 * 1024 * 1024);
    bench.end(gbits);
  });

  alice.pipe(bob);

  while (writes-- > 0)
    alice.write(message, encoding);

  alice.end();
}

function legacyWrite(alice, bob, message, encoding, writes) {
  var written = 0;
  var enc, dec;
  for (var i = 0; i < writes; i++) {
    enc = alice.update(message, encoding);
    dec = bob.update(enc);
    written += dec.length;
  }
  enc = alice.final();
  dec = bob.update(enc);
  written += dec.length;
  dec = bob.final();
  written += dec.length;
  const gbits = written / (1024 * 1024 * 1024);
  bench.end(gbits);
}