elliptic-keychain
Version:
Library for creating elliptic curve keypairs and deriving child keys
80 lines (56 loc) • 2.52 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", {
value: true
});
require('core-js/shim');
var _createHmac = require('create-hmac');
var _createHmac2 = _interopRequireDefault(_createHmac);
var _bigi = require('bigi');
var _bigi2 = _interopRequireDefault(_bigi);
var _bitcoinjsLib = require('bitcoinjs-lib');
var _ecurve = require('ecurve');
var _ecurve2 = _interopRequireDefault(_ecurve);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
var secp256k1 = _ecurve2.default.getCurveByName('secp256k1');
function getChildKeyMultiplier(parentKeypair, entropyBuffer) {
var parentPublicKeyBuffer = parentKeypair.getPublicKeyBuffer();
var childKeyMultiplier = _bigi2.default.fromBuffer((0, _createHmac2.default)('sha256', Buffer.concat([parentPublicKeyBuffer, entropyBuffer])).digest());
if (childKeyMultiplier.compareTo(secp256k1.n) >= 0) {
throw new TypeError('Entropy is resulting in an invalid child scalar');
}
return childKeyMultiplier;
}
function getChildPrivateKeypair(parentKeypair, entropyBuffer) {
if (!parentKeypair.d) {
throw new TypeError('Parent keypair must have a private key');
}
var childKeyMultiplier = getChildKeyMultiplier(parentKeypair, entropyBuffer),
parentSecretExponent = parentKeypair.d,
childSecretExponent = childKeyMultiplier.add(parentSecretExponent).mod(secp256k1.n);
if (childSecretExponent.signum() === 0) {
throw new TypeError('Entropy is resulting in an invalid child private key');
}
return new _bitcoinjsLib.ECPair(childSecretExponent, null, {});
}
function getChildPublicKeypair(parentKeypair, entropyBuffer) {
if (!parentKeypair.Q) {
throw new TypeError('Parent keypair must have a public key');
}
var childKeyMultiplier = getChildKeyMultiplier(parentKeypair, entropyBuffer),
parentPoint = parentKeypair.Q,
childPoint = secp256k1.G.multiply(childKeyMultiplier).add(parentPoint);
if (secp256k1.isInfinity(childPoint)) {
throw new TypeError('Entropy is resulting in an invalid child public key');
}
return new _bitcoinjsLib.ECPair(null, childPoint, {});
}
function getChildKeypair(parentKeypair, entropyBuffer) {
if (parentKeypair.d) {
// parent keypair has both a private key and a public key
return getChildPrivateKeypair(parentKeypair, entropyBuffer);
} else {
// parent keypair only has a public key in it
return getChildPublicKeypair(parentKeypair, entropyBuffer);
}
}
exports.default = getChildKeypair;