elliptic-keychain
Version:
Library for creating elliptic curve keypairs and deriving child keys
197 lines (174 loc) • 6.48 kB
JavaScript
;
var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol ? "symbol" : typeof obj; };
Object.defineProperty(exports, "__esModule", {
value: true
});
require('core-js/shim');
var _bitcoinjsLib = require('bitcoinjs-lib');
var _bs58check = require('bs58check');
var _bs58check2 = _interopRequireDefault(_bs58check);
var _utils = require('./utils');
var _derivation = require('./derivation');
var _derivation2 = _interopRequireDefault(_derivation);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
function isWIF(privateKeyString) {
var isValid = true;
try {
_bs58check2.default.decode(privateKeyString);
} catch (e) {
isValid = false;
}
return isValid;
}
function numberToEntropy(baseBuffer, index) {
if (!(typeof index === 'undefined' ? 'undefined' : _typeof(index)) === 'number') {
throw new Error('Index must be a number');
}
var indexHexString = index.toString(16);
if (indexHexString.length % 2 === 1) {
indexHexString = '0' + indexHexString;
}
var entropy = _bitcoinjsLib.crypto.sha256(Buffer.concat([baseBuffer, new Buffer(indexHexString, 'hex')]));
return entropy;
}
var PrivateKeychain = function () {
function PrivateKeychain(privateKey) {
_classCallCheck(this, PrivateKeychain);
if (!privateKey) {
this.ecPair = new _bitcoinjsLib.ECPair.makeRandom({ rng: _utils.getEntropy });
} else {
if (privateKey instanceof _bitcoinjsLib.ECPair) {
this.ecPair = privateKey;
} else if (isWIF(privateKey)) {
this.ecPair = new _bitcoinjsLib.ECPair.fromWIF(privateKey);
} else {
this.ecPair = new _bitcoinjsLib.ECPair(privateKey, null, {});
}
}
}
_createClass(PrivateKeychain, [{
key: 'publicKeychain',
value: function publicKeychain() {
return new PublicKeychain(this.ecPair.getPublicKeyBuffer());
}
}, {
key: 'privateKey',
value: function privateKey(format) {
var privateKeyBuffer = this.ecPair.d.toBuffer(32);
if (!format) {
return privateKeyBuffer;
} else if (format === 'hex') {
return privateKeyBuffer.toString('hex');
} else {
throw new Error('Format not supported');
}
}
}, {
key: 'wif',
value: function wif() {
return this.ecPair.toWIF();
}
}, {
key: 'sign',
value: function sign(message) {
return _bitcoinjsLib.message.sign(this.ecPair, message);
}
}, {
key: 'child',
value: function child(entropy) {
if (!entropy instanceof Buffer) {
throw new Error('Entropy must be a buffer');
}
var childKeypair = (0, _derivation2.default)(this.ecPair, entropy);
return new PrivateKeychain(childKeypair);
}
}, {
key: 'privatelyEnumeratedChild',
value: function privatelyEnumeratedChild(index) {
var entropy = numberToEntropy(this.privateKey(), index);
return this.child(entropy);
}
}, {
key: 'privatelyNamedChild',
value: function privatelyNamedChild(name) {
if (name.length === 0) {
throw new Error('Name must be at least one character long');
}
var entropy = _bitcoinjsLib.crypto.sha256(Buffer.concat([this.privateKey(), new Buffer(name)]));
return this.child(entropy);
}
}]);
return PrivateKeychain;
}();
var PublicKeychain = function () {
function PublicKeychain(publicKey) {
_classCallCheck(this, PublicKeychain);
if (publicKey instanceof _bitcoinjsLib.ECPair) {
this.ecPair = publicKey;
} else if (publicKey instanceof Buffer) {
this.ecPair = new _bitcoinjsLib.ECPair.fromPublicKeyBuffer(publicKey);
} else {
var publicKeyBuffer = new Buffer(publicKey, 'hex');
this.ecPair = new _bitcoinjsLib.ECPair.fromPublicKeyBuffer(publicKeyBuffer);
}
}
_createClass(PublicKeychain, [{
key: 'publicKey',
value: function publicKey(format) {
var publicKeyBuffer = this.ecPair.getPublicKeyBuffer();
if (!format) {
return publicKeyBuffer;
} else if (format === 'hex') {
return publicKeyBuffer.toString('hex');
} else {
throw new Error('Format not supported');
}
}
}, {
key: 'address',
value: function address() {
return this.ecPair.getAddress();
}
}, {
key: 'verify',
value: function verify(message, signature) {
var signatureBuffer = signature;
if (!signature instanceof Buffer) {
signatureBuffer = new Buffer(signature, 'hex');
}
return _bitcoinjsLib.message.verify(this.address(), signature, message);
}
}, {
key: 'child',
value: function child(entropy) {
if (!entropy instanceof Buffer) {
throw new Error('Entropy must be a buffer');
}
var childKeypair = (0, _derivation2.default)(this.ecPair, entropy);
return new PublicKeychain(childKeypair);
}
}, {
key: 'publiclyEnumeratedChild',
value: function publiclyEnumeratedChild(index) {
var entropy = numberToEntropy(this.publicKey(), index);
return this.child(entropy);
}
}, {
key: 'publiclyNamedChild',
value: function publiclyNamedChild(name) {
if (name.length === 0) {
throw new Error('Name must be at least one character long');
}
var entropy = _bitcoinjsLib.crypto.sha256(Buffer.concat([this.publicKey(), new Buffer(name)]));
return this.child(entropy);
}
}]);
return PublicKeychain;
}();
exports.default = {
PrivateKeychain: PrivateKeychain,
PublicKeychain: PublicKeychain,
numberToEntropy: numberToEntropy
};