From 0ea33e6597e19186bf82ea76c0b0db432068bda3 Mon Sep 17 00:00:00 2001 From: Robert Kieffer Date: Sat, 9 Sep 2017 07:04:51 -0700 Subject: [PATCH] use typeof to check for crypto rather than global. Fixes #185 (#221) * use typeof to check for crypto rather than global. Fixes #185 * fix test(s) for node v0.12 * tweak --- lib/rng-browser.js | 16 ++++++---------- lib/rng.js | 10 ++++------ test/test.js | 43 +++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 53 insertions(+), 16 deletions(-) diff --git a/lib/rng-browser.js b/lib/rng-browser.js index ac39b128..ab843826 100644 --- a/lib/rng-browser.js +++ b/lib/rng-browser.js @@ -2,25 +2,23 @@ // browser this is a little complicated due to unknown quality of Math.random() // and inconsistent support for the `crypto` API. We do the best we can via // feature-detection -var rng; -var crypto = global.crypto || global.msCrypto; // for IE 11 -if (crypto && crypto.getRandomValues) { +if (typeof(crypto) != 'undefined' && crypto.getRandomValues) { // WHATWG crypto RNG - http://wiki.whatwg.org/wiki/Crypto var rnds8 = new Uint8Array(16); // eslint-disable-line no-undef - rng = function whatwgRNG() { + + module.exports = function whatwgRNG() { crypto.getRandomValues(rnds8); return rnds8; }; -} - -if (!rng) { +} else { // Math.random()-based (RNG) // // If all else fails, use Math.random(). It's fast, but is of unspecified // quality. var rnds = new Array(16); - rng = function() { + + module.exports = function mathRNG() { for (var i = 0, r; i < 16; i++) { if ((i & 0x03) === 0) r = Math.random() * 0x100000000; rnds[i] = r >>> ((i & 0x03) << 3) & 0xff; @@ -29,5 +27,3 @@ if (!rng) { return rnds; }; } - -module.exports = rng; diff --git a/lib/rng.js b/lib/rng.js index 4a0182fd..58f0dc9c 100644 --- a/lib/rng.js +++ b/lib/rng.js @@ -1,10 +1,8 @@ // Unique ID creation requires a high quality random # generator. In node.js // this is pretty straight-forward - we use the crypto API. -var rb = require('crypto').randomBytes; +var crypto = require('crypto'); -function rng() { - return rb(16); -} - -module.exports = rng; +module.exports = function nodeRNG() { + return crypto.randomBytes(16); +}; diff --git a/test/test.js b/test/test.js index c35a1eea..bc111b08 100644 --- a/test/test.js +++ b/test/test.js @@ -46,6 +46,49 @@ function compare(name, ids) { }); } +test('nodeRNG', function() { + var rng = require('../lib/rng'); + assert.equal(rng.name, 'nodeRNG'); + + var bytes = rng(); + assert.equal(bytes.length, 16); + + for (var i = 0; i < bytes.length; i++) { + assert.equal(typeof(bytes[i]), 'number'); + } +}); + +test('mathRNG', function() { + var rng = require('../lib/rng-browser'); + assert.equal(rng.name, 'mathRNG'); + + var bytes = rng(); + assert.equal(bytes.length, 16); + + for (var i = 0; i < bytes.length; i++) { + assert.equal(typeof(bytes[i]), 'number'); + } +}); + +test('cryptoRNG', function() { + // We shim the web crypto API to trigger cryptoRNG code path in rng module, + // then unshim once we've required it + global.crypto = { + getRandomValues: function(arr) { + return randomFillSync(arr); + } + }; + var rng = require('../lib/rng-browser'); + delete global.crypto; + + var bytes = rng(); + assert.equal(bytes.length, 16); + + for (var i = 0; i < bytes.length; i++) { + assert.equal(typeof(bytes[i]), 'number'); + } +}); + test('sha1 node', function() { var sha1 = require('../lib/sha1');