Skip to content

Commit

Permalink
use typeof to check for crypto rather than global. Fixes #185 (#221)
Browse files Browse the repository at this point in the history
* use typeof to check for crypto rather than global.  Fixes #185

* fix test(s) for node v0.12

* tweak
  • Loading branch information
broofa committed Sep 9, 2017
1 parent c1f720d commit 0ea33e6
Show file tree
Hide file tree
Showing 3 changed files with 53 additions and 16 deletions.
16 changes: 6 additions & 10 deletions lib/rng-browser.js
Expand Up @@ -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) {

This comment has been minimized.

Copy link
@leeor

leeor Nov 28, 2017

Hi @broofa, will this break IE11 support when it's released?

This comment has been minimized.

Copy link
@broofa

broofa Nov 28, 2017

Author Member

@leeor Ah, good catch! Filed as #241. I'll fix this before rolling v3.2.0

// 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;
Expand All @@ -29,5 +27,3 @@ if (!rng) {
return rnds;
};
}

module.exports = rng;
10 changes: 4 additions & 6 deletions 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);
};
43 changes: 43 additions & 0 deletions test/test.js
Expand Up @@ -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');

Expand Down

0 comments on commit 0ea33e6

Please sign in to comment.