Skip to content

Commit

Permalink
crypto: refactoring internals, add WebCrypto
Browse files Browse the repository at this point in the history
Fixes: #678
Refs: #26854

Signed-off-by: James M Snell <jasnell@gmail.com>

PR-URL: #35093
Reviewed-By: Matteo Collina <matteo.collina@gmail.com>
Reviewed-By: Anna Henningsen <anna@addaleax.net>
Reviewed-By: Michaël Zasso <targos@protonmail.com>
Reviewed-By: Rich Trott <rtrott@gmail.com>
  • Loading branch information
jasnell committed Oct 8, 2020
1 parent ba77dc8 commit dae283d
Show file tree
Hide file tree
Showing 149 changed files with 28,390 additions and 8,575 deletions.
2 changes: 1 addition & 1 deletion .github/CODEOWNERS
Validating CODEOWNERS rules …
Expand Up @@ -59,7 +59,7 @@
/lib/crypto.js @nodejs/crypto
/lib/tls.js @nodejs/crypto @nodejs/net
/src/node_crypto* @nodejs/crypto
/src/node_crypto_common* @nodejs/crypto @nodejs/quic
/src/crypto/* @nodejs/crypto @nodejs/quic

# http

Expand Down
44 changes: 44 additions & 0 deletions benchmark/crypto/hkdf.js
@@ -0,0 +1,44 @@
'use strict';

const common = require('../common.js');
const assert = require('assert');
const {
hkdf,
hkdfSync
} = require('crypto');

const bench = common.createBenchmark(main, {
sync: [0, 1],
size: [10, 64, 1024],
key: ['a', 'secret', 'this-is-a-much-longer-secret'],
salt: ['', 'salt'],
info: ['', 'info'],
hash: ['sha256', 'sha512'],
n: [1e3],
});

function measureSync(n, size, salt, info, hash, key) {
bench.start();
for (let i = 0; i < n; ++i)
hkdfSync(hash, key, salt, info, size);
bench.end(n);
}

function measureAsync(n, size, salt, info, hash, key) {
let remaining = n;
function done(err) {
assert.ifError(err);
if (--remaining === 0)
bench.end(n);
}
bench.start();
for (let i = 0; i < n; ++i)
hkdf(hash, key, salt, info, size, done);
}

function main({ n, sync, size, salt, info, hash, key }) {
if (sync)
measureSync(n, size, salt, info, hash, key);
else
measureAsync(n, size, salt, info, hash, key);
}
71 changes: 71 additions & 0 deletions benchmark/crypto/keygen.js
@@ -0,0 +1,71 @@
'use strict';

const common = require('../common.js');
const assert = require('assert');
const {
generateKeyPair,
generateKeyPairSync
} = require('crypto');

const bench = common.createBenchmark(main, {
method: ['rsaSync', 'rsaAsync', 'dsaSync', 'dsaAsync'],
n: [1e2],
});

const methods = {
rsaSync(n) {
bench.start();
for (let i = 0; i < n; ++i) {
generateKeyPairSync('rsa', {
modulusLength: 1024,
publicExponent: 0x10001
});
}
bench.end(n);
},

rsaAsync(n) {
let remaining = n;
function done(err) {
assert.ifError(err);
if (--remaining === 0)
bench.end(n);
}
bench.start();
for (let i = 0; i < n; ++i)
generateKeyPair('rsa', {
modulusLength: 512,
publicExponent: 0x10001
}, done);
},

dsaSync(n) {
bench.start();
for (let i = 0; i < n; ++i) {
generateKeyPairSync('dsa', {
modulusLength: 512,
divisorLength: 256,
});
}
bench.end(n);
},

dsaAsync(n) {
let remaining = n;
function done(err) {
assert.ifError(err);
if (--remaining === 0)
bench.end(n);
}
bench.start();
for (let i = 0; i < n; ++i)
generateKeyPair('dsa', {
modulusLength: 512,
divisorLength: 256,
}, done);
},
};

function main({ n, method }) {
methods[method](n);
}
58 changes: 58 additions & 0 deletions benchmark/crypto/webcrypto-digest.js
@@ -0,0 +1,58 @@
'use strict';

const common = require('../common.js');
const {
createHash,
webcrypto: {
subtle,
getRandomValues
}
} = require('crypto');

const bench = common.createBenchmark(main, {
sync: ['createHash', 'subtle'],
data: [10, 20, 50, 100],
method: ['SHA-1', 'SHA-256', 'SHA-384', 'SHA-512'],
n: [1e3],
});

const kMethods = {
'SHA-1': 'sha1',
'SHA-256': 'sha256',
'SHA-384': 'sha384',
'SHA-512': 'sha512'
};

// This benchmark only looks at clock time and ignores factors
// such as event loop delay, event loop utilization, and memory.
// As such, it is expected that the synchronous legacy method
// will always be faster in clock time.

function measureLegacy(n, data, method) {
method = kMethods[method];
bench.start();
for (let i = 0; i < n; ++i) {
createHash(method).update(data).digest();
}
bench.end(n);
}

function measureSubtle(n, data, method) {
const ec = new TextEncoder();
data = ec.encode(data);
const jobs = new Array(n);
bench.start();
for (let i = 0; i < n; i++)
jobs[i] = subtle.digest(method, data);
Promise.all(jobs).then(() => bench.end(n)).catch((err) => {
process.nextTick(() => { throw err; });
});
}

function main({ n, sync, data, method }) {
data = getRandomValues(Buffer.alloc(data));
switch (sync) {
case 'createHash': return measureLegacy(n, data, method);
case 'subtle': return measureSubtle(n, data, method);
}
}

0 comments on commit dae283d

Please sign in to comment.