cleanup.
This commit is contained in:
parent
bd54b42dc4
commit
5153e0e1f0
49
lib/bcoin.js
49
lib/bcoin.js
@ -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');
|
||||||
|
|||||||
@ -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;
|
||||||
|
|||||||
@ -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());
|
||||||
};
|
};
|
||||||
|
|||||||
267
lib/bcoin/hd.js
267
lib/bcoin/hd.js
@ -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;
|
||||||
|
|||||||
@ -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(
|
||||||
|
|||||||
@ -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)
|
||||||
|
|||||||
@ -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() {
|
||||||
|
|||||||
@ -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);
|
||||||
|
|||||||
@ -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",
|
||||||
|
|||||||
@ -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);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user