hd: cache.

This commit is contained in:
Christopher Jeffrey 2016-10-03 16:48:30 -07:00
parent b45c20b157
commit d77215009f
No known key found for this signature in database
GPG Key ID: 8962AB9DE6666BBD
2 changed files with 48 additions and 26 deletions

View File

@ -7,6 +7,7 @@
'use strict'; 'use strict';
var utils = require('../utils/utils'); var utils = require('../utils/utils');
var LRU = require('../utils/lru');
var crypto = require('../crypto/crypto'); var crypto = require('../crypto/crypto');
var ec = require('../crypto/ec'); var ec = require('../crypto/ec');
var assert = require('assert'); var assert = require('assert');
@ -187,11 +188,19 @@ HDPrivateKey.prototype.destroy = function destroy(pub) {
* @returns {HDPrivateKey} * @returns {HDPrivateKey}
*/ */
HDPrivateKey.prototype.derive = function derive(index, hardened) { HDPrivateKey.prototype.derive = function derive(index, hardened, cache) {
var p, id, data, hash, left, right, key, child; var p, id, data, hash, left, right, key, child;
if (hardened instanceof LRU) {
cache = hardened;
hardened = false;
}
if (!cache)
cache = HD.cache;
if (typeof index === 'string') if (typeof index === 'string')
return this.derivePath(index); return this.derivePath(index, cache);
hardened = index >= constants.hd.HARDENED ? true : hardened; hardened = index >= constants.hd.HARDENED ? true : hardened;
@ -204,11 +213,12 @@ HDPrivateKey.prototype.derive = function derive(index, hardened) {
if (this.depth >= 0xff) if (this.depth >= 0xff)
throw new Error('Depth too high.'); throw new Error('Depth too high.');
id = this.getID(index); if (cache) {
child = HD.cache.get(id); id = this.getID(index);
child = cache.get(id);
if (child) if (child)
return child; return child;
}
p = new BufferWriter(); p = new BufferWriter();
@ -245,7 +255,8 @@ HDPrivateKey.prototype.derive = function derive(index, hardened) {
child.privateKey = key; child.privateKey = key;
child.publicKey = ec.publicKeyCreate(key, true); child.publicKey = ec.publicKeyCreate(key, true);
HD.cache.set(id, child); if (cache)
cache.set(id, child);
return child; return child;
}; };
@ -270,13 +281,13 @@ HDPrivateKey.prototype.getID = function getID(index) {
* @throws Error if key is not a master key. * @throws Error if key is not a master key.
*/ */
HDPrivateKey.prototype.deriveAccount44 = function deriveAccount44(accountIndex) { HDPrivateKey.prototype.deriveAccount44 = function deriveAccount44(accountIndex, cache) {
assert(utils.isNumber(accountIndex), 'Account index must be a number.'); assert(utils.isNumber(accountIndex), 'Account index must be a number.');
assert(this.isMaster(), 'Cannot derive account index.'); assert(this.isMaster(), 'Cannot derive account index.');
return this return this
.derive(44, true) .derive(44, true, cache)
.derive(this.network.keyPrefix.coinType, true) .derive(this.network.keyPrefix.coinType, true, cache)
.derive(accountIndex, true); .derive(accountIndex, true, cache);
}; };
/** /**
@ -284,9 +295,9 @@ HDPrivateKey.prototype.deriveAccount44 = function deriveAccount44(accountIndex)
* @returns {HDPrivateKey} * @returns {HDPrivateKey}
*/ */
HDPrivateKey.prototype.derivePurpose45 = function derivePurpose45() { HDPrivateKey.prototype.derivePurpose45 = function derivePurpose45(cache) {
assert(this.isMaster(), 'Cannot derive purpose 45.'); assert(this.isMaster(), 'Cannot derive purpose 45.');
return this.derive(45, true); return this.derive(45, true, cache);
}; };
/** /**
@ -395,13 +406,13 @@ HDPrivateKey.isValidPath = function isValidPath(path) {
* @throws Error if `path` is not a valid path. * @throws Error if `path` is not a valid path.
*/ */
HDPrivateKey.prototype.derivePath = function derivePath(path) { HDPrivateKey.prototype.derivePath = function derivePath(path, cache) {
var indexes = HD.parsePath(path, constants.hd.MAX_INDEX); var indexes = HD.parsePath(path, constants.hd.MAX_INDEX);
var key = this; var key = this;
var i; var i;
for (i = 0; i < indexes.length; i++) for (i = 0; i < indexes.length; i++)
key = key.derive(indexes[i]); key = key.derive(indexes[i], cache);
return key; return key;
}; };

View File

@ -7,6 +7,7 @@
'use strict'; 'use strict';
var utils = require('../utils/utils'); var utils = require('../utils/utils');
var LRU = require('../utils/lru');
var crypto = require('../crypto/crypto'); var crypto = require('../crypto/crypto');
var ec = require('../crypto/ec'); var ec = require('../crypto/ec');
var assert = require('assert'); var assert = require('assert');
@ -140,11 +141,19 @@ HDPublicKey.prototype.destroy = function destroy() {
* @throws on `hardened` * @throws on `hardened`
*/ */
HDPublicKey.prototype.derive = function derive(index, hardened) { HDPublicKey.prototype.derive = function derive(index, hardened, cache) {
var p, id, data, hash, left, right, key, child; var p, id, data, hash, left, right, key, child;
if (hardened instanceof LRU) {
cache = hardened;
hardened = false;
}
if (!cache)
cache = HD.cache;
if (typeof index === 'string') if (typeof index === 'string')
return this.derivePath(index); return this.derivePath(index, cache);
if (index >= constants.hd.HARDENED || hardened) if (index >= constants.hd.HARDENED || hardened)
throw new Error('Index out of range.'); throw new Error('Index out of range.');
@ -155,11 +164,12 @@ HDPublicKey.prototype.derive = function derive(index, hardened) {
if (this.depth >= 0xff) if (this.depth >= 0xff)
throw new Error('Depth too high.'); throw new Error('Depth too high.');
id = this.getID(index); if (cache) {
child = HD.cache.get(id); id = this.getID(index);
child = cache.get(id);
if (child) if (child)
return child; return child;
}
p = new BufferWriter(); p = new BufferWriter();
p.writeBytes(this.publicKey); p.writeBytes(this.publicKey);
@ -187,7 +197,8 @@ HDPublicKey.prototype.derive = function derive(index, hardened) {
child.chainCode = right; child.chainCode = right;
child.publicKey = key; child.publicKey = key;
HD.cache.set(id, child); if (cache)
cache.set(id, child);
return child; return child;
}; };
@ -288,13 +299,13 @@ HDPublicKey.isValidPath = function isValidPath(path) {
* @throws Error if hardened. * @throws Error if hardened.
*/ */
HDPublicKey.prototype.derivePath = function derivePath(path) { HDPublicKey.prototype.derivePath = function derivePath(path, cache) {
var indexes = HD.parsePath(path, constants.hd.HARDENED); var indexes = HD.parsePath(path, constants.hd.HARDENED);
var key = this; var key = this;
var i; var i;
for (i = 0; i < indexes.length; i++) for (i = 0; i < indexes.length; i++)
key = key.derive(indexes[i]); key = key.derive(indexes[i], cache);
return key; return key;
}; };