Merge branch 'feature/secure-random'
Conflicts: lib/browser/Key.js
This commit is contained in:
commit
9575929162
|
@ -17,9 +17,11 @@ requireWhenAccessed('buffertools', 'buffertools');
|
||||||
requireWhenAccessed('Buffers.monkey', './patches/Buffers.monkey');
|
requireWhenAccessed('Buffers.monkey', './patches/Buffers.monkey');
|
||||||
requireWhenAccessed('config', './config');
|
requireWhenAccessed('config', './config');
|
||||||
requireWhenAccessed('const', './const');
|
requireWhenAccessed('const', './const');
|
||||||
|
requireWhenAccessed('Curve', './lib/Curve');
|
||||||
requireWhenAccessed('Deserialize', './lib/Deserialize');
|
requireWhenAccessed('Deserialize', './lib/Deserialize');
|
||||||
requireWhenAccessed('log', './util/log');
|
requireWhenAccessed('log', './util/log');
|
||||||
requireWhenAccessed('networks', './networks');
|
requireWhenAccessed('networks', './networks');
|
||||||
|
requireWhenAccessed('SecureRandom', './lib/SecureRandom');
|
||||||
requireWhenAccessed('util', './util/util');
|
requireWhenAccessed('util', './util/util');
|
||||||
requireWhenAccessed('EncodedData', './util/EncodedData');
|
requireWhenAccessed('EncodedData', './util/EncodedData');
|
||||||
requireWhenAccessed('VersionedData', './util/VersionedData');
|
requireWhenAccessed('VersionedData', './util/VersionedData');
|
||||||
|
|
|
@ -28,6 +28,7 @@ var modules = [
|
||||||
'lib/Block',
|
'lib/Block',
|
||||||
'lib/Bloom',
|
'lib/Bloom',
|
||||||
'lib/Connection',
|
'lib/Connection',
|
||||||
|
'lib/Curve',
|
||||||
'lib/Deserialize',
|
'lib/Deserialize',
|
||||||
'lib/Electrum',
|
'lib/Electrum',
|
||||||
'lib/Message',
|
'lib/Message',
|
||||||
|
@ -42,6 +43,7 @@ var modules = [
|
||||||
'lib/SINKey',
|
'lib/SINKey',
|
||||||
'lib/Script',
|
'lib/Script',
|
||||||
'lib/ScriptInterpreter',
|
'lib/ScriptInterpreter',
|
||||||
|
'lib/SecureRandom',
|
||||||
'lib/Sign',
|
'lib/Sign',
|
||||||
'lib/Transaction',
|
'lib/Transaction',
|
||||||
'lib/TransactionBuilder',
|
'lib/TransactionBuilder',
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
var Peer = require('../Peer');
|
var Peer = require('../lib/Peer');
|
||||||
var Connection = require('../Connection');
|
var Connection = require('../lib/Connection');
|
||||||
var dns = require('dns');
|
var dns = require('dns');
|
||||||
|
|
||||||
// get a peer from dns seed
|
// get a peer from dns seed
|
||||||
|
|
12
lib/BIP32.js
12
lib/BIP32.js
|
@ -3,6 +3,7 @@ var base58 = imports.base58 || require('base58-native').base58;
|
||||||
var coinUtil = imports.coinUtil || require('../util');
|
var coinUtil = imports.coinUtil || require('../util');
|
||||||
var Key = imports.Key || require('./Key');
|
var Key = imports.Key || require('./Key');
|
||||||
var Point = imports.Point || require('./Point');
|
var Point = imports.Point || require('./Point');
|
||||||
|
var SecureRandom = imports.SecureRandom || require('./SecureRandom');
|
||||||
var bignum = imports.bignum || require('bignum');
|
var bignum = imports.bignum || require('bignum');
|
||||||
var crypto = require('crypto');
|
var crypto = require('crypto');
|
||||||
var networks = require('../networks');
|
var networks = require('../networks');
|
||||||
|
@ -27,7 +28,7 @@ var BIP32 = function(bytes) {
|
||||||
this.depth = 0x00;
|
this.depth = 0x00;
|
||||||
this.parentFingerprint = new Buffer([0, 0, 0, 0]);
|
this.parentFingerprint = new Buffer([0, 0, 0, 0]);
|
||||||
this.childIndex = 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.eckey = Key.generateSync();
|
||||||
this.hasPrivateKey = true;
|
this.hasPrivateKey = true;
|
||||||
this.pubKeyHash = coinUtil.sha256ripe160(this.eckey.public);
|
this.pubKeyHash = coinUtil.sha256ripe160(this.eckey.public);
|
||||||
|
@ -288,17 +289,20 @@ BIP32.prototype.deriveChild = function(i) {
|
||||||
var ilGkey = new Key();
|
var ilGkey = new Key();
|
||||||
ilGkey.private = il;
|
ilGkey.private = il;
|
||||||
ilGkey.regenerateSync();
|
ilGkey.regenerateSync();
|
||||||
var ilG = Point.fromKey(ilGkey);
|
ilGkey.compressed = false;
|
||||||
|
var ilG = Point.fromUncompressedPubKey(ilGkey.public);
|
||||||
var oldkey = new Key();
|
var oldkey = new Key();
|
||||||
oldkey.public = this.eckey.public;
|
oldkey.public = this.eckey.public;
|
||||||
var Kpar = Point.fromKey(oldkey);
|
oldkey.compressed = false;
|
||||||
var newpub = Point.add(ilG, Kpar).toKey().public;
|
var Kpar = Point.fromUncompressedPubKey(oldkey.public);
|
||||||
|
var newpub = Point.add(ilG, Kpar).toUncompressedPubKey();
|
||||||
|
|
||||||
ret = new BIP32(null);
|
ret = new BIP32(null);
|
||||||
ret.chainCode = new Buffer(ir);
|
ret.chainCode = new Buffer(ir);
|
||||||
|
|
||||||
var eckey = new Key();
|
var eckey = new Key();
|
||||||
eckey.public = newpub;
|
eckey.public = newpub;
|
||||||
|
eckey.compressed = true;
|
||||||
ret.eckey = eckey;
|
ret.eckey = eckey;
|
||||||
ret.hasPrivateKey = false;
|
ret.hasPrivateKey = false;
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,7 +17,8 @@ var util = imports.util || require('../util');
|
||||||
var Parser = imports.Parser || require('../util/BinaryParser');
|
var Parser = imports.Parser || require('../util/BinaryParser');
|
||||||
var buffertools = imports.buffertools || require('buffertools');
|
var buffertools = imports.buffertools || require('buffertools');
|
||||||
var doubleSha256 = imports.doubleSha256 || util.twoSha256;
|
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;
|
var BIP0031_VERSION = 60000;
|
||||||
|
|
||||||
|
|
|
@ -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);
|
|
@ -31,8 +31,9 @@ Electrum.prototype.generatePubKey = function (n, for_change) {
|
||||||
var sequence_key = new Key();
|
var sequence_key = new Key();
|
||||||
sequence_key.private = sequence.toBuffer();
|
sequence_key.private = sequence.toBuffer();
|
||||||
sequence_key.regenerateSync();
|
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);
|
pt = Point.add(mpk_pt, sequence_pt);
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,5 @@
|
||||||
|
if (process.versions) {
|
||||||
|
module.exports = require('./node/SecureRandom');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
module.exports = require('./browser/SecureRandom');
|
|
@ -1,8 +1,10 @@
|
||||||
var ECKey = require('../../browser/vendor-bundle.js').ECKey;
|
var ECKey = require('../../browser/vendor-bundle.js').ECKey;
|
||||||
|
var SecureRandom = require('../SecureRandom');
|
||||||
|
var Curve = require('../Curve');
|
||||||
|
|
||||||
var Key = function() {
|
var Key = function() {
|
||||||
this._pub = null;
|
this._pub = null;
|
||||||
this.compressed = true; // default
|
this._compressed = true; // default
|
||||||
};
|
};
|
||||||
|
|
||||||
var bufferToArray = Key.bufferToArray = function(buffer) {
|
var bufferToArray = Key.bufferToArray = function(buffer) {
|
||||||
|
@ -16,14 +18,13 @@ var bufferToArray = Key.bufferToArray = function(buffer) {
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
Object.defineProperty(Key.prototype, 'public', {
|
Object.defineProperty(Key.prototype, 'public', {
|
||||||
set: function(p){
|
set: function(p){
|
||||||
if (!Buffer.isBuffer(p) ) {
|
if (!Buffer.isBuffer(p) ) {
|
||||||
throw new Error('Arg should be a buffer');
|
throw new Error('Arg should be a buffer');
|
||||||
}
|
}
|
||||||
var type = p[0];
|
var type = p[0];
|
||||||
this.compressed = type!==0x04;
|
this._compressed = type!==0x04;
|
||||||
this._pub = p;
|
this._pub = p;
|
||||||
},
|
},
|
||||||
get: function(){
|
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() {
|
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);
|
eck.setCompressed(true);
|
||||||
var pub = eck.getPub();
|
var pub = eck.getPub();
|
||||||
|
|
||||||
var ret = new Key();
|
ret = new Key();
|
||||||
ret.private = new Buffer(eck.priv.toByteArrayUnsigned());
|
ret.private = privbuf;
|
||||||
ret.public = new Buffer(pub);
|
ret._compressed = true;
|
||||||
|
ret.public = new Buffer(eck.getPub());
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -48,8 +83,8 @@ Key.prototype.regenerateSync = function() {
|
||||||
}
|
}
|
||||||
|
|
||||||
var eck = new ECKey(this.private.toString('hex'));
|
var eck = new ECKey(this.private.toString('hex'));
|
||||||
eck.setCompressed(this.compressed);
|
eck.setCompressed(this._compressed);
|
||||||
this.public = new Buffer(eck.getPub());
|
this._pub = new Buffer(eck.getPub());
|
||||||
return this;
|
return this;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -62,7 +97,7 @@ Key.prototype.signSync = function(hash) {
|
||||||
throw new Error('Arg should be a 32 bytes hash buffer');
|
throw new Error('Arg should be a 32 bytes hash buffer');
|
||||||
}
|
}
|
||||||
var eck = new ECKey(this.private.toString('hex'));
|
var eck = new ECKey(this.private.toString('hex'));
|
||||||
eck.setCompressed(this.compressed);
|
eck.setCompressed(this._compressed);
|
||||||
var signature = eck.sign(bufferToArray(hash));
|
var signature = eck.sign(bufferToArray(hash));
|
||||||
// return it as a buffer to keep c++ compatibility
|
// return it as a buffer to keep c++ compatibility
|
||||||
return new Buffer(signature);
|
return new Buffer(signature);
|
||||||
|
@ -92,7 +127,7 @@ Key.prototype.verifySignatureSync = function(hash, sig) {
|
||||||
|
|
||||||
var eck = new ECKey();
|
var eck = new ECKey();
|
||||||
eck.setPub(bufferToArray(self.public));
|
eck.setPub(bufferToArray(self.public));
|
||||||
eck.setCompressed(self.compressed);
|
eck.setCompressed(self._compressed);
|
||||||
var sigA = bufferToArray(sig);
|
var sigA = bufferToArray(sig);
|
||||||
var ret = eck.verify(bufferToArray(hash),sigA);
|
var ret = eck.verify(bufferToArray(hash),sigA);
|
||||||
return ret;
|
return ret;
|
||||||
|
|
|
@ -51,31 +51,20 @@ Point.add = function(p1, p2) {
|
||||||
};
|
};
|
||||||
|
|
||||||
//convert the public key of a Key into a Point
|
//convert the public key of a Key into a Point
|
||||||
Point.fromKey = function(key) {
|
Point.fromUncompressedPubKey = function(pubkey) {
|
||||||
var point = new Point();
|
var point = new Point();
|
||||||
var pubKeyBuf = new Buffer(key.public);
|
point.x = bignum.fromBuffer((new Buffer(pubkey)).slice(1, 33), {size: 32});
|
||||||
var key2 = new ECKey();
|
point.y = bignum.fromBuffer((new Buffer(pubkey)).slice(33, 65), {size: 32});
|
||||||
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});
|
|
||||||
return point;
|
return point;
|
||||||
};
|
};
|
||||||
|
|
||||||
//convert the Point into the Key containing a compressed public key
|
//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 xbuf = this.x.toBuffer({size: 32});
|
||||||
var ybuf = this.y.toBuffer({size: 32});
|
var ybuf = this.y.toBuffer({size: 32});
|
||||||
var key = new ECKey();
|
|
||||||
key.setCompressed(false);
|
|
||||||
var prefix = new Buffer([0x04]);
|
var prefix = new Buffer([0x04]);
|
||||||
var pub = Buffer.concat([prefix, xbuf, ybuf]); //this might be wrong
|
var pub = Buffer.concat([prefix, xbuf, ybuf]);
|
||||||
key.setPub(Key.bufferToArray(pub));
|
return pub;
|
||||||
key.setCompressed(true);
|
|
||||||
var key2 = new Key();
|
|
||||||
key2.public = new Buffer(key.getPub());
|
|
||||||
return key2;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
module.exports = require('soop')(Point);
|
module.exports = require('soop')(Point);
|
||||||
|
|
|
@ -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);
|
|
@ -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);
|
|
@ -1 +1,3 @@
|
||||||
module.exports = require('bindings')('KeyModule').Key;
|
var Key = require('bindings')('KeyModule').Key;
|
||||||
|
|
||||||
|
module.exports = Key;
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
"use strict";
|
"use strict";
|
||||||
|
|
||||||
var imports = require('soop').imports();
|
var imports = require('soop').imports();
|
||||||
var Key = imports.Key || require('../Key');
|
|
||||||
var bignum = imports.bignum || require('bignum');
|
var bignum = imports.bignum || require('bignum');
|
||||||
|
var CPPKey = imports.CPPKey || require('bindings')('KeyModule').Key;
|
||||||
var assert = require('assert');
|
var assert = require('assert');
|
||||||
|
|
||||||
//a point on the secp256k1 curve
|
//a point on the secp256k1 curve
|
||||||
|
@ -13,41 +13,27 @@ var Point = function(x, y) {
|
||||||
};
|
};
|
||||||
|
|
||||||
Point.add = function(p1, p2) {
|
Point.add = function(p1, p2) {
|
||||||
var key1 = p1.toKey();
|
var u1 = p1.toUncompressedPubKey();
|
||||||
key1.compressed = false;
|
var u2 = p2.toUncompressedPubKey();
|
||||||
var key2 = p2.toKey();
|
var pubKey = CPPKey.addUncompressed(u1, u2);
|
||||||
key2.compressed = false;
|
return Point.fromUncompressedPubKey(pubKey);
|
||||||
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);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
//convert the public key of a Key into a Point
|
//convert the public key of a Key into a Point
|
||||||
Point.fromKey = function(key) {
|
Point.fromUncompressedPubKey = function(pubkey) {
|
||||||
var point = new Point();
|
var point = new Point();
|
||||||
var pubKeyBuf = new Buffer(key.public);
|
point.x = bignum.fromBuffer(pubkey.slice(1, 33), {size: 32});
|
||||||
var key2 = new Key();
|
point.y = bignum.fromBuffer(pubkey.slice(33, 65), {size: 32});
|
||||||
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});
|
|
||||||
return point;
|
return point;
|
||||||
};
|
};
|
||||||
|
|
||||||
//convert the Point into the Key containing a compressed public key
|
//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 xbuf = this.x.toBuffer({size: 32});
|
||||||
var ybuf = this.y.toBuffer({size: 32});
|
var ybuf = this.y.toBuffer({size: 32});
|
||||||
var key = new Key();
|
|
||||||
key.compressed = false;
|
|
||||||
var prefix = new Buffer([0x04]);
|
var prefix = new Buffer([0x04]);
|
||||||
key.public = Buffer.concat([prefix, xbuf, ybuf]); //this might be wrong
|
var pubkey = Buffer.concat([prefix, xbuf, ybuf]);
|
||||||
key.compressed = true;
|
return pubkey;
|
||||||
return key;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
module.exports = require('soop')(Point);
|
module.exports = require('soop')(Point);
|
||||||
|
|
|
@ -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);
|
|
@ -21,6 +21,7 @@
|
||||||
<script src="test.Block.js"></script>
|
<script src="test.Block.js"></script>
|
||||||
<script src="test.Bloom.js"></script>
|
<script src="test.Bloom.js"></script>
|
||||||
<script src="test.Connection.js"></script>
|
<script src="test.Connection.js"></script>
|
||||||
|
<script src="test.Curve.js"></script>
|
||||||
<script src="test.EncodedData.js"></script>
|
<script src="test.EncodedData.js"></script>
|
||||||
<script src="test.Electrum.js"></script>
|
<script src="test.Electrum.js"></script>
|
||||||
<script src="test.Key.js"></script>
|
<script src="test.Key.js"></script>
|
||||||
|
@ -36,6 +37,7 @@
|
||||||
<script src="test.RpcClient.js"></script>
|
<script src="test.RpcClient.js"></script>
|
||||||
<script src="test.Script.js"></script>
|
<script src="test.Script.js"></script>
|
||||||
<script src="test.ScriptInterpreter.js"></script>
|
<script src="test.ScriptInterpreter.js"></script>
|
||||||
|
<script src="test.SecureRandom.js"></script>
|
||||||
<script src="test.sighash.js"></script>
|
<script src="test.sighash.js"></script>
|
||||||
<script src="test.SIN.js"></script>
|
<script src="test.SIN.js"></script>
|
||||||
<script src="test.SINKey.js"></script>
|
<script src="test.SINKey.js"></script>
|
||||||
|
|
|
@ -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);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
});
|
|
@ -66,7 +66,6 @@ describe('Electrum', function() {
|
||||||
//change
|
//change
|
||||||
pubkey = elec.generateChangePubKey(i);
|
pubkey = elec.generateChangePubKey(i);
|
||||||
addr = Address.fromPubKey(pubkey);
|
addr = Address.fromPubKey(pubkey);
|
||||||
console.log('change');
|
|
||||||
addr.as('base58').should.equal(expected_values.change[i]);
|
addr.as('base58').should.equal(expected_values.change[i]);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
|
@ -7,6 +7,9 @@ var should = chai.should();
|
||||||
var assert = chai.assert;
|
var assert = chai.assert;
|
||||||
|
|
||||||
var Key = bitcore.Key;
|
var Key = bitcore.Key;
|
||||||
|
var Point = bitcore.Point;
|
||||||
|
var bignum = require('bignum');
|
||||||
|
|
||||||
describe('Key', function() {
|
describe('Key', function() {
|
||||||
it('should initialize the main object', function() {
|
it('should initialize the main object', function() {
|
||||||
should.exist(Key);
|
should.exist(Key);
|
||||||
|
@ -15,6 +18,20 @@ describe('Key', function() {
|
||||||
var k = new Key();
|
var k = new Key();
|
||||||
should.exist(k);
|
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() {
|
it('should be able to generateSync instance', function() {
|
||||||
var k = Key.generateSync();
|
var k = Key.generateSync();
|
||||||
should.exist(k);
|
should.exist(k);
|
||||||
|
@ -112,4 +129,5 @@ describe('Key', function() {
|
||||||
var ret= k.verifySignatureSync(a_hash, sig2);
|
var ret= k.verifySignatureSync(a_hash, sig2);
|
||||||
ret.should.equal(false);
|
ret.should.equal(false);
|
||||||
});
|
});
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
|
@ -49,8 +49,9 @@ describe('Point', function() {
|
||||||
var pubKeyBufCompressedHex = "0369b154b42ff9452c31251cb341d7db01ad603dc56d64f9c5fb9e7031b89a241d";
|
var pubKeyBufCompressedHex = "0369b154b42ff9452c31251cb341d7db01ad603dc56d64f9c5fb9e7031b89a241d";
|
||||||
var key = new Key();
|
var key = new Key();
|
||||||
key.public = new Buffer(pubKeyBufCompressedHex, 'hex');
|
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() {
|
it('should convert the public key of a Key into a Point', function() {
|
||||||
|
@ -60,8 +61,9 @@ describe('Point', function() {
|
||||||
var pubKeyBufCompressedHex = "0369b154b42ff9452c31251cb341d7db01ad603dc56d64f9c5fb9e7031b89a241d";
|
var pubKeyBufCompressedHex = "0369b154b42ff9452c31251cb341d7db01ad603dc56d64f9c5fb9e7031b89a241d";
|
||||||
var key = new Key();
|
var key = new Key();
|
||||||
key.public = new Buffer(pubKeyBufCompressedHex, 'hex');
|
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.x.toBuffer({size: 32}).toString('hex').should.equal(axhex);
|
||||||
point.y.toBuffer({size: 32}).toString('hex').should.equal(ayhex);
|
point.y.toBuffer({size: 32}).toString('hex').should.equal(ayhex);
|
||||||
});
|
});
|
||||||
|
|
|
@ -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'));
|
||||||
|
});
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
});
|
31
util/util.js
31
util/util.js
|
@ -10,7 +10,6 @@ if (inBrowser) {
|
||||||
browser = require('../browser/vendor-bundle.js');
|
browser = require('../browser/vendor-bundle.js');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
var sha256 = exports.sha256 = function(data) {
|
var sha256 = exports.sha256 = function(data) {
|
||||||
return new Buffer(crypto.createHash('sha256').update(data).digest('binary'), 'binary');
|
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.
|
* Decode difficulty bits.
|
||||||
*
|
*
|
||||||
|
|
Loading…
Reference in New Issue