diff --git a/bitcore.js b/bitcore.js
index aa0de4b..bb92336 100644
--- a/bitcore.js
+++ b/bitcore.js
@@ -17,9 +17,11 @@ requireWhenAccessed('buffertools', 'buffertools');
requireWhenAccessed('Buffers.monkey', './patches/Buffers.monkey');
requireWhenAccessed('config', './config');
requireWhenAccessed('const', './const');
+requireWhenAccessed('Curve', './lib/Curve');
requireWhenAccessed('Deserialize', './lib/Deserialize');
requireWhenAccessed('log', './util/log');
requireWhenAccessed('networks', './networks');
+requireWhenAccessed('SecureRandom', './lib/SecureRandom');
requireWhenAccessed('util', './util/util');
requireWhenAccessed('EncodedData', './util/EncodedData');
requireWhenAccessed('VersionedData', './util/VersionedData');
diff --git a/browser/build.js b/browser/build.js
index 05f7a62..0b8b59f 100644
--- a/browser/build.js
+++ b/browser/build.js
@@ -28,6 +28,7 @@ var modules = [
'lib/Block',
'lib/Bloom',
'lib/Connection',
+ 'lib/Curve',
'lib/Deserialize',
'lib/Electrum',
'lib/Message',
@@ -42,6 +43,7 @@ var modules = [
'lib/SINKey',
'lib/Script',
'lib/ScriptInterpreter',
+ 'lib/SecureRandom',
'lib/Sign',
'lib/Transaction',
'lib/TransactionBuilder',
diff --git a/examples/ConnectionTor.js b/examples/ConnectionTor.js
index 2d9d8a6..c96040f 100644
--- a/examples/ConnectionTor.js
+++ b/examples/ConnectionTor.js
@@ -1,5 +1,5 @@
-var Peer = require('../Peer');
-var Connection = require('../Connection');
+var Peer = require('../lib/Peer');
+var Connection = require('../lib/Connection');
var dns = require('dns');
// get a peer from dns seed
diff --git a/lib/BIP32.js b/lib/BIP32.js
index 94a7602..6484af0 100644
--- a/lib/BIP32.js
+++ b/lib/BIP32.js
@@ -3,6 +3,7 @@ var base58 = imports.base58 || require('base58-native').base58;
var coinUtil = imports.coinUtil || require('../util');
var Key = imports.Key || require('./Key');
var Point = imports.Point || require('./Point');
+var SecureRandom = imports.SecureRandom || require('./SecureRandom');
var bignum = imports.bignum || require('bignum');
var crypto = require('crypto');
var networks = require('../networks');
@@ -27,7 +28,7 @@ var BIP32 = function(bytes) {
this.depth = 0x00;
this.parentFingerprint = new Buffer([0, 0, 0, 0]);
this.childIndex = new Buffer([0, 0, 0, 0]);
- this.chainCode = Key.generateSync().private;
+ this.chainCode = SecureRandom.getRandomBuffer(32);
this.eckey = Key.generateSync();
this.hasPrivateKey = true;
this.pubKeyHash = coinUtil.sha256ripe160(this.eckey.public);
@@ -288,17 +289,20 @@ BIP32.prototype.deriveChild = function(i) {
var ilGkey = new Key();
ilGkey.private = il;
ilGkey.regenerateSync();
- var ilG = Point.fromKey(ilGkey);
+ ilGkey.compressed = false;
+ var ilG = Point.fromUncompressedPubKey(ilGkey.public);
var oldkey = new Key();
oldkey.public = this.eckey.public;
- var Kpar = Point.fromKey(oldkey);
- var newpub = Point.add(ilG, Kpar).toKey().public;
+ oldkey.compressed = false;
+ var Kpar = Point.fromUncompressedPubKey(oldkey.public);
+ var newpub = Point.add(ilG, Kpar).toUncompressedPubKey();
ret = new BIP32(null);
ret.chainCode = new Buffer(ir);
var eckey = new Key();
eckey.public = newpub;
+ eckey.compressed = true;
ret.eckey = eckey;
ret.hasPrivateKey = false;
}
diff --git a/lib/Connection.js b/lib/Connection.js
index f03e953..1377545 100644
--- a/lib/Connection.js
+++ b/lib/Connection.js
@@ -17,7 +17,8 @@ var util = imports.util || require('../util');
var Parser = imports.Parser || require('../util/BinaryParser');
var buffertools = imports.buffertools || require('buffertools');
var doubleSha256 = imports.doubleSha256 || util.twoSha256;
-var nonce = util.generateNonce();
+var SecureRandom = imports.SecureRandom || require('./SecureRandom');
+var nonce = SecureRandom.getPseudoRandomBuffer(8);
var BIP0031_VERSION = 60000;
diff --git a/lib/Curve.js b/lib/Curve.js
new file mode 100644
index 0000000..f2d140d
--- /dev/null
+++ b/lib/Curve.js
@@ -0,0 +1,22 @@
+"use strict";
+var imports = require('soop');
+var bignum = imports.bignum || require('bignum');
+var Point = imports.Point || require('./Point');
+
+var n = bignum.fromBuffer(new Buffer("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141", 'hex'), {size: 32});
+var G = new Point(bignum.fromBuffer(new Buffer("79BE667EF9DCBBAC55A06295CE870B07029BFCDB2DCE28D959F2815B16F81798", 'hex'), {size: 32}),
+ bignum.fromBuffer(new Buffer("483ADA7726A3C4655DA4FBFC0E1108A8FD17B448A68554199C47D08FFB10D4B8", 'hex'), {size: 32}));
+
+/* secp256k1 curve */
+var Curve = function() {
+};
+
+Curve.getG = function() {
+ return G;
+};
+
+Curve.getN = function() {
+ return n;
+};
+
+module.exports = require('soop')(Curve);
diff --git a/lib/Electrum.js b/lib/Electrum.js
index 1cf499e..0245779 100644
--- a/lib/Electrum.js
+++ b/lib/Electrum.js
@@ -31,8 +31,9 @@ Electrum.prototype.generatePubKey = function (n, for_change) {
var sequence_key = new Key();
sequence_key.private = sequence.toBuffer();
sequence_key.regenerateSync();
+ sequence_key.compressed = false;
- var sequence_pt = Point.fromKey(sequence_key);
+ var sequence_pt = Point.fromUncompressedPubKey(sequence_key.public);
pt = Point.add(mpk_pt, sequence_pt);
diff --git a/lib/SecureRandom.js b/lib/SecureRandom.js
new file mode 100644
index 0000000..fa7f5ef
--- /dev/null
+++ b/lib/SecureRandom.js
@@ -0,0 +1,5 @@
+if (process.versions) {
+ module.exports = require('./node/SecureRandom');
+ return;
+}
+module.exports = require('./browser/SecureRandom');
diff --git a/lib/browser/Key.js b/lib/browser/Key.js
index a35437b..790efd1 100644
--- a/lib/browser/Key.js
+++ b/lib/browser/Key.js
@@ -1,8 +1,10 @@
var ECKey = require('../../browser/vendor-bundle.js').ECKey;
+var SecureRandom = require('../SecureRandom');
+var Curve = require('../Curve');
var Key = function() {
this._pub = null;
- this.compressed = true; // default
+ this._compressed = true; // default
};
var bufferToArray = Key.bufferToArray = function(buffer) {
@@ -16,14 +18,13 @@ var bufferToArray = Key.bufferToArray = function(buffer) {
return ret;
}
-
Object.defineProperty(Key.prototype, 'public', {
set: function(p){
if (!Buffer.isBuffer(p) ) {
throw new Error('Arg should be a buffer');
}
var type = p[0];
- this.compressed = type!==0x04;
+ this._compressed = type!==0x04;
this._pub = p;
},
get: function(){
@@ -31,14 +32,48 @@ Object.defineProperty(Key.prototype, 'public', {
}
});
+Object.defineProperty(Key.prototype, 'compressed', {
+ set: function(c) {
+ var oldc = this._compressed;
+ this._compressed = !!c;
+ if (oldc == this._compressed)
+ return;
+ var oldp = this._pub;
+ if (this._pub) {
+ var eckey = new ECKey();
+ eckey.setPub(bufferToArray(this.public));
+ eckey.setCompressed(this._compressed);
+ this._pub = new Buffer(eckey.getPub());
+ }
+ if (!this._compressed) {
+ //bug in eckey
+ //oldp.slice(1).copy(this._pub, 1);
+ }
+ },
+ get: function() {
+ return this._compressed;
+ }
+});
+
Key.generateSync = function() {
- var eck = new ECKey();
+ var privbuf;
+
+ while(true) {
+ privbuf = SecureRandom.getRandomBuffer(32);
+ if ((bignum.fromBuffer(privbuf, {size: 32})).cmp(Curve.getN()) < 0)
+ break;
+ }
+
+ var privhex = privbuf.toString('hex');
+ var eck = new ECKey(privhex);
eck.setCompressed(true);
var pub = eck.getPub();
- var ret = new Key();
- ret.private = new Buffer(eck.priv.toByteArrayUnsigned());
- ret.public = new Buffer(pub);
+ ret = new Key();
+ ret.private = privbuf;
+ ret._compressed = true;
+ ret.public = new Buffer(eck.getPub());
+
return ret;
};
@@ -48,8 +83,8 @@ Key.prototype.regenerateSync = function() {
}
var eck = new ECKey(this.private.toString('hex'));
- eck.setCompressed(this.compressed);
- this.public = new Buffer(eck.getPub());
+ eck.setCompressed(this._compressed);
+ this._pub = new Buffer(eck.getPub());
return this;
};
@@ -62,7 +97,7 @@ Key.prototype.signSync = function(hash) {
throw new Error('Arg should be a 32 bytes hash buffer');
}
var eck = new ECKey(this.private.toString('hex'));
- eck.setCompressed(this.compressed);
+ eck.setCompressed(this._compressed);
var signature = eck.sign(bufferToArray(hash));
// return it as a buffer to keep c++ compatibility
return new Buffer(signature);
@@ -92,7 +127,7 @@ Key.prototype.verifySignatureSync = function(hash, sig) {
var eck = new ECKey();
eck.setPub(bufferToArray(self.public));
- eck.setCompressed(self.compressed);
+ eck.setCompressed(self._compressed);
var sigA = bufferToArray(sig);
var ret = eck.verify(bufferToArray(hash),sigA);
return ret;
diff --git a/lib/browser/Point.js b/lib/browser/Point.js
index b9f4c36..fba0b3d 100644
--- a/lib/browser/Point.js
+++ b/lib/browser/Point.js
@@ -51,31 +51,20 @@ Point.add = function(p1, p2) {
};
//convert the public key of a Key into a Point
-Point.fromKey = function(key) {
+Point.fromUncompressedPubKey = function(pubkey) {
var point = new Point();
- var pubKeyBuf = new Buffer(key.public);
- var key2 = new ECKey();
- key2.setCompressed(key.compressed);
- key2.setPub(Key.bufferToArray(pubKeyBuf));
- key2.setCompressed(false);
- point.x = bignum.fromBuffer((new Buffer(key2.getPub())).slice(1, 33), {size: 32});
- point.y = bignum.fromBuffer((new Buffer(key2.getPub())).slice(33, 65), {size: 32});
+ point.x = bignum.fromBuffer((new Buffer(pubkey)).slice(1, 33), {size: 32});
+ point.y = bignum.fromBuffer((new Buffer(pubkey)).slice(33, 65), {size: 32});
return point;
};
//convert the Point into the Key containing a compressed public key
-Point.prototype.toKey = function() {
+Point.prototype.toUncompressedPubKey = function() {
var xbuf = this.x.toBuffer({size: 32});
var ybuf = this.y.toBuffer({size: 32});
- var key = new ECKey();
- key.setCompressed(false);
var prefix = new Buffer([0x04]);
- var pub = Buffer.concat([prefix, xbuf, ybuf]); //this might be wrong
- key.setPub(Key.bufferToArray(pub));
- key.setCompressed(true);
- var key2 = new Key();
- key2.public = new Buffer(key.getPub());
- return key2;
+ var pub = Buffer.concat([prefix, xbuf, ybuf]);
+ return pub;
};
module.exports = require('soop')(Point);
diff --git a/lib/browser/SecureRandom.js b/lib/browser/SecureRandom.js
new file mode 100644
index 0000000..79f1db5
--- /dev/null
+++ b/lib/browser/SecureRandom.js
@@ -0,0 +1,23 @@
+var imports = require('soop');
+
+var SecureRandom = require('../common/SecureRandom');
+
+SecureRandom.getRandomBuffer = function(size) {
+ if (!window.crypto && !window.msCrypto)
+ throw new Error('window.crypto not available');
+
+ if (window.crypto && window.crypto.getRandomValues)
+ var crypto = window.crypto;
+ else if (window.msCrypto && window.msCrypto.getRandomValues) //internet explorer
+ var crypto = window.msCrypto;
+ else
+ throw new Error('window.crypto.getRandomValues not available');
+
+ var bbuf = new Uint8Array(size);
+ crypto.getRandomValues(bbuf);
+ var buf = new Buffer(bbuf);
+
+ return buf;
+};
+
+module.exports = require('soop')(SecureRandom);
diff --git a/lib/common/SecureRandom.js b/lib/common/SecureRandom.js
new file mode 100644
index 0000000..a276d22
--- /dev/null
+++ b/lib/common/SecureRandom.js
@@ -0,0 +1,28 @@
+var imports = require('soop');
+
+var SecureRandom = function() {
+};
+
+/* secure random bytes that sometimes throws an error due to lack of entropy */
+SecureRandom.getRandomBuffer = function() {};
+
+/* insecure random bytes, but it never fails */
+SecureRandom.getPseudoRandomBuffer = function(size) {
+ var b32 = 0x100000000;
+ var b = new Buffer(size);
+
+ for (var i = 0; i <= size; i++) {
+ var j = Math.floor(i / 4);
+ var k = i - j * 4;
+ if (k == 0) {
+ r = Math.random() * b32;
+ b[i] = r & 0xff;
+ } else {
+ b[i] = (r = r >>> 8) & 0xff;
+ }
+ }
+
+ return b;
+};
+
+module.exports = require('soop')(SecureRandom);
diff --git a/lib/node/Key.js b/lib/node/Key.js
index 8e079d9..bec7c80 100644
--- a/lib/node/Key.js
+++ b/lib/node/Key.js
@@ -1 +1,3 @@
-module.exports = require('bindings')('KeyModule').Key;
+var Key = require('bindings')('KeyModule').Key;
+
+module.exports = Key;
diff --git a/lib/node/Point.js b/lib/node/Point.js
index 38a6466..64d4dd7 100644
--- a/lib/node/Point.js
+++ b/lib/node/Point.js
@@ -1,8 +1,8 @@
"use strict";
var imports = require('soop').imports();
-var Key = imports.Key || require('../Key');
var bignum = imports.bignum || require('bignum');
+var CPPKey = imports.CPPKey || require('bindings')('KeyModule').Key;
var assert = require('assert');
//a point on the secp256k1 curve
@@ -13,41 +13,27 @@ var Point = function(x, y) {
};
Point.add = function(p1, p2) {
- var key1 = p1.toKey();
- key1.compressed = false;
- var key2 = p2.toKey();
- key2.compressed = false;
- var pubKey = Key.addUncompressed(key1.public, key2.public);
- var key = new Key();
- key.compressed = false;
- key.public = pubKey;
- key.compressed = true;
- return Point.fromKey(key);
+ var u1 = p1.toUncompressedPubKey();
+ var u2 = p2.toUncompressedPubKey();
+ var pubKey = CPPKey.addUncompressed(u1, u2);
+ return Point.fromUncompressedPubKey(pubKey);
};
//convert the public key of a Key into a Point
-Point.fromKey = function(key) {
+Point.fromUncompressedPubKey = function(pubkey) {
var point = new Point();
- var pubKeyBuf = new Buffer(key.public);
- var key2 = new Key();
- key2.compressed = key.compressed;
- key2.public = pubKeyBuf;
- key2.compressed = false;
- point.x = bignum.fromBuffer(key2.public.slice(1, 33), {size: 32});
- point.y = bignum.fromBuffer(key2.public.slice(33, 65), {size: 32});
+ point.x = bignum.fromBuffer(pubkey.slice(1, 33), {size: 32});
+ point.y = bignum.fromBuffer(pubkey.slice(33, 65), {size: 32});
return point;
};
//convert the Point into the Key containing a compressed public key
-Point.prototype.toKey = function() {
+Point.prototype.toUncompressedPubKey = function() {
var xbuf = this.x.toBuffer({size: 32});
var ybuf = this.y.toBuffer({size: 32});
- var key = new Key();
- key.compressed = false;
var prefix = new Buffer([0x04]);
- key.public = Buffer.concat([prefix, xbuf, ybuf]); //this might be wrong
- key.compressed = true;
- return key;
+ var pubkey = Buffer.concat([prefix, xbuf, ybuf]);
+ return pubkey;
};
module.exports = require('soop')(Point);
diff --git a/lib/node/SecureRandom.js b/lib/node/SecureRandom.js
new file mode 100644
index 0000000..3639f75
--- /dev/null
+++ b/lib/node/SecureRandom.js
@@ -0,0 +1,10 @@
+var imports = require('soop');
+var crypto = imports.crypto || require('crypto');
+
+var SecureRandom = require('../common/SecureRandom');
+
+SecureRandom.getRandomBuffer = function(size) {
+ return crypto.randomBytes(size);
+}
+
+module.exports = require('soop')(SecureRandom);
diff --git a/test/index.html b/test/index.html
index 6a86409..5f88d54 100644
--- a/test/index.html
+++ b/test/index.html
@@ -21,6 +21,7 @@
+
@@ -36,6 +37,7 @@
+
diff --git a/test/test.Curve.js b/test/test.Curve.js
new file mode 100644
index 0000000..2116450
--- /dev/null
+++ b/test/test.Curve.js
@@ -0,0 +1,37 @@
+'use strict';
+
+var chai = chai || require('chai');
+var bitcore = bitcore || require('../bitcore');
+var coinUtil = coinUtil || bitcore.util;
+var buffertools = require('buffertools');
+var bignum = require('bignum');
+
+var should = chai.should();
+var assert = chai.assert;
+
+var Curve = bitcore.Curve;
+
+describe('Curve', function() {
+
+ it('should initialize the main object', function() {
+ should.exist(Curve);
+ });
+
+ describe('getN', function() {
+ it('should return a big number', function() {
+ var N = Curve.getN();
+ should.exist(N);
+ N.toBuffer({size: 32}).toString('hex').length.should.equal(64);
+ });
+ });
+
+ describe('getG', function() {
+ it('should return a Point', function() {
+ var G = Curve.getG();
+ should.exist(G.x);
+ G.x.toBuffer({size: 32}).toString('hex').length.should.equal(64);
+ G.y.toBuffer({size: 32}).toString('hex').length.should.equal(64);
+ });
+ });
+
+});
diff --git a/test/test.Electrum.js b/test/test.Electrum.js
index 8e82c18..b6bfe8e 100644
--- a/test/test.Electrum.js
+++ b/test/test.Electrum.js
@@ -66,7 +66,6 @@ describe('Electrum', function() {
//change
pubkey = elec.generateChangePubKey(i);
addr = Address.fromPubKey(pubkey);
- console.log('change');
addr.as('base58').should.equal(expected_values.change[i]);
}
});
diff --git a/test/test.Key.js b/test/test.Key.js
index 25cdb26..d2bef61 100644
--- a/test/test.Key.js
+++ b/test/test.Key.js
@@ -7,6 +7,9 @@ var should = chai.should();
var assert = chai.assert;
var Key = bitcore.Key;
+var Point = bitcore.Point;
+var bignum = require('bignum');
+
describe('Key', function() {
it('should initialize the main object', function() {
should.exist(Key);
@@ -15,6 +18,20 @@ describe('Key', function() {
var k = new Key();
should.exist(k);
});
+ it('should set change compressed to uncompressed', function() {
+ var key = Key.generateSync();
+ key.public.length.should.equal(33);
+ key.compressed = false;
+ key.public.length.should.equal(65);
+ });
+ it('should change uncompressed to compressed', function() {
+ var key = Key.generateSync();
+ key.compressed = false;
+ var key2 = new Key();
+ key2.public = key.public;
+ key2.compressed = true;
+ key2.public.length.should.equal(33);
+ });
it('should be able to generateSync instance', function() {
var k = Key.generateSync();
should.exist(k);
@@ -112,4 +129,5 @@ describe('Key', function() {
var ret= k.verifySignatureSync(a_hash, sig2);
ret.should.equal(false);
});
+
});
diff --git a/test/test.Point.js b/test/test.Point.js
index 66e32c1..4ca45a5 100644
--- a/test/test.Point.js
+++ b/test/test.Point.js
@@ -49,8 +49,9 @@ describe('Point', function() {
var pubKeyBufCompressedHex = "0369b154b42ff9452c31251cb341d7db01ad603dc56d64f9c5fb9e7031b89a241d";
var key = new Key();
key.public = new Buffer(pubKeyBufCompressedHex, 'hex');
+ key.compressed = false;
- key.public.toString('hex').should.equal(a.toKey().public.toString('hex'));
+ key.public.toString('hex').should.equal(a.toUncompressedPubKey().toString('hex'));
});
it('should convert the public key of a Key into a Point', function() {
@@ -60,8 +61,9 @@ describe('Point', function() {
var pubKeyBufCompressedHex = "0369b154b42ff9452c31251cb341d7db01ad603dc56d64f9c5fb9e7031b89a241d";
var key = new Key();
key.public = new Buffer(pubKeyBufCompressedHex, 'hex');
+ key.compressed = false;
- var point = Point.fromKey(key);
+ var point = Point.fromUncompressedPubKey(key.public);
point.x.toBuffer({size: 32}).toString('hex').should.equal(axhex);
point.y.toBuffer({size: 32}).toString('hex').should.equal(ayhex);
});
diff --git a/test/test.SecureRandom.js b/test/test.SecureRandom.js
new file mode 100644
index 0000000..ab8207b
--- /dev/null
+++ b/test/test.SecureRandom.js
@@ -0,0 +1,57 @@
+'use strict';
+
+var chai = chai || require('chai');
+var bitcore = bitcore || require('../bitcore');
+var should = chai.should();
+var assert = chai.assert;
+var SecureRandom = bitcore.SecureRandom;
+
+describe('SecureRandom', function() {
+
+ describe('getRandomBuffer', function() {
+
+ it('should return a buffer', function() {
+ var bytes = SecureRandom.getRandomBuffer(8);
+ bytes.length.should.equal(8);
+ Buffer.isBuffer(bytes).should.equal(true);
+ });
+
+ it('should not equate two 256 bit random buffers', function() {
+ var bytes1 = SecureRandom.getRandomBuffer(32);
+ var bytes2 = SecureRandom.getRandomBuffer(32);
+ bytes1.toString('hex').should.not.equal(bytes2.toString('hex'));
+ });
+
+ });
+
+ describe('getPseudoRandomBuffer', function() {
+
+ it('should generate 7 random bytes', function() {
+ var buf = SecureRandom.getPseudoRandomBuffer(7);
+ buf.length.should.equal(7);
+ });
+
+ it('should generate 8 random bytes', function() {
+ var buf = SecureRandom.getPseudoRandomBuffer(8);
+ buf.length.should.equal(8);
+ });
+
+ it('should generate 9 random bytes', function() {
+ var buf = SecureRandom.getPseudoRandomBuffer(9);
+ buf.length.should.equal(9);
+ });
+
+ it('should generate 90 random bytes', function() {
+ var buf = SecureRandom.getPseudoRandomBuffer(90);
+ buf.length.should.equal(90);
+ });
+
+ it('should generate two 8 byte buffers that are not equal', function() {
+ var buf1 = SecureRandom.getPseudoRandomBuffer(8);
+ var buf2 = SecureRandom.getPseudoRandomBuffer(8);
+ buf1.toString('hex').should.not.equal(buf2.toString('hex'));
+ });
+
+ });
+
+});
diff --git a/util/util.js b/util/util.js
index f89dce8..a59df4b 100644
--- a/util/util.js
+++ b/util/util.js
@@ -10,7 +10,6 @@ if (inBrowser) {
browser = require('../browser/vendor-bundle.js');
}
-
var sha256 = exports.sha256 = function(data) {
return new Buffer(crypto.createHash('sha256').update(data).digest('binary'), 'binary');
};
@@ -336,36 +335,6 @@ var createSynchrotron = exports.createSynchrotron = function(fn) {
};
};
-/**
- * Generate a random 64-bit number.
- *
- * With ideas from node-uuid:
- * Copyright (c) 2010 Robert Kieffer
- * https://github.com/broofa/node-uuid/
- *
- * @returns Buffer random nonce
- */
-var generateNonce = exports.generateNonce = function() {
- var b32 = 0x100000000,
- ff = 0xff;
- var b = new Buffer(8),
- i = 0;
-
- // Generate eight random bytes
- r = Math.random() * b32;
- b[i++] = r & ff;
- b[i++] = (r = r >>> 8) & ff;
- b[i++] = (r = r >>> 8) & ff;
- b[i++] = (r = r >>> 8) & ff;
- r = Math.random() * b32;
- b[i++] = r & ff;
- b[i++] = (r = r >>> 8) & ff;
- b[i++] = (r = r >>> 8) & ff;
- b[i++] = (r = r >>> 8) & ff;
-
- return b;
-};
-
/**
* Decode difficulty bits.
*