UNPKG

@crpdo/key

Version:

Streamlines key generation, derivation, and management through its simple and intuitive API

173 lines (156 loc) 5.47 kB
const Nacl = require('@crpdo/crypto/nacl') const CoinUtils = require('@crpdo/coins') const BaseKey = require('./base-key') const HDKey = require('hdkey') const { _: { _, log }} = require('@crpdo/crypto') /** * Class representing a Hierarchical Deterministic Key (HdKey) * @extends BaseKey */ class HdKey extends BaseKey { static get HDKey() { return HDKey } /** * Create a HdKey. * @param {string} seed - The seed to initialize the HdKey. */ constructor(seed) { super(seed.startsWith('xprv') ? HDKey.fromExtendedKey(seed) : HDKey.fromMasterSeed(seed)) } /** * Get the depth of the key derivation. * @return {number} The depth of the key. */ get depth() { return this.key.depth } /** * Get the public key. * @return {string} The public key. */ get publicKey() { return this.key.publicExtendedKey } /** * Get the private key. * @return {string} The private key. */ get privateKey() { return this.key.privateExtendedKey } /** * Get the public extended key. * @return {string} The public extended key. */ get publicExtendedKey() { return this.key.publicExtendedKey } /** * Get the private extended key. * @return {string} The private extended key. */ get privateExtendedKey() { return this.key.privateExtendedKey } /** * Derive a new key from the current key. * @param {string} path - The derivation path. * @return {HDKey} The derived key. */ derive(path) { return this.key.derive(path) } /** * Sign a piece of data with this key. * @param {string|Buffer} data - The data to sign. * @return {string} The signature. */ sign(data) { if (!_.isBinary(data) || data.length !== _.BYTE_LENGTH) data = _.hash(data, _.BYTE_LENGTH, false) const signature = this.key.sign(data) return _.encode(signature) } /** * Verify a signature on a piece of data with this key. * @param {string|Buffer} data - The data whose signature to verify. * @param {string} signature - The signature to verify. * @param {HDKey} publicKey - The public key to verify the signature against. * @return {boolean} Whether the signature is valid. */ verify(data, signature, publicKey) { if (!_.isBinary(data) || data.length !== _.BYTE_LENGTH) data = _.hash(data, _.BYTE_LENGTH, false) publicKey = publicKey || this.key.publicExtendedKey if (!(publicKey instanceof HDKey)) publicKey = HDKey.fromExtendedKey(publicKey) signature = _.isString(signature) ? _.decode(signature) : signature return publicKey.verify(data, signature) } /** * Derive a softened key from the current key. * @param {string} coinSymbol - The coin symbol, default is 'BTC'. * @param {number} account - The account number, default is 0. * @param {number} change - The change number, default is 0. * @param {number} index - The index number. * @return {HDKey} The derived softened key. */ deriveSoftened(coinSymbol = 'BTC', account = 0, change = 0, index) { return HdKey.deriveSoftenedNode(this.key, coinSymbol, account, change, index) } /** * Derive a softened public key from the current key. * @param {string} coinSymbol - The coin symbol, default is 'BTC'. * @param {number} account - The account number, default is 0. * @param {number} change - The change number, default is 0. * @param {number} index - The index number. * @return {string} The derived softened public key. */ deriveSoftenedPublicKey(coinSymbol = 'BTC', account = 0, change = 0, index) { return HdKey.deriveSoftenedPublicKey(this.key, coinSymbol, account, change, index) } /** * Derives a node from an input and path. * @static * @param {HDKey | string} input - The input to derive the node from, either an instance of HDKey or a string to create an HDKey from. * @param {string} [path='m'] - The path to derive the node at. * @return {HDKey} The derived node. */ static deriveNode(input, path = 'm') { if (!(input instanceof HDKey)) input = HDKey.fromExtendedKey(input) return input.derive(path) } /** * Derives a softened node from an input and additional arguments. * @static * @param {HDKey | string} input - The input to derive the softened node from, either an instance of HDKey or a string to create an HDKey from. * @param {...any} args - The additional arguments for deriving the path. * @return {HDKey} The derived softened node. */ static deriveSoftenedNode(input, ...args) { const derivePath = CoinUtils.getDerivePath(...args) const node = this.deriveNode(input, derivePath) this.neuterNode(node) return node } /** * Derives a softened public key from an input and additional arguments. * @static * @param {HDKey | string} input - The input to derive the softened public key from, either an instance of HDKey or a string to create an HDKey from. * @param {...any} args - The additional arguments for deriving the path. * @return {string} The derived softened public key. */ static deriveSoftenedPublicKey(input, ...args) { const node = this.deriveSoftenedNode(input, ...args) return node.publicExtendedKey } /** * Removes private data from a node, rendering it a public node. * @static * @param {HDKey} node - The node to neuter. */ static neuterNode(node) { node.wipePrivateData() } } module.exports = HdKey