function PrivateKey(data, network) {
  /* jshint maxstatements: 20 */
  /* jshint maxcomplexity: 8 */

  if (!(this instanceof PrivateKey)) {
    return new PrivateKey(data, network);
  }
  if (data instanceof PrivateKey) {
    return data;
  }

  var info = this._classifyArguments(data, network);

  // validation
  if (!info.bn || info.bn.cmp(new BN(0)) === 0){
    throw new TypeError('Number can not be equal to zero, undefined, null or false');
  }
  if (!info.bn.lt(Point.getN())) {
    throw new TypeError('Number must be less than N');
  }
  if (typeof(info.network) === 'undefined') {
    throw new TypeError('Must specify the network ("livenet" or "testnet")');
  }

  JSUtil.defineImmutable(this, {
    bn: info.bn,
    compressed: info.compressed,
    network: info.network
  });

  Object.defineProperty(this, 'publicKey', {
    configurable: false,
    enumerable: true,
    get: this.toPublicKey.bind(this)
  });

  return this;

}
Instantiate a PrivateKey from a BN, Buffer and WIF.

@example
```javascript
// generate a new random key
var key = PrivateKey();

// get the associated address
var address = key.toAddress();

// encode into wallet export format
var exported = key.toWIF();

// instantiate from the exported (and saved) private key
var imported = PrivateKey.fromWIF(exported);
```

@param {string} data - The encoded data in various formats
@param {Network|string=} network - a {@link Network} object, or a string with the network name
@returns {PrivateKey} A new valid instance of an PrivateKey
@constructor