hd testing methods.
This commit is contained in:
parent
9ac406aa2d
commit
48f8edbe80
124
lib/bcoin/hd.js
124
lib/bcoin/hd.js
@ -139,7 +139,8 @@ Mnemonic.prototype.toSeed = function toSeed() {
|
||||
this.seed = utils.pbkdf2(
|
||||
nfkd(this.phrase),
|
||||
nfkd('mnemonic' + this.passphrase),
|
||||
2048, 64);
|
||||
2048,
|
||||
64);
|
||||
|
||||
return this.seed;
|
||||
};
|
||||
@ -560,34 +561,24 @@ HDPrivateKey.prototype.derive = function derive(index, hardened) {
|
||||
* @throws Error if key is not a master key.
|
||||
*/
|
||||
|
||||
HDPrivateKey.prototype.deriveAccount44 = function deriveAccount44(options) {
|
||||
var coinType, accountIndex, child;
|
||||
HDPrivateKey.prototype.deriveAccount44 = function deriveAccount44(accountIndex) {
|
||||
var coinType;
|
||||
|
||||
if (typeof options === 'number')
|
||||
options = { accountIndex: options };
|
||||
|
||||
coinType = options.coinType;
|
||||
accountIndex = options.accountIndex;
|
||||
assert(utils.isNumber(accountIndex), 'accountIndex must be a number.');
|
||||
|
||||
if (this instanceof HDPublicKey) {
|
||||
assert(this.isAccount44());
|
||||
assert(this.isAccount44(accountIndex), 'Cannot derive account index.');
|
||||
return this;
|
||||
}
|
||||
|
||||
if (coinType == null)
|
||||
coinType = this.network === 'main' ? 0 : 1;
|
||||
assert(this.isMaster(), 'Cannot derive account index.');
|
||||
|
||||
assert(utils.isNumber(coinType));
|
||||
assert(utils.isNumber(accountIndex));
|
||||
coinType = this.network === 'main' ? 0 : 1;
|
||||
|
||||
child = this
|
||||
return this
|
||||
.derive(44, true)
|
||||
.derive(coinType, true)
|
||||
.derive(accountIndex, true);
|
||||
|
||||
assert(child.isAccount44());
|
||||
|
||||
return child;
|
||||
};
|
||||
|
||||
/**
|
||||
@ -599,15 +590,38 @@ HDPrivateKey.prototype.derivePurpose45 = function derivePurpose45() {
|
||||
var child;
|
||||
|
||||
if (this instanceof HDPublicKey) {
|
||||
assert(this.isPurpose45());
|
||||
assert(this.isPurpose45(), 'Cannot derive purpose 45.');
|
||||
return this;
|
||||
}
|
||||
|
||||
child = this.derive(45, true);
|
||||
assert(this.isMaster(), 'Cannot derive purpose 45.');
|
||||
|
||||
assert(child.isPurpose45());
|
||||
return this.derive(45, true);
|
||||
};
|
||||
|
||||
return child;
|
||||
/**
|
||||
* Test whether the key is a master key.
|
||||
* @returns {Boolean}
|
||||
*/
|
||||
|
||||
HDPrivateKey.prototype.isMaster = function isMaster() {
|
||||
return this.depth === 0
|
||||
&& this.childIndex === 0
|
||||
&& utils.readU32(this.parentFingerPrint, 0) === 0;
|
||||
};
|
||||
|
||||
/**
|
||||
* Test whether the key is (most likely) a BIP44 account key.
|
||||
* @param {Number?} accountIndex
|
||||
* @returns {Boolean}
|
||||
*/
|
||||
|
||||
HDPrivateKey.prototype.isAccount44 = function isAccount44(accountIndex) {
|
||||
if (accountIndex != null) {
|
||||
if (this.childIndex !== constants.hd.HARDENED + accountIndex)
|
||||
return false;
|
||||
}
|
||||
return this.depth === 3 && this.childIndex >= constants.hd.HARDENED;
|
||||
};
|
||||
|
||||
/**
|
||||
@ -616,20 +630,7 @@ HDPrivateKey.prototype.derivePurpose45 = function derivePurpose45() {
|
||||
*/
|
||||
|
||||
HDPrivateKey.prototype.isPurpose45 = function isPurpose45() {
|
||||
if (this.depth !== 1)
|
||||
return false;
|
||||
return this.childIndex === constants.hd.HARDENED + 45;
|
||||
};
|
||||
|
||||
/**
|
||||
* Test whether the key is (most likely) a BIP44 account key.
|
||||
* @returns {Boolean}
|
||||
*/
|
||||
|
||||
HDPrivateKey.prototype.isAccount44 = function isAccount44() {
|
||||
if (this.childIndex < constants.hd.HARDENED)
|
||||
return false;
|
||||
return this.depth === 3;
|
||||
return this.depth === 1 && this.childIndex === constants.hd.HARDENED + 45;
|
||||
};
|
||||
|
||||
/**
|
||||
@ -662,6 +663,9 @@ HDPrivateKey.isExtended = function isExtended(data) {
|
||||
*/
|
||||
|
||||
HDPrivateKey.isValidPath = function isValidPath(path) {
|
||||
if (typeof path !== 'string')
|
||||
return false;
|
||||
|
||||
try {
|
||||
HD.parsePath(path, constants.hd.MAX_INDEX);
|
||||
return true;
|
||||
@ -722,8 +726,7 @@ HDPrivateKey.parseSeed = function parseSeed(seed, network) {
|
||||
parentFingerPrint: new Buffer([0, 0, 0, 0]),
|
||||
childIndex: 0,
|
||||
chainCode: chainCode,
|
||||
privateKey: privateKey,
|
||||
mnemonic: seed
|
||||
privateKey: privateKey
|
||||
};
|
||||
};
|
||||
|
||||
@ -752,14 +755,19 @@ HDPrivateKey.fromMnemonic = function fromMnemonic(mnemonic, network) {
|
||||
if (!(mnemonic instanceof Mnemonic))
|
||||
mnemonic = new Mnemonic(mnemonic);
|
||||
|
||||
if (mnemonic.seed || mnemonic.phrase || mnemonic.entropy)
|
||||
return HDPrivateKey.fromSeed(mnemonic.toSeed(), network);
|
||||
if (mnemonic.seed || mnemonic.phrase || mnemonic.entropy) {
|
||||
key = HDPrivateKey.parseSeed(mnemonic.toSeed(), network);
|
||||
key.mnemonic = mnemonic;
|
||||
return new HDPrivateKey(key);
|
||||
}
|
||||
|
||||
// Very unlikely, but not impossible
|
||||
// to get an invalid private key.
|
||||
for (;;) {
|
||||
try {
|
||||
key = HDPrivateKey.fromSeed(mnemonic.toSeed(), network);
|
||||
key = HDPrivateKey.parseSeed(mnemonic.toSeed(), network);
|
||||
key.mnemonic = mnemonic;
|
||||
key = new HDPrivateKey(key);
|
||||
} catch (e) {
|
||||
if (e.message === 'Master private key is invalid.') {
|
||||
mnemonic.seed = null;
|
||||
@ -896,8 +904,7 @@ HDPrivateKey.prototype.toBase58 = function toBase58(network) {
|
||||
*/
|
||||
|
||||
HDPrivateKey.fromBase58 = function fromBase58(xkey) {
|
||||
var data = HDPrivateKey.parseBase58(xkey);
|
||||
return new HDPrivateKey(data);
|
||||
return new HDPrivateKey(HDPrivateKey.parseBase58(xkey));
|
||||
};
|
||||
|
||||
/**
|
||||
@ -1149,6 +1156,23 @@ HDPublicKey.prototype.deriveAccount44 = HDPrivateKey.prototype.deriveAccount44;
|
||||
|
||||
HDPublicKey.prototype.derivePurpose45 = HDPrivateKey.prototype.derivePurpose45;
|
||||
|
||||
/**
|
||||
* Test whether the key is a master key.
|
||||
* @method
|
||||
* @returns {Boolean}
|
||||
*/
|
||||
|
||||
HDPublicKey.prototype.isMaster = HDPrivateKey.prototype.isMaster;
|
||||
|
||||
/**
|
||||
* Test whether the key is (most likely) a BIP44 account key.
|
||||
* @method
|
||||
* @param {Number?} accountIndex
|
||||
* @returns {Boolean}
|
||||
*/
|
||||
|
||||
HDPublicKey.prototype.isAccount44 = HDPrivateKey.prototype.isAccount44;
|
||||
|
||||
/**
|
||||
* Test whether the key is a BIP45 purpose key.
|
||||
* @method
|
||||
@ -1157,14 +1181,6 @@ HDPublicKey.prototype.derivePurpose45 = HDPrivateKey.prototype.derivePurpose45;
|
||||
|
||||
HDPublicKey.prototype.isPurpose45 = HDPrivateKey.prototype.isPurpose45;
|
||||
|
||||
/**
|
||||
* Test whether the key is (most likely) a BIP44 account key.
|
||||
* @method
|
||||
* @returns {Boolean}
|
||||
*/
|
||||
|
||||
HDPublicKey.prototype.isAccount44 = HDPrivateKey.prototype.isAccount44;
|
||||
|
||||
/**
|
||||
* Test whether a string is a valid path.
|
||||
* @param {String} path
|
||||
@ -1173,6 +1189,9 @@ HDPublicKey.prototype.isAccount44 = HDPrivateKey.prototype.isAccount44;
|
||||
*/
|
||||
|
||||
HDPublicKey.isValidPath = function isValidPath(path) {
|
||||
if (typeof path !== 'string')
|
||||
return false;
|
||||
|
||||
try {
|
||||
HD.parsePath(path, constants.hd.HARDENED);
|
||||
return true;
|
||||
@ -1314,8 +1333,7 @@ HDPublicKey.prototype.toBase58 = function toBase58(network) {
|
||||
*/
|
||||
|
||||
HDPublicKey.fromBase58 = function fromBase58(xkey) {
|
||||
var data = HDPublicKey.parseBase58(xkey);
|
||||
return new HDPublicKey(data);
|
||||
return new HDPublicKey(HDPublicKey.parseBase58(xkey));
|
||||
};
|
||||
|
||||
/**
|
||||
|
||||
Loading…
Reference in New Issue
Block a user