tweetnacl-es6
Version:
Port of TweetNaCl cryptographic library to JavaScript es6
221 lines (198 loc) • 6.61 kB
JavaScript
import nacl from './../../nacl-fast-es.js';
import * as helpers from './helpers.js';
const log = (typeof window === "undefined") ? new helpers.NodeLogger() : new helpers.BrowserLogger();
if (!nacl) throw new Error('nacl not loaded');
function decodeUTF8(s) {
var i, d = unescape(encodeURIComponent(s)), b = new Uint8Array(d.length);
for (i = 0; i < d.length; i++) b[i] = d.charCodeAt(i);
return b;
}
var getTime = (function() {
if (typeof performance !== 'undefined') {
return performance.now.bind(performance);
}
if (typeof process !== 'undefined' && process.hrtime) {
return function() {
var _a = process.hrtime(), sec = _a[0], nanosec = _a[1];
return (sec * 1e9 + nanosec) / 1e6;
};
}
return Date.now.bind(Date);
})();
function benchmark(fn, bytes) {
var elapsed = 0;
var iterations = 1;
var runsPerIteration = 1;
// Run once without measuring anything to possibly kick-off JIT.
fn();
while (true) { // eslint-disable-line
var startTime = void 0;
var diff = void 0;
if (runsPerIteration === 1) {
// Measure one iteration.
startTime = getTime();
fn();
diff = getTime() - startTime;
} else {
// Measure many iterations.
startTime = getTime();
for (var i = 0; i < runsPerIteration; i++) {
fn();
}
diff = getTime() - startTime;
}
// If diff is too small, double the number of iterations
// and start over without recording results.
if (diff < 1) {
runsPerIteration *= 2;
continue;
}
// Otherwise, record the result.
elapsed += diff;
if (elapsed > 500 && iterations > 2) {
break;
}
iterations += runsPerIteration;
}
// Calculate average time per iteration.
var avg = elapsed / iterations;
return {
iterations: iterations,
msPerOp: avg,
opsPerSecond: 1000 / avg,
bytesPerSecond: bytes ? 1000 * (bytes * iterations) / (avg * iterations) : undefined
};
}
function pad(s, upto, end) {
if (end === void 0) { end = false; }
var padlen = upto - s.length;
if (padlen <= 0) {
return s;
}
// XXX: in ES2015 we can use ' '.repeat(padlen)
var padding = new Array(padlen + 1).join(' ');
if (end) {
return s + padding;
}
return padding + s;
}
function report(name, results) {
var ops = results.iterations + ' ops';
var msPerOp = results.msPerOp.toFixed(2) + ' ms/op';
var opsPerSecond = results.opsPerSecond.toFixed(2) + ' ops/sec';
var mibPerSecond = results.bytesPerSecond
? (results.bytesPerSecond / 1024 / 1024).toFixed(2) + ' MiB/s'
: '';
log.print(
pad(name, 25, true) + ' ' +
pad(ops, 20) + ' ' +
pad(msPerOp, 20) + ' ' +
pad(opsPerSecond, 20) + ' ' +
pad(mibPerSecond, 15)
);
}
function crypto_stream_xor_benchmark() {
var m = new Uint8Array(1024),
n = new Uint8Array(24),
k = new Uint8Array(32),
out = new Uint8Array(1024),
i;
for (i = 0; i < 1024; i++) m[i] = i & 255;
for (i = 0; i < 24; i++) n[i] = i;
for (i = 0; i < 32; i++) k[i] = i;
report('crypto_stream_xor 1K', benchmark(function() {
nacl.lowlevel.crypto_stream_xor(out, 0, m, 0, m.length, n, k);
}, m.length));
}
function crypto_onetimeauth_benchmark() {
var m = new Uint8Array(1024),
out = new Uint8Array(1024),
k = new Uint8Array([0,1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9,0,1]);
for (var i = 0; i < 1024; i++) {
m[i] = i & 255;
}
report('crypto_onetimeauth 1K', benchmark(function() {
nacl.lowlevel.crypto_onetimeauth(out, 0, m, 0, m.length, k);
}, m.length));
}
function crypto_secretbox_benchmark() {
var i, k = new Uint8Array(32), n = new Uint8Array(24),
m = new Uint8Array(1024), c = new Uint8Array(1024);
for (i = 0; i < 32; i++) k[i] = 1;
for (i = 0; i < 24; i++) n[i] = 2;
for (i = 0; i < 1024; i++) m[i] = 3;
report('crypto_secretbox 1K', benchmark(function() {
nacl.lowlevel.crypto_secretbox(c, m, m.length, n, k);
}, m.length));
}
function secretbox_seal_open_benchmark() {
var key = new Uint8Array(32),
nonce = new Uint8Array(24),
msg = new Uint8Array(1024),
box, i;
for (i = 0; i < 32; i++) key[i] = 1;
for (i = 0; i < 24; i++) nonce[i] = 2;
for (i = 0; i < 1024; i++) msg[i] = 3;
report('secretbox 1K', benchmark(function() {
box = nacl.secretbox(msg, nonce, key);
}, msg.length));
report('secretbox.open 1K', benchmark(function() {
nacl.secretbox.open(box, nonce, key);
}, msg.length));
}
function crypto_scalarmult_base_benchmark() {
var n = new Uint8Array(32), q = new Uint8Array(32);
for (var i = 0; i < 32; i++) n[i] = i;
report('crypto_scalarmult_base', benchmark(function() {
nacl.lowlevel.crypto_scalarmult_base(q, n);
}));
}
function box_seal_open_benchmark() {
var pk1 = new Uint8Array(32), sk1 = new Uint8Array(32),
pk2 = new Uint8Array(32), sk2 = new Uint8Array(32);
nacl.lowlevel.crypto_box_keypair(pk1, sk1);
nacl.lowlevel.crypto_box_keypair(pk2, sk2);
var nonce = decodeUTF8('123456789012345678901234');
var msg = decodeUTF8((new Array(1024)).join('a'));
var box = null;
report('box 1K', benchmark(function() {
box = nacl.box(msg, nonce, pk1, sk2);
}, msg.length));
report('box.open 1K', benchmark(function() {
nacl.box.open(box, nonce, pk2, sk1);
}, msg.length));
}
function sign_open_benchmark() {
var k = nacl.sign.keyPair();
var sk = k.secretKey;
var pk = k.publicKey;
var msg = decodeUTF8((new Array(128)).join('a'));
var sm;
report('sign', benchmark(function() {
sm = nacl.sign(msg, sk);
}));
report('sign.open', benchmark(function() {
nacl.sign.open(sm, pk);
}));
}
function crypto_hash_benchmark() {
var m = new Uint8Array(1024), out = new Uint8Array(64);
var i;
for (i = 0; i < m.length; i++) m[i] = i & 255;
report('crypto_hash 1K', benchmark(function() {
nacl.lowlevel.crypto_hash(out, m, m.length);
}, m.length));
m = new Uint8Array(16*1024);
for (i = 0; i < m.length; i++) m[i] = i & 255;
report('crypto_hash 16K', benchmark(function() {
nacl.lowlevel.crypto_hash(out, m, m.length);
}, m.length));
}
crypto_stream_xor_benchmark();
crypto_onetimeauth_benchmark();
crypto_secretbox_benchmark();
crypto_hash_benchmark();
secretbox_seal_open_benchmark();
crypto_scalarmult_base_benchmark();
box_seal_open_benchmark();
sign_open_benchmark();