diff --git a/package.json b/package.json index b121804..813951c 100644 --- a/package.json +++ b/package.json @@ -40,6 +40,7 @@ "compile": "./node_modules/.bin/browserify ./src/index.js -s Bitcoin | ./node_modules/.bin/uglifyjs > bitcoinjs-min.js" }, "dependencies": { - "crypto-js": "3.1.2-2" + "crypto-js": "3.1.2-2", + "secure-random": "^0.2.0" } } diff --git a/src/ecdsa.js b/src/ecdsa.js index f189148..573f25f 100644 --- a/src/ecdsa.js +++ b/src/ecdsa.js @@ -1,12 +1,11 @@ var sec = require('./jsbn/sec'); -var SecureRandom = require('./jsbn/rng'); +var rng = require('secure-random'); var BigInteger = require('./jsbn/jsbn'); var convert = require('./convert') var HmacSHA256 = require('crypto-js/hmac-sha256'); var ECPointFp = require('./jsbn/ec').ECPointFp; -var rng = new SecureRandom(); var ecparams = sec("secp256k1"); var P_OVER_FOUR = null; diff --git a/src/jsbn/jsbn.js b/src/jsbn/jsbn.js index 6618f37..143488e 100644 --- a/src/jsbn/jsbn.js +++ b/src/jsbn/jsbn.js @@ -672,9 +672,9 @@ function bnpFromNumber(a,b,c) { } else { // new BigInteger(int,RNG) - var x = new Array(), t = a&7; - x.length = (a>>3)+1; - b.nextBytes(x); + var t = a&7; + var length = (a>>3)+1; + var x = b(length, {array: true}); if(t > 0) x[0] &= ((1< -// in your main HTML document. - -var rng_state; -var rng_pool; -var rng_pptr; - -// Mix in a 32-bit integer into the pool -function rng_seed_int(x) { - rng_pool[rng_pptr++] ^= x & 255; - rng_pool[rng_pptr++] ^= (x >> 8) & 255; - rng_pool[rng_pptr++] ^= (x >> 16) & 255; - rng_pool[rng_pptr++] ^= (x >> 24) & 255; - if(rng_pptr >= rng_psize) rng_pptr -= rng_psize; -} - -// Mix in the current time (w/milliseconds) into the pool -function rng_seed_time() { - rng_seed_int(new Date().getTime()); -} - -// Initialize the pool with junk if needed. -if(rng_pool == null) { - rng_pool = new Array(); - rng_pptr = 0; - var t; - // TODO(shtylman) use browser crypto if available - /* - if(navigator.appName == "Netscape" && navigator.appVersion < "5" && window.crypto) { - // Extract entropy (256 bits) from NS4 RNG if available - var z = window.crypto.random(32); - for(t = 0; t < z.length; ++t) - rng_pool[rng_pptr++] = z.charCodeAt(t) & 255; - } - */ - while(rng_pptr < rng_psize) { // extract some randomness from Math.random() - t = Math.floor(65536 * Math.random()); - rng_pool[rng_pptr++] = t >>> 8; - rng_pool[rng_pptr++] = t & 255; - } - rng_pptr = 0; - rng_seed_time(); - //rng_seed_int(window.screenX); - //rng_seed_int(window.screenY); -} - -function rng_get_byte() { - if(rng_state == null) { - rng_seed_time(); - rng_state = prng_newstate(); - rng_state.init(rng_pool); - for(rng_pptr = 0; rng_pptr < rng_pool.length; ++rng_pptr) - rng_pool[rng_pptr] = 0; - rng_pptr = 0; - //rng_pool = null; - } - // TODO: allow reseeding after first request - return rng_state.next(); -} - -function rng_get_bytes(ba) { - var i; - for(i = 0; i < ba.length; ++i) ba[i] = rng_get_byte(); -} - -function SecureRandom() {} - -SecureRandom.prototype.nextBytes = rng_get_bytes; - -module.exports = SecureRandom; diff --git a/src/wallet.js b/src/wallet.js index 698f9a3..cf1be8c 100644 --- a/src/wallet.js +++ b/src/wallet.js @@ -7,8 +7,7 @@ var Transaction = require('./transaction').Transaction; var TransactionIn = require('./transaction').TransactionIn; var TransactionOut = require('./transaction').TransactionOut; var HDNode = require('./hdwallet.js') -var SecureRandom = require('./jsbn/rng'); -var rng = new SecureRandom(); +var rng = require('secure-random'); var Wallet = function (seed, options) { if (!(this instanceof Wallet)) { return new Wallet(seed, options); } @@ -32,10 +31,7 @@ var Wallet = function (seed, options) { // Make a new master key this.newMasterKey = function(seed, network) { - if (!seed) { - var seed= new Array(32); - rng.nextBytes(seed); - } + if (!seed) seed= rng(32, { array: true }) masterkey = new HDNode(seed, network); // HD first-level child derivation method should be private diff --git a/test/jsbn.js b/test/jsbn.js index c2320b3..686dab0 100644 --- a/test/jsbn.js +++ b/test/jsbn.js @@ -2,6 +2,7 @@ var assert = require('assert'); var BigInteger = require('../src/jsbn/jsbn.js') var bytesToHex = require('../src/convert.js').bytesToHex; +var secureRandom = require('secure-random'); describe('BigInteger', function() { describe('toByteArraySigned', function() { @@ -25,4 +26,12 @@ describe('BigInteger', function() { assert.equal(hex(-62300), '0x80f35c'); }) }) + + describe('with RNG passed into constructor as the 2nd argument', function(){ + it('returns a BigInteger with the limit of the specified length', function(){ + var bitLength = 256 + var i = new BigInteger(bitLength, secureRandom) + assert(i.bitLength() <= 256) + }) + }) }) diff --git a/test/misc.js b/test/misc.js index 2c85b89..192b548 100644 --- a/test/misc.js +++ b/test/misc.js @@ -1,13 +1,9 @@ -/* global it */ var assert = require('assert'); var bitcoinjs = require('../'); var sec = require('../src/jsbn/sec'); var BigInteger = require('../src/jsbn/jsbn.js'); var SHA256 = require('crypto-js/sha256'); - -var SecureRandom = require('../src/jsbn/rng'); -var rng = new SecureRandom(); - +var rng = require('secure-random'); var ecparams = sec('secp256k1'); var ECPointFp = bitcoinjs.ECPointFp; var convert = require('../src/convert');