PHP WebShell

Текущая директория: /usr/lib/node_modules/bitgo-express/node_modules/prova-lib/src

Просмотр файла: hdNode.js

const base58check = require('bs58check');
const BigInteger = require('bigi');
const bitcoin = require('bitcoinjs-lib');
const crypto = require('crypto');
const ECPair = require('./ecPair');
const ecurve = require('ecurve');
const curve = ecurve.getCurveByName('secp256k1');
const NETWORKS = require('./networks');
const typeforce = require('typeforce');
const types = require('./types');

let secp256k1;
try {
  secp256k1 = require('secp256k1');
} catch (err) {
  console.log('running without secp256k1 acceleration');
}

const HDNode = bitcoin.HDNode;

const inferredNetworks = [
  NETWORKS.rmg,
  NETWORKS.rmgTest,
  bitcoin.networks.bitcoin,
  bitcoin.networks.testnet,
  bitcoin.networks.litecoin,
  NETWORKS.litecoinTest
];

HDNode.prototype.neutered = function() {
  const neuteredKeyPair = new ECPair(null, this.keyPair.Q, {
    network: this.keyPair.network
  });

  const neutered = new HDNode(neuteredKeyPair, this.chainCode);
  neutered.depth = this.depth;
  neutered.index = this.index;
  neutered.parentFingerprint = this.parentFingerprint;

  return neutered;
};

HDNode.prototype.getKey = function(overrideNetwork) {
  try {
    typeforce(types.maybe(types.Network), overrideNetwork);
  } catch (e) {
    throw new Error(e.message);
  }

  const k = this.keyPair;
  const network = overrideNetwork || this.keyPair.network || NETWORKS.rmg;
  const result = new ECPair(k.d, k.d ? null : k.Q, { network: network, compressed: k.compressed });
  // Creating Q from d takes ~25ms, so if it's not created, use native bindings to pre-compute
  if (!result.__Q && secp256k1) {
    result.__Q = ecurve.Point.decodeFrom(curve, secp256k1.publicKeyCreate(k.d.toBuffer(32), false));
  }
  return result;
};

/**
 *  Derive a BIP32 path, given a root key
 *  We cache keys at each level of hierarchy we derive, to avoid re-deriving (approx 25ms per derivation)
 * @param path the path, e.g. 'm/0/0/0/1'
 * @returns {*} the derived hd key
 */
HDNode.prototype.hdPath = function() {
  const cache = {};
  const cachedDerive = (path) => {
    const components = path.split('/').filter((c) => {
      return c !== '';
    });
    // strip any extraneous / characters
    const canonicalPath = components.join('/');
    if (cache[canonicalPath]) {
      return cache[canonicalPath];
    }
    const len = components.length;
    if (len === 0 || len === 1 && components[0] === 'm') {
      return this;
    }
    const parentPath = components.slice(0, len - 1).join('/');
    const parentKey = cachedDerive(parentPath);
    const el = components[len - 1];

    let hardened = false;
    if (el[el.length - 1] === "'") {
      hardened = true;
    }
    const index = parseInt(el);
    let derived;
    if (hardened) {
      derived = parentKey.deriveHardened(index);
    } else {
      derived = parentKey.derive(index);
    }
    cache[canonicalPath] = derived;
    return derived;
  };

  const deriveKey = (path) => {
    return cachedDerive(path).getKey();
  };

  return {
    derive: cachedDerive,
    deriveKey: deriveKey
  };
};

HDNode.prototype.deriveSlow = function(index) {
  try {
    typeforce(types.UInt32, index);
  } catch (e) {
    throw new Error(e.message);
  }

  const isHardened = index >= HDNode.HIGHEST_BIT;
  const data = new Buffer(37);

  // Hardened child
  if (isHardened) {
    if (this.isNeutered()) {
      throw new TypeError('Could not derive hardened child key');
    }

    // data = 0x00 || ser256(kpar) || ser32(index)
    data[0] = 0x00;
    this.keyPair.d.toBuffer(32).copy(data, 1);
    data.writeUInt32BE(index, 33);

    // Normal child
  } else {
    // data = serP(point(kpar)) || ser32(index)
    //      = serP(Kpar) || ser32(index)
    this.keyPair.getPublicKeyBuffer().copy(data, 0);
    data.writeUInt32BE(index, 33);
  }

  const I = crypto.createHmac('sha512', this.chainCode).update(data).digest();
  const IL = I.slice(0, 32);
  const IR = I.slice(32);

  const pIL = BigInteger.fromBuffer(IL);

  // In case parse256(IL) >= n, proceed with the next value for i
  if (pIL.compareTo(curve.n) >= 0) {
    return this.derive(index + 1);
  }

  // Private parent key -> private child key
  let derivedKeyPair;
  if (!this.isNeutered()) {
    // ki = parse256(IL) + kpar (mod n)
    const ki = pIL.add(this.keyPair.d).mod(curve.n);

    // In case ki == 0, proceed with the next value for i
    if (ki.signum() === 0) {
      return this.derive(index + 1);
    }

    derivedKeyPair = new ECPair(ki, null, {
      network: this.keyPair.network
    });

    // Public parent key -> public child key
  } else {
    // Ki = point(parse256(IL)) + Kpar
    //    = G*IL + Kpar
    const Ki = curve.G.multiply(pIL).add(this.keyPair.Q);

    // In case Ki is the point at infinity, proceed with the next value for i
    if (curve.isInfinity(Ki)) {
      return this.derive(index + 1);
    }

    derivedKeyPair = new ECPair(null, Ki, {
      network: this.keyPair.network
    });
  }

  const hd = new HDNode(derivedKeyPair, IR);
  hd.depth = this.depth + 1;
  hd.index = index;
  hd.parentFingerprint = this.getFingerprint().readUInt32BE(0);

  return hd;
};

/**
 * Derive a child HDNode from a parent HDNode and index. Uses secp256k1 to speed
 * up public key derivations by 100x vs. bitcoinjs-lib implementation.
 *
 * @param   {Number} index   child index
 * @returns {HDNode}         derived HDNode
 */
HDNode.prototype.derive = function(index) {
  // no fast path for private key derivations -- delegate to standard method
  if (!secp256k1 || this.keyPair.d) {
    return this.deriveSlow(index);
  }

  const isHardened = index >= HDNode.HIGHEST_BIT;
  if (isHardened) {
    throw new Error('cannot derive hardened key from public key');
  }

  const indexBuffer = new Buffer(4);
  indexBuffer.writeUInt32BE(index, 0);

  const data = Buffer.concat([
    this.keyPair.getPublicKeyBuffer(),
    indexBuffer
  ]);

  const I = crypto.createHmac('sha512', this.chainCode).update(data).digest();
  const IL = I.slice(0, 32);
  const IR = I.slice(32);

  const pIL = BigInteger.fromBuffer(IL);

  // In case parse256(IL) >= n, proceed with the next value for i
  if (pIL.compareTo(curve.n) >= 0) {
    return this.derive(index + 1);
  }

  // The expensive op is the point multiply -- use secp256k1 lib to do that
  const Ki = ecurve.Point.decodeFrom(curve, secp256k1.publicKeyCreate(IL, false)).add(this.keyPair.Q);

  // In case Ki is the point at infinity, proceed with the next value for i
  if (curve.isInfinity(Ki)) {
    return this.derive(index + 1);
  }

  const keyPair = new ECPair(null, Ki, { network: this.keyPair.network });
  const hd = new HDNode(keyPair, IR);

  hd.depth = this.depth + 1;
  hd.index = index;
  hd.parentFingerprint = this.getFingerprint().readUInt32BE(0);

  return hd;
};

HDNode.fromBase58 = function(string, networks = inferredNetworks) {
  const buffer = base58check.decode(string);
  if (buffer.length !== 78) {
    throw new Error('Invalid buffer length');
  }

  // 4 bytes: version bytes
  const version = buffer.readUInt32BE(0);
  let network;

  // list of networks?
  if (Array.isArray(networks)) {
    network = networks.filter((network) => {
      return version === network.bip32.private ||
      version === network.bip32.public
    }).pop();

    if (!network) {
      throw new Error('Unknown network version');
    }

    // otherwise, assume a network object (or default to rmg)
  } else {
    try {
      typeforce(types.maybe(types.Network), networks);
    } catch (e) {
      throw new Error(e.message);
    }
    network = networks || NETWORKS.rmg;
  }

  if (version !== network.bip32.private && version !== network.bip32.public) {
    throw new Error('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 Error('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 Error('Invalid index');
  }

  // 32 bytes: the chain code
  const chainCode = buffer.slice(13, 45);
  let keyPair;

  // 33 bytes: private key data (0x00 + k)
  if (version === network.bip32.private) {
    if (buffer.readUInt8(45) !== 0x00) {
      throw new Error('Invalid private key');
    }

    const d = BigInteger.fromBuffer(buffer.slice(46, 78));
    keyPair = new ECPair(d, null, { network: network });

    // 33 bytes: public key data (0x02 + X or 0x03 + X)
  } else {
    const Q = ecurve.Point.decodeFrom(curve, buffer.slice(45, 78));
    // Q.compressed is assumed, if somehow this assumption is broken, `new HDNode` will throw

    // Verify that the X coordinate in the public point corresponds to a point on the curve.
    // If not, the extended public key is invalid.
    curve.validate(Q);

    keyPair = new ECPair(null, Q, { network: network });
  }

  const hd = new HDNode(keyPair, chainCode);
  hd.depth = depth;
  hd.index = index;
  hd.parentFingerprint = parentFingerprint;

  return hd;
};

HDNode.fromSeedBuffer = function(seed, network = NETWORKS.rmg) {
  try {
    typeforce(types.tuple(types.Buffer, types.maybe(types.Network)), arguments);
  } catch (e) {
    throw new Error(e.message);
  }

  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');
  }

  const I = crypto.createHmac('sha512', HDNode.MASTER_SECRET).update(seed).digest();
  const IL = I.slice(0, 32);
  const IR = I.slice(32);

  // In case IL is 0 or >= n, the master key is invalid
  // This is handled by the ECPair constructor
  const pIL = BigInteger.fromBuffer(IL);
  const keyPair = new ECPair(pIL, null, {
    network: network
  });

  return new HDNode(keyPair, IR);
};

module.exports = HDNode;

Выполнить команду


Для локальной разработки. Не используйте в интернете!