Merge pull request #36 from bitcoinjs/replace-rng
Replace all Math.random/other (P)RNG
This commit is contained in:
commit
771d415179
8 changed files with 18 additions and 141 deletions
|
@ -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"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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<<t)-1); else x[0] = 0;
|
||||
self.fromString(x,256);
|
||||
}
|
||||
|
|
|
@ -1,39 +0,0 @@
|
|||
// prng4.js - uses Arcfour as a PRNG
|
||||
|
||||
function Arcfour() {
|
||||
this.i = 0;
|
||||
this.j = 0;
|
||||
this.S = new Array();
|
||||
}
|
||||
|
||||
// Initialize arcfour context from key, an array of ints, each from [0..255]
|
||||
function ARC4init(key) {
|
||||
var i, j, t;
|
||||
for(i = 0; i < 256; ++i)
|
||||
this.S[i] = i;
|
||||
j = 0;
|
||||
for(i = 0; i < 256; ++i) {
|
||||
j = (j + this.S[i] + key[i % key.length]) & 255;
|
||||
t = this.S[i];
|
||||
this.S[i] = this.S[j];
|
||||
this.S[j] = t;
|
||||
}
|
||||
this.i = 0;
|
||||
this.j = 0;
|
||||
}
|
||||
|
||||
function ARC4next() {
|
||||
var t;
|
||||
this.i = (this.i + 1) & 255;
|
||||
this.j = (this.j + this.S[this.i]) & 255;
|
||||
t = this.S[this.i];
|
||||
this.S[this.i] = this.S[this.j];
|
||||
this.S[this.j] = t;
|
||||
return this.S[(t + this.S[this.i]) & 255];
|
||||
}
|
||||
|
||||
Arcfour.prototype.init = ARC4init;
|
||||
Arcfour.prototype.next = ARC4next;
|
||||
|
||||
module.exports = Arcfour;
|
||||
|
|
@ -1,85 +0,0 @@
|
|||
// Random number generator - requires a PRNG backend, e.g. prng4.js
|
||||
// prng4.js - uses Arcfour as a PRNG
|
||||
|
||||
var Arcfour = require('./prng4');
|
||||
|
||||
// Plug in your RNG constructor here
|
||||
function prng_newstate() {
|
||||
return new Arcfour();
|
||||
}
|
||||
|
||||
// Pool size must be a multiple of 4 and greater than 32.
|
||||
// An array of bytes the size of the pool will be passed to init()
|
||||
var rng_psize = 256;
|
||||
|
||||
// For best results, put code like
|
||||
// <body onClick='rng_seed_time();' onKeyPress='rng_seed_time();'>
|
||||
// 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;
|
|
@ -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
|
||||
|
|
|
@ -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)
|
||||
})
|
||||
})
|
||||
})
|
||||
|
|
|
@ -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');
|
||||
|
|
Loading…
Add table
Reference in a new issue