This commit is contained in:
Christopher Jeffrey 2016-03-19 10:03:55 -07:00
parent bd54b42dc4
commit 5153e0e1f0
10 changed files with 161 additions and 320 deletions

View File

@ -7,6 +7,13 @@
var bcoin = exports; var bcoin = exports;
var utils = require('./bcoin/utils'); var utils = require('./bcoin/utils');
var assert = utils.assert; var assert = utils.assert;
var fs;
try {
fs = require('f' + 's');
} catch (e) {
;
}
bcoin.isBrowser = bcoin.isBrowser =
(typeof process !== 'undefined' && process.browser) (typeof process !== 'undefined' && process.browser)
@ -19,7 +26,7 @@ bcoin.profile = +process.env.BCOIN_PROFILE === 1;
bcoin.fresh = +process.env.BCOIN_FRESH === 1; bcoin.fresh = +process.env.BCOIN_FRESH === 1;
bcoin.ensurePrefix = function ensurePrefix() { bcoin.ensurePrefix = function ensurePrefix() {
if (!bcoin.fs) if (bcoin.isBrowser)
return; return;
if (bcoin._ensured) if (bcoin._ensured)
@ -31,21 +38,25 @@ bcoin.ensurePrefix = function ensurePrefix() {
bcoin.rimraf(bcoin.prefix); bcoin.rimraf(bcoin.prefix);
try { try {
bcoin.fs.statSync(bcoin.prefix); fs.statSync(bcoin.prefix);
} catch (e) { } catch (e) {
bcoin.fs.mkdirSync(bcoin.prefix, 0750); fs.mkdirSync(bcoin.prefix, 0750);
} }
}; };
bcoin.rimraf = function rimraf(file) { bcoin.rimraf = function rimraf(file) {
if (!bcoin.cp) var cp;
if (bcoin.isBrowser)
return; return;
cp = require('child_' + 'process');
assert(typeof file === 'string'); assert(typeof file === 'string');
assert(file !== '/'); assert(file !== '/');
assert(file !== process.env.HOME); assert(file !== process.env.HOME);
bcoin.cp.execFileSync('rm', ['-rf', file], { stdio: 'ignore' }); cp.execFileSync('rm', ['-rf', file], { stdio: 'ignore' });
}; };
bcoin.debug = function debug() { bcoin.debug = function debug() {
@ -57,10 +68,10 @@ bcoin.debug = function debug() {
process.stdout.write(msg); process.stdout.write(msg);
} }
if (bcoin.debugFile && bcoin.fs) { if (bcoin.debugFile && !bcoin.isBrowser) {
if (!bcoin._debug) { if (!bcoin._debug) {
bcoin.ensurePrefix(); bcoin.ensurePrefix();
bcoin._debug = bcoin.fs.createWriteStream( bcoin._debug = fs.createWriteStream(
bcoin.prefix + '/debug.log', { flags: 'a' }); bcoin.prefix + '/debug.log', { flags: 'a' });
} }
msg = utils.format(args, false); msg = utils.format(args, false);
@ -68,31 +79,9 @@ bcoin.debug = function debug() {
} }
}; };
bcoin.bn = require('bn.js');
bcoin.elliptic = require('elliptic');
if (!bcoin.isBrowser) {
bcoin.fs = require('f' + 's');
bcoin.crypto = require('cry' + 'pto');
bcoin.net = require('n' + 'et');
bcoin.cp = require('child_' + 'process');
try {
bcoin.secp256k1 = require('secp' + '256k1');
} catch (e) {
;
}
} else {
bcoin.hash = require('hash.js');
}
bcoin.ecdsa = bcoin.elliptic.ec('secp256k1');
assert(!bcoin.ecdsa.signature);
bcoin.ecdsa.signature = require('elliptic/lib/elliptic/ec/signature');
assert(!bcoin.ecdsa.keypair);
bcoin.ecdsa.keypair = require('elliptic/lib/elliptic/ec/key');
bcoin.utils = utils; bcoin.utils = utils;
bcoin.utils.debug = bcoin.debug; bcoin.utils.debug = bcoin.debug;
bcoin.utils.ensurePrefix = bcoin.ensurePrefix;
bcoin.reader = require('./bcoin/reader'); bcoin.reader = require('./bcoin/reader');
bcoin.writer = require('./bcoin/writer'); bcoin.writer = require('./bcoin/writer');
bcoin.profiler = require('./bcoin/profiler'); bcoin.profiler = require('./bcoin/profiler');

View File

@ -5,11 +5,11 @@
*/ */
var EventEmitter = require('events').EventEmitter; var EventEmitter = require('events').EventEmitter;
var fs = require('fs');
var bcoin = require('../bcoin'); var bcoin = require('../bcoin');
var network = bcoin.protocol.network; var network = bcoin.protocol.network;
var utils = require('./utils'); var utils = require('./utils');
var assert = utils.assert; var assert = utils.assert;
var fs = bcoin.fs;
var pad32 = utils.pad32; var pad32 = utils.pad32;
var MAX_FILE_SIZE = 128 * 1024 * 1024; var MAX_FILE_SIZE = 128 * 1024 * 1024;

View File

@ -9,6 +9,20 @@ var elliptic = require('elliptic');
var utils = require('./utils'); var utils = require('./utils');
var assert = utils.assert; var assert = utils.assert;
var ec = exports; var ec = exports;
var crypto, secp256k1;
if (!bcoin.isBrowser)
crypto = require('cry' + 'pto');
try {
secp256k1 = require('secp' + '256k1');
} catch (e) {
;
}
ec.elliptic = elliptic.ec('secp256k1');
ec.signature = require('elliptic/lib/elliptic/ec/signature');
ec.keypair = require('elliptic/lib/elliptic/ec/key');
/** /**
* EC * EC
@ -17,12 +31,12 @@ var ec = exports;
ec.generatePrivateKey = function generatePrivateKey() { ec.generatePrivateKey = function generatePrivateKey() {
var key, priv; var key, priv;
if (bcoin.secp256k1 && bcoin.crypto) { if (secp256k1 && crypto) {
do { do {
priv = bcoin.crypto.randomBytes(32); priv = crypto.randomBytes(32);
} while (!bcoin.secp256k1.privateKeyVerify(priv)); } while (!secp256k1.privateKeyVerify(priv));
} else { } else {
key = bcoin.ecdsa.genKeyPair(); key = ec.elliptic.genKeyPair();
priv = new Buffer(key.getPrivate().toArray('be', 32)); priv = new Buffer(key.getPrivate().toArray('be', 32));
} }
@ -32,16 +46,16 @@ ec.generatePrivateKey = function generatePrivateKey() {
ec.publicKeyCreate = function publicKeyCreate(priv, compressed) { ec.publicKeyCreate = function publicKeyCreate(priv, compressed) {
assert(Buffer.isBuffer(priv)); assert(Buffer.isBuffer(priv));
if (bcoin.secp256k1) if (secp256k1)
return bcoin.secp256k1.publicKeyCreate(priv, compressed); return secp256k1.publicKeyCreate(priv, compressed);
priv = bcoin.ecdsa.keyPair({ priv: priv }).getPublic(compressed, 'array'); priv = ec.elliptic.keyPair({ priv: priv }).getPublic(compressed, 'array');
return new Buffer(priv); return new Buffer(priv);
}; };
ec.random = function random(size) { ec.random = function random(size) {
if (bcoin.crypto) if (crypto)
return bcoin.crypto.randomBytes(size); return crypto.randomBytes(size);
return new Buffer(elliptic.rand(size)); return new Buffer(elliptic.rand(size));
}; };
@ -63,23 +77,23 @@ ec.verify = function verify(msg, sig, key, historical) {
sig = ec.normalizeLength(sig); sig = ec.normalizeLength(sig);
try { try {
if (bcoin.secp256k1) { if (secp256k1) {
// secp256k1 fails on high s values. This is // secp256k1 fails on high s values. This is
// bad for verifying historical data. // bad for verifying historical data.
if (historical) if (historical)
sig = ec.toLowS(sig); sig = ec.toLowS(sig);
// Import from DER. // Import from DER.
sig = bcoin.secp256k1.signatureImport(sig); sig = secp256k1.signatureImport(sig);
// This is supposed to lower the S value // This is supposed to lower the S value
// but it doesn't seem to work. // but it doesn't seem to work.
// if (historical) // if (historical)
// sig = bcoin.secp256k1.signatureNormalize(sig); // sig = bcoin.secp256k1.signatureNormalize(sig);
return bcoin.secp256k1.verify(msg, sig, key); return secp256k1.verify(msg, sig, key);
} }
return bcoin.ecdsa.verify(msg, sig, key); return ec.elliptic.verify(msg, sig, key);
} catch (e) { } catch (e) {
utils.debug('Elliptic threw during verification:'); utils.debug('Elliptic threw during verification:');
utils.debug(e.stack + ''); utils.debug(e.stack + '');
@ -98,18 +112,18 @@ ec.sign = function sign(msg, key) {
if (key.getPrivateKey) if (key.getPrivateKey)
key = key.getPrivateKey(); key = key.getPrivateKey();
if (bcoin.secp256k1) { if (secp256k1) {
// Sign message // Sign message
sig = bcoin.secp256k1.sign(msg, key); sig = secp256k1.sign(msg, key);
// Ensure low S value // Ensure low S value
sig = bcoin.secp256k1.signatureNormalize(sig.signature); sig = secp256k1.signatureNormalize(sig.signature);
// Convert to DER array // Convert to DER array
sig = bcoin.secp256k1.signatureExport(sig); sig = secp256k1.signatureExport(sig);
} else { } else {
// Sign message and ensure low S value // Sign message and ensure low S value
sig = bcoin.ecdsa.sign(msg, key, { canonical: true }); sig = ec.elliptic.sign(msg, key, { canonical: true });
// Convert to DER array // Convert to DER array
sig = new Buffer(sig.toDER()); sig = new Buffer(sig.toDER());
@ -168,7 +182,7 @@ ec.isLowS = function isLowS(sig) {
assert(Buffer.isBuffer(sig)); assert(Buffer.isBuffer(sig));
try { try {
sig = new bcoin.ecdsa.signature(sig); sig = new ec.signature(sig);
} catch (e) { } catch (e) {
return false; return false;
} }
@ -182,7 +196,7 @@ ec.isLowS = function isLowS(sig) {
// If S is greater than half the order, // If S is greater than half the order,
// it's too high. // it's too high.
if (sig.s.cmp(bcoin.ecdsa.nh) > 0) if (sig.s.cmp(ec.elliptic.nh) > 0)
return false; return false;
return true; return true;
@ -193,7 +207,7 @@ ec.toLowS = function toLowS(sig) {
assert(Buffer.isBuffer(sig)); assert(Buffer.isBuffer(sig));
try { try {
sig = new bcoin.ecdsa.signature(sig); sig = new ec.signature(sig);
} catch (e) { } catch (e) {
return sig; return sig;
} }
@ -201,8 +215,8 @@ ec.toLowS = function toLowS(sig) {
// If S is greater than half the order, // If S is greater than half the order,
// it's too high. // it's too high.
if (sig.s.cmp(bcoin.ecdsa.nh) > 0) if (sig.s.cmp(ec.elliptic.nh) > 0)
sig.s = bcoin.ecdsa.n.sub(sig.s); sig.s = ec.elliptic.n.sub(sig.s);
return new Buffer(sig.toDER()); return new Buffer(sig.toDER());
}; };

View File

@ -53,9 +53,12 @@
var bcoin = require('../bcoin'); var bcoin = require('../bcoin');
var bn = require('bn.js'); var bn = require('bn.js');
var utils = require('./utils'); var utils = require('./utils');
var ec = require('./ec');
var assert = utils.assert; var assert = utils.assert;
var constants = bcoin.protocol.constants; var constants = bcoin.protocol.constants;
var network = bcoin.protocol.network; var network = bcoin.protocol.network;
var KeyPair = require('./keypair');
var LRU = require('./lru');
var english = require('../../etc/english.json'); var english = require('../../etc/english.json');
@ -83,12 +86,12 @@ HDSeed.prototype.createSeed = function createSeed() {
return this.seed; return this.seed;
if (!this.entropy) if (!this.entropy)
this.entropy = bcoin.ec.random(this.bits / 8); this.entropy = ec.random(this.bits / 8);
if (!this.mnemonic) if (!this.mnemonic)
this.mnemonic = this.createMnemonic(this.entropy); this.mnemonic = this.createMnemonic(this.entropy);
this.seed = pbkdf2(this.mnemonic, 'mnemonic' + this.passphrase, 2048, 64); this.seed = utils.pbkdf2(this.mnemonic, 'mnemonic' + this.passphrase, 2048, 64);
return this.seed; return this.seed;
}; };
@ -125,7 +128,7 @@ HD.fromSeed = function fromSeed(options) {
return HDPrivateKey.fromSeed(options); return HDPrivateKey.fromSeed(options);
}; };
HD.cache = new bcoin.lru(500); HD.cache = new LRU(500);
/** /**
* HD Private Key * HD Private Key
@ -183,107 +186,6 @@ function HDPrivateKey(options) {
utils.inherits(HDPrivateKey, HD); utils.inherits(HDPrivateKey, HD);
HDPrivateKey.prototype.scan44 = function scan44(options, txByAddress, callback) {
var self = this;
var accounts = [];
var isAccount = this.isAccount44();
var coinType, root;
// 0. get the root node
if (!isAccount) {
coinType = options.coinType;
if (coinType == null)
coinType = network[this.network].type === 'main' ? 0 : 1;
assert(utils.isFinite(coinType));
root = this
.derive(44, true)
.derive(coinType, true);
}
return (function chainCheck(chainConstant) {
return (function scanner(accountIndex) {
var addressIndex = 0;
var total = 0;
var gap = 0;
// 1. derive the first account's node (index = 0)
var account = isAccount
? self
: root.derive(accountIndex, true);
if (isAccount)
accountIndex = utils.readU32BE(self.childIndex) - constants.hd.hardened;
// 2. derive the external chain node of this account
var chain = account.derive(chainConstant);
// 3. scan addresses of the external chain;
// respect the gap limit described below
return (function next() {
var address = chain.derive(addressIndex++);
var addr = bcoin.address.compileData(address.publicKey);
return txByAddress(addr, function(err, txs) {
var result;
if (err)
return callback(err);
if (txs) {
if (typeof txs === 'boolean')
result = txs;
else if (typeof txs === 'number')
result = txs > 0;
else if (Array.isArray(txs))
result = txs.length > 0;
else
result = false;
}
if (result) {
total++;
gap = 0;
return next();
}
if (++gap < 20)
return next();
assert(accounts[accountIndex] == null || chainConstant === 1);
if (chainConstant === 0)
accounts[accountIndex] = { addressDepth: addressIndex - gap };
else
accounts[accountIndex].changeDepth = addressIndex - gap;
// 4. if no transactions are found on the
// external chain, stop discovery
if (total === 0) {
if (chainConstant === 0)
return chainCheck(1);
if (isAccount)
return callback(null, accounts[accountIndex]);
return callback(null, accounts);
}
// 5. if there are some transactions, increase
// the account index and go to step 1
if (isAccount) {
if (chainConstant === 0)
return chainCheck(1);
return callback(null, accounts[accountIndex]);
}
return scanner(accountIndex + 1);
});
})();
})(0);
})(0);
};
HDPrivateKey.prototype.deriveAccount44 = function deriveAccount44(options) { HDPrivateKey.prototype.deriveAccount44 = function deriveAccount44(options) {
var coinType, accountIndex, child; var coinType, accountIndex, child;
@ -356,73 +258,6 @@ HDPrivateKey.prototype.deriveAddress = function deriveAddress(accountIndex, addr
}); });
}; };
HDPrivateKey.prototype.scan45 = function scan45(options, txByAddress, callback) {
var cosigners = [];
var root;
root = this.isPurpose45()
? this
: this.derivePurpose45(options);
return (function chainCheck(chainConstant) {
return (function scanner(cosignerIndex) {
var addressIndex = 0;
var total = 0;
var gap = 0;
var cosigner = root.derive(cosignerIndex);
var chain = cosigner.derive(chainConstant);
return (function next() {
var address = chain.derive(addressIndex++);
var addr = bcoin.address.compileData(address.publicKey);
return txByAddress(addr, function(err, txs) {
var result;
if (err)
return callback(err);
if (txs) {
if (typeof txs === 'boolean')
result = txs;
else if (typeof txs === 'number')
result = txs > 0;
else if (Array.isArray(txs))
result = txs.length > 0;
else
result = false;
}
if (result) {
total++;
gap = 0;
return next();
}
if (++gap < 20)
return next();
assert(cosigners[cosignerIndex] == null || chainConstant === 1);
if (chainConstant === 0)
cosigners[cosignerIndex] = { addressDepth: addressIndex - gap };
else
cosigners[cosignerIndex].changeDepth = addressIndex - gap;
if (total === 0) {
if (chainConstant === 0)
return chainCheck(1);
return callback(null, cosigners);
}
return scanner(cosignerIndex + 1);
});
})();
})(0);
})(0);
};
HDPrivateKey.prototype.derivePurpose45 = function derivePurpose45() { HDPrivateKey.prototype.derivePurpose45 = function derivePurpose45() {
var child; var child;
@ -591,10 +426,10 @@ HDPrivateKey.fromSeed = function fromSeed(options) {
HDPrivateKey._generate = function _generate(privateKey, entropy) { HDPrivateKey._generate = function _generate(privateKey, entropy) {
if (!privateKey) if (!privateKey)
privateKey = bcoin.ec.generatePrivateKey(); privateKey = ec.generatePrivateKey();
if (!entropy) if (!entropy)
entropy = bcoin.ec.random(32); entropy = ec.random(32);
return { return {
version: null, version: null,
@ -685,7 +520,7 @@ HDPrivateKey.prototype._build = function _build(data) {
this.privateKey = data.privateKey; this.privateKey = data.privateKey;
this.checksum = null; this.checksum = null;
this.publicKey = bcoin.ec.publicKeyCreate(data.privateKey, true); this.publicKey = ec.publicKeyCreate(data.privateKey, true);
this.fingerPrint = null; this.fingerPrint = null;
this.hdPrivateKey = this; this.hdPrivateKey = this;
@ -746,7 +581,7 @@ HDPrivateKey.prototype.derive = function derive(index, hardened) {
privateKey = new Buffer(leftPart privateKey = new Buffer(leftPart
.add(new bn(this.privateKey)) .add(new bn(this.privateKey))
.mod(bcoin.ecdsa.curve.n) .mod(ec.elliptic.curve.n)
.toArray('be', 32)); .toArray('be', 32));
if (!this.fingerPrint) { if (!this.fingerPrint) {
@ -1107,8 +942,8 @@ HDPublicKey.prototype.derive = function derive(index, hardened) {
leftPart = new bn(hash.slice(0, 32)); leftPart = new bn(hash.slice(0, 32));
chainCode = hash.slice(32, 64); chainCode = hash.slice(32, 64);
publicPoint = bcoin.ecdsa.curve.decodePoint(this.publicKey); publicPoint = ec.elliptic.curve.decodePoint(this.publicKey);
point = bcoin.ecdsa.curve.g.mul(leftPart).add(publicPoint); point = ec.elliptic.curve.g.mul(leftPart).add(publicPoint);
publicKey = new Buffer(point.encode('array', true)); publicKey = new Buffer(point.encode('array', true));
if (!this.fingerPrint) { if (!this.fingerPrint) {
@ -1165,26 +1000,26 @@ HDPublicKey.prototype.derivePath = function derivePath(path) {
[HDPrivateKey, HDPublicKey].forEach(function(HD) { [HDPrivateKey, HDPublicKey].forEach(function(HD) {
HD.prototype.getPrivateKey = function getPrivateKey() { HD.prototype.getPrivateKey = function getPrivateKey() {
return bcoin.keypair.prototype.getPrivateKey.apply(this, arguments); return KeyPair.prototype.getPrivateKey.apply(this, arguments);
}; };
HD.prototype.getPublicKey = function getPublicKey() { HD.prototype.getPublicKey = function getPublicKey() {
return bcoin.keypair.prototype.getPublicKey.apply(this, arguments); return KeyPair.prototype.getPublicKey.apply(this, arguments);
}; };
HD.prototype.sign = function sign() { HD.prototype.sign = function sign() {
return bcoin.keypair.prototype.sign.apply(this, arguments); return KeyPair.prototype.sign.apply(this, arguments);
}; };
HD.prototype.verify = function verify() { HD.prototype.verify = function verify() {
return bcoin.keypair.prototype.verify.apply(this, arguments); return KeyPair.prototype.verify.apply(this, arguments);
}; };
HD.prototype.compressed = true; HD.prototype.compressed = true;
}); });
HDPrivateKey.prototype.toSecret = function toSecret() { HDPrivateKey.prototype.toSecret = function toSecret() {
return bcoin.keypair.toSecret.call(this); return KeyPair.toSecret.call(this);
}; };
/** /**
@ -1197,73 +1032,6 @@ function array32(data) {
return b; return b;
} }
/**
* PDKBF2
* Credit to: https://github.com/stayradiated/pbkdf2-sha512
* Copyright (c) 2010-2011 Intalio Pte, All Rights Reserved
* Copyright (c) 2014, JP Richardson
*/
function pbkdf2(key, salt, iterations, dkLen) {
'use strict';
if (bcoin.crypto && bcoin.crypto.pbkdf2Sync)
return bcoin.crypto.pbkdf2Sync(key, salt, iterations, dkLen, 'sha512');
var hLen = 64;
if (dkLen > (Math.pow(2, 32) - 1) * hLen)
throw Error('Requested key length too long');
if (typeof key !== 'string' && typeof key.length !== 'number')
throw new TypeError('key must a string or array');
if (typeof salt !== 'string' && typeof salt.length !== 'number')
throw new TypeError('salt must a string or array');
if (typeof key === 'string')
key = new Buffer(key, 'ascii');
if (typeof salt === 'string')
salt = new Buffer(salt, 'ascii');
var DK = new Buffer(dkLen);
var U = new Buffer(hLen);
var T = new Buffer(hLen);
var block1 = new Buffer(salt.length + 4);
var l = Math.ceil(dkLen / hLen);
var r = dkLen - (l - 1) * hLen;
var i, j, k, destPos, len;
utils.copy(salt.slice(0, salt.length), block1, 0);
for (i = 1; i <= l; i++) {
block1[salt.length + 0] = i >> 24 & 0xff;
block1[salt.length + 1] = i >> 16 & 0xff;
block1[salt.length + 2] = i >> 8 & 0xff;
block1[salt.length + 3] = i >> 0 & 0xff;
U = utils.sha512hmac(block1, key);
utils.copy(U.slice(0, hLen), T, 0);
for (j = 1; j < iterations; j++) {
U = utils.sha512hmac(U, key);
for (k = 0; k < hLen; k++)
T[k] ^= U[k];
}
destPos = (i - 1) * hLen;
len = i === l ? r : hLen;
utils.copy(T.slice(0, len), DK, 0);
}
return DK;
}
/** /**
* Expose * Expose
*/ */
@ -1275,7 +1043,6 @@ exports.priv = HDPrivateKey;
exports.pub = HDPublicKey; exports.pub = HDPublicKey;
exports.privateKey = HDPrivateKey; exports.privateKey = HDPrivateKey;
exports.publicKey = HDPublicKey; exports.publicKey = HDPublicKey;
exports.pbkdf2 = pbkdf2;
exports.fromJSON = HDPrivateKey.fromJSON; exports.fromJSON = HDPrivateKey.fromJSON;
module.exports = HD; module.exports = HD;

View File

@ -180,7 +180,7 @@ Peer.prototype._init = function init() {
Peer.prototype.createSocket = function createSocket(port, host) { Peer.prototype.createSocket = function createSocket(port, host) {
var self = this; var self = this;
var socket; var socket, net;
assert(port != null); assert(port != null);
assert(host); assert(host);
@ -190,10 +190,11 @@ Peer.prototype.createSocket = function createSocket(port, host) {
if (this._createSocket) { if (this._createSocket) {
socket = this._createSocket(port, host); socket = this._createSocket(port, host);
} else if (bcoin.isBrowser) {
throw new Error('Please include a `createSocket` callback.');
} else { } else {
if (!bcoin.net) net = require('n' + 'et');
throw new Error('Please include a `createSocket` callback.'); socket = net.connect(port, host);
socket = bcoin.net.connect(port, host);
} }
utils.debug( utils.debug(

View File

@ -295,16 +295,19 @@ Pool.prototype.getHeaders = function getHeaders(peer, top, stop, callback) {
Pool.prototype.startServer = function startServer() { Pool.prototype.startServer = function startServer() {
var self = this; var self = this;
var net;
if (!bcoin.net) if (bcoin.isBrowser)
return; return;
net = require('n' + 'et');
if (!this.options.listen) if (!this.options.listen)
return; return;
assert(!this.server); assert(!this.server);
this.server = new bcoin.net.Server(); this.server = new net.Server();
this.server.on('connection', function(socket) { this.server.on('connection', function(socket) {
self._addLeech(socket); self._addLeech(socket);
@ -321,7 +324,7 @@ Pool.prototype.startServer = function startServer() {
}; };
Pool.prototype.stopServer = function stopServer() { Pool.prototype.stopServer = function stopServer() {
if (!bcoin.net) if (bcoin.isBrowser)
return; return;
if (!this.server) if (!this.server)

View File

@ -7,11 +7,12 @@
var bcoin = require('../bcoin'); var bcoin = require('../bcoin');
var utils = require('./utils'); var utils = require('./utils');
var assert = utils.assert; var assert = utils.assert;
var fs = bcoin.fs; var fs, profiler;
var profiler;
if (bcoin.profile && !bcoin.isBrowser) if (bcoin.profile && !bcoin.isBrowser) {
profiler = require('v8-' + 'profiler'); profiler = require('v8-' + 'profiler');
fs = require('f' + 's');
}
if (profiler) { if (profiler) {
utils.nextTick(function() { utils.nextTick(function() {

View File

@ -14,11 +14,10 @@ utils.isBrowser =
(typeof process !== 'undefined' && process.browser) (typeof process !== 'undefined' && process.browser)
|| typeof window !== 'undefined'; || typeof window !== 'undefined';
if (!utils.isBrowser) { if (!utils.isBrowser)
crypto = require('cry' + 'pto'); crypto = require('cry' + 'pto');
} else { else
hash = require('hash.js'); hash = require('hash.js');
}
/** /**
* Utils * Utils
@ -246,6 +245,73 @@ utils.sha512hmac = function sha512hmac(data, salt) {
return result; return result;
}; };
/**
* PDKBF2
* Credit to: https://github.com/stayradiated/pbkdf2-sha512
* Copyright (c) 2010-2011 Intalio Pte, All Rights Reserved
* Copyright (c) 2014, JP Richardson
*/
utils.pbkdf2 = function pbkdf2(key, salt, iterations, dkLen) {
'use strict';
if (crypto && crypto.pbkdf2Sync)
return crypto.pbkdf2Sync(key, salt, iterations, dkLen, 'sha512');
var hLen = 64;
if (dkLen > (Math.pow(2, 32) - 1) * hLen)
throw Error('Requested key length too long');
if (typeof key !== 'string' && typeof key.length !== 'number')
throw new TypeError('key must a string or array');
if (typeof salt !== 'string' && typeof salt.length !== 'number')
throw new TypeError('salt must a string or array');
if (typeof key === 'string')
key = new Buffer(key, 'ascii');
if (typeof salt === 'string')
salt = new Buffer(salt, 'ascii');
var DK = new Buffer(dkLen);
var U = new Buffer(hLen);
var T = new Buffer(hLen);
var block1 = new Buffer(salt.length + 4);
var l = Math.ceil(dkLen / hLen);
var r = dkLen - (l - 1) * hLen;
var i, j, k, destPos, len;
utils.copy(salt.slice(0, salt.length), block1, 0);
for (i = 1; i <= l; i++) {
block1[salt.length + 0] = i >> 24 & 0xff;
block1[salt.length + 1] = i >> 16 & 0xff;
block1[salt.length + 2] = i >> 8 & 0xff;
block1[salt.length + 3] = i >> 0 & 0xff;
U = utils.sha512hmac(block1, key);
utils.copy(U.slice(0, hLen), T, 0);
for (j = 1; j < iterations; j++) {
U = utils.sha512hmac(U, key);
for (k = 0; k < hLen; k++)
T[k] ^= U[k];
}
destPos = (i - 1) * hLen;
len = i === l ? r : hLen;
utils.copy(T.slice(0, len), DK, 0);
}
return DK;
};
utils.salt = 'bcoin:'; utils.salt = 'bcoin:';
utils.encrypt = function encrypt(data, passphrase) { utils.encrypt = function encrypt(data, passphrase) {
@ -784,6 +850,7 @@ utils.print = function print() {
}; };
utils.debug = utils.nop; utils.debug = utils.nop;
utils.ensurePrefix = utils.nop;
utils.merge = function merge(target) { utils.merge = function merge(target) {
var args = Array.prototype.slice.call(arguments, 1); var args = Array.prototype.slice.call(arguments, 1);

View File

@ -30,8 +30,7 @@
"dependencies": { "dependencies": {
"bn.js": "4.10.3", "bn.js": "4.10.3",
"elliptic": "6.0.2", "elliptic": "6.0.2",
"rocksdown": "1.4.4-2", "leveldown": "1.4.4"
"levelup": "1.3.1"
}, },
"optionalDependencies": { "optionalDependencies": {
"secp256k1": "3.0.0", "secp256k1": "3.0.0",

View File

@ -32,7 +32,7 @@ describe('HD', function() {
var master, child1, child2, child3, child4, child5, child6; var master, child1, child2, child3, child4, child5, child6;
it('should create a pbkdf2 seed', function() { it('should create a pbkdf2 seed', function() {
var checkSeed = utils.toHex(bcoin.hd.pbkdf2(phrase, 'mnemonic' + 'foo', 2048, 64)); var checkSeed = utils.toHex(bcoin.utils.pbkdf2(phrase, 'mnemonic' + 'foo', 2048, 64));
assert.equal(checkSeed, seed); assert.equal(checkSeed, seed);
}); });