Viewing File: /home/ubuntu/efiexchange-node-base/node_modules/bitcoinjs-lib/node_modules/bip32/src/bip32.js
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const crypto = require("./crypto");
const bs58check = require('bs58check');
const ecc = require('tiny-secp256k1');
const typeforce = require('typeforce');
const wif = require('wif');
const UINT256_TYPE = typeforce.BufferN(32);
const NETWORK_TYPE = typeforce.compile({
wif: typeforce.UInt8,
bip32: {
public: typeforce.UInt32,
private: typeforce.UInt32,
},
});
const BITCOIN = {
messagePrefix: '\x18Bitcoin Signed Message:\n',
bech32: 'bc',
bip32: {
public: 0x0488b21e,
private: 0x0488ade4,
},
pubKeyHash: 0x00,
scriptHash: 0x05,
wif: 0x80,
};
const HIGHEST_BIT = 0x80000000;
const UINT31_MAX = Math.pow(2, 31) - 1;
function BIP32Path(value) {
return (typeforce.String(value) && value.match(/^(m\/)?(\d+'?\/)*\d+'?$/) !== null);
}
function UInt31(value) {
return typeforce.UInt32(value) && value <= UINT31_MAX;
}
class BIP32 {
constructor(__D, __Q, chainCode, network, __DEPTH = 0, __INDEX = 0, __PARENT_FINGERPRINT = 0x00000000) {
this.__D = __D;
this.__Q = __Q;
this.chainCode = chainCode;
this.network = network;
this.__DEPTH = __DEPTH;
this.__INDEX = __INDEX;
this.__PARENT_FINGERPRINT = __PARENT_FINGERPRINT;
typeforce(NETWORK_TYPE, network);
this.lowR = false;
}
get depth() {
return this.__DEPTH;
}
get index() {
return this.__INDEX;
}
get parentFingerprint() {
return this.__PARENT_FINGERPRINT;
}
get publicKey() {
if (this.__Q === undefined)
this.__Q = ecc.pointFromScalar(this.__D, true);
return this.__Q;
}
get privateKey() {
return this.__D;
}
get identifier() {
return crypto.hash160(this.publicKey);
}
get fingerprint() {
return this.identifier.slice(0, 4);
}
get compressed() {
return true;
}
// Private === not neutered
// Public === neutered
isNeutered() {
return this.__D === undefined;
}
neutered() {
return fromPublicKeyLocal(this.publicKey, this.chainCode, this.network, this.depth, this.index, this.parentFingerprint);
}
toBase58() {
const network = this.network;
const version = !this.isNeutered()
? network.bip32.private
: network.bip32.public;
const buffer = Buffer.allocUnsafe(78);
// 4 bytes: version bytes
buffer.writeUInt32BE(version, 0);
// 1 byte: depth: 0x00 for master nodes, 0x01 for level-1 descendants, ....
buffer.writeUInt8(this.depth, 4);
// 4 bytes: the fingerprint of the parent's key (0x00000000 if master key)
buffer.writeUInt32BE(this.parentFingerprint, 5);
// 4 bytes: child number. This is the number i in xi = xpar/i, with xi the key being serialized.
// This is encoded in big endian. (0x00000000 if master key)
buffer.writeUInt32BE(this.index, 9);
// 32 bytes: the chain code
this.chainCode.copy(buffer, 13);
// 33 bytes: the public key or private key data
if (!this.isNeutered()) {
// 0x00 + k for private keys
buffer.writeUInt8(0, 45);
this.privateKey.copy(buffer, 46);
// 33 bytes: the public key
}
else {
// X9.62 encoding for public keys
this.publicKey.copy(buffer, 45);
}
return bs58check.encode(buffer);
}
toWIF() {
if (!this.privateKey)
throw new TypeError('Missing private key');
return wif.encode(this.network.wif, this.privateKey, true);
}
// https://github.com/bitcoin/bips/blob/master/bip-0032.mediawiki#child-key-derivation-ckd-functions
derive(index) {
typeforce(typeforce.UInt32, index);
const isHardened = index >= HIGHEST_BIT;
const data = Buffer.allocUnsafe(37);
// Hardened child
if (isHardened) {
if (this.isNeutered())
throw new TypeError('Missing private key for hardened child key');
// data = 0x00 || ser256(kpar) || ser32(index)
data[0] = 0x00;
this.privateKey.copy(data, 1);
data.writeUInt32BE(index, 33);
// Normal child
}
else {
// data = serP(point(kpar)) || ser32(index)
// = serP(Kpar) || ser32(index)
this.publicKey.copy(data, 0);
data.writeUInt32BE(index, 33);
}
const I = crypto.hmacSHA512(this.chainCode, data);
const IL = I.slice(0, 32);
const IR = I.slice(32);
// if parse256(IL) >= n, proceed with the next value for i
if (!ecc.isPrivate(IL))
return this.derive(index + 1);
// Private parent key -> private child key
let hd;
if (!this.isNeutered()) {
// ki = parse256(IL) + kpar (mod n)
const ki = ecc.privateAdd(this.privateKey, IL);
// In case ki == 0, proceed with the next value for i
if (ki == null)
return this.derive(index + 1);
hd = fromPrivateKeyLocal(ki, IR, this.network, this.depth + 1, index, this.fingerprint.readUInt32BE(0));
// Public parent key -> public child key
}
else {
// Ki = point(parse256(IL)) + Kpar
// = G*IL + Kpar
const Ki = ecc.pointAddScalar(this.publicKey, IL, true);
// In case Ki is the point at infinity, proceed with the next value for i
if (Ki === null)
return this.derive(index + 1);
hd = fromPublicKeyLocal(Ki, IR, this.network, this.depth + 1, index, this.fingerprint.readUInt32BE(0));
}
return hd;
}
deriveHardened(index) {
typeforce(UInt31, index);
// Only derives hardened private keys by default
return this.derive(index + HIGHEST_BIT);
}
derivePath(path) {
typeforce(BIP32Path, path);
let splitPath = path.split('/');
if (splitPath[0] === 'm') {
if (this.parentFingerprint)
throw new TypeError('Expected master, got child');
splitPath = splitPath.slice(1);
}
return splitPath.reduce((prevHd, indexStr) => {
let index;
if (indexStr.slice(-1) === `'`) {
index = parseInt(indexStr.slice(0, -1), 10);
return prevHd.deriveHardened(index);
}
else {
index = parseInt(indexStr, 10);
return prevHd.derive(index);
}
}, this);
}
sign(hash, lowR) {
if (!this.privateKey)
throw new Error('Missing private key');
if (lowR === undefined)
lowR = this.lowR;
if (lowR === false) {
return ecc.sign(hash, this.privateKey);
}
else {
let sig = ecc.sign(hash, this.privateKey);
const extraData = Buffer.alloc(32, 0);
let counter = 0;
// if first try is lowR, skip the loop
// for second try and on, add extra entropy counting up
while (sig[0] > 0x7f) {
counter++;
extraData.writeUIntLE(counter, 0, 6);
sig = ecc.signWithEntropy(hash, this.privateKey, extraData);
}
return sig;
}
}
verify(hash, signature) {
return ecc.verify(hash, this.publicKey, signature);
}
}
function fromBase58(inString, network) {
const buffer = bs58check.decode(inString);
if (buffer.length !== 78)
throw new TypeError('Invalid buffer length');
network = network || BITCOIN;
// 4 bytes: version bytes
const version = buffer.readUInt32BE(0);
if (version !== network.bip32.private && version !== network.bip32.public)
throw new TypeError('Invalid network version');
// 1 byte: depth: 0x00 for master nodes, 0x01 for level-1 descendants, ...
const depth = buffer[4];
// 4 bytes: the fingerprint of the parent's key (0x00000000 if master key)
const parentFingerprint = buffer.readUInt32BE(5);
if (depth === 0) {
if (parentFingerprint !== 0x00000000)
throw new TypeError('Invalid parent fingerprint');
}
// 4 bytes: child number. This is the number i in xi = xpar/i, with xi the key being serialized.
// This is encoded in MSB order. (0x00000000 if master key)
const index = buffer.readUInt32BE(9);
if (depth === 0 && index !== 0)
throw new TypeError('Invalid index');
// 32 bytes: the chain code
const chainCode = buffer.slice(13, 45);
let hd;
// 33 bytes: private key data (0x00 + k)
if (version === network.bip32.private) {
if (buffer.readUInt8(45) !== 0x00)
throw new TypeError('Invalid private key');
const k = buffer.slice(46, 78);
hd = fromPrivateKeyLocal(k, chainCode, network, depth, index, parentFingerprint);
// 33 bytes: public key data (0x02 + X or 0x03 + X)
}
else {
const X = buffer.slice(45, 78);
hd = fromPublicKeyLocal(X, chainCode, network, depth, index, parentFingerprint);
}
return hd;
}
exports.fromBase58 = fromBase58;
function fromPrivateKey(privateKey, chainCode, network) {
return fromPrivateKeyLocal(privateKey, chainCode, network);
}
exports.fromPrivateKey = fromPrivateKey;
function fromPrivateKeyLocal(privateKey, chainCode, network, depth, index, parentFingerprint) {
typeforce({
privateKey: UINT256_TYPE,
chainCode: UINT256_TYPE,
}, { privateKey, chainCode });
network = network || BITCOIN;
if (!ecc.isPrivate(privateKey))
throw new TypeError('Private key not in range [1, n)');
return new BIP32(privateKey, undefined, chainCode, network, depth, index, parentFingerprint);
}
function fromPublicKey(publicKey, chainCode, network) {
return fromPublicKeyLocal(publicKey, chainCode, network);
}
exports.fromPublicKey = fromPublicKey;
function fromPublicKeyLocal(publicKey, chainCode, network, depth, index, parentFingerprint) {
typeforce({
publicKey: typeforce.BufferN(33),
chainCode: UINT256_TYPE,
}, { publicKey, chainCode });
network = network || BITCOIN;
// verify the X coordinate is a point on the curve
if (!ecc.isPoint(publicKey))
throw new TypeError('Point is not on the curve');
return new BIP32(undefined, publicKey, chainCode, network, depth, index, parentFingerprint);
}
function fromSeed(seed, network) {
typeforce(typeforce.Buffer, seed);
if (seed.length < 16)
throw new TypeError('Seed should be at least 128 bits');
if (seed.length > 64)
throw new TypeError('Seed should be at most 512 bits');
network = network || BITCOIN;
const I = crypto.hmacSHA512(Buffer.from('Bitcoin seed', 'utf8'), seed);
const IL = I.slice(0, 32);
const IR = I.slice(32);
return fromPrivateKey(IL, IR, network);
}
exports.fromSeed = fromSeed;
Back to Directory
File Manager