UNPKG

elliptic-keychain

Version:

Library for creating elliptic curve keypairs and deriving child keys

80 lines (56 loc) 2.52 kB
'use strict'; 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;