diff --git a/app/bitcore.js b/app/bitcore.js index e2e18c1..3bb2c38 100644 --- a/app/bitcore.js +++ b/app/bitcore.js @@ -4,10 +4,12 @@ require=(function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof requ var _ = require('lodash'); var $ = require('./util/preconditions'); -var base58check = require('./encoding/base58check'); +var errors = require('./errors'); +var Base58Check = require('./encoding/base58check'); var Networks = require('./networks'); var Hash = require('./crypto/hash'); var JSUtil = require('./util/js'); +var PublicKey = require('./publickey'); /** * Instantiate an address from an address String or Buffer, a public key or script hash Buffer, @@ -38,8 +40,8 @@ var JSUtil = require('./util/js'); * ``` * * @param {*} data - The encoded data in various formats - * @param {Network|String|number} [network] - The network: 'livenet' or 'testnet' - * @param {String} [type] - The type of address: 'script' or 'pubkey' + * @param {Network|String|number=} network - The network: 'livenet' or 'testnet' + * @param {string=} type - The type of address: 'script' or 'pubkey' * @returns {Address} A new valid and frozen instance of an Address * @constructor */ @@ -60,7 +62,7 @@ function Address(data, network, type) { return data; } - $.checkArgument(data, new TypeError('First argument is required, please include address data.')); + $.checkArgument(data, 'First argument is required, please include address data.', 'guide/address.html'); if (network && !Networks.get(network)) { throw new TypeError('Second argument must be "livenet" or "testnet".'); @@ -88,13 +90,11 @@ function Address(data, network, type) { /** * Internal function used to split different kinds of arguments of the constructor * @param {*} data - The encoded data in various formats - * @param {Network|String|number} [network] - The network: 'livenet' or 'testnet' - * @param {String} [type] - The type of address: 'script' or 'pubkey' + * @param {Network|String|number=} network - The network: 'livenet' or 'testnet' + * @param {string=} type - The type of address: 'script' or 'pubkey' * @returns {Object} An "info" object with "type", "network", and "hashBuffer" */ Address.prototype._classifyArguments = function(data, network, type) { - var PublicKey = require('./publickey'); - var Script = require('./script'); /* jshint maxcomplexity: 10 */ // transform and validate input data if ((data instanceof Buffer || data instanceof Uint8Array) && data.length === 20) { @@ -124,7 +124,7 @@ Address.PayToScriptHash = 'scripthash'; * @returns {Object} An object with keys: hashBuffer * @private */ -Address._transformHash = function(hash){ +Address._transformHash = function(hash) { var info = {}; if (!(hash instanceof Buffer) && !(hash instanceof Uint8Array)) { throw new TypeError('Address supplied is not a buffer.'); @@ -161,26 +161,20 @@ Address._transformObject = function(data) { * @returns {Object} An object with keys: network and type * @private */ -Address._classifyFromVersion = function(buffer){ +Address._classifyFromVersion = function(buffer) { var version = {}; - version.network = Networks.get(buffer[0]); - switch (buffer[0]) { // the version byte - case Networks.livenet.pubkeyhash: - version.type = Address.PayToPublicKeyHash; - break; - case Networks.livenet.scripthash: - version.type = Address.PayToScriptHash; - break; + var pubkeyhashNetwork = Networks.get(buffer[0], 'pubkeyhash'); + var scripthashNetwork = Networks.get(buffer[0], 'scripthash'); - case Networks.testnet.pubkeyhash: - version.type = Address.PayToPublicKeyHash; - break; - - case Networks.testnet.scripthash: - version.type = Address.PayToScriptHash; - break; + if (pubkeyhashNetwork) { + version.network = pubkeyhashNetwork; + version.type = Address.PayToPublicKeyHash; + } else if (scripthashNetwork) { + version.network = scripthashNetwork; + version.type = Address.PayToScriptHash; } + return version; }; @@ -188,12 +182,12 @@ Address._classifyFromVersion = function(buffer){ * Internal function to transform a bitcoin address buffer * * @param {Buffer} buffer - An instance of a hex encoded address Buffer - * @param {String} [network] - The network: 'livenet' or 'testnet' - * @param {String} [type] - The type: 'pubkeyhash' or 'scripthash' + * @param {string=} network - The network: 'livenet' or 'testnet' + * @param {string=} type - The type: 'pubkeyhash' or 'scripthash' * @returns {Object} An object with keys: hashBuffer, network and type * @private */ -Address._transformBuffer = function(buffer, network, type){ +Address._transformBuffer = function(buffer, network, type) { /* jshint maxcomplexity: 9 */ var info = {}; if (!(buffer instanceof Buffer) && !(buffer instanceof Uint8Array)) { @@ -210,7 +204,7 @@ Address._transformBuffer = function(buffer, network, type){ throw new TypeError('Address has mismatched network type.'); } - if (!bufferVersion.type || ( type && type !== bufferVersion.type )) { + if (!bufferVersion.type || (type && type !== bufferVersion.type)) { throw new TypeError('Address has mismatched type.'); } @@ -227,8 +221,7 @@ Address._transformBuffer = function(buffer, network, type){ * @returns {Object} An object with keys: hashBuffer, type * @private */ -Address._transformPublicKey = function(pubkey){ - var PublicKey = require('./publickey'); +Address._transformPublicKey = function(pubkey) { var info = {}; if (!(pubkey instanceof PublicKey)) { throw new TypeError('Address must be an instance of PublicKey.'); @@ -245,23 +238,12 @@ Address._transformPublicKey = function(pubkey){ * @returns {Object} An object with keys: hashBuffer, type * @private */ -Address._transformScript = function(script, network){ - var Script = require('./script'); - var info = {}; - if (!(script instanceof Script)) { - throw new TypeError('Address must be an instance of Script.'); - } - if (script.isScriptHashOut()) { - info.hashBuffer = script.getData(); - info.type = Address.PayToScriptHash; - } else if (script.isPublicKeyHashOut()) { - info.hashBuffer = script.getData(); - info.type = Address.PayToPublicKeyHash; - } else { - info.hashBuffer = Hash.sha256ripemd160(script.toBuffer()); - info.type = Address.PayToScriptHash; +Address._transformScript = function(script, network) { + $.checkArgument(script instanceof Script, 'script must be a Script instance'); + var info = script.getAddressInfo(network); + if (!info) { + throw new errors.Script.CantDeriveAddress(script); } - info.network = Networks.get(network) || Networks.defaultNetwork; return info; }; @@ -278,25 +260,25 @@ Address._transformScript = function(script, network){ * @return {Address} */ Address.createMultisig = function(publicKeys, threshold, network) { - var Script = require('./script'); - network = network || publicKeys[0].network; - return new Address(Script.buildMultisigOut(publicKeys, threshold), network || Networks.defaultNetwork); + network = network || publicKeys[0].network || Networks.defaultNetwork; + return Address.payingTo(Script.buildMultisigOut(publicKeys, threshold), network); }; /** * Internal function to transform a bitcoin address string * - * @param {String} data - * @param {String|Network} [network] - either a Network instance, 'livenet', or 'testnet' - * @param {String} [type] - The type: 'pubkeyhash' or 'scripthash' + * @param {string} data + * @param {String|Network=} network - either a Network instance, 'livenet', or 'testnet' + * @param {string=} type - The type: 'pubkeyhash' or 'scripthash' * @returns {Object} An object with keys: hashBuffer, network and type * @private */ -Address._transformString = function(data, network, type){ - if( typeof(data) !== 'string' ) { - throw new TypeError('Address supplied is not a string.'); +Address._transformString = function(data, network, type) { + if (typeof(data) !== 'string') { + throw new TypeError('data parameter supplied is not a string.'); } - var addressBuffer = base58check.decode(data); + data = data.trim(); + var addressBuffer = Base58Check.decode(data); var info = Address._transformBuffer(addressBuffer, network, type); return info; }; @@ -308,7 +290,7 @@ Address._transformString = function(data, network, type){ * @param {String|Network} network - either a Network instance, 'livenet', or 'testnet' * @returns {Address} A new valid and frozen instance of an Address */ -Address.fromPublicKey = function(data, network){ +Address.fromPublicKey = function(data, network) { var info = Address._transformPublicKey(data); network = network || Networks.defaultNetwork; return new Address(info.hashBuffer, network, info.type); @@ -334,18 +316,42 @@ Address.fromPublicKeyHash = function(hash, network) { * @returns {Address} A new valid and frozen instance of an Address */ Address.fromScriptHash = function(hash, network) { + $.checkArgument(hash, 'hash parameter is required'); var info = Address._transformHash(hash); return new Address(info.hashBuffer, network, Address.PayToScriptHash); }; /** - * Instantiate an address from a Script + * Builds a p2sh address paying to script. This will hash the script and + * use that to create the address. + * If you want to extract an address associated with a script instead, + * see {{Address#fromScript}} + * + * @param {Script} script - An instance of Script + * @param {String|Network} network - either a Network instance, 'livenet', or 'testnet' + * @returns {Address} A new valid and frozen instance of an Address + */ +Address.payingTo = function(script, network) { + $.checkArgument(script, 'script is required'); + $.checkArgument(script instanceof Script, 'script must be instance of Script'); + + return Address.fromScriptHash(Hash.sha256ripemd160(script.toBuffer()), network); +}; + +/** + * Extract address from a Script. The script must be of one + * of the following types: p2pkh input, p2pkh output, p2sh input + * or p2sh output. + * This will analyze the script and extract address information from it. + * If you want to transform any script to a p2sh Address paying + * to that script's hash instead, use {{Address#payingTo}} * * @param {Script} script - An instance of Script * @param {String|Network} network - either a Network instance, 'livenet', or 'testnet' * @returns {Address} A new valid and frozen instance of an Address */ Address.fromScript = function(script, network) { + $.checkArgument(script instanceof Script, 'script must be a Script instance'); var info = Address._transformScript(script, network); return new Address(info.hashBuffer, network, info.type); }; @@ -354,8 +360,8 @@ Address.fromScript = function(script, network) { * Instantiate an address from a buffer of the address * * @param {Buffer} buffer - An instance of buffer of the address - * @param {String|Network} [network] - either a Network instance, 'livenet', or 'testnet' - * @param {String} [type] - The type of address: 'script' or 'pubkey' + * @param {String|Network=} network - either a Network instance, 'livenet', or 'testnet' + * @param {string=} type - The type of address: 'script' or 'pubkey' * @returns {Address} A new valid and frozen instance of an Address */ Address.fromBuffer = function(buffer, network, type) { @@ -366,9 +372,9 @@ Address.fromBuffer = function(buffer, network, type) { /** * Instantiate an address from an address string * - * @param {String} str - An string of the bitcoin address - * @param {String|Network} [network] - either a Network instance, 'livenet', or 'testnet' - * @param {String} [type] - The type of address: 'script' or 'pubkey' + * @param {string} str - An string of the bitcoin address + * @param {String|Network=} network - either a Network instance, 'livenet', or 'testnet' + * @param {string=} type - The type of address: 'script' or 'pubkey' * @returns {Address} A new valid and frozen instance of an Address */ Address.fromString = function(str, network, type) { @@ -377,21 +383,18 @@ Address.fromString = function(str, network, type) { }; /** - * Instantiate an address from JSON + * Instantiate an address from an Object * - * @param {String} json - An JSON string or Object with keys: hash, network and type + * @param {string} json - An JSON string or Object with keys: hash, network and type * @returns {Address} A new valid instance of an Address */ -Address.fromJSON = function fromJSON(json) { - if (JSUtil.isValidJSON(json)) { - json = JSON.parse(json); - } +Address.fromObject = function fromObject(obj) { $.checkState( - JSUtil.isHexa(json.hash), - 'Unexpected hash property, "' + json.hash + '", expected to be hex.' + JSUtil.isHexa(obj.hash), + 'Unexpected hash property, "' + obj.hash + '", expected to be hex.' ); - var hashBuffer = new Buffer(json.hash, 'hex'); - return new Address(hashBuffer, json.network, json.type); + var hashBuffer = new Buffer(obj.hash, 'hex'); + return new Address(hashBuffer, obj.network, obj.type); }; /** @@ -403,9 +406,9 @@ Address.fromJSON = function fromJSON(json) { * var error = Address.getValidationError('15vkcKf7gB23wLAnZLmbVuMiiVDc1Nm4a2', 'testnet'); * ``` * - * @param {String} data - The encoded data + * @param {string} data - The encoded data * @param {String|Network} network - either a Network instance, 'livenet', or 'testnet' - * @param {String} type - The type of address: 'script' or 'pubkey' + * @param {string} type - The type of address: 'script' or 'pubkey' * @returns {null|Error} The corresponding error message */ Address.getValidationError = function(data, network, type) { @@ -427,9 +430,9 @@ Address.getValidationError = function(data, network, type) { * assert(Address.isValid('15vkcKf7gB23wLAnZLmbVuMiiVDc1Nm4a2', 'livenet')); * ``` * - * @param {String} data - The encoded data + * @param {string} data - The encoded data * @param {String|Network} network - either a Network instance, 'livenet', or 'testnet' - * @param {String} type - The type of address: 'script' or 'pubkey' + * @param {string} type - The type of address: 'script' or 'pubkey' * @returns {boolean} The corresponding error message */ Address.isValid = function(data, network, type) { @@ -466,7 +469,7 @@ Address.prototype.toBuffer = function() { /** * @returns {Object} A plain object with the address information */ -Address.prototype.toObject = function toObject() { +Address.prototype.toObject = Address.prototype.toJSON = function toObject() { return { hash: this.hashBuffer.toString('hex'), type: this.type, @@ -474,48 +477,42 @@ Address.prototype.toObject = function toObject() { }; }; -/** - * @returns {String} A JSON representation of a plain object with the address information - */ -Address.prototype.toJSON = function toJSON() { - return JSON.stringify(this.toObject()); -}; - /** * Will return a the string representation of the address * - * @returns {String} Bitcoin address + * @returns {string} Bitcoin address */ Address.prototype.toString = function() { - return base58check.encode(this.toBuffer()); + return Base58Check.encode(this.toBuffer()); }; /** * Will return a string formatted for the console * - * @returns {String} Bitcoin address + * @returns {string} Bitcoin address */ Address.prototype.inspect = function() { - return ''; + return ''; }; module.exports = Address; +var Script = require('./script'); + }).call(this,require("buffer").Buffer) -},{"./crypto/hash":6,"./encoding/base58check":11,"./networks":20,"./publickey":23,"./script":24,"./util/js":39,"./util/preconditions":40,"buffer":42,"lodash":230}],2:[function(require,module,exports){ +},{"./crypto/hash":8,"./encoding/base58check":13,"./errors":17,"./networks":22,"./publickey":25,"./script":26,"./util/js":43,"./util/preconditions":44,"buffer":47,"lodash":241}],2:[function(require,module,exports){ (function (Buffer){ 'use strict'; var _ = require('lodash'); var BlockHeader = require('./blockheader'); -var BN = require('./crypto/bn'); -var BufferUtil = require('./util/buffer'); -var BufferReader = require('./encoding/bufferreader'); -var BufferWriter = require('./encoding/bufferwriter'); -var Hash = require('./crypto/hash'); -var JSUtil = require('./util/js'); -var Transaction = require('./transaction'); -var $ = require('./util/preconditions'); +var BN = require('../crypto/bn'); +var BufferUtil = require('../util/buffer'); +var BufferReader = require('../encoding/bufferreader'); +var BufferWriter = require('../encoding/bufferwriter'); +var Hash = require('../crypto/hash'); +var Transaction = require('../transaction'); +var $ = require('../util/preconditions'); /** * Instantiate a Block from a Buffer, JSON object, or Object with @@ -546,21 +543,8 @@ Block._from = function _from(arg) { var info = {}; if (BufferUtil.isBuffer(arg)) { info = Block._fromBufferReader(BufferReader(arg)); - } else if (JSUtil.isValidJSON(arg)) { - info = Block._fromJSON(arg); } else if (_.isObject(arg)) { - info = { - /** - * @name Block#header - * @type {BlockHeader} - */ - header: arg.header, - /** - * @name Block#transactions - * @type {Transaction[]} - */ - transactions: arg.transactions - }; + info = Block._fromObject(arg); } else { throw new TypeError('Unrecognized argument for Block'); } @@ -568,31 +552,32 @@ Block._from = function _from(arg) { }; /** - * @param {String|Object} - A JSON string or object + * @param {Object} - A plain JavaScript object * @returns {Object} - An object representing block data * @private */ -Block._fromJSON = function _fromJSON(data) { - if (JSUtil.isValidJSON(data)) { - data = JSON.parse(data); - } +Block._fromObject = function _fromObject(data) { var transactions = []; - data.transactions.forEach(function(data) { - transactions.push(Transaction().fromJSON(data)); + data.transactions.forEach(function(tx) { + if (tx instanceof Transaction) { + transactions.push(tx); + } else { + transactions.push(Transaction().fromObject(tx)); + } }); var info = { - header: BlockHeader.fromJSON(data.header), + header: BlockHeader.fromObject(data.header), transactions: transactions }; return info; }; /** - * @param {String|Object} - A JSON string or object + * @param {Object} - A plain JavaScript object * @returns {Block} - An instance of block */ -Block.fromJSON = function fromJSON(json) { - var info = Block._fromJSON(json); +Block.fromObject = function fromObject(obj) { + var info = Block._fromObject(obj); return new Block(info); }; @@ -618,6 +603,7 @@ Block._fromBufferReader = function _fromBufferReader(br) { * @returns {Block} - An instance of block */ Block.fromBufferReader = function fromBufferReader(br) { + $.checkArgument(br, 'br is required'); var info = Block._fromBufferReader(br); return new Block(info); }; @@ -627,11 +613,11 @@ Block.fromBufferReader = function fromBufferReader(br) { * @returns {Block} - An instance of block */ Block.fromBuffer = function fromBuffer(buf) { - return Block.fromBufferReader(BufferReader(buf)); + return Block.fromBufferReader(new BufferReader(buf)); }; /** - * @param {String} - str - A hex encoded string of the block + * @param {string} - str - A hex encoded string of the block * @returns {Block} - A hex encoded string of the block */ Block.fromString = function fromString(str) { @@ -656,7 +642,7 @@ Block.fromRawBlock = function fromRawBlock(data) { /** * @returns {Object} - A plain object with the block properties */ -Block.prototype.toObject = function toObject() { +Block.prototype.toObject = Block.prototype.toJSON = function toObject() { var transactions = []; this.transactions.forEach(function(tx) { transactions.push(tx.toObject()); @@ -667,13 +653,6 @@ Block.prototype.toObject = function toObject() { }; }; -/** - * @returns {String} - A JSON string - */ -Block.prototype.toJSON = function toJSON() { - return JSON.stringify(this.toObject()); -}; - /** * @returns {Buffer} - A buffer of the block */ @@ -682,7 +661,7 @@ Block.prototype.toBuffer = function toBuffer() { }; /** - * @returns {String} - A hex encoded string of the block + * @returns {string} - A hex encoded string of the block */ Block.prototype.toString = function toString() { return this.toBuffer().toString('hex'); @@ -776,7 +755,7 @@ Block.prototype._getHash = function() { var idProperty = { configurable: false, - writeable: false, + enumerable: true, /** * @returns {string} - The big endian hash buffer of the header */ @@ -792,7 +771,7 @@ Object.defineProperty(Block.prototype, 'id', idProperty); Object.defineProperty(Block.prototype, 'hash', idProperty); /** - * @returns {String} - A string formated for the console + * @returns {string} - A string formatted for the console */ Block.prototype.inspect = function inspect() { return ''; @@ -806,17 +785,20 @@ Block.Values = { module.exports = Block; }).call(this,require("buffer").Buffer) -},{"./blockheader":3,"./crypto/bn":4,"./crypto/hash":6,"./encoding/bufferreader":12,"./encoding/bufferwriter":13,"./transaction":27,"./util/buffer":38,"./util/js":39,"./util/preconditions":40,"buffer":42,"lodash":230}],3:[function(require,module,exports){ +},{"../crypto/bn":6,"../crypto/hash":8,"../encoding/bufferreader":14,"../encoding/bufferwriter":15,"../transaction":29,"../util/buffer":42,"../util/preconditions":44,"./blockheader":3,"buffer":47,"lodash":241}],3:[function(require,module,exports){ (function (Buffer){ 'use strict'; var _ = require('lodash'); -var BN = require('./crypto/bn'); -var BufferUtil = require('./util/buffer'); -var BufferReader = require('./encoding/bufferreader'); -var BufferWriter = require('./encoding/bufferwriter'); -var Hash = require('./crypto/hash'); -var JSUtil = require('./util/js'); +var BN = require('../crypto/bn'); +var BufferUtil = require('../util/buffer'); +var BufferReader = require('../encoding/bufferreader'); +var BufferWriter = require('../encoding/bufferwriter'); +var Hash = require('../crypto/hash'); +var JSUtil = require('../util/js'); +var $ = require('../util/preconditions'); + +var GENESIS_BITS = 0x1d00ffff; /** * Instantiate a BlockHeader from a Buffer, JSON object, or Object with @@ -830,7 +812,22 @@ var BlockHeader = function BlockHeader(arg) { if (!(this instanceof BlockHeader)) { return new BlockHeader(arg); } - _.extend(this, BlockHeader._from(arg)); + var info = BlockHeader._from(arg); + this.version = info.version; + this.prevHash = info.prevHash; + this.merkleRoot = info.merkleRoot; + this.time = info.time; + this.timestamp = info.time; + this.bits = info.bits; + this.nonce = info.nonce; + + if (info.hash) { + $.checkState( + this.hash === info.hash, + 'Argument object hash property does not match block hash.' + ); + } + return this; }; @@ -844,17 +841,8 @@ BlockHeader._from = function _from(arg) { var info = {}; if (BufferUtil.isBuffer(arg)) { info = BlockHeader._fromBufferReader(BufferReader(arg)); - } else if (JSUtil.isValidJSON(arg)) { - info = BlockHeader._fromJSON(arg); } else if (_.isObject(arg)) { - info = { - version: arg.version, - prevHash: arg.prevHash, - merkleRoot: arg.merkleRoot, - time: arg.time, - bits: arg.bits, - nonce: arg.nonce - }; + info = BlockHeader._fromObject(arg); } else { throw new TypeError('Unrecognized argument for BlockHeader'); } @@ -862,18 +850,25 @@ BlockHeader._from = function _from(arg) { }; /** - * @param {String|Object} - A JSON string or object + * @param {Object} - A JSON string * @returns {Object} - An object representing block header data * @private */ -BlockHeader._fromJSON = function _fromJSON(data) { - if (JSUtil.isValidJSON(data)) { - data = JSON.parse(data); +BlockHeader._fromObject = function _fromObject(data) { + $.checkArgument(data, 'data is required'); + var prevHash = data.prevHash; + var merkleRoot = data.merkleRoot; + if (_.isString(data.prevHash)) { + prevHash = BufferUtil.reverse(new Buffer(data.prevHash, 'hex')); + } + if (_.isString(data.merkleRoot)) { + merkleRoot = BufferUtil.reverse(new Buffer(data.merkleRoot, 'hex')); } var info = { + hash: data.hash, version: data.version, - prevHash: new Buffer(data.prevHash, 'hex'), - merkleRoot: new Buffer(data.merkleRoot, 'hex'), + prevHash: prevHash, + merkleRoot: merkleRoot, time: data.time, timestamp: data.time, bits: data.bits, @@ -883,11 +878,11 @@ BlockHeader._fromJSON = function _fromJSON(data) { }; /** - * @param {String|Object} - A JSON string or object + * @param {Object} - A plain JavaScript object * @returns {BlockHeader} - An instance of block header */ -BlockHeader.fromJSON = function fromJSON(json) { - var info = BlockHeader._fromJSON(json); +BlockHeader.fromObject = function fromObject(obj) { + var info = BlockHeader._fromObject(obj); return new BlockHeader(info); }; @@ -915,7 +910,7 @@ BlockHeader.fromBuffer = function fromBuffer(buf) { }; /** - * @param {String} - A hex encoded buffer of the block header + * @param {string} - A hex encoded buffer of the block header * @returns {BlockHeader} - An instance of block header */ BlockHeader.fromString = function fromString(str) { @@ -951,24 +946,18 @@ BlockHeader.fromBufferReader = function fromBufferReader(br) { /** * @returns {Object} - A plain object of the BlockHeader */ -BlockHeader.prototype.toObject = function toObject() { +BlockHeader.prototype.toObject = BlockHeader.prototype.toJSON = function toObject() { return { + hash: this.hash, version: this.version, - prevHash: this.prevHash.toString('hex'), - merkleRoot: this.merkleRoot.toString('hex'), + prevHash: BufferUtil.reverse(this.prevHash).toString('hex'), + merkleRoot: BufferUtil.reverse(this.merkleRoot).toString('hex'), time: this.time, bits: this.bits, nonce: this.nonce }; }; -/** - * @returns {String} - A JSON string - */ -BlockHeader.prototype.toJSON = function toJSON() { - return JSON.stringify(this.toObject()); -}; - /** * @returns {Buffer} - A Buffer of the BlockHeader */ @@ -977,7 +966,7 @@ BlockHeader.prototype.toBuffer = function toBuffer() { }; /** - * @returns {String} - A hex encoded string of the BlockHeader + * @returns {string} - A hex encoded string of the BlockHeader */ BlockHeader.prototype.toString = function toString() { return this.toBuffer().toString('hex'); @@ -1001,18 +990,36 @@ BlockHeader.prototype.toBufferWriter = function toBufferWriter(bw) { }; /** - * @link https://en.bitcoin.it/wiki/Difficulty - * @returns {BN} - An instance of BN with the decoded difficulty bits + * Returns the target difficulty for this block + * @param {Number} bits + * @returns {BN} An instance of BN with the decoded difficulty bits */ -BlockHeader.prototype.getTargetDifficulty = function getTargetDifficulty(info) { - var target = new BN(this.bits & 0xffffff); - var mov = 8 * ((this.bits >>> 24) - 3); +BlockHeader.prototype.getTargetDifficulty = function getTargetDifficulty(bits) { + bits = bits || this.bits; + + var target = new BN(bits & 0xffffff); + var mov = 8 * ((bits >>> 24) - 3); while (mov-- > 0) { target = target.mul(new BN(2)); } return target; }; +/** + * @link https://en.bitcoin.it/wiki/Difficulty + * @return {Number} + */ +BlockHeader.prototype.getDifficulty = function getDifficulty() { + var difficulty1TargetBN = this.getTargetDifficulty(GENESIS_BITS).mul(new BN(Math.pow(10, 8))); + var currentTargetBN = this.getTargetDifficulty(); + + var difficultyString = difficulty1TargetBN.div(currentTargetBN).toString(10); + var decimalPos = difficultyString.length - 8; + difficultyString = difficultyString.slice(0, decimalPos) + '.' + difficultyString.slice(decimalPos); + + return parseFloat(difficultyString); +}; + /** * @returns {Buffer} - The little endian hash buffer of the header */ @@ -1023,11 +1030,10 @@ BlockHeader.prototype._getHash = function hash() { var idProperty = { configurable: false, - writeable: false, enumerable: true, /** - * @returns {string} - The big endian hash buffer of the header - */ + * @returns {string} - The big endian hash buffer of the header + */ get: function() { if (!this._id) { this._id = BufferReader(this._getHash()).readReverse().toString('hex'); @@ -1064,7 +1070,7 @@ BlockHeader.prototype.validProofOfWork = function validProofOfWork() { }; /** - * @returns {String} - A string formated for the console + * @returns {string} - A string formated for the console */ BlockHeader.prototype.inspect = function inspect() { return ''; @@ -1079,7 +1085,289 @@ BlockHeader.Constants = { module.exports = BlockHeader; }).call(this,require("buffer").Buffer) -},{"./crypto/bn":4,"./crypto/hash":6,"./encoding/bufferreader":12,"./encoding/bufferwriter":13,"./util/buffer":38,"./util/js":39,"buffer":42,"lodash":230}],4:[function(require,module,exports){ +},{"../crypto/bn":6,"../crypto/hash":8,"../encoding/bufferreader":14,"../encoding/bufferwriter":15,"../util/buffer":42,"../util/js":43,"../util/preconditions":44,"buffer":47,"lodash":241}],4:[function(require,module,exports){ +module.exports = require('./block'); + +module.exports.BlockHeader = require('./blockheader'); +module.exports.MerkleBlock = require('./merkleblock'); + +},{"./block":2,"./blockheader":3,"./merkleblock":5}],5:[function(require,module,exports){ +(function (Buffer){ +'use strict'; + +var _ = require('lodash'); +var BlockHeader = require('./blockheader'); +var BufferUtil = require('../util/buffer'); +var BufferReader = require('../encoding/bufferreader'); +var BufferWriter = require('../encoding/bufferwriter'); +var Hash = require('../crypto/hash'); +var JSUtil = require('../util/js'); +var Transaction = require('../transaction'); +var $ = require('../util/preconditions'); + +/** + * Instantiate a MerkleBlock from a Buffer, JSON object, or Object with + * the properties of the Block + * + * @param {*} - A Buffer, JSON string, or Object representing a MerkleBlock + * @returns {MerkleBlock} + * @constructor + */ +function MerkleBlock(arg) { + /* jshint maxstatements: 18 */ + + if (!(this instanceof MerkleBlock)) { + return new MerkleBlock(arg); + } + + var info = {}; + if (BufferUtil.isBuffer(arg)) { + info = MerkleBlock._fromBufferReader(BufferReader(arg)); + } else if (_.isObject(arg)) { + var header; + if(arg.header instanceof BlockHeader) { + header = arg.header; + } else { + header = BlockHeader.fromObject(arg.header); + } + info = { + /** + * @name MerkleBlock#header + * @type {BlockHeader} + */ + header: header, + /** + * @name MerkleBlock#numTransactions + * @type {Number} + */ + numTransactions: arg.numTransactions, + /** + * @name MerkleBlock#hashes + * @type {String[]} + */ + hashes: arg.hashes, + /** + * @name MerkleBlock#flags + * @type {Number[]} + */ + flags: arg.flags + }; + } else { + throw new TypeError('Unrecognized argument for MerkleBlock'); + } + _.extend(this,info); + this._flagBitsUsed = 0; + this._hashesUsed = 0; + return this; +} + +/** + * @param {Buffer} - MerkleBlock data in a Buffer object + * @returns {MerkleBlock} - A MerkleBlock object + */ +MerkleBlock.fromBuffer = function fromBuffer(buf) { + return MerkleBlock.fromBufferReader(BufferReader(buf)); +}; + +/** + * @param {BufferReader} - MerkleBlock data in a BufferReader object + * @returns {MerkleBlock} - A MerkleBlock object + */ +MerkleBlock.fromBufferReader = function fromBufferReader(br) { + return new MerkleBlock(MerkleBlock._fromBufferReader(br)); +}; + +/** + * @returns {Buffer} - A buffer of the block + */ +MerkleBlock.prototype.toBuffer = function toBuffer() { + return this.toBufferWriter().concat(); +}; + +/** + * @param {BufferWriter} - An existing instance of BufferWriter + * @returns {BufferWriter} - An instance of BufferWriter representation of the MerkleBlock + */ +MerkleBlock.prototype.toBufferWriter = function toBufferWriter(bw) { + if (!bw) { + bw = new BufferWriter(); + } + bw.write(this.header.toBuffer()); + bw.writeUInt32LE(this.numTransactions); + bw.writeVarintNum(this.hashes.length); + for (var i = 0; i < this.hashes.length; i++) { + bw.write(new Buffer(this.hashes[i], 'hex')); + } + bw.writeVarintNum(this.flags.length); + for (i = 0; i < this.flags.length; i++) { + bw.writeUInt8(this.flags[i]); + } + return bw; +}; + +/** + * @returns {Object} - A plain object with the MerkleBlock properties + */ +MerkleBlock.prototype.toObject = MerkleBlock.prototype.toJSON = function toObject() { + return { + header: this.header.toObject(), + numTransactions: this.numTransactions, + hashes: this.hashes, + flags: this.flags + }; +}; + +/** + * Verify that the MerkleBlock is valid + * @returns {Boolean} - True/False whether this MerkleBlock is Valid + */ +MerkleBlock.prototype.validMerkleTree = function validMerkleTree() { + $.checkState(_.isArray(this.flags), 'MerkleBlock flags is not an array'); + $.checkState(_.isArray(this.hashes), 'MerkleBlock hashes is not an array'); + + // Can't have more hashes than numTransactions + if(this.hashes.length > this.numTransactions) { + return false; + } + + // Can't have more flag bits than num hashes + if(this.flags.length * 8 < this.hashes.length) { + return false; + } + + var height = this._calcTreeHeight(); + var opts = { hashesUsed: 0, flagBitsUsed: 0 }; + var root = this._traverseMerkleTree(height, 0, opts); + if(opts.hashesUsed !== this.hashes.length) { + return false; + } + return BufferUtil.equals(root, this.header.merkleRoot); +}; + +/** + * Traverse a the tree in this MerkleBlock, validating it along the way + * Modeled after Bitcoin Core merkleblock.cpp TraverseAndExtract() + * @param {Number} - depth - Current height + * @param {Number} - pos - Current position in the tree + * @param {Object} - opts - Object with values that need to be mutated throughout the traversal + * @param {Number} - opts.flagBitsUsed - Number of flag bits used, should start at 0 + * @param {Number} - opts.hashesUsed - Number of hashes used, should start at 0 + * @param {Array} - opts.txs - Will finish populated by transactions found during traversal + * @returns {Buffer|null} - Buffer containing the Merkle Hash for that height + * @private + */ +MerkleBlock.prototype._traverseMerkleTree = function traverseMerkleTree(depth, pos, opts) { + /* jshint maxcomplexity: 12*/ + /* jshint maxstatements: 20 */ + + opts = opts || {}; + opts.txs = opts.txs || []; + opts.flagBitsUsed = opts.flagBitsUsed || 0; + opts.hashesUsed = opts.hashesUsed || 0; + + if(opts.flagBitsUsed > this.flags.length * 8) { + return null; + } + var isParentOfMatch = (this.flags[opts.flagBitsUsed >> 3] >>> (opts.flagBitsUsed++ & 7)) & 1; + if(depth === 0 || !isParentOfMatch) { + if(opts.hashesUsed >= this.hashes.length) { + return null; + } + var hash = this.hashes[opts.hashesUsed++]; + if(depth === 0 && isParentOfMatch) { + opts.txs.push(hash); + } + return new Buffer(hash, 'hex'); + } else { + var left = this._traverseMerkleTree(depth-1, pos*2, opts); + var right = left; + if(pos*2+1 < this._calcTreeWidth(depth-1)) { + right = this._traverseMerkleTree(depth-1, pos*2+1, opts); + } + return Hash.sha256sha256(new Buffer.concat([left, right])); + } +}; + +/** Calculates the width of a merkle tree at a given height. + * Modeled after Bitcoin Core merkleblock.h CalcTreeWidth() + * @param {Number} - Height at which we want the tree width + * @returns {Number} - Width of the tree at a given height + * @private + */ +MerkleBlock.prototype._calcTreeWidth = function calcTreeWidth(height) { + return (this.numTransactions + (1 << height) - 1) >> height; +}; + +/** Calculates the height of the merkle tree in this MerkleBlock + * @param {Number} - Height at which we want the tree width + * @returns {Number} - Height of the merkle tree in this MerkleBlock + * @private + */ +MerkleBlock.prototype._calcTreeHeight = function calcTreeHeight() { + var height = 0; + while (this._calcTreeWidth(height) > 1) { + height++; + } + return height; +}; + +/** + * @param {Transaction|String} - Transaction or Transaction ID Hash + * @returns {Boolean} - return true/false if this MerkleBlock has the TX or not + * @private + */ +MerkleBlock.prototype.hasTransaction = function hasTransaction(tx) { + $.checkArgument(!_.isUndefined(tx), 'tx cannot be undefined'); + $.checkArgument(tx instanceof Transaction || typeof tx === 'string', + 'Invalid tx given, tx must be a "string" or "Transaction"'); + + var hash = tx; + if(tx instanceof Transaction) { + // We need to reverse the id hash for the lookup + hash = BufferUtil.reverse(new Buffer(tx.id, 'hex')).toString('hex'); + } + + var txs = []; + var height = this._calcTreeHeight(); + this._traverseMerkleTree(height, 0, { txs: txs }); + return txs.indexOf(hash) !== -1; +}; + +/** + * @param {Buffer} - MerkleBlock data + * @returns {Object} - An Object representing merkleblock data + * @private + */ +MerkleBlock._fromBufferReader = function _fromBufferReader(br) { + $.checkState(!br.finished(), 'No merkleblock data received'); + var info = {}; + info.header = BlockHeader.fromBufferReader(br); + info.numTransactions = br.readUInt32LE(); + var numHashes = br.readVarintNum(); + info.hashes = []; + for (var i = 0; i < numHashes; i++) { + info.hashes.push(br.read(32).toString('hex')); + } + var numFlags = br.readVarintNum(); + info.flags = []; + for (i = 0; i < numFlags; i++) { + info.flags.push(br.readUInt8()); + } + return info; +}; + +/** + * @param {Object} - A plain JavaScript object + * @returns {Block} - An instance of block + */ +MerkleBlock.fromObject = function fromObject(obj) { + return new MerkleBlock(obj); +}; + +module.exports = MerkleBlock; + +}).call(this,require("buffer").Buffer) +},{"../crypto/hash":8,"../encoding/bufferreader":14,"../encoding/bufferwriter":15,"../transaction":29,"../util/buffer":42,"../util/js":43,"../util/preconditions":44,"./blockheader":3,"buffer":47,"lodash":241}],6:[function(require,module,exports){ (function (Buffer){ 'use strict'; @@ -1104,9 +1392,9 @@ BN.fromNumber = function(n) { return new BN(n); }; -BN.fromString = function(str) { +BN.fromString = function(str, base) { $.checkArgument(_.isString(str)); - return new BN(str); + return new BN(str, base); }; BN.fromBuffer = function(buf, opts) { @@ -1214,10 +1502,11 @@ BN.prototype.toSM = function(opts) { * This is analogous to the constructor for CScriptNum in bitcoind. Many ops in * bitcoind's script interpreter use CScriptNum, which is not really a proper * bignum. Instead, an error is thrown if trying to input a number bigger than - * 4 bytes. We copy that behavior here. + * 4 bytes. We copy that behavior here. A third argument, `size`, is provided to + * extend the hard limit of 4 bytes, as some usages require more than 4 bytes. */ -BN.fromScriptNumBuffer = function(buf, fRequireMinimal) { - var nMaxNumSize = 4; +BN.fromScriptNumBuffer = function(buf, fRequireMinimal, size) { + var nMaxNumSize = size || 4; $.checkArgument(buf.length <= nMaxNumSize, new Error('script number overflow')); if (fRequireMinimal && buf.length > 0) { // Check that the number is encoded with the minimum possible @@ -1258,6 +1547,10 @@ BN.prototype.gt = function(b) { return this.cmp(b) > 0; }; +BN.prototype.gte = function(b) { + return this.cmp(b) >= 0; +}; + BN.prototype.lt = function(b) { return this.cmp(b) < 0; }; @@ -1280,7 +1573,7 @@ BN.pad = function(buf, natlen, size) { module.exports = BN; }).call(this,require("buffer").Buffer) -},{"../util/preconditions":40,"bn.js":207,"buffer":42,"lodash":230}],5:[function(require,module,exports){ +},{"../util/preconditions":44,"bn.js":217,"buffer":47,"lodash":241}],7:[function(require,module,exports){ (function (Buffer){ 'use strict'; @@ -1579,8 +1872,8 @@ ECDSA.verify = function(hashbuf, sig, pubkey, endian) { module.exports = ECDSA; }).call(this,require("buffer").Buffer) -},{"../publickey":23,"../util/buffer":38,"../util/preconditions":40,"./bn":4,"./hash":6,"./point":7,"./random":8,"./signature":9,"buffer":42,"lodash":230}],6:[function(require,module,exports){ -(function (Buffer){ +},{"../publickey":25,"../util/buffer":42,"../util/preconditions":44,"./bn":6,"./hash":8,"./point":9,"./random":10,"./signature":11,"buffer":47,"lodash":241}],8:[function(require,module,exports){ +(function (process,Buffer){ 'use strict'; var hashjs = require('hash.js'); @@ -1612,10 +1905,19 @@ Hash.sha256sha256 = function(buf) { Hash.ripemd160 = function(buf) { $.checkArgument(BufferUtil.isBuffer(buf)); - var hash = (new hashjs.ripemd160()).update(buf).digest(); - return new Buffer(hash); + return crypto.createHash('ripemd160').update(buf).digest(); }; +// Node.js crypto ripemd160 hashes are not supported in a browser +// We'll replace with a (slower) version that does. +if (process.browser) { + Hash.ripemd160 = function(buf) { + $.checkArgument(BufferUtil.isBuffer(buf)); + var hash = (new hashjs.ripemd160()).update(buf).digest(); + return new Buffer(hash); + }; +} + Hash.sha256ripemd160 = function(buf) { $.checkArgument(BufferUtil.isBuffer(buf)); return Hash.ripemd160(Hash.sha256(buf)); @@ -1671,13 +1973,13 @@ Hash.sha512hmac = function(data, key) { return Hash.hmac(Hash.sha512, data, key); }; -}).call(this,require("buffer").Buffer) -},{"../util/buffer":38,"../util/preconditions":40,"buffer":42,"crypto":46,"hash.js":223,"sha512":233}],7:[function(require,module,exports){ +}).call(this,require('_process'),require("buffer").Buffer) +},{"../util/buffer":42,"../util/preconditions":44,"_process":194,"buffer":47,"crypto":51,"hash.js":234,"sha512":244}],9:[function(require,module,exports){ (function (Buffer){ 'use strict'; var BN = require('./bn'); -var bufferUtil = require('../util/buffer'); +var BufferUtil = require('../util/buffer'); var ec = require('elliptic').curves.secp256k1; var ecPoint = ec.curve.point.bind(ec.curve); var ecPointFromX = ec.curve.pointFromX.bind(ec.curve); @@ -1815,13 +2117,13 @@ Point.pointToCompressed = function pointToCompressed(point) { } else { prefix = new Buffer([0x02]); } - return bufferUtil.concat([prefix, xbuf]); + return BufferUtil.concat([prefix, xbuf]); }; module.exports = Point; }).call(this,require("buffer").Buffer) -},{"../util/buffer":38,"./bn":4,"buffer":42,"elliptic":209}],8:[function(require,module,exports){ +},{"../util/buffer":42,"./bn":6,"buffer":47,"elliptic":219}],10:[function(require,module,exports){ (function (process,Buffer){ 'use strict'; @@ -1882,7 +2184,7 @@ Random.getPseudoRandomBuffer = function(size) { module.exports = Random; }).call(this,require('_process'),require("buffer").Buffer) -},{"_process":184,"buffer":42,"crypto":46}],9:[function(require,module,exports){ +},{"_process":194,"buffer":47,"crypto":51}],11:[function(require,module,exports){ (function (Buffer){ 'use strict'; @@ -1890,6 +2192,7 @@ var BN = require('./bn'); var _ = require('lodash'); var $ = require('../util/preconditions'); var BufferUtil = require('../util/buffer'); +var JSUtil = require('../util/js'); var Signature = function Signature(r, s) { if (!(this instanceof Signature)) { @@ -1913,14 +2216,22 @@ Signature.prototype.set = function(obj) { this.i = typeof obj.i !== 'undefined' ? obj.i : this.i; //public key recovery parameter in range [0, 3] this.compressed = typeof obj.compressed !== 'undefined' ? obj.compressed : this.compressed; //whether the recovered pubkey is compressed + this.nhashtype = obj.nhashtype || this.nhashtype || undefined; return this; }; Signature.fromCompact = function(buf) { + $.checkArgument(BufferUtil.isBuffer(buf), 'Argument is expected to be a Buffer'); + var sig = new Signature(); - //TODO: handle uncompressed pubkeys + var compressed = true; var i = buf.slice(0, 1)[0] - 27 - 4; + if (i < 0) { + compressed = false; + i = i + 4; + } + var b2 = buf.slice(1, 33); var b3 = buf.slice(33, 65); @@ -1936,7 +2247,7 @@ Signature.fromCompact = function(buf) { return sig; }; -Signature.fromDER = function(buf, strict) { +Signature.fromDER = Signature.fromBuffer = function(buf, strict) { var obj = Signature.parseDER(buf, strict); var sig = new Signature(); @@ -2028,8 +2339,9 @@ Signature.prototype.toCompact = function(i, compressed) { } var val = i + 27 + 4; - if (compressed === false) + if (compressed === false) { val = val - 4; + } var b1 = new Buffer([val]); var b2 = this.r.toBuffer({ size: 32 @@ -2162,7 +2474,12 @@ Signature.prototype.hasLowS = function() { * Translated from bitcoind's IsDefinedHashtypeSignature */ Signature.prototype.hasDefinedHashtype = function() { - if (this.nhashtype < Signature.SIGHASH_ALL || this.nhashtype > Signature.SIGHASH_SINGLE) { + if (!JSUtil.isNaturalNumber(this.nhashtype)) { + return false; + } + // accept with or without Signature.SIGHASH_ANYONECANPAY by ignoring the bit + var temp = this.nhashtype & ~Signature.SIGHASH_ANYONECANPAY; + if (temp < Signature.SIGHASH_ALL || temp > Signature.SIGHASH_SINGLE) { return false; } return true; @@ -2183,7 +2500,7 @@ Signature.SIGHASH_ANYONECANPAY = 0x80; module.exports = Signature; }).call(this,require("buffer").Buffer) -},{"../util/buffer":38,"../util/preconditions":40,"./bn":4,"buffer":42,"lodash":230}],10:[function(require,module,exports){ +},{"../util/buffer":42,"../util/js":43,"../util/preconditions":44,"./bn":6,"buffer":47,"lodash":241}],12:[function(require,module,exports){ (function (Buffer){ 'use strict'; @@ -2257,12 +2574,12 @@ Base58.prototype.toString = function() { module.exports = Base58; }).call(this,require("buffer").Buffer) -},{"bs58":208,"buffer":42,"lodash":230}],11:[function(require,module,exports){ +},{"bs58":218,"buffer":47,"lodash":241}],13:[function(require,module,exports){ (function (Buffer){ 'use strict'; var _ = require('lodash'); -var base58 = require('./base58'); +var Base58 = require('./base58'); var buffer = require('buffer'); var sha256sha256 = require('../crypto/hash').sha256sha256; @@ -2287,10 +2604,10 @@ Base58Check.prototype.set = function(obj) { Base58Check.validChecksum = function validChecksum(data, checksum) { if (_.isString(data)) { - data = new buffer.Buffer(base58.decode(data)); + data = new buffer.Buffer(Base58.decode(data)); } if (_.isString(checksum)) { - checksum = new buffer.Buffer(base58.decode(checksum)); + checksum = new buffer.Buffer(Base58.decode(checksum)); } if (!checksum) { checksum = data.slice(-4); @@ -2303,7 +2620,7 @@ Base58Check.decode = function(s) { if (typeof s !== 'string') throw new Error('Input must be a string'); - var buf = new Buffer(base58.decode(s)); + var buf = new Buffer(Base58.decode(s)); if (buf.length < 4) throw new Error("Input string too short"); @@ -2331,7 +2648,7 @@ Base58Check.encode = function(buf) { var hash = Base58Check.checksum(buf); buf.copy(checkedBuf); hash.copy(checkedBuf, buf.length); - return base58.encode(checkedBuf); + return Base58.encode(checkedBuf); }; Base58Check.prototype.fromBuffer = function(buf) { @@ -2356,26 +2673,35 @@ Base58Check.prototype.toString = function() { module.exports = Base58Check; }).call(this,require("buffer").Buffer) -},{"../crypto/hash":6,"./base58":10,"buffer":42,"lodash":230}],12:[function(require,module,exports){ +},{"../crypto/hash":8,"./base58":12,"buffer":47,"lodash":241}],14:[function(require,module,exports){ (function (Buffer){ 'use strict'; var _ = require('lodash'); var $ = require('../util/preconditions'); -var bufferUtil = require('../util/buffer'); +var BufferUtil = require('../util/buffer'); var BN = require('../crypto/bn'); var BufferReader = function BufferReader(buf) { if (!(this instanceof BufferReader)) { return new BufferReader(buf); } + if (_.isUndefined(buf)) { + return; + } if (Buffer.isBuffer(buf)) { this.set({ buf: buf }); - } else if (buf) { + } else if (_.isString(buf)) { + this.set({ + buf: new Buffer(buf, 'hex'), + }); + } else if (_.isObject(buf)) { var obj = buf; this.set(obj); + } else { + throw new TypeError('Unrecognized argument for BufferReader'); } }; @@ -2442,11 +2768,22 @@ BufferReader.prototype.readUInt64BEBN = function() { }; BufferReader.prototype.readUInt64LEBN = function() { - var buf = this.buf.slice(this.pos, this.pos + 8); - var reversebuf = BufferReader({ - buf: buf - }).readReverse(); - var bn = BN.fromBuffer(reversebuf); + var second = this.buf.readUInt32LE(this.pos); + var first = this.buf.readUInt32LE(this.pos + 4); + var combined = (first * 0x100000000) + second; + // Instantiating an instance of BN with a number is faster than with an + // array or string. However, the maximum safe number for a double precision + // floating point is 2 ^ 52 - 1 (0x1fffffffffffff), thus we can safely use + // non-floating point numbers less than this amount (52 bits). And in the case + // that the number is larger, we can instatiate an instance of BN by passing + // an array from the buffer (slower) and specifying the endianness. + var bn; + if (combined <= 0x1fffffffffffff) { + bn = new BN(combined); + } else { + var data = Array.prototype.slice.call(this.buf, this.pos, this.pos + 8); + bn = new BN(data, 10, 'le'); + } this.pos = this.pos + 8; return bn; }; @@ -2526,13 +2863,13 @@ BufferReader.prototype.readReverse = function(len) { } var buf = this.buf.slice(this.pos, this.pos + len); this.pos = this.pos + len; - return bufferUtil.reverse(buf); + return BufferUtil.reverse(buf); }; module.exports = BufferReader; }).call(this,require("buffer").Buffer) -},{"../crypto/bn":4,"../util/buffer":38,"../util/preconditions":40,"buffer":42,"lodash":230}],13:[function(require,module,exports){ +},{"../crypto/bn":6,"../util/buffer":42,"../util/preconditions":44,"buffer":47,"lodash":241}],15:[function(require,module,exports){ (function (Buffer){ 'use strict'; @@ -2688,7 +3025,7 @@ BufferWriter.varintBufBN = function(bn) { module.exports = BufferWriter; }).call(this,require("buffer").Buffer) -},{"../util/buffer":38,"assert":41,"buffer":42}],14:[function(require,module,exports){ +},{"../util/buffer":42,"assert":45,"buffer":47}],16:[function(require,module,exports){ (function (Buffer){ 'use strict'; @@ -2764,7 +3101,7 @@ Varint.prototype.toNumber = function() { module.exports = Varint; }).call(this,require("buffer").Buffer) -},{"../crypto/bn":4,"./bufferreader":12,"./bufferwriter":13,"buffer":42}],15:[function(require,module,exports){ +},{"../crypto/bn":6,"./bufferreader":14,"./bufferwriter":15,"buffer":47}],17:[function(require,module,exports){ 'use strict'; var _ = require('lodash'); @@ -2827,9 +3164,11 @@ module.exports.extend = function(spec) { return traverseNode(bitcore.Error, spec); }; -},{"./spec":16,"lodash":230}],16:[function(require,module,exports){ +},{"./spec":18,"lodash":241}],18:[function(require,module,exports){ 'use strict'; +var docsURL = 'http://bitcore.io/'; + module.exports = [{ name: 'InvalidB58Char', message: 'Invalid Base58 character: {0} in {1}' @@ -2851,11 +3190,12 @@ module.exports = [{ }, { name: 'InvalidArgument', message: function() { - return 'Invalid Argument' + (arguments[0] ? (': ' + arguments[0]) : ''); + return 'Invalid Argument' + (arguments[0] ? (': ' + arguments[0]) : '') + + (arguments[1] ? (' Documentation: ' + docsURL + arguments[1]) : ''); } }, { name: 'AbstractMethodInvoked', - message: 'Abstract Method Invokation: {0}' + message: 'Abstract Method Invocation: {0}' }, { name: 'InvalidArgumentType', message: function() { @@ -2880,10 +3220,25 @@ module.exports = [{ errors: [{ name: 'MissingScript', message: 'Need a script to create an input' + }, { + name: 'UnsupportedScript', + message: 'Unsupported input script type: {0}' + }, { + name: 'MissingPreviousOutput', + message: 'No previous output information.' }] }, { name: 'NeedMoreInfo', message: '{0}' + }, { + name: 'InvalidSorting', + message: 'The sorting function provided did not return the change output as one of the array elements' + }, { + name: 'InvalidOutputAmountSum', + message: '{0}' + }, { + name: 'MissingSignatures', + message: 'Some inputs have not been fully signed' }, { name: 'InvalidIndex', message: 'Invalid index: {0} is not between 0, {1}' @@ -2893,12 +3248,34 @@ module.exports = [{ }, { name: 'DustOutputs', message: 'Dust amount detected in one output' + }, { + name: 'InvalidSatoshis', + message: 'Output satoshis are invalid', }, { name: 'FeeError', - message: 'Fees are not correctly set {0}', + message: 'Internal Error on Fee {0}', + errors: [{ + name: 'TooSmall', + message: 'Fee is too small: {0}', + }, { + name: 'TooLarge', + message: 'Fee is too large: {0}', + }, { + name: 'Different', + message: 'Unspent value is different from specified fee: {0}', + }] }, { name: 'ChangeAddressMissing', message: 'Change address is missing' + }, { + name: 'BlockHeightTooHigh', + message: 'Block Height can be at most 2^32 -1' + }, { + name: 'NLockTimeOutOfRange', + message: 'Block Height can only be between 0 and 499 999 999' + }, { + name: 'LockTimeTooEarly', + message: 'Lock Time can\'t be earlier than UNIX date 500 000 000' }] }, { name: 'Script', @@ -2906,6 +3283,12 @@ module.exports = [{ errors: [{ name: 'UnrecognizedAddress', message: 'Expected argument {0} to be an address' + }, { + name: 'CantDeriveAddress', + message: 'Can\'t derive address associated with script {0}, needs to be p2pkh in, p2pkh out, p2sh in, or p2sh out.' + }, { + name: 'InvalidBuffer', + message: 'Invalid script buffer: can\'t parse valid script from given buffer {0}' }] }, { name: 'HDPrivateKey', @@ -2948,6 +3331,9 @@ module.exports = [{ }, { name: 'InvalidPath', message: 'Invalid derivation path, it should look like: "m/1/100", got "{0}"' + }, { + name: 'InvalidIndexCantDeriveHardened', + message: 'Invalid argument: creating a hardened path requires an HDPrivateKey' }, { name: 'MustSupplyArgument', message: 'Must supply an argument to create a HDPublicKey' @@ -2957,7 +3343,7 @@ module.exports = [{ }] }]; -},{}],17:[function(require,module,exports){ +},{}],19:[function(require,module,exports){ 'use strict'; module.exports = { @@ -3004,7 +3390,7 @@ module.exports = { } }; -},{}],18:[function(require,module,exports){ +},{}],20:[function(require,module,exports){ (function (Buffer){ 'use strict'; @@ -3012,6 +3398,7 @@ module.exports = { var assert = require('assert'); var buffer = require('buffer'); var _ = require('lodash'); +var $ = require('./util/preconditions'); var BN = require('./crypto/bn'); var Base58 = require('./encoding/base58'); @@ -3029,7 +3416,7 @@ var BufferUtil = require('./util/buffer'); var JSUtil = require('./util/js'); var MINIMUM_ENTROPY_BITS = 128; -var BITS_TO_BYTES = 1/8; +var BITS_TO_BYTES = 1 / 8; var MAXIMUM_ENTROPY_BITS = 512; @@ -3116,13 +3503,23 @@ HDPrivateKey._getDerivationIndexes = function(path) { } var indexes = steps.slice(1).map(function(step) { - var index = parseInt(step); - index += step != index.toString() ? HDPrivateKey.Hardened : 0; + var isHardened = step.slice(-1) === '\''; + if (isHardened) { + step = step.slice(0, -1); + } + if (!step || step[0] === '-') { + return NaN; + } + var index = +step; // cast to number + if (isHardened) { + index += HDPrivateKey.Hardened; + } + return index; }); return _.any(indexes, isNaN) ? null : indexes; -} +}; /** * Get a derivated child based on a string or number. @@ -3182,10 +3579,14 @@ HDPrivateKey.prototype._deriveWithNumber = function(index, hardened) { data = BufferUtil.concat([this.publicKey.toBuffer(), indexBuffer]); } var hash = Hash.sha512hmac(data, this._buffers.chainCode); - var leftPart = BN.fromBuffer(hash.slice(0, 32), {size: 32}); + var leftPart = BN.fromBuffer(hash.slice(0, 32), { + size: 32 + }); var chainCode = hash.slice(32, 64); - var privateKey = leftPart.add(this.privateKey.toBigNumber()).mod(Point.getN()).toBuffer({size: 32}); + var privateKey = leftPart.add(this.privateKey.toBigNumber()).mod(Point.getN()).toBuffer({ + size: 32 + }); var derived = new HDPrivateKey({ network: this.network, @@ -3271,7 +3672,13 @@ HDPrivateKey._validateNetwork = function(data, networkArg) { return null; }; -HDPrivateKey.fromJSON = HDPrivateKey.fromObject = HDPrivateKey.fromString = function(arg) { +HDPrivateKey.fromString = function(arg) { + $.checkArgument(_.isString(arg), 'No valid string was provided'); + return new HDPrivateKey(arg); +}; + +HDPrivateKey.fromObject = function(arg) { + $.checkArgument(_.isObject(arg), 'No valid argument was provided'); return new HDPrivateKey(arg); }; @@ -3300,7 +3707,7 @@ HDPrivateKey.prototype._buildFromSerialized = function(arg) { version: decoded.slice(HDPrivateKey.VersionStart, HDPrivateKey.VersionEnd), depth: decoded.slice(HDPrivateKey.DepthStart, HDPrivateKey.DepthEnd), parentFingerPrint: decoded.slice(HDPrivateKey.ParentFingerPrintStart, - HDPrivateKey.ParentFingerPrintEnd), + HDPrivateKey.ParentFingerPrintEnd), childIndex: decoded.slice(HDPrivateKey.ChildIndexStart, HDPrivateKey.ChildIndexEnd), chainCode: decoded.slice(HDPrivateKey.ChainCodeStart, HDPrivateKey.ChainCodeEnd), privateKey: decoded.slice(HDPrivateKey.PrivateKeyStart, HDPrivateKey.PrivateKeyEnd), @@ -3347,6 +3754,15 @@ HDPrivateKey.fromSeed = function(hexa, network) { }); }; + + +HDPrivateKey.prototype._calcHDPublicKey = function() { + if (!this._hdPublicKey) { + var HDPublicKey = require('./hdpublickey'); + this._hdPublicKey = new HDPublicKey(this); + } +}; + /** * Receives a object with buffers in all the properties and populates the * internal structure @@ -3386,32 +3802,43 @@ HDPrivateKey.prototype._buildFromBuffers = function(arg) { } } + var network = Network.get(BufferUtil.integerFromBuffer(arg.version)); var xprivkey; xprivkey = Base58Check.encode(buffer.Buffer.concat(sequence)); arg.xprivkey = new Buffer(xprivkey); - var privateKey = new PrivateKey(BN.fromBuffer(arg.privateKey)); + var privateKey = new PrivateKey(BN.fromBuffer(arg.privateKey), network); var publicKey = privateKey.toPublicKey(); var size = HDPrivateKey.ParentFingerPrintSize; var fingerPrint = Hash.sha256ripemd160(publicKey.toBuffer()).slice(0, size); JSUtil.defineImmutable(this, { xprivkey: xprivkey, - network: Network.get(BufferUtil.integerFromBuffer(arg.version)), + network: network, depth: BufferUtil.integerFromSingleByteBuffer(arg.depth), privateKey: privateKey, publicKey: publicKey, fingerPrint: fingerPrint }); - var HDPublicKey = require('./hdpublickey'); - var hdPublicKey = new HDPublicKey(this); + this._hdPublicKey = null; - JSUtil.defineImmutable(this, { - hdPublicKey: hdPublicKey, - xpubkey: hdPublicKey.xpubkey + Object.defineProperty(this, 'hdPublicKey', { + configurable: false, + enumerable: true, + get: function() { + this._calcHDPublicKey(); + return this._hdPublicKey; + } + }); + Object.defineProperty(this, 'xpubkey', { + configurable: false, + enumerable: true, + get: function() { + this._calcHDPublicKey(); + return this._hdPublicKey.xpubkey; + } }); - return this; }; @@ -3472,9 +3899,9 @@ HDPrivateKey.prototype.inspect = function() { * * @return {Object} */ -HDPrivateKey.prototype.toObject = function toObject() { +HDPrivateKey.prototype.toObject = HDPrivateKey.prototype.toJSON = function toObject() { return { - network: Network.get(BufferUtil.integerFromBuffer(this._buffers.version)).name, + network: Network.get(BufferUtil.integerFromBuffer(this._buffers.version), 'xprivkey').name, depth: BufferUtil.integerFromSingleByteBuffer(this._buffers.depth), fingerPrint: BufferUtil.integerFromBuffer(this.fingerPrint), parentFingerPrint: BufferUtil.integerFromBuffer(this._buffers.parentFingerPrint), @@ -3486,15 +3913,6 @@ HDPrivateKey.prototype.toObject = function toObject() { }; }; -/** - * Returns a JSON representation of the HDPrivateKey - * - * @return {string} - */ -HDPrivateKey.prototype.toJSON = function toJSON() { - return JSON.stringify(this.toObject()); -}; - /** * Build a HDPrivateKey from a buffer * @@ -3533,31 +3951,33 @@ HDPrivateKey.CheckSumSize = 4; HDPrivateKey.DataLength = 78; HDPrivateKey.SerializedByteSize = 82; -HDPrivateKey.VersionStart = 0; -HDPrivateKey.VersionEnd = HDPrivateKey.VersionStart + HDPrivateKey.VersionSize; -HDPrivateKey.DepthStart = HDPrivateKey.VersionEnd; -HDPrivateKey.DepthEnd = HDPrivateKey.DepthStart + HDPrivateKey.DepthSize; +HDPrivateKey.VersionStart = 0; +HDPrivateKey.VersionEnd = HDPrivateKey.VersionStart + HDPrivateKey.VersionSize; +HDPrivateKey.DepthStart = HDPrivateKey.VersionEnd; +HDPrivateKey.DepthEnd = HDPrivateKey.DepthStart + HDPrivateKey.DepthSize; HDPrivateKey.ParentFingerPrintStart = HDPrivateKey.DepthEnd; -HDPrivateKey.ParentFingerPrintEnd = HDPrivateKey.ParentFingerPrintStart + HDPrivateKey.ParentFingerPrintSize; -HDPrivateKey.ChildIndexStart = HDPrivateKey.ParentFingerPrintEnd; -HDPrivateKey.ChildIndexEnd = HDPrivateKey.ChildIndexStart + HDPrivateKey.ChildIndexSize; -HDPrivateKey.ChainCodeStart = HDPrivateKey.ChildIndexEnd; -HDPrivateKey.ChainCodeEnd = HDPrivateKey.ChainCodeStart + HDPrivateKey.ChainCodeSize; -HDPrivateKey.PrivateKeyStart = HDPrivateKey.ChainCodeEnd + 1; -HDPrivateKey.PrivateKeyEnd = HDPrivateKey.PrivateKeyStart + HDPrivateKey.PrivateKeySize; -HDPrivateKey.ChecksumStart = HDPrivateKey.PrivateKeyEnd; -HDPrivateKey.ChecksumEnd = HDPrivateKey.ChecksumStart + HDPrivateKey.CheckSumSize; +HDPrivateKey.ParentFingerPrintEnd = HDPrivateKey.ParentFingerPrintStart + HDPrivateKey.ParentFingerPrintSize; +HDPrivateKey.ChildIndexStart = HDPrivateKey.ParentFingerPrintEnd; +HDPrivateKey.ChildIndexEnd = HDPrivateKey.ChildIndexStart + HDPrivateKey.ChildIndexSize; +HDPrivateKey.ChainCodeStart = HDPrivateKey.ChildIndexEnd; +HDPrivateKey.ChainCodeEnd = HDPrivateKey.ChainCodeStart + HDPrivateKey.ChainCodeSize; +HDPrivateKey.PrivateKeyStart = HDPrivateKey.ChainCodeEnd + 1; +HDPrivateKey.PrivateKeyEnd = HDPrivateKey.PrivateKeyStart + HDPrivateKey.PrivateKeySize; +HDPrivateKey.ChecksumStart = HDPrivateKey.PrivateKeyEnd; +HDPrivateKey.ChecksumEnd = HDPrivateKey.ChecksumStart + HDPrivateKey.CheckSumSize; assert(HDPrivateKey.ChecksumEnd === HDPrivateKey.SerializedByteSize); module.exports = HDPrivateKey; }).call(this,require("buffer").Buffer) -},{"./crypto/bn":4,"./crypto/hash":6,"./crypto/point":7,"./crypto/random":8,"./encoding/base58":10,"./encoding/base58check":11,"./errors":15,"./hdkeycache":17,"./hdpublickey":19,"./networks":20,"./privatekey":22,"./util/buffer":38,"./util/js":39,"assert":41,"buffer":42,"lodash":230}],19:[function(require,module,exports){ +},{"./crypto/bn":6,"./crypto/hash":8,"./crypto/point":9,"./crypto/random":10,"./encoding/base58":12,"./encoding/base58check":13,"./errors":17,"./hdkeycache":19,"./hdpublickey":21,"./networks":22,"./privatekey":24,"./util/buffer":42,"./util/js":43,"./util/preconditions":44,"assert":45,"buffer":47,"lodash":241}],21:[function(require,module,exports){ (function (Buffer){ 'use strict'; var _ = require('lodash'); +var $ = require('./util/preconditions'); + var BN = require('./crypto/bn'); var Base58 = require('./encoding/base58'); var Base58Check = require('./encoding/base58check'); @@ -3598,8 +4018,6 @@ function HDPublicKey(arg) { var error = HDPublicKey.getSerializedError(arg); if (!error) { return this._buildFromSerialized(arg); - } else if (JSUtil.isValidJSON(arg)) { - return this._buildFromJSON(arg); } else if (BufferUtil.isBuffer(arg) && !HDPublicKey.getSerializedError(arg.toString())) { return this._buildFromSerialized(arg.toString()); } else { @@ -3665,9 +4083,9 @@ HDPublicKey.isValidPath = function(arg) { * * @param {string|number} arg */ -HDPublicKey.prototype.derive = function (arg) { +HDPublicKey.prototype.derive = function(arg, hardened) { if (_.isNumber(arg)) { - return this._deriveWithNumber(arg); + return this._deriveWithNumber(arg, hardened); } else if (_.isString(arg)) { return this._deriveFromString(arg); } else { @@ -3675,8 +4093,8 @@ HDPublicKey.prototype.derive = function (arg) { } }; -HDPublicKey.prototype._deriveWithNumber = function (index) { - if (index >= HDPublicKey.Hardened) { +HDPublicKey.prototype._deriveWithNumber = function(index, hardened) { + if (index >= HDPublicKey.Hardened || hardened) { throw new hdErrors.InvalidIndexCantDeriveHardened(); } if (index < 0) { @@ -3707,7 +4125,7 @@ HDPublicKey.prototype._deriveWithNumber = function (index) { return derived; }; -HDPublicKey.prototype._deriveFromString = function (path) { +HDPublicKey.prototype._deriveFromString = function(path) { /* jshint maxcomplexity: 8 */ if (_.contains(path, "'")) { throw new hdErrors.InvalidIndexCantDeriveHardened(); @@ -3732,7 +4150,7 @@ HDPublicKey.prototype._deriveFromString = function (path) { * network provided matches the network serialized. * @return {boolean} */ -HDPublicKey.isValidSerialized = function (data, network) { +HDPublicKey.isValidSerialized = function(data, network) { return _.isNull(HDPublicKey.getSerializedError(data, network)); }; @@ -3745,7 +4163,7 @@ HDPublicKey.isValidSerialized = function (data, network) { * network provided matches the network serialized. * @return {errors|null} */ -HDPublicKey.getSerializedError = function (data, network) { +HDPublicKey.getSerializedError = function(data, network) { /* jshint maxcomplexity: 10 */ /* jshint maxstatements: 20 */ if (!(_.isString(data) || BufferUtil.isBuffer(data))) { @@ -3760,7 +4178,7 @@ HDPublicKey.getSerializedError = function (data, network) { return new errors.InvalidB58Checksum(data); } if (data.length !== HDPublicKey.DataSize) { - return new errors.InvalidLength(data); + return new hdErrors.InvalidLength(data); } if (!_.isUndefined(network)) { var error = HDPublicKey._validateNetwork(data, network); @@ -3775,7 +4193,7 @@ HDPublicKey.getSerializedError = function (data, network) { return null; }; -HDPublicKey._validateNetwork = function (data, networkArg) { +HDPublicKey._validateNetwork = function(data, networkArg) { var network = Network.get(networkArg); if (!network) { return new errors.InvalidNetworkArgument(networkArg); @@ -3787,10 +4205,6 @@ HDPublicKey._validateNetwork = function (data, networkArg) { return null; }; -HDPublicKey.prototype._buildFromJSON = function (arg) { - return this._buildFromObject(JSON.parse(arg)); -}; - HDPublicKey.prototype._buildFromPrivate = function (arg) { var args = _.clone(arg._buffers); var point = Point.getG().mul(BN.fromBuffer(args.privateKey)); @@ -3802,7 +4216,7 @@ HDPublicKey.prototype._buildFromPrivate = function (arg) { return this._buildFromBuffers(args); }; -HDPublicKey.prototype._buildFromObject = function (arg) { +HDPublicKey.prototype._buildFromObject = function(arg) { /* jshint maxcomplexity: 10 */ // TODO: Type validation var buffers = { @@ -3818,7 +4232,7 @@ HDPublicKey.prototype._buildFromObject = function (arg) { return this._buildFromBuffers(buffers); }; -HDPublicKey.prototype._buildFromSerialized = function (arg) { +HDPublicKey.prototype._buildFromSerialized = function(arg) { var decoded = Base58Check.decode(arg); var buffers = { version: decoded.slice(HDPublicKey.VersionStart, HDPublicKey.VersionEnd), @@ -3850,7 +4264,7 @@ HDPublicKey.prototype._buildFromSerialized = function (arg) { * representation * @return {HDPublicKey} this */ -HDPublicKey.prototype._buildFromBuffers = function (arg) { +HDPublicKey.prototype._buildFromBuffers = function(arg) { /* jshint maxcomplexity: 8 */ /* jshint maxstatements: 20 */ @@ -3873,18 +4287,19 @@ HDPublicKey.prototype._buildFromBuffers = function (arg) { throw new errors.InvalidB58Checksum(concat, checksum); } } + var network = Network.get(BufferUtil.integerFromBuffer(arg.version)); var xpubkey; xpubkey = Base58Check.encode(BufferUtil.concat(sequence)); arg.xpubkey = new Buffer(xpubkey); - var publicKey = PublicKey.fromString(arg.publicKey); + var publicKey = new PublicKey(arg.publicKey, {network: network}); var size = HDPublicKey.ParentFingerPrintSize; var fingerPrint = Hash.sha256ripemd160(publicKey.toBuffer()).slice(0, size); JSUtil.defineImmutable(this, { xpubkey: xpubkey, - network: Network.get(BufferUtil.integerFromBuffer(arg.version)), + network: network, depth: BufferUtil.integerFromSingleByteBuffer(arg.depth), publicKey: publicKey, fingerPrint: fingerPrint @@ -3893,7 +4308,7 @@ HDPublicKey.prototype._buildFromBuffers = function (arg) { return this; }; -HDPublicKey._validateBufferArguments = function (arg) { +HDPublicKey._validateBufferArguments = function(arg) { var checkBuffer = function(name, size) { var buff = arg[name]; assert(BufferUtil.isBuffer(buff), name + ' argument is not a buffer, it\'s ' + typeof buff); @@ -3913,7 +4328,13 @@ HDPublicKey._validateBufferArguments = function (arg) { } }; -HDPublicKey.fromString = HDPublicKey.fromObject = HDPublicKey.fromJSON = function(arg) { +HDPublicKey.fromString = function(arg) { + $.checkArgument(_.isString(arg), 'No valid string was provided'); + return new HDPublicKey(arg); +}; + +HDPublicKey.fromObject = function(arg) { + $.checkArgument(_.isObject(arg), 'No valid argument was provided'); return new HDPublicKey(arg); }; @@ -3921,7 +4342,7 @@ HDPublicKey.fromString = HDPublicKey.fromObject = HDPublicKey.fromJSON = functio * Returns the base58 checked representation of the public key * @return {string} a string starting with "xpub..." in livenet */ -HDPublicKey.prototype.toString = function () { +HDPublicKey.prototype.toString = function() { return this.xpubkey; }; @@ -3934,7 +4355,7 @@ HDPublicKey.prototype.inspect = function() { }; /** - * Returns a plain javascript object with information to reconstruct a key. + * Returns a plain JavaScript object with information to reconstruct a key. * * Fields are:
    *
  • network: 'livenet' or 'testnet' @@ -3950,7 +4371,7 @@ HDPublicKey.prototype.inspect = function() { *
  • checksum: the base58 checksum of xpubkey *
*/ -HDPublicKey.prototype.toObject = function toObject() { +HDPublicKey.prototype.toObject = HDPublicKey.prototype.toJSON = function toObject() { return { network: Network.get(BufferUtil.integerFromBuffer(this._buffers.version)).name, depth: BufferUtil.integerFromSingleByteBuffer(this._buffers.depth), @@ -3964,14 +4385,6 @@ HDPublicKey.prototype.toObject = function toObject() { }; }; -/** - * Serializes this object into a JSON string - * @return {string} - */ -HDPublicKey.prototype.toJSON = function toJSON() { - return JSON.stringify(this.toObject()); -}; - /** * Create a HDPublicKey from a buffer argument * @@ -4026,11 +4439,12 @@ assert(HDPublicKey.ChecksumEnd === HDPublicKey.SerializedByteSize); module.exports = HDPublicKey; }).call(this,require("buffer").Buffer) -},{"./crypto/bn":4,"./crypto/hash":6,"./crypto/point":7,"./encoding/base58":10,"./encoding/base58check":11,"./errors":15,"./hdkeycache":17,"./hdprivatekey":18,"./networks":20,"./publickey":23,"./util/buffer":38,"./util/js":39,"assert":41,"buffer":42,"lodash":230}],20:[function(require,module,exports){ +},{"./crypto/bn":6,"./crypto/hash":8,"./crypto/point":9,"./encoding/base58":12,"./encoding/base58check":13,"./errors":17,"./hdkeycache":19,"./hdprivatekey":20,"./networks":22,"./publickey":25,"./util/buffer":42,"./util/js":43,"./util/preconditions":44,"assert":45,"buffer":47,"lodash":241}],22:[function(require,module,exports){ 'use strict'; var _ = require('lodash'); var BufferUtil = require('./util/buffer'); +var JSUtil = require('./util/js'); var networks = []; var networkMaps = {}; @@ -4051,16 +4465,22 @@ Network.prototype.toString = function toString() { * @member Networks#get * Retrieves the network associated with a magic number or string. * @param {string|number|Network} arg - * @param {string} key - if set, only check if the magic number associated with this name matches + * @param {string|Array} keys - if set, only check if the magic number associated with this name matches * @return Network */ -function getNetwork(arg, key) { +function get(arg, keys) { if (~networks.indexOf(arg)) { return arg; } - if (key) { + if (keys) { + if (!_.isArray(keys)) { + keys = [keys]; + } + var containsArg = function(key) { + return networks[index][key] === arg; + }; for (var index in networks) { - if (networks[index][key] === arg) { + if (_.any(keys, containsArg)) { return networks[index]; } } @@ -4074,8 +4494,8 @@ function getNetwork(arg, key) { * @member Networks#add * Will add a custom Network * @param {Object} data - * @param {String} data.name - The name of the network - * @param {String} data.alias - The aliased name of the network + * @param {string} data.name - The name of the network + * @param {string} data.alias - The aliased name of the network * @param {Number} data.pubkeyhash - The publickey hash prefix * @param {Number} data.privatekey - The privatekey prefix * @param {Number} data.scripthash - The scripthash prefix @@ -4090,7 +4510,7 @@ function addNetwork(data) { var network = new Network(); - _.extend(network, { + JSUtil.defineImmutable(network, { name: data.name, alias: data.alias, pubkeyhash: data.pubkeyhash, @@ -4103,8 +4523,8 @@ function addNetwork(data) { dnsSeeds: data.dnsSeeds }); - _.each(_.values(network), function(value) { - if (!_.isObject(value)) { + _.each(network, function(value) { + if (!_.isUndefined(value) && !_.isObject(value)) { networkMaps[value] = network; } }); @@ -4115,13 +4535,32 @@ function addNetwork(data) { } +/** + * @function + * @member Networks#remove + * Will remove a custom network + * @param {Network} network + */ +function removeNetwork(network) { + for (var i = 0; i < networks.length; i++) { + if (networks[i] === network) { + networks.splice(i, 1); + } + } + for (var key in networkMaps) { + if (networkMaps[key] === network) { + delete networkMaps[key]; + } + } +} + addNetwork({ name: 'livenet', alias: 'mainnet', pubkeyhash: 0x00, privatekey: 0x80, scripthash: 0x05, - xpubkey: 0x0488b21e, + xpubkey: 0x0488b21e, xprivkey: 0x0488ade4, networkMagic: 0xf9beb4d9, port: 8333, @@ -4147,35 +4586,38 @@ addNetwork({ port: 18333, dnsSeeds: [ 'testnet-seed.bitcoin.petertodd.org', - 'testnet-seed.bluematt.me' + 'testnet-seed.bluematt.me', + 'testnet-seed.alexykot.me', + 'testnet-seed.bitcoin.schildbach.de' ], }); /** -* @instance -* @member Networks#livenet -*/ -var livenet = getNetwork('livenet'); + * @instance + * @member Networks#livenet + */ +var livenet = get('livenet'); /** -* @instance -* @member Networks#testnet -*/ -var testnet = getNetwork('testnet'); + * @instance + * @member Networks#testnet + */ +var testnet = get('testnet'); /** * @namespace Networks */ module.exports = { add: addNetwork, + remove: removeNetwork, defaultNetwork: livenet, livenet: livenet, mainnet: livenet, testnet: testnet, - get: getNetwork + get: get }; -},{"./util/buffer":38,"lodash":230}],21:[function(require,module,exports){ +},{"./util/buffer":42,"./util/js":43,"lodash":241}],23:[function(require,module,exports){ (function (Buffer){ 'use strict'; @@ -4374,6 +4816,8 @@ Opcode.map = { OP_CHECKMULTISIG: 174, OP_CHECKMULTISIGVERIFY: 175, + OP_CHECKLOCKTIMEVERIFY: 177, + // expansion OP_NOP1: 176, OP_NOP2: 177, @@ -4412,22 +4856,32 @@ Opcode.isSmallIntOp = function(opcode) { ((opcode >= Opcode.map.OP_1) && (opcode <= Opcode.map.OP_16))); }; +/** + * Will return a string formatted for the console + * + * @returns {string} Script opcode + */ +Opcode.prototype.inspect = function() { + return ''; +}; + module.exports = Opcode; }).call(this,require("buffer").Buffer) -},{"./util/buffer":38,"./util/js":39,"./util/preconditions":40,"buffer":42,"lodash":230}],22:[function(require,module,exports){ +},{"./util/buffer":42,"./util/js":43,"./util/preconditions":44,"buffer":47,"lodash":241}],24:[function(require,module,exports){ (function (Buffer){ 'use strict'; var _ = require('lodash'); var Address = require('./address'); -var base58check = require('./encoding/base58check'); +var Base58Check = require('./encoding/base58check'); var BN = require('./crypto/bn'); var JSUtil = require('./util/js'); var Networks = require('./networks'); var Point = require('./crypto/point'); var PublicKey = require('./publickey'); var Random = require('./crypto/random'); +var $ = require('./util/preconditions'); /** * Instantiate a PrivateKey from a BN, Buffer and WIF. @@ -4448,11 +4902,11 @@ var Random = require('./crypto/random'); * ``` * * @param {string} data - The encoded data in various formats - * @param {Network|string} [network] - a {@link Network} object, or a string with the network name + * @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 */ -var PrivateKey = function PrivateKey(data, network) { +function PrivateKey(data, network) { /* jshint maxstatements: 20 */ /* jshint maxcomplexity: 8 */ @@ -4497,7 +4951,7 @@ var PrivateKey = function PrivateKey(data, network) { * different kinds of arguments passed to the constructor. * * @param {*} data - * @param {Network|string} [network] - a {@link Network} object, or a string with the network name + * @param {Network|string=} network - a {@link Network} object, or a string with the network name * @return {Object} */ PrivateKey.prototype._classifyArguments = function(data, network) { @@ -4514,8 +4968,8 @@ PrivateKey.prototype._classifyArguments = function(data, network) { info.bn = data; } else if (data instanceof Buffer || data instanceof Uint8Array) { info = PrivateKey._transformBuffer(data, network); - } else if (PrivateKey._isJSON(data)){ - info = PrivateKey._transformJSON(data); + } else if (data.bn && data.network){ + info = PrivateKey._transformObject(data); } else if (!network && Networks.get(data)) { info.bn = PrivateKey._getRandomBN(); info.network = Networks.get(data); @@ -4548,22 +5002,11 @@ PrivateKey._getRandomBN = function(){ return bn; }; -/** - * Internal function to detect if a param is a JSON string or plain object - * - * @param {*} param - value to test - * @returns {boolean} - * @private - */ -PrivateKey._isJSON = function(json) { - return JSUtil.isValidJSON(json) || (json.bn && json.network); -}; - /** * Internal function to transform a WIF Buffer into a private key * * @param {Buffer} buf - An WIF string - * @param {Network|string} [network] - a {@link Network} object, or a string with the network name + * @param {Network|string=} network - a {@link Network} object, or a string with the network name * @returns {Object} An object with keys: bn, network and compressed * @private */ @@ -4576,11 +5019,8 @@ PrivateKey._transformBuffer = function(buf, network) { } info.network = Networks.get(buf[0], 'privatekey'); - if (buf[0] === Networks.livenet.privatekey) { - info.network = Networks.livenet; - } else if (buf[0] === Networks.testnet.privatekey) { - info.network = Networks.testnet; - } else { + + if (!info.network) { throw new Error('Invalid network'); } @@ -4605,7 +5045,7 @@ PrivateKey._transformBuffer = function(buf, network) { * Internal function to transform a BN buffer into a private key * * @param {Buffer} buf - * @param {Network|string} [network] - a {@link Network} object, or a string with the network name + * @param {Network|string=} network - a {@link Network} object, or a string with the network name * @returns {object} an Object with keys: bn, network, and compressed * @private */ @@ -4620,26 +5060,12 @@ PrivateKey._transformBNBuffer = function(buf, network) { /** * Internal function to transform a WIF string into a private key * - * @param {String} buf - An WIF string + * @param {string} buf - An WIF string * @returns {Object} An object with keys: bn, network and compressed * @private */ PrivateKey._transformWIF = function(str, network) { - return PrivateKey._transformBuffer(base58check.decode(str), network); -}; - -/** - * Instantiate a PrivateKey from a JSON string - * - * @param {String} json - The JSON encoded private key string - * @returns {PrivateKey} A new valid instance of PrivateKey - */ -PrivateKey.fromJSON = function(json) { - if (!PrivateKey._isJSON(json)) { - throw new TypeError('Must be a valid JSON string or plain object'); - } - - return new PrivateKey(json); + return PrivateKey._transformBuffer(Base58Check.decode(str), network); }; /** @@ -4657,18 +5083,16 @@ PrivateKey.fromBuffer = function(arg, network) { * Internal function to transform a JSON string on plain object into a private key * return this. * - * @param {String} json - A JSON string or plain object + * @param {string} json - A JSON string or plain object * @returns {Object} An object with keys: bn, network and compressed * @private */ -PrivateKey._transformJSON = function(json) { - if (JSUtil.isValidJSON(json)) { - json = JSON.parse(json); - } +PrivateKey._transformObject = function(json) { var bn = new BN(json.bn, 'hex'); + var network = Networks.get(json.network); return { bn: bn, - network: json.network, + network: network, compressed: json.compressed }; }; @@ -4676,17 +5100,28 @@ PrivateKey._transformJSON = function(json) { /** * Instantiate a PrivateKey from a WIF string * - * @param {String} str - The WIF encoded private key string + * @param {string} str - The WIF encoded private key string * @returns {PrivateKey} A new valid instance of PrivateKey */ PrivateKey.fromString = PrivateKey.fromWIF = function(str) { + $.checkArgument(_.isString(str), 'First argument is expected to be a string.'); return new PrivateKey(str); }; +/** + * Instantiate a PrivateKey from a plain JavaScript object + * + * @param {Object} obj - The output from privateKey.toObject() + */ +PrivateKey.fromObject = function(obj) { + $.checkArgument(_.isObject(obj), 'First argument is expected to be an object.'); + return new PrivateKey(obj); +}; + /** * Instantiate a PrivateKey from random bytes * - * @param {String} [network] - Either "livenet" or "testnet" + * @param {string=} network - Either "livenet" or "testnet" * @returns {PrivateKey} A new valid instance of PrivateKey */ PrivateKey.fromRandom = function(network) { @@ -4697,8 +5132,8 @@ PrivateKey.fromRandom = function(network) { /** * Check if there would be any errors when initializing a PrivateKey * - * @param {String} data - The encoded data in various formats - * @param {String} [network] - Either "livenet" or "testnet" + * @param {string} data - The encoded data in various formats + * @param {string=} network - Either "livenet" or "testnet" * @returns {null|Error} An error if exists */ @@ -4716,18 +5151,21 @@ PrivateKey.getValidationError = function(data, network) { /** * Check if the parameters are valid * - * @param {String} data - The encoded data in various formats - * @param {String} [network] - Either "livenet" or "testnet" + * @param {string} data - The encoded data in various formats + * @param {string=} network - Either "livenet" or "testnet" * @returns {Boolean} If the private key is would be valid */ PrivateKey.isValid = function(data, network){ + if (!data) { + return false; + } return !PrivateKey.getValidationError(data, network); }; /** * Will output the PrivateKey encoded as hex string * - * @returns {String} + * @returns {string} */ PrivateKey.prototype.toString = function() { return this.toBuffer().toString('hex'); @@ -4736,7 +5174,7 @@ PrivateKey.prototype.toString = function() { /** * Will output the PrivateKey to a WIF string * - * @returns {String} A WIP representation of the private key + * @returns {string} A WIP representation of the private key */ PrivateKey.prototype.toWIF = function() { var network = this.network; @@ -4752,7 +5190,7 @@ PrivateKey.prototype.toWIF = function() { this.bn.toBuffer({size: 32})]); } - return base58check.encode(buf); + return Base58Check.encode(buf); }; /** @@ -4787,18 +5225,20 @@ PrivateKey.prototype.toPublicKey = function(){ /** * Will return an address for the private key + * @param {Network=} network - optional parameter specifying + * the desired network for the address * * @returns {Address} An address generated from the private key */ -PrivateKey.prototype.toAddress = function() { +PrivateKey.prototype.toAddress = function(network) { var pubkey = this.toPublicKey(); - return Address.fromPublicKey(pubkey, this.network); + return Address.fromPublicKey(pubkey, network || this.network); }; /** * @returns {Object} A plain object representation */ -PrivateKey.prototype.toObject = function toObject() { +PrivateKey.prototype.toObject = PrivateKey.prototype.toJSON = function toObject() { return { bn: this.bn.toString('hex'), compressed: this.compressed, @@ -4806,14 +5246,10 @@ PrivateKey.prototype.toObject = function toObject() { }; }; -PrivateKey.prototype.toJSON = function toJSON() { - return JSON.stringify(this.toObject()); -}; - /** * Will return a string formatted for the console * - * @returns {String} Private key + * @returns {string} Private key */ PrivateKey.prototype.inspect = function() { var uncompressed = !this.compressed ? ', uncompressed' : ''; @@ -4823,11 +5259,10 @@ PrivateKey.prototype.inspect = function() { module.exports = PrivateKey; }).call(this,require("buffer").Buffer) -},{"./address":1,"./crypto/bn":4,"./crypto/point":7,"./crypto/random":8,"./encoding/base58check":11,"./networks":20,"./publickey":23,"./util/js":39,"buffer":42,"lodash":230}],23:[function(require,module,exports){ +},{"./address":1,"./crypto/bn":6,"./crypto/point":9,"./crypto/random":10,"./encoding/base58check":13,"./networks":22,"./publickey":25,"./util/js":43,"./util/preconditions":44,"buffer":47,"lodash":241}],25:[function(require,module,exports){ (function (Buffer){ 'use strict'; -var Address = require('./address'); var BN = require('./crypto/bn'); var Point = require('./crypto/point'); var Hash = require('./crypto/hash'); @@ -4854,20 +5289,20 @@ var $ = require('./util/preconditions'); * var imported = PublicKey.fromString(exported); * ``` * - * @param {String} data - The encoded data in various formats + * @param {string} data - The encoded data in various formats * @param {Object} extra - additional options * @param {Network=} extra.network - Which network should the address for this public key be for * @param {String=} extra.compressed - If the public key is compressed * @returns {PublicKey} A new valid instance of an PublicKey * @constructor */ -var PublicKey = function PublicKey(data, extra) { +function PublicKey(data, extra) { if (!(this instanceof PublicKey)) { return new PublicKey(data, extra); } - $.checkArgument(data, new TypeError('First argument is required, please include public key data.')); + $.checkArgument(data, 'First argument is required, please include public key data.'); if (data instanceof PublicKey) { // Return copy, but as it's an immutable object, return same argument @@ -4897,15 +5332,14 @@ var PublicKey = function PublicKey(data, extra) { PublicKey.prototype._classifyArgs = function(data, extra) { /* jshint maxcomplexity: 10 */ var info = { - compressed: _.isUndefined(extra.compressed) || extra.compressed, - network: _.isUndefined(extra.network) ? undefined : Network.get(extra.network) + compressed: _.isUndefined(extra.compressed) || extra.compressed }; // detect type of data if (data instanceof Point) { info.point = data; - } else if (PublicKey._isJSON(data)) { - info = PublicKey._transformJSON(data); + } else if (data.x && data.y) { + info = PublicKey._transformObject(data); } else if (typeof(data) === 'string') { info = PublicKey._transformDER(new Buffer(data, 'hex')); } else if (PublicKey._isBuffer(data)) { @@ -4915,6 +5349,9 @@ PublicKey.prototype._classifyArgs = function(data, extra) { } else { throw new TypeError('First argument is an unrecognized data format.'); } + if (!info.network) { + info.network = _.isUndefined(extra.network) ? undefined : Network.get(extra.network); + } return info; }; @@ -4941,17 +5378,6 @@ PublicKey._isBuffer = function(param) { return (param instanceof Buffer) || (param instanceof Uint8Array); }; -/** - * Internal function to detect if a param is a JSON string or plain object - * - * @param {*} param - value to test - * @returns {boolean} - * @private - */ -PublicKey._isJSON = function(json) { - return !!(JSUtil.isValidJSON(json) || (json.x && json.y)); -}; - /** * Internal function to transform a private key into a public key point * @@ -4960,8 +5386,7 @@ PublicKey._isJSON = function(json) { * @private */ PublicKey._transformPrivateKey = function(privkey) { - $.checkArgument(PublicKey._isPrivateKey(privkey), - new TypeError('Must be an instance of PrivateKey')); + $.checkArgument(PublicKey._isPrivateKey(privkey), 'Must be an instance of PrivateKey'); var info = {}; info.point = Point.getG().mul(privkey.bn); info.compressed = privkey.compressed; @@ -4973,14 +5398,14 @@ PublicKey._transformPrivateKey = function(privkey) { * Internal function to transform DER into a public key point * * @param {Buffer} buf - An hex encoded buffer - * @param {bool} [strict] - if set to false, will loosen some conditions + * @param {bool=} strict - if set to false, will loosen some conditions * @returns {Object} An object with keys: point and compressed * @private */ PublicKey._transformDER = function(buf, strict) { /* jshint maxstatements: 30 */ /* jshint maxcomplexity: 12 */ - $.checkArgument(PublicKey._isBuffer(buf), new TypeError('Must be a hex buffer of DER encoded public key')); + $.checkArgument(PublicKey._isBuffer(buf), 'Must be a hex buffer of DER encoded public key'); var info = {}; strict = _.isUndefined(strict) ? true : strict; @@ -5025,36 +5450,20 @@ PublicKey._transformDER = function(buf, strict) { * @private */ PublicKey._transformX = function(odd, x) { - $.checkArgument(typeof odd === 'boolean', - new TypeError('Must specify whether y is odd or not (true or false)')); + $.checkArgument(typeof odd === 'boolean', 'Must specify whether y is odd or not (true or false)'); var info = {}; info.point = Point.fromX(odd, x); return info; }; -/** - * Instantiate a PublicKey from JSON - * - * @param {String} json - A JSON string - * @returns {PublicKey} A new valid instance of PublicKey - */ -PublicKey.fromJSON = function(json) { - $.checkArgument(PublicKey._isJSON(json), - new TypeError('Must be a valid JSON string or plain object')); - return new PublicKey(json); -}; - /** * Internal function to transform a JSON into a public key point * - * @param {Buffer} buf - a JSON string or plain object + * @param {String|Object} json - a JSON string or plain object * @returns {Object} An object with keys: point and compressed * @private */ -PublicKey._transformJSON = function(json) { - if (JSUtil.isValidJSON(json)) { - json = JSON.parse(json); - } +PublicKey._transformObject = function(json) { var x = new BN(json.x, 'hex'); var y = new BN(json.y, 'hex'); var point = new Point(x, y); @@ -5070,7 +5479,7 @@ PublicKey._transformJSON = function(json) { * @returns {PublicKey} A new valid instance of PublicKey */ PublicKey.fromPrivateKey = function(privkey) { - $.checkArgument(PublicKey._isPrivateKey(privkey), new TypeError('Must be an instance of PrivateKey')); + $.checkArgument(PublicKey._isPrivateKey(privkey), 'Must be an instance of PrivateKey'); var info = PublicKey._transformPrivateKey(privkey); return new PublicKey(info.point, { compressed: info.compressed, @@ -5081,12 +5490,11 @@ PublicKey.fromPrivateKey = function(privkey) { /** * Instantiate a PublicKey from a Buffer * @param {Buffer} buf - A DER hex buffer - * @param {bool} [strict] - if set to false, will loosen some conditions + * @param {bool=} strict - if set to false, will loosen some conditions * @returns {PublicKey} A new valid instance of PublicKey */ PublicKey.fromDER = PublicKey.fromBuffer = function(buf, strict) { - $.checkArgument(PublicKey._isBuffer(buf), - new TypeError('Must be a hex buffer of DER encoded public key')); + $.checkArgument(PublicKey._isBuffer(buf), 'Must be a hex buffer of DER encoded public key'); var info = PublicKey._transformDER(buf, strict); return new PublicKey(info.point, { compressed: info.compressed @@ -5101,8 +5509,7 @@ PublicKey.fromDER = PublicKey.fromBuffer = function(buf, strict) { * @returns {PublicKey} A new valid instance of PublicKey */ PublicKey.fromPoint = function(point, compressed) { - $.checkArgument(point instanceof Point, - new TypeError('First argument must be an instance of Point.')); + $.checkArgument(point instanceof Point, 'First argument must be an instance of Point.'); return new PublicKey(point, { compressed: compressed }); @@ -5111,8 +5518,8 @@ PublicKey.fromPoint = function(point, compressed) { /** * Instantiate a PublicKey from a DER hex encoded string * - * @param {String} str - A DER hex string - * @param {String} [encoding] - The type of string encoding + * @param {string} str - A DER hex string + * @param {String=} encoding - The type of string encoding * @returns {PublicKey} A new valid instance of PublicKey */ PublicKey.fromString = function(str, encoding) { @@ -5140,8 +5547,7 @@ PublicKey.fromX = function(odd, x) { /** * Check if there would be any errors when initializing a PublicKey * - * @param {String} data - The encoded data in various formats - * @param {String} [compressed] - If the public key is compressed + * @param {string} data - The encoded data in various formats * @returns {null|Error} An error if exists */ PublicKey.getValidationError = function(data) { @@ -5158,8 +5564,7 @@ PublicKey.getValidationError = function(data) { /** * Check if the parameters are valid * - * @param {String} data - The encoded data in various formats - * @param {String} [compressed] - If the public key is compressed + * @param {string} data - The encoded data in various formats * @returns {Boolean} If the public key would be valid */ PublicKey.isValid = function(data) { @@ -5169,18 +5574,14 @@ PublicKey.isValid = function(data) { /** * @returns {Object} A plain object of the PublicKey */ -PublicKey.prototype.toObject = function toObject() { +PublicKey.prototype.toObject = PublicKey.prototype.toJSON = function toObject() { return { - x: this.point.getX().toString('hex'), - y: this.point.getY().toString('hex'), + x: this.point.getX().toString('hex', 2), + y: this.point.getY().toString('hex', 2), compressed: this.compressed }; }; -PublicKey.prototype.toJSON = function toJSON() { - return JSON.stringify(this.toObject()); -}; - /** * Will output the PublicKey to a DER Buffer * @@ -5224,16 +5625,18 @@ PublicKey.prototype._getID = function _getID() { /** * Will return an address for the public key * + * @param {String|Network=} network - Which network should the address be for * @returns {Address} An address generated from the public key */ PublicKey.prototype.toAddress = function(network) { + var Address = require('./address'); return Address.fromPublicKey(this, network || this.network); }; /** * Will output the PublicKey to a DER encoded hex string * - * @returns {String} A DER hex encoded string + * @returns {string} A DER hex encoded string */ PublicKey.prototype.toString = function() { return this.toDER().toString('hex'); @@ -5242,7 +5645,7 @@ PublicKey.prototype.toString = function() { /** * Will return a string formatted for the console * - * @returns {String} Public key + * @returns {string} Public key */ PublicKey.prototype.inspect = function() { return '= Interpreter.LOCKTIME_THRESHOLD && nLockTime.gte(Interpreter.LOCKTIME_THRESHOLD_BN)) + )) { + return false; + } + + // Now that we know we're comparing apples-to-apples, the + // comparison is a simple numeric one. + if (nLockTime.gt(new BN(this.tx.nLockTime))) { + return false; + } + + // Finally the nLockTime feature can be disabled and thus + // CHECKLOCKTIMEVERIFY bypassed if every txin has been + // finalized by setting nSequence to maxint. The + // transaction would be allowed into the blockchain, making + // the opcode ineffective. + // + // Testing if this vin is not final is sufficient to + // prevent this condition. Alternatively we could test all + // inputs, but testing just this input minimizes the data + // required to prove correct CHECKLOCKTIMEVERIFY execution. + if (!this.tx.inputs[this.nin].isFinal()) { + return false; + } + + return true; +} + /** * Based on the inner loop of bitcoind's EvalScript function * bitcoind commit: b5d1b1092998bc95313856d535c632ea5a8f9104 @@ -5676,8 +6132,55 @@ Interpreter.prototype.step = function() { case Opcode.OP_NOP: break; - case Opcode.OP_NOP1: case Opcode.OP_NOP2: + case Opcode.OP_CHECKLOCKTIMEVERIFY: + + if (!(this.flags & Interpreter.SCRIPT_VERIFY_CHECKLOCKTIMEVERIFY)) { + // not enabled; treat as a NOP2 + if (this.flags & Interpreter.SCRIPT_VERIFY_DISCOURAGE_UPGRADABLE_NOPS) { + this.errstr = 'SCRIPT_ERR_DISCOURAGE_UPGRADABLE_NOPS'; + return false; + } + break; + } + + if (this.stack.length < 1) { + this.errstr = 'SCRIPT_ERR_INVALID_STACK_OPERATION'; + return false; + } + + // Note that elsewhere numeric opcodes are limited to + // operands in the range -2**31+1 to 2**31-1, however it is + // legal for opcodes to produce results exceeding that + // range. This limitation is implemented by CScriptNum's + // default 4-byte limit. + // + // If we kept to that limit we'd have a year 2038 problem, + // even though the nLockTime field in transactions + // themselves is uint32 which only becomes meaningless + // after the year 2106. + // + // Thus as a special case we tell CScriptNum to accept up + // to 5-byte bignums, which are good until 2**39-1, well + // beyond the 2**32-1 limit of the nLockTime field itself. + var nLockTime = BN.fromScriptNumBuffer(this.stack[this.stack.length - 1], fRequireMinimal, 5); + + // In the rare event that the argument may be < 0 due to + // some arithmetic being done first, you can always use + // 0 MAX CHECKLOCKTIMEVERIFY. + if (nLockTime.lt(new BN(0))) { + this.errstr = 'SCRIPT_ERR_NEGATIVE_LOCKTIME'; + return false; + } + + // Actually compare the specified lock time with the transaction. + if (!this.checkLockTime(nLockTime)) { + this.errstr = 'SCRIPT_ERR_UNSATISFIED_LOCKTIME'; + return false; + } + break; + + case Opcode.OP_NOP1: case Opcode.OP_NOP3: case Opcode.OP_NOP4: case Opcode.OP_NOP5: @@ -6427,11 +6930,10 @@ Interpreter.prototype.step = function() { }).call(this,require("buffer").Buffer) -},{"../crypto/bn":4,"../crypto/hash":6,"../crypto/signature":9,"../opcode":21,"../publickey":23,"../transaction":27,"./script":26,"buffer":42,"lodash":230}],26:[function(require,module,exports){ +},{"../crypto/bn":6,"../crypto/hash":8,"../crypto/signature":11,"../opcode":23,"../publickey":25,"../transaction":29,"./script":28,"buffer":47,"lodash":241}],28:[function(require,module,exports){ (function (Buffer){ 'use strict'; - var Address = require('../address'); var BufferReader = require('../encoding/bufferreader'); var BufferWriter = require('../encoding/bufferwriter'); @@ -6440,7 +6942,6 @@ var Opcode = require('../opcode'); var PublicKey = require('../publickey'); var Signature = require('../crypto/signature'); var Networks = require('../networks'); - var $ = require('../util/preconditions'); var _ = require('lodash'); var errors = require('../errors'); @@ -6455,13 +6956,12 @@ var JSUtil = require('../util/js'); * See https://en.bitcoin.it/wiki/Script * * @constructor - * @param {Object|string|Buffer} [from] optional data to populate script + * @param {Object|string|Buffer=} from optional data to populate script */ var Script = function Script(from) { if (!(this instanceof Script)) { return new Script(from); } - this.chunks = []; if (BufferUtil.isBuffer(from)) { @@ -6488,44 +6988,51 @@ Script.fromBuffer = function(buffer) { var br = new BufferReader(buffer); while (!br.finished()) { - var opcodenum = br.readUInt8(); + try { + var opcodenum = br.readUInt8(); - var len, buf; - if (opcodenum > 0 && opcodenum < Opcode.OP_PUSHDATA1) { - len = opcodenum; - script.chunks.push({ - buf: br.read(len), - len: len, - opcodenum: opcodenum - }); - } else if (opcodenum === Opcode.OP_PUSHDATA1) { - len = br.readUInt8(); - buf = br.read(len); - script.chunks.push({ - buf: buf, - len: len, - opcodenum: opcodenum - }); - } else if (opcodenum === Opcode.OP_PUSHDATA2) { - len = br.readUInt16LE(); - buf = br.read(len); - script.chunks.push({ - buf: buf, - len: len, - opcodenum: opcodenum - }); - } else if (opcodenum === Opcode.OP_PUSHDATA4) { - len = br.readUInt32LE(); - buf = br.read(len); - script.chunks.push({ - buf: buf, - len: len, - opcodenum: opcodenum - }); - } else { - script.chunks.push({ - opcodenum: opcodenum - }); + var len, buf; + if (opcodenum > 0 && opcodenum < Opcode.OP_PUSHDATA1) { + len = opcodenum; + script.chunks.push({ + buf: br.read(len), + len: len, + opcodenum: opcodenum + }); + } else if (opcodenum === Opcode.OP_PUSHDATA1) { + len = br.readUInt8(); + buf = br.read(len); + script.chunks.push({ + buf: buf, + len: len, + opcodenum: opcodenum + }); + } else if (opcodenum === Opcode.OP_PUSHDATA2) { + len = br.readUInt16LE(); + buf = br.read(len); + script.chunks.push({ + buf: buf, + len: len, + opcodenum: opcodenum + }); + } else if (opcodenum === Opcode.OP_PUSHDATA4) { + len = br.readUInt32LE(); + buf = br.read(len); + script.chunks.push({ + buf: buf, + len: len, + opcodenum: opcodenum + }); + } else { + script.chunks.push({ + opcodenum: opcodenum + }); + } + } catch (e) { + if (e instanceof RangeError) { + throw new errors.Script.InvalidBuffer(buffer.toString('hex')); + } + throw e; } } @@ -6558,6 +7065,48 @@ Script.prototype.toBuffer = function() { return bw.concat(); }; +Script.fromASM = function(str) { + var script = new Script(); + script.chunks = []; + + var tokens = str.split(' '); + var i = 0; + while (i < tokens.length) { + var token = tokens[i]; + var opcode = Opcode(token); + var opcodenum = opcode.toNumber(); + + if (_.isUndefined(opcodenum)) { + var buf = new Buffer(tokens[i], 'hex'); + script.chunks.push({ + buf: buf, + len: buf.length, + opcodenum: buf.length + }); + i = i + 1; + } else if (opcodenum === Opcode.OP_PUSHDATA1 || + opcodenum === Opcode.OP_PUSHDATA2 || + opcodenum === Opcode.OP_PUSHDATA4) { + script.chunks.push({ + buf: new Buffer(tokens[i + 2], 'hex'), + len: parseInt(tokens[i + 1]), + opcodenum: opcodenum + }); + i = i + 3; + } else { + script.chunks.push({ + opcodenum: opcodenum + }); + i = i + 1; + } + } + return script; +}; + +Script.fromHex = function(str) { + return new Script(new buffer.Buffer(str, 'hex')); +}; + Script.fromString = function(str) { if (JSUtil.isHexa(str) || str.length === 0) { return new Script(new buffer.Buffer(str, 'hex')); @@ -6606,33 +7155,59 @@ Script.fromString = function(str) { return script; }; -Script.prototype.toString = function() { +Script.prototype._chunkToString = function(chunk, type) { + var opcodenum = chunk.opcodenum; + var asm = (type === 'asm'); var str = ''; - for (var i = 0; i < this.chunks.length; i++) { - var chunk = this.chunks[i]; - var opcodenum = chunk.opcodenum; - if (!chunk.buf) { - if (typeof Opcode.reverseMap[opcodenum] !== 'undefined') { - str = str + ' ' + Opcode(opcodenum).toString(); + if (!chunk.buf) { + // no data chunk + if (typeof Opcode.reverseMap[opcodenum] !== 'undefined') { + str = str + ' ' + Opcode(opcodenum).toString(); + } else { + var numstr = opcodenum.toString(16); + if (numstr.length % 2 !== 0) { + numstr = '0' + numstr; + } + if (asm) { + str = str + ' ' + numstr; } else { - var numstr = opcodenum.toString(16); - if (numstr.length % 2 !== 0) { - numstr = '0' + numstr; - } str = str + ' ' + '0x' + numstr; } - } else { - if (opcodenum === Opcode.OP_PUSHDATA1 || - opcodenum === Opcode.OP_PUSHDATA2 || - opcodenum === Opcode.OP_PUSHDATA4) { - str = str + ' ' + Opcode(opcodenum).toString(); - } - str = str + ' ' + chunk.len; - if (chunk.len > 0) { - str = str + ' ' + '0x' + chunk.buf.toString('hex'); + } + } else { + // data chunk + if (opcodenum === Opcode.OP_PUSHDATA1 || + opcodenum === Opcode.OP_PUSHDATA2 || + opcodenum === Opcode.OP_PUSHDATA4) { + str = str + ' ' + Opcode(opcodenum).toString(); + } + if (chunk.len > 0) { + if (asm) { + str = str + ' ' + chunk.buf.toString('hex'); + } else { + str = str + ' ' + chunk.len + ' ' + '0x' + chunk.buf.toString('hex'); } } } + return str; +}; + +Script.prototype.toASM = function() { + var str = ''; + for (var i = 0; i < this.chunks.length; i++) { + var chunk = this.chunks[i]; + str += this._chunkToString(chunk, 'asm'); + } + + return str.substr(1); +}; + +Script.prototype.toString = function() { + var str = ''; + for (var i = 0; i < this.chunks.length; i++) { + var chunk = this.chunks[i]; + str += this._chunkToString(chunk); + } return str.substr(1); }; @@ -6655,6 +7230,7 @@ Script.prototype.isPublicKeyHashOut = function() { this.chunks[0].opcodenum === Opcode.OP_DUP && this.chunks[1].opcodenum === Opcode.OP_HASH160 && this.chunks[2].buf && + this.chunks[2].buf.length === 20 && this.chunks[3].opcodenum === Opcode.OP_EQUALVERIFY && this.chunks[4].opcodenum === Opcode.OP_CHECKSIG); }; @@ -6663,11 +7239,31 @@ Script.prototype.isPublicKeyHashOut = function() { * @returns {boolean} if this is a pay to public key hash input script */ Script.prototype.isPublicKeyHashIn = function() { - return this.chunks.length === 2 && - this.chunks[0].buf && - this.chunks[0].buf.length >= 0x47 && - this.chunks[0].buf.length <= 0x49 && - PublicKey.isValid(this.chunks[1].buf); + if (this.chunks.length === 2) { + var signatureBuf = this.chunks[0].buf; + var pubkeyBuf = this.chunks[1].buf; + if (signatureBuf && + signatureBuf.length && + signatureBuf[0] === 0x30 && + pubkeyBuf && + pubkeyBuf.length + ) { + var version = pubkeyBuf[0]; + if ((version === 0x04 || + version === 0x06 || + version === 0x07) && pubkeyBuf.length === 65) { + return true; + } else if ((version === 0x03 || version === 0x02) && pubkeyBuf.length === 33) { + return true; + } + } + } + return false; +}; + +Script.prototype.getPublicKey = function() { + $.checkState(this.isPublicKeyOut(), 'Can\'t retreive PublicKey from a non-PK output'); + return this.chunks[0].buf; }; Script.prototype.getPublicKeyHash = function() { @@ -6679,22 +7275,42 @@ Script.prototype.getPublicKeyHash = function() { * @returns {boolean} if this is a public key output script */ Script.prototype.isPublicKeyOut = function() { - return this.chunks.length === 2 && - BufferUtil.isBuffer(this.chunks[0].buf) && - PublicKey.isValid(this.chunks[0].buf) && - this.chunks[1].opcodenum === Opcode.OP_CHECKSIG; + if (this.chunks.length === 2 && + this.chunks[0].buf && + this.chunks[0].buf.length && + this.chunks[1].opcodenum === Opcode.OP_CHECKSIG) { + var pubkeyBuf = this.chunks[0].buf; + var version = pubkeyBuf[0]; + var isVersion = false; + if ((version === 0x04 || + version === 0x06 || + version === 0x07) && pubkeyBuf.length === 65) { + isVersion = true; + } else if ((version === 0x03 || version === 0x02) && pubkeyBuf.length === 33) { + isVersion = true; + } + if (isVersion) { + return PublicKey.isValid(pubkeyBuf); + } + } + return false; }; /** * @returns {boolean} if this is a pay to public key input script */ Script.prototype.isPublicKeyIn = function() { - return this.chunks.length === 1 && - BufferUtil.isBuffer(this.chunks[0].buf) && - this.chunks[0].buf.length === 0x47; + if (this.chunks.length === 1) { + var signatureBuf = this.chunks[0].buf; + if (signatureBuf && + signatureBuf.length && + signatureBuf[0] === 0x30) { + return true; + } + } + return false; }; - /** * @returns {boolean} if this is a p2sh output script */ @@ -6711,18 +7327,24 @@ Script.prototype.isScriptHashOut = function() { * Note that these are frequently indistinguishable from pubkeyhashin */ Script.prototype.isScriptHashIn = function() { - if (this.chunks.length === 0) { + if (this.chunks.length <= 1) { return false; } - var chunk = this.chunks[this.chunks.length - 1]; - if (!chunk) { + var redeemChunk = this.chunks[this.chunks.length - 1]; + var redeemBuf = redeemChunk.buf; + if (!redeemBuf) { return false; } - var scriptBuf = chunk.buf; - if (!scriptBuf) { - return false; + + var redeemScript; + try { + redeemScript = Script.fromBuffer(redeemBuf); + } catch (e) { + if (e instanceof errors.Script.InvalidBuffer) { + return false; + } + throw e; } - var redeemScript = new Script(scriptBuf); var type = redeemScript.classify(); return type !== Script.types.UNKNOWN; }; @@ -6755,7 +7377,7 @@ Script.prototype.isMultisigIn = function() { }; /** - * @returns {boolean} if this is an OP_RETURN data script + * @returns {boolean} true if this is a valid standard OP_RETURN output */ Script.prototype.isDataOut = function() { return this.chunks.length >= 1 && @@ -6763,7 +7385,7 @@ Script.prototype.isDataOut = function() { (this.chunks.length === 1 || (this.chunks.length === 2 && this.chunks[1].buf && - this.chunks[1].buf.length <= 40 && + this.chunks[1].buf.length <= Script.OP_RETURN_STANDARD_SIZE && this.chunks[1].length === this.chunks.len)); }; @@ -6775,7 +7397,11 @@ Script.prototype.isDataOut = function() { */ Script.prototype.getData = function() { if (this.isDataOut() || this.isScriptHashOut()) { - return new Buffer(this.chunks[1].buf); + if (_.isUndefined(this.chunks[1])) { + return new Buffer(0); + } else { + return new Buffer(this.chunks[1].buf); + } } if (this.isPublicKeyHashOut()) { return new Buffer(this.chunks[2].buf); @@ -6806,6 +7432,8 @@ Script.types.MULTISIG_OUT = 'Pay to multisig'; Script.types.MULTISIG_IN = 'Spend from multisig'; Script.types.DATA_OUT = 'Data push'; +Script.OP_RETURN_STANDARD_SIZE = 80; + Script.identifiers = {}; Script.identifiers.PUBKEY_OUT = Script.prototype.isPublicKeyOut; Script.identifiers.PUBKEY_IN = Script.prototype.isPublicKeyIn; @@ -6862,14 +7490,12 @@ Script.prototype.equals = function(script) { } var i; for (i = 0; i < this.chunks.length; i++) { - if (BufferUtil.isBuffer(this.chunks[i]) && !BufferUtil.isBuffer(script.chunks[i])) { - return false; - } else if (this.chunks[i] instanceof Opcode && !(script.chunks[i] instanceof Opcode)) { + if (BufferUtil.isBuffer(this.chunks[i].buf) && !BufferUtil.isBuffer(script.chunks[i].buf)) { return false; } - if (BufferUtil.isBuffer(this.chunks[i]) && !BufferUtil.equals(this.chunks[i], script.chunks[i])) { + if (BufferUtil.isBuffer(this.chunks[i].buf) && !BufferUtil.equals(this.chunks[i].buf, script.chunks[i].buf)) { return false; - } else if (this.chunks[i].num !== script.chunks[i].num) { + } else if (this.chunks[i].opcodenum !== script.chunks[i].opcodenum) { return false; } } @@ -6897,10 +7523,10 @@ Script.prototype._addByType = function(obj, prepend) { this._addOpcode(obj, prepend); } else if (BufferUtil.isBuffer(obj)) { this._addBuffer(obj, prepend); - } else if (typeof obj === 'object') { - this._insertAtPosition(obj, prepend); } else if (obj instanceof Script) { this.chunks = this.chunks.concat(obj.chunks); + } else if (typeof obj === 'object') { + this._insertAtPosition(obj, prepend); } else { throw new Error('Invalid script chunk'); } @@ -6969,11 +7595,13 @@ Script.prototype.removeCodeseparators = function() { * requiring m of those public keys to spend * @param {PublicKey[]} publicKeys - list of all public keys controlling the output * @param {number} threshold - amount of required signatures to spend the output - * @param {Object} [opts] - Several options: + * @param {Object=} opts - Several options: * - noSorting: defaults to false, if true, don't sort the given * public keys before creating the script */ Script.buildMultisigOut = function(publicKeys, threshold, opts) { + $.checkArgument(threshold <= publicKeys.length, + 'Number of required signatures must be less than or equal to the number of public keys'); opts = opts || {}; var script = new Script(); script.add(Opcode.smallInt(threshold)); @@ -6998,7 +7626,7 @@ Script.buildMultisigOut = function(publicKeys, threshold, opts) { * * @param {PublicKey[]} pubkeys list of all public keys controlling the output * @param {number} threshold amount of required signatures to spend the output - * @param {Array} signatures signatures to append to the script + * @param {Array} signatures and array of signature buffers to append to the script * @param {Object=} opts * @param {boolean=} opts.noSorting don't sort the given public keys before creating the script (false by default) * @param {Script=} opts.cachedMultisig don't recalculate the redeemScript @@ -7013,6 +7641,8 @@ Script.buildP2SHMultisigIn = function(pubkeys, threshold, signatures, opts) { var s = new Script(); s.add(Opcode.OP_0); _.each(signatures, function(signature) { + $.checkArgument(BufferUtil.isBuffer(signature), 'Signatures must be an array of Buffers'); + // TODO: allow signatures to be an array of Signature objects s.add(signature); }); s.add((opts.cachedMultisig || Script.buildMultisigOut(pubkeys, threshold, opts)).toBuffer()); @@ -7056,12 +7686,13 @@ Script.buildPublicKeyOut = function(pubkey) { /** * @returns {Script} a new OP_RETURN script with data - * @param {(string|Buffer)} to - the data to embed in the output + * @param {(string|Buffer)} data - the data to embed in the output + * @param {(string)} encoding - the type of encoding of the string */ -Script.buildDataOut = function(data) { +Script.buildDataOut = function(data, encoding) { $.checkArgument(_.isUndefined(data) || _.isString(data) || BufferUtil.isBuffer(data)); - if (typeof data === 'string') { - data = new Buffer(data); + if (_.isString(data)) { + data = new Buffer(data, encoding); } var s = new Script(); s.add(Opcode.OP_RETURN); @@ -7084,10 +7715,30 @@ Script.buildScriptHashOut = function(script) { .add(script instanceof Address ? script.hashBuffer : Hash.sha256ripemd160(script.toBuffer())) .add(Opcode.OP_EQUAL); - s._network = script._network || script.network; + s._network = script._network || script.network; return s; }; +/** + * Builds a scriptSig (a script for an input) that signs a public key output script. + * + * @param {Signature|Buffer} signature - a Signature object, or the signature in DER cannonical encoding + * @param {number=} sigtype - the type of the signature (defaults to SIGHASH_ALL) + */ +Script.buildPublicKeyIn = function(signature, sigtype) { + $.checkArgument(signature instanceof Signature || BufferUtil.isBuffer(signature)); + $.checkArgument(_.isUndefined(sigtype) || _.isNumber(sigtype)); + if (signature instanceof Signature) { + signature = signature.toBuffer(); + } + var script = new Script(); + script.add(BufferUtil.concat([ + signature, + BufferUtil.integerAsSingleByteBuffer(sigtype || Signature.SIGHASH_ALL) + ])); + return script; +}; + /** * Builds a scriptSig (a script for an input) that signs a public key hash * output script. @@ -7126,7 +7777,7 @@ Script.prototype.toScriptHashOut = function() { }; /** - * @return {Script} a script built from the address + * @return {Script} an output script built from the address */ Script.fromAddress = function(address) { address = Address(address); @@ -7139,22 +7790,74 @@ Script.fromAddress = function(address) { }; /** - * @param {Network} [network] - * @return {Address} the associated address for this script + * Will return the associated address information object + * @return {Address|boolean} */ -Script.prototype.toAddress = function(network) { - network = Networks.get(network) || this._network || Networks.defaultNetwork; - if (this.isPublicKeyHashOut() || this.isScriptHashOut()) { - return new Address(this, network); +Script.prototype.getAddressInfo = function(opts) { + if (this._isInput) { + return this._getInputAddressInfo(); + } else if (this._isOutput) { + return this._getOutputAddressInfo(); + } else { + var info = this._getOutputAddressInfo(); + if (!info) { + return this._getInputAddressInfo(); + } + return info; } - throw new Error('The script type needs to be PayToPublicKeyHash or PayToScriptHash'); }; /** - * @return {Script} + * Will return the associated output scriptPubKey address information object + * @return {Address|boolean} + * @private */ -Script.prototype.toScriptHashOut = function() { - return Script.buildScriptHashOut(this); +Script.prototype._getOutputAddressInfo = function() { + var info = {}; + if (this.isScriptHashOut()) { + info.hashBuffer = this.getData(); + info.type = Address.PayToScriptHash; + } else if (this.isPublicKeyHashOut()) { + info.hashBuffer = this.getData(); + info.type = Address.PayToPublicKeyHash; + } else { + return false; + } + return info; +}; + +/** + * Will return the associated input scriptSig address information object + * @return {Address|boolean} + * @private + */ +Script.prototype._getInputAddressInfo = function() { + var info = {}; + if (this.isPublicKeyHashIn()) { + // hash the publickey found in the scriptSig + info.hashBuffer = Hash.sha256ripemd160(this.chunks[1].buf); + info.type = Address.PayToPublicKeyHash; + } else if (this.isScriptHashIn()) { + // hash the redeemscript found at the end of the scriptSig + info.hashBuffer = Hash.sha256ripemd160(this.chunks[this.chunks.length - 1].buf); + info.type = Address.PayToScriptHash; + } else { + return false; + } + return info; +}; + +/** + * @param {Network=} network + * @return {Address|boolean} the associated address for this script if possible, or false + */ +Script.prototype.toAddress = function(network) { + var info = this.getAddressInfo(); + if (!info) { + return false; + } + info.network = Networks.get(network) || this._network || Networks.defaultNetwork; + return new Address(info); }; /** @@ -7214,26 +7917,70 @@ Script.prototype.checkMinimalPush = function(i) { return true; }; +/** + * Comes from bitcoind's script DecodOP_N function + * @param {number} opcode + * @returns {number} numeric value in range of 0 to 16 + */ +Script.prototype._decodeOP_N = function(opcode) { + if (opcode === Opcode.OP_0) { + return 0; + } else if (opcode >= Opcode.OP_1 && opcode <= Opcode.OP_16) { + return opcode - (Opcode.OP_1 - 1); + } else { + throw new Error('Invalid opcode: ' + JSON.stringify(opcode)); + } +}; + +/** + * Comes from bitcoind's script GetSigOpCount(boolean) function + * @param {boolean} use current (true) or pre-version-0.6 (false) logic + * @returns {number} number of signature operations required by this script + */ +Script.prototype.getSignatureOperationsCount = function(accurate) { + accurate = (_.isUndefined(accurate) ? true : accurate); + var self = this; + var n = 0; + var lastOpcode = Opcode.OP_INVALIDOPCODE; + _.each(self.chunks, function getChunk(chunk) { + var opcode = chunk.opcodenum; + if (opcode == Opcode.OP_CHECKSIG || opcode == Opcode.OP_CHECKSIGVERIFY) { + n++; + } else if (opcode == Opcode.OP_CHECKMULTISIG || opcode == Opcode.OP_CHECKMULTISIGVERIFY) { + if (accurate && lastOpcode >= Opcode.OP_1 && lastOpcode <= Opcode.OP_16) { + n += self._decodeOP_N(lastOpcode); + } else { + n += 20; + } + } + lastOpcode = opcode; + }); + return n; +}; + module.exports = Script; }).call(this,require("buffer").Buffer) -},{"../address":1,"../crypto/hash":6,"../crypto/signature":9,"../encoding/bufferreader":12,"../encoding/bufferwriter":13,"../errors":15,"../networks":20,"../opcode":21,"../publickey":23,"../util/buffer":38,"../util/js":39,"../util/preconditions":40,"buffer":42,"lodash":230}],27:[function(require,module,exports){ +},{"../address":1,"../crypto/hash":8,"../crypto/signature":11,"../encoding/bufferreader":14,"../encoding/bufferwriter":15,"../errors":17,"../networks":22,"../opcode":23,"../publickey":25,"../util/buffer":42,"../util/js":43,"../util/preconditions":44,"buffer":47,"lodash":241}],29:[function(require,module,exports){ module.exports = require('./transaction'); module.exports.Input = require('./input'); module.exports.Output = require('./output'); module.exports.UnspentOutput = require('./unspentoutput'); +module.exports.Signature = require('./signature'); -},{"./input":28,"./output":32,"./transaction":34,"./unspentoutput":35}],28:[function(require,module,exports){ +},{"./input":30,"./output":35,"./signature":37,"./transaction":38,"./unspentoutput":39}],30:[function(require,module,exports){ module.exports = require('./input'); +module.exports.PublicKey = require('./publickey'); module.exports.PublicKeyHash = require('./publickeyhash'); module.exports.MultiSigScriptHash = require('./multisigscripthash.js'); -},{"./input":29,"./multisigscripthash.js":30,"./publickeyhash":31}],29:[function(require,module,exports){ +},{"./input":31,"./multisigscripthash.js":32,"./publickey":33,"./publickeyhash":34}],31:[function(require,module,exports){ 'use strict'; var _ = require('lodash'); +var $ = require('../../util/preconditions'); var errors = require('../../errors'); var BufferWriter = require('../../encoding/bufferwriter'); var buffer = require('buffer'); @@ -7243,6 +7990,10 @@ var Script = require('../../script'); var Sighash = require('../sighash'); var Output = require('../output'); + +var DEFAULT_SEQNUMBER = 0xFFFFFFFF; +var DEFAULT_LOCKTIME_SEQNUMBER = 0x00000000; + function Input(params) { if (!(this instanceof Input)) { return new Input(params); @@ -7252,60 +8003,65 @@ function Input(params) { } } +Input.DEFAULT_SEQNUMBER = DEFAULT_SEQNUMBER; +Input.DEFAULT_LOCKTIME_SEQNUMBER = DEFAULT_LOCKTIME_SEQNUMBER; + Object.defineProperty(Input.prototype, 'script', { configurable: false, - writeable: false, enumerable: true, get: function() { + if (this.isNull()) { + return null; + } if (!this._script) { this._script = new Script(this._scriptBuffer); + this._script._isInput = true; } return this._script; } }); +Input.fromObject = function(obj) { + $.checkArgument(_.isObject(obj)); + var input = new Input(); + return input._fromObject(obj); +}; + Input.prototype._fromObject = function(params) { + var prevTxId; if (_.isString(params.prevTxId) && JSUtil.isHexa(params.prevTxId)) { - params.prevTxId = new buffer.Buffer(params.prevTxId, 'hex'); + prevTxId = new buffer.Buffer(params.prevTxId, 'hex'); + } else { + prevTxId = params.prevTxId; } this.output = params.output ? - (params.output instanceof Output ? params.output : new Output(params.output)) : undefined; - this.prevTxId = params.prevTxId; - this.outputIndex = params.outputIndex; - this.sequenceNumber = params.sequenceNumber; - if (!_.isUndefined(params.script) || !_.isUndefined(params.scriptBuffer)) { - this.setScript(_.isUndefined(params.script) ? params.scriptBuffer : params.script); - } else { + (params.output instanceof Output ? params.output : new Output(params.output)) : undefined; + this.prevTxId = prevTxId || params.txidbuf; + this.outputIndex = _.isUndefined(params.outputIndex) ? params.txoutnum : params.outputIndex; + this.sequenceNumber = _.isUndefined(params.sequenceNumber) ? + (_.isUndefined(params.seqnum) ? DEFAULT_SEQNUMBER : params.seqnum) : params.sequenceNumber; + if (_.isUndefined(params.script) && _.isUndefined(params.scriptBuffer)) { throw new errors.Transaction.Input.MissingScript(); } + this.setScript(params.scriptBuffer || params.script); return this; }; -Input.prototype.toObject = function toObject() { - return { +Input.prototype.toObject = Input.prototype.toJSON = function toObject() { + var obj = { prevTxId: this.prevTxId.toString('hex'), outputIndex: this.outputIndex, sequenceNumber: this.sequenceNumber, - script: this.script.toString(), - output: this.output ? this.output.toObject() : undefined + script: this._scriptBuffer.toString('hex'), }; -}; - -Input.prototype.toJSON = function toJSON() { - return JSON.stringify(this.toObject()); -}; - -Input.fromJSON = function(json) { - if (JSUtil.isValidJSON(json)) { - json = JSON.parse(json); + // add human readable form if input contains valid script + if (this.script) { + obj.scriptString = this.script.toString(); } - return new Input({ - output: json.output ? new Output(json.output) : undefined, - prevTxId: json.prevTxId || json.txidbuf, - outputIndex: _.isUndefined(json.outputIndex) ? json.txoutnum : json.outputIndex, - sequenceNumber: json.sequenceNumber || json.seqnum, - scriptBuffer: new Script(json.script, 'hex') - }); + if (this.output) { + obj.output = this.output.toObject(); + } + return obj; }; Input.fromBufferReader = function(br) { @@ -7314,6 +8070,8 @@ Input.fromBufferReader = function(br) { input.outputIndex = br.readUInt32LE(); input._scriptBuffer = br.readVarLengthBuffer(); input.sequenceNumber = br.readUInt32LE(); + // TODO: return different classes according to which input it is + // e.g: CoinbaseInput, PublicKeyHashInput, MultiSigScriptHashInput, etc. return input; }; @@ -7331,17 +8089,24 @@ Input.prototype.toBufferWriter = function(writer) { }; Input.prototype.setScript = function(script) { + this._script = null; if (script instanceof Script) { this._script = script; + this._script._isInput = true; this._scriptBuffer = script.toBuffer(); + } else if (JSUtil.isHexa(script)) { + // hex string script + this._scriptBuffer = new buffer.Buffer(script, 'hex'); } else if (_.isString(script)) { + // human readable string script this._script = new Script(script); + this._script._isInput = true; this._scriptBuffer = this._script.toBuffer(); } else if (BufferUtil.isBuffer(script)) { - this._script = null; + // buffer script this._scriptBuffer = new buffer.Buffer(script); } else { - throw new TypeError('Invalid Argument'); + throw new TypeError('Invalid argument type: script'); } return this; }; @@ -7360,7 +8125,7 @@ Input.prototype.setScript = function(script) { Input.prototype.getSignatures = function() { throw new errors.AbstractMethodInvoked( 'Trying to sign unsupported output type (only P2PKH and P2SH multisig inputs are supported)' + - ' for input: ' + this.toJSON() + ' for input: ' + JSON.stringify(this) ); }; @@ -7368,6 +8133,10 @@ Input.prototype.isFullySigned = function() { throw new errors.AbstractMethodInvoked('Input#isFullySigned'); }; +Input.prototype.isFinal = function() { + return this.sequenceNumber !== 4294967295; +}; + Input.prototype.addSignature = function() { throw new errors.AbstractMethodInvoked('Input#addSignature'); }; @@ -7397,14 +8166,12 @@ Input.prototype.isNull = function() { }; Input.prototype._estimateSize = function() { - var bufferWriter = new BufferWriter(); - this.toBufferWriter(bufferWriter); - return bufferWriter.toBuffer().length; + return this.toBufferWriter().toBuffer().length; }; module.exports = Input; -},{"../../encoding/bufferwriter":13,"../../errors":15,"../../script":24,"../../util/buffer":38,"../../util/js":39,"../output":32,"../sighash":33,"buffer":42,"lodash":230}],30:[function(require,module,exports){ +},{"../../encoding/bufferwriter":15,"../../errors":17,"../../script":26,"../../util/buffer":42,"../../util/js":43,"../../util/preconditions":44,"../output":35,"../sighash":36,"buffer":47,"lodash":241}],32:[function(require,module,exports){ 'use strict'; var _ = require('lodash'); @@ -7418,6 +8185,7 @@ var Signature = require('../../crypto/signature'); var Sighash = require('../sighash'); var PublicKey = require('../../publickey'); var BufferUtil = require('../../util/buffer'); +var TransactionSignature = require('../signature'); /** * @constructor @@ -7425,6 +8193,9 @@ var BufferUtil = require('../../util/buffer'); function MultiSigScriptHashInput(input, pubkeys, threshold, signatures) { Input.apply(this, arguments); var self = this; + pubkeys = pubkeys || input.publicKeys; + threshold = threshold || input.threshold; + signatures = signatures || input.signatures; this.publicKeys = _.sortBy(pubkeys, function(publicKey) { return publicKey.toString('hex'); }); this.redeemScript = Script.buildMultisigOut(this.publicKeys, threshold); $.checkState(Script.buildScriptHashOut(this.redeemScript).equals(this.output.script), @@ -7452,14 +8223,7 @@ MultiSigScriptHashInput.prototype._deserializeSignatures = function(signatures) if (!signature) { return undefined; } - return { - publicKey: new PublicKey(signature.publicKey), - prevTxId: signature.txId, - outputIndex: signature.outputIndex, - inputIndex: signature.inputIndex, - signature: Signature.fromString(signature.signature), - sigtype: signature.sigtype - }; + return new TransactionSignature(signature); }); }; @@ -7468,14 +8232,7 @@ MultiSigScriptHashInput.prototype._serializeSignatures = function() { if (!signature) { return undefined; } - return { - publicKey: signature.publicKey.toString(), - prevTxId: signature.txId, - outputIndex: signature.outputIndex, - inputIndex: signature.inputIndex, - signature: signature.signature.toString(), - sigtype: signature.sigtype - }; + return signature.toObject(); }); }; @@ -7487,14 +8244,14 @@ MultiSigScriptHashInput.prototype.getSignatures = function(transaction, privateK var results = []; _.each(this.publicKeys, function(publicKey) { if (publicKey.toString() === privateKey.publicKey.toString()) { - results.push({ + results.push(new TransactionSignature({ publicKey: privateKey.publicKey, - prevTxId: self.txId, + prevTxId: self.prevTxId, outputIndex: self.outputIndex, inputIndex: index, signature: Sighash.sign(transaction, privateKey, sigtype, index, self.redeemScript), sigtype: sigtype - }); + })); } }); return results; @@ -7582,7 +8339,98 @@ MultiSigScriptHashInput.prototype._estimateSize = function() { module.exports = MultiSigScriptHashInput; -},{"../../crypto/signature":9,"../../publickey":23,"../../script":24,"../../util/buffer":38,"../../util/preconditions":40,"../output":32,"../sighash":33,"./input":29,"inherits":229,"lodash":230}],31:[function(require,module,exports){ +},{"../../crypto/signature":11,"../../publickey":25,"../../script":26,"../../util/buffer":42,"../../util/preconditions":44,"../output":35,"../sighash":36,"../signature":37,"./input":31,"inherits":240,"lodash":241}],33:[function(require,module,exports){ +'use strict'; + +var inherits = require('inherits'); + +var $ = require('../../util/preconditions'); +var BufferUtil = require('../../util/buffer'); + +var Input = require('./input'); +var Output = require('../output'); +var Sighash = require('../sighash'); +var Script = require('../../script'); +var Signature = require('../../crypto/signature'); +var TransactionSignature = require('../signature'); + +/** + * Represents a special kind of input of PayToPublicKey kind. + * @constructor + */ +function PublicKeyInput() { + Input.apply(this, arguments); +} +inherits(PublicKeyInput, Input); + +/** + * @param {Transaction} transaction - the transaction to be signed + * @param {PrivateKey} privateKey - the private key with which to sign the transaction + * @param {number} index - the index of the input in the transaction input vector + * @param {number=} sigtype - the type of signature, defaults to Signature.SIGHASH_ALL + * @return {Array} of objects that can be + */ +PublicKeyInput.prototype.getSignatures = function(transaction, privateKey, index, sigtype) { + $.checkState(this.output instanceof Output); + sigtype = sigtype || Signature.SIGHASH_ALL; + var publicKey = privateKey.toPublicKey(); + if (publicKey.toString() === this.output.script.getPublicKey().toString('hex')) { + return [new TransactionSignature({ + publicKey: publicKey, + prevTxId: this.prevTxId, + outputIndex: this.outputIndex, + inputIndex: index, + signature: Sighash.sign(transaction, privateKey, sigtype, index, this.output.script), + sigtype: sigtype + })]; + } + return []; +}; + +/** + * Add the provided signature + * + * @param {Object} signature + * @param {PublicKey} signature.publicKey + * @param {Signature} signature.signature + * @param {number=} signature.sigtype + * @return {PublicKeyInput} this, for chaining + */ +PublicKeyInput.prototype.addSignature = function(transaction, signature) { + $.checkState(this.isValidSignature(transaction, signature), 'Signature is invalid'); + this.setScript(Script.buildPublicKeyIn( + signature.signature.toDER(), + signature.sigtype + )); + return this; +}; + +/** + * Clear the input's signature + * @return {PublicKeyHashInput} this, for chaining + */ +PublicKeyInput.prototype.clearSignatures = function() { + this.setScript(Script.empty()); + return this; +}; + +/** + * Query whether the input is signed + * @return {boolean} + */ +PublicKeyInput.prototype.isFullySigned = function() { + return this.script.isPublicKeyIn(); +}; + +PublicKeyInput.SCRIPT_MAX_SIZE = 73; // sigsize (1 + 72) + +PublicKeyInput.prototype._estimateSize = function() { + return PublicKeyInput.SCRIPT_MAX_SIZE; +}; + +module.exports = PublicKeyInput; + +},{"../../crypto/signature":11,"../../script":26,"../../util/buffer":42,"../../util/preconditions":44,"../output":35,"../sighash":36,"../signature":37,"./input":31,"inherits":240}],34:[function(require,module,exports){ 'use strict'; var inherits = require('inherits'); @@ -7596,6 +8444,7 @@ var Output = require('../output'); var Sighash = require('../sighash'); var Script = require('../../script'); var Signature = require('../../crypto/signature'); +var TransactionSignature = require('../signature'); /** * Represents a special kind of input of PayToPublicKeyHash kind. @@ -7621,14 +8470,14 @@ PublicKeyHashInput.prototype.getSignatures = function(transaction, privateKey, i sigtype = sigtype || Signature.SIGHASH_ALL; if (BufferUtil.equals(hashData, this.output.script.getPublicKeyHash())) { - return [{ + return [new TransactionSignature({ publicKey: privateKey.publicKey, - prevTxId: this.txId, + prevTxId: this.prevTxId, outputIndex: this.outputIndex, inputIndex: index, signature: Sighash.sign(transaction, privateKey, sigtype, index, this.output.script), sigtype: sigtype - }]; + })]; } return []; }; @@ -7678,7 +8527,7 @@ PublicKeyHashInput.prototype._estimateSize = function() { module.exports = PublicKeyHashInput; -},{"../../crypto/hash":6,"../../crypto/signature":9,"../../script":24,"../../util/buffer":38,"../../util/preconditions":40,"../output":32,"../sighash":33,"./input":29,"inherits":229}],32:[function(require,module,exports){ +},{"../../crypto/hash":8,"../../crypto/signature":11,"../../script":26,"../../util/buffer":42,"../../util/preconditions":44,"../output":35,"../sighash":36,"../signature":37,"./input":31,"inherits":240}],35:[function(require,module,exports){ 'use strict'; var _ = require('lodash'); @@ -7688,34 +8537,49 @@ var bufferUtil = require('../util/buffer'); var JSUtil = require('../util/js'); var BufferWriter = require('../encoding/bufferwriter'); var Script = require('../script'); +var $ = require('../util/preconditions'); +var errors = require('../errors'); + +var MAX_SAFE_INTEGER = 0x1fffffffffffff; -function Output(params) { +function Output(args) { if (!(this instanceof Output)) { - return new Output(params); + return new Output(args); } - if (params) { - if (JSUtil.isValidJSON(params)) { - return Output.fromJSON(params); + if (_.isObject(args)) { + this.satoshis = args.satoshis; + if (bufferUtil.isBuffer(args.script)) { + this._scriptBuffer = args.script; + } else { + var script; + if (_.isString(args.script) && JSUtil.isHexa(args.script)) { + script = new buffer.Buffer(args.script, 'hex'); + } else { + script = args.script; + } + this.setScript(script); } - return this._fromObject(params); + } else { + throw new TypeError('Unrecognized argument for Output'); } } Object.defineProperty(Output.prototype, 'script', { configurable: false, - writeable: false, enumerable: true, get: function() { - if (!this._script) { - this._script = new Script(this._scriptBuffer); + if (this._script) { + return this._script; + } else { + this.setScriptFromBuffer(this._scriptBuffer); + return this._script; } - return this._script; + } }); Object.defineProperty(Output.prototype, 'satoshis', { configurable: false, - writeable: true, enumerable: true, get: function() { return this._satoshis; @@ -7728,71 +8592,96 @@ Object.defineProperty(Output.prototype, 'satoshis', { this._satoshis = parseInt(num); this._satoshisBN = BN.fromNumber(this._satoshis); } else { + $.checkArgument( + JSUtil.isNaturalNumber(num), + 'Output satoshis is not a natural number' + ); this._satoshisBN = BN.fromNumber(num); this._satoshis = num; } + $.checkState( + JSUtil.isNaturalNumber(this._satoshis), + 'Output satoshis is not a natural number' + ); } }); -Output.prototype._fromObject = function(param) { - this.satoshis = param.satoshis; - if (param.script || param.scriptBuffer) { - this.setScript(param.script || param.scriptBuffer); +Output.prototype.invalidSatoshis = function() { + if (this._satoshis > MAX_SAFE_INTEGER) { + return 'transaction txout satoshis greater than max safe integer'; } - return this; + if (this._satoshis !== this._satoshisBN.toNumber()) { + return 'transaction txout satoshis has corrupted value'; + } + if (this._satoshis < 0) { + return 'transaction txout negative'; + } + return false; }; -Output.prototype.toObject = function toObject() { - return { - satoshis: this.satoshis, - script: this.script.toString() +Output.prototype.toObject = Output.prototype.toJSON = function toObject() { + var obj = { + satoshis: this.satoshis }; + obj.script = this._scriptBuffer.toString('hex'); + return obj; }; -Output.prototype.toJSON = function toJSON() { - return JSON.stringify(this.toObject()); +Output.fromObject = function(data) { + return new Output(data); }; -Output.fromJSON = function(json) { - if (JSUtil.isValidJSON(json)) { - json = JSON.parse(json); +Output.prototype.setScriptFromBuffer = function(buffer) { + this._scriptBuffer = buffer; + try { + this._script = Script.fromBuffer(this._scriptBuffer); + this._script._isOutput = true; + } catch(e) { + if (e instanceof errors.Script.InvalidBuffer) { + this._script = null; + } else { + throw e; + } } - return new Output({ - satoshis: json.satoshis || -(-json.valuebn), - script: new Script(json.script) - }); }; Output.prototype.setScript = function(script) { if (script instanceof Script) { this._scriptBuffer = script.toBuffer(); this._script = script; + this._script._isOutput = true; } else if (_.isString(script)) { - this._script = new Script(script); + this._script = Script.fromString(script); this._scriptBuffer = this._script.toBuffer(); + this._script._isOutput = true; } else if (bufferUtil.isBuffer(script)) { - this._scriptBuffer = script; - this._script = null; + this.setScriptFromBuffer(script); } else { - throw new TypeError('Unrecognized Argument'); + throw new TypeError('Invalid argument type: script'); } return this; }; Output.prototype.inspect = function() { - return ''; + var scriptStr; + if (this.script) { + scriptStr = this.script.inspect(); + } else { + scriptStr = this._scriptBuffer.toString('hex'); + } + return ''; }; Output.fromBufferReader = function(br) { - var output = new Output(); - output.satoshis = br.readUInt64LEBN(); + var obj = {}; + obj.satoshis = br.readUInt64LEBN(); var size = br.readVarintNum(); if (size !== 0) { - output._scriptBuffer = br.read(size); + obj.script = br.read(size); } else { - output._scriptBuffer = new buffer.Buffer([]); + obj.script = new buffer.Buffer([]); } - return output; + return new Output(obj); }; Output.prototype.toBufferWriter = function(writer) { @@ -7808,7 +8697,7 @@ Output.prototype.toBufferWriter = function(writer) { module.exports = Output; -},{"../crypto/bn":4,"../encoding/bufferwriter":13,"../script":24,"../util/buffer":38,"../util/js":39,"buffer":42,"lodash":230}],33:[function(require,module,exports){ +},{"../crypto/bn":6,"../encoding/bufferwriter":15,"../errors":17,"../script":26,"../util/buffer":42,"../util/js":43,"../util/preconditions":44,"buffer":47,"lodash":241}],36:[function(require,module,exports){ (function (Buffer){ 'use strict'; @@ -7874,12 +8763,9 @@ var sighash = function sighash(transaction, sighashType, inputNumber, subscript) } else if ((sighashType & 31) === Signature.SIGHASH_SINGLE) { // The SIGHASH_SINGLE bug. // https://bitcointalk.org/index.php?topic=260595.0 - if (inputNumber > txcopy.outputs.length - 1) { + if (inputNumber >= txcopy.outputs.length) { return new Buffer(SIGHASH_SINGLE_BUG, 'hex'); } - if (txcopy.outputs.length <= inputNumber) { - throw new Error('Missing output to sign'); - } txcopy.outputs.length = inputNumber + 1; @@ -7951,7 +8837,100 @@ module.exports = { }; }).call(this,require("buffer").Buffer) -},{"../crypto/bn":4,"../crypto/ecdsa":5,"../crypto/hash":6,"../crypto/signature":9,"../encoding/bufferreader":12,"../encoding/bufferwriter":13,"../script":24,"../util/preconditions":40,"./input":28,"./output":32,"./transaction":34,"buffer":42,"lodash":230}],34:[function(require,module,exports){ +},{"../crypto/bn":6,"../crypto/ecdsa":7,"../crypto/hash":8,"../crypto/signature":11,"../encoding/bufferreader":14,"../encoding/bufferwriter":15,"../script":26,"../util/preconditions":44,"./input":30,"./output":35,"./transaction":38,"buffer":47,"lodash":241}],37:[function(require,module,exports){ +(function (Buffer){ +'use strict'; + +var _ = require('lodash'); +var $ = require('../util/preconditions'); +var inherits = require('inherits'); +var BufferUtil = require('../util/buffer'); +var JSUtil = require('../util/js'); + +var PublicKey = require('../publickey'); +var errors = require('../errors'); +var Signature = require('../crypto/signature'); + +/** + * @desc + * Wrapper around Signature with fields related to signing a transaction specifically + * + * @param {Object|string|TransactionSignature} arg + * @constructor + */ +function TransactionSignature(arg) { + if (!(this instanceof TransactionSignature)) { + return new TransactionSignature(arg); + } + if (arg instanceof TransactionSignature) { + return arg; + } + if (_.isObject(arg)) { + return this._fromObject(arg); + } + throw new errors.InvalidArgument('TransactionSignatures must be instantiated from an object'); +} +inherits(TransactionSignature, Signature); + +TransactionSignature.prototype._fromObject = function(arg) { + this._checkObjectArgs(arg); + this.publicKey = new PublicKey(arg.publicKey); + this.prevTxId = BufferUtil.isBuffer(arg.prevTxId) ? arg.prevTxId : new Buffer(arg.prevTxId, 'hex'); + this.outputIndex = arg.outputIndex; + this.inputIndex = arg.inputIndex; + this.signature = (arg.signature instanceof Signature) ? arg.signature : + BufferUtil.isBuffer(arg.signature) ? Signature.fromBuffer(arg.signature) : + Signature.fromString(arg.signature); + this.sigtype = arg.sigtype; + return this; +}; + +TransactionSignature.prototype._checkObjectArgs = function(arg) { + $.checkArgument(PublicKey(arg.publicKey), 'publicKey'); + $.checkArgument(!_.isUndefined(arg.inputIndex), 'inputIndex'); + $.checkArgument(!_.isUndefined(arg.outputIndex), 'outputIndex'); + $.checkState(_.isNumber(arg.inputIndex), 'inputIndex must be a number'); + $.checkState(_.isNumber(arg.outputIndex), 'outputIndex must be a number'); + $.checkArgument(arg.signature, 'signature'); + $.checkArgument(arg.prevTxId, 'prevTxId'); + $.checkState(arg.signature instanceof Signature || + BufferUtil.isBuffer(arg.signature) || + JSUtil.isHexa(arg.signature), 'signature must be a buffer or hexa value'); + $.checkState(BufferUtil.isBuffer(arg.prevTxId) || + JSUtil.isHexa(arg.prevTxId), 'prevTxId must be a buffer or hexa value'); + $.checkArgument(arg.sigtype, 'sigtype'); + $.checkState(_.isNumber(arg.sigtype), 'sigtype must be a number'); +}; + +/** + * Serializes a transaction to a plain JS object + * @return {Object} + */ +TransactionSignature.prototype.toObject = TransactionSignature.prototype.toJSON = function toObject() { + return { + publicKey: this.publicKey.toString(), + prevTxId: this.prevTxId.toString('hex'), + outputIndex: this.outputIndex, + inputIndex: this.inputIndex, + signature: this.signature.toString(), + sigtype: this.sigtype + }; +}; + +/** + * Builds a TransactionSignature from an object + * @param {Object} object + * @return {TransactionSignature} + */ +TransactionSignature.fromObject = function(object) { + $.checkArgument(object); + return new TransactionSignature(object); +}; + +module.exports = TransactionSignature; + +}).call(this,require("buffer").Buffer) +},{"../crypto/signature":11,"../errors":17,"../publickey":25,"../util/buffer":42,"../util/js":43,"../util/preconditions":44,"buffer":47,"inherits":240,"lodash":241}],38:[function(require,module,exports){ 'use strict'; var _ = require('lodash'); @@ -7959,8 +8938,7 @@ var $ = require('../util/preconditions'); var buffer = require('buffer'); var errors = require('../errors'); -var util = require('../util/js'); -var bufferUtil = require('../util/buffer'); +var BufferUtil = require('../util/buffer'); var JSUtil = require('../util/js'); var BufferReader = require('../encoding/bufferreader'); var BufferWriter = require('../encoding/bufferwriter'); @@ -7972,17 +8950,13 @@ var Address = require('../address'); var UnspentOutput = require('./unspentoutput'); var Input = require('./input'); var PublicKeyHashInput = Input.PublicKeyHash; +var PublicKeyInput = Input.PublicKey; var MultiSigScriptHashInput = Input.MultiSigScriptHash; var Output = require('./output'); var Script = require('../script'); var PrivateKey = require('../privatekey'); -var Block = require('../block'); var BN = require('../crypto/bn'); -var CURRENT_VERSION = 1; -var DEFAULT_NLOCKTIME = 0; -var DEFAULT_SEQNUMBER = 0xFFFFFFFF; - /** * Represents a transaction, a set of inputs and outputs to change ownership of tokens * @@ -7995,17 +8969,15 @@ function Transaction(serialized) { } this.inputs = []; this.outputs = []; - this._inputAmount = 0; - this._outputAmount = 0; + this._inputAmount = undefined; + this._outputAmount = undefined; if (serialized) { if (serialized instanceof Transaction) { return Transaction.shallowCopy(serialized); - } else if (util.isHexa(serialized)) { + } else if (JSUtil.isHexa(serialized)) { this.fromString(serialized); - } else if (util.isValidJSON(serialized)) { - this.fromJSON(serialized); - } else if (bufferUtil.isBuffer(serialized)) { + } else if (BufferUtil.isBuffer(serialized)) { this.fromBuffer(serialized); } else if (_.isObject(serialized)) { this.fromObject(serialized); @@ -8017,9 +8989,32 @@ function Transaction(serialized) { } } +var CURRENT_VERSION = 1; +var DEFAULT_NLOCKTIME = 0; +var MAX_BLOCK_SIZE = 1000000; + +// Minimum amount for an output for it not to be considered a dust output +Transaction.DUST_AMOUNT = 546; + +// Margin of error to allow fees in the vecinity of the expected value but doesn't allow a big difference +Transaction.FEE_SECURITY_MARGIN = 15; + // max amount of satoshis in circulation Transaction.MAX_MONEY = 21000000 * 1e8; +// nlocktime limit to be considered block height rather than a timestamp +Transaction.NLOCKTIME_BLOCKHEIGHT_LIMIT = 5e8; + +// Max value for an unsigned 32 bit value +Transaction.NLOCKTIME_MAX_VALUE = 4294967295; + +// Value used for fee estimation (satoshis per kilobyte) +Transaction.FEE_PER_KB = 10000; + +// Safe upper bound for change address script size in bytes +Transaction.CHANGE_OUTPUT_MAX_SIZE = 20 + 4 + 34 + 4; +Transaction.MAXIMUM_EXTRA_SIZE = 4 + 9 + 9 + 4; + /* Constructors and Serialization */ /** @@ -8036,7 +9031,6 @@ Transaction.shallowCopy = function(transaction) { var hashProperty = { configurable: false, - writeable: false, enumerable: true, get: function() { return new BufferReader(this._getHash()).readReverse().toString('hex'); @@ -8045,6 +9039,19 @@ var hashProperty = { Object.defineProperty(Transaction.prototype, 'hash', hashProperty); Object.defineProperty(Transaction.prototype, 'id', hashProperty); +var ioProperty = { + configurable: false, + enumerable: true, + get: function() { + return this._getInputAmount(); + } +}; +Object.defineProperty(Transaction.prototype, 'inputAmount', ioProperty); +ioProperty.get = function() { + return this._getOutputAmount(); +}; +Object.defineProperty(Transaction.prototype, 'outputAmount', ioProperty); + /** * Retrieve the little endian hash of the transaction (used for serialization) * @return {Buffer} @@ -8057,61 +9064,140 @@ Transaction.prototype._getHash = function() { * Retrieve a hexa string that can be used with bitcoind's CLI interface * (decoderawtransaction, sendrawtransaction) * - * @param {boolean=} unsafe if true, skip testing for fees that are too high + * @param {Object|boolean=} unsafe if true, skip all tests. if it's an object, + * it's expected to contain a set of flags to skip certain tests: + * * `disableAll`: disable all checks + * * `disableSmallFees`: disable checking for fees that are too small + * * `disableLargeFees`: disable checking for fees that are too large + * * `disableNotFullySigned`: disable checking if all inputs are fully signed + * * `disableDustOutputs`: disable checking if there are no outputs that are dust amounts + * * `disableMoreOutputThanInput`: disable checking if the transaction spends more bitcoins than the sum of the input amounts * @return {string} */ Transaction.prototype.serialize = function(unsafe) { - if (unsafe) { + if (true === unsafe || unsafe && unsafe.disableAll) { return this.uncheckedSerialize(); } else { - return this.checkedSerialize(); + return this.checkedSerialize(unsafe); } }; -Transaction.prototype.uncheckedSerialize = function() { +Transaction.prototype.uncheckedSerialize = Transaction.prototype.toString = function() { return this.toBuffer().toString('hex'); }; -Transaction.prototype.checkedSerialize = Transaction.prototype.toString = function() { - var feeError = this._validateFees(); - if (feeError) { - var changeError = this._validateChange(); - if (changeError) { - throw new errors.Transaction.ChangeAddressMissing(); - } else { - throw new errors.Transaction.FeeError(feeError); - } - } - if (this._hasDustOutputs()) { - throw new errors.Transaction.DustOutputs(); +/** + * Retrieve a hexa string that can be used with bitcoind's CLI interface + * (decoderawtransaction, sendrawtransaction) + * + * @param {Object} opts allows to skip certain tests. {@see Transaction#serialize} + * @return {string} + */ +Transaction.prototype.checkedSerialize = function(opts) { + var serializationError = this.getSerializationError(opts); + if (serializationError) { + serializationError.message += ' Use Transaction#uncheckedSerialize if you want to skip security checks. ' + + 'See http://bitcore.io/guide/transaction.html#Serialization for more info.'; + throw serializationError; } return this.uncheckedSerialize(); }; -Transaction.FEE_SECURITY_MARGIN = 15; +Transaction.prototype.invalidSatoshis = function() { + var invalid = false; + for (var i = 0; i < this.outputs.length; i++) { + if (this.outputs[i].invalidSatoshis()) { + invalid = true; + } + } + return invalid; +}; + +/** + * Retrieve a possible error that could appear when trying to serialize and + * broadcast this transaction. + * + * @param {Object} opts allows to skip certain tests. {@see Transaction#serialize} + * @return {bitcore.Error} + */ +Transaction.prototype.getSerializationError = function(opts) { + opts = opts || {}; -Transaction.prototype._validateFees = function() { - if (this._getUnspentValue() > Transaction.FEE_SECURITY_MARGIN * this._estimateFee()) { - return 'Fee is more than ' + Transaction.FEE_SECURITY_MARGIN + ' times the suggested amount'; + if (this.invalidSatoshis()) { + return new errors.Transaction.InvalidSatoshis(); } + + var unspent = this._getUnspentValue(); + var unspentError; + if (unspent < 0) { + if (!opts.disableMoreOutputThanInput) { + unspentError = new errors.Transaction.InvalidOutputAmountSum(); + } + } else { + unspentError = this._hasFeeError(opts, unspent); + } + + return unspentError || + this._hasDustOutputs(opts) || + this._isMissingSignatures(opts); }; -Transaction.prototype._validateChange = function() { - if (!this._change) { - return 'Missing change address'; +Transaction.prototype._hasFeeError = function(opts, unspent) { + + if (!_.isUndefined(this._fee) && this._fee !== unspent) { + return new errors.Transaction.FeeError.Different( + 'Unspent value is ' + unspent + ' but specified fee is ' + this._fee + ); + } + + if (!opts.disableLargeFees) { + var maximumFee = Math.floor(Transaction.FEE_SECURITY_MARGIN * this._estimateFee()); + if (unspent > maximumFee) { + if (this._missingChange()) { + return new errors.Transaction.ChangeAddressMissing( + 'Fee is too large and no change address was provided' + ); + } + return new errors.Transaction.FeeError.TooLarge( + 'expected less than ' + maximumFee + ' but got ' + unspent + ); + } + } + + if (!opts.disableSmallFees) { + var minimumFee = Math.ceil(this._estimateFee() / Transaction.FEE_SECURITY_MARGIN); + if (unspent < minimumFee) { + return new errors.Transaction.FeeError.TooSmall( + 'expected more than ' + minimumFee + ' but got ' + unspent + ); + } } }; -Transaction.DUST_AMOUNT = 5460; +Transaction.prototype._missingChange = function() { + return !this._changeScript; +}; -Transaction.prototype._hasDustOutputs = function() { - var output; - for (output in this.outputs) { - if (this.outputs[output].satoshis < Transaction.DUST_AMOUNT) { - return true; +Transaction.prototype._hasDustOutputs = function(opts) { + if (opts.disableDustOutputs) { + return; + } + var index, output; + for (index in this.outputs) { + output = this.outputs[index]; + if (output.satoshis < Transaction.DUST_AMOUNT && !output.script.isDataOut()) { + return new errors.Transaction.DustOutputs(); } } - return false; +}; + +Transaction.prototype._isMissingSignatures = function(opts) { + if (opts.disableIsFullySigned) { + return; + } + if (!this.isFullySigned()) { + return new errors.Transaction.MissingSignatures(); + } }; Transaction.prototype.inspect = function() { @@ -8160,30 +9246,7 @@ Transaction.prototype.fromBufferReader = function(reader) { return this; }; -Transaction.prototype.fromJSON = function(json) { - if (JSUtil.isValidJSON(json)) { - json = JSON.parse(json); - } - var self = this; - this.inputs = []; - var inputs = json.inputs || json.txins; - inputs.forEach(function(input) { - self.inputs.push(Input.fromJSON(input)); - }); - this.outputs = []; - var outputs = json.outputs || json.txouts; - outputs.forEach(function(output) { - self.outputs.push(Output.fromJSON(output)); - }); - if (json.change) { - this.change(json.change); - } - this.version = json.version; - this.nLockTime = json.nLockTime; - return this; -}; - -Transaction.prototype.toObject = function toObject() { +Transaction.prototype.toObject = Transaction.prototype.toJSON = function toObject() { var inputs = []; this.inputs.forEach(function(input) { inputs.push(input.toObject()); @@ -8192,48 +9255,151 @@ Transaction.prototype.toObject = function toObject() { this.outputs.forEach(function(output) { outputs.push(output.toObject()); }); - return { - change: this._change ? this._change.toString() : undefined, - fee: this._fee ? this._fee : undefined, + var obj = { + hash: this.hash, version: this.version, inputs: inputs, outputs: outputs, nLockTime: this.nLockTime }; + if (this._changeScript) { + obj.changeScript = this._changeScript.toString(); + } + if (!_.isUndefined(this._changeIndex)) { + obj.changeIndex = this._changeIndex; + } + if (!_.isUndefined(this._fee)) { + obj.fee = this._fee; + } + return obj; }; -Transaction.prototype.fromObject = function(transaction) { +Transaction.prototype.fromObject = function fromObject(arg) { + /* jshint maxstatements: 20 */ + $.checkArgument(_.isObject(arg) || arg instanceof Transaction); var self = this; + var transaction; + if (arg instanceof Transaction) { + transaction = transaction.toObject(); + } else { + transaction = arg; + } _.each(transaction.inputs, function(input) { - if (input.output && input.output.script) { - input.output.script = new Script(input.output.script); - if (input.output.script.isPublicKeyHashOut()) { - self.addInput(new Input.PublicKeyHash(input)); - return; - } else if (input.output.script.isScriptHashOut() && input.publicKeys && input.threshold) { - self.addInput(new Input.MultiSigScriptHash( - input, input.publicKeys, input.threshold, input.signatures - )); - return; - } + if (!input.output || !input.output.script) { + self.uncheckedAddInput(new Input(input)); + return; } - self.uncheckedAddInput(new Input(input)); + var script = new Script(input.output.script); + var txin; + if (script.isPublicKeyHashOut()) { + txin = new Input.PublicKeyHash(input); + } else if (script.isScriptHashOut() && input.publicKeys && input.threshold) { + txin = new Input.MultiSigScriptHash( + input, input.publicKeys, input.threshold, input.signatures + ); + } else { + throw new errors.Transaction.Input.UnsupportedScript(input.output.script); + } + self.addInput(txin); }); _.each(transaction.outputs, function(output) { self.addOutput(new Output(output)); }); - if (transaction.change) { - this.change(transaction.change); + if (transaction.changeIndex) { + this._changeIndex = transaction.changeIndex; + } + if (transaction.changeScript) { + this._changeScript = new Script(transaction.changeScript); } if (transaction.fee) { this.fee(transaction.fee); } this.nLockTime = transaction.nLockTime; this.version = transaction.version; + this._checkConsistency(arg); + return this; +}; + +Transaction.prototype._checkConsistency = function(arg) { + if (!_.isUndefined(this._changeIndex)) { + $.checkState(this._changeScript); + $.checkState(this.outputs[this._changeIndex]); + $.checkState(this.outputs[this._changeIndex].script.toString() === + this._changeScript.toString()); + } + if (arg && arg.hash) { + $.checkState(arg.hash === this.hash, 'Hash in object does not match transaction hash'); + } +}; + +/** + * Sets nLockTime so that transaction is not valid until the desired date(a + * timestamp in seconds since UNIX epoch is also accepted) + * + * @param {Date | Number} time + * @return {Transaction} this + */ +Transaction.prototype.lockUntilDate = function(time) { + $.checkArgument(time); + if (_.isNumber(time) && time < Transaction.NLOCKTIME_BLOCKHEIGHT_LIMIT) { + throw new errors.Transaction.LockTimeTooEarly(); + } + if (_.isDate(time)) { + time = time.getTime() / 1000; + } + + for (var i = 0; i < this.inputs.length; i++) { + if (this.inputs[i].sequenceNumber === Input.DEFAULT_SEQNUMBER){ + this.inputs[i].sequenceNumber = Input.DEFAULT_LOCKTIME_SEQNUMBER; + } + } + + this.nLockTime = time; + return this; +}; + +/** + * Sets nLockTime so that transaction is not valid until the desired block + * height. + * + * @param {Number} height + * @return {Transaction} this + */ +Transaction.prototype.lockUntilBlockHeight = function(height) { + $.checkArgument(_.isNumber(height)); + if (height >= Transaction.NLOCKTIME_BLOCKHEIGHT_LIMIT) { + throw new errors.Transaction.BlockHeightTooHigh(); + } + if (height < 0) { + throw new errors.Transaction.NLockTimeOutOfRange(); + } + + for (var i = 0; i < this.inputs.length; i++) { + if (this.inputs[i].sequenceNumber === Input.DEFAULT_SEQNUMBER){ + this.inputs[i].sequenceNumber = Input.DEFAULT_LOCKTIME_SEQNUMBER; + } + } + + + this.nLockTime = height; + return this; }; -Transaction.prototype.toJSON = function toJSON() { - return JSON.stringify(this.toObject()); +/** + * Returns a semantic version of the transaction's nLockTime. + * @return {Number|Date} + * If nLockTime is 0, it returns null, + * if it is < 500000000, it returns a block height (number) + * else it returns a Date object. + */ +Transaction.prototype.getLockTime = function() { + if (!this.nLockTime) { + return null; + } + if (this.nLockTime < Transaction.NLOCKTIME_BLOCKHEIGHT_LIMIT) { + return this.nLockTime; + } + return new Date(1000 * this.nLockTime); }; Transaction.prototype.fromString = function(string) { @@ -8316,6 +9482,8 @@ Transaction.prototype._fromNonP2SH = function(utxo) { utxo = new UnspentOutput(utxo); if (utxo.script.isPublicKeyHashOut()) { clazz = PublicKeyHashInput; + } else if (utxo.script.isPublicKeyOut()) { + clazz = PublicKeyInput; } else { clazz = Input; } @@ -8326,12 +9494,13 @@ Transaction.prototype._fromNonP2SH = function(utxo) { }), prevTxId: utxo.txId, outputIndex: utxo.outputIndex, - sequenceNumber: DEFAULT_SEQNUMBER, script: Script.empty() })); }; Transaction.prototype._fromMultisigUtxo = function(utxo, pubkeys, threshold) { + $.checkArgument(threshold <= pubkeys.length, + 'Number of required signatures must be greater than the number of public keys'); utxo = new UnspentOutput(utxo); this.addInput(new MultiSigScriptHashInput({ output: new Output({ @@ -8340,7 +9509,6 @@ Transaction.prototype._fromMultisigUtxo = function(utxo, pubkeys, threshold) { }), prevTxId: utxo.txId, outputIndex: utxo.outputIndex, - sequenceNumber: DEFAULT_SEQNUMBER, script: Script.empty() }, pubkeys, threshold)); }; @@ -8381,9 +9549,7 @@ Transaction.prototype.addInput = function(input, outputScript, satoshis) { Transaction.prototype.uncheckedAddInput = function(input) { $.checkArgumentType(input, Input, 'input'); this.inputs.push(input); - if (input.output) { - this._inputAmount += input.output.satoshis; - } + this._inputAmount = undefined; this._updateChangeOutput(); return this; }; @@ -8408,11 +9574,27 @@ Transaction.prototype.hasAllUtxoInfo = function() { * @return {Transaction} this, for chaining */ Transaction.prototype.fee = function(amount) { + $.checkArgument(_.isNumber(amount), 'amount must be a number'); this._fee = amount; this._updateChangeOutput(); return this; }; +/** + * Manually set the fee per KB for this transaction. Beware that this resets all the signatures + * for inputs (in further versions, SIGHASH_SINGLE or SIGHASH_NONE signatures will not + * be reset). + * + * @param {number} amount satoshis per KB to be sent + * @return {Transaction} this, for chaining + */ +Transaction.prototype.feePerKb = function(amount) { + $.checkArgument(_.isNumber(amount), 'amount must be a number'); + this._feePerKb = amount; + this._updateChangeOutput(); + return this; +}; + /* Output management */ /** @@ -8421,15 +9603,27 @@ Transaction.prototype.fee = function(amount) { * Beware that this resets all the signatures for inputs (in further versions, * SIGHASH_SINGLE or SIGHASH_NONE signatures will not be reset). * - * @param {number} amount satoshis to be sent + * @param {Address} address An address for change to be sent to. * @return {Transaction} this, for chaining */ Transaction.prototype.change = function(address) { - this._change = new Address(address); + $.checkArgument(address, 'address is required'); + this._changeScript = Script.fromAddress(address); this._updateChangeOutput(); return this; }; + +/** + * @return {Output} change output, if it exists + */ +Transaction.prototype.getChangeOutput = function() { + if (!_.isUndefined(this._changeIndex)) { + return this.outputs[this._changeIndex]; + } + return null; +}; + /** * Add an output to the transaction. * @@ -8441,6 +9635,10 @@ Transaction.prototype.change = function(address) { * @return {Transaction} this, for chaining */ Transaction.prototype.to = function(address, amount) { + $.checkArgument( + JSUtil.isNaturalNumber(amount), + 'Amount is expected to be a positive integer' + ); this.addOutput(new Output({ script: Script(new Address(address)), satoshis: amount @@ -8466,50 +9664,142 @@ Transaction.prototype.addData = function(value) { return this; }; + +/** + * Add an output to the transaction. + * + * @param {Output} output the output to add. + * @return {Transaction} this, for chaining + */ Transaction.prototype.addOutput = function(output) { $.checkArgumentType(output, Output, 'output'); this._addOutput(output); this._updateChangeOutput(); + return this; }; + +/** + * Remove all outputs from the transaction. + * + * @return {Transaction} this, for chaining + */ +Transaction.prototype.clearOutputs = function() { + this.outputs = []; + this._clearSignatures(); + this._outputAmount = undefined; + this._changeIndex = undefined; + this._updateChangeOutput(); + return this; +}; + + Transaction.prototype._addOutput = function(output) { this.outputs.push(output); - this._outputAmount += output.satoshis; + this._outputAmount = undefined; +}; + + +/** + * Calculates or gets the total output amount in satoshis + * + * @return {Number} the transaction total output amount + */ +Transaction.prototype._getOutputAmount = function() { + if (_.isUndefined(this._outputAmount)) { + var self = this; + this._outputAmount = 0; + _.each(this.outputs, function(output) { + self._outputAmount += output.satoshis; + }); + } + return this._outputAmount; +}; + + +/** + * Calculates or gets the total input amount in satoshis + * + * @return {Number} the transaction total input amount + */ +Transaction.prototype._getInputAmount = function() { + if (_.isUndefined(this._inputAmount)) { + var self = this; + this._inputAmount = 0; + _.each(this.inputs, function(input) { + if (_.isUndefined(input.output)) { + throw new errors.Transaction.Input.MissingPreviousOutput(); + } + self._inputAmount += input.output.satoshis; + }); + } + return this._inputAmount; }; Transaction.prototype._updateChangeOutput = function() { - if (!this._change) { + if (!this._changeScript) { return; } this._clearSignatures(); - if (!_.isUndefined(this._changeOutput)) { - this._removeOutput(this._changeOutput); + if (!_.isUndefined(this._changeIndex)) { + this._removeOutput(this._changeIndex); } var available = this._getUnspentValue(); var fee = this.getFee(); - if (available - fee > 0) { - this._changeOutput = this.outputs.length; + var changeAmount = available - fee; + if (changeAmount > 0) { + this._changeIndex = this.outputs.length; this._addOutput(new Output({ - script: Script.fromAddress(this._change), - satoshis: available - fee + script: this._changeScript, + satoshis: changeAmount })); } else { - this._changeOutput = undefined; + this._changeIndex = undefined; } }; - +/** + * Calculates the fee of the transaction. + * + * If there's a fixed fee set, return that. + * + * If there is no change output set, the fee is the + * total value of the outputs minus inputs. Note that + * a serialized transaction only specifies the value + * of its outputs. (The value of inputs are recorded + * in the previous transaction outputs being spent.) + * This method therefore raises a "MissingPreviousOutput" + * error when called on a serialized transaction. + * + * If there's no fee set and no change address, + * estimate the fee based on size. + * + * @return {Number} fee of this transaction in satoshis + */ Transaction.prototype.getFee = function() { - return this._fee || this._estimateFee(); + if (this.isCoinbase()) { + return 0; + } + if (!_.isUndefined(this._fee)) { + return this._fee; + } + // if no change output is set, fees should equal all the unspent amount + if (!this._changeScript) { + return this._getUnspentValue(); + } + return this._estimateFee(); }; +/** + * Estimates fee from serialized transaction size in bytes. + */ Transaction.prototype._estimateFee = function() { var estimatedSize = this._estimateSize(); var available = this._getUnspentValue(); - return Transaction._estimateFee(estimatedSize, available); + return Transaction._estimateFee(estimatedSize, available, this._feePerKb); }; Transaction.prototype._getUnspentValue = function() { - return this._inputAmount - this._outputAmount; + return this._getInputAmount() - this._getOutputAmount(); }; Transaction.prototype._clearSignatures = function() { @@ -8518,20 +9808,14 @@ Transaction.prototype._clearSignatures = function() { }); }; -Transaction.FEE_PER_KB = 10000; -Transaction.CHANGE_OUTPUT_MAX_SIZE = 20 + 4 + 34 + 4; - -Transaction._estimateFee = function(size, amountAvailable) { - var fee = Math.ceil(size / Transaction.FEE_PER_KB); +Transaction._estimateFee = function(size, amountAvailable, feePerKb) { + var fee = Math.ceil(size / 1000) * (feePerKb || Transaction.FEE_PER_KB); if (amountAvailable > fee) { - // Safe upper bound for change address script size += Transaction.CHANGE_OUTPUT_MAX_SIZE; } - return Math.ceil(size / 1000) * Transaction.FEE_PER_KB; + return Math.ceil(size / 1000) * (feePerKb || Transaction.FEE_PER_KB); }; -Transaction.MAXIMUM_EXTRA_SIZE = 4 + 9 + 9 + 4; - Transaction.prototype._estimateSize = function() { var result = Transaction.MAXIMUM_EXTRA_SIZE; _.each(this.inputs, function(input) { @@ -8545,8 +9829,8 @@ Transaction.prototype._estimateSize = function() { Transaction.prototype._removeOutput = function(index) { var output = this.outputs[index]; - this._outputAmount -= output.satoshis; this.outputs = _.without(this.outputs, output); + this._outputAmount = undefined; }; Transaction.prototype.removeOutput = function(index) { @@ -8554,6 +9838,46 @@ Transaction.prototype.removeOutput = function(index) { this._updateChangeOutput(); }; +/** + * Randomize this transaction's outputs ordering. The shuffling algorithm is a + * version of the Fisher-Yates shuffle, provided by lodash's _.shuffle(). + * + * @return {Transaction} this + */ +Transaction.prototype.shuffleOutputs = function() { + return this.sortOutputs(_.shuffle); +}; + +/** + * Sort this transaction's outputs, according to a given sorting function that + * takes an array as argument and returns a new array, with the same elements + * but with a different order. The argument function MUST NOT modify the order + * of the original array + * + * @param {Function} sortingFunction + * @return {Transaction} this + */ +Transaction.prototype.sortOutputs = function(sortingFunction) { + var outs = sortingFunction(this.outputs); + return this._newOutputOrder(outs); +}; + +Transaction.prototype._newOutputOrder = function(newOutputs) { + var isInvalidSorting = (this.outputs.length !== newOutputs.length || + _.difference(this.outputs, newOutputs).length !== 0); + if (isInvalidSorting) { + throw new errors.Transaction.InvalidSorting(); + } + + if (!_.isUndefined(this._changeIndex)) { + var changeOutput = this.outputs[this._changeIndex]; + this._changeIndex = _.findIndex(newOutputs, changeOutput); + } + + this.outputs = newOutputs; + return this; +}; + Transaction.prototype.removeInput = function(txId, outputIndex) { var index; if (!outputIndex && _.isNumber(txId)) { @@ -8567,8 +9891,8 @@ Transaction.prototype.removeInput = function(txId, outputIndex) { throw new errors.Transaction.InvalidIndex(index, this.inputs.length); } var input = this.inputs[index]; - this._inputAmount -= input.output.satoshis; this.inputs = _.without(this.inputs, input); + this._inputAmount = undefined; this._updateChangeOutput(); }; @@ -8675,28 +9999,28 @@ Transaction.prototype.verify = function() { return 'transaction txouts empty'; } - // Size limits - if (this.toBuffer().length > Block.MAX_BLOCK_SIZE) { - return 'transaction over the maximum block size'; - } - // Check for negative or overflow output values var valueoutbn = new BN(0); for (var i = 0; i < this.outputs.length; i++) { var txout = this.outputs[i]; - var valuebn = txout._satoshisBN; - if (valuebn.lt(BN.Zero)) { - return 'transaction txout ' + i + ' negative'; + + if (txout.invalidSatoshis()) { + return 'transaction txout ' + i + ' satoshis is invalid'; } - if (valuebn.gt(new BN(Transaction.MAX_MONEY, 10))) { + if (txout._satoshisBN.gt(new BN(Transaction.MAX_MONEY, 10))) { return 'transaction txout ' + i + ' greater than MAX_MONEY'; } - valueoutbn = valueoutbn.add(valuebn); + valueoutbn = valueoutbn.add(txout._satoshisBN); if (valueoutbn.gt(new BN(Transaction.MAX_MONEY))) { return 'transaction txout ' + i + ' total output greater than MAX_MONEY'; } } + // Size limits + if (this.toBuffer().length > MAX_BLOCK_SIZE) { + return 'transaction over the maximum block size'; + } + // Check for duplicate inputs var txinmap = {}; for (i = 0; i < this.inputs.length; i++) { @@ -8711,14 +10035,14 @@ Transaction.prototype.verify = function() { var isCoinbase = this.isCoinbase(); if (isCoinbase) { - var buf = this.inputs[0]._script.toBuffer(); + var buf = this.inputs[0]._scriptBuffer; if (buf.length < 2 || buf.length > 100) { - return 'coinbase trasaction script size invalid'; + return 'coinbase transaction script size invalid'; } } else { for (i = 0; i < this.inputs.length; i++) { if (this.inputs[i].isNull()) { - return 'tranasction input ' + i + ' has null input'; + return 'transaction input ' + i + ' has null input'; } } } @@ -8735,7 +10059,7 @@ Transaction.prototype.isCoinbase = function() { module.exports = Transaction; -},{"../address":1,"../block":2,"../crypto/bn":4,"../crypto/hash":6,"../crypto/signature":9,"../encoding/bufferreader":12,"../encoding/bufferwriter":13,"../errors":15,"../privatekey":22,"../script":24,"../util/buffer":38,"../util/js":39,"../util/preconditions":40,"./input":28,"./output":32,"./sighash":33,"./unspentoutput":35,"buffer":42,"lodash":230}],35:[function(require,module,exports){ +},{"../address":1,"../crypto/bn":6,"../crypto/hash":8,"../crypto/signature":11,"../encoding/bufferreader":14,"../encoding/bufferwriter":15,"../errors":17,"../privatekey":24,"../script":26,"../util/buffer":42,"../util/js":43,"../util/preconditions":44,"./input":30,"./output":35,"./sighash":36,"./unspentoutput":39,"buffer":47,"lodash":241}],39:[function(require,module,exports){ 'use strict'; var _ = require('lodash'); @@ -8813,30 +10137,19 @@ UnspentOutput.prototype.toString = function() { }; /** - * Deserialize an UnspentOutput from an object or JSON string + * Deserialize an UnspentOutput from an object * @param {object|string} data * @return UnspentOutput */ -UnspentOutput.fromJSON = UnspentOutput.fromObject = function(data) { - if (JSUtil.isValidJSON(data)) { - data = JSON.parse(data); - } +UnspentOutput.fromObject = function(data) { return new UnspentOutput(data); }; -/** - * Retrieve a string representation of this object - * @return {string} - */ -UnspentOutput.prototype.toJSON = function() { - return JSON.stringify(this.toObject()); -}; - /** * Returns a plain object (no prototype or methods) with the associated infor for this output * @return {object} */ -UnspentOutput.prototype.toObject = function() { +UnspentOutput.prototype.toObject = UnspentOutput.prototype.toJSON = function toObject() { return { address: this.address ? this.address.toString() : undefined, txid: this.txId, @@ -8848,13 +10161,13 @@ UnspentOutput.prototype.toObject = function() { module.exports = UnspentOutput; -},{"../address":1,"../script":24,"../unit":36,"../util/js":39,"../util/preconditions":40,"lodash":230}],36:[function(require,module,exports){ +},{"../address":1,"../script":26,"../unit":40,"../util/js":43,"../util/preconditions":44,"lodash":241}],40:[function(require,module,exports){ 'use strict'; var _ = require('lodash'); var errors = require('./errors'); -var JSUtil = require('./util/js'); +var $ = require('./util/preconditions'); var UNITS = { 'BTC' : [1e8, 8], @@ -8925,11 +10238,9 @@ Object.keys(UNITS).forEach(function(key) { * @param {String|Object} json - JSON with keys: amount and code * @returns {Unit} A Unit instance */ -Unit.fromJSON = function fromJSON(json){ - if (JSUtil.isValidJSON(json)) { - json = JSON.parse(json); - } - return new Unit(json.amount, json.code); +Unit.fromObject = function fromObject(data){ + $.checkArgument(_.isObject(data), 'Argument is expected to be an object'); + return new Unit(data.amount, data.code); }; /** @@ -9061,7 +10372,7 @@ Unit.prototype.atRate = function(rate) { /** * Returns a the string representation of the value in satoshis * - * @returns {String} the value in satoshis + * @returns {string} the value in satoshis */ Unit.prototype.toString = function() { return this.satoshis + ' satoshis'; @@ -9072,21 +10383,17 @@ Unit.prototype.toString = function() { * * @returns {Object} An object with the keys: amount and code */ -Unit.prototype.toObject = function toObject() { +Unit.prototype.toObject = Unit.prototype.toJSON = function toObject() { return { amount: this.BTC, code: Unit.BTC }; }; -Unit.prototype.toJSON = function toJSON() { - return JSON.stringify(this.toObject()); -}; - /** * Returns a string formatted for the console * - * @returns {String} the value in satoshis + * @returns {string} the value in satoshis */ Unit.prototype.inspect = function() { return ''; @@ -9094,7 +10401,7 @@ Unit.prototype.inspect = function() { module.exports = Unit; -},{"./errors":15,"./util/js":39,"lodash":230}],37:[function(require,module,exports){ +},{"./errors":17,"./util/preconditions":44,"lodash":241}],41:[function(require,module,exports){ 'use strict'; var _ = require('lodash'); @@ -9102,7 +10409,6 @@ var URL = require('url'); var Address = require('./address'); var Unit = require('./unit'); -var JSUtil = require('./util/js'); /** * Bitcore URI @@ -9123,7 +10429,7 @@ var JSUtil = require('./util/js'); * ``` * * @param {string|Object} data - A bitcoin URI string or an Object - * @param {Array.} [knownParams] - Required non-standard params + * @param {Array.=} knownParams - Required non-standard params * @throws {TypeError} Invalid bitcoin address * @throws {TypeError} Invalid amount * @throws {Error} Unknown required argument @@ -9155,7 +10461,7 @@ var URI = function(data, knownParams) { /** * Instantiate a URI from a String * - * @param {String} str - JSON string or object of the URI + * @param {string} str - JSON string or object of the URI * @returns {URI} A new instance of a URI */ URI.fromString = function fromString(str) { @@ -9166,15 +10472,12 @@ URI.fromString = function fromString(str) { }; /** - * Instantiate a URI from JSON + * Instantiate a URI from an Object * - * @param {String|Object} json - JSON string or object of the URI + * @param {Object} data - object of the URI * @returns {URI} A new instance of a URI */ -URI.fromJSON = function fromJSON(json) { - if (JSUtil.isValidJSON(json)) { - json = JSON.parse(json); - } +URI.fromObject = function fromObject(json) { return new URI(json); }; @@ -9189,7 +10492,7 @@ URI.fromJSON = function fromJSON(json) { * ``` * * @param {string|Object} data - A bitcoin URI string or an Object - * @param {Array.} [knownParams] - Required non-standard params + * @param {Array.=} knownParams - Required non-standard params * @returns {boolean} Result of uri validation */ URI.isValid = function(arg, knownParams) { @@ -9260,7 +10563,7 @@ URI.prototype._fromObject = function(obj) { /** * Internal function to transform a BTC string amount into satoshis * - * @param {String} amount - Amount BTC string + * @param {string} amount - Amount BTC string * @throws {TypeError} Invalid amount * @returns {Object} Amount represented in satoshis */ @@ -9272,7 +10575,7 @@ URI.prototype._parseAmount = function(amount) { return Unit.fromBTC(amount).toSatoshis(); }; -URI.prototype.toObject = function toObject() { +URI.prototype.toObject = URI.prototype.toJSON = function toObject() { var json = {}; for (var i = 0; i < URI.Members.length; i++) { var m = URI.Members[i]; @@ -9284,14 +10587,10 @@ URI.prototype.toObject = function toObject() { return json; }; -URI.prototype.toJSON = function toJSON() { - return JSON.stringify(this.toObject()); -}; - /** * Will return a the string representation of the URI * - * @returns {String} Bitcoin URI string + * @returns {string} Bitcoin URI string */ URI.prototype.toString = function() { var query = {}; @@ -9319,7 +10618,7 @@ URI.prototype.toString = function() { /** * Will return a string formatted for the console * - * @returns {String} Bitcoin URI + * @returns {string} Bitcoin URI */ URI.prototype.inspect = function() { return ''; @@ -9327,7 +10626,7 @@ URI.prototype.inspect = function() { module.exports = URI; -},{"./address":1,"./unit":36,"./util/js":39,"lodash":230,"url":202}],38:[function(require,module,exports){ +},{"./address":1,"./unit":40,"lodash":241,"url":212}],42:[function(require,module,exports){ (function (Buffer){ 'use strict'; @@ -9483,7 +10782,6 @@ module.exports = { * @return {Buffer} */ reverse: function reverse(param) { - $.checkArgumentType(param, 'Buffer', 'param'); var ret = new buffer.Buffer(param.length); for (var i = 0; i < param.length; i++) { ret[i] = param[param.length - i - 1]; @@ -9509,7 +10807,7 @@ module.exports.NULL_HASH = module.exports.fill(new Buffer(32), 0); module.exports.EMPTY_BUFFER = new Buffer(0); }).call(this,require("buffer").Buffer) -},{"./js":39,"./preconditions":40,"assert":41,"buffer":42}],39:[function(require,module,exports){ +},{"./js":43,"./preconditions":44,"assert":45,"buffer":47}],43:[function(require,module,exports){ 'use strict'; var _ = require('lodash'); @@ -9541,6 +10839,9 @@ module.exports = { */ isValidJSON: function isValidJSON(arg) { var parsed; + if (!_.isString(arg)) { + return false; + } try { parsed = JSON.parse(arg); } catch (e) { @@ -9568,7 +10869,7 @@ module.exports = { * @param {Object} values - An object of properties * @return {Object} The target object */ - defineImmutable: function defineImmutable(target, values){ + defineImmutable: function defineImmutable(target, values) { Object.keys(values).forEach(function(key){ Object.defineProperty(target, key, { configurable: false, @@ -9577,10 +10878,22 @@ module.exports = { }); }); return target; + }, + /** + * Checks that a value is a natural number, a positive integer or zero. + * + * @param {*} value + * @return {Boolean} + */ + isNaturalNumber: function isNaturalNumber(value) { + return typeof value === 'number' && + isFinite(value) && + Math.floor(value) === value && + value >= 0; } }; -},{"lodash":230}],40:[function(require,module,exports){ +},{"lodash":241}],44:[function(require,module,exports){ 'use strict'; var errors = require('../errors'); @@ -9592,9 +10905,9 @@ module.exports = { throw new errors.InvalidState(message); } }, - checkArgument: function(condition, argumentName, message) { + checkArgument: function(condition, argumentName, message, docsPath) { if (!condition) { - throw new errors.InvalidArgument(argumentName, message); + throw new errors.InvalidArgument(argumentName, message, docsPath); } }, checkArgumentType: function(argument, type, argumentName) { @@ -9616,7 +10929,7 @@ module.exports = { } }; -},{"../errors":15,"./buffer":38,"lodash":230}],41:[function(require,module,exports){ +},{"../errors":17,"./buffer":42,"lodash":241}],45:[function(require,module,exports){ // http://wiki.commonjs.org/wiki/Unit_Testing/1.0 // // THIS IS NOT TESTED NOR LIKELY TO WORK OUTSIDE V8! @@ -9978,7 +11291,9 @@ var objectKeys = Object.keys || function (obj) { return keys; }; -},{"util/":204}],42:[function(require,module,exports){ +},{"util/":214}],46:[function(require,module,exports){ + +},{}],47:[function(require,module,exports){ /*! * The buffer module from node.js, for the browser. * @@ -11032,7 +12347,7 @@ function decodeUtf8Char (str) { } } -},{"base64-js":43,"ieee754":44,"is-array":45}],43:[function(require,module,exports){ +},{"base64-js":48,"ieee754":49,"is-array":50}],48:[function(require,module,exports){ var lookup = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'; ;(function (exports) { @@ -11154,93 +12469,93 @@ var lookup = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'; exports.fromByteArray = uint8ToBase64 }(typeof exports === 'undefined' ? (this.base64js = {}) : exports)) -},{}],44:[function(require,module,exports){ -exports.read = function(buffer, offset, isLE, mLen, nBytes) { - var e, m, - eLen = nBytes * 8 - mLen - 1, - eMax = (1 << eLen) - 1, - eBias = eMax >> 1, - nBits = -7, - i = isLE ? (nBytes - 1) : 0, - d = isLE ? -1 : 1, - s = buffer[offset + i]; - - i += d; - - e = s & ((1 << (-nBits)) - 1); - s >>= (-nBits); - nBits += eLen; - for (; nBits > 0; e = e * 256 + buffer[offset + i], i += d, nBits -= 8); - - m = e & ((1 << (-nBits)) - 1); - e >>= (-nBits); - nBits += mLen; - for (; nBits > 0; m = m * 256 + buffer[offset + i], i += d, nBits -= 8); +},{}],49:[function(require,module,exports){ +exports.read = function (buffer, offset, isLE, mLen, nBytes) { + var e, m + var eLen = nBytes * 8 - mLen - 1 + var eMax = (1 << eLen) - 1 + var eBias = eMax >> 1 + var nBits = -7 + var i = isLE ? (nBytes - 1) : 0 + var d = isLE ? -1 : 1 + var s = buffer[offset + i] + + i += d + + e = s & ((1 << (-nBits)) - 1) + s >>= (-nBits) + nBits += eLen + for (; nBits > 0; e = e * 256 + buffer[offset + i], i += d, nBits -= 8) {} + + m = e & ((1 << (-nBits)) - 1) + e >>= (-nBits) + nBits += mLen + for (; nBits > 0; m = m * 256 + buffer[offset + i], i += d, nBits -= 8) {} if (e === 0) { - e = 1 - eBias; + e = 1 - eBias } else if (e === eMax) { - return m ? NaN : ((s ? -1 : 1) * Infinity); + return m ? NaN : ((s ? -1 : 1) * Infinity) } else { - m = m + Math.pow(2, mLen); - e = e - eBias; + m = m + Math.pow(2, mLen) + e = e - eBias } - return (s ? -1 : 1) * m * Math.pow(2, e - mLen); -}; + return (s ? -1 : 1) * m * Math.pow(2, e - mLen) +} -exports.write = function(buffer, value, offset, isLE, mLen, nBytes) { - var e, m, c, - eLen = nBytes * 8 - mLen - 1, - eMax = (1 << eLen) - 1, - eBias = eMax >> 1, - rt = (mLen === 23 ? Math.pow(2, -24) - Math.pow(2, -77) : 0), - i = isLE ? 0 : (nBytes - 1), - d = isLE ? 1 : -1, - s = value < 0 || (value === 0 && 1 / value < 0) ? 1 : 0; +exports.write = function (buffer, value, offset, isLE, mLen, nBytes) { + var e, m, c + var eLen = nBytes * 8 - mLen - 1 + var eMax = (1 << eLen) - 1 + var eBias = eMax >> 1 + var rt = (mLen === 23 ? Math.pow(2, -24) - Math.pow(2, -77) : 0) + var i = isLE ? 0 : (nBytes - 1) + var d = isLE ? 1 : -1 + var s = value < 0 || (value === 0 && 1 / value < 0) ? 1 : 0 - value = Math.abs(value); + value = Math.abs(value) if (isNaN(value) || value === Infinity) { - m = isNaN(value) ? 1 : 0; - e = eMax; + m = isNaN(value) ? 1 : 0 + e = eMax } else { - e = Math.floor(Math.log(value) / Math.LN2); + e = Math.floor(Math.log(value) / Math.LN2) if (value * (c = Math.pow(2, -e)) < 1) { - e--; - c *= 2; + e-- + c *= 2 } if (e + eBias >= 1) { - value += rt / c; + value += rt / c } else { - value += rt * Math.pow(2, 1 - eBias); + value += rt * Math.pow(2, 1 - eBias) } if (value * c >= 2) { - e++; - c /= 2; + e++ + c /= 2 } if (e + eBias >= eMax) { - m = 0; - e = eMax; + m = 0 + e = eMax } else if (e + eBias >= 1) { - m = (value * c - 1) * Math.pow(2, mLen); - e = e + eBias; + m = (value * c - 1) * Math.pow(2, mLen) + e = e + eBias } else { - m = value * Math.pow(2, eBias - 1) * Math.pow(2, mLen); - e = 0; + m = value * Math.pow(2, eBias - 1) * Math.pow(2, mLen) + e = 0 } } - for (; mLen >= 8; buffer[offset + i] = m & 0xff, i += d, m /= 256, mLen -= 8); + for (; mLen >= 8; buffer[offset + i] = m & 0xff, i += d, m /= 256, mLen -= 8) {} - e = (e << mLen) | m; - eLen += mLen; - for (; eLen > 0; buffer[offset + i] = e & 0xff, i += d, e /= 256, eLen -= 8); + e = (e << mLen) | m + eLen += mLen + for (; eLen > 0; buffer[offset + i] = e & 0xff, i += d, e /= 256, eLen -= 8) {} - buffer[offset + i - d] |= s * 128; -}; + buffer[offset + i - d] |= s * 128 +} -},{}],45:[function(require,module,exports){ +},{}],50:[function(require,module,exports){ /** * isArray @@ -11275,26 +12590,24 @@ module.exports = isArray || function (val) { return !! val && '[object Array]' == str.call(val); }; -},{}],46:[function(require,module,exports){ -'use strict'; +},{}],51:[function(require,module,exports){ +'use strict' exports.randomBytes = exports.rng = exports.pseudoRandomBytes = exports.prng = require('randombytes') - exports.createHash = exports.Hash = require('create-hash') - exports.createHmac = exports.Hmac = require('create-hmac') var hashes = ['sha1', 'sha224', 'sha256', 'sha384', 'sha512', 'md5', 'rmd160'].concat(Object.keys(require('browserify-sign/algos'))) exports.getHashes = function () { - return hashes; + return hashes } -var p = require('pbkdf2-compat') +var p = require('pbkdf2') exports.pbkdf2 = p.pbkdf2 exports.pbkdf2Sync = p.pbkdf2Sync -var aes = require('browserify-aes'); -[ +var aes = require('browserify-cipher') +;[ 'Cipher', 'createCipher', 'Cipheriv', @@ -11306,105 +12619,132 @@ var aes = require('browserify-aes'); 'getCiphers', 'listCiphers' ].forEach(function (key) { - exports[key] = aes[key]; + exports[key] = aes[key] }) -var dh = require('diffie-hellman'); -[ +var dh = require('diffie-hellman') +;[ 'DiffieHellmanGroup', 'createDiffieHellmanGroup', 'getDiffieHellman', 'createDiffieHellman', 'DiffieHellman' ].forEach(function (key) { - exports[key] = dh[key]; + exports[key] = dh[key] +}) + +var sign = require('browserify-sign') +;[ + 'createSign', + 'Sign', + 'createVerify', + 'Verify' +].forEach(function (key) { + exports[key] = sign[key] }) -require('browserify-sign/inject')(module.exports, exports); -require('create-ecdh/inject')(module.exports, exports); -require('public-encrypt/inject')(module.exports, exports); +exports.createECDH = require('create-ecdh') -// the least I can do is make error messages for the rest of the node.js/crypto api. -[ - 'createCredentials', +var publicEncrypt = require('public-encrypt') + +;[ + 'publicEncrypt', 'privateEncrypt', - 'publicDecrypt' + 'publicDecrypt', + 'privateDecrypt' +].forEach(function (key) { + exports[key] = publicEncrypt[key] +}) + +// the least I can do is make error messages for the rest of the node.js/crypto api. +;[ + 'createCredentials' ].forEach(function (name) { exports[name] = function () { throw new Error([ 'sorry, ' + name + ' is not implemented yet', 'we accept pull requests', 'https://github.com/crypto-browserify/crypto-browserify' - ].join('\n')); + ].join('\n')) } }) -},{"browserify-aes":50,"browserify-sign/algos":65,"browserify-sign/inject":66,"create-ecdh/inject":112,"create-hash":134,"create-hmac":145,"diffie-hellman":146,"pbkdf2-compat":153,"public-encrypt/inject":154,"randombytes":181}],47:[function(require,module,exports){ -(function (Buffer){ -var md5 = require('create-hash/md5'); -module.exports = EVP_BytesToKey; -function EVP_BytesToKey(password, keyLen, ivLen) { - if (!Buffer.isBuffer(password)) { - password = new Buffer(password, 'binary'); - } - keyLen = keyLen/8; - ivLen = ivLen || 0; - var ki = 0; - var ii = 0; - var key = new Buffer(keyLen); - var iv = new Buffer(ivLen); - var addmd = 0; - var md_buf; - var i; - var bufs = []; - while (true) { - if(addmd++ > 0) { - bufs.push(md_buf); - } - bufs.push(password); - md_buf = md5(Buffer.concat(bufs)); - bufs = []; - i = 0; - if(keyLen > 0) { - while(true) { - if(keyLen === 0) { - break; - } - if(i === md_buf.length) { - break; - } - key[ki++] = md_buf[i]; - keyLen--; - i++; - } - } - if(ivLen > 0 && i !== md_buf.length) { - while(true) { - if(ivLen === 0) { - break; - } - if(i === md_buf.length) { - break; - } - iv[ii++] = md_buf[i]; - ivLen--; - i++; - } - } - if(keyLen === 0 && ivLen === 0) { - break; - } +},{"browserify-cipher":52,"browserify-sign":82,"browserify-sign/algos":81,"create-ecdh":124,"create-hash":125,"create-hmac":138,"diffie-hellman":139,"pbkdf2":145,"public-encrypt":146,"randombytes":190}],52:[function(require,module,exports){ +var ebtk = require('evp_bytestokey') +var aes = require('browserify-aes/browser') +var DES = require('browserify-des') +var desModes = require('browserify-des/modes') +var aesModes = require('browserify-aes/modes') +function createCipher (suite, password) { + var keyLen, ivLen + suite = suite.toLowerCase() + if (aesModes[suite]) { + keyLen = aesModes[suite].key + ivLen = aesModes[suite].iv + } else if (desModes[suite]) { + keyLen = desModes[suite].key * 8 + ivLen = desModes[suite].iv + } else { + throw new TypeError('invalid suite type') } - for(i=0;i uint_max || x < 0 ? (x_pos = Math.abs(x) % uint_max, x < 0 ? uint_max - x_pos : x_pos) : x; - return ret; +var uint_max = Math.pow(2, 32) +function fixup_uint32 (x) { + var ret, x_pos + ret = x > uint_max || x < 0 ? (x_pos = Math.abs(x) % uint_max, x < 0 ? uint_max - x_pos : x_pos) : x + return ret } -function scrub_vec(v) { - var i, _i, _ref; - for (i = _i = 0, _ref = v.length; 0 <= _ref ? _i < _ref : _i > _ref; i = 0 <= _ref ? ++_i : --_i) { - v[i] = 0; +function scrub_vec (v) { + for (var i = 0; i < v.length; v++) { + v[i] = 0 } - return false; + return false } -function Global() { - var i; - this.SBOX = []; - this.INV_SBOX = []; - this.SUB_MIX = (function() { - var _i, _results; - _results = []; - for (i = _i = 0; _i < 4; i = ++_i) { - _results.push([]); - } - return _results; - })(); - this.INV_SUB_MIX = (function() { - var _i, _results; - _results = []; - for (i = _i = 0; _i < 4; i = ++_i) { - _results.push([]); - } - return _results; - })(); - this.init(); - this.RCON = [0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36]; -} - -Global.prototype.init = function() { - var d, i, sx, t, x, x2, x4, x8, xi, _i; - d = (function() { - var _i, _results; - _results = []; +function Global () { + this.SBOX = [] + this.INV_SBOX = [] + this.SUB_MIX = [[], [], [], []] + this.INV_SUB_MIX = [[], [], [], []] + this.init() + this.RCON = [0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36] +} + +Global.prototype.init = function () { + var d, i, sx, t, x, x2, x4, x8, xi, _i + d = (function () { + var _i, _results + _results = [] for (i = _i = 0; _i < 256; i = ++_i) { if (i < 128) { - _results.push(i << 1); + _results.push(i << 1) } else { - _results.push((i << 1) ^ 0x11b); + _results.push((i << 1) ^ 0x11b) } } - return _results; - })(); - x = 0; - xi = 0; + return _results + })() + x = 0 + xi = 0 for (i = _i = 0; _i < 256; i = ++_i) { - sx = xi ^ (xi << 1) ^ (xi << 2) ^ (xi << 3) ^ (xi << 4); - sx = (sx >>> 8) ^ (sx & 0xff) ^ 0x63; - this.SBOX[x] = sx; - this.INV_SBOX[sx] = x; - x2 = d[x]; - x4 = d[x2]; - x8 = d[x4]; - t = (d[sx] * 0x101) ^ (sx * 0x1010100); - this.SUB_MIX[0][x] = (t << 24) | (t >>> 8); - this.SUB_MIX[1][x] = (t << 16) | (t >>> 16); - this.SUB_MIX[2][x] = (t << 8) | (t >>> 24); - this.SUB_MIX[3][x] = t; - t = (x8 * 0x1010101) ^ (x4 * 0x10001) ^ (x2 * 0x101) ^ (x * 0x1010100); - this.INV_SUB_MIX[0][sx] = (t << 24) | (t >>> 8); - this.INV_SUB_MIX[1][sx] = (t << 16) | (t >>> 16); - this.INV_SUB_MIX[2][sx] = (t << 8) | (t >>> 24); - this.INV_SUB_MIX[3][sx] = t; + sx = xi ^ (xi << 1) ^ (xi << 2) ^ (xi << 3) ^ (xi << 4) + sx = (sx >>> 8) ^ (sx & 0xff) ^ 0x63 + this.SBOX[x] = sx + this.INV_SBOX[sx] = x + x2 = d[x] + x4 = d[x2] + x8 = d[x4] + t = (d[sx] * 0x101) ^ (sx * 0x1010100) + this.SUB_MIX[0][x] = (t << 24) | (t >>> 8) + this.SUB_MIX[1][x] = (t << 16) | (t >>> 16) + this.SUB_MIX[2][x] = (t << 8) | (t >>> 24) + this.SUB_MIX[3][x] = t + t = (x8 * 0x1010101) ^ (x4 * 0x10001) ^ (x2 * 0x101) ^ (x * 0x1010100) + this.INV_SUB_MIX[0][sx] = (t << 24) | (t >>> 8) + this.INV_SUB_MIX[1][sx] = (t << 16) | (t >>> 16) + this.INV_SUB_MIX[2][sx] = (t << 8) | (t >>> 24) + this.INV_SUB_MIX[3][sx] = t if (x === 0) { - x = xi = 1; + x = xi = 1 } else { - x = x2 ^ d[d[d[x8 ^ x2]]]; - xi ^= d[d[xi]]; + x = x2 ^ d[d[d[x8 ^ x2]]] + xi ^= d[d[xi]] } } - return true; -}; - -var G = new Global(); + return true +} +var G = new Global() -AES.blockSize = 4 * 4; +AES.blockSize = 4 * 4 -AES.prototype.blockSize = AES.blockSize; +AES.prototype.blockSize = AES.blockSize -AES.keySize = 256 / 8; +AES.keySize = 256 / 8 -AES.prototype.keySize = AES.keySize; +AES.prototype.keySize = AES.keySize - function bufferToArray(buf) { - var len = buf.length/4; - var out = new Array(len); - var i = -1; +function bufferToArray (buf) { + var len = buf.length / 4 + var out = new Array(len) + var i = -1 while (++i < len) { - out[i] = buf.readUInt32BE(i * 4); + out[i] = buf.readUInt32BE(i * 4) } - return out; - } -function AES(key) { - this._key = bufferToArray(key); - this._doReset(); -} - -AES.prototype._doReset = function() { - var invKsRow, keySize, keyWords, ksRow, ksRows, t, _i, _j; - keyWords = this._key; - keySize = keyWords.length; - this._nRounds = keySize + 6; - ksRows = (this._nRounds + 1) * 4; - this._keySchedule = []; - for (ksRow = _i = 0; 0 <= ksRows ? _i < ksRows : _i > ksRows; ksRow = 0 <= ksRows ? ++_i : --_i) { - this._keySchedule[ksRow] = ksRow < keySize ? keyWords[ksRow] : (t = this._keySchedule[ksRow - 1], (ksRow % keySize) === 0 ? (t = (t << 8) | (t >>> 24), t = (G.SBOX[t >>> 24] << 24) | (G.SBOX[(t >>> 16) & 0xff] << 16) | (G.SBOX[(t >>> 8) & 0xff] << 8) | G.SBOX[t & 0xff], t ^= G.RCON[(ksRow / keySize) | 0] << 24) : keySize > 6 && ksRow % keySize === 4 ? t = (G.SBOX[t >>> 24] << 24) | (G.SBOX[(t >>> 16) & 0xff] << 16) | (G.SBOX[(t >>> 8) & 0xff] << 8) | G.SBOX[t & 0xff] : void 0, this._keySchedule[ksRow - keySize] ^ t); - } - this._invKeySchedule = []; - for (invKsRow = _j = 0; 0 <= ksRows ? _j < ksRows : _j > ksRows; invKsRow = 0 <= ksRows ? ++_j : --_j) { - ksRow = ksRows - invKsRow; - t = this._keySchedule[ksRow - (invKsRow % 4 ? 0 : 4)]; - this._invKeySchedule[invKsRow] = invKsRow < 4 || ksRow <= 4 ? t : G.INV_SUB_MIX[0][G.SBOX[t >>> 24]] ^ G.INV_SUB_MIX[1][G.SBOX[(t >>> 16) & 0xff]] ^ G.INV_SUB_MIX[2][G.SBOX[(t >>> 8) & 0xff]] ^ G.INV_SUB_MIX[3][G.SBOX[t & 0xff]]; - } - return true; -}; - -AES.prototype.encryptBlock = function(M) { - M = bufferToArray(new Buffer(M)); - var out = this._doCryptBlock(M, this._keySchedule, G.SUB_MIX, G.SBOX); - var buf = new Buffer(16); - buf.writeUInt32BE(out[0], 0); - buf.writeUInt32BE(out[1], 4); - buf.writeUInt32BE(out[2], 8); - buf.writeUInt32BE(out[3], 12); - return buf; -}; + return out +} +function AES (key) { + this._key = bufferToArray(key) + this._doReset() +} + +AES.prototype._doReset = function () { + var invKsRow, keySize, keyWords, ksRow, ksRows, t + keyWords = this._key + keySize = keyWords.length + this._nRounds = keySize + 6 + ksRows = (this._nRounds + 1) * 4 + this._keySchedule = [] + for (ksRow = 0; ksRow < ksRows; ksRow++) { + this._keySchedule[ksRow] = ksRow < keySize ? keyWords[ksRow] : (t = this._keySchedule[ksRow - 1], (ksRow % keySize) === 0 ? (t = (t << 8) | (t >>> 24), t = (G.SBOX[t >>> 24] << 24) | (G.SBOX[(t >>> 16) & 0xff] << 16) | (G.SBOX[(t >>> 8) & 0xff] << 8) | G.SBOX[t & 0xff], t ^= G.RCON[(ksRow / keySize) | 0] << 24) : keySize > 6 && ksRow % keySize === 4 ? t = (G.SBOX[t >>> 24] << 24) | (G.SBOX[(t >>> 16) & 0xff] << 16) | (G.SBOX[(t >>> 8) & 0xff] << 8) | G.SBOX[t & 0xff] : void 0, this._keySchedule[ksRow - keySize] ^ t) + } + this._invKeySchedule = [] + for (invKsRow = 0; invKsRow < ksRows; invKsRow++) { + ksRow = ksRows - invKsRow + t = this._keySchedule[ksRow - (invKsRow % 4 ? 0 : 4)] + this._invKeySchedule[invKsRow] = invKsRow < 4 || ksRow <= 4 ? t : G.INV_SUB_MIX[0][G.SBOX[t >>> 24]] ^ G.INV_SUB_MIX[1][G.SBOX[(t >>> 16) & 0xff]] ^ G.INV_SUB_MIX[2][G.SBOX[(t >>> 8) & 0xff]] ^ G.INV_SUB_MIX[3][G.SBOX[t & 0xff]] + } + return true +} + +AES.prototype.encryptBlock = function (M) { + M = bufferToArray(new Buffer(M)) + var out = this._doCryptBlock(M, this._keySchedule, G.SUB_MIX, G.SBOX) + var buf = new Buffer(16) + buf.writeUInt32BE(out[0], 0) + buf.writeUInt32BE(out[1], 4) + buf.writeUInt32BE(out[2], 8) + buf.writeUInt32BE(out[3], 12) + return buf +} -AES.prototype.decryptBlock = function(M) { - M = bufferToArray(new Buffer(M)); - var temp = [M[3], M[1]]; - M[1] = temp[0]; - M[3] = temp[1]; - var out = this._doCryptBlock(M, this._invKeySchedule, G.INV_SUB_MIX, G.INV_SBOX); - var buf = new Buffer(16); - buf.writeUInt32BE(out[0], 0); - buf.writeUInt32BE(out[3], 4); - buf.writeUInt32BE(out[2], 8); - buf.writeUInt32BE(out[1], 12); - return buf; -}; +AES.prototype.decryptBlock = function (M) { + M = bufferToArray(new Buffer(M)) + var temp = [M[3], M[1]] + M[1] = temp[0] + M[3] = temp[1] + var out = this._doCryptBlock(M, this._invKeySchedule, G.INV_SUB_MIX, G.INV_SBOX) + var buf = new Buffer(16) + buf.writeUInt32BE(out[0], 0) + buf.writeUInt32BE(out[3], 4) + buf.writeUInt32BE(out[2], 8) + buf.writeUInt32BE(out[1], 12) + return buf +} -AES.prototype.scrub = function() { - scrub_vec(this._keySchedule); - scrub_vec(this._invKeySchedule); - scrub_vec(this._key); -}; - -AES.prototype._doCryptBlock = function(M, keySchedule, SUB_MIX, SBOX) { - var ksRow, round, s0, s1, s2, s3, t0, t1, t2, t3, _i, _ref; - - s0 = M[0] ^ keySchedule[0]; - s1 = M[1] ^ keySchedule[1]; - s2 = M[2] ^ keySchedule[2]; - s3 = M[3] ^ keySchedule[3]; - ksRow = 4; - for (round = _i = 1, _ref = this._nRounds; 1 <= _ref ? _i < _ref : _i > _ref; round = 1 <= _ref ? ++_i : --_i) { - t0 = SUB_MIX[0][s0 >>> 24] ^ SUB_MIX[1][(s1 >>> 16) & 0xff] ^ SUB_MIX[2][(s2 >>> 8) & 0xff] ^ SUB_MIX[3][s3 & 0xff] ^ keySchedule[ksRow++]; - t1 = SUB_MIX[0][s1 >>> 24] ^ SUB_MIX[1][(s2 >>> 16) & 0xff] ^ SUB_MIX[2][(s3 >>> 8) & 0xff] ^ SUB_MIX[3][s0 & 0xff] ^ keySchedule[ksRow++]; - t2 = SUB_MIX[0][s2 >>> 24] ^ SUB_MIX[1][(s3 >>> 16) & 0xff] ^ SUB_MIX[2][(s0 >>> 8) & 0xff] ^ SUB_MIX[3][s1 & 0xff] ^ keySchedule[ksRow++]; - t3 = SUB_MIX[0][s3 >>> 24] ^ SUB_MIX[1][(s0 >>> 16) & 0xff] ^ SUB_MIX[2][(s1 >>> 8) & 0xff] ^ SUB_MIX[3][s2 & 0xff] ^ keySchedule[ksRow++]; - s0 = t0; - s1 = t1; - s2 = t2; - s3 = t3; - } - t0 = ((SBOX[s0 >>> 24] << 24) | (SBOX[(s1 >>> 16) & 0xff] << 16) | (SBOX[(s2 >>> 8) & 0xff] << 8) | SBOX[s3 & 0xff]) ^ keySchedule[ksRow++]; - t1 = ((SBOX[s1 >>> 24] << 24) | (SBOX[(s2 >>> 16) & 0xff] << 16) | (SBOX[(s3 >>> 8) & 0xff] << 8) | SBOX[s0 & 0xff]) ^ keySchedule[ksRow++]; - t2 = ((SBOX[s2 >>> 24] << 24) | (SBOX[(s3 >>> 16) & 0xff] << 16) | (SBOX[(s0 >>> 8) & 0xff] << 8) | SBOX[s1 & 0xff]) ^ keySchedule[ksRow++]; - t3 = ((SBOX[s3 >>> 24] << 24) | (SBOX[(s0 >>> 16) & 0xff] << 16) | (SBOX[(s1 >>> 8) & 0xff] << 8) | SBOX[s2 & 0xff]) ^ keySchedule[ksRow++]; +AES.prototype.scrub = function () { + scrub_vec(this._keySchedule) + scrub_vec(this._invKeySchedule) + scrub_vec(this._key) +} + +AES.prototype._doCryptBlock = function (M, keySchedule, SUB_MIX, SBOX) { + var ksRow, s0, s1, s2, s3, t0, t1, t2, t3 + + s0 = M[0] ^ keySchedule[0] + s1 = M[1] ^ keySchedule[1] + s2 = M[2] ^ keySchedule[2] + s3 = M[3] ^ keySchedule[3] + ksRow = 4 + for (var round = 1; round < this._nRounds; round++) { + t0 = SUB_MIX[0][s0 >>> 24] ^ SUB_MIX[1][(s1 >>> 16) & 0xff] ^ SUB_MIX[2][(s2 >>> 8) & 0xff] ^ SUB_MIX[3][s3 & 0xff] ^ keySchedule[ksRow++] + t1 = SUB_MIX[0][s1 >>> 24] ^ SUB_MIX[1][(s2 >>> 16) & 0xff] ^ SUB_MIX[2][(s3 >>> 8) & 0xff] ^ SUB_MIX[3][s0 & 0xff] ^ keySchedule[ksRow++] + t2 = SUB_MIX[0][s2 >>> 24] ^ SUB_MIX[1][(s3 >>> 16) & 0xff] ^ SUB_MIX[2][(s0 >>> 8) & 0xff] ^ SUB_MIX[3][s1 & 0xff] ^ keySchedule[ksRow++] + t3 = SUB_MIX[0][s3 >>> 24] ^ SUB_MIX[1][(s0 >>> 16) & 0xff] ^ SUB_MIX[2][(s1 >>> 8) & 0xff] ^ SUB_MIX[3][s2 & 0xff] ^ keySchedule[ksRow++] + s0 = t0 + s1 = t1 + s2 = t2 + s3 = t3 + } + t0 = ((SBOX[s0 >>> 24] << 24) | (SBOX[(s1 >>> 16) & 0xff] << 16) | (SBOX[(s2 >>> 8) & 0xff] << 8) | SBOX[s3 & 0xff]) ^ keySchedule[ksRow++] + t1 = ((SBOX[s1 >>> 24] << 24) | (SBOX[(s2 >>> 16) & 0xff] << 16) | (SBOX[(s3 >>> 8) & 0xff] << 8) | SBOX[s0 & 0xff]) ^ keySchedule[ksRow++] + t2 = ((SBOX[s2 >>> 24] << 24) | (SBOX[(s3 >>> 16) & 0xff] << 16) | (SBOX[(s0 >>> 8) & 0xff] << 8) | SBOX[s1 & 0xff]) ^ keySchedule[ksRow++] + t3 = ((SBOX[s3 >>> 24] << 24) | (SBOX[(s0 >>> 16) & 0xff] << 16) | (SBOX[(s1 >>> 8) & 0xff] << 8) | SBOX[s2 & 0xff]) ^ keySchedule[ksRow++] return [ fixup_uint32(t0), fixup_uint32(t1), fixup_uint32(t2), fixup_uint32(t3) - ]; - -}; - - + ] +} +exports.AES = AES - exports.AES = AES; }).call(this,require("buffer").Buffer) -},{"buffer":42}],49:[function(require,module,exports){ +},{"buffer":47}],54:[function(require,module,exports){ (function (Buffer){ -var aes = require('./aes'); -var Transform = require('./cipherBase'); -var inherits = require('inherits'); -var GHASH = require('./ghash'); -var xor = require('./xor'); -inherits(StreamCipher, Transform); -module.exports = StreamCipher; +var aes = require('./aes') +var Transform = require('cipher-base') +var inherits = require('inherits') +var GHASH = require('./ghash') +var xor = require('buffer-xor') +inherits(StreamCipher, Transform) +module.exports = StreamCipher -function StreamCipher(mode, key, iv, decrypt) { +function StreamCipher (mode, key, iv, decrypt) { if (!(this instanceof StreamCipher)) { - return new StreamCipher(mode, key, iv); - } - Transform.call(this); - this._finID = Buffer.concat([iv, new Buffer([0, 0, 0, 1])]); - iv = Buffer.concat([iv, new Buffer([0, 0, 0, 2])]); - this._cipher = new aes.AES(key); - this._prev = new Buffer(iv.length); - this._cache = new Buffer(''); - this._secCache = new Buffer(''); - this._decrypt = decrypt; - this._alen = 0; - this._len = 0; - iv.copy(this._prev); - this._mode = mode; - var h = new Buffer(4); - h.fill(0); - this._ghash = new GHASH(this._cipher.encryptBlock(h)); - this._authTag = null; - this._called = false; + return new StreamCipher(mode, key, iv) + } + Transform.call(this) + this._finID = Buffer.concat([iv, new Buffer([0, 0, 0, 1])]) + iv = Buffer.concat([iv, new Buffer([0, 0, 0, 2])]) + this._cipher = new aes.AES(key) + this._prev = new Buffer(iv.length) + this._cache = new Buffer('') + this._secCache = new Buffer('') + this._decrypt = decrypt + this._alen = 0 + this._len = 0 + iv.copy(this._prev) + this._mode = mode + var h = new Buffer(4) + h.fill(0) + this._ghash = new GHASH(this._cipher.encryptBlock(h)) + this._authTag = null + this._called = false } StreamCipher.prototype._update = function (chunk) { if (!this._called && this._alen) { - var rump = 16 - (this._alen % 16); - if (rump <16) { - rump = new Buffer(rump); - rump.fill(0); - this._ghash.update(rump); + var rump = 16 - (this._alen % 16) + if (rump < 16) { + rump = new Buffer(rump) + rump.fill(0) + this._ghash.update(rump) } } - this._called = true; - var out = this._mode.encrypt(this, chunk); + this._called = true + var out = this._mode.encrypt(this, chunk) if (this._decrypt) { - this._ghash.update(chunk); + this._ghash.update(chunk) } else { - this._ghash.update(out); + this._ghash.update(out) } - this._len += chunk.length; - return out; -}; + this._len += chunk.length + return out +} StreamCipher.prototype._final = function () { if (this._decrypt && !this._authTag) { - throw new Error('Unsupported state or unable to authenticate data'); + throw new Error('Unsupported state or unable to authenticate data') } - var tag = xor(this._ghash.final(this._alen * 8, this._len * 8), this._cipher.encryptBlock(this._finID)); + var tag = xor(this._ghash.final(this._alen * 8, this._len * 8), this._cipher.encryptBlock(this._finID)) if (this._decrypt) { if (xorTest(tag, this._authTag)) { - throw new Error('Unsupported state or unable to authenticate data'); + throw new Error('Unsupported state or unable to authenticate data') } } else { - this._authTag = tag; + this._authTag = tag } - this._cipher.scrub(); -}; + this._cipher.scrub() +} StreamCipher.prototype.getAuthTag = function getAuthTag () { if (!this._decrypt && Buffer.isBuffer(this._authTag)) { - return this._authTag; + return this._authTag } else { - throw new Error('Attempting to get auth tag in unsupported state'); + throw new Error('Attempting to get auth tag in unsupported state') } -}; +} StreamCipher.prototype.setAuthTag = function setAuthTag (tag) { if (this._decrypt) { - this._authTag = tag; + this._authTag = tag } else { - throw new Error('Attempting to set auth tag in unsupported state'); + throw new Error('Attempting to set auth tag in unsupported state') } -}; +} StreamCipher.prototype.setAAD = function setAAD (buf) { if (!this._called) { - this._ghash.update(buf); - this._alen += buf.length; + this._ghash.update(buf) + this._alen += buf.length } else { - throw new Error('Attempting to set AAD in unsupported state'); + throw new Error('Attempting to set AAD in unsupported state') } -}; -function xorTest(a, b) { - var out = 0; +} +function xorTest (a, b) { + var out = 0 if (a.length !== b.length) { - out++; + out++ } - var len = Math.min(a.length, b.length); - var i = -1; + var len = Math.min(a.length, b.length) + var i = -1 while (++i < len) { - out += (a[i] ^ b[i]); + out += (a[i] ^ b[i]) } - return out; + return out } - - }).call(this,require("buffer").Buffer) -},{"./aes":48,"./cipherBase":51,"./ghash":54,"./xor":64,"buffer":42,"inherits":229}],50:[function(require,module,exports){ -var ciphers = require('./encrypter'); -exports.createCipher = exports.Cipher = ciphers.createCipher; -exports.createCipheriv = exports.Cipheriv = ciphers.createCipheriv; -var deciphers = require('./decrypter'); -exports.createDecipher = exports.Decipher = deciphers.createDecipher; -exports.createDecipheriv = exports.Decipheriv = deciphers.createDecipheriv; -var modes = require('./modes'); +},{"./aes":53,"./ghash":58,"buffer":47,"buffer-xor":67,"cipher-base":68,"inherits":240}],55:[function(require,module,exports){ +var ciphers = require('./encrypter') +exports.createCipher = exports.Cipher = ciphers.createCipher +exports.createCipheriv = exports.Cipheriv = ciphers.createCipheriv +var deciphers = require('./decrypter') +exports.createDecipher = exports.Decipher = deciphers.createDecipher +exports.createDecipheriv = exports.Decipheriv = deciphers.createDecipheriv +var modes = require('./modes') function getCiphers () { - return Object.keys(modes); + return Object.keys(modes) } -exports.listCiphers = exports.getCiphers = getCiphers; - -},{"./decrypter":52,"./encrypter":53,"./modes":55}],51:[function(require,module,exports){ -(function (Buffer){ -var Transform = require('stream').Transform; -var inherits = require('inherits'); +exports.listCiphers = exports.getCiphers = getCiphers -module.exports = CipherBase; -inherits(CipherBase, Transform); -function CipherBase() { - Transform.call(this); -} -CipherBase.prototype.update = function (data, inputEnc, outputEnc) { - if (typeof data === 'string') { - data = new Buffer(data, inputEnc); - } - var outData = this._update(data); - if (outputEnc) { - outData = outData.toString(outputEnc); - } - return outData; -}; -CipherBase.prototype._transform = function (data, _, next) { - this.push(this._update(data)); - next(); -}; -CipherBase.prototype._flush = function (next) { - try { - this.push(this._final()); - } catch(e) { - return next(e); - } - next(); -}; -CipherBase.prototype.final = function (outputEnc) { - var outData = this._final() || new Buffer(''); - if (outputEnc) { - outData = outData.toString(outputEnc); - } - return outData; -}; -}).call(this,require("buffer").Buffer) -},{"buffer":42,"inherits":229,"stream":200}],52:[function(require,module,exports){ +},{"./decrypter":56,"./encrypter":57,"./modes":59}],56:[function(require,module,exports){ (function (Buffer){ -var aes = require('./aes'); -var Transform = require('./cipherBase'); -var inherits = require('inherits'); -var modes = require('./modes'); -var StreamCipher = require('./streamCipher'); -var AuthCipher = require('./authCipher'); -var ebtk = require('./EVP_BytesToKey'); +var aes = require('./aes') +var Transform = require('cipher-base') +var inherits = require('inherits') +var modes = require('./modes') +var StreamCipher = require('./streamCipher') +var AuthCipher = require('./authCipher') +var ebtk = require('evp_bytestokey') -inherits(Decipher, Transform); -function Decipher(mode, key, iv) { +inherits(Decipher, Transform) +function Decipher (mode, key, iv) { if (!(this instanceof Decipher)) { - return new Decipher(mode, key, iv); + return new Decipher(mode, key, iv) } - Transform.call(this); - this._cache = new Splitter(); - this._last = void 0; - this._cipher = new aes.AES(key); - this._prev = new Buffer(iv.length); - iv.copy(this._prev); - this._mode = mode; - this._autopadding = true; + Transform.call(this) + this._cache = new Splitter() + this._last = void 0 + this._cipher = new aes.AES(key) + this._prev = new Buffer(iv.length) + iv.copy(this._prev) + this._mode = mode + this._autopadding = true } Decipher.prototype._update = function (data) { - this._cache.add(data); - var chunk; - var thing; - var out = []; + this._cache.add(data) + var chunk + var thing + var out = [] while ((chunk = this._cache.get(this._autopadding))) { - thing = this._mode.decrypt(this, chunk); - out.push(thing); + thing = this._mode.decrypt(this, chunk) + out.push(thing) } - return Buffer.concat(out); -}; + return Buffer.concat(out) +} Decipher.prototype._final = function () { - var chunk = this._cache.flush(); + var chunk = this._cache.flush() if (this._autopadding) { - return unpad(this._mode.decrypt(this, chunk)); + return unpad(this._mode.decrypt(this, chunk)) } else if (chunk) { - throw new Error('data not multiple of block length'); + throw new Error('data not multiple of block length') } -}; +} Decipher.prototype.setAutoPadding = function (setTo) { - this._autopadding = !!setTo; -}; -function Splitter() { - if (!(this instanceof Splitter)) { - return new Splitter(); + this._autopadding = !!setTo +} +function Splitter () { + if (!(this instanceof Splitter)) { + return new Splitter() } - this.cache = new Buffer(''); + this.cache = new Buffer('') } Splitter.prototype.add = function (data) { - this.cache = Buffer.concat([this.cache, data]); -}; + this.cache = Buffer.concat([this.cache, data]) +} Splitter.prototype.get = function (autoPadding) { - var out; + var out if (autoPadding) { if (this.cache.length > 16) { - out = this.cache.slice(0, 16); - this.cache = this.cache.slice(16); - return out; + out = this.cache.slice(0, 16) + this.cache = this.cache.slice(16) + return out } } else { if (this.cache.length >= 16) { - out = this.cache.slice(0, 16); - this.cache = this.cache.slice(16); - return out; + out = this.cache.slice(0, 16) + this.cache = this.cache.slice(16) + return out } } - return null; -}; + return null +} Splitter.prototype.flush = function () { if (this.cache.length) { - return this.cache; + return this.cache } -}; -function unpad(last) { - var padded = last[15]; - var i = -1; +} +function unpad (last) { + var padded = last[15] + var i = -1 while (++i < padded) { if (last[(i + (16 - padded))] !== padded) { - throw new Error('unable to decrypt data'); + throw new Error('unable to decrypt data') } } if (padded === 16) { - return; + return } - return last.slice(0, 16 - padded); + return last.slice(0, 16 - padded) } var modelist = { @@ -11862,122 +13140,122 @@ var modelist = { OFB: require('./modes/ofb'), CTR: require('./modes/ctr'), GCM: require('./modes/ctr') -}; - +} -function createDecipheriv(suite, password, iv) { - var config = modes[suite.toLowerCase()]; +function createDecipheriv (suite, password, iv) { + var config = modes[suite.toLowerCase()] if (!config) { - throw new TypeError('invalid suite type'); + throw new TypeError('invalid suite type') } if (typeof iv === 'string') { - iv = new Buffer(iv); + iv = new Buffer(iv) } if (typeof password === 'string') { - password = new Buffer(password); + password = new Buffer(password) } - if (password.length !== config.key/8) { - throw new TypeError('invalid key length ' + password.length); + if (password.length !== config.key / 8) { + throw new TypeError('invalid key length ' + password.length) } if (iv.length !== config.iv) { - throw new TypeError('invalid iv length ' + iv.length); + throw new TypeError('invalid iv length ' + iv.length) } if (config.type === 'stream') { - return new StreamCipher(modelist[config.mode], password, iv, true); + return new StreamCipher(modelist[config.mode], password, iv, true) } else if (config.type === 'auth') { - return new AuthCipher(modelist[config.mode], password, iv, true); + return new AuthCipher(modelist[config.mode], password, iv, true) } - return new Decipher(modelist[config.mode], password, iv); + return new Decipher(modelist[config.mode], password, iv) } function createDecipher (suite, password) { - var config = modes[suite.toLowerCase()]; + var config = modes[suite.toLowerCase()] if (!config) { - throw new TypeError('invalid suite type'); + throw new TypeError('invalid suite type') } - var keys = ebtk(password, config.key, config.iv); - return createDecipheriv(suite, keys.key, keys.iv); + var keys = ebtk(password, false, config.key, config.iv) + return createDecipheriv(suite, keys.key, keys.iv) } -exports.createDecipher = createDecipher; -exports.createDecipheriv = createDecipheriv; +exports.createDecipher = createDecipher +exports.createDecipheriv = createDecipheriv + }).call(this,require("buffer").Buffer) -},{"./EVP_BytesToKey":47,"./aes":48,"./authCipher":49,"./cipherBase":51,"./modes":55,"./modes/cbc":56,"./modes/cfb":57,"./modes/cfb1":58,"./modes/cfb8":59,"./modes/ctr":60,"./modes/ecb":61,"./modes/ofb":62,"./streamCipher":63,"buffer":42,"inherits":229}],53:[function(require,module,exports){ +},{"./aes":53,"./authCipher":54,"./modes":59,"./modes/cbc":60,"./modes/cfb":61,"./modes/cfb1":62,"./modes/cfb8":63,"./modes/ctr":64,"./modes/ecb":65,"./modes/ofb":66,"./streamCipher":69,"buffer":47,"cipher-base":68,"evp_bytestokey":80,"inherits":240}],57:[function(require,module,exports){ (function (Buffer){ -var aes = require('./aes'); -var Transform = require('./cipherBase'); -var inherits = require('inherits'); -var modes = require('./modes'); -var ebtk = require('./EVP_BytesToKey'); -var StreamCipher = require('./streamCipher'); -var AuthCipher = require('./authCipher'); -inherits(Cipher, Transform); -function Cipher(mode, key, iv) { +var aes = require('./aes') +var Transform = require('cipher-base') +var inherits = require('inherits') +var modes = require('./modes') +var ebtk = require('evp_bytestokey') +var StreamCipher = require('./streamCipher') +var AuthCipher = require('./authCipher') +inherits(Cipher, Transform) +function Cipher (mode, key, iv) { if (!(this instanceof Cipher)) { - return new Cipher(mode, key, iv); + return new Cipher(mode, key, iv) } - Transform.call(this); - this._cache = new Splitter(); - this._cipher = new aes.AES(key); - this._prev = new Buffer(iv.length); - iv.copy(this._prev); - this._mode = mode; - this._autopadding = true; + Transform.call(this) + this._cache = new Splitter() + this._cipher = new aes.AES(key) + this._prev = new Buffer(iv.length) + iv.copy(this._prev) + this._mode = mode + this._autopadding = true } Cipher.prototype._update = function (data) { - this._cache.add(data); - var chunk; - var thing; - var out = []; + this._cache.add(data) + var chunk + var thing + var out = [] while ((chunk = this._cache.get())) { - thing = this._mode.encrypt(this, chunk); - out.push(thing); + thing = this._mode.encrypt(this, chunk) + out.push(thing) } - return Buffer.concat(out); -}; + return Buffer.concat(out) +} Cipher.prototype._final = function () { - var chunk = this._cache.flush(); + var chunk = this._cache.flush() if (this._autopadding) { - chunk = this._mode.encrypt(this, chunk); - this._cipher.scrub(); - return chunk; + chunk = this._mode.encrypt(this, chunk) + this._cipher.scrub() + return chunk } else if (chunk.toString('hex') !== '10101010101010101010101010101010') { - this._cipher.scrub(); - throw new Error('data not multiple of block length'); + this._cipher.scrub() + throw new Error('data not multiple of block length') } -}; +} Cipher.prototype.setAutoPadding = function (setTo) { - this._autopadding = !!setTo; -}; + this._autopadding = !!setTo +} -function Splitter() { - if (!(this instanceof Splitter)) { - return new Splitter(); +function Splitter () { + if (!(this instanceof Splitter)) { + return new Splitter() } - this.cache = new Buffer(''); + this.cache = new Buffer('') } Splitter.prototype.add = function (data) { - this.cache = Buffer.concat([this.cache, data]); -}; + this.cache = Buffer.concat([this.cache, data]) +} Splitter.prototype.get = function () { if (this.cache.length > 15) { - var out = this.cache.slice(0, 16); - this.cache = this.cache.slice(16); - return out; + var out = this.cache.slice(0, 16) + this.cache = this.cache.slice(16) + return out } - return null; -}; + return null +} Splitter.prototype.flush = function () { - var len = 16 - this.cache.length; - var padBuff = new Buffer(len); + var len = 16 - this.cache.length + var padBuff = new Buffer(len) - var i = -1; + var i = -1 while (++i < len) { - padBuff.writeUInt8(len, i); + padBuff.writeUInt8(len, i) } - var out = Buffer.concat([this.cache, padBuff]); - return out; -}; + var out = Buffer.concat([this.cache, padBuff]) + return out +} var modelist = { ECB: require('./modes/ecb'), CBC: require('./modes/cbc'), @@ -11987,11847 +13265,10507 @@ var modelist = { OFB: require('./modes/ofb'), CTR: require('./modes/ctr'), GCM: require('./modes/ctr') -}; +} -function createCipheriv(suite, password, iv) { - var config = modes[suite.toLowerCase()]; +function createCipheriv (suite, password, iv) { + var config = modes[suite.toLowerCase()] if (!config) { - throw new TypeError('invalid suite type'); + throw new TypeError('invalid suite type') } if (typeof iv === 'string') { - iv = new Buffer(iv); + iv = new Buffer(iv) } if (typeof password === 'string') { - password = new Buffer(password); + password = new Buffer(password) } - if (password.length !== config.key/8) { - throw new TypeError('invalid key length ' + password.length); + if (password.length !== config.key / 8) { + throw new TypeError('invalid key length ' + password.length) } if (iv.length !== config.iv) { - throw new TypeError('invalid iv length ' + iv.length); + throw new TypeError('invalid iv length ' + iv.length) } if (config.type === 'stream') { - return new StreamCipher(modelist[config.mode], password, iv); + return new StreamCipher(modelist[config.mode], password, iv) } else if (config.type === 'auth') { - return new AuthCipher(modelist[config.mode], password, iv); + return new AuthCipher(modelist[config.mode], password, iv) } - return new Cipher(modelist[config.mode], password, iv); + return new Cipher(modelist[config.mode], password, iv) } function createCipher (suite, password) { - var config = modes[suite.toLowerCase()]; + var config = modes[suite.toLowerCase()] if (!config) { - throw new TypeError('invalid suite type'); + throw new TypeError('invalid suite type') } - var keys = ebtk(password, config.key, config.iv); - return createCipheriv(suite, keys.key, keys.iv); + var keys = ebtk(password, false, config.key, config.iv) + return createCipheriv(suite, keys.key, keys.iv) } -exports.createCipheriv = createCipheriv; -exports.createCipher = createCipher; +exports.createCipheriv = createCipheriv +exports.createCipher = createCipher + }).call(this,require("buffer").Buffer) -},{"./EVP_BytesToKey":47,"./aes":48,"./authCipher":49,"./cipherBase":51,"./modes":55,"./modes/cbc":56,"./modes/cfb":57,"./modes/cfb1":58,"./modes/cfb8":59,"./modes/ctr":60,"./modes/ecb":61,"./modes/ofb":62,"./streamCipher":63,"buffer":42,"inherits":229}],54:[function(require,module,exports){ +},{"./aes":53,"./authCipher":54,"./modes":59,"./modes/cbc":60,"./modes/cfb":61,"./modes/cfb1":62,"./modes/cfb8":63,"./modes/ctr":64,"./modes/ecb":65,"./modes/ofb":66,"./streamCipher":69,"buffer":47,"cipher-base":68,"evp_bytestokey":80,"inherits":240}],58:[function(require,module,exports){ (function (Buffer){ -var zeros = new Buffer(16); -zeros.fill(0); -module.exports = GHASH; -function GHASH(key){ - this.h = key; - this.state = new Buffer(16); - this.state.fill(0); - this.cache = new Buffer(''); +var zeros = new Buffer(16) +zeros.fill(0) +module.exports = GHASH +function GHASH (key) { + this.h = key + this.state = new Buffer(16) + this.state.fill(0) + this.cache = new Buffer('') } // from http://bitwiseshiftleft.github.io/sjcl/doc/symbols/src/core_gcm.js.html // by Juho Vähä-Herttua GHASH.prototype.ghash = function (block) { - var i = -1; + var i = -1 while (++i < block.length) { - this.state[i] ^= block[i]; + this.state[i] ^= block[i] } - this._multiply(); -}; + this._multiply() +} GHASH.prototype._multiply = function () { - var Vi = toArray(this.h); - var Zi = [0, 0, 0, 0]; - var j, xi, lsb_Vi; - var i = -1; + var Vi = toArray(this.h) + var Zi = [0, 0, 0, 0] + var j, xi, lsb_Vi + var i = -1 while (++i < 128) { - xi = (this.state[~~(i/8)] & (1 << (7-i%8))) !== 0; + xi = (this.state[~~(i / 8)] & (1 << (7 - i % 8))) !== 0 if (xi) { // Z_i+1 = Z_i ^ V_i - Zi = xor(Zi, Vi); + Zi = xor(Zi, Vi) } // Store the value of LSB(V_i) - lsb_Vi = (Vi[3] & 1) !== 0; + lsb_Vi = (Vi[3] & 1) !== 0 // V_i+1 = V_i >> 1 - for (j=3; j>0; j--) { - Vi[j] = (Vi[j] >>> 1) | ((Vi[j-1]&1) << 31); + for (j = 3; j > 0; j--) { + Vi[j] = (Vi[j] >>> 1) | ((Vi[j - 1] & 1) << 31) } - Vi[0] = Vi[0] >>> 1; + Vi[0] = Vi[0] >>> 1 // If LSB(V_i) is 1, V_i+1 = (V_i >> 1) ^ R if (lsb_Vi) { - Vi[0] = Vi[0] ^ (0xe1 << 24); + Vi[0] = Vi[0] ^ (0xe1 << 24) } } - this.state = fromArray(Zi); -}; + this.state = fromArray(Zi) +} GHASH.prototype.update = function (buf) { - this.cache = Buffer.concat([this.cache, buf]); - var chunk; + this.cache = Buffer.concat([this.cache, buf]) + var chunk while (this.cache.length >= 16) { - chunk = this.cache.slice(0, 16); - this.cache = this.cache.slice(16); - this.ghash(chunk); + chunk = this.cache.slice(0, 16) + this.cache = this.cache.slice(16) + this.ghash(chunk) } -}; +} GHASH.prototype.final = function (abl, bl) { if (this.cache.length) { - this.ghash(Buffer.concat([this.cache, zeros], 16)); + this.ghash(Buffer.concat([this.cache, zeros], 16)) } this.ghash(fromArray([ - 0, abl, - 0, bl - ])); - return this.state; -}; + 0, abl, + 0, bl + ])) + return this.state +} -function toArray(buf) { +function toArray (buf) { return [ buf.readUInt32BE(0), buf.readUInt32BE(4), buf.readUInt32BE(8), buf.readUInt32BE(12) - ]; + ] } -function fromArray(out) { - out = out.map(fixup_uint32); - var buf = new Buffer(16); - buf.writeUInt32BE(out[0], 0); - buf.writeUInt32BE(out[1], 4); - buf.writeUInt32BE(out[2], 8); - buf.writeUInt32BE(out[3], 12); - return buf; +function fromArray (out) { + out = out.map(fixup_uint32) + var buf = new Buffer(16) + buf.writeUInt32BE(out[0], 0) + buf.writeUInt32BE(out[1], 4) + buf.writeUInt32BE(out[2], 8) + buf.writeUInt32BE(out[3], 12) + return buf } -var uint_max = Math.pow(2, 32); -function fixup_uint32(x) { - var ret, x_pos; - ret = x > uint_max || x < 0 ? (x_pos = Math.abs(x) % uint_max, x < 0 ? uint_max - x_pos : x_pos) : x; - return ret; +var uint_max = Math.pow(2, 32) +function fixup_uint32 (x) { + var ret, x_pos + ret = x > uint_max || x < 0 ? (x_pos = Math.abs(x) % uint_max, x < 0 ? uint_max - x_pos : x_pos) : x + return ret } -function xor(a, b) { +function xor (a, b) { return [ a[0] ^ b[0], a[1] ^ b[1], a[2] ^ b[2], - a[3] ^ b[3], - ]; + a[3] ^ b[3] + ] } + }).call(this,require("buffer").Buffer) -},{"buffer":42}],55:[function(require,module,exports){ +},{"buffer":47}],59:[function(require,module,exports){ exports['aes-128-ecb'] = { cipher: 'AES', key: 128, iv: 0, mode: 'ECB', type: 'block' -}; +} exports['aes-192-ecb'] = { cipher: 'AES', key: 192, iv: 0, mode: 'ECB', type: 'block' -}; +} exports['aes-256-ecb'] = { cipher: 'AES', key: 256, iv: 0, mode: 'ECB', type: 'block' -}; +} exports['aes-128-cbc'] = { cipher: 'AES', key: 128, iv: 16, mode: 'CBC', type: 'block' -}; +} exports['aes-192-cbc'] = { cipher: 'AES', key: 192, iv: 16, mode: 'CBC', type: 'block' -}; +} exports['aes-256-cbc'] = { cipher: 'AES', key: 256, iv: 16, mode: 'CBC', type: 'block' -}; -exports['aes128'] = exports['aes-128-cbc']; -exports['aes192'] = exports['aes-192-cbc']; -exports['aes256'] = exports['aes-256-cbc']; +} +exports['aes128'] = exports['aes-128-cbc'] +exports['aes192'] = exports['aes-192-cbc'] +exports['aes256'] = exports['aes-256-cbc'] exports['aes-128-cfb'] = { cipher: 'AES', key: 128, iv: 16, mode: 'CFB', type: 'stream' -}; +} exports['aes-192-cfb'] = { cipher: 'AES', key: 192, iv: 16, mode: 'CFB', type: 'stream' -}; +} exports['aes-256-cfb'] = { cipher: 'AES', key: 256, iv: 16, mode: 'CFB', type: 'stream' -}; +} exports['aes-128-cfb8'] = { cipher: 'AES', key: 128, iv: 16, mode: 'CFB8', type: 'stream' -}; +} exports['aes-192-cfb8'] = { cipher: 'AES', key: 192, iv: 16, mode: 'CFB8', type: 'stream' -}; +} exports['aes-256-cfb8'] = { cipher: 'AES', key: 256, iv: 16, mode: 'CFB8', type: 'stream' -}; +} exports['aes-128-cfb1'] = { cipher: 'AES', key: 128, iv: 16, mode: 'CFB1', type: 'stream' -}; +} exports['aes-192-cfb1'] = { cipher: 'AES', key: 192, iv: 16, mode: 'CFB1', type: 'stream' -}; +} exports['aes-256-cfb1'] = { cipher: 'AES', key: 256, iv: 16, mode: 'CFB1', type: 'stream' -}; +} exports['aes-128-ofb'] = { cipher: 'AES', key: 128, iv: 16, mode: 'OFB', type: 'stream' -}; +} exports['aes-192-ofb'] = { cipher: 'AES', key: 192, iv: 16, mode: 'OFB', type: 'stream' -}; +} exports['aes-256-ofb'] = { cipher: 'AES', key: 256, iv: 16, mode: 'OFB', type: 'stream' -}; +} exports['aes-128-ctr'] = { cipher: 'AES', key: 128, iv: 16, mode: 'CTR', type: 'stream' -}; +} exports['aes-192-ctr'] = { cipher: 'AES', key: 192, iv: 16, mode: 'CTR', type: 'stream' -}; +} exports['aes-256-ctr'] = { cipher: 'AES', key: 256, iv: 16, mode: 'CTR', type: 'stream' -}; +} exports['aes-128-gcm'] = { cipher: 'AES', key: 128, iv: 12, mode: 'GCM', type: 'auth' -}; +} exports['aes-192-gcm'] = { cipher: 'AES', key: 192, iv: 12, mode: 'GCM', type: 'auth' -}; +} exports['aes-256-gcm'] = { cipher: 'AES', key: 256, iv: 12, mode: 'GCM', type: 'auth' -}; -},{}],56:[function(require,module,exports){ -var xor = require('../xor'); +} + +},{}],60:[function(require,module,exports){ +var xor = require('buffer-xor') + exports.encrypt = function (self, block) { - var data = xor(block, self._prev); - self._prev = self._cipher.encryptBlock(data); - return self._prev; -}; + var data = xor(block, self._prev) + + self._prev = self._cipher.encryptBlock(data) + return self._prev +} + exports.decrypt = function (self, block) { - var pad = self._prev; - self._prev = block; - var out = self._cipher.decryptBlock(block); - return xor(out, pad); -}; -},{"../xor":64}],57:[function(require,module,exports){ + var pad = self._prev + + self._prev = block + var out = self._cipher.decryptBlock(block) + + return xor(out, pad) +} + +},{"buffer-xor":67}],61:[function(require,module,exports){ (function (Buffer){ -var xor = require('../xor'); +var xor = require('buffer-xor') + exports.encrypt = function (self, data, decrypt) { - var out = new Buffer(''); - var len; + var out = new Buffer('') + var len + while (data.length) { if (self._cache.length === 0) { - self._cache = self._cipher.encryptBlock(self._prev); - self._prev = new Buffer(''); + self._cache = self._cipher.encryptBlock(self._prev) + self._prev = new Buffer('') } + if (self._cache.length <= data.length) { - len = self._cache.length; - out = Buffer.concat([out, encryptStart(self, data.slice(0, len), decrypt)]); - data = data.slice(len); + len = self._cache.length + out = Buffer.concat([out, encryptStart(self, data.slice(0, len), decrypt)]) + data = data.slice(len) } else { - out = Buffer.concat([out, encryptStart(self, data, decrypt)]); - break; + out = Buffer.concat([out, encryptStart(self, data, decrypt)]) + break } } - return out; -}; -function encryptStart(self, data, decrypt) { - var len = data.length; - var out = xor(data, self._cache); - self._cache = self._cache.slice(len); - self._prev = Buffer.concat([self._prev, decrypt?data:out]); - return out; + + return out } +function encryptStart (self, data, decrypt) { + var len = data.length + var out = xor(data, self._cache) + self._cache = self._cache.slice(len) + self._prev = Buffer.concat([self._prev, decrypt ? data : out]) + return out +} + }).call(this,require("buffer").Buffer) -},{"../xor":64,"buffer":42}],58:[function(require,module,exports){ +},{"buffer":47,"buffer-xor":67}],62:[function(require,module,exports){ (function (Buffer){ - -function encryptByte(self, byte, decrypt) { - var pad; - var i = -1; - var len = 8; - var out = 0; - var bit, value; +function encryptByte (self, byteParam, decrypt) { + var pad + var i = -1 + var len = 8 + var out = 0 + var bit, value while (++i < len) { - pad = self._cipher.encryptBlock(self._prev); - bit = (byte & (1 << (7-i))) ? 0x80:0; - value = pad[0] ^ bit; - out += ((value&0x80) >> (i%8)); - self._prev = shiftIn(self._prev, decrypt?bit:value); + pad = self._cipher.encryptBlock(self._prev) + bit = (byteParam & (1 << (7 - i))) ? 0x80 : 0 + value = pad[0] ^ bit + out += ((value & 0x80) >> (i % 8)) + self._prev = shiftIn(self._prev, decrypt ? bit : value) } - return out; + return out } exports.encrypt = function (self, chunk, decrypt) { - var len = chunk.length; - var out = new Buffer(len); - var i = -1; + var len = chunk.length + var out = new Buffer(len) + var i = -1 while (++i < len) { - out[i] = encryptByte(self, chunk[i], decrypt); + out[i] = encryptByte(self, chunk[i], decrypt) } - return out; -}; -function shiftIn(buffer, value) { - var len = buffer.length; - var i = -1; - var out = new Buffer(buffer.length); - buffer = Buffer.concat([buffer, new Buffer([value])]); - while(++i < len) { - out[i] = buffer[i]<<1 | buffer[i+1]>>(7); + return out +} +function shiftIn (buffer, value) { + var len = buffer.length + var i = -1 + var out = new Buffer(buffer.length) + buffer = Buffer.concat([buffer, new Buffer([value])]) + while (++i < len) { + out[i] = buffer[i] << 1 | buffer[i + 1] >> (7) } - return out; + return out } + }).call(this,require("buffer").Buffer) -},{"buffer":42}],59:[function(require,module,exports){ +},{"buffer":47}],63:[function(require,module,exports){ (function (Buffer){ -function encryptByte(self, byte, decrypt) { - var pad = self._cipher.encryptBlock(self._prev); - var out = pad[0] ^ byte; - self._prev = Buffer.concat([self._prev.slice(1), new Buffer([decrypt?byte:out])]); - return out; +function encryptByte (self, byteParam, decrypt) { + var pad = self._cipher.encryptBlock(self._prev) + var out = pad[0] ^ byteParam + self._prev = Buffer.concat([self._prev.slice(1), new Buffer([decrypt ? byteParam : out])]) + return out } exports.encrypt = function (self, chunk, decrypt) { - var len = chunk.length; - var out = new Buffer(len); - var i = -1; + var len = chunk.length + var out = new Buffer(len) + var i = -1 while (++i < len) { - out[i] = encryptByte(self, chunk[i], decrypt); + out[i] = encryptByte(self, chunk[i], decrypt) } - return out; -}; + return out +} + }).call(this,require("buffer").Buffer) -},{"buffer":42}],60:[function(require,module,exports){ +},{"buffer":47}],64:[function(require,module,exports){ (function (Buffer){ -var xor = require('../xor'); -function getBlock(self) { - var out = self._cipher.encryptBlock(self._prev); - incr32(self._prev); - return out; -} -exports.encrypt = function (self, chunk) { - while (self._cache.length < chunk.length) { - self._cache = Buffer.concat([self._cache, getBlock(self)]); - } - var pad = self._cache.slice(0, chunk.length); - self._cache = self._cache.slice(chunk.length); - return xor(chunk, pad); -}; -function incr32(iv) { - var len = iv.length; - var item; +var xor = require('buffer-xor') + +function incr32 (iv) { + var len = iv.length + var item while (len--) { - item = iv.readUInt8(len); + item = iv.readUInt8(len) if (item === 255) { - iv.writeUInt8(0, len); + iv.writeUInt8(0, len) } else { - item++; - iv.writeUInt8(item, len); - break; + item++ + iv.writeUInt8(item, len) + break } } } + +function getBlock (self) { + var out = self._cipher.encryptBlock(self._prev) + incr32(self._prev) + return out +} + +exports.encrypt = function (self, chunk) { + while (self._cache.length < chunk.length) { + self._cache = Buffer.concat([self._cache, getBlock(self)]) + } + var pad = self._cache.slice(0, chunk.length) + self._cache = self._cache.slice(chunk.length) + return xor(chunk, pad) +} + }).call(this,require("buffer").Buffer) -},{"../xor":64,"buffer":42}],61:[function(require,module,exports){ +},{"buffer":47,"buffer-xor":67}],65:[function(require,module,exports){ exports.encrypt = function (self, block) { - return self._cipher.encryptBlock(block); -}; + return self._cipher.encryptBlock(block) +} exports.decrypt = function (self, block) { - return self._cipher.decryptBlock(block); -}; -},{}],62:[function(require,module,exports){ + return self._cipher.decryptBlock(block) +} + +},{}],66:[function(require,module,exports){ (function (Buffer){ -var xor = require('../xor'); -function getBlock(self) { - self._prev = self._cipher.encryptBlock(self._prev); - return self._prev; +var xor = require('buffer-xor') + +function getBlock (self) { + self._prev = self._cipher.encryptBlock(self._prev) + return self._prev } + exports.encrypt = function (self, chunk) { while (self._cache.length < chunk.length) { - self._cache = Buffer.concat([self._cache, getBlock(self)]); + self._cache = Buffer.concat([self._cache, getBlock(self)]) } - var pad = self._cache.slice(0, chunk.length); - self._cache = self._cache.slice(chunk.length); - return xor(chunk, pad); -}; + + var pad = self._cache.slice(0, chunk.length) + self._cache = self._cache.slice(chunk.length) + return xor(chunk, pad) +} + }).call(this,require("buffer").Buffer) -},{"../xor":64,"buffer":42}],63:[function(require,module,exports){ +},{"buffer":47,"buffer-xor":67}],67:[function(require,module,exports){ (function (Buffer){ -var aes = require('./aes'); -var Transform = require('./cipherBase'); -var inherits = require('inherits'); +module.exports = function xor (a, b) { + var length = Math.min(a.length, b.length) + var buffer = new Buffer(length) -inherits(StreamCipher, Transform); -module.exports = StreamCipher; -function StreamCipher(mode, key, iv, decrypt) { - if (!(this instanceof StreamCipher)) { - return new StreamCipher(mode, key, iv); + for (var i = 0; i < length; ++i) { + buffer[i] = a[i] ^ b[i] } - Transform.call(this); - this._cipher = new aes.AES(key); - this._prev = new Buffer(iv.length); - this._cache = new Buffer(''); - this._secCache = new Buffer(''); - this._decrypt = decrypt; - iv.copy(this._prev); - this._mode = mode; + + return buffer } -StreamCipher.prototype._update = function (chunk) { - return this._mode.encrypt(this, chunk, this._decrypt); -}; -StreamCipher.prototype._final = function () { - this._cipher.scrub(); -}; + }).call(this,require("buffer").Buffer) -},{"./aes":48,"./cipherBase":51,"buffer":42,"inherits":229}],64:[function(require,module,exports){ +},{"buffer":47}],68:[function(require,module,exports){ (function (Buffer){ -module.exports = xor; -function xor(a, b) { - var len = Math.min(a.length, b.length); - var out = new Buffer(len); - var i = -1; - while (++i < len) { - out.writeUInt8(a[i] ^ b[i], i); +var Transform = require('stream').Transform +var inherits = require('inherits') +var StringDecoder = require('string_decoder').StringDecoder +module.exports = CipherBase +inherits(CipherBase, Transform) +function CipherBase (hashMode) { + Transform.call(this) + this.hashMode = typeof hashMode === 'string' + if (this.hashMode) { + this[hashMode] = this._finalOrDigest + } else { + this.final = this._finalOrDigest } - return out; + this._decoder = null + this._encoding = null +} +CipherBase.prototype.update = function (data, inputEnc, outputEnc) { + if (typeof data === 'string') { + data = new Buffer(data, inputEnc) + } + var outData = this._update(data) + if (this.hashMode) { + return this + } + if (outputEnc) { + outData = this._toString(outData, outputEnc) + } + return outData +} +CipherBase.prototype._transform = function (data, _, next) { + var err + try { + if (this.hashMode) { + this._update(data) + } else { + this.push(this._update(data)) + } + } catch (e) { + err = e + } finally { + next(err) + } +} +CipherBase.prototype._flush = function (done) { + var err + try { + this.push(this._final()) + } catch (e) { + err = e + } finally { + done(err) + } +} +CipherBase.prototype._finalOrDigest = function (outputEnc) { + var outData = this._final() || new Buffer('') + if (outputEnc) { + outData = this._toString(outData, outputEnc, true) + } + return outData } -}).call(this,require("buffer").Buffer) -},{"buffer":42}],65:[function(require,module,exports){ -(function (Buffer){ -exports['RSA-SHA224'] = exports.sha224WithRSAEncryption = { - sign: 'rsa', - hash: 'sha224', - id: new Buffer('302d300d06096086480165030402040500041c', 'hex') -}; -exports['RSA-SHA256'] = exports.sha256WithRSAEncryption = { - sign: 'rsa', - hash: 'sha256', - id: new Buffer('3031300d060960864801650304020105000420', 'hex') -}; -exports['RSA-SHA384'] = exports.sha384WithRSAEncryption = { - sign: 'rsa', - hash: 'sha384', - id: new Buffer('3041300d060960864801650304020205000430', 'hex') -}; -exports['RSA-SHA512'] = exports.sha512WithRSAEncryption = { - sign: 'rsa', - hash: 'sha512', - id: new Buffer('3051300d060960864801650304020305000440', 'hex') -}; -exports['RSA-SHA1'] = { - sign: 'rsa', - hash: 'sha1', - id: new Buffer('3021300906052b0e03021a05000414', 'hex') -}; -exports['ecdsa-with-SHA1'] = { - sign: 'ecdsa', - hash: 'sha1', - id: new Buffer('', 'hex') -}; -exports.DSA = exports['DSA-SHA1'] = exports['DSA-SHA'] = { - sign: 'dsa', - hash: 'sha1', - id: new Buffer('', 'hex') -}; -exports['DSA-SHA224'] = exports['DSA-WITH-SHA224'] = { - sign: 'dsa', - hash: 'sha224', - id: new Buffer('', 'hex') -}; -exports['DSA-SHA256'] = exports['DSA-WITH-SHA256'] = { - sign: 'dsa', - hash: 'sha256', - id: new Buffer('', 'hex') -}; -exports['DSA-SHA384'] = exports['DSA-WITH-SHA384'] = { - sign: 'dsa', - hash: 'sha384', - id: new Buffer('', 'hex') -}; -exports['DSA-SHA512'] = exports['DSA-WITH-SHA512'] = { - sign: 'dsa', - hash: 'sha512', - id: new Buffer('', 'hex') -}; -exports['DSA-RIPEMD160'] = { - sign: 'dsa', - hash: 'rmd160', - id: new Buffer('', 'hex') -}; -exports['RSA-RIPEMD160'] = exports.ripemd160WithRSA = { - sign: 'rsa', - hash: 'rmd160', - id: new Buffer('3021300906052b2403020105000414', 'hex') -}; -exports['RSA-MD5'] = exports.md5WithRSAEncryption = { - sign: 'rsa', - hash: 'md5', - id: new Buffer('3020300c06082a864886f70d020505000410', 'hex') -}; -}).call(this,require("buffer").Buffer) -},{"buffer":42}],66:[function(require,module,exports){ -(function (Buffer){ -var sign = require('./sign'); -var verify = require('./verify'); -var stream = require('stream'); -var inherits = require('inherits'); -var _algos = require('./algos'); -var algos = {}; -Object.keys(_algos).forEach(function (key) { - algos[key] = algos[key.toLowerCase()] = _algos[key]; -}); -'use strict'; -module.exports = function (exports, crypto) { - exports.createSign = exports.Sign = createSign; - function createSign(algorithm) { - return new Sign(algorithm, crypto); - } - exports.createVerify = exports.Verify = createVerify; - function createVerify(algorithm) { - return new Verify(algorithm, crypto); - } -}; -inherits(Sign, stream.Writable); -function Sign(algorithm, crypto) { - stream.Writable.call(this); - var data = algos[algorithm]; - if (!data) { - throw new Error('Unknown message digest'); - } - this._hashType = data.hash; - this._hash = crypto.createHash(data.hash); - this._tag = data.id; - this._crypto = crypto; +CipherBase.prototype._toString = function (value, enc, final) { + if (!this._decoder) { + this._decoder = new StringDecoder(enc) + this._encoding = enc + } + if (this._encoding !== enc) { + throw new Error('can\'t switch encodings') + } + var out = this._decoder.write(value) + if (final) { + out += this._decoder.end() + } + return out } -Sign.prototype._write = function _write(data, _, done) { - this._hash.update(data); - done(); -}; -Sign.prototype.update = function update(data) { - this.write(data); - return this; -}; -Sign.prototype.sign = function signMethod(key, enc) { - this.end(); - var hash = this._hash.digest(); - var sig = sign(Buffer.concat([this._tag, hash]), key, this._hashType, this._crypto); - if (enc) { - sig = sig.toString(enc); - } - return sig; -}; +}).call(this,require("buffer").Buffer) +},{"buffer":47,"inherits":240,"stream":210,"string_decoder":211}],69:[function(require,module,exports){ +(function (Buffer){ +var aes = require('./aes') +var Transform = require('cipher-base') +var inherits = require('inherits') -inherits(Verify, stream.Writable); -function Verify(algorithm, crypto) { - stream.Writable.call(this); - var data = algos[algorithm]; - if (!data) { - throw new Error('Unknown message digest'); - } - this._hash = crypto.createHash(data.hash); - this._tag = data.id; +inherits(StreamCipher, Transform) +module.exports = StreamCipher +function StreamCipher (mode, key, iv, decrypt) { + if (!(this instanceof StreamCipher)) { + return new StreamCipher(mode, key, iv) + } + Transform.call(this) + this._cipher = new aes.AES(key) + this._prev = new Buffer(iv.length) + this._cache = new Buffer('') + this._secCache = new Buffer('') + this._decrypt = decrypt + iv.copy(this._prev) + this._mode = mode +} +StreamCipher.prototype._update = function (chunk) { + return this._mode.encrypt(this, chunk, this._decrypt) +} +StreamCipher.prototype._final = function () { + this._cipher.scrub() } -Verify.prototype._write = function _write(data, _, done) { - this._hash.update(data); - done(); -}; -Verify.prototype.update = function update(data) { - this.write(data); - return this; -}; -Verify.prototype.verify = function verifyMethod(key, sig, enc) { - this.end(); - var hash = this._hash.digest(); - if (!Buffer.isBuffer(sig)) { - sig = new Buffer(sig, enc); - } - return verify(sig, Buffer.concat([this._tag, hash]), key); -}; }).call(this,require("buffer").Buffer) -},{"./algos":65,"./sign":109,"./verify":110,"buffer":42,"inherits":229,"stream":200}],67:[function(require,module,exports){ -// Utils +},{"./aes":53,"buffer":47,"cipher-base":68,"inherits":240}],70:[function(require,module,exports){ +(function (Buffer){ +var CipherBase = require('cipher-base') +var des = require('des.js') +var inherits = require('inherits') -function assert(val, msg) { - if (!val) - throw new Error(msg || 'Assertion failed'); +var modes = { + 'des-ede3-cbc': des.CBC.instantiate(des.EDE), + 'des-ede3': des.EDE, + 'des-ede-cbc': des.CBC.instantiate(des.EDE), + 'des-ede': des.EDE, + 'des-cbc': des.CBC.instantiate(des.DES), + 'des-ecb': des.DES +} +modes.des = modes['des-cbc'] +modes.des3 = modes['des-ede3-cbc'] +module.exports = DES +inherits(DES, CipherBase) +function DES (opts) { + CipherBase.call(this) + var modeName = opts.mode.toLowerCase() + var mode = modes[modeName] + var type + if (opts.decrypt) { + type = 'decrypt' + } else { + type = 'encrypt' + } + var key = opts.key + if (modeName === 'des-ede' || modeName === 'des-ede-cbc') { + key = Buffer.concat([key, key.slice(0, 8)]) + } + var iv = opts.iv + this._des = mode.create({ + key: key, + iv: iv, + type: type + }) } - -function assertEqual(l, r, msg) { - if (l != r) - throw new Error(msg || ('Assertion failed: ' + l + ' != ' + r)); +DES.prototype._update = function (data) { + return new Buffer(this._des.update(data)) } - -// Could use `inherits` module, but don't want to move from single file -// architecture yet. -function inherits(ctor, superCtor) { - ctor.super_ = superCtor - var TempCtor = function () {} - TempCtor.prototype = superCtor.prototype - ctor.prototype = new TempCtor() - ctor.prototype.constructor = ctor +DES.prototype._final = function () { + return new Buffer(this._des.final()) } -// BN +}).call(this,require("buffer").Buffer) +},{"buffer":47,"cipher-base":72,"des.js":73,"inherits":240}],71:[function(require,module,exports){ +exports['des-ecb'] = { + key: 8, + iv: 0 +} +exports['des-cbc'] = exports.des = { + key: 8, + iv: 8 +} +exports['des-ede3-cbc'] = exports.des3 = { + key: 24, + iv: 8 +} +exports['des-ede3'] = { + key: 24, + iv: 0 +} +exports['des-ede-cbc'] = { + key: 16, + iv: 8 +} +exports['des-ede'] = { + key: 16, + iv: 0 +} -function BN(number, base, endian) { - // May be `new BN(bn)` ? - if (number !== null && - typeof number === 'object' && - Array.isArray(number.words)) { - return number; - } +},{}],72:[function(require,module,exports){ +module.exports=require(68) +},{"/home/braydon/bitcore/node_modules/bitcore-build/node_modules/browserify/node_modules/crypto-browserify/node_modules/browserify-cipher/node_modules/browserify-aes/node_modules/cipher-base/index.js":68,"buffer":47,"inherits":240,"stream":210,"string_decoder":211}],73:[function(require,module,exports){ +'use strict'; - this.sign = false; - this.words = null; - this.length = 0; +exports.utils = require('./des/utils'); +exports.Cipher = require('./des/cipher'); +exports.DES = require('./des/des'); +exports.CBC = require('./des/cbc'); +exports.EDE = require('./des/ede'); - // Reduction context - this.red = null; +},{"./des/cbc":74,"./des/cipher":75,"./des/des":76,"./des/ede":77,"./des/utils":78}],74:[function(require,module,exports){ +'use strict'; - if (base === 'le' || base === 'be') { - endian = base; - base = 10; - } +var assert = require('minimalistic-assert'); +var inherits = require('inherits'); - if (number !== null) - this._init(number || 0, base || 10, endian || 'be'); +var proto = {}; + +function CBCState(iv) { + assert.equal(iv.length, 8, 'Invalid IV length'); + + this.iv = new Array(8); + for (var i = 0; i < this.iv.length; i++) + this.iv[i] = iv[i]; } -if (typeof module === 'object') - module.exports = BN; -BN.BN = BN; -BN.wordSize = 26; +function instantiate(Base) { + function CBC(options) { + Base.call(this, options); + this._cbcInit(); + } + inherits(CBC, Base); -BN.prototype._init = function init(number, base, endian) { - if (typeof number === 'number') { - if (number < 0) { - this.sign = true; - number = -number; - } - if (number < 0x4000000) { - this.words = [ number & 0x3ffffff ]; - this.length = 1; - } else { - this.words = [ - number & 0x3ffffff, - (number / 0x4000000) & 0x3ffffff - ]; - this.length = 2; - } - return; - } else if (typeof number === 'object') { - return this._initArray(number, base, endian); + var keys = Object.keys(proto); + for (var i = 0; i < keys.length; i++) { + var key = keys[i]; + CBC.prototype[key] = proto[key]; } - if (base === 'hex') - base = 16; - assert(base === (base | 0) && base >= 2 && base <= 36); - number = number.toString().replace(/\s+/g, ''); - var start = 0; - if (number[0] === '-') - start++; + CBC.create = function create(options) { + return new CBC(options); + }; - if (base === 16) - this._parseHex(number, start); - else - this._parseBase(number, base, start); + return CBC; +} - if (number[0] === '-') - this.sign = true; +exports.instantiate = instantiate; - this.strip(); +proto._cbcInit = function _cbcInit() { + var state = new CBCState(this.options.iv); + this._cbcState = state; }; -BN.prototype._initArray = function _initArray(number, base, endian) { - // Perhaps a Uint8Array - assert(typeof number.length === 'number'); - this.length = Math.ceil(number.length / 3); - this.words = new Array(this.length); - for (var i = 0; i < this.length; i++) - this.words[i] = 0; +proto._update = function _update(inp, inOff, out, outOff) { + var state = this._cbcState; + var superProto = this.constructor.super_.prototype; - var off = 0; - if (endian === 'be') { - for (var i = number.length - 1, j = 0; i >= 0; i -= 3) { - var w = number[i] | (number[i - 1] << 8) | (number[i - 2] << 16); - this.words[j] |= (w << off) & 0x3ffffff; - this.words[j + 1] = (w >>> (26 - off)) & 0x3ffffff; - off += 24; - if (off >= 26) { - off -= 26; - j++; - } - } - } else if (endian === 'le') { - for (var i = 0, j = 0; i < number.length; i += 3) { - var w = number[i] | (number[i + 1] << 8) | (number[i + 2] << 16); - this.words[j] |= (w << off) & 0x3ffffff; - this.words[j + 1] = (w >>> (26 - off)) & 0x3ffffff; - off += 24; - if (off >= 26) { - off -= 26; - j++; - } - } + var iv = state.iv; + if (this.type === 'encrypt') { + for (var i = 0; i < this.blockSize; i++) + iv[i] ^= inp[inOff + i]; + + superProto._update.call(this, iv, 0, out, outOff); + + for (var i = 0; i < this.blockSize; i++) + iv[i] = out[outOff + i]; + } else { + superProto._update.call(this, inp, inOff, out, outOff); + + for (var i = 0; i < this.blockSize; i++) + out[outOff + i] ^= iv[i]; + + for (var i = 0; i < this.blockSize; i++) + iv[i] = inp[inOff + i]; } - return this.strip(); }; -function parseHex(str, start, end) { - var r = 0; - var len = Math.min(str.length, end); - for (var i = start; i < len; i++) { - var c = str.charCodeAt(i) - 48; +},{"inherits":240,"minimalistic-assert":79}],75:[function(require,module,exports){ +'use strict'; - r <<= 4; +var assert = require('minimalistic-assert'); - // 'a' - 'f' - if (c >= 49 && c <= 54) - r |= c - 49 + 0xa; +function Cipher(options) { + this.options = options; - // 'A' - 'F' - else if (c >= 17 && c <= 22) - r |= c - 17 + 0xa; + this.type = this.options.type; + this.blockSize = 8; + this._init(); - // '0' - '9' - else - r |= c & 0xf; - } - return r; + this.buffer = new Array(this.blockSize); + this.bufferOff = 0; } +module.exports = Cipher; -BN.prototype._parseHex = function _parseHex(number, start) { - // Create possibly bigger array to ensure that it fits the number - this.length = Math.ceil((number.length - start) / 6); - this.words = new Array(this.length); - for (var i = 0; i < this.length; i++) - this.words[i] = 0; +Cipher.prototype._init = function _init() { + // Might be overrided +}; - // Scan 24-bit chunks and add them to the number - var off = 0; - for (var i = number.length - 6, j = 0; i >= start; i -= 6) { - var w = parseHex(number, i, i + 6); - this.words[j] |= (w << off) & 0x3ffffff; - this.words[j + 1] |= w >>> (26 - off) & 0x3fffff; - off += 24; - if (off >= 26) { - off -= 26; - j++; - } - } - if (i + 6 !== start) { - var w = parseHex(number, start, i + 6); - this.words[j] |= (w << off) & 0x3ffffff; - this.words[j + 1] |= w >>> (26 - off) & 0x3fffff; - } - this.strip(); +Cipher.prototype.update = function update(data) { + if (data.length === 0) + return []; + + if (this.type === 'decrypt') + return this._updateDecrypt(data); + else + return this._updateEncrypt(data); }; -function parseBase(str, start, end, mul) { - var r = 0; - var len = Math.min(str.length, end); - for (var i = start; i < len; i++) { - var c = str.charCodeAt(i) - 48; +Cipher.prototype._buffer = function _buffer(data, off) { + // Append data to buffer + var min = Math.min(this.buffer.length - this.bufferOff, data.length - off); + for (var i = 0; i < min; i++) + this.buffer[this.bufferOff + i] = data[off + i]; + this.bufferOff += min; - r *= mul; + // Shift next + return min; +}; - // 'a' - if (c >= 49) - r += c - 49 + 0xa; +Cipher.prototype._flushBuffer = function _flushBuffer(out, off) { + this._update(this.buffer, 0, out, off); + this.bufferOff = 0; + return this.blockSize; +}; - // 'A' - else if (c >= 17) - r += c - 17 + 0xa; +Cipher.prototype._updateEncrypt = function _updateEncrypt(data) { + var inputOff = 0; + var outputOff = 0; - // '0' - '9' - else - r += c; + var count = ((this.bufferOff + data.length) / this.blockSize) | 0; + var out = new Array(count * this.blockSize); + + if (this.bufferOff !== 0) { + inputOff += this._buffer(data, inputOff); + + if (this.bufferOff === this.buffer.length) + outputOff += this._flushBuffer(out, outputOff); } - return r; -} -BN.prototype._parseBase = function _parseBase(number, base, start) { - // Initialize as zero - this.words = [ 0 ]; - this.length = 1; + // Write blocks + var max = data.length - ((data.length - inputOff) % this.blockSize); + for (; inputOff < max; inputOff += this.blockSize) { + this._update(data, inputOff, out, outputOff); + outputOff += this.blockSize; + } - // Find length of limb in base - for (var limbLen = 0, limbPow = 1; limbPow <= 0x3ffffff; limbPow *= base) - limbLen++; - limbLen--; - limbPow = (limbPow / base) | 0; + // Queue rest + for (; inputOff < data.length; inputOff++, this.bufferOff++) + this.buffer[this.bufferOff] = data[inputOff]; - var total = number.length - start; - var mod = total % limbLen; - var end = Math.min(total, total - mod) + start; + return out; +}; - var word = 0; - for (var i = start; i < end; i += limbLen) { - word = parseBase(number, i, i + limbLen, base); +Cipher.prototype._updateDecrypt = function _updateDecrypt(data) { + var inputOff = 0; + var outputOff = 0; - this.imuln(limbPow); - this.words[0] += word; + var count = Math.ceil((this.bufferOff + data.length) / this.blockSize) - 1; + var out = new Array(count * this.blockSize); + + // TODO(indutny): optimize it, this is far from optimal + for (; count > 0; count--) { + inputOff += this._buffer(data, inputOff); + outputOff += this._flushBuffer(out, outputOff); } - if (mod !== 0) { - var pow = 1; - var word = parseBase(number, i, number.length, base); + // Buffer rest of the input + inputOff += this._buffer(data, inputOff); - for (var i = 0; i < mod; i++) - pow *= base; - this.imuln(pow); - this.words[0] += word; - } + return out; }; -BN.prototype.copy = function copy(dest) { - dest.words = new Array(this.length); - for (var i = 0; i < this.length; i++) - dest.words[i] = this.words[i]; - dest.length = this.length; - dest.sign = this.sign; - dest.red = this.red; +Cipher.prototype.final = function final(buffer) { + var first; + if (buffer) + first = this.update(buffer); + + var last; + if (this.type === 'encrypt') + last = this._finalEncrypt(); + else + last = this._finalDecrypt(); + + if (first) + return first.concat(last); + else + return last; }; -BN.prototype.clone = function clone() { - var r = new BN(null); - this.copy(r); - return r; +Cipher.prototype._pad = function _pad(buffer, off) { + if (off === 0) + return false; + + while (off < buffer.length) + buffer[off++] = 0; + + return true; }; -// Remove leading `0` from `this` -BN.prototype.strip = function strip() { - while (this.length > 1 && this.words[this.length - 1] === 0) - this.length--; - return this._normSign(); +Cipher.prototype._finalEncrypt = function _finalEncrypt() { + if (!this._pad(this.buffer, this.bufferOff)) + return []; + + var out = new Array(this.blockSize); + this._update(this.buffer, 0, out, 0); + return out; }; -BN.prototype._normSign = function _normSign() { - // -0 = 0 - if (this.length === 1 && this.words[0] === 0) - this.sign = false; - return this; +Cipher.prototype._unpad = function _unpad(buffer) { + return buffer; }; -BN.prototype.inspect = function inspect() { - return (this.red ? ''; +Cipher.prototype._finalDecrypt = function _finalDecrypt() { + assert.equal(this.bufferOff, this.blockSize, 'Not enough data to decrypt'); + var out = new Array(this.blockSize); + this._flushBuffer(out, 0); + + return this._unpad(out); }; -/* +},{"minimalistic-assert":79}],76:[function(require,module,exports){ +'use strict'; -var zeros = []; -var groupSizes = []; -var groupBases = []; +var assert = require('minimalistic-assert'); +var inherits = require('inherits'); -var s = ''; -var i = -1; -while (++i < BN.wordSize) { - zeros[i] = s; - s += '0'; +var des = require('../des'); +var utils = des.utils; +var Cipher = des.Cipher; + +function DESState() { + this.tmp = new Array(2); + this.keys = null; } -groupSizes[0] = 0; -groupSizes[1] = 0; -groupBases[0] = 0; -groupBases[1] = 0; -var base = 2 - 1; -while (++base < 36 + 1) { - var groupSize = 0; - var groupBase = 1; - // TODO: <= - while (groupBase < (1 << BN.wordSize) / base) { - groupBase *= base; - groupSize += 1; - } - groupSizes[base] = groupSize; - groupBases[base] = groupBase; + +function DES(options) { + Cipher.call(this, options); + + var state = new DESState(); + this._desState = state; + + this.deriveKeys(state, options.key); } +inherits(DES, Cipher); +module.exports = DES; -*/ +DES.create = function create(options) { + return new DES(options); +}; -var zeros = [ - '', - '0', - '00', - '000', - '0000', - '00000', - '000000', - '0000000', - '00000000', - '000000000', - '0000000000', - '00000000000', - '000000000000', - '0000000000000', - '00000000000000', - '000000000000000', - '0000000000000000', - '00000000000000000', - '000000000000000000', - '0000000000000000000', - '00000000000000000000', - '000000000000000000000', - '0000000000000000000000', - '00000000000000000000000', - '000000000000000000000000', - '0000000000000000000000000' +var shiftTable = [ + 1, 1, 2, 2, 2, 2, 2, 2, + 1, 2, 2, 2, 2, 2, 2, 1 ]; -var groupSizes = [ - 0, 0, - 25, 16, 12, 11, 10, 9, 8, - 8, 7, 7, 7, 7, 6, 6, - 6, 6, 6, 6, 6, 5, 5, - 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5 -]; +DES.prototype.deriveKeys = function deriveKeys(state, key) { + state.keys = new Array(16 * 2); -var groupBases = [ - 0, 0, - 33554432, 43046721, 16777216, 48828125, 60466176, 40353607, 16777216, - 43046721, 10000000, 19487171, 35831808, 62748517, 7529536, 11390625, - 16777216, 24137569, 34012224, 47045881, 64000000, 4084101, 5153632, - 6436343, 7962624, 9765625, 11881376, 14348907, 17210368, 20511149, - 24300000, 28629151, 33554432, 39135393, 45435424, 52521875, 60466176 -]; + assert.equal(key.length, this.blockSize, 'Invalid key length'); -BN.prototype.toString = function toString(base, padding) { - base = base || 10; - if (base === 16 || base === 'hex') { - var out = ''; - var off = 0; - var padding = padding | 0 || 1; - var carry = 0; - for (var i = 0; i < this.length; i++) { - var w = this.words[i]; - var word = (((w << off) | carry) & 0xffffff).toString(16); - carry = (w >>> (24 - off)) & 0xffffff; - if (carry !== 0 || i !== this.length - 1) - out = zeros[6 - word.length] + word + out; - else - out = word + out; - off += 2; - if (off >= 26) { - off -= 26; - i--; - } - } - if (carry !== 0) - out = carry.toString(16) + out; - while (out.length % padding !== 0) - out = '0' + out; - if (this.sign) - out = '-' + out; - return out; - } else if (base === (base | 0) && base >= 2 && base <= 36) { - // var groupSize = Math.floor(BN.wordSize * Math.LN2 / Math.log(base)); - var groupSize = groupSizes[base]; - // var groupBase = Math.pow(base, groupSize); - var groupBase = groupBases[base]; - var out = ''; - var c = this.clone(); - c.sign = false; - while (c.cmpn(0) !== 0) { - var r = c.modn(groupBase).toString(base); - c = c.idivn(groupBase); + var kL = utils.readUInt32BE(key, 0); + var kR = utils.readUInt32BE(key, 4); - if (c.cmpn(0) !== 0) - out = zeros[groupSize - r.length] + r + out; - else - out = r + out; - } - if (this.cmpn(0) === 0) - out = '0' + out; - if (this.sign) - out = '-' + out; - return out; - } else { - assert(false, 'Base should be between 2 and 36'); + utils.pc1(kL, kR, state.tmp, 0); + kL = state.tmp[0]; + kR = state.tmp[1]; + for (var i = 0; i < state.keys.length; i += 2) { + var shift = shiftTable[i >>> 1]; + kL = utils.r28shl(kL, shift); + kR = utils.r28shl(kR, shift); + utils.pc2(kL, kR, state.keys, i); } }; -BN.prototype.toJSON = function toJSON() { - return this.toString(16); +DES.prototype._update = function _update(inp, inOff, out, outOff) { + var state = this._desState; + + var l = utils.readUInt32BE(inp, inOff); + var r = utils.readUInt32BE(inp, inOff + 4); + + // Initial Permutation + utils.ip(l, r, state.tmp, 0); + l = state.tmp[0]; + r = state.tmp[1]; + + if (this.type === 'encrypt') + this._encrypt(state, l, r, state.tmp, 0); + else + this._decrypt(state, l, r, state.tmp, 0); + + l = state.tmp[0]; + r = state.tmp[1]; + + utils.writeUInt32BE(out, l, outOff); + utils.writeUInt32BE(out, r, outOff + 4); }; -BN.prototype.toArray = function toArray() { - this.strip(); - var res = new Array(this.byteLength()); - res[0] = 0; +DES.prototype._pad = function _pad(buffer, off) { + var value = buffer.length - off; + for (var i = off; i < buffer.length; i++) + buffer[i] = value; - var q = this.clone(); - for (var i = 0; q.cmpn(0) !== 0; i++) { - var b = q.andln(0xff); - q.ishrn(8); + return true; +}; - // Assume big-endian - res[res.length - i - 1] = b; +DES.prototype._unpad = function _unpad(buffer) { + var pad = buffer[buffer.length - 1]; + for (var i = buffer.length - pad; i < buffer.length; i++) + assert.equal(buffer[i], pad); + + return buffer.slice(0, buffer.length - pad); +}; + +DES.prototype._encrypt = function _encrypt(state, lStart, rStart, out, off) { + var l = lStart; + var r = rStart; + + // Apply f() x16 times + for (var i = 0; i < state.keys.length; i += 2) { + var keyL = state.keys[i]; + var keyR = state.keys[i + 1]; + + // f(r, k) + utils.expand(r, state.tmp, 0); + + keyL ^= state.tmp[0]; + keyR ^= state.tmp[1]; + var s = utils.substitute(keyL, keyR); + var f = utils.permute(s); + + var t = r; + r = (l ^ f) >>> 0; + l = t; } - return res; + // Reverse Initial Permutation + utils.rip(r, l, out, off); }; -/* -function genCountBits(bits) { - var arr = []; +DES.prototype._decrypt = function _decrypt(state, lStart, rStart, out, off) { + var l = rStart; + var r = lStart; + + // Apply f() x16 times + for (var i = state.keys.length - 2; i >= 0; i -= 2) { + var keyL = state.keys[i]; + var keyR = state.keys[i + 1]; - for (var i = bits - 1; i >= 0; i--) { - var bit = '0x' + (1 << i).toString(16); - arr.push('w >= ' + bit + ' ? ' + (i + 1)); + // f(r, k) + utils.expand(l, state.tmp, 0); + + keyL ^= state.tmp[0]; + keyR ^= state.tmp[1]; + var s = utils.substitute(keyL, keyR); + var f = utils.permute(s); + + var t = l; + l = (r ^ f) >>> 0; + r = t; } - return new Function('w', 'return ' + arr.join(' :\n') + ' :\n0;'); + // Reverse Initial Permutation + utils.rip(l, r, out, off); }; -BN.prototype._countBits = genCountBits(26); -*/ +},{"../des":73,"inherits":240,"minimalistic-assert":79}],77:[function(require,module,exports){ +'use strict'; + +var assert = require('minimalistic-assert'); +var inherits = require('inherits'); + +var des = require('../des'); +var Cipher = des.Cipher; +var DES = des.DES; + +function EDEState(type, key) { + assert.equal(key.length, 24, 'Invalid key length'); + + var k1 = key.slice(0, 8); + var k2 = key.slice(8, 16); + var k3 = key.slice(16, 24); + + if (type === 'encrypt') { + this.ciphers = [ + DES.create({ type: 'encrypt', key: k1 }), + DES.create({ type: 'decrypt', key: k2 }), + DES.create({ type: 'encrypt', key: k3 }) + ]; + } else { + this.ciphers = [ + DES.create({ type: 'decrypt', key: k3 }), + DES.create({ type: 'encrypt', key: k2 }), + DES.create({ type: 'decrypt', key: k1 }) + ]; + } +} + +function EDE(options) { + Cipher.call(this, options); + + var state = new EDEState(this.type, this.options.key); + this._edeState = state; +} +inherits(EDE, Cipher); + +module.exports = EDE; -// Sadly chrome apps could not contain `new Function()` calls -BN.prototype._countBits = function _countBits(w) { - return w >= 0x2000000 ? 26 : - w >= 0x1000000 ? 25 : - w >= 0x800000 ? 24 : - w >= 0x400000 ? 23 : - w >= 0x200000 ? 22 : - w >= 0x100000 ? 21 : - w >= 0x80000 ? 20 : - w >= 0x40000 ? 19 : - w >= 0x20000 ? 18 : - w >= 0x10000 ? 17 : - w >= 0x8000 ? 16 : - w >= 0x4000 ? 15 : - w >= 0x2000 ? 14 : - w >= 0x1000 ? 13 : - w >= 0x800 ? 12 : - w >= 0x400 ? 11 : - w >= 0x200 ? 10 : - w >= 0x100 ? 9 : - w >= 0x80 ? 8 : - w >= 0x40 ? 7 : - w >= 0x20 ? 6 : - w >= 0x10 ? 5 : - w >= 0x8 ? 4 : - w >= 0x4 ? 3 : - w >= 0x2 ? 2 : - w >= 0x1 ? 1 : - 0; +EDE.create = function create(options) { + return new EDE(options); }; -// Return number of used bits in a BN -BN.prototype.bitLength = function bitLength() { - var hi = 0; - var w = this.words[this.length - 1]; - var hi = this._countBits(w); - return (this.length - 1) * 26 + hi; +EDE.prototype._update = function _update(inp, inOff, out, outOff) { + var state = this._edeState; + + state.ciphers[0]._update(inp, inOff, out, outOff); + state.ciphers[1]._update(out, outOff, out, outOff); + state.ciphers[2]._update(out, outOff, out, outOff); }; -BN.prototype.byteLength = function byteLength() { - var hi = 0; - var w = this.words[this.length - 1]; - return Math.ceil(this.bitLength() / 8); +EDE.prototype._pad = DES.prototype._pad; +EDE.prototype._unpad = DES.prototype._unpad; + +},{"../des":73,"inherits":240,"minimalistic-assert":79}],78:[function(require,module,exports){ +'use strict'; + +exports.readUInt32BE = function readUInt32BE(bytes, off) { + var res = (bytes[0 + off] << 24) | + (bytes[1 + off] << 16) | + (bytes[2 + off] << 8) | + bytes[3 + off]; + return res >>> 0; }; -// Return negative clone of `this` -BN.prototype.neg = function neg() { - if (this.cmpn(0) === 0) - return this.clone(); +exports.writeUInt32BE = function writeUInt32BE(bytes, value, off) { + bytes[0 + off] = value >>> 24; + bytes[1 + off] = (value >>> 16) & 0xff; + bytes[2 + off] = (value >>> 8) & 0xff; + bytes[3 + off] = value & 0xff; +}; - var r = this.clone(); - r.sign = !this.sign; - return r; +exports.ip = function ip(inL, inR, out, off) { + var outL = 0; + var outR = 0; + + for (var i = 6; i >= 0; i -= 2) { + for (var j = 0; j <= 24; j += 8) { + outL <<= 1; + outL |= (inR >>> (j + i)) & 1; + } + for (var j = 0; j <= 24; j += 8) { + outL <<= 1; + outL |= (inL >>> (j + i)) & 1; + } + } + + for (var i = 6; i >= 0; i -= 2) { + for (var j = 1; j <= 25; j += 8) { + outR <<= 1; + outR |= (inR >>> (j + i)) & 1; + } + for (var j = 1; j <= 25; j += 8) { + outR <<= 1; + outR |= (inL >>> (j + i)) & 1; + } + } + + out[off + 0] = outL >>> 0; + out[off + 1] = outR >>> 0; }; -// Add `num` to `this` in-place -BN.prototype.iadd = function iadd(num) { - // negative + positive - if (this.sign && !num.sign) { - this.sign = false; - var r = this.isub(num); - this.sign = !this.sign; - return this._normSign(); +exports.rip = function rip(inL, inR, out, off) { + var outL = 0; + var outR = 0; - // positive + negative - } else if (!this.sign && num.sign) { - num.sign = false; - var r = this.isub(num); - num.sign = true; - return r._normSign(); + for (var i = 0; i < 4; i++) { + for (var j = 24; j >= 0; j -= 8) { + outL <<= 1; + outL |= (inR >>> (j + i)) & 1; + outL <<= 1; + outL |= (inL >>> (j + i)) & 1; + } + } + for (var i = 4; i < 8; i++) { + for (var j = 24; j >= 0; j -= 8) { + outR <<= 1; + outR |= (inR >>> (j + i)) & 1; + outR <<= 1; + outR |= (inL >>> (j + i)) & 1; + } } - // a.length > b.length - var a; - var b; - if (this.length > num.length) { - a = this; - b = num; - } else { - a = num; - b = this; + out[off + 0] = outL >>> 0; + out[off + 1] = outR >>> 0; +}; + +exports.pc1 = function pc1(inL, inR, out, off) { + var outL = 0; + var outR = 0; + + // 7, 15, 23, 31, 39, 47, 55, 63 + // 6, 14, 22, 30, 39, 47, 55, 63 + // 5, 13, 21, 29, 39, 47, 55, 63 + // 4, 12, 20, 28 + for (var i = 7; i >= 5; i--) { + for (var j = 0; j <= 24; j += 8) { + outL <<= 1; + outL |= (inR >> (j + i)) & 1; + } + for (var j = 0; j <= 24; j += 8) { + outL <<= 1; + outL |= (inL >> (j + i)) & 1; + } + } + for (var j = 0; j <= 24; j += 8) { + outL <<= 1; + outL |= (inR >> (j + i)) & 1; } - var carry = 0; - for (var i = 0; i < b.length; i++) { - var r = a.words[i] + b.words[i] + carry; - this.words[i] = r & 0x3ffffff; - carry = r >>> 26; + // 1, 9, 17, 25, 33, 41, 49, 57 + // 2, 10, 18, 26, 34, 42, 50, 58 + // 3, 11, 19, 27, 35, 43, 51, 59 + // 36, 44, 52, 60 + for (var i = 1; i <= 3; i++) { + for (var j = 0; j <= 24; j += 8) { + outR <<= 1; + outR |= (inR >> (j + i)) & 1; + } + for (var j = 0; j <= 24; j += 8) { + outR <<= 1; + outR |= (inL >> (j + i)) & 1; + } } - for (; carry !== 0 && i < a.length; i++) { - var r = a.words[i] + carry; - this.words[i] = r & 0x3ffffff; - carry = r >>> 26; + for (var j = 0; j <= 24; j += 8) { + outR <<= 1; + outR |= (inL >> (j + i)) & 1; } - this.length = a.length; - if (carry !== 0) { - this.words[this.length] = carry; - this.length++; - // Copy the rest of the words - } else if (a !== this) { - for (; i < a.length; i++) - this.words[i] = a.words[i]; + out[off + 0] = outL >>> 0; + out[off + 1] = outR >>> 0; +}; + +exports.r28shl = function r28shl(num, shift) { + return ((num << shift) & 0xfffffff) | (num >>> (28 - shift)); +}; + +var pc2table = [ + // inL => outL + 14, 11, 17, 4, 27, 23, 25, 0, + 13, 22, 7, 18, 5, 9, 16, 24, + 2, 20, 12, 21, 1, 8, 15, 26, + + // inR => outR + 15, 4, 25, 19, 9, 1, 26, 16, + 5, 11, 23, 8, 12, 7, 17, 0, + 22, 3, 10, 14, 6, 20, 27, 24 +]; + +exports.pc2 = function pc2(inL, inR, out, off) { + var outL = 0; + var outR = 0; + + var len = pc2table.length >>> 1; + for (var i = 0; i < len; i++) { + outL <<= 1; + outL |= (inL >>> pc2table[i]) & 0x1; + } + for (var i = len; i < pc2table.length; i++) { + outR <<= 1; + outR |= (inR >>> pc2table[i]) & 0x1; } - return this; + out[off + 0] = outL >>> 0; + out[off + 1] = outR >>> 0; }; -// Add `num` to `this` -BN.prototype.add = function add(num) { - if (num.sign && !this.sign) { - num.sign = false; - var res = this.sub(num); - num.sign = true; - return res; - } else if (!num.sign && this.sign) { - this.sign = false; - var res = num.sub(this); - this.sign = true; - return res; - } - - if (this.length > num.length) - return this.clone().iadd(num); - else - return num.clone().iadd(this); -}; - -// Subtract `num` from `this` in-place -BN.prototype.isub = function isub(num) { - // this - (-num) = this + num - if (num.sign) { - num.sign = false; - var r = this.iadd(num); - num.sign = true; - return r._normSign(); - - // -this - num = -(this + num) - } else if (this.sign) { - this.sign = false; - this.iadd(num); - this.sign = true; - return this._normSign(); - } - - // At this point both numbers are positive - var cmp = this.cmp(num); - - // Optimization - zeroify - if (cmp === 0) { - this.sign = false; - this.length = 1; - this.words[0] = 0; - return this; - } - - // a > b - if (cmp > 0) { - var a = this; - var b = num; - } else { - var a = num; - var b = this; - } +exports.expand = function expand(r, out, off) { + var outL = 0; + var outR = 0; - var carry = 0; - for (var i = 0; i < b.length; i++) { - var r = a.words[i] - b.words[i] - carry; - if (r < 0) { - r += 0x4000000; - carry = 1; - } else { - carry = 0; - } - this.words[i] = r; + outL = ((r & 1) << 5) | (r >>> 27); + for (var i = 23; i >= 15; i -= 4) { + outL <<= 6; + outL |= (r >>> i) & 0x3f; } - for (; carry !== 0 && i < a.length; i++) { - var r = a.words[i] - carry; - if (r < 0) { - r += 0x4000000; - carry = 1; - } else { - carry = 0; - } - this.words[i] = r; + for (var i = 11; i >= 3; i -= 4) { + outR |= (r >>> i) & 0x3f; + outR <<= 6; } + outR |= ((r & 0x1f) << 1) | (r >>> 31); - // Copy rest of the words - if (carry === 0 && i < a.length && a !== this) - for (; i < a.length; i++) - this.words[i] = a.words[i]; - this.length = Math.max(this.length, i); + out[off + 0] = outL >>> 0; + out[off + 1] = outR >>> 0; +}; - if (a !== this) - this.sign = true; +var sTable = [ + 14, 0, 4, 15, 13, 7, 1, 4, 2, 14, 15, 2, 11, 13, 8, 1, + 3, 10, 10, 6, 6, 12, 12, 11, 5, 9, 9, 5, 0, 3, 7, 8, + 4, 15, 1, 12, 14, 8, 8, 2, 13, 4, 6, 9, 2, 1, 11, 7, + 15, 5, 12, 11, 9, 3, 7, 14, 3, 10, 10, 0, 5, 6, 0, 13, - return this.strip(); -}; + 15, 3, 1, 13, 8, 4, 14, 7, 6, 15, 11, 2, 3, 8, 4, 14, + 9, 12, 7, 0, 2, 1, 13, 10, 12, 6, 0, 9, 5, 11, 10, 5, + 0, 13, 14, 8, 7, 10, 11, 1, 10, 3, 4, 15, 13, 4, 1, 2, + 5, 11, 8, 6, 12, 7, 6, 12, 9, 0, 3, 5, 2, 14, 15, 9, -// Subtract `num` from `this` -BN.prototype.sub = function sub(num) { - return this.clone().isub(num); -}; + 10, 13, 0, 7, 9, 0, 14, 9, 6, 3, 3, 4, 15, 6, 5, 10, + 1, 2, 13, 8, 12, 5, 7, 14, 11, 12, 4, 11, 2, 15, 8, 1, + 13, 1, 6, 10, 4, 13, 9, 0, 8, 6, 15, 9, 3, 8, 0, 7, + 11, 4, 1, 15, 2, 14, 12, 3, 5, 11, 10, 5, 14, 2, 7, 12, -/* -// NOTE: This could be potentionally used to generate loop-less multiplications -function _genCombMulTo(alen, blen) { - var len = alen + blen - 1; - var src = [ - 'var a = this.words, b = num.words, o = out.words, c = 0, w, ' + - 'mask = 0x3ffffff, shift = 0x4000000;', - 'out.length = ' + len + ';' - ]; - for (var k = 0; k < len; k++) { - var minJ = Math.max(0, k - alen + 1); - var maxJ = Math.min(k, blen - 1); + 7, 13, 13, 8, 14, 11, 3, 5, 0, 6, 6, 15, 9, 0, 10, 3, + 1, 4, 2, 7, 8, 2, 5, 12, 11, 1, 12, 10, 4, 14, 15, 9, + 10, 3, 6, 15, 9, 0, 0, 6, 12, 10, 11, 1, 7, 13, 13, 8, + 15, 9, 1, 4, 3, 5, 14, 11, 5, 12, 2, 7, 8, 2, 4, 14, - for (var j = minJ; j <= maxJ; j++) { - var i = k - j; - var mul = 'a[' + i + '] * b[' + j + ']'; + 2, 14, 12, 11, 4, 2, 1, 12, 7, 4, 10, 7, 11, 13, 6, 1, + 8, 5, 5, 0, 3, 15, 15, 10, 13, 3, 0, 9, 14, 8, 9, 6, + 4, 11, 2, 8, 1, 12, 11, 7, 10, 1, 13, 14, 7, 2, 8, 13, + 15, 6, 9, 15, 12, 0, 5, 9, 6, 10, 3, 4, 0, 5, 14, 3, - if (j === minJ) { - src.push('w = ' + mul + ' + c;'); - src.push('c = (w / shift) | 0;'); - } else { - src.push('w += ' + mul + ';'); - src.push('c += (w / shift) | 0;'); - } - src.push('w &= mask;'); - } - src.push('o[' + k + '] = w;'); - } - src.push('if (c !== 0) {', - ' o[' + k + '] = c;', - ' out.length++;', - '}', - 'return out;'); + 12, 10, 1, 15, 10, 4, 15, 2, 9, 7, 2, 12, 6, 9, 8, 5, + 0, 6, 13, 1, 3, 13, 4, 14, 14, 0, 7, 11, 5, 3, 11, 8, + 9, 4, 14, 3, 15, 2, 5, 12, 2, 9, 8, 5, 12, 15, 3, 10, + 7, 11, 0, 14, 4, 1, 10, 7, 1, 6, 13, 0, 11, 8, 6, 13, - return src.join('\n'); -} -*/ + 4, 13, 11, 0, 2, 11, 14, 7, 15, 4, 0, 9, 8, 1, 13, 10, + 3, 14, 12, 3, 9, 5, 7, 12, 5, 2, 10, 15, 6, 8, 1, 6, + 1, 6, 4, 11, 11, 13, 13, 8, 12, 1, 3, 4, 7, 10, 14, 7, + 10, 9, 15, 5, 6, 0, 8, 15, 0, 14, 5, 2, 9, 3, 2, 12, -BN.prototype._smallMulTo = function _smallMulTo(num, out) { - out.sign = num.sign !== this.sign; - out.length = this.length + num.length; + 13, 1, 2, 15, 8, 13, 4, 8, 6, 10, 15, 3, 11, 7, 1, 4, + 10, 12, 9, 5, 3, 6, 14, 11, 5, 0, 0, 14, 12, 9, 7, 2, + 7, 2, 11, 1, 4, 14, 1, 7, 9, 4, 12, 10, 14, 8, 2, 13, + 0, 15, 6, 12, 10, 9, 13, 0, 15, 3, 3, 5, 5, 6, 8, 11 +]; - var carry = 0; - for (var k = 0; k < out.length - 1; k++) { - // Sum all words with the same `i + j = k` and accumulate `ncarry`, - // note that ncarry could be >= 0x3ffffff - var ncarry = carry >>> 26; - var rword = carry & 0x3ffffff; - var maxJ = Math.min(k, num.length - 1); - for (var j = Math.max(0, k - this.length + 1); j <= maxJ; j++) { - var i = k - j; - var a = this.words[i] | 0; - var b = num.words[j] | 0; - var r = a * b; +exports.substitute = function substitute(inL, inR) { + var out = 0; + for (var i = 0; i < 4; i++) { + var b = (inL >>> (18 - i * 6)) & 0x3f; + var sb = sTable[i * 0x40 + b]; - var lo = r & 0x3ffffff; - ncarry = (ncarry + ((r / 0x4000000) | 0)) | 0; - lo = (lo + rword) | 0; - rword = lo & 0x3ffffff; - ncarry = (ncarry + (lo >>> 26)) | 0; - } - out.words[k] = rword; - carry = ncarry; - } - if (carry !== 0) { - out.words[k] = carry; - } else { - out.length--; + out <<= 4; + out |= sb; } + for (var i = 0; i < 4; i++) { + var b = (inR >>> (18 - i * 6)) & 0x3f; + var sb = sTable[4 * 0x40 + i * 0x40 + b]; - return out.strip(); + out <<= 4; + out |= sb; + } + return out >>> 0; }; -BN.prototype._bigMulTo = function _bigMulTo(num, out) { - out.sign = num.sign !== this.sign; - out.length = this.length + num.length; - - var carry = 0; - var hncarry = 0; - for (var k = 0; k < out.length - 1; k++) { - // Sum all words with the same `i + j = k` and accumulate `ncarry`, - // note that ncarry could be >= 0x3ffffff - var ncarry = hncarry; - hncarry = 0; - var rword = carry & 0x3ffffff; - var maxJ = Math.min(k, num.length - 1); - for (var j = Math.max(0, k - this.length + 1); j <= maxJ; j++) { - var i = k - j; - var a = this.words[i] | 0; - var b = num.words[j] | 0; - var r = a * b; - - var lo = r & 0x3ffffff; - ncarry = (ncarry + ((r / 0x4000000) | 0)) | 0; - lo = (lo + rword) | 0; - rword = lo & 0x3ffffff; - ncarry = (ncarry + (lo >>> 26)) | 0; +var permuteTable = [ + 16, 25, 12, 11, 3, 20, 4, 15, 31, 17, 9, 6, 27, 14, 1, 22, + 30, 24, 8, 18, 0, 5, 29, 23, 13, 19, 2, 26, 10, 21, 28, 7 +]; - hncarry += ncarry >>> 26; - ncarry &= 0x3ffffff; - } - out.words[k] = rword; - carry = ncarry; - ncarry = hncarry; - } - if (carry !== 0) { - out.words[k] = carry; - } else { - out.length--; +exports.permute = function permute(num) { + var out = 0; + for (var i = 0; i < permuteTable.length; i++) { + out <<= 1; + out |= (num >>> permuteTable[i]) & 0x1; } - - return out.strip(); + return out >>> 0; }; -BN.prototype.mulTo = function mulTo(num, out) { - var res; - if (this.length + num.length < 63) - res = this._smallMulTo(num, out); - else - res = this._bigMulTo(num, out); - return res; -}; +exports.padSplit = function padSplit(num, size, group) { + var str = num.toString(2); + while (str.length < size) + str = '0' + str; -// Multiply `this` by `num` -BN.prototype.mul = function mul(num) { - var out = new BN(null); - out.words = new Array(this.length + num.length); - return this.mulTo(num, out); + var out = []; + for (var i = 0; i < size; i += group) + out.push(str.slice(i, i + group)); + return out.join(' '); }; -// In-place Multiplication -BN.prototype.imul = function imul(num) { - if (this.cmpn(0) === 0 || num.cmpn(0) === 0) { - this.words[0] = 0; - this.length = 1; - return this; - } - - var tlen = this.length; - var nlen = num.length; +},{}],79:[function(require,module,exports){ +module.exports = assert; - this.sign = num.sign !== this.sign; - this.length = this.length + num.length; - this.words[this.length - 1] = 0; +function assert(val, msg) { + if (!val) + throw new Error(msg || 'Assertion failed'); +} - var lastCarry = 0; - for (var k = this.length - 2; k >= 0; k--) { - // Sum all words with the same `i + j = k` and accumulate `carry`, - // note that carry could be >= 0x3ffffff - var carry = 0; - var rword = 0; - var maxJ = Math.min(k, nlen - 1); - for (var j = Math.max(0, k - tlen + 1); j <= maxJ; j++) { - var i = k - j; - var a = this.words[i]; - var b = num.words[j]; - var r = a * b; +assert.equal = function assertEqual(l, r, msg) { + if (l != r) + throw new Error(msg || ('Assertion failed: ' + l + ' != ' + r)); +}; - var lo = r & 0x3ffffff; - carry += (r / 0x4000000) | 0; - lo += rword; - rword = lo & 0x3ffffff; - carry += lo >>> 26; +},{}],80:[function(require,module,exports){ +(function (Buffer){ +var md5 = require('create-hash/md5') +module.exports = EVP_BytesToKey +function EVP_BytesToKey (password, salt, keyLen, ivLen) { + if (!Buffer.isBuffer(password)) { + password = new Buffer(password, 'binary') + } + if (salt && !Buffer.isBuffer(salt)) { + salt = new Buffer(salt, 'binary') + } + keyLen = keyLen / 8 + ivLen = ivLen || 0 + var ki = 0 + var ii = 0 + var key = new Buffer(keyLen) + var iv = new Buffer(ivLen) + var addmd = 0 + var md_buf + var i + var bufs = [] + while (true) { + if (addmd++ > 0) { + bufs.push(md_buf) + } + bufs.push(password) + if (salt) { + bufs.push(salt) + } + md_buf = md5(Buffer.concat(bufs)) + bufs = [] + i = 0 + if (keyLen > 0) { + while (true) { + if (keyLen === 0) { + break + } + if (i === md_buf.length) { + break + } + key[ki++] = md_buf[i] + keyLen-- + i++ + } + } + if (ivLen > 0 && i !== md_buf.length) { + while (true) { + if (ivLen === 0) { + break + } + if (i === md_buf.length) { + break + } + iv[ii++] = md_buf[i] + ivLen-- + i++ + } + } + if (keyLen === 0 && ivLen === 0) { + break } - this.words[k] = rword; - this.words[k + 1] += carry; - carry = 0; - } - - // Propagate overflows - var carry = 0; - for (var i = 1; i < this.length; i++) { - var w = this.words[i] + carry; - this.words[i] = w & 0x3ffffff; - carry = w >>> 26; } - - return this.strip(); -}; - -BN.prototype.imuln = function imuln(num) { - assert(typeof num === 'number'); - - // Carry - var carry = 0; - for (var i = 0; i < this.length; i++) { - var w = this.words[i] * num; - var lo = (w & 0x3ffffff) + carry; - carry = (w / 0x4000000) | 0; - this.words[i] = lo; + for (i = 0; i < md_buf.length; i++) { + md_buf[i] = 0 } - - if (carry !== 0) { - this.words[i] = carry; - this.length++; + return { + key: key, + iv: iv } +} - return this; -}; - -// `this` * `this` -BN.prototype.sqr = function sqr() { - return this.mul(this); -}; +}).call(this,require("buffer").Buffer) +},{"buffer":47,"create-hash/md5":127}],81:[function(require,module,exports){ +(function (Buffer){ +'use strict' +exports['RSA-SHA224'] = exports.sha224WithRSAEncryption = { + sign: 'rsa', + hash: 'sha224', + id: new Buffer('302d300d06096086480165030402040500041c', 'hex') +} +exports['RSA-SHA256'] = exports.sha256WithRSAEncryption = { + sign: 'rsa', + hash: 'sha256', + id: new Buffer('3031300d060960864801650304020105000420', 'hex') +} +exports['RSA-SHA384'] = exports.sha384WithRSAEncryption = { + sign: 'rsa', + hash: 'sha384', + id: new Buffer('3041300d060960864801650304020205000430', 'hex') +} +exports['RSA-SHA512'] = exports.sha512WithRSAEncryption = { + sign: 'rsa', + hash: 'sha512', + id: new Buffer('3051300d060960864801650304020305000440', 'hex') +} +exports['RSA-SHA1'] = { + sign: 'rsa', + hash: 'sha1', + id: new Buffer('3021300906052b0e03021a05000414', 'hex') +} +exports['ecdsa-with-SHA1'] = { + sign: 'ecdsa', + hash: 'sha1', + id: new Buffer('', 'hex') +} +exports.DSA = exports['DSA-SHA1'] = exports['DSA-SHA'] = { + sign: 'dsa', + hash: 'sha1', + id: new Buffer('', 'hex') +} +exports['DSA-SHA224'] = exports['DSA-WITH-SHA224'] = { + sign: 'dsa', + hash: 'sha224', + id: new Buffer('', 'hex') +} +exports['DSA-SHA256'] = exports['DSA-WITH-SHA256'] = { + sign: 'dsa', + hash: 'sha256', + id: new Buffer('', 'hex') +} +exports['DSA-SHA384'] = exports['DSA-WITH-SHA384'] = { + sign: 'dsa', + hash: 'sha384', + id: new Buffer('', 'hex') +} +exports['DSA-SHA512'] = exports['DSA-WITH-SHA512'] = { + sign: 'dsa', + hash: 'sha512', + id: new Buffer('', 'hex') +} +exports['DSA-RIPEMD160'] = { + sign: 'dsa', + hash: 'rmd160', + id: new Buffer('', 'hex') +} +exports['RSA-RIPEMD160'] = exports.ripemd160WithRSA = { + sign: 'rsa', + hash: 'rmd160', + id: new Buffer('3021300906052b2403020105000414', 'hex') +} +exports['RSA-MD5'] = exports.md5WithRSAEncryption = { + sign: 'rsa', + hash: 'md5', + id: new Buffer('3020300c06082a864886f70d020505000410', 'hex') +} -// `this` * `this` in-place -BN.prototype.isqr = function isqr() { - return this.mul(this); -}; +}).call(this,require("buffer").Buffer) +},{"buffer":47}],82:[function(require,module,exports){ +(function (Buffer){ +var _algos = require('./algos') +var createHash = require('create-hash') +var inherits = require('inherits') +var sign = require('./sign') +var stream = require('stream') +var verify = require('./verify') -// Shift-left in-place -BN.prototype.ishln = function ishln(bits) { - assert(typeof bits === 'number' && bits >= 0); - var r = bits % 26; - var s = (bits - r) / 26; - var carryMask = (0x3ffffff >>> (26 - r)) << (26 - r); +var algos = {} +Object.keys(_algos).forEach(function (key) { + algos[key] = algos[key.toLowerCase()] = _algos[key] +}) - var o = this.clone(); - if (r !== 0) { - var carry = 0; - for (var i = 0; i < this.length; i++) { - var newCarry = this.words[i] & carryMask; - var c = (this.words[i] - newCarry) << r; - this.words[i] = c | carry; - carry = newCarry >>> (26 - r); - } - if (carry) { - this.words[i] = carry; - this.length++; - } - } +function Sign (algorithm) { + stream.Writable.call(this) - if (s !== 0) { - for (var i = this.length - 1; i >= 0; i--) - this.words[i + s] = this.words[i]; - for (var i = 0; i < s; i++) - this.words[i] = 0; - this.length += s; + var data = algos[algorithm] + if (!data) { + throw new Error('Unknown message digest') } - return this.strip(); -}; - -// Shift-right in-place -// NOTE: `hint` is a lowest bit before trailing zeroes -// NOTE: if `extended` is true - { lo: ..., hi: } object will be returned -BN.prototype.ishrn = function ishrn(bits, hint, extended) { - assert(typeof bits === 'number' && bits >= 0); - if (hint) - hint = (hint - (hint % 26)) / 26; - else - hint = 0; - - var r = bits % 26; - var s = Math.min((bits - r) / 26, this.length); - var mask = 0x3ffffff ^ ((0x3ffffff >>> r) << r); - var maskedWords = extended; + this._hashType = data.hash + this._hash = createHash(data.hash) + this._tag = data.id + this._signType = data.sign +} +inherits(Sign, stream.Writable) - hint -= s; - hint = Math.max(0, hint); +Sign.prototype._write = function _write (data, _, done) { + this._hash.update(data) + done() +} - // Extended mode, copy masked part - if (maskedWords) { - for (var i = 0; i < s; i++) - maskedWords.words[i] = this.words[i]; - maskedWords.length = s; +Sign.prototype.update = function update (data, enc) { + if (typeof data === 'string') { + data = new Buffer(data, enc) } - if (s === 0) { - // No-op, we should not move anything at all - } else if (this.length > s) { - this.length -= s; - for (var i = 0; i < this.length; i++) - this.words[i] = this.words[i + s]; - } else { - this.words[0] = 0; - this.length = 1; - } + this._hash.update(data) + return this +} - var carry = 0; - for (var i = this.length - 1; i >= 0 && (carry !== 0 || i >= hint); i--) { - var word = this.words[i]; - this.words[i] = (carry << (26 - r)) | (word >>> r); - carry = word & mask; - } +Sign.prototype.sign = function signMethod (key, enc) { + this.end() + var hash = this._hash.digest() + var sig = sign(Buffer.concat([this._tag, hash]), key, this._hashType, this._signType) - // Push carried bits as a mask - if (maskedWords && carry !== 0) - maskedWords.words[maskedWords.length++] = carry; + return enc ? sig.toString(enc) : sig +} - if (this.length === 0) { - this.words[0] = 0; - this.length = 1; +function Verify (algorithm) { + stream.Writable.call(this) + + var data = algos[algorithm] + if (!data) { + throw new Error('Unknown message digest') } - this.strip(); - if (extended) - return { hi: this, lo: maskedWords }; + this._hash = createHash(data.hash) + this._tag = data.id + this._signType = data.sign +} +inherits(Verify, stream.Writable) - return this; -}; +Verify.prototype._write = function _write (data, _, done) { + this._hash.update(data) -// Shift-left -BN.prototype.shln = function shln(bits) { - return this.clone().ishln(bits); -}; + done() +} -// Shift-right -BN.prototype.shrn = function shrn(bits) { - return this.clone().ishrn(bits); -}; +Verify.prototype.update = function update (data, enc) { + if (typeof data === 'string') { + data = new Buffer(data, enc) + } -// Test if n bit is set -BN.prototype.testn = function testn(bit) { - assert(typeof bit === 'number' && bit >= 0); - var r = bit % 26; - var s = (bit - r) / 26; - var q = 1 << r; + this._hash.update(data) + return this +} - // Fast case: bit is much higher than all existing words - if (this.length <= s) { - return false; +Verify.prototype.verify = function verifyMethod (key, sig, enc) { + if (typeof sig === 'string') { + sig = new Buffer(sig, enc) } - // Check bit and return - var w = this.words[s]; - - return !!(w & q); -}; + this.end() + var hash = this._hash.digest() -// Return only lowers bits of number (in-place) -BN.prototype.imaskn = function imaskn(bits) { - assert(typeof bits === 'number' && bits >= 0); - var r = bits % 26; - var s = (bits - r) / 26; + return verify(sig, Buffer.concat([this._tag, hash]), key, this._signType) +} - assert(!this.sign, 'imaskn works only with positive numbers'); +function createSign (algorithm) { + return new Sign(algorithm) +} - if (r !== 0) - s++; - this.length = Math.min(s, this.length); +function createVerify (algorithm) { + return new Verify(algorithm) +} - if (r !== 0) { - var mask = 0x3ffffff ^ ((0x3ffffff >>> r) << r); - this.words[this.length - 1] &= mask; - } +module.exports = { + Sign: createSign, + Verify: createVerify, + createSign: createSign, + createVerify: createVerify +} - return this.strip(); -}; +}).call(this,require("buffer").Buffer) +},{"./algos":81,"./sign":122,"./verify":123,"buffer":47,"create-hash":125,"inherits":240,"stream":210}],83:[function(require,module,exports){ +'use strict' +exports['1.3.132.0.10'] = 'secp256k1' -// Return only lowers bits of number -BN.prototype.maskn = function maskn(bits) { - return this.clone().imaskn(bits); -}; +exports['1.3.132.0.33'] = 'p224' -// Add plain number `num` to `this` -BN.prototype.iaddn = function iaddn(num) { - assert(typeof num === 'number'); - if (num < 0) - return this.isubn(-num); +exports['1.2.840.10045.3.1.1'] = 'p192' - // Possible sign change - if (this.sign) { - if (this.length === 1 && this.words[0] < num) { - this.words[0] = num - this.words[0]; - this.sign = false; - return this; - } +exports['1.2.840.10045.3.1.7'] = 'p256' - this.sign = false; - this.isubn(num); - this.sign = true; - return this; +},{}],84:[function(require,module,exports){ +(function (Buffer){ +var bn = require('bn.js'); +var randomBytes = require('randombytes'); +module.exports = crt; +function blind(priv) { + var r = getr(priv); + var blinder = r.toRed(bn.mont(priv.modulus)) + .redPow(new bn(priv.publicExponent)).fromRed(); + return { + blinder: blinder, + unblinder:r.invm(priv.modulus) + }; +} +function crt(msg, priv) { + var blinds = blind(priv); + var len = priv.modulus.byteLength(); + var mod = bn.mont(priv.modulus); + var blinded = new bn(msg).mul(blinds.blinder).mod(priv.modulus); + var c1 = blinded.toRed(bn.mont(priv.prime1)); + var c2 = blinded.toRed(bn.mont(priv.prime2)); + var qinv = priv.coefficient; + var p = priv.prime1; + var q = priv.prime2; + var m1 = c1.redPow(priv.exponent1); + var m2 = c2.redPow(priv.exponent2); + m1 = m1.fromRed(); + m2 = m2.fromRed(); + var h = m1.isub(m2).imul(qinv).mod(p); + h.imul(q); + m2.iadd(h); + var out = new Buffer(m2.imul(blinds.unblinder).mod(priv.modulus).toArray()); + if (out.length < len) { + var prefix = new Buffer(len - out.length); + prefix.fill(0); + out = Buffer.concat([prefix, out], len); } - this.words[0] += num; - - // Carry - for (var i = 0; i < this.length && this.words[i] >= 0x4000000; i++) { - this.words[i] -= 0x4000000; - if (i === this.length - 1) - this.words[i + 1] = 1; - else - this.words[i + 1]++; + return out; +} +crt.getr = getr; +function getr(priv) { + var len = priv.modulus.byteLength(); + var r = new bn(randomBytes(len)); + while (r.cmp(priv.modulus) >= 0 || !r.mod(priv.prime1) || !r.mod(priv.prime2)) { + r = new bn(randomBytes(len)); } - this.length = Math.max(this.length, i + 1); + return r; +} +}).call(this,require("buffer").Buffer) +},{"bn.js":217,"buffer":47,"randombytes":190}],85:[function(require,module,exports){ +module.exports={"2.16.840.1.101.3.4.1.1": "aes-128-ecb", +"2.16.840.1.101.3.4.1.2": "aes-128-cbc", +"2.16.840.1.101.3.4.1.3": "aes-128-ofb", +"2.16.840.1.101.3.4.1.4": "aes-128-cfb", +"2.16.840.1.101.3.4.1.21": "aes-192-ecb", +"2.16.840.1.101.3.4.1.22": "aes-192-cbc", +"2.16.840.1.101.3.4.1.23": "aes-192-ofb", +"2.16.840.1.101.3.4.1.24": "aes-192-cfb", +"2.16.840.1.101.3.4.1.41": "aes-256-ecb", +"2.16.840.1.101.3.4.1.42": "aes-256-cbc", +"2.16.840.1.101.3.4.1.43": "aes-256-ofb", +"2.16.840.1.101.3.4.1.44": "aes-256-cfb" +} +},{}],86:[function(require,module,exports){ +// from https://github.com/indutny/self-signed/blob/gh-pages/lib/asn1.js +// Fedor, you are amazing. - return this; -}; +var asn1 = require('asn1.js') -// Subtract plain number `num` from `this` -BN.prototype.isubn = function isubn(num) { - assert(typeof num === 'number'); - if (num < 0) - return this.iaddn(-num); +var RSAPrivateKey = asn1.define('RSAPrivateKey', function () { + this.seq().obj( + this.key('version').int(), + this.key('modulus').int(), + this.key('publicExponent').int(), + this.key('privateExponent').int(), + this.key('prime1').int(), + this.key('prime2').int(), + this.key('exponent1').int(), + this.key('exponent2').int(), + this.key('coefficient').int() + ) +}) +exports.RSAPrivateKey = RSAPrivateKey - if (this.sign) { - this.sign = false; - this.iaddn(num); - this.sign = true; - return this; - } +var RSAPublicKey = asn1.define('RSAPublicKey', function () { + this.seq().obj( + this.key('modulus').int(), + this.key('publicExponent').int() + ) +}) +exports.RSAPublicKey = RSAPublicKey - this.words[0] -= num; +var PublicKey = asn1.define('SubjectPublicKeyInfo', function () { + this.seq().obj( + this.key('algorithm').use(AlgorithmIdentifier), + this.key('subjectPublicKey').bitstr() + ) +}) +exports.PublicKey = PublicKey - // Carry - for (var i = 0; i < this.length && this.words[i] < 0; i++) { - this.words[i] += 0x4000000; - this.words[i + 1] -= 1; - } +var AlgorithmIdentifier = asn1.define('AlgorithmIdentifier', function () { + this.seq().obj( + this.key('algorithm').objid(), + this.key('none').null_().optional(), + this.key('curve').objid().optional(), + this.key('params').seq().obj( + this.key('p').int(), + this.key('q').int(), + this.key('g').int() + ).optional() + ) +}) - return this.strip(); -}; +var PrivateKeyInfo = asn1.define('PrivateKeyInfo', function () { + this.seq().obj( + this.key('version').int(), + this.key('algorithm').use(AlgorithmIdentifier), + this.key('subjectPrivateKey').octstr() + ) +}) +exports.PrivateKey = PrivateKeyInfo +var EncryptedPrivateKeyInfo = asn1.define('EncryptedPrivateKeyInfo', function () { + this.seq().obj( + this.key('algorithm').seq().obj( + this.key('id').objid(), + this.key('decrypt').seq().obj( + this.key('kde').seq().obj( + this.key('id').objid(), + this.key('kdeparams').seq().obj( + this.key('salt').octstr(), + this.key('iters').int() + ) + ), + this.key('cipher').seq().obj( + this.key('algo').objid(), + this.key('iv').octstr() + ) + ) + ), + this.key('subjectPrivateKey').octstr() + ) +}) -BN.prototype.addn = function addn(num) { - return this.clone().iaddn(num); -}; +exports.EncryptedPrivateKey = EncryptedPrivateKeyInfo -BN.prototype.subn = function subn(num) { - return this.clone().isubn(num); -}; +var DSAPrivateKey = asn1.define('DSAPrivateKey', function () { + this.seq().obj( + this.key('version').int(), + this.key('p').int(), + this.key('q').int(), + this.key('g').int(), + this.key('pub_key').int(), + this.key('priv_key').int() + ) +}) +exports.DSAPrivateKey = DSAPrivateKey -BN.prototype.iabs = function iabs() { - this.sign = false; +exports.DSAparam = asn1.define('DSAparam', function () { + this.int() +}) +var ECPrivateKey = asn1.define('ECPrivateKey', function () { + this.seq().obj( + this.key('version').int(), + this.key('privateKey').octstr(), + this.key('parameters').optional().explicit(0).use(ECParameters), + this.key('publicKey').optional().explicit(1).bitstr() + ) +}) +exports.ECPrivateKey = ECPrivateKey +var ECParameters = asn1.define('ECParameters', function () { + this.choice({ + namedCurve: this.objid() + }) +}) - return this -}; +exports.signature = asn1.define('signature', function () { + this.seq().obj( + this.key('r').int(), + this.key('s').int() + ) +}) -BN.prototype.abs = function abs() { - return this.clone().iabs(); -}; +},{"asn1.js":89}],87:[function(require,module,exports){ +(function (Buffer){ +// adapted from https://github.com/apatil/pemstrip +var findProc = /Proc-Type: 4,ENCRYPTED\r?\nDEK-Info: AES-((?:128)|(?:192)|(?:256))-CBC,([0-9A-H]+)\r?\n\r?\n([0-9A-z\n\r\+\/\=]+)\r?\n/m +var startRegex = /^-----BEGIN (.*) KEY-----\r?\n/m +var fullRegex = /^-----BEGIN (.*) KEY-----\r?\n([0-9A-z\n\r\+\/\=]+)\r?\n-----END \1 KEY-----$/m +var evp = require('evp_bytestokey') +var ciphers = require('browserify-aes') +module.exports = function (okey, password) { + var key = okey.toString() + var match = key.match(findProc) + var decrypted + if (!match) { + var match2 = key.match(fullRegex) + decrypted = new Buffer(match2[2].replace(/\r?\n/g, ''), 'base64') + } else { + var suite = 'aes' + match[1] + var iv = new Buffer(match[2], 'hex') + var cipherText = new Buffer(match[3].replace(/\r?\n/g, ''), 'base64') + var cipherKey = evp(password, iv.slice(0, 8), parseInt(match[1], 10)).key + var out = [] + var cipher = ciphers.createDecipheriv(suite, cipherKey, iv) + out.push(cipher.update(cipherText)) + out.push(cipher.final()) + decrypted = Buffer.concat(out) + } + var tag = key.match(startRegex)[1] + ' KEY' + return { + tag: tag, + data: decrypted + } +} -BN.prototype._wordDiv = function _wordDiv(num, mode) { - var shift = this.length - num.length; +}).call(this,require("buffer").Buffer) +},{"browserify-aes":106,"buffer":47,"evp_bytestokey":121}],88:[function(require,module,exports){ +(function (Buffer){ +var asn1 = require('./asn1') +var aesid = require('./aesid.json') +var fixProc = require('./fixProc') +var ciphers = require('browserify-aes') +var compat = require('pbkdf2') +module.exports = parseKeys + +function parseKeys (buffer) { + var password + if (typeof buffer === 'object' && !Buffer.isBuffer(buffer)) { + password = buffer.passphrase + buffer = buffer.key + } + if (typeof buffer === 'string') { + buffer = new Buffer(buffer) + } - var a = this.clone(); - var b = num; + var stripped = fixProc(buffer, password) - var q = mode !== 'mod' && new BN(0); - var sign = false; - - // Approximate quotient at each step - while (a.length > b.length) { - // NOTE: a.length is always >= 2, because of the condition .div() - var hi = a.words[a.length - 1] * 0x4000000 + a.words[a.length - 2]; - var sq = (hi / b.words[b.length - 1]); - var sqhi = (sq / 0x4000000) | 0; - var sqlo = sq & 0x3ffffff; - sq = new BN(null); - sq.words = [ sqlo, sqhi ]; - sq.length = 2; - - // Collect quotient - var shift = (a.length - b.length - 1) * 26; - if (q) { - var t = sq.shln(shift); - if (a.sign) - q.isub(t); - else - q.iadd(t); - } + var type = stripped.tag + var data = stripped.data + var subtype, ndata + switch (type) { + case 'PUBLIC KEY': + ndata = asn1.PublicKey.decode(data, 'der') + subtype = ndata.algorithm.algorithm.join('.') + switch (subtype) { + case '1.2.840.113549.1.1.1': + return asn1.RSAPublicKey.decode(ndata.subjectPublicKey.data, 'der') + case '1.2.840.10045.2.1': + ndata.subjectPrivateKey = ndata.subjectPublicKey + return { + type: 'ec', + data: ndata + } + case '1.2.840.10040.4.1': + ndata.algorithm.params.pub_key = asn1.DSAparam.decode(ndata.subjectPublicKey.data, 'der') + return { + type: 'dsa', + data: ndata.algorithm.params + } + default: throw new Error('unknown key id ' + subtype) + } + throw new Error('unknown key type ' + type) + case 'ENCRYPTED PRIVATE KEY': + data = asn1.EncryptedPrivateKey.decode(data, 'der') + data = decrypt(data, password) + // falls through + case 'PRIVATE KEY': + ndata = asn1.PrivateKey.decode(data, 'der') + subtype = ndata.algorithm.algorithm.join('.') + switch (subtype) { + case '1.2.840.113549.1.1.1': + return asn1.RSAPrivateKey.decode(ndata.subjectPrivateKey, 'der') + case '1.2.840.10045.2.1': + return { + curve: ndata.algorithm.curve, + privateKey: asn1.ECPrivateKey.decode(ndata.subjectPrivateKey, 'der').privateKey + } + case '1.2.840.10040.4.1': + ndata.algorithm.params.priv_key = asn1.DSAparam.decode(ndata.subjectPrivateKey, 'der') + return { + type: 'dsa', + params: ndata.algorithm.params + } + default: throw new Error('unknown key id ' + subtype) + } + throw new Error('unknown key type ' + type) + case 'RSA PUBLIC KEY': + return asn1.RSAPublicKey.decode(data, 'der') + case 'RSA PRIVATE KEY': + return asn1.RSAPrivateKey.decode(data, 'der') + case 'DSA PRIVATE KEY': + return { + type: 'dsa', + params: asn1.DSAPrivateKey.decode(data, 'der') + } + case 'EC PRIVATE KEY': + data = asn1.ECPrivateKey.decode(data, 'der') + return { + curve: data.parameters.value, + privateKey: data.privateKey + } + default: throw new Error('unknown key type ' + type) + } +} +parseKeys.signature = asn1.signature +function decrypt (data, password) { + var salt = data.algorithm.decrypt.kde.kdeparams.salt + var iters = parseInt(data.algorithm.decrypt.kde.kdeparams.iters.toString(), 10) + var algo = aesid[data.algorithm.decrypt.cipher.algo.join('.')] + var iv = data.algorithm.decrypt.cipher.iv + var cipherText = data.subjectPrivateKey + var keylen = parseInt(algo.split('-')[1], 10) / 8 + var key = compat.pbkdf2Sync(password, salt, iters, keylen) + var cipher = ciphers.createDecipheriv(algo, key, iv) + var out = [] + out.push(cipher.update(cipherText)) + out.push(cipher.final()) + return Buffer.concat(out) +} - sq = sq.mul(b).ishln(shift); - if (a.sign) - a.iadd(sq) - else - a.isub(sq); - } - // At this point a.length <= b.length - while (a.ucmp(b) >= 0) { - // NOTE: a.length is always >= 2, because of the condition above - var hi = a.words[a.length - 1]; - var sq = new BN((hi / b.words[b.length - 1]) | 0); - var shift = (a.length - b.length) * 26; - - if (q) { - var t = sq.shln(shift); - if (a.sign) - q.isub(t); - else - q.iadd(t); - } +}).call(this,require("buffer").Buffer) +},{"./aesid.json":85,"./asn1":86,"./fixProc":87,"browserify-aes":106,"buffer":47,"pbkdf2":145}],89:[function(require,module,exports){ +var asn1 = exports; - sq = sq.mul(b).ishln(shift); +asn1.bignum = require('bn.js'); - if (a.sign) - a.iadd(sq); - else - a.isub(sq); - } +asn1.define = require('./asn1/api').define; +asn1.base = require('./asn1/base'); +asn1.constants = require('./asn1/constants'); +asn1.decoders = require('./asn1/decoders'); +asn1.encoders = require('./asn1/encoders'); - if (a.sign) { - if (q) - q.isubn(1); - a.iadd(b); - } - return { div: q ? q : null, mod: a }; -}; +},{"./asn1/api":90,"./asn1/base":92,"./asn1/constants":96,"./asn1/decoders":98,"./asn1/encoders":101,"bn.js":217}],90:[function(require,module,exports){ +var asn1 = require('../asn1'); +var inherits = require('inherits'); -BN.prototype.divmod = function divmod(num, mode) { - assert(num.cmpn(0) !== 0); +var api = exports; - if (this.sign && !num.sign) { - var res = this.neg().divmod(num, mode); - var div; - var mod; - if (mode !== 'mod') - div = res.div.neg(); - if (mode !== 'div') - mod = res.mod.cmpn(0) === 0 ? res.mod : num.sub(res.mod); - return { - div: div, - mod: mod - }; - } else if (!this.sign && num.sign) { - var res = this.divmod(num.neg(), mode); - var div; - if (mode !== 'mod') - div = res.div.neg(); - return { div: div, mod: res.mod }; - } else if (this.sign && num.sign) { - return this.neg().divmod(num.neg(), mode); - } +api.define = function define(name, body) { + return new Entity(name, body); +}; - // Both numbers are positive at this point +function Entity(name, body) { + this.name = name; + this.body = body; - // Strip both numbers to approximate shift value - if (num.length > this.length || this.cmp(num) < 0) - return { div: new BN(0), mod: this }; + this.decoders = {}; + this.encoders = {}; +}; - // Very short reduction - if (num.length === 1) { - if (mode === 'div') - return { div: this.divn(num.words[0]), mod: null }; - else if (mode === 'mod') - return { div: null, mod: new BN(this.modn(num.words[0])) }; - return { - div: this.divn(num.words[0]), - mod: new BN(this.modn(num.words[0])) +Entity.prototype._createNamed = function createNamed(base) { + var named; + try { + named = require('vm').runInThisContext( + '(function ' + this.name + '(entity) {\n' + + ' this._initNamed(entity);\n' + + '})' + ); + } catch (e) { + named = function (entity) { + this._initNamed(entity); }; } + inherits(named, base); + named.prototype._initNamed = function initnamed(entity) { + base.call(this, entity); + }; - return this._wordDiv(num, mode); + return new named(this); }; -// Find `this` / `num` -BN.prototype.div = function div(num) { - return this.divmod(num, 'div').div; +Entity.prototype._getDecoder = function _getDecoder(enc) { + // Lazily create decoder + if (!this.decoders.hasOwnProperty(enc)) + this.decoders[enc] = this._createNamed(asn1.decoders[enc]); + return this.decoders[enc]; }; -// Find `this` % `num` -BN.prototype.mod = function mod(num) { - return this.divmod(num, 'mod').mod; +Entity.prototype.decode = function decode(data, enc, options) { + return this._getDecoder(enc).decode(data, options); }; -// Find Round(`this` / `num`) -BN.prototype.divRound = function divRound(num) { - var dm = this.divmod(num); - - // Fast case - exact division - if (dm.mod.cmpn(0) === 0) - return dm.div; - - var mod = dm.div.sign ? dm.mod.isub(num) : dm.mod; - - var half = num.shrn(1); - var r2 = num.andln(1); - var cmp = mod.cmp(half); - - // Round down - if (cmp < 0 || r2 === 1 && cmp === 0) - return dm.div; +Entity.prototype._getEncoder = function _getEncoder(enc) { + // Lazily create encoder + if (!this.encoders.hasOwnProperty(enc)) + this.encoders[enc] = this._createNamed(asn1.encoders[enc]); + return this.encoders[enc]; +}; - // Round up - return dm.div.sign ? dm.div.isubn(1) : dm.div.iaddn(1); +Entity.prototype.encode = function encode(data, enc, /* internal */ reporter) { + return this._getEncoder(enc).encode(data, reporter); }; -BN.prototype.modn = function modn(num) { - assert(num <= 0x3ffffff); - var p = (1 << 26) % num; +},{"../asn1":89,"inherits":240,"vm":215}],91:[function(require,module,exports){ +var inherits = require('inherits'); +var Reporter = require('../base').Reporter; +var Buffer = require('buffer').Buffer; - var acc = 0; - for (var i = this.length - 1; i >= 0; i--) - acc = (p * acc + this.words[i]) % num; +function DecoderBuffer(base, options) { + Reporter.call(this, options); + if (!Buffer.isBuffer(base)) { + this.error('Input not Buffer'); + return; + } - return acc; + this.base = base; + this.offset = 0; + this.length = base.length; +} +inherits(DecoderBuffer, Reporter); +exports.DecoderBuffer = DecoderBuffer; + +DecoderBuffer.prototype.save = function save() { + return { offset: this.offset, reporter: Reporter.prototype.save.call(this) }; }; -// In-place division by number -BN.prototype.idivn = function idivn(num) { - assert(num <= 0x3ffffff); +DecoderBuffer.prototype.restore = function restore(save) { + // Return skipped data + var res = new DecoderBuffer(this.base); + res.offset = save.offset; + res.length = this.offset; - var carry = 0; - for (var i = this.length - 1; i >= 0; i--) { - var w = this.words[i] + carry * 0x4000000; - this.words[i] = (w / num) | 0; - carry = w % num; - } + this.offset = save.offset; + Reporter.prototype.restore.call(this, save.reporter); - return this.strip(); + return res; }; -BN.prototype.divn = function divn(num) { - return this.clone().idivn(num); +DecoderBuffer.prototype.isEmpty = function isEmpty() { + return this.offset === this.length; }; -BN.prototype._egcd = function _egcd(x1, p) { - assert(!p.sign); - assert(p.cmpn(0) !== 0); +DecoderBuffer.prototype.readUInt8 = function readUInt8(fail) { + if (this.offset + 1 <= this.length) + return this.base.readUInt8(this.offset++, true); + else + return this.error(fail || 'DecoderBuffer overrun'); +} - var a = this; - var b = p.clone(); +DecoderBuffer.prototype.skip = function skip(bytes, fail) { + if (!(this.offset + bytes <= this.length)) + return this.error(fail || 'DecoderBuffer overrun'); - if (a.sign) - a = a.mod(p); - else - a = a.clone(); + var res = new DecoderBuffer(this.base); - var x2 = new BN(0); - while (b.isEven()) - b.ishrn(1); - var delta = b.clone(); - while (a.cmpn(1) > 0 && b.cmpn(1) > 0) { - while (a.isEven()) { - a.ishrn(1); - if (x1.isEven()) - x1.ishrn(1); - else - x1.iadd(delta).ishrn(1); - } - while (b.isEven()) { - b.ishrn(1); - if (x2.isEven()) - x2.ishrn(1); - else - x2.iadd(delta).ishrn(1); - } - if (a.cmp(b) >= 0) { - a.isub(b); - x1.isub(x2); - } else { - b.isub(a); - x2.isub(x1); - } - } - if (a.cmpn(1) === 0) - return x1; - else - return x2; -}; + // Share reporter state + res._reporterState = this._reporterState; -BN.prototype.gcd = function gcd(num) { - if (this.cmpn(0) === 0) - return num.clone(); - if (num.cmpn(0) === 0) - return this.clone(); + res.offset = this.offset; + res.length = this.offset + bytes; + this.offset += bytes; + return res; +} - var a = this.clone(); - var b = num.clone(); - a.sign = false; - b.sign = false; +DecoderBuffer.prototype.raw = function raw(save) { + return this.base.slice(save ? save.offset : this.offset, this.length); +} - // Remove common factor of two - for (var shift = 0; a.isEven() && b.isEven(); shift++) { - a.ishrn(1); - b.ishrn(1); +function EncoderBuffer(value, reporter) { + if (Array.isArray(value)) { + this.length = 0; + this.value = value.map(function(item) { + if (!(item instanceof EncoderBuffer)) + item = new EncoderBuffer(item, reporter); + this.length += item.length; + return item; + }, this); + } else if (typeof value === 'number') { + if (!(0 <= value && value <= 0xff)) + return reporter.error('non-byte EncoderBuffer value'); + this.value = value; + this.length = 1; + } else if (typeof value === 'string') { + this.value = value; + this.length = Buffer.byteLength(value); + } else if (Buffer.isBuffer(value)) { + this.value = value; + this.length = value.length; + } else { + return reporter.error('Unsupported type: ' + typeof value); } +} +exports.EncoderBuffer = EncoderBuffer; - while (a.isEven()) - a.ishrn(1); +EncoderBuffer.prototype.join = function join(out, offset) { + if (!out) + out = new Buffer(this.length); + if (!offset) + offset = 0; - do { - while (b.isEven()) - b.ishrn(1); + if (this.length === 0) + return out; - // Swap `a` and `b` to make `a` always bigger than `b` - if (a.cmp(b) < 0) { - var t = a; - a = b; - b = t; - } - a.isub(a.div(b).mul(b)); - } while (a.cmpn(0) !== 0 && b.cmpn(0) !== 0); - if (a.cmpn(0) === 0) - return b.ishln(shift); - else - return a.ishln(shift); -}; + if (Array.isArray(this.value)) { + this.value.forEach(function(item) { + item.join(out, offset); + offset += item.length; + }); + } else { + if (typeof this.value === 'number') + out[offset] = this.value; + else if (typeof this.value === 'string') + out.write(this.value, offset); + else if (Buffer.isBuffer(this.value)) + this.value.copy(out, offset); + offset += this.length; + } -// Invert number in the field F(num) -BN.prototype.invm = function invm(num) { - return this._egcd(new BN(1), num).mod(num); + return out; }; -BN.prototype.isEven = function isEven(num) { - return (this.words[0] & 1) === 0; -}; +},{"../base":92,"buffer":47,"inherits":240}],92:[function(require,module,exports){ +var base = exports; -BN.prototype.isOdd = function isOdd(num) { - return (this.words[0] & 1) === 1; -}; +base.Reporter = require('./reporter').Reporter; +base.DecoderBuffer = require('./buffer').DecoderBuffer; +base.EncoderBuffer = require('./buffer').EncoderBuffer; +base.Node = require('./node'); -// And first word and num -BN.prototype.andln = function andln(num) { - return this.words[0] & num; -}; +},{"./buffer":91,"./node":93,"./reporter":94}],93:[function(require,module,exports){ +var Reporter = require('../base').Reporter; +var EncoderBuffer = require('../base').EncoderBuffer; +var assert = require('minimalistic-assert'); -// Increment at the bit position in-line -BN.prototype.bincn = function bincn(bit) { - assert(typeof bit === 'number'); - var r = bit % 26; - var s = (bit - r) / 26; - var q = 1 << r; +// Supported tags +var tags = [ + 'seq', 'seqof', 'set', 'setof', 'octstr', 'bitstr', 'objid', 'bool', + 'gentime', 'utctime', 'null_', 'enum', 'int', 'ia5str', 'utf8str' +]; - // Fast case: bit is much higher than all existing words - if (this.length <= s) { - for (var i = this.length; i < s + 1; i++) - this.words[i] = 0; - this.words[s] |= q; - this.length = s + 1; - return this; - } +// Public methods list +var methods = [ + 'key', 'obj', 'use', 'optional', 'explicit', 'implicit', 'def', 'choice', + 'any' +].concat(tags); - // Add bit and propagate, if needed - var carry = q; - for (var i = s; carry !== 0 && i < this.length; i++) { - var w = this.words[i]; - w += carry; - carry = w >>> 26; - w &= 0x3ffffff; - this.words[i] = w; - } - if (carry !== 0) { - this.words[i] = carry; - this.length++; - } - return this; -}; +// Overrided methods list +var overrided = [ + '_peekTag', '_decodeTag', '_use', + '_decodeStr', '_decodeObjid', '_decodeTime', + '_decodeNull', '_decodeInt', '_decodeBool', '_decodeList', -BN.prototype.cmpn = function cmpn(num) { - var sign = num < 0; - if (sign) - num = -num; + '_encodeComposite', '_encodeStr', '_encodeObjid', '_encodeTime', + '_encodeNull', '_encodeInt', '_encodeBool' +]; - if (this.sign && !sign) - return -1; - else if (!this.sign && sign) - return 1; +function Node(enc, parent) { + var state = {}; + this._baseState = state; - num &= 0x3ffffff; - this.strip(); + state.enc = enc; - var res; - if (this.length > 1) { - res = 1; - } else { - var w = this.words[0]; - res = w === num ? 0 : w < num ? -1 : 1; + state.parent = parent || null; + state.children = null; + + // State + state.tag = null; + state.args = null; + state.reverseArgs = null; + state.choice = null; + state.optional = false; + state.any = false; + state.obj = false; + state.use = null; + state.useDecoder = null; + state.key = null; + state['default'] = null; + state.explicit = null; + state.implicit = null; + + // Should create new instance on each method + if (!state.parent) { + state.children = []; + this._wrap(); } - if (this.sign) - res = -res; +} +module.exports = Node; + +var stateProps = [ + 'enc', 'parent', 'children', 'tag', 'args', 'reverseArgs', 'choice', + 'optional', 'any', 'obj', 'use', 'alteredUse', 'key', 'default', 'explicit', + 'implicit' +]; + +Node.prototype.clone = function clone() { + var state = this._baseState; + var cstate = {}; + stateProps.forEach(function(prop) { + cstate[prop] = state[prop]; + }); + var res = new this.constructor(cstate.parent); + res._baseState = cstate; return res; }; -// Compare two numbers and return: -// 1 - if `this` > `num` -// 0 - if `this` == `num` -// -1 - if `this` < `num` -BN.prototype.cmp = function cmp(num) { - if (this.sign && !num.sign) - return -1; - else if (!this.sign && num.sign) - return 1; +Node.prototype._wrap = function wrap() { + var state = this._baseState; + methods.forEach(function(method) { + this[method] = function _wrappedMethod() { + var clone = new this.constructor(this); + state.children.push(clone); + return clone[method].apply(clone, arguments); + }; + }, this); +}; - var res = this.ucmp(num); - if (this.sign) - return -res; - else - return res; +Node.prototype._init = function init(body) { + var state = this._baseState; + + assert(state.parent === null); + body.call(this); + + // Filter children + state.children = state.children.filter(function(child) { + return child._baseState.parent === this; + }, this); + assert.equal(state.children.length, 1, 'Root node can have only one child'); }; -// Unsigned comparison -BN.prototype.ucmp = function ucmp(num) { - // At this point both numbers have the same sign - if (this.length > num.length) - return 1; - else if (this.length < num.length) - return -1; +Node.prototype._useArgs = function useArgs(args) { + var state = this._baseState; - var res = 0; - for (var i = this.length - 1; i >= 0; i--) { - var a = this.words[i]; - var b = num.words[i]; + // Filter children and args + var children = args.filter(function(arg) { + return arg instanceof this.constructor; + }, this); + args = args.filter(function(arg) { + return !(arg instanceof this.constructor); + }, this); - if (a === b) - continue; - if (a < b) - res = -1; - else if (a > b) - res = 1; - break; + if (children.length !== 0) { + assert(state.children === null); + state.children = children; + + // Replace parent to maintain backward link + children.forEach(function(child) { + child._baseState.parent = this; + }, this); + } + if (args.length !== 0) { + assert(state.args === null); + state.args = args; + state.reverseArgs = args.map(function(arg) { + if (typeof arg !== 'object' || arg.constructor !== Object) + return arg; + + var res = {}; + Object.keys(arg).forEach(function(key) { + if (key == (key | 0)) + key |= 0; + var value = arg[key]; + res[value] = key; + }); + return res; + }); } - return res; }; // -// A reduce context, could be using montgomery or something better, depending -// on the `m` itself. +// Overrided methods // -BN.red = function red(num) { - return new Red(num); -}; -BN.prototype.toRed = function toRed(ctx) { - assert(!this.red, 'Already a number in reduction context'); - assert(!this.sign, 'red works only with positives'); - return ctx.convertTo(this)._forceRed(ctx); -}; +overrided.forEach(function(method) { + Node.prototype[method] = function _overrided() { + var state = this._baseState; + throw new Error(method + ' not implemented for encoding: ' + state.enc); + }; +}); -BN.prototype.fromRed = function fromRed() { - assert(this.red, 'fromRed works only with numbers in reduction context'); - return this.red.convertFrom(this); -}; +// +// Public methods +// -BN.prototype._forceRed = function _forceRed(ctx) { - this.red = ctx; - return this; -}; +tags.forEach(function(tag) { + Node.prototype[tag] = function _tagMethod() { + var state = this._baseState; + var args = Array.prototype.slice.call(arguments); -BN.prototype.forceRed = function forceRed(ctx) { - assert(!this.red, 'Already a number in reduction context'); - return this._forceRed(ctx); -}; + assert(state.tag === null); + state.tag = tag; -BN.prototype.redAdd = function redAdd(num) { - assert(this.red, 'redAdd works only with red numbers'); - return this.red.add(this, num); -}; + this._useArgs(args); -BN.prototype.redIAdd = function redIAdd(num) { - assert(this.red, 'redIAdd works only with red numbers'); - return this.red.iadd(this, num); -}; + return this; + }; +}); -BN.prototype.redSub = function redSub(num) { - assert(this.red, 'redSub works only with red numbers'); - return this.red.sub(this, num); -}; +Node.prototype.use = function use(item) { + var state = this._baseState; -BN.prototype.redISub = function redISub(num) { - assert(this.red, 'redISub works only with red numbers'); - return this.red.isub(this, num); -}; + assert(state.use === null); + state.use = item; -BN.prototype.redShl = function redShl(num) { - assert(this.red, 'redShl works only with red numbers'); - return this.red.shl(this, num); + return this; }; -BN.prototype.redMul = function redMul(num) { - assert(this.red, 'redMul works only with red numbers'); - this.red._verify2(this, num); - return this.red.mul(this, num); -}; +Node.prototype.optional = function optional() { + var state = this._baseState; -BN.prototype.redIMul = function redIMul(num) { - assert(this.red, 'redMul works only with red numbers'); - this.red._verify2(this, num); - return this.red.imul(this, num); -}; + state.optional = true; -BN.prototype.redSqr = function redSqr() { - assert(this.red, 'redSqr works only with red numbers'); - this.red._verify1(this); - return this.red.sqr(this); + return this; }; -BN.prototype.redISqr = function redISqr() { - assert(this.red, 'redISqr works only with red numbers'); - this.red._verify1(this); - return this.red.isqr(this); -}; +Node.prototype.def = function def(val) { + var state = this._baseState; -// Square root over p -BN.prototype.redSqrt = function redSqrt() { - assert(this.red, 'redSqrt works only with red numbers'); - this.red._verify1(this); - return this.red.sqrt(this); -}; + assert(state['default'] === null); + state['default'] = val; + state.optional = true; -BN.prototype.redInvm = function redInvm() { - assert(this.red, 'redInvm works only with red numbers'); - this.red._verify1(this); - return this.red.invm(this); + return this; }; -// Return negative clone of `this` % `red modulo` -BN.prototype.redNeg = function redNeg() { - assert(this.red, 'redNeg works only with red numbers'); - this.red._verify1(this); - return this.red.neg(this); -}; +Node.prototype.explicit = function explicit(num) { + var state = this._baseState; -BN.prototype.redPow = function redPow(num) { - assert(this.red && !num.red, 'redPow(normalNum)'); - this.red._verify1(this); - return this.red.pow(this, num); -}; + assert(state.explicit === null && state.implicit === null); + state.explicit = num; -// Prime numbers with efficient reduction -var primes = { - k256: null, - p224: null, - p192: null, - p25519: null + return this; }; -// Pseudo-Mersenne prime -function MPrime(name, p) { - // P = 2 ^ N - K - this.name = name; - this.p = new BN(p, 16); - this.n = this.p.bitLength(); - this.k = new BN(1).ishln(this.n).isub(this.p); +Node.prototype.implicit = function implicit(num) { + var state = this._baseState; - this.tmp = this._tmp(); -} + assert(state.explicit === null && state.implicit === null); + state.implicit = num; -MPrime.prototype._tmp = function _tmp() { - var tmp = new BN(null); - tmp.words = new Array(Math.ceil(this.n / 13)); - return tmp; + return this; }; -MPrime.prototype.ireduce = function ireduce(num) { - // Assumes that `num` is less than `P^2` - // num = HI * (2 ^ N - K) + HI * K + LO = HI * K + LO (mod P) - var r = num; - var rlen; +Node.prototype.obj = function obj() { + var state = this._baseState; + var args = Array.prototype.slice.call(arguments); - do { - var pair = r.ishrn(this.n, 0, this.tmp); - r = this.imulK(pair.hi); - r = r.iadd(pair.lo); - rlen = r.bitLength(); - } while (rlen > this.n); + state.obj = true; - var cmp = rlen < this.n ? -1 : r.cmp(this.p); - if (cmp === 0) { - r.words[0] = 0; - r.length = 1; - } else if (cmp > 0) { - r.isub(this.p); - } else { - r.strip(); - } + if (args.length !== 0) + this._useArgs(args); - return r; + return this; }; -MPrime.prototype.imulK = function imulK(num) { - return num.imul(this.k); +Node.prototype.key = function key(newKey) { + var state = this._baseState; + + assert(state.key === null); + state.key = newKey; + + return this; }; -function K256() { - MPrime.call( - this, - 'k256', - 'ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff fffffffe fffffc2f'); -} -inherits(K256, MPrime); +Node.prototype.any = function any() { + var state = this._baseState; -K256.prototype.imulK = function imulK(num) { - // K = 0x1000003d1 = [ 0x40, 0x3d1 ] - num.words[num.length] = 0; - num.words[num.length + 1] = 0; - num.length += 2; + state.any = true; - var uhi = 0; - var hi = 0; - var lo = 0; - for (var i = 0; i < num.length; i++) { - var w = num.words[i]; - hi += w * 0x40; - lo += w * 0x3d1; - hi += (lo / 0x4000000) | 0; - uhi += (hi / 0x4000000) | 0; - hi &= 0x3ffffff; - lo &= 0x3ffffff; + return this; +}; - num.words[i] = lo; +Node.prototype.choice = function choice(obj) { + var state = this._baseState; - lo = hi; - hi = uhi; - uhi = 0; - } + assert(state.choice === null); + state.choice = obj; + this._useArgs(Object.keys(obj).map(function(key) { + return obj[key]; + })); - // Fast length reduction - if (num.words[num.length - 1] === 0) - num.length--; - if (num.words[num.length - 1] === 0) - num.length--; - return num; + return this; }; -function P224() { - MPrime.call( - this, - 'p224', - 'ffffffff ffffffff ffffffff ffffffff 00000000 00000000 00000001'); -} -inherits(P224, MPrime); +// +// Decoding +// -function P192() { - MPrime.call( - this, - 'p192', - 'ffffffff ffffffff ffffffff fffffffe ffffffff ffffffff'); -} -inherits(P192, MPrime); +Node.prototype._decode = function decode(input) { + var state = this._baseState; -function P25519() { - // 2 ^ 255 - 19 - MPrime.call( - this, - '25519', - '7fffffffffffffff ffffffffffffffff ffffffffffffffff ffffffffffffffed'); -} -inherits(P25519, MPrime); + // Decode root node + if (state.parent === null) + return input.wrapResult(state.children[0]._decode(input)); -P25519.prototype.imulK = function imulK(num) { - // K = 0x13 - var carry = 0; - for (var i = 0; i < num.length; i++) { - var hi = num.words[i] * 0x13 + carry; - var lo = hi & 0x3ffffff; - hi >>>= 26; + var result = state['default']; + var present = true; - num.words[i] = lo; - carry = hi; - } - if (carry !== 0) - num.words[num.length++] = carry; - return num; -}; + var prevKey; + if (state.key !== null) + prevKey = input.enterKey(state.key); -// Exported mostly for testing purposes, use plain name instead -BN._prime = function prime(name) { - // Cached version of prime - if (primes[name]) - return primes[name]; + // Check if tag is there + if (state.optional) { + var tag = null; + if (state.explicit !== null) + tag = state.explicit; + else if (state.implicit !== null) + tag = state.implicit; + else if (state.tag !== null) + tag = state.tag; + + if (tag === null && !state.any) { + // Trial and Error + var save = input.save(); + try { + if (state.choice === null) + this._decodeGeneric(state.tag, input); + else + this._decodeChoice(input); + present = true; + } catch (e) { + present = false; + } + input.restore(save); + } else { + present = this._peekTag(input, tag, state.any); - var prime; - if (name === 'k256') - prime = new K256(); - else if (name === 'p224') - prime = new P224(); - else if (name === 'p192') - prime = new P192(); - else if (name === 'p25519') - prime = new P25519(); - else - throw new Error('Unknown prime ' + name); - primes[name] = prime; + if (input.isError(present)) + return present; + } + } - return prime; -} + // Push object on stack + var prevObj; + if (state.obj && present) + prevObj = input.enterObject(); -// -// Base reduction engine -// -function Red(m) { - if (typeof m === 'string') { - var prime = BN._prime(m); - this.m = prime.p; - this.prime = prime; - } else { - this.m = m; - this.prime = null; + if (present) { + // Unwrap explicit values + if (state.explicit !== null) { + var explicit = this._decodeTag(input, state.explicit); + if (input.isError(explicit)) + return explicit; + input = explicit; + } + + // Unwrap implicit and normal values + if (state.use === null && state.choice === null) { + if (state.any) + var save = input.save(); + var body = this._decodeTag( + input, + state.implicit !== null ? state.implicit : state.tag, + state.any + ); + if (input.isError(body)) + return body; + + if (state.any) + result = input.raw(save); + else + input = body; + } + + // Select proper method for tag + if (state.any) + result = result; + else if (state.choice === null) + result = this._decodeGeneric(state.tag, input); + else + result = this._decodeChoice(input); + + if (input.isError(result)) + return result; + + // Decode children + if (!state.any && state.choice === null && state.children !== null) { + var fail = state.children.some(function decodeChildren(child) { + // NOTE: We are ignoring errors here, to let parser continue with other + // parts of encoded data + child._decode(input); + }); + if (fail) + return err; + } } -} -Red.prototype._verify1 = function _verify1(a) { - assert(!a.sign, 'red works only with positives'); - assert(a.red, 'red works only with red numbers'); -}; + // Pop object + if (state.obj && present) + result = input.leaveObject(prevObj); -Red.prototype._verify2 = function _verify2(a, b) { - assert(!a.sign && !b.sign, 'red works only with positives'); - assert(a.red && a.red === b.red, - 'red works only with red numbers'); -}; + // Set key + if (state.key !== null && (result !== null || present === true)) + input.leaveKey(prevKey, state.key, result); -Red.prototype.imod = function imod(a) { - if (this.prime) - return this.prime.ireduce(a)._forceRed(this); - return a.mod(this.m)._forceRed(this); + return result; }; -Red.prototype.neg = function neg(a) { - var r = a.clone(); - r.sign = !r.sign; - return r.iadd(this.m)._forceRed(this); -}; +Node.prototype._decodeGeneric = function decodeGeneric(tag, input) { + var state = this._baseState; -Red.prototype.add = function add(a, b) { - this._verify2(a, b); + if (tag === 'seq' || tag === 'set') + return null; + if (tag === 'seqof' || tag === 'setof') + return this._decodeList(input, tag, state.args[0]); + else if (tag === 'octstr' || tag === 'bitstr') + return this._decodeStr(input, tag); + else if (tag === 'ia5str' || tag === 'utf8str') + return this._decodeStr(input, tag); + else if (tag === 'objid' && state.args) + return this._decodeObjid(input, state.args[0], state.args[1]); + else if (tag === 'objid') + return this._decodeObjid(input, null, null); + else if (tag === 'gentime' || tag === 'utctime') + return this._decodeTime(input, tag); + else if (tag === 'null_') + return this._decodeNull(input); + else if (tag === 'bool') + return this._decodeBool(input); + else if (tag === 'int' || tag === 'enum') + return this._decodeInt(input, state.args && state.args[0]); + else if (state.use !== null) + return this._getUse(state.use, input._reporterState.obj)._decode(input); + else + return input.error('unknown tag: ' + tag); - var res = a.add(b); - if (res.cmp(this.m) >= 0) - res.isub(this.m); - return res._forceRed(this); + return null; }; -Red.prototype.iadd = function iadd(a, b) { - this._verify2(a, b); +Node.prototype._getUse = function _getUse(entity, obj) { - var res = a.iadd(b); - if (res.cmp(this.m) >= 0) - res.isub(this.m); - return res; + var state = this._baseState; + // Create altered use decoder if implicit is set + state.useDecoder = this._use(entity, obj); + assert(state.useDecoder._baseState.parent === null); + state.useDecoder = state.useDecoder._baseState.children[0]; + if (state.implicit !== state.useDecoder._baseState.implicit) { + state.useDecoder = state.useDecoder.clone(); + state.useDecoder._baseState.implicit = state.implicit; + } + return state.useDecoder; }; -Red.prototype.sub = function sub(a, b) { - this._verify2(a, b); +Node.prototype._decodeChoice = function decodeChoice(input) { + var state = this._baseState; + var result = null; + var match = false; - var res = a.sub(b); - if (res.cmpn(0) < 0) - res.iadd(this.m); - return res._forceRed(this); -}; + Object.keys(state.choice).some(function(key) { + var save = input.save(); + var node = state.choice[key]; + try { + var value = node._decode(input); + if (input.isError(value)) + return false; -Red.prototype.isub = function isub(a, b) { - this._verify2(a, b); + result = { type: key, value: value }; + match = true; + } catch (e) { + input.restore(save); + return false; + } + return true; + }, this); - var res = a.isub(b); - if (res.cmpn(0) < 0) - res.iadd(this.m); - return res; -}; + if (!match) + return input.error('Choice not matched'); -Red.prototype.shl = function shl(a, num) { - this._verify1(a); - return this.imod(a.shln(num)); + return result; }; -Red.prototype.imul = function imul(a, b) { - this._verify2(a, b); - return this.imod(a.imul(b)); -}; +// +// Encoding +// -Red.prototype.mul = function mul(a, b) { - this._verify2(a, b); - return this.imod(a.mul(b)); +Node.prototype._createEncoderBuffer = function createEncoderBuffer(data) { + return new EncoderBuffer(data, this.reporter); }; -Red.prototype.isqr = function isqr(a) { - return this.imul(a, a); -}; +Node.prototype._encode = function encode(data, reporter, parent) { + var state = this._baseState; + if (state['default'] !== null && state['default'] === data) + return; -Red.prototype.sqr = function sqr(a) { - return this.mul(a, a); + var result = this._encodeValue(data, reporter, parent); + if (result === undefined) + return; + + if (this._skipDefault(result, reporter, parent)) + return; + + return result; }; -Red.prototype.sqrt = function sqrt(a) { - if (a.cmpn(0) === 0) - return a.clone(); +Node.prototype._encodeValue = function encode(data, reporter, parent) { + var state = this._baseState; - var mod3 = this.m.andln(3); - assert(mod3 % 2 === 1); + // Decode root node + if (state.parent === null) + return state.children[0]._encode(data, reporter || new Reporter()); - // Fast case - if (mod3 === 3) { - var pow = this.m.add(new BN(1)).ishrn(2); - var r = this.pow(a, pow); - return r; - } + var result = null; + var present = true; - // Tonelli-Shanks algorithm (Totally unoptimized and slow) - // - // Find Q and S, that Q * 2 ^ S = (P - 1) - var q = this.m.subn(1); - var s = 0; - while (q.cmpn(0) !== 0 && q.andln(1) === 0) { - s++; - q.ishrn(1); + // Set reporter to share it with a child class + this.reporter = reporter; + + // Check if data is there + if (state.optional && data === undefined) { + if (state['default'] !== null) + data = state['default'] + else + return; } - assert(q.cmpn(0) !== 0); - var one = new BN(1).toRed(this); - var nOne = one.redNeg(); + // For error reporting + var prevKey; - // Find quadratic non-residue - // NOTE: Max is such because of generalized Riemann hypothesis. - var lpow = this.m.subn(1).ishrn(1); - var z = this.m.bitLength(); - z = new BN(2 * z * z).toRed(this); - while (this.pow(z, lpow).cmp(nOne) !== 0) - z.redIAdd(nOne); + // Encode children first + var content = null; + var primitive = false; + if (state.any) { + // Anything that was given is translated to buffer + result = this._createEncoderBuffer(data); + } else if (state.choice) { + result = this._encodeChoice(data, reporter); + } else if (state.children) { + content = state.children.map(function(child) { + if (child._baseState.tag === 'null_') + return child._encode(null, reporter, data); - var c = this.pow(z, q); - var r = this.pow(a, q.addn(1).ishrn(1)); - var t = this.pow(a, q); - var m = s; - while (t.cmp(one) !== 0) { - var tmp = t; - for (var i = 0; tmp.cmp(one) !== 0; i++) - tmp = tmp.redSqr(); - assert(i < m); - var b = this.pow(c, new BN(1).ishln(m - i - 1)); + if (child._baseState.key === null) + return reporter.error('Child should have a key'); + var prevKey = reporter.enterKey(child._baseState.key); - r = r.redMul(b); - c = b.redSqr(); - t = t.redMul(c); - m = i; - } + if (typeof data !== 'object') + return reporter.error('Child expected, but input is not object'); - return r; -}; + var res = child._encode(data[child._baseState.key], reporter, data); + reporter.leaveKey(prevKey); -Red.prototype.invm = function invm(a) { - var inv = a._egcd(new BN(1), this.m); - if (inv.sign) { - inv.sign = false; - return this.imod(inv).redNeg(); + return res; + }, this).filter(function(child) { + return child; + }); + + content = this._createEncoderBuffer(content); } else { - return this.imod(inv); - } -}; + if (state.tag === 'seqof' || state.tag === 'setof') { + // TODO(indutny): this should be thrown on DSL level + if (!(state.args && state.args.length === 1)) + return reporter.error('Too many args for : ' + state.tag); -Red.prototype.pow = function pow(a, num) { - var w = []; - var q = num.clone(); - while (q.cmpn(0) !== 0) { - w.push(q.andln(1)); - q.ishrn(1); + if (!Array.isArray(data)) + return reporter.error('seqof/setof, but data is not Array'); + + var child = this.clone(); + child._baseState.implicit = null; + content = this._createEncoderBuffer(data.map(function(item) { + var state = this._baseState; + + return this._getUse(state.args[0], data)._encode(item, reporter); + }, child)); + } else if (state.use !== null) { + result = this._getUse(state.use, parent)._encode(data, reporter); + } else { + content = this._encodePrimitive(state.tag, data); + primitive = true; + } } - // Skip leading zeroes - var res = a; - for (var i = 0; i < w.length; i++, res = this.sqr(res)) - if (w[i] !== 0) - break; + // Encode data itself + var result; + if (!state.any && state.choice === null) { + var tag = state.implicit !== null ? state.implicit : state.tag; + var cls = state.implicit === null ? 'universal' : 'context'; - if (++i < w.length) { - for (var q = this.sqr(res); i < w.length; i++, q = this.sqr(q)) { - if (w[i] === 0) - continue; - res = this.mul(res, q); + if (tag === null) { + if (state.use === null) + reporter.error('Tag could be ommited only for .use()'); + } else { + if (state.use === null) + result = this._encodeComposite(tag, primitive, cls, content); } } - return res; -}; + // Wrap in explicit + if (state.explicit !== null) + result = this._encodeComposite(state.explicit, false, 'context', result); -Red.prototype.convertTo = function convertTo(num) { - return num.clone(); + return result; }; -Red.prototype.convertFrom = function convertFrom(num) { - var res = num.clone(); - res.red = null; - return res; +Node.prototype._encodeChoice = function encodeChoice(data, reporter) { + var state = this._baseState; + + var node = state.choice[data.type]; + if (!node) { + assert( + false, + data.type + ' not found in ' + + JSON.stringify(Object.keys(state.choice))); + } + return node._encode(data.value, reporter); }; -// -// Montgomery method engine -// +Node.prototype._encodePrimitive = function encodePrimitive(tag, data) { + var state = this._baseState; -BN.mont = function mont(num) { - return new Mont(num); + if (tag === 'octstr' || tag === 'bitstr' || tag === 'ia5str') + return this._encodeStr(data, tag); + else if (tag === 'utf8str') + return this._encodeStr(data, tag); + else if (tag === 'objid' && state.args) + return this._encodeObjid(data, state.reverseArgs[0], state.args[1]); + else if (tag === 'objid') + return this._encodeObjid(data, null, null); + else if (tag === 'gentime' || tag === 'utctime') + return this._encodeTime(data, tag); + else if (tag === 'null_') + return this._encodeNull(); + else if (tag === 'int' || tag === 'enum') + return this._encodeInt(data, state.args && state.reverseArgs[0]); + else if (tag === 'bool') + return this._encodeBool(data); + else + throw new Error('Unsupported tag: ' + tag); }; -function Mont(m) { - Red.call(this, m); - - this.shift = this.m.bitLength(); - if (this.shift % 26 !== 0) - this.shift += 26 - (this.shift % 26); - this.r = new BN(1).ishln(this.shift); - this.r2 = this.imod(this.r.sqr()); - this.rinv = this.r.invm(this.m); +},{"../base":92,"minimalistic-assert":103}],94:[function(require,module,exports){ +var inherits = require('inherits'); - // TODO(indutny): simplify it - this.minv = this.rinv.mul(this.r) - .sub(new BN(1)) - .div(this.m) - .neg() - .mod(this.r); +function Reporter(options) { + this._reporterState = { + obj: null, + path: [], + options: options || {}, + errors: [] + }; } -inherits(Mont, Red); +exports.Reporter = Reporter; -Mont.prototype.convertTo = function convertTo(num) { - return this.imod(num.shln(this.shift)); +Reporter.prototype.isError = function isError(obj) { + return obj instanceof ReporterError; }; -Mont.prototype.convertFrom = function convertFrom(num) { - var r = this.imod(num.mul(this.rinv)); - r.red = null; - return r; +Reporter.prototype.save = function save() { + var state = this._reporterState; + + return { obj: state.obj, pathLen: state.path.length }; }; -Mont.prototype.imul = function imul(a, b) { - if (a.cmpn(0) === 0 || b.cmpn(0) === 0) { - a.words[0] = 0; - a.length = 1; - return a; - } +Reporter.prototype.restore = function restore(data) { + var state = this._reporterState; - var t = a.imul(b); - var c = t.maskn(this.shift).mul(this.minv).imaskn(this.shift).mul(this.m); - var u = t.isub(c).ishrn(this.shift); - var res = u; - if (u.cmp(this.m) >= 0) - res = u.isub(this.m); - else if (u.cmpn(0) < 0) - res = u.iadd(this.m); + state.obj = data.obj; + state.path = state.path.slice(0, data.pathLen); +}; - return res._forceRed(this); +Reporter.prototype.enterKey = function enterKey(key) { + return this._reporterState.path.push(key); }; -Mont.prototype.mul = function mul(a, b) { - if (a.cmpn(0) === 0 || b.cmpn(0) === 0) - return new BN(0)._forceRed(this); +Reporter.prototype.leaveKey = function leaveKey(index, key, value) { + var state = this._reporterState; - var t = a.mul(b); - var c = t.maskn(this.shift).mul(this.minv).imaskn(this.shift).mul(this.m); - var u = t.isub(c).ishrn(this.shift); - var res = u; - if (u.cmp(this.m) >= 0) - res = u.isub(this.m); - else if (u.cmpn(0) < 0) - res = u.iadd(this.m); + state.path = state.path.slice(0, index - 1); + if (state.obj !== null) + state.obj[key] = value; +}; - return res._forceRed(this); +Reporter.prototype.enterObject = function enterObject() { + var state = this._reporterState; + + var prev = state.obj; + state.obj = {}; + return prev; }; -Mont.prototype.invm = function invm(a) { - // (AR)^-1 * R^2 = (A^-1 * R^-1) * R^2 = A^-1 * R - var res = this.imod(a.invm(this.m).mul(this.r2)); - return res._forceRed(this); +Reporter.prototype.leaveObject = function leaveObject(prev) { + var state = this._reporterState; + + var now = state.obj; + state.obj = prev; + return now; }; -},{}],68:[function(require,module,exports){ -(function (Buffer){ -var bn = require('bn.js'); -module.exports = crt; -function blind(priv, crypto) { - var r = getr(priv, crypto); - var blinder = r.toRed(bn.mont(priv.modulus)) - .redPow(new bn(priv.publicExponent)).fromRed(); - return { - blinder: blinder, - unblinder:r.invm(priv.modulus) - }; -} -function crt(msg, priv, crypto) { - var blinds = blind(priv, crypto); - var len = priv.modulus.byteLength(); - var mod = bn.mont(priv.modulus); - var blinded = new bn(msg).mul(blinds.blinder).mod(priv.modulus); - var c1 = blinded.toRed(bn.mont(priv.prime1)); - var c2 = blinded.toRed(bn.mont(priv.prime2)); - var qinv = priv.coefficient; - var p = priv.prime1; - var q = priv.prime2; - var m1 = c1.redPow(priv.exponent1); - var m2 = c2.redPow(priv.exponent2); - m1 = m1.fromRed(); - m2 = m2.fromRed(); - var h = m1.isub(m2).imul(qinv).mod(p); - h.imul(q); - m2.iadd(h); - var out = new Buffer(m2.imul(blinds.unblinder).mod(priv.modulus).toArray()); - if (out.length < len) { - var prefix = new Buffer(len - out.length); - prefix.fill(0); - out = Buffer.concat([prefix, out], len); - } - return out; -} -crt.getr = getr; -function getr(priv, crypto) { - var len = priv.modulus.byteLength(); - var r = new bn(crypto.randomBytes(len)); - while (r.cmp(priv.modulus) >= 0 || !r.mod(priv.prime1) || !r.mod(priv.prime2)) { - r = new bn(crypto.randomBytes(len)); +Reporter.prototype.error = function error(msg) { + var err; + var state = this._reporterState; + + var inherited = msg instanceof ReporterError; + if (inherited) { + err = msg; + } else { + err = new ReporterError(state.path.map(function(elem) { + return '[' + JSON.stringify(elem) + ']'; + }).join(''), msg.message || msg, msg.stack); } - return r; -} -}).call(this,require("buffer").Buffer) -},{"bn.js":67,"buffer":42}],69:[function(require,module,exports){ -var elliptic = exports; -elliptic.version = require('../package.json').version; -elliptic.utils = require('./elliptic/utils'); -elliptic.rand = require('brorand'); -elliptic.hmacDRBG = require('./elliptic/hmac-drbg'); -elliptic.curve = require('./elliptic/curve'); -elliptic.curves = require('./elliptic/curves'); + if (!state.options.partial) + throw err; -// Protocols -elliptic.ec = require('./elliptic/ec'); + if (!inherited) + state.errors.push(err); -},{"../package.json":88,"./elliptic/curve":72,"./elliptic/curves":75,"./elliptic/ec":76,"./elliptic/hmac-drbg":79,"./elliptic/utils":80,"brorand":81}],70:[function(require,module,exports){ -var bn = require('bn.js'); -var elliptic = require('../../elliptic'); + return err; +}; -var getNAF = elliptic.utils.getNAF; -var getJSF = elliptic.utils.getJSF; -var assert = elliptic.utils.assert; +Reporter.prototype.wrapResult = function wrapResult(result) { + var state = this._reporterState; + if (!state.options.partial) + return result; -function BaseCurve(type, conf) { - this.type = type; - this.p = new bn(conf.p, 16); + return { + result: this.isError(result) ? null : result, + errors: state.errors + }; +}; - // Use Montgomery, when there is no fast reduction for the prime - this.red = conf.prime ? bn.red(conf.prime) : bn.mont(this.p); +function ReporterError(path, msg) { + this.path = path; + this.rethrow(msg); +}; +inherits(ReporterError, Error); - // Useful for many curves - this.zero = new bn(0).toRed(this.red); - this.one = new bn(1).toRed(this.red); - this.two = new bn(2).toRed(this.red); +ReporterError.prototype.rethrow = function rethrow(msg) { + this.message = msg + ' at: ' + (this.path || '(shallow)'); + Error.captureStackTrace(this, ReporterError); - // Curve configuration, optional - this.n = conf.n && new bn(conf.n, 16); - this.g = conf.g && this.pointFromJSON(conf.g, conf.gRed); + return this; +}; - // Temporary arrays - this._wnafT1 = new Array(4); - this._wnafT2 = new Array(4); - this._wnafT3 = new Array(4); - this._wnafT4 = new Array(4); -} -module.exports = BaseCurve; +},{"inherits":240}],95:[function(require,module,exports){ +var constants = require('../constants'); -BaseCurve.prototype.point = function point() { - throw new Error('Not implemented'); +exports.tagClass = { + 0: 'universal', + 1: 'application', + 2: 'context', + 3: 'private' }; +exports.tagClassByName = constants._reverse(exports.tagClass); -BaseCurve.prototype.validate = function validate(point) { - throw new Error('Not implemented'); +exports.tag = { + 0x00: 'end', + 0x01: 'bool', + 0x02: 'int', + 0x03: 'bitstr', + 0x04: 'octstr', + 0x05: 'null_', + 0x06: 'objid', + 0x07: 'objDesc', + 0x08: 'external', + 0x09: 'real', + 0x0a: 'enum', + 0x0b: 'embed', + 0x0c: 'utf8str', + 0x0d: 'relativeOid', + 0x10: 'seq', + 0x11: 'set', + 0x12: 'numstr', + 0x13: 'printstr', + 0x14: 't61str', + 0x15: 'videostr', + 0x16: 'ia5str', + 0x17: 'utctime', + 0x18: 'gentime', + 0x19: 'graphstr', + 0x1a: 'iso646str', + 0x1b: 'genstr', + 0x1c: 'unistr', + 0x1d: 'charstr', + 0x1e: 'bmpstr' }; +exports.tagByName = constants._reverse(exports.tag); -BaseCurve.prototype._fixedNafMul = function _fixedNafMul(p, k) { - var doubles = p._getDoubles(); +},{"../constants":96}],96:[function(require,module,exports){ +var constants = exports; - var naf = getNAF(k, 1); - var I = (1 << (doubles.step + 1)) - (doubles.step % 2 === 0 ? 2 : 1); - I /= 3; +// Helper +constants._reverse = function reverse(map) { + var res = {}; - // Translate into more windowed form - var repr = []; - for (var j = 0; j < naf.length; j += doubles.step) { - var nafW = 0; - for (var k = j + doubles.step - 1; k >= j; k--) - nafW = (nafW << 1) + naf[k]; - repr.push(nafW); - } + Object.keys(map).forEach(function(key) { + // Convert key to integer if it is stringified + if ((key | 0) == key) + key = key | 0; - var a = this.jpoint(null, null, null); - var b = this.jpoint(null, null, null); - for (var i = I; i > 0; i--) { - for (var j = 0; j < repr.length; j++) { - var nafW = repr[j]; - if (nafW === i) - b = b.mixedAdd(doubles.points[j]); - else if (nafW === -i) - b = b.mixedAdd(doubles.points[j].neg()); - } - a = a.add(b); - } - return a.toP(); + var value = map[key]; + res[value] = key; + }); + + return res; }; -BaseCurve.prototype._wnafMul = function _wnafMul(p, k) { - var w = 4; +constants.der = require('./der'); - // Precompute window - var nafPoints = p._getNAFPoints(w); - w = nafPoints.wnd; - var wnd = nafPoints.points; +},{"./der":95}],97:[function(require,module,exports){ +var inherits = require('inherits'); - // Get NAF form - var naf = getNAF(k, w); +var asn1 = require('../../asn1'); +var base = asn1.base; +var bignum = asn1.bignum; - // Add `this`*(N+1) for every w-NAF index - var acc = this.jpoint(null, null, null); - for (var i = naf.length - 1; i >= 0; i--) { - // Count zeroes - for (var k = 0; i >= 0 && naf[i] === 0; i--) - k++; - if (i >= 0) - k++; - acc = acc.dblp(k); +// Import DER constants +var der = asn1.constants.der; - if (i < 0) - break; - var z = naf[i]; - assert(z !== 0); - if (p.type === 'affine') { - // J +- P - if (z > 0) - acc = acc.mixedAdd(wnd[(z - 1) >> 1]); - else - acc = acc.mixedAdd(wnd[(-z - 1) >> 1].neg()); - } else { - // J +- J - if (z > 0) - acc = acc.add(wnd[(z - 1) >> 1]); - else - acc = acc.add(wnd[(-z - 1) >> 1].neg()); - } - } - return p.type === 'affine' ? acc.toP() : acc; +function DERDecoder(entity) { + this.enc = 'der'; + this.name = entity.name; + this.entity = entity; + + // Construct base tree + this.tree = new DERNode(); + this.tree._init(entity.body); }; +module.exports = DERDecoder; -BaseCurve.prototype._wnafMulAdd = function _wnafMulAdd(defW, - points, - coeffs, - len) { - var wndWidth = this._wnafT1; - var wnd = this._wnafT2; - var naf = this._wnafT3; +DERDecoder.prototype.decode = function decode(data, options) { + if (!(data instanceof base.DecoderBuffer)) + data = new base.DecoderBuffer(data, options); - // Fill all arrays - var max = 0; - for (var i = 0; i < len; i++) { - var p = points[i]; - var nafPoints = p._getNAFPoints(defW); - wndWidth[i] = nafPoints.wnd; - wnd[i] = nafPoints.points; - } + return this.tree._decode(data, options); +}; - // Comb small window NAFs - for (var i = len - 1; i >= 1; i -= 2) { - var a = i - 1; - var b = i; - if (wndWidth[a] !== 1 || wndWidth[b] !== 1) { - naf[a] = getNAF(coeffs[a], wndWidth[a]); - naf[b] = getNAF(coeffs[b], wndWidth[b]); - max = Math.max(naf[a].length, max); - max = Math.max(naf[b].length, max); - continue; - } +// Tree methods - var comb = [ - points[a], /* 1 */ - null, /* 3 */ - null, /* 5 */ - points[b] /* 7 */ - ]; +function DERNode(parent) { + base.Node.call(this, 'der', parent); +} +inherits(DERNode, base.Node); - // Try to avoid Projective points, if possible - if (points[a].y.cmp(points[b].y) === 0) { - comb[1] = points[a].add(points[b]); - comb[2] = points[a].toJ().mixedAdd(points[b].neg()); - } else if (points[a].y.cmp(points[b].y.redNeg()) === 0) { - comb[1] = points[a].toJ().mixedAdd(points[b]); - comb[2] = points[a].add(points[b].neg()); - } else { - comb[1] = points[a].toJ().mixedAdd(points[b]); - comb[2] = points[a].toJ().mixedAdd(points[b].neg()); - } +DERNode.prototype._peekTag = function peekTag(buffer, tag, any) { + if (buffer.isEmpty()) + return false; - var index = [ - -3, /* -1 -1 */ - -1, /* -1 0 */ - -5, /* -1 1 */ - -7, /* 0 -1 */ - 0, /* 0 0 */ - 7, /* 0 1 */ - 5, /* 1 -1 */ - 1, /* 1 0 */ - 3 /* 1 1 */ - ]; + var state = buffer.save(); + var decodedTag = derDecodeTag(buffer, 'Failed to peek tag: "' + tag + '"'); + if (buffer.isError(decodedTag)) + return decodedTag; - var jsf = getJSF(coeffs[a], coeffs[b]); - max = Math.max(jsf[0].length, max); - naf[a] = new Array(max); - naf[b] = new Array(max); - for (var j = 0; j < max; j++) { - var ja = jsf[0][j] | 0; - var jb = jsf[1][j] | 0; + buffer.restore(state); - naf[a][j] = index[(ja + 1) * 3 + (jb + 1)]; - naf[b][j] = 0; - wnd[a] = comb; - } - } + return decodedTag.tag === tag || decodedTag.tagStr === tag || any; +}; - var acc = this.jpoint(null, null, null); - var tmp = this._wnafT4; - for (var i = max; i >= 0; i--) { - var k = 0; +DERNode.prototype._decodeTag = function decodeTag(buffer, tag, any) { + var decodedTag = derDecodeTag(buffer, + 'Failed to decode tag of "' + tag + '"'); + if (buffer.isError(decodedTag)) + return decodedTag; - while (i >= 0) { - var zero = true; - for (var j = 0; j < len; j++) { - tmp[j] = naf[j][i] | 0; - if (tmp[j] !== 0) - zero = false; - } - if (!zero) - break; - k++; - i--; - } - if (i >= 0) - k++; - acc = acc.dblp(k); - if (i < 0) - break; + var len = derDecodeLen(buffer, + decodedTag.primitive, + 'Failed to get length of "' + tag + '"'); - for (var j = 0; j < len; j++) { - var z = tmp[j]; - var p; - if (z === 0) - continue; - else if (z > 0) - p = wnd[j][(z - 1) >> 1]; - else if (z < 0) - p = wnd[j][(-z - 1) >> 1].neg(); + // Failure + if (buffer.isError(len)) + return len; - if (p.type === 'affine') - acc = acc.mixedAdd(p); - else - acc = acc.add(p); - } + if (!any && + decodedTag.tag !== tag && + decodedTag.tagStr !== tag && + decodedTag.tagStr + 'of' !== tag) { + return buffer.error('Failed to match tag: "' + tag + '"'); } - // Zeroify references - for (var i = 0; i < len; i++) - wnd[i] = null; - return acc.toP(); -}; -BaseCurve.BasePoint = BasePoint; + if (decodedTag.primitive || len !== null) + return buffer.skip(len, 'Failed to match body of: "' + tag + '"'); -function BasePoint(curve, type) { - this.curve = curve; - this.type = type; - this.precomputed = null; -} + // Indefinite length... find END tag + var state = buffer.save(); + var res = this._skipUntilEnd( + buffer, + 'Failed to skip indefinite length body: "' + this.tag + '"'); + if (buffer.isError(res)) + return res; -BasePoint.prototype.validate = function validate() { - return this.curve.validate(this); + len = buffer.offset - state.offset; + buffer.restore(state); + return buffer.skip(len, 'Failed to match body of: "' + tag + '"'); }; -BasePoint.prototype.precompute = function precompute(power, _beta) { - if (this.precomputed) - return this; - - var precomputed = { - doubles: null, - naf: null, - beta: null - }; - precomputed.naf = this._getNAFPoints(8); - precomputed.doubles = this._getDoubles(4, power); - precomputed.beta = this._getBeta(); - this.precomputed = precomputed; +DERNode.prototype._skipUntilEnd = function skipUntilEnd(buffer, fail) { + while (true) { + var tag = derDecodeTag(buffer, fail); + if (buffer.isError(tag)) + return tag; + var len = derDecodeLen(buffer, tag.primitive, fail); + if (buffer.isError(len)) + return len; - return this; -}; + var res; + if (tag.primitive || len !== null) + res = buffer.skip(len) + else + res = this._skipUntilEnd(buffer, fail); -BasePoint.prototype._getDoubles = function _getDoubles(step, power) { - if (this.precomputed && this.precomputed.doubles) - return this.precomputed.doubles; + // Failure + if (buffer.isError(res)) + return res; - var doubles = [ this ]; - var acc = this; - for (var i = 0; i < power; i += step) { - for (var j = 0; j < step; j++) - acc = acc.dbl(); - doubles.push(acc); + if (tag.tagStr === 'end') + break; } - return { - step: step, - points: doubles - }; }; -BasePoint.prototype._getNAFPoints = function _getNAFPoints(wnd) { - if (this.precomputed && this.precomputed.naf) - return this.precomputed.naf; +DERNode.prototype._decodeList = function decodeList(buffer, tag, decoder) { + var result = []; + while (!buffer.isEmpty()) { + var possibleEnd = this._peekTag(buffer, 'end'); + if (buffer.isError(possibleEnd)) + return possibleEnd; - var res = [ this ]; - var max = (1 << wnd) - 1; - var dbl = max === 1 ? null : this.dbl(); - for (var i = 1; i < max; i++) - res[i] = res[i - 1].add(dbl); - return { - wnd: wnd, - points: res - }; + var res = decoder.decode(buffer, 'der'); + if (buffer.isError(res) && possibleEnd) + break; + result.push(res); + } + return result; }; -BasePoint.prototype._getBeta = function _getBeta() { - return null; -}; +DERNode.prototype._decodeStr = function decodeStr(buffer, tag) { + if (tag === 'octstr') { + return buffer.raw(); + } else if (tag === 'bitstr') { + var unused = buffer.readUInt8(); + if (buffer.isError(unused)) + return unused; -BasePoint.prototype.dblp = function dblp(k) { - var r = this; - for (var i = 0; i < k; i++) - r = r.dbl(); - return r; + return { unused: unused, data: buffer.raw() }; + } else if (tag === 'ia5str' || tag === 'utf8str') { + return buffer.raw().toString(); + } else { + return this.error('Decoding of string type: ' + tag + ' unsupported'); + } }; -},{"../../elliptic":69,"bn.js":67}],71:[function(require,module,exports){ -var curve = require('../curve'); -var elliptic = require('../../elliptic'); -var bn = require('bn.js'); -var inherits = require('inherits'); -var Base = curve.base; - -var getNAF = elliptic.utils.getNAF; -var assert = elliptic.utils.assert; - -function EdwardsCurve(conf) { - // NOTE: Important as we are creating point in Base.call() - this.twisted = conf.a != 1; - this.mOneA = this.twisted && conf.a == -1; - this.extended = this.mOneA; +DERNode.prototype._decodeObjid = function decodeObjid(buffer, values, relative) { + var identifiers = []; + var ident = 0; + while (!buffer.isEmpty()) { + var subident = buffer.readUInt8(); + ident <<= 7; + ident |= subident & 0x7f; + if ((subident & 0x80) === 0) { + identifiers.push(ident); + ident = 0; + } + } + if (subident & 0x80) + identifiers.push(ident); - Base.call(this, 'mont', conf); + var first = (identifiers[0] / 40) | 0; + var second = identifiers[0] % 40; - this.a = new bn(conf.a, 16).mod(this.red.m).toRed(this.red); - this.c = new bn(conf.c, 16).toRed(this.red); - this.c2 = this.c.redSqr(); - this.d = new bn(conf.d, 16).toRed(this.red); - this.dd = this.d.redAdd(this.d); + if (relative) + result = identifiers; + else + result = [first, second].concat(identifiers.slice(1)); - assert(!this.twisted || this.c.fromRed().cmpn(1) === 0); - this.oneC = conf.c == 1; -} -inherits(EdwardsCurve, Base); -module.exports = EdwardsCurve; + if (values) + result = values[result.join(' ')]; -EdwardsCurve.prototype._mulA = function _mulA(num) { - if (this.mOneA) - return num.redNeg(); - else - return this.a.redMul(num); + return result; }; -EdwardsCurve.prototype._mulC = function _mulC(num) { - if (this.oneC) - return num; - else - return this.c.redMul(num); -}; +DERNode.prototype._decodeTime = function decodeTime(buffer, tag) { + var str = buffer.raw().toString(); + if (tag === 'gentime') { + var year = str.slice(0, 4) | 0; + var mon = str.slice(4, 6) | 0; + var day = str.slice(6, 8) | 0; + var hour = str.slice(8, 10) | 0; + var min = str.slice(10, 12) | 0; + var sec = str.slice(12, 14) | 0; + } else if (tag === 'utctime') { + var year = str.slice(0, 2) | 0; + var mon = str.slice(2, 4) | 0; + var day = str.slice(4, 6) | 0; + var hour = str.slice(6, 8) | 0; + var min = str.slice(8, 10) | 0; + var sec = str.slice(10, 12) | 0; + if (year < 70) + year = 2000 + year; + else + year = 1900 + year; + } else { + return this.error('Decoding ' + tag + ' time is not supported yet'); + } -EdwardsCurve.prototype.point = function point(x, y, z, t) { - return new Point(this, x, y, z, t); + return Date.UTC(year, mon - 1, day, hour, min, sec, 0); }; -// Just for compatibility with Short curve -EdwardsCurve.prototype.jpoint = function jpoint(x, y, z, t) { - return this.point(x, y, z, t); +DERNode.prototype._decodeNull = function decodeNull(buffer) { + return null; }; -EdwardsCurve.prototype.pointFromJSON = function pointFromJSON(obj) { - return Point.fromJSON(this, obj); +DERNode.prototype._decodeBool = function decodeBool(buffer) { + var res = buffer.readUInt8(); + if (buffer.isError(res)) + return res; + else + return res !== 0; }; -EdwardsCurve.prototype.pointFromX = function pointFromX(odd, x) { - x = new bn(x, 16); - if (!x.red) - x = x.toRed(this.red); - - var x2 = x.redSqr(); - var rhs = this.c2.redSub(this.a.redMul(x2)); - var lhs = this.one.redSub(this.c2.redMul(this.d).redMul(x2)); +DERNode.prototype._decodeInt = function decodeInt(buffer, values) { + // Bigint, return as it is (assume big endian) + var raw = buffer.raw(); + var res = new bignum(raw); - var y = rhs.redMul(lhs.redInvm()).redSqrt(); - var isOdd = y.fromRed().isOdd(); - if (odd && !isOdd || !odd && isOdd) - y = y.redNeg(); + if (values) + res = values[res.toString(10)] || res; - return this.point(x, y, curve.one); + return res; }; -EdwardsCurve.prototype.validate = function validate(point) { - if (point.isInfinity()) - return true; +DERNode.prototype._use = function use(entity, obj) { + if (typeof entity === 'function') + entity = entity(obj); + return entity._getDecoder('der').tree; +}; - // Curve: A * X^2 + Y^2 = C^2 * (1 + D * X^2 * Y^2) - point.normalize(); +// Utility methods - var x2 = point.x.redSqr(); - var y2 = point.y.redSqr(); - var lhs = x2.redMul(this.a).redAdd(y2); - var rhs = this.c2.redMul(this.one.redAdd(this.d.redMul(x2).redMul(y2))); +function derDecodeTag(buf, fail) { + var tag = buf.readUInt8(fail); + if (buf.isError(tag)) + return tag; - return lhs.cmp(rhs) === 0; -}; + var cls = der.tagClass[tag >> 6]; + var primitive = (tag & 0x20) === 0; -function Point(curve, x, y, z, t) { - Base.BasePoint.call(this, curve, 'projective'); - if (x === null && y === null && z === null) { - this.x = this.curve.zero; - this.y = this.curve.one; - this.z = this.curve.one; - this.t = this.curve.zero; - this.zOne = true; - } else { - this.x = new bn(x, 16); - this.y = new bn(y, 16); - this.z = z ? new bn(z, 16) : this.curve.one; - this.t = t && new bn(t, 16); - if (!this.x.red) - this.x = this.x.toRed(this.curve.red); - if (!this.y.red) - this.y = this.y.toRed(this.curve.red); - if (!this.z.red) - this.z = this.z.toRed(this.curve.red); - if (this.t && !this.t.red) - this.t = this.t.toRed(this.curve.red); - this.zOne = this.z === this.curve.one; + // Multi-octet tag - load + if ((tag & 0x1f) === 0x1f) { + var oct = tag; + tag = 0; + while ((oct & 0x80) === 0x80) { + oct = buf.readUInt8(fail); + if (buf.isError(oct)) + return oct; - // Use extended coordinates - if (this.curve.extended && !this.t) { - this.t = this.x.redMul(this.y); - if (!this.zOne) - this.t = this.t.redMul(this.z.redInvm()); + tag <<= 7; + tag |= oct & 0x7f; } + } else { + tag &= 0x1f; } + var tagStr = der.tag[tag]; + + return { + cls: cls, + primitive: primitive, + tag: tag, + tagStr: tagStr + }; } -inherits(Point, Base.BasePoint); -Point.fromJSON = function fromJSON(curve, obj) { - return new Point(curve, obj[0], obj[1], obj[2]); -}; +function derDecodeLen(buf, primitive, fail) { + var len = buf.readUInt8(fail); + if (buf.isError(len)) + return len; -Point.prototype.inspect = function inspect() { - if (this.isInfinity()) - return ''; - return ''; -}; + // Indefinite form + if (!primitive && len === 0x80) + return null; -Point.prototype.isInfinity = function isInfinity() { - // XXX This code assumes that zero is always zero in red - return this.x.cmpn(0) === 0 && - this.y.cmp(this.z) === 0; -}; + // Definite form + if ((len & 0x80) === 0) { + // Short form + return len; + } -Point.prototype._extDbl = function _extDbl() { - // http://hyperelliptic.org/EFD/g1p/auto-twisted-extended-1.html#doubling-dbl-2008-hwcd - // 4M + 4S + // Long form + var num = len & 0x7f; + if (num >= 4) + return buf.error('length octect is too long'); - // A = X1^2 - var a = this.x.redSqr(); - // B = Y1^2 - var b = this.y.redSqr(); - // C = 2 * Z1^2 - var c = this.z.redSqr(); - c = c.redIAdd(c); - // D = a * A - var d = this.curve._mulA(a); - // E = (X1 + Y1)^2 - A - B - var e = this.x.redAdd(this.y).redSqr().redISub(a).redISub(b); - // G = D + B - var g = d.redAdd(b); - // F = G - C - var f = g.redSub(c); - // H = D - B - var h = d.redSub(b); - // X3 = E * F - var nx = e.redMul(f); - // Y3 = G * H - var ny = g.redMul(h); - // T3 = E * H - var nt = e.redMul(h); - // Z3 = F * G - var nz = f.redMul(g); - return this.curve.point(nx, ny, nz, nt); -}; + len = 0; + for (var i = 0; i < num; i++) { + len <<= 8; + var j = buf.readUInt8(fail); + if (buf.isError(j)) + return j; + len |= j; + } -Point.prototype._projDbl = function _projDbl() { - // http://hyperelliptic.org/EFD/g1p/auto-twisted-projective.html#doubling-dbl-2008-bbjlp - // http://hyperelliptic.org/EFD/g1p/auto-edwards-projective.html#doubling-dbl-2007-bl - // and others - // Generally 3M + 4S or 2M + 4S + return len; +} - // B = (X1 + Y1)^2 - var b = this.x.redAdd(this.y).redSqr(); - // C = X1^2 - var c = this.x.redSqr(); - // D = Y1^2 - var d = this.y.redSqr(); +},{"../../asn1":89,"inherits":240}],98:[function(require,module,exports){ +var decoders = exports; - if (this.curve.twisted) { - // E = a * C - var e = this.curve._mulA(c); - // F = E + D - var f = e.redAdd(d); - if (this.zOne) { - // X3 = (B - C - D) * (F - 2) - var nx = b.redSub(c).redSub(d).redMul(f.redSub(this.curve.two)); - // Y3 = F * (E - D) - var ny = f.redMul(e.redSub(d)); - // Z3 = F^2 - 2 * F - var nz = f.redSqr().redSub(f).redSub(f); - } else { - // H = Z1^2 - var h = this.z.redSqr(); - // J = F - 2 * H - var j = f.redSub(h).redISub(h); - // X3 = (B-C-D)*J - var nx = b.redSub(c).redISub(d).redMul(j); - // Y3 = F * (E - D) - var ny = f.redMul(e.redSub(d)); - // Z3 = F * J - var nz = f.redMul(j); - } - } else { - // E = C + D - var e = c.redAdd(d); - // H = (c * Z1)^2 - var h = this.curve._mulC(redMul(this.z)).redSqr(); - // J = E - 2 * H - var j = e.redSub(h).redSub(h); - // X3 = c * (B - E) * J - var nx = this.curve._mulC(b.redISub(e)).redMul(j); - // Y3 = c * E * (C - D) - var ny = this.curve._mulC(e).redMul(c.redISub(d)); - // Z3 = E * J - var nz = e.redMul(j); - } - return this.curve.point(nx, ny, nz); -}; +decoders.der = require('./der'); +decoders.pem = require('./pem'); -Point.prototype.dbl = function dbl() { - if (this.isInfinity()) - return this; +},{"./der":97,"./pem":99}],99:[function(require,module,exports){ +var inherits = require('inherits'); +var Buffer = require('buffer').Buffer; - // Double in extended coordinates - if (this.curve.extended) - return this._extDbl(); - else - return this._projDbl(); +var asn1 = require('../../asn1'); +var DERDecoder = require('./der'); + +function PEMDecoder(entity) { + DERDecoder.call(this, entity); + this.enc = 'pem'; }; +inherits(PEMDecoder, DERDecoder); +module.exports = PEMDecoder; -Point.prototype._extAdd = function _extAdd(p) { - // http://hyperelliptic.org/EFD/g1p/auto-twisted-extended-1.html#addition-add-2008-hwcd-3 - // 8M +PEMDecoder.prototype.decode = function decode(data, options) { + var lines = data.toString().split(/[\r\n]+/g); - // A = (Y1 - X1) * (Y2 - X2) - var a = this.y.redSub(this.x).redMul(p.y.redSub(p.x)); - // B = (Y1 + X1) * (Y2 + X2) - var b = this.y.redAdd(this.x).redMul(p.y.redAdd(p.x)); - // C = T1 * k * T2 - var c = this.t.redMul(this.curve.dd).redMul(p.t); - // D = Z1 * 2 * Z2 - var d = this.z.redMul(p.z.redAdd(p.z)); - // E = B - A - var e = b.redSub(a); - // F = D - C - var f = d.redSub(c); - // G = D + C - var g = d.redAdd(c); - // H = B + A - var h = b.redAdd(a); - // X3 = E * F - var nx = e.redMul(f); - // Y3 = G * H - var ny = g.redMul(h); - // T3 = E * H - var nt = e.redMul(h); - // Z3 = F * G - var nz = f.redMul(g); - return this.curve.point(nx, ny, nz, nt); -}; + var label = options.label.toUpperCase(); -Point.prototype._projAdd = function _projAdd(p) { - // http://hyperelliptic.org/EFD/g1p/auto-twisted-projective.html#addition-add-2008-bbjlp - // http://hyperelliptic.org/EFD/g1p/auto-edwards-projective.html#addition-add-2007-bl - // 10M + 1S + var re = /^-----(BEGIN|END) ([^-]+)-----$/; + var start = -1; + var end = -1; + for (var i = 0; i < lines.length; i++) { + var match = lines[i].match(re); + if (match === null) + continue; - // A = Z1 * Z2 - var a = this.z.redMul(p.z); - // B = A^2 - var b = a.redSqr(); - // C = X1 * X2 - var c = this.x.redMul(p.x); - // D = Y1 * Y2 - var d = this.y.redMul(p.y); - // E = d * C * D - var e = this.curve.d.redMul(c).redMul(d); - // F = B - E - var f = b.redSub(e); - // G = B + E - var g = b.redAdd(e); - // X3 = A * F * ((X1 + Y1) * (X2 + Y2) - C - D) - var tmp = this.x.redAdd(this.y).redMul(p.x.redAdd(p.y)).redISub(c).redISub(d); - var nx = a.redMul(f).redMul(tmp); - if (this.curve.twisted) { - // Y3 = A * G * (D - a * C) - var ny = a.redMul(g).redMul(d.redSub(this.curve._mulA(c))); - // Z3 = F * G - var nz = f.redMul(g); - } else { - // Y3 = A * G * (D - C) - var ny = a.redMul(g).redMul(d.redSub(c)); - // Z3 = c * F * G - var nz = this.curve._mulC(f).redMul(g); + if (match[2] !== label) + continue; + + if (start === -1) { + if (match[1] !== 'BEGIN') + break; + start = i; + } else { + if (match[1] !== 'END') + break; + end = i; + break; + } } - return this.curve.point(nx, ny, nz); -}; + if (start === -1 || end === -1) + throw new Error('PEM section not found for: ' + label); -Point.prototype.add = function add(p) { - if (this.isInfinity()) - return p; - if (p.isInfinity()) - return this; + var base64 = lines.slice(start + 1, end).join(''); + // Remove excessive symbols + base64.replace(/[^a-z0-9\+\/=]+/gi, ''); - if (this.curve.extended) - return this._extAdd(p); - else - return this._projAdd(p); + var input = new Buffer(base64, 'base64'); + return DERDecoder.prototype.decode.call(this, input, options); }; -Point.prototype.mul = function mul(k) { - if (this.precomputed && this.precomputed.doubles) - return this.curve._fixedNafMul(this, k); - else - return this.curve._wnafMul(this, k); -}; +},{"../../asn1":89,"./der":97,"buffer":47,"inherits":240}],100:[function(require,module,exports){ +var inherits = require('inherits'); +var Buffer = require('buffer').Buffer; -Point.prototype.mulAdd = function mulAdd(k1, p, k2) { - return this.curve._wnafMulAdd(1, [ this, p ], [ k1, k2 ], 2); -}; +var asn1 = require('../../asn1'); +var base = asn1.base; +var bignum = asn1.bignum; -Point.prototype.normalize = function normalize() { - if (this.zOne) - return this; +// Import DER constants +var der = asn1.constants.der; - // Normalize coordinates - var zi = this.z.redInvm(); - this.x = this.x.redMul(zi); - this.y = this.y.redMul(zi); - if (this.t) - this.t = this.t.redMul(zi); - this.z = this.curve.one; - this.zOne = true; - return this; -}; +function DEREncoder(entity) { + this.enc = 'der'; + this.name = entity.name; + this.entity = entity; -Point.prototype.neg = function neg() { - return this.curve.point(this.x.redNeg(), - this.y, - this.z, - this.t && this.t.redNeg()); + // Construct base tree + this.tree = new DERNode(); + this.tree._init(entity.body); }; +module.exports = DEREncoder; -Point.prototype.getX = function getX() { - this.normalize(); - return this.x.fromRed(); +DEREncoder.prototype.encode = function encode(data, reporter) { + return this.tree._encode(data, reporter).join(); }; -Point.prototype.getY = function getY() { - this.normalize(); - return this.y.fromRed(); -}; +// Tree methods -// Compatibility with BaseCurve -Point.prototype.toP = Point.prototype.normalize; -Point.prototype.mixedAdd = Point.prototype.add; +function DERNode(parent) { + base.Node.call(this, 'der', parent); +} +inherits(DERNode, base.Node); -},{"../../elliptic":69,"../curve":72,"bn.js":67,"inherits":229}],72:[function(require,module,exports){ -var curve = exports; +DERNode.prototype._encodeComposite = function encodeComposite(tag, + primitive, + cls, + content) { + var encodedTag = encodeTag(tag, primitive, cls, this.reporter); -curve.base = require('./base'); -curve.short = require('./short'); -curve.mont = require('./mont'); -curve.edwards = require('./edwards'); + // Short form + if (content.length < 0x80) { + var header = new Buffer(2); + header[0] = encodedTag; + header[1] = content.length; + return this._createEncoderBuffer([ header, content ]); + } -},{"./base":70,"./edwards":71,"./mont":73,"./short":74}],73:[function(require,module,exports){ -var curve = require('../curve'); -var elliptic = require('../../elliptic'); -var bn = require('bn.js'); -var inherits = require('inherits'); -var Base = curve.base; + // Long form + // Count octets required to store length + var lenOctets = 1; + for (var i = content.length; i >= 0x100; i >>= 8) + lenOctets++; -var getNAF = elliptic.utils.getNAF; -var assert = elliptic.utils.assert; + var header = new Buffer(1 + 1 + lenOctets); + header[0] = encodedTag; + header[1] = 0x80 | lenOctets; -function MontCurve(conf) { - Base.call(this, 'mont', conf); + for (var i = 1 + lenOctets, j = content.length; j > 0; i--, j >>= 8) + header[i] = j & 0xff; - this.a = new bn(conf.a, 16).toRed(this.red); - this.b = new bn(conf.b, 16).toRed(this.red); - this.i4 = new bn(4).toRed(this.red).redInvm(); - this.two = new bn(2).toRed(this.red); - this.a24 = this.i4.redMul(this.a.redAdd(this.two)); -} -inherits(MontCurve, Base); -module.exports = MontCurve; + return this._createEncoderBuffer([ header, content ]); +}; -MontCurve.prototype.point = function point(x, z) { - return new Point(this, x, z); +DERNode.prototype._encodeStr = function encodeStr(str, tag) { + if (tag === 'octstr') + return this._createEncoderBuffer(str); + else if (tag === 'bitstr') + return this._createEncoderBuffer([ str.unused | 0, str.data ]); + else if (tag === 'ia5str' || tag === 'utf8str') + return this._createEncoderBuffer(str); + return this.reporter.error('Encoding of string type: ' + tag + + ' unsupported'); }; -MontCurve.prototype.pointFromJSON = function pointFromJSON(obj) { - return Point.fromJSON(this, obj); -} +DERNode.prototype._encodeObjid = function encodeObjid(id, values, relative) { + if (typeof id === 'string') { + if (!values) + return this.reporter.error('string objid given, but no values map found'); + if (!values.hasOwnProperty(id)) + return this.reporter.error('objid not found in values map'); + id = values[id].split(/[\s\.]+/g); + for (var i = 0; i < id.length; i++) + id[i] |= 0; + } else if (Array.isArray(id)) { + id = id.slice(); + for (var i = 0; i < id.length; i++) + id[i] |= 0; + } -MontCurve.prototype.validate = function validate(point) { - var x = point.normalize().x; - var x2 = x.redSqr(); - var rhs = x2.redMul(x).redAdd(x2.redMul(this.a)).redAdd(x); - var y = rhs.redSqrt(); + if (!Array.isArray(id)) { + return this.reporter.error('objid() should be either array or string, ' + + 'got: ' + JSON.stringify(id)); + } - return y.redSqr().cmp(rhs) === 0; -}; + if (!relative) { + if (id[1] >= 40) + return this.reporter.error('Second objid identifier OOB'); + id.splice(0, 2, id[0] * 40 + id[1]); + } -function Point(curve, x, z) { - Base.BasePoint.call(this, curve, 'projective'); - if (x === null && z === null) { - this.x = this.curve.one; - this.z = this.curve.zero; - } else { - this.x = new bn(x, 16); - this.z = new bn(z, 16); - if (!this.x.red) - this.x = this.x.toRed(this.curve.red); - if (!this.z.red) - this.z = this.z.toRed(this.curve.red); + // Count number of octets + var size = 0; + for (var i = 0; i < id.length; i++) { + var ident = id[i]; + for (size++; ident >= 0x80; ident >>= 7) + size++; } -} -inherits(Point, Base.BasePoint); -Point.prototype.precompute = function precompute() { - // No-op -}; + var objid = new Buffer(size); + var offset = objid.length - 1; + for (var i = id.length - 1; i >= 0; i--) { + var ident = id[i]; + objid[offset--] = ident & 0x7f; + while ((ident >>= 7) > 0) + objid[offset--] = 0x80 | (ident & 0x7f); + } -Point.fromJSON = function fromJSON(curve, obj) { - return new Point(curve, obj[0], obj[1] || curve.one); + return this._createEncoderBuffer(objid); }; -Point.prototype.inspect = function inspect() { - if (this.isInfinity()) - return ''; - return ''; -}; +function two(num) { + if (num < 10) + return '0' + num; + else + return num; +} -Point.prototype.isInfinity = function isInfinity() { - // XXX This code assumes that zero is always zero in red - return this.z.cmpn(0) === 0; -}; +DERNode.prototype._encodeTime = function encodeTime(time, tag) { + var str; + var date = new Date(time); -Point.prototype.dbl = function dbl() { - // http://hyperelliptic.org/EFD/g1p/auto-montgom-xz.html#doubling-dbl-1987-m-3 - // 2M + 2S + 4A + if (tag === 'gentime') { + str = [ + two(date.getFullYear()), + two(date.getUTCMonth() + 1), + two(date.getUTCDate()), + two(date.getUTCHours()), + two(date.getUTCMinutes()), + two(date.getUTCSeconds()), + 'Z' + ].join(''); + } else if (tag === 'utctime') { + str = [ + two(date.getFullYear() % 100), + two(date.getUTCMonth() + 1), + two(date.getUTCDate()), + two(date.getUTCHours()), + two(date.getUTCMinutes()), + two(date.getUTCSeconds()), + 'Z' + ].join(''); + } else { + this.reporter.error('Encoding ' + tag + ' time is not supported yet'); + } - // A = X1 + Z1 - var a = this.x.redAdd(this.z); - // AA = A^2 - var aa = a.redSqr(); - // B = X1 - Z1 - var b = this.x.redSub(this.z); - // BB = B^2 - var bb = b.redSqr(); - // C = AA - BB - var c = aa.redSub(bb); - // X3 = AA * BB - var nx = aa.redMul(bb); - // Z3 = C * (BB + A24 * C) - var nz = c.redMul(bb.redAdd(this.curve.a24.redMul(c))); - return this.curve.point(nx, nz); + return this._encodeStr(str, 'octstr'); }; -Point.prototype.add = function add(p) { - throw new Error('Not supported on Montgomery curve'); +DERNode.prototype._encodeNull = function encodeNull() { + return this._createEncoderBuffer(''); }; -Point.prototype.diffAdd = function diffAdd(p, diff) { - // http://hyperelliptic.org/EFD/g1p/auto-montgom-xz.html#diffadd-dadd-1987-m-3 - // 4M + 2S + 6A +DERNode.prototype._encodeInt = function encodeInt(num, values) { + if (typeof num === 'string') { + if (!values) + return this.reporter.error('String int or enum given, but no values map'); + if (!values.hasOwnProperty(num)) { + return this.reporter.error('Values map doesn\'t contain: ' + + JSON.stringify(num)); + } + num = values[num]; + } - // A = X2 + Z2 - var a = this.x.redAdd(this.z); - // B = X2 - Z2 - var b = this.x.redSub(this.z); - // C = X3 + Z3 - var c = p.x.redAdd(p.z); - // D = X3 - Z3 - var d = p.x.redSub(p.z); - // DA = D * A - var da = d.redMul(a); - // CB = C * B - var cb = c.redMul(b); - // X5 = Z1 * (DA + CB)^2 - var nx = diff.z.redMul(da.redAdd(cb).redSqr()); - // Z5 = X1 * (DA - CB)^2 - var nz = diff.x.redMul(da.redISub(cb).redSqr()); - return this.curve.point(nx, nz); -}; + // Bignum, assume big endian + if (typeof num !== 'number' && !Buffer.isBuffer(num)) { + var numArray = num.toArray(); + if (num.sign === false && numArray[0] & 0x80) { + numArray.unshift(0); + } + num = new Buffer(numArray); + } -Point.prototype.mul = function mul(k) { - var t = k.clone(); - var a = this; // (N / 2) * Q + Q - var b = this.curve.point(null, null); // (N / 2) * Q - var c = this; // Q + if (Buffer.isBuffer(num)) { + var size = num.length; + if (num.length === 0) + size++; - for (var bits = []; t.cmpn(0) !== 0; t.ishrn(1)) - bits.push(t.andln(1)); + var out = new Buffer(size); + num.copy(out); + if (num.length === 0) + out[0] = 0 + return this._createEncoderBuffer(out); + } - for (var i = bits.length - 1; i >= 0; i--) { - if (bits[i] === 0) { - // N * Q + Q = ((N / 2) * Q + Q)) + (N / 2) * Q - a = a.diffAdd(b, c); - // N * Q = 2 * ((N / 2) * Q + Q)) - b = b.dbl(); - } else { - // N * Q = ((N / 2) * Q + Q) + ((N / 2) * Q) - b = a.diffAdd(b, c); - // N * Q + Q = 2 * ((N / 2) * Q + Q) - a = a.dbl(); - } + if (num < 0x80) + return this._createEncoderBuffer(num); + + if (num < 0x100) + return this._createEncoderBuffer([0, num]); + + var size = 1; + for (var i = num; i >= 0x100; i >>= 8) + size++; + + var out = new Array(size); + for (var i = out.length - 1; i >= 0; i--) { + out[i] = num & 0xff; + num >>= 8; } - return b; + if(out[0] & 0x80) { + out.unshift(0); + } + + return this._createEncoderBuffer(new Buffer(out)); }; -Point.prototype.mulAdd = function mulAdd() { - throw new Error('Not supported on Montgomery curve'); +DERNode.prototype._encodeBool = function encodeBool(value) { + return this._createEncoderBuffer(value ? 0xff : 0); }; -Point.prototype.normalize = function normalize() { - this.x = this.x.redMul(this.z.redInvm()); - this.z = this.curve.one; - return this; +DERNode.prototype._use = function use(entity, obj) { + if (typeof entity === 'function') + entity = entity(obj); + return entity._getEncoder('der').tree; }; -Point.prototype.getX = function getX() { - // Normalize coordinates - this.normalize(); +DERNode.prototype._skipDefault = function skipDefault(dataBuffer, reporter, parent) { + var state = this._baseState; + var i; + if (state['default'] === null) + return false; - return this.x.fromRed(); + var data = dataBuffer.join(); + if (state.defaultBuffer === undefined) + state.defaultBuffer = this._encodeValue(state['default'], reporter, parent).join(); + + if (data.length !== state.defaultBuffer.length) + return false; + + for (i=0; i < data.length; i++) + if (data[i] !== state.defaultBuffer[i]) + return false; + + return true; }; -},{"../../elliptic":69,"../curve":72,"bn.js":67,"inherits":229}],74:[function(require,module,exports){ -var curve = require('../curve'); -var elliptic = require('../../elliptic'); -var bn = require('bn.js'); -var inherits = require('inherits'); -var Base = curve.base; +// Utility methods -var getNAF = elliptic.utils.getNAF; -var assert = elliptic.utils.assert; +function encodeTag(tag, primitive, cls, reporter) { + var res; -function ShortCurve(conf) { - Base.call(this, 'short', conf); + if (tag === 'seqof') + tag = 'seq'; + else if (tag === 'setof') + tag = 'set'; - this.a = new bn(conf.a, 16).toRed(this.red); - this.b = new bn(conf.b, 16).toRed(this.red); - this.tinv = this.two.redInvm(); + if (der.tagByName.hasOwnProperty(tag)) + res = der.tagByName[tag]; + else if (typeof tag === 'number' && (tag | 0) === tag) + res = tag; + else + return reporter.error('Unknown tag: ' + tag); - this.zeroA = this.a.fromRed().cmpn(0) === 0; - this.threeA = this.a.fromRed().sub(this.p).cmpn(-3) === 0; + if (res >= 0x1f) + return reporter.error('Multi-octet tag encoding unsupported'); - // If the curve is endomorphic, precalculate beta and lambda - this.endo = this._getEndomorphism(conf); - this._endoWnafT1 = new Array(4); - this._endoWnafT2 = new Array(4); -} -inherits(ShortCurve, Base); -module.exports = ShortCurve; + if (!primitive) + res |= 0x20; -ShortCurve.prototype._getEndomorphism = function _getEndomorphism(conf) { - // No efficient endomorphism - if (!this.zeroA || !this.g || !this.n || this.p.modn(3) !== 1) - return; + res |= (der.tagClassByName[cls || 'universal'] << 6); - // Compute beta and lambda, that lambda * P = (beta * Px; Py) - var beta; - var lambda; - if (conf.beta) { - beta = new bn(conf.beta, 16).toRed(this.red); - } else { - var betas = this._getEndoRoots(this.p); - // Choose the smallest beta - beta = betas[0].cmp(betas[1]) < 0 ? betas[0] : betas[1]; - beta = beta.toRed(this.red); - } - if (conf.lambda) { - lambda = new bn(conf.lambda, 16); - } else { - // Choose the lambda that is matching selected beta - var lambdas = this._getEndoRoots(this.n); - if (this.g.mul(lambdas[0]).x.cmp(this.g.x.redMul(beta)) === 0) { - lambda = lambdas[0]; - } else { - lambda = lambdas[1]; - assert(this.g.mul(lambda).x.cmp(this.g.x.redMul(beta)) === 0); - } - } + return res; +} - // Get basis vectors, used for balanced length-two representation - var basis; - if (conf.basis) { - basis = conf.basis.map(function(vec) { - return { - a: new bn(vec.a, 16), - b: new bn(vec.b, 16), - }; - }); - } else { - basis = this._getEndoBasis(lambda); - } +},{"../../asn1":89,"buffer":47,"inherits":240}],101:[function(require,module,exports){ +var encoders = exports; - return { - beta: beta, - lambda: lambda, - basis: basis - }; -}; +encoders.der = require('./der'); +encoders.pem = require('./pem'); -ShortCurve.prototype._getEndoRoots = function _getEndoRoots(num) { - // Find roots of for x^2 + x + 1 in F - // Root = (-1 +- Sqrt(-3)) / 2 - // - var red = num === this.p ? this.red : bn.mont(num); - var tinv = new bn(2).toRed(red).redInvm(); - var ntinv = tinv.redNeg(); - var one = new bn(1).toRed(red); +},{"./der":100,"./pem":102}],102:[function(require,module,exports){ +var inherits = require('inherits'); +var Buffer = require('buffer').Buffer; - var s = new bn(3).toRed(red).redNeg().redSqrt().redMul(tinv); +var asn1 = require('../../asn1'); +var DEREncoder = require('./der'); - var l1 = ntinv.redAdd(s).fromRed(); - var l2 = ntinv.redSub(s).fromRed(); - return [ l1, l2 ]; +function PEMEncoder(entity) { + DEREncoder.call(this, entity); + this.enc = 'pem'; }; +inherits(PEMEncoder, DEREncoder); +module.exports = PEMEncoder; -ShortCurve.prototype._getEndoBasis = function _getEndoBasis(lambda) { - // aprxSqrt >= sqrt(this.n) - var aprxSqrt = this.n.shrn(Math.floor(this.n.bitLength() / 2)); - - // 3.74 - // Run EGCD, until r(L + 1) < aprxSqrt - var u = lambda; - var v = this.n.clone(); - var x1 = new bn(1); - var y1 = new bn(0); - var x2 = new bn(0); - var y2 = new bn(1); +PEMEncoder.prototype.encode = function encode(data, options) { + var buf = DEREncoder.prototype.encode.call(this, data); - // NOTE: all vectors are roots of: a + b * lambda = 0 (mod n) - var a0; - var b0; - // First vector - var a1; - var b1; - // Second vector - var a2; - var b2; + var p = buf.toString('base64'); + var out = [ '-----BEGIN ' + options.label + '-----' ]; + for (var i = 0; i < p.length; i += 64) + out.push(p.slice(i, i + 64)); + out.push('-----END ' + options.label + '-----'); + return out.join('\n'); +}; - var prevR; - var i = 0; - while (u.cmpn(0) !== 0) { - var q = v.div(u); - var r = v.sub(q.mul(u)); - var x = x2.sub(q.mul(x1)); - var y = y2.sub(q.mul(y1)); +},{"../../asn1":89,"./der":100,"buffer":47,"inherits":240}],103:[function(require,module,exports){ +module.exports=require(79) +},{"/home/braydon/bitcore/node_modules/bitcore-build/node_modules/browserify/node_modules/crypto-browserify/node_modules/browserify-cipher/node_modules/browserify-des/node_modules/des.js/node_modules/minimalistic-assert/index.js":79}],104:[function(require,module,exports){ +module.exports=require(53) +},{"/home/braydon/bitcore/node_modules/bitcore-build/node_modules/browserify/node_modules/crypto-browserify/node_modules/browserify-cipher/node_modules/browserify-aes/aes.js":53,"buffer":47}],105:[function(require,module,exports){ +module.exports=require(54) +},{"./aes":104,"./ghash":109,"/home/braydon/bitcore/node_modules/bitcore-build/node_modules/browserify/node_modules/crypto-browserify/node_modules/browserify-cipher/node_modules/browserify-aes/authCipher.js":54,"buffer":47,"buffer-xor":118,"cipher-base":119,"inherits":240}],106:[function(require,module,exports){ +module.exports=require(55) +},{"./decrypter":107,"./encrypter":108,"./modes":110,"/home/braydon/bitcore/node_modules/bitcore-build/node_modules/browserify/node_modules/crypto-browserify/node_modules/browserify-cipher/node_modules/browserify-aes/browser.js":55}],107:[function(require,module,exports){ +module.exports=require(56) +},{"./aes":104,"./authCipher":105,"./modes":110,"./modes/cbc":111,"./modes/cfb":112,"./modes/cfb1":113,"./modes/cfb8":114,"./modes/ctr":115,"./modes/ecb":116,"./modes/ofb":117,"./streamCipher":120,"/home/braydon/bitcore/node_modules/bitcore-build/node_modules/browserify/node_modules/crypto-browserify/node_modules/browserify-cipher/node_modules/browserify-aes/decrypter.js":56,"buffer":47,"cipher-base":119,"evp_bytestokey":121,"inherits":240}],108:[function(require,module,exports){ +module.exports=require(57) +},{"./aes":104,"./authCipher":105,"./modes":110,"./modes/cbc":111,"./modes/cfb":112,"./modes/cfb1":113,"./modes/cfb8":114,"./modes/ctr":115,"./modes/ecb":116,"./modes/ofb":117,"./streamCipher":120,"/home/braydon/bitcore/node_modules/bitcore-build/node_modules/browserify/node_modules/crypto-browserify/node_modules/browserify-cipher/node_modules/browserify-aes/encrypter.js":57,"buffer":47,"cipher-base":119,"evp_bytestokey":121,"inherits":240}],109:[function(require,module,exports){ +module.exports=require(58) +},{"/home/braydon/bitcore/node_modules/bitcore-build/node_modules/browserify/node_modules/crypto-browserify/node_modules/browserify-cipher/node_modules/browserify-aes/ghash.js":58,"buffer":47}],110:[function(require,module,exports){ +module.exports=require(59) +},{"/home/braydon/bitcore/node_modules/bitcore-build/node_modules/browserify/node_modules/crypto-browserify/node_modules/browserify-cipher/node_modules/browserify-aes/modes.js":59}],111:[function(require,module,exports){ +module.exports=require(60) +},{"/home/braydon/bitcore/node_modules/bitcore-build/node_modules/browserify/node_modules/crypto-browserify/node_modules/browserify-cipher/node_modules/browserify-aes/modes/cbc.js":60,"buffer-xor":118}],112:[function(require,module,exports){ +module.exports=require(61) +},{"/home/braydon/bitcore/node_modules/bitcore-build/node_modules/browserify/node_modules/crypto-browserify/node_modules/browserify-cipher/node_modules/browserify-aes/modes/cfb.js":61,"buffer":47,"buffer-xor":118}],113:[function(require,module,exports){ +module.exports=require(62) +},{"/home/braydon/bitcore/node_modules/bitcore-build/node_modules/browserify/node_modules/crypto-browserify/node_modules/browserify-cipher/node_modules/browserify-aes/modes/cfb1.js":62,"buffer":47}],114:[function(require,module,exports){ +module.exports=require(63) +},{"/home/braydon/bitcore/node_modules/bitcore-build/node_modules/browserify/node_modules/crypto-browserify/node_modules/browserify-cipher/node_modules/browserify-aes/modes/cfb8.js":63,"buffer":47}],115:[function(require,module,exports){ +module.exports=require(64) +},{"/home/braydon/bitcore/node_modules/bitcore-build/node_modules/browserify/node_modules/crypto-browserify/node_modules/browserify-cipher/node_modules/browserify-aes/modes/ctr.js":64,"buffer":47,"buffer-xor":118}],116:[function(require,module,exports){ +module.exports=require(65) +},{"/home/braydon/bitcore/node_modules/bitcore-build/node_modules/browserify/node_modules/crypto-browserify/node_modules/browserify-cipher/node_modules/browserify-aes/modes/ecb.js":65}],117:[function(require,module,exports){ +module.exports=require(66) +},{"/home/braydon/bitcore/node_modules/bitcore-build/node_modules/browserify/node_modules/crypto-browserify/node_modules/browserify-cipher/node_modules/browserify-aes/modes/ofb.js":66,"buffer":47,"buffer-xor":118}],118:[function(require,module,exports){ +module.exports=require(67) +},{"/home/braydon/bitcore/node_modules/bitcore-build/node_modules/browserify/node_modules/crypto-browserify/node_modules/browserify-cipher/node_modules/browserify-aes/node_modules/buffer-xor/index.js":67,"buffer":47}],119:[function(require,module,exports){ +module.exports=require(68) +},{"/home/braydon/bitcore/node_modules/bitcore-build/node_modules/browserify/node_modules/crypto-browserify/node_modules/browserify-cipher/node_modules/browserify-aes/node_modules/cipher-base/index.js":68,"buffer":47,"inherits":240,"stream":210,"string_decoder":211}],120:[function(require,module,exports){ +module.exports=require(69) +},{"./aes":104,"/home/braydon/bitcore/node_modules/bitcore-build/node_modules/browserify/node_modules/crypto-browserify/node_modules/browserify-cipher/node_modules/browserify-aes/streamCipher.js":69,"buffer":47,"cipher-base":119,"inherits":240}],121:[function(require,module,exports){ +module.exports=require(80) +},{"/home/braydon/bitcore/node_modules/bitcore-build/node_modules/browserify/node_modules/crypto-browserify/node_modules/browserify-cipher/node_modules/evp_bytestokey/index.js":80,"buffer":47,"create-hash/md5":127}],122:[function(require,module,exports){ +(function (Buffer){ +// much of this based on https://github.com/indutny/self-signed/blob/gh-pages/lib/rsa.js +var createHmac = require('create-hmac') +var crt = require('browserify-rsa') +var curves = require('./curves') +var elliptic = require('elliptic') +var parseKeys = require('parse-asn1') - if (!a1 && r.cmp(aprxSqrt) < 0) { - a0 = prevR.neg(); - b0 = x1; - a1 = r.neg(); - b1 = x; - } else if (a1 && ++i === 2) { - break; - } - prevR = r; +var BN = require('bn.js') +var EC = elliptic.ec - v = u; - u = r; - x2 = x1; - x1 = x; - y2 = y1; - y1 = y; - } - a2 = r.neg(); - b2 = x; +function sign (hash, key, hashType, signType) { + var priv = parseKeys(key) + if (priv.curve) { + if (signType !== 'ecdsa') throw new Error('wrong private key type') - var len1 = a1.sqr().add(b1.sqr()); - var len2 = a2.sqr().add(b2.sqr()); - if (len2.cmp(len1) >= 0) { - a2 = a0; - b2 = b0; + return ecSign(hash, priv) + } else if (priv.type === 'dsa') { + if (signType !== 'dsa') { + throw new Error('wrong private key type') + } + return dsaSign(hash, priv, hashType) + } else { + if (signType !== 'rsa') throw new Error('wrong private key type') } - // Normalize signs - if (a1.sign) { - a1 = a1.neg(); - b1 = b1.neg(); + var len = priv.modulus.byteLength() + var pad = [ 0, 1 ] + while (hash.length + pad.length + 1 < len) { + pad.push(0xff) } - if (a2.sign) { - a2 = a2.neg(); - b2 = b2.neg(); + pad.push(0x00) + var i = -1 + while (++i < hash.length) { + pad.push(hash[i]) } - return [ - { a: a1, b: b1 }, - { a: a2, b: b2 } - ]; -}; + var out = crt(pad, priv) + return out +} -ShortCurve.prototype._endoSplit = function _endoSplit(k) { - var basis = this.endo.basis; - var v1 = basis[0]; - var v2 = basis[1]; +function ecSign (hash, priv) { + var curveId = curves[priv.curve.join('.')] + if (!curveId) throw new Error('unknown curve ' + priv.curve.join('.')) - var c1 = v2.b.mul(k).divRound(this.n); - var c2 = v1.b.neg().mul(k).divRound(this.n); + var curve = new EC(curveId) + var key = curve.genKeyPair() - var p1 = c1.mul(v1.a); - var p2 = c2.mul(v2.a); - var q1 = c1.mul(v1.b); - var q2 = c2.mul(v2.b); + key._importPrivate(priv.privateKey) + var out = key.sign(hash) - // Calculate answer - var k1 = k.sub(p1).sub(p2); - var k2 = q1.add(q2).neg(); - return { k1: k1, k2: k2 }; -}; + return new Buffer(out.toDER()) +} -ShortCurve.prototype.point = function point(x, y, isRed) { - return new Point(this, x, y, isRed); -}; +function dsaSign (hash, priv, algo) { + var x = priv.params.priv_key + var p = priv.params.p + var q = priv.params.q + var g = priv.params.g + var r = new BN(0) + var k + var H = bits2int(hash, q).mod(q) + var s = false + var kv = getKey(x, q, hash, algo) + while (s === false) { + k = makeKey(q, kv, algo) + r = makeR(g, k, p, q) + s = k.invm(q).imul(H.add(x.mul(r))).mod(q) + if (!s.cmpn(0)) { + s = false + r = new BN(0) + } + } + return toDER(r, s) +} -ShortCurve.prototype.pointFromX = function pointFromX(odd, x) { - x = new bn(x, 16); - if (!x.red) - x = x.toRed(this.red); +function toDER (r, s) { + r = r.toArray() + s = s.toArray() - var y2 = x.redSqr().redMul(x).redIAdd(x.redMul(this.a)).redIAdd(this.b); - var y = y2.redSqrt(); + // Pad values + if (r[0] & 0x80) { + r = [ 0 ].concat(r) + } + // Pad values + if (s[0] & 0x80) { + s = [0].concat(s) + } - // XXX Is there any way to tell if the number is odd without converting it - // to non-red form? - var isOdd = y.fromRed().isOdd(); - if (odd && !isOdd || !odd && isOdd) - y = y.redNeg(); + var total = r.length + s.length + 4 + var res = [ 0x30, total, 0x02, r.length ] + res = res.concat(r, [ 0x02, s.length ], s) + return new Buffer(res) +} - return this.point(x, y); -}; +function getKey (x, q, hash, algo) { + x = new Buffer(x.toArray()) + if (x.length < q.byteLength()) { + var zeros = new Buffer(q.byteLength() - x.length) + zeros.fill(0) + x = Buffer.concat([zeros, x]) + } + var hlen = hash.length + var hbits = bits2octets(hash, q) + var v = new Buffer(hlen) + v.fill(1) + var k = new Buffer(hlen) + k.fill(0) + k = createHmac(algo, k) + .update(v) + .update(new Buffer([0])) + .update(x) + .update(hbits) + .digest() + v = createHmac(algo, k) + .update(v) + .digest() + k = createHmac(algo, k) + .update(v) + .update(new Buffer([1])) + .update(x) + .update(hbits) + .digest() + v = createHmac(algo, k) + .update(v) + .digest() + return { + k: k, + v: v + } +} -ShortCurve.prototype.jpoint = function jpoint(x, y, z) { - return new JPoint(this, x, y, z); -}; +function bits2int (obits, q) { + var bits = new BN(obits) + var shift = (obits.length << 3) - q.bitLength() + if (shift > 0) { + bits.ishrn(shift) + } + return bits +} -ShortCurve.prototype.pointFromJSON = function pointFromJSON(obj, red) { - return Point.fromJSON(this, obj, red); -}; +function bits2octets (bits, q) { + bits = bits2int(bits, q) + bits = bits.mod(q) + var out = new Buffer(bits.toArray()) + if (out.length < q.byteLength()) { + var zeros = new Buffer(q.byteLength() - out.length) + zeros.fill(0) + out = Buffer.concat([zeros, out]) + } + return out +} -ShortCurve.prototype.validate = function validate(point) { - if (point.inf) - return true; +function makeKey (q, kv, algo) { + var t, k - var x = point.x; - var y = point.y; + do { + t = new Buffer('') - var ax = this.a.redMul(x); - var rhs = x.redSqr().redMul(x).redIAdd(ax).redIAdd(this.b); - return y.redSqr().redISub(rhs).cmpn(0) === 0; -}; + while (t.length * 8 < q.bitLength()) { + kv.v = createHmac(algo, kv.k) + .update(kv.v) + .digest() + t = Buffer.concat([t, kv.v]) + } -ShortCurve.prototype._endoWnafMulAdd = function _endoWnafMulAdd(points, coeffs) { - var npoints = this._endoWnafT1; - var ncoeffs = this._endoWnafT2; - for (var i = 0; i < points.length; i++) { - var split = this._endoSplit(coeffs[i]); - var p = points[i]; - var beta = p._getBeta(); + k = bits2int(t, q) + kv.k = createHmac(algo, kv.k) + .update(kv.v) + .update(new Buffer([0])) + .digest() + kv.v = createHmac(algo, kv.k) + .update(kv.v) + .digest() + } while (k.cmp(q) !== -1) - if (split.k1.sign) { - split.k1.sign = !split.k1.sign; - p = p.neg(true); + return k +} + +function makeR (g, k, p, q) { + return g.toRed(BN.mont(p)).redPow(k).fromRed().mod(q) +} + +module.exports = sign +module.exports.getKey = getKey +module.exports.makeKey = makeKey + +}).call(this,require("buffer").Buffer) +},{"./curves":83,"bn.js":217,"browserify-rsa":84,"buffer":47,"create-hmac":138,"elliptic":219,"parse-asn1":88}],123:[function(require,module,exports){ +(function (Buffer){ +// much of this based on https://github.com/indutny/self-signed/blob/gh-pages/lib/rsa.js +var curves = require('./curves') +var elliptic = require('elliptic') +var parseKeys = require('parse-asn1') + +var BN = require('bn.js') +var EC = elliptic.ec + +function verify (sig, hash, key, signType) { + var pub = parseKeys(key) + if (pub.type === 'ec') { + if (signType !== 'ecdsa') { + throw new Error('wrong public key type') } - if (split.k2.sign) { - split.k2.sign = !split.k2.sign; - beta = beta.neg(true); + return ecVerify(sig, hash, pub) + } else if (pub.type === 'dsa') { + if (signType !== 'dsa') { + throw new Error('wrong public key type') + } + return dsaVerify(sig, hash, pub) + } else { + if (signType !== 'rsa') { + throw new Error('wrong public key type') } - - npoints[i * 2] = p; - npoints[i * 2 + 1] = beta; - ncoeffs[i * 2] = split.k1; - ncoeffs[i * 2 + 1] = split.k2; } - var res = this._wnafMulAdd(1, npoints, ncoeffs, i * 2); + var len = pub.modulus.byteLength() + var pad = [ 1 ] + var padNum = 0 + while (hash.length + pad.length + 2 < len) { + pad.push(0xff) + padNum++ + } + pad.push(0x00) + var i = -1 + while (++i < hash.length) { + pad.push(hash[i]) + } + pad = new Buffer(pad) + var red = BN.mont(pub.modulus) + sig = new BN(sig).toRed(red) - // Clean-up references to points and coefficients - for (var j = 0; j < i * 2; j++) { - npoints[j] = null; - ncoeffs[j] = null; + sig = sig.redPow(new BN(pub.publicExponent)) + + sig = new Buffer(sig.fromRed().toArray()) + var out = 0 + if (padNum < 8) { + out = 1 + } + len = Math.min(sig.length, pad.length) + if (sig.length !== pad.length) { + out = 1 } - return res; -}; -function Point(curve, x, y, isRed) { - Base.BasePoint.call(this, curve, 'affine'); - if (x === null && y === null) { - this.x = null; - this.y = null; - this.inf = true; - } else { - this.x = new bn(x, 16); - this.y = new bn(y, 16); - // Force redgomery representation when loading from JSON - if (isRed) { - this.x.forceRed(this.curve.red); - this.y.forceRed(this.curve.red); - } - if (!this.x.red) - this.x = this.x.toRed(this.curve.red); - if (!this.y.red) - this.y = this.y.toRed(this.curve.red); - this.inf = false; + i = -1 + while (++i < len) { + out |= (sig[i] ^ pad[i]) } + return out === 0 } -inherits(Point, Base.BasePoint); -Point.prototype._getBeta = function _getBeta() { - if (!this.curve.endo) - return; +function ecVerify (sig, hash, pub) { + var curveId = curves[pub.data.algorithm.curve.join('.')] + if (!curveId) throw new Error('unknown curve ' + pub.data.algorithm.curve.join('.')) - var pre = this.precomputed; - if (pre && pre.beta) - return pre.beta; + var curve = new EC(curveId) + var pubkey = pub.data.subjectPrivateKey.data - var beta = this.curve.point(this.x.redMul(this.curve.endo.beta), this.y); - if (pre) { - var curve = this.curve; - function endoMul(p) { - return curve.point(p.x.redMul(curve.endo.beta), p.y); - } - pre.beta = beta; - beta.precomputed = { - beta: null, - naf: pre.naf && { - wnd: pre.naf.wnd, - points: pre.naf.points.map(endoMul) - }, - doubles: pre.doubles && { - step: pre.doubles.step, - points: pre.doubles.points.map(endoMul) - } - }; - } - return beta; -}; - -Point.prototype.toJSON = function toJSON() { - if (!this.precomputed) - return [ this.x, this.y ]; - - return [ this.x, this.y, this.precomputed && { - doubles: this.precomputed.doubles && { - step: this.precomputed.doubles.step, - points: this.precomputed.doubles.points.slice(1) - }, - naf: this.precomputed.naf && { - wnd: this.precomputed.naf.wnd, - points: this.precomputed.naf.points.slice(1) - } - }]; -}; + return curve.verify(hash, sig, pubkey) +} -Point.fromJSON = function fromJSON(curve, obj, red) { - if (typeof obj === 'string') - obj = JSON.parse(obj); - var res = curve.point(obj[0], obj[1], red); - if (!obj[2]) - return res; +function dsaVerify (sig, hash, pub) { + var p = pub.data.p + var q = pub.data.q + var g = pub.data.g + var y = pub.data.pub_key + var unpacked = parseKeys.signature.decode(sig, 'der') + var s = unpacked.s + var r = unpacked.r + checkValue(s, q) + checkValue(r, q) + var montp = BN.mont(p) + var w = s.invm(q) + var v = g.toRed(montp) + .redPow(new BN(hash).mul(w).mod(q)) + .fromRed() + .mul( + y.toRed(montp) + .redPow(r.mul(w).mod(q)) + .fromRed() + ).mod(p).mod(q) + return !v.cmp(r) +} - function obj2point(obj) { - return curve.point(obj[0], obj[1], red); +function checkValue (b, q) { + if (b.cmpn(0) <= 0) { + throw new Error('invalid sig') + } + if (b.cmp(q) >= q) { + throw new Error('invalid sig') } +} - var pre = obj[2]; - res.precomputed = { - beta: null, - doubles: pre.doubles && { - step: pre.doubles.step, - points: [ res ].concat(pre.doubles.points.map(obj2point)) - }, - naf: pre.naf && { - wnd: pre.naf.wnd, - points: [ res ].concat(pre.naf.points.map(obj2point)) - } - }; - return res; -}; +module.exports = verify -Point.prototype.inspect = function inspect() { - if (this.isInfinity()) - return ''; - return ''; -}; +}).call(this,require("buffer").Buffer) +},{"./curves":83,"bn.js":217,"buffer":47,"elliptic":219,"parse-asn1":88}],124:[function(require,module,exports){ +(function (Buffer){ +var elliptic = require('elliptic'); +var BN = require('bn.js'); -Point.prototype.isInfinity = function isInfinity() { - return this.inf; +module.exports = function createECDH(curve) { + return new ECDH(curve); }; -Point.prototype.add = function add(p) { - // O + P = P - if (this.inf) - return p; - - // P + O = P - if (p.inf) - return this; - - // P + P = 2P - if (this.eq(p)) - return this.dbl(); - - // P + (-P) = O - if (this.neg().eq(p)) - return this.curve.point(null, null); - - // P + Q = O - if (this.x.cmp(p.x) === 0) - return this.curve.point(null, null); - - var c = this.y.redSub(p.y); - if (c.cmpn(0) !== 0) - c = c.redMul(this.x.redSub(p.x).redInvm()); - var nx = c.redSqr().redISub(this.x).redISub(p.x); - var ny = c.redMul(this.x.redSub(nx)).redISub(this.y); - return this.curve.point(nx, ny); +var aliases = { + secp256k1: { + name: 'secp256k1', + byteLength: 32 + }, + secp224r1: { + name: 'p224', + byteLength: 28 + }, + prime256v1: { + name: 'p256', + byteLength: 32 + }, + prime192v1: { + name: 'p192', + byteLength: 24 + }, + ed25519: { + name: 'ed25519', + byteLength: 32 + } }; -Point.prototype.dbl = function dbl() { - if (this.inf) - return this; - - // 2P = O - var ys1 = this.y.redAdd(this.y); - if (ys1.cmpn(0) === 0) - return this.curve.point(null, null); - - var a = this.curve.a; +aliases.p224 = aliases.secp224r1; +aliases.p256 = aliases.secp256r1 = aliases.prime256v1; +aliases.p192 = aliases.secp192r1 = aliases.prime192v1; - var x2 = this.x.redSqr(); - var dyinv = ys1.redInvm(); - var c = x2.redAdd(x2).redIAdd(x2).redIAdd(a).redMul(dyinv); +function ECDH(curve) { + this.curveType = aliases[curve]; + if (!this.curveType ) { + this.curveType = { + name: curve + }; + } + this.curve = new elliptic.ec(this.curveType.name); + this.keys = void 0; +} - var nx = c.redSqr().redISub(this.x.redAdd(this.x)); - var ny = c.redMul(this.x.redSub(nx)).redISub(this.y); - return this.curve.point(nx, ny); +ECDH.prototype.generateKeys = function (enc, format) { + this.keys = this.curve.genKeyPair(); + return this.getPublicKey(enc, format); }; -Point.prototype.getX = function getX() { - return this.x.fromRed(); +ECDH.prototype.computeSecret = function (other, inenc, enc) { + inenc = inenc || 'utf8'; + if (!Buffer.isBuffer(other)) { + other = new Buffer(other, inenc); + } + var otherPub = this.curve.keyFromPublic(other).getPublic(); + var out = otherPub.mul(this.keys.getPrivate()).getX(); + return formatReturnValue(out, enc, this.curveType.byteLength); }; -Point.prototype.getY = function getY() { - return this.y.fromRed(); +ECDH.prototype.getPublicKey = function (enc, format) { + var key = this.keys.getPublic(format === 'compressed', true); + if (format === 'hybrid') { + if (key[key.length - 1] % 2) { + key[0] = 7; + } else { + key [0] = 6; + } + } + return formatReturnValue(key, enc); }; -Point.prototype.mul = function mul(k) { - k = new bn(k, 16); - - if (this.precomputed && this.precomputed.doubles) - return this.curve._fixedNafMul(this, k); - else if (this.curve.endo) - return this.curve._endoWnafMulAdd([ this ], [ k ]); - else - return this.curve._wnafMul(this, k); +ECDH.prototype.getPrivateKey = function (enc) { + return formatReturnValue(this.keys.getPrivate(), enc); }; -Point.prototype.mulAdd = function mulAdd(k1, p2, k2) { - var points = [ this, p2 ]; - var coeffs = [ k1, k2 ]; - if (this.curve.endo) - return this.curve._endoWnafMulAdd(points, coeffs); - else - return this.curve._wnafMulAdd(1, points, coeffs, 2); +ECDH.prototype.setPublicKey = function (pub, enc) { + enc = enc || 'utf8'; + if (!Buffer.isBuffer(pub)) { + pub = new Buffer(pub, enc); + } + this.keys._importPublic(pub); + return this; }; -Point.prototype.eq = function eq(p) { - return this === p || - this.inf === p.inf && - (this.inf || this.x.cmp(p.x) === 0 && this.y.cmp(p.y) === 0); +ECDH.prototype.setPrivateKey = function (priv, enc) { + enc = enc || 'utf8'; + if (!Buffer.isBuffer(priv)) { + priv = new Buffer(priv, enc); + } + var _priv = new BN(priv); + _priv = _priv.toString(16); + this.keys._importPrivate(_priv); + return this; }; -Point.prototype.neg = function neg(_precompute) { - if (this.inf) - return this; - - var res = this.curve.point(this.x, this.y.redNeg()); - if (_precompute && this.precomputed) { - var pre = this.precomputed; - function negate(p) { - return p.neg(); - } - res.precomputed = { - naf: pre.naf && { - wnd: pre.naf.wnd, - points: pre.naf.points.map(negate) - }, - doubles: pre.doubles && { - step: pre.doubles.step, - points: pre.doubles.points.map(negate) - } - }; - } - return res; -}; +function formatReturnValue(bn, enc, len) { + if (!Array.isArray(bn)) { + bn = bn.toArray(); + } + var buf = new Buffer(bn); + if (len && buf.length < len) { + var zeros = new Buffer(len - buf.length); + zeros.fill(0); + buf = Buffer.concat([zeros, buf]); + } + if (!enc) { + return buf; + } else { + return buf.toString(enc); + } +} -Point.prototype.toJ = function toJ() { - if (this.inf) - return this.curve.jpoint(null, null, null); +}).call(this,require("buffer").Buffer) +},{"bn.js":217,"buffer":47,"elliptic":219}],125:[function(require,module,exports){ +(function (Buffer){ +'use strict'; +var inherits = require('inherits') +var md5 = require('./md5') +var rmd160 = require('ripemd160') +var sha = require('sha.js') - var res = this.curve.jpoint(this.x, this.y, this.curve.one); - return res; -}; +var Base = require('cipher-base') -function JPoint(curve, x, y, z) { - Base.BasePoint.call(this, curve, 'jacobian'); - if (x === null && y === null && z === null) { - this.x = this.curve.one; - this.y = this.curve.one; - this.z = new bn(0); - } else { - this.x = new bn(x, 16); - this.y = new bn(y, 16); - this.z = new bn(z, 16); - } - if (!this.x.red) - this.x = this.x.toRed(this.curve.red); - if (!this.y.red) - this.y = this.y.toRed(this.curve.red); - if (!this.z.red) - this.z = this.z.toRed(this.curve.red); +function HashNoConstructor(hash) { + Base.call(this, 'digest') - this.zOne = this.z === this.curve.one; + this._hash = hash + this.buffers = [] } -inherits(JPoint, Base.BasePoint); -JPoint.prototype.toP = function toP() { - if (this.isInfinity()) - return this.curve.point(null, null); +inherits(HashNoConstructor, Base) - var zinv = this.z.redInvm(); - var zinv2 = zinv.redSqr(); - var ax = this.x.redMul(zinv2); - var ay = this.y.redMul(zinv2).redMul(zinv); +HashNoConstructor.prototype._update = function (data) { + this.buffers.push(data) +} - return this.curve.point(ax, ay); -}; +HashNoConstructor.prototype._final = function () { + var buf = Buffer.concat(this.buffers) + var r = this._hash(buf) + this.buffers = null -JPoint.prototype.neg = function neg() { - return this.curve.jpoint(this.x, this.y.redNeg(), this.z); -}; + return r +} -JPoint.prototype.add = function add(p) { - // O + P = P - if (this.isInfinity()) - return p; +function Hash(hash) { + Base.call(this, 'digest') - // P + O = P - if (p.isInfinity()) - return this; + this._hash = hash +} - // 12M + 4S + 7A - var pz2 = p.z.redSqr(); - var z2 = this.z.redSqr(); - var u1 = this.x.redMul(pz2); - var u2 = p.x.redMul(z2); - var s1 = this.y.redMul(pz2.redMul(p.z)); - var s2 = p.y.redMul(z2.redMul(this.z)); +inherits(Hash, Base) - var h = u1.redSub(u2); - var r = s1.redSub(s2); - if (h.cmpn(0) === 0) { - if (r.cmpn(0) !== 0) - return this.curve.jpoint(null, null, null); - else - return this.dbl(); - } +Hash.prototype._update = function (data) { + this._hash.update(data) +} - var h2 = h.redSqr(); - var h3 = h2.redMul(h); - var v = u1.redMul(h2); +Hash.prototype._final = function () { + return this._hash.digest() +} - var nx = r.redSqr().redIAdd(h3).redISub(v).redISub(v); - var ny = r.redMul(v.redISub(nx)).redISub(s1.redMul(h3)); - var nz = this.z.redMul(p.z).redMul(h); +module.exports = function createHash (alg) { + alg = alg.toLowerCase() + if ('md5' === alg) return new HashNoConstructor(md5) + if ('rmd160' === alg || 'ripemd160' === alg) return new HashNoConstructor(rmd160) - return this.curve.jpoint(nx, ny, nz); -}; + return new Hash(sha(alg)) +} -JPoint.prototype.mixedAdd = function mixedAdd(p) { - // O + P = P - if (this.isInfinity()) - return p.toJ(); +}).call(this,require("buffer").Buffer) +},{"./md5":127,"buffer":47,"cipher-base":128,"inherits":240,"ripemd160":129,"sha.js":131}],126:[function(require,module,exports){ +(function (Buffer){ +'use strict'; +var intSize = 4; +var zeroBuffer = new Buffer(intSize); zeroBuffer.fill(0); +var chrsz = 8; - // P + O = P - if (p.isInfinity()) - return this; +function toArray(buf, bigEndian) { + if ((buf.length % intSize) !== 0) { + var len = buf.length + (intSize - (buf.length % intSize)); + buf = Buffer.concat([buf, zeroBuffer], len); + } - // 8M + 3S + 7A - var z2 = this.z.redSqr(); - var u1 = this.x; - var u2 = p.x.redMul(z2); - var s1 = this.y; - var s2 = p.y.redMul(z2).redMul(this.z); + var arr = []; + var fn = bigEndian ? buf.readInt32BE : buf.readInt32LE; + for (var i = 0; i < buf.length; i += intSize) { + arr.push(fn.call(buf, i)); + } + return arr; +} - var h = u1.redSub(u2); - var r = s1.redSub(s2); - if (h.cmpn(0) === 0) { - if (r.cmpn(0) !== 0) - return this.curve.jpoint(null, null, null); - else - return this.dbl(); +function toBuffer(arr, size, bigEndian) { + var buf = new Buffer(size); + var fn = bigEndian ? buf.writeInt32BE : buf.writeInt32LE; + for (var i = 0; i < arr.length; i++) { + fn.call(buf, arr[i], i * 4, true); } + return buf; +} - var h2 = h.redSqr(); - var h3 = h2.redMul(h); - var v = u1.redMul(h2); +function hash(buf, fn, hashSize, bigEndian) { + if (!Buffer.isBuffer(buf)) buf = new Buffer(buf); + var arr = fn(toArray(buf, bigEndian), buf.length * chrsz); + return toBuffer(arr, hashSize, bigEndian); +} +exports.hash = hash; +}).call(this,require("buffer").Buffer) +},{"buffer":47}],127:[function(require,module,exports){ +'use strict'; +/* + * A JavaScript implementation of the RSA Data Security, Inc. MD5 Message + * Digest Algorithm, as defined in RFC 1321. + * Version 2.1 Copyright (C) Paul Johnston 1999 - 2002. + * Other contributors: Greg Holt, Andrew Kepert, Ydnar, Lostinet + * Distributed under the BSD License + * See http://pajhome.org.uk/crypt/md5 for more info. + */ - var nx = r.redSqr().redIAdd(h3).redISub(v).redISub(v); - var ny = r.redMul(v.redISub(nx)).redISub(s1.redMul(h3)); - var nz = this.z.redMul(h); +var helpers = require('./helpers'); - return this.curve.jpoint(nx, ny, nz); -}; +/* + * Calculate the MD5 of an array of little-endian words, and a bit length + */ +function core_md5(x, len) +{ + /* append padding */ + x[len >> 5] |= 0x80 << ((len) % 32); + x[(((len + 64) >>> 9) << 4) + 14] = len; -JPoint.prototype.dblp = function dblp(pow) { - if (pow === 0) - return this; - if (this.isInfinity()) - return this; - if (!pow) - return this.dbl(); + var a = 1732584193; + var b = -271733879; + var c = -1732584194; + var d = 271733878; - if (this.curve.zeroA || this.curve.threeA) { - var r = this; - for (var i = 0; i < pow; i++) - r = r.dbl(); - return r; - } + for(var i = 0; i < x.length; i += 16) + { + var olda = a; + var oldb = b; + var oldc = c; + var oldd = d; - // 1M + 2S + 1A + N * (4S + 5M + 8A) - // N = 1 => 6M + 6S + 9A - var a = this.curve.a; - var tinv = this.curve.tinv; + a = md5_ff(a, b, c, d, x[i+ 0], 7 , -680876936); + d = md5_ff(d, a, b, c, x[i+ 1], 12, -389564586); + c = md5_ff(c, d, a, b, x[i+ 2], 17, 606105819); + b = md5_ff(b, c, d, a, x[i+ 3], 22, -1044525330); + a = md5_ff(a, b, c, d, x[i+ 4], 7 , -176418897); + d = md5_ff(d, a, b, c, x[i+ 5], 12, 1200080426); + c = md5_ff(c, d, a, b, x[i+ 6], 17, -1473231341); + b = md5_ff(b, c, d, a, x[i+ 7], 22, -45705983); + a = md5_ff(a, b, c, d, x[i+ 8], 7 , 1770035416); + d = md5_ff(d, a, b, c, x[i+ 9], 12, -1958414417); + c = md5_ff(c, d, a, b, x[i+10], 17, -42063); + b = md5_ff(b, c, d, a, x[i+11], 22, -1990404162); + a = md5_ff(a, b, c, d, x[i+12], 7 , 1804603682); + d = md5_ff(d, a, b, c, x[i+13], 12, -40341101); + c = md5_ff(c, d, a, b, x[i+14], 17, -1502002290); + b = md5_ff(b, c, d, a, x[i+15], 22, 1236535329); - var jx = this.x; - var jy = this.y; - var jz = this.z; - var jz4 = jz.redSqr().redSqr(); + a = md5_gg(a, b, c, d, x[i+ 1], 5 , -165796510); + d = md5_gg(d, a, b, c, x[i+ 6], 9 , -1069501632); + c = md5_gg(c, d, a, b, x[i+11], 14, 643717713); + b = md5_gg(b, c, d, a, x[i+ 0], 20, -373897302); + a = md5_gg(a, b, c, d, x[i+ 5], 5 , -701558691); + d = md5_gg(d, a, b, c, x[i+10], 9 , 38016083); + c = md5_gg(c, d, a, b, x[i+15], 14, -660478335); + b = md5_gg(b, c, d, a, x[i+ 4], 20, -405537848); + a = md5_gg(a, b, c, d, x[i+ 9], 5 , 568446438); + d = md5_gg(d, a, b, c, x[i+14], 9 , -1019803690); + c = md5_gg(c, d, a, b, x[i+ 3], 14, -187363961); + b = md5_gg(b, c, d, a, x[i+ 8], 20, 1163531501); + a = md5_gg(a, b, c, d, x[i+13], 5 , -1444681467); + d = md5_gg(d, a, b, c, x[i+ 2], 9 , -51403784); + c = md5_gg(c, d, a, b, x[i+ 7], 14, 1735328473); + b = md5_gg(b, c, d, a, x[i+12], 20, -1926607734); - // Reuse results - var jyd = jy.redAdd(jy); - for (var i = 0; i < pow; i++) { - var jx2 = jx.redSqr(); - var jyd2 = jyd.redSqr(); - var jyd4 = jyd2.redSqr(); - var c = jx2.redAdd(jx2).redIAdd(jx2).redIAdd(a.redMul(jz4)); + a = md5_hh(a, b, c, d, x[i+ 5], 4 , -378558); + d = md5_hh(d, a, b, c, x[i+ 8], 11, -2022574463); + c = md5_hh(c, d, a, b, x[i+11], 16, 1839030562); + b = md5_hh(b, c, d, a, x[i+14], 23, -35309556); + a = md5_hh(a, b, c, d, x[i+ 1], 4 , -1530992060); + d = md5_hh(d, a, b, c, x[i+ 4], 11, 1272893353); + c = md5_hh(c, d, a, b, x[i+ 7], 16, -155497632); + b = md5_hh(b, c, d, a, x[i+10], 23, -1094730640); + a = md5_hh(a, b, c, d, x[i+13], 4 , 681279174); + d = md5_hh(d, a, b, c, x[i+ 0], 11, -358537222); + c = md5_hh(c, d, a, b, x[i+ 3], 16, -722521979); + b = md5_hh(b, c, d, a, x[i+ 6], 23, 76029189); + a = md5_hh(a, b, c, d, x[i+ 9], 4 , -640364487); + d = md5_hh(d, a, b, c, x[i+12], 11, -421815835); + c = md5_hh(c, d, a, b, x[i+15], 16, 530742520); + b = md5_hh(b, c, d, a, x[i+ 2], 23, -995338651); - var t1 = jx.redMul(jyd2); - var nx = c.redSqr().redISub(t1.redAdd(t1)); - var t2 = t1.redISub(nx); - var dny = c.redMul(t2); - dny = dny.redIAdd(dny).redISub(jyd4); - var nz = jyd.redMul(jz); - if (i + 1 < pow) - jz4 = jz4.redMul(jyd4); + a = md5_ii(a, b, c, d, x[i+ 0], 6 , -198630844); + d = md5_ii(d, a, b, c, x[i+ 7], 10, 1126891415); + c = md5_ii(c, d, a, b, x[i+14], 15, -1416354905); + b = md5_ii(b, c, d, a, x[i+ 5], 21, -57434055); + a = md5_ii(a, b, c, d, x[i+12], 6 , 1700485571); + d = md5_ii(d, a, b, c, x[i+ 3], 10, -1894986606); + c = md5_ii(c, d, a, b, x[i+10], 15, -1051523); + b = md5_ii(b, c, d, a, x[i+ 1], 21, -2054922799); + a = md5_ii(a, b, c, d, x[i+ 8], 6 , 1873313359); + d = md5_ii(d, a, b, c, x[i+15], 10, -30611744); + c = md5_ii(c, d, a, b, x[i+ 6], 15, -1560198380); + b = md5_ii(b, c, d, a, x[i+13], 21, 1309151649); + a = md5_ii(a, b, c, d, x[i+ 4], 6 , -145523070); + d = md5_ii(d, a, b, c, x[i+11], 10, -1120210379); + c = md5_ii(c, d, a, b, x[i+ 2], 15, 718787259); + b = md5_ii(b, c, d, a, x[i+ 9], 21, -343485551); - jx = nx; - jz = nz; - jyd = dny; + a = safe_add(a, olda); + b = safe_add(b, oldb); + c = safe_add(c, oldc); + d = safe_add(d, oldd); } + return Array(a, b, c, d); - return this.curve.jpoint(jx, jyd.redMul(tinv), jz); -}; - -JPoint.prototype.dbl = function dbl() { - if (this.isInfinity()) - return this; +} - if (this.curve.zeroA) - return this._zeroDbl(); - else if (this.curve.threeA) - return this._threeDbl(); - else - return this._dbl(); -}; +/* + * These functions implement the four basic operations the algorithm uses. + */ +function md5_cmn(q, a, b, x, s, t) +{ + return safe_add(bit_rol(safe_add(safe_add(a, q), safe_add(x, t)), s),b); +} +function md5_ff(a, b, c, d, x, s, t) +{ + return md5_cmn((b & c) | ((~b) & d), a, b, x, s, t); +} +function md5_gg(a, b, c, d, x, s, t) +{ + return md5_cmn((b & d) | (c & (~d)), a, b, x, s, t); +} +function md5_hh(a, b, c, d, x, s, t) +{ + return md5_cmn(b ^ c ^ d, a, b, x, s, t); +} +function md5_ii(a, b, c, d, x, s, t) +{ + return md5_cmn(c ^ (b | (~d)), a, b, x, s, t); +} -JPoint.prototype._zeroDbl = function _zeroDbl() { - // Z = 1 - if (this.zOne) { - // http://hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-0.html#doubling-mdbl-2007-bl - // 1M + 5S + 14A +/* + * Add integers, wrapping at 2^32. This uses 16-bit operations internally + * to work around bugs in some JS interpreters. + */ +function safe_add(x, y) +{ + var lsw = (x & 0xFFFF) + (y & 0xFFFF); + var msw = (x >> 16) + (y >> 16) + (lsw >> 16); + return (msw << 16) | (lsw & 0xFFFF); +} - // XX = X1^2 - var xx = this.x.redSqr(); - // YY = Y1^2 - var yy = this.y.redSqr(); - // YYYY = YY^2 - var yyyy = yy.redSqr(); - // S = 2 * ((X1 + YY)^2 - XX - YYYY) - var s = this.x.redAdd(yy).redSqr().redISub(xx).redISub(yyyy); - s = s.redIAdd(s); - // M = 3 * XX + a; a = 0 - var m = xx.redAdd(xx).redIAdd(xx); - // T = M ^ 2 - 2*S - var t = m.redSqr().redISub(s).redISub(s); +/* + * Bitwise rotate a 32-bit number to the left. + */ +function bit_rol(num, cnt) +{ + return (num << cnt) | (num >>> (32 - cnt)); +} - // 8 * YYYY - var yyyy8 = yyyy.redIAdd(yyyy); - yyyy8 = yyyy8.redIAdd(yyyy8); - yyyy8 = yyyy8.redIAdd(yyyy8); +module.exports = function md5(buf) { + return helpers.hash(buf, core_md5, 16); +}; +},{"./helpers":126}],128:[function(require,module,exports){ +module.exports=require(68) +},{"/home/braydon/bitcore/node_modules/bitcore-build/node_modules/browserify/node_modules/crypto-browserify/node_modules/browserify-cipher/node_modules/browserify-aes/node_modules/cipher-base/index.js":68,"buffer":47,"inherits":240,"stream":210,"string_decoder":211}],129:[function(require,module,exports){ +(function (Buffer){ +/* +CryptoJS v3.1.2 +code.google.com/p/crypto-js +(c) 2009-2013 by Jeff Mott. All rights reserved. +code.google.com/p/crypto-js/wiki/License +*/ +/** @preserve +(c) 2012 by Cédric Mesnil. All rights reserved. - // X3 = T - var nx = t; - // Y3 = M * (S - T) - 8 * YYYY - var ny = m.redMul(s.redISub(t)).redISub(yyyy8); - // Z3 = 2*Y1 - var nz = this.y.redAdd(this.y); - } else { - // http://hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-0.html#doubling-dbl-2009-l - // 2M + 5S + 13A +Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: - // A = X1^2 - var a = this.x.redSqr(); - // B = Y1^2 - var b = this.y.redSqr(); - // C = B^2 - var c = b.redSqr(); - // D = 2 * ((X1 + B)^2 - A - C) - var d = this.x.redAdd(b).redSqr().redISub(a).redISub(c); - d = d.redIAdd(d); - // E = 3 * A - var e = a.redAdd(a).redIAdd(a); - // F = E^2 - var f = e.redSqr(); + - Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. + - Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. - // 8 * C - var c8 = c.redIAdd(c); - c8 = c8.redIAdd(c8); - c8 = c8.redIAdd(c8); +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ - // X3 = F - 2 * D - var nx = f.redISub(d).redISub(d); - // Y3 = E * (D - X3) - 8 * C - var ny = e.redMul(d.redISub(nx)).redISub(c8); - // Z3 = 2 * Y1 * Z1 - var nz = this.y.redMul(this.z); - nz = nz.redIAdd(nz); - } +// constants table +var zl = [ + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, + 7, 4, 13, 1, 10, 6, 15, 3, 12, 0, 9, 5, 2, 14, 11, 8, + 3, 10, 14, 4, 9, 15, 8, 1, 2, 7, 0, 6, 13, 11, 5, 12, + 1, 9, 11, 10, 0, 8, 12, 4, 13, 3, 7, 15, 14, 5, 6, 2, + 4, 0, 5, 9, 7, 12, 2, 10, 14, 1, 3, 8, 11, 6, 15, 13 +] - return this.curve.jpoint(nx, ny, nz); -}; +var zr = [ + 5, 14, 7, 0, 9, 2, 11, 4, 13, 6, 15, 8, 1, 10, 3, 12, + 6, 11, 3, 7, 0, 13, 5, 10, 14, 15, 8, 12, 4, 9, 1, 2, + 15, 5, 1, 3, 7, 14, 6, 9, 11, 8, 12, 2, 10, 0, 4, 13, + 8, 6, 4, 1, 3, 11, 15, 0, 5, 12, 2, 13, 9, 7, 10, 14, + 12, 15, 10, 4, 1, 5, 8, 7, 6, 2, 13, 14, 0, 3, 9, 11 +] -JPoint.prototype._threeDbl = function _threeDbl() { - // Z = 1 - if (this.zOne) { - // http://hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-3.html#doubling-mdbl-2007-bl - // 1M + 5S + 15A +var sl = [ + 11, 14, 15, 12, 5, 8, 7, 9, 11, 13, 14, 15, 6, 7, 9, 8, + 7, 6, 8, 13, 11, 9, 7, 15, 7, 12, 15, 9, 11, 7, 13, 12, + 11, 13, 6, 7, 14, 9, 13, 15, 14, 8, 13, 6, 5, 12, 7, 5, + 11, 12, 14, 15, 14, 15, 9, 8, 9, 14, 5, 6, 8, 6, 5, 12, + 9, 15, 5, 11, 6, 8, 13, 12, 5, 12, 13, 14, 11, 8, 5, 6 +] - // XX = X1^2 - var xx = this.x.redSqr(); - // YY = Y1^2 - var yy = this.y.redSqr(); - // YYYY = YY^2 - var yyyy = yy.redSqr(); - // S = 2 * ((X1 + YY)^2 - XX - YYYY) - var s = this.x.redAdd(yy).redSqr().redISub(xx).redISub(yyyy); - s = s.redIAdd(s); - // M = 3 * XX + a - var m = xx.redAdd(xx).redIAdd(xx).redIAdd(this.curve.a); - // T = M^2 - 2 * S - var t = m.redSqr().redISub(s).redISub(s); - // X3 = T - var nx = t; - // Y3 = M * (S - T) - 8 * YYYY - var yyyy8 = yyyy.redIAdd(yyyy); - yyyy8 = yyyy8.redIAdd(yyyy8); - yyyy8 = yyyy8.redIAdd(yyyy8); - var ny = m.redMul(s.redISub(t)).redISub(yyyy8); - // Z3 = 2 * Y1 - var nz = this.y.redAdd(this.y); - } else { - // http://hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-3.html#doubling-dbl-2001-b - // 3M + 5S +var sr = [ + 8, 9, 9, 11, 13, 15, 15, 5, 7, 7, 8, 11, 14, 14, 12, 6, + 9, 13, 15, 7, 12, 8, 9, 11, 7, 7, 12, 7, 6, 15, 13, 11, + 9, 7, 15, 11, 8, 6, 6, 14, 12, 13, 5, 14, 13, 13, 7, 5, + 15, 5, 8, 11, 14, 14, 6, 14, 6, 9, 12, 9, 12, 5, 15, 8, + 8, 5, 12, 9, 12, 5, 14, 6, 8, 13, 6, 5, 15, 13, 11, 11 +] - // delta = Z1^2 - var delta = this.z.redSqr(); - // gamma = Y1^2 - var gamma = this.y.redSqr(); - // beta = X1 * gamma - var beta = this.x.redMul(gamma); - // alpha = 3 * (X1 - delta) * (X1 + delta) - var alpha = this.x.redSub(delta).redMul(this.x.redAdd(delta)); - alpha = alpha.redAdd(alpha).redIAdd(alpha); - // X3 = alpha^2 - 8 * beta - var beta4 = beta.redIAdd(beta); - beta4 = beta4.redIAdd(beta4); - var beta8 = beta4.redAdd(beta4); - var nx = alpha.redSqr().redISub(beta8); - // Z3 = (Y1 + Z1)^2 - gamma - delta - var nz = this.y.redAdd(this.z).redSqr().redISub(gamma).redISub(delta); - // Y3 = alpha * (4 * beta - X3) - 8 * gamma^2 - var ggamma8 = gamma.redSqr(); - ggamma8 = ggamma8.redIAdd(ggamma8); - ggamma8 = ggamma8.redIAdd(ggamma8); - ggamma8 = ggamma8.redIAdd(ggamma8); - var ny = alpha.redMul(beta4.redISub(nx)).redISub(ggamma8); +var hl = [0x00000000, 0x5A827999, 0x6ED9EBA1, 0x8F1BBCDC, 0xA953FD4E] +var hr = [0x50A28BE6, 0x5C4DD124, 0x6D703EF3, 0x7A6D76E9, 0x00000000] + +function bytesToWords (bytes) { + var words = [] + for (var i = 0, b = 0; i < bytes.length; i++, b += 8) { + words[b >>> 5] |= bytes[i] << (24 - b % 32) } + return words +} - return this.curve.jpoint(nx, ny, nz); -}; +function wordsToBytes (words) { + var bytes = [] + for (var b = 0; b < words.length * 32; b += 8) { + bytes.push((words[b >>> 5] >>> (24 - b % 32)) & 0xFF) + } + return bytes +} -JPoint.prototype._dbl = function _dbl() { - var a = this.curve.a; - var tinv = this.curve.tinv; +function processBlock (H, M, offset) { + // swap endian + for (var i = 0; i < 16; i++) { + var offset_i = offset + i + var M_offset_i = M[offset_i] - // 4M + 6S + 10A - var jx = this.x; - var jy = this.y; - var jz = this.z; - var jz4 = jz.redSqr().redSqr(); + // Swap + M[offset_i] = ( + (((M_offset_i << 8) | (M_offset_i >>> 24)) & 0x00ff00ff) | + (((M_offset_i << 24) | (M_offset_i >>> 8)) & 0xff00ff00) + ) + } - var jx2 = jx.redSqr(); - var jy2 = jy.redSqr(); + // Working variables + var al, bl, cl, dl, el + var ar, br, cr, dr, er - var c = jx2.redAdd(jx2).redIAdd(jx2).redIAdd(a.redMul(jz4)); + ar = al = H[0] + br = bl = H[1] + cr = cl = H[2] + dr = dl = H[3] + er = el = H[4] - var jxd4 = jx.redAdd(jx); - jxd4 = jxd4.redIAdd(jxd4); - var t1 = jxd4.redMul(jy2); - var nx = c.redSqr().redISub(t1.redAdd(t1)); - var t2 = t1.redISub(nx); + // computation + var t + for (i = 0; i < 80; i += 1) { + t = (al + M[offset + zl[i]]) | 0 + if (i < 16) { + t += f1(bl, cl, dl) + hl[0] + } else if (i < 32) { + t += f2(bl, cl, dl) + hl[1] + } else if (i < 48) { + t += f3(bl, cl, dl) + hl[2] + } else if (i < 64) { + t += f4(bl, cl, dl) + hl[3] + } else {// if (i<80) { + t += f5(bl, cl, dl) + hl[4] + } + t = t | 0 + t = rotl(t, sl[i]) + t = (t + el) | 0 + al = el + el = dl + dl = rotl(cl, 10) + cl = bl + bl = t - var jyd8 = jy2.redSqr(); - jyd8 = jyd8.redIAdd(jyd8); - jyd8 = jyd8.redIAdd(jyd8); - jyd8 = jyd8.redIAdd(jyd8); - var ny = c.redMul(t2).redISub(jyd8); - var nz = jy.redAdd(jy).redMul(jz); + t = (ar + M[offset + zr[i]]) | 0 + if (i < 16) { + t += f5(br, cr, dr) + hr[0] + } else if (i < 32) { + t += f4(br, cr, dr) + hr[1] + } else if (i < 48) { + t += f3(br, cr, dr) + hr[2] + } else if (i < 64) { + t += f2(br, cr, dr) + hr[3] + } else {// if (i<80) { + t += f1(br, cr, dr) + hr[4] + } - return this.curve.jpoint(nx, ny, nz); -}; + t = t | 0 + t = rotl(t, sr[i]) + t = (t + er) | 0 + ar = er + er = dr + dr = rotl(cr, 10) + cr = br + br = t + } -JPoint.prototype.trpl = function trpl() { - if (!this.curve.zeroA) - return this.dbl().add(this); + // intermediate hash value + t = (H[1] + cl + dr) | 0 + H[1] = (H[2] + dl + er) | 0 + H[2] = (H[3] + el + ar) | 0 + H[3] = (H[4] + al + br) | 0 + H[4] = (H[0] + bl + cr) | 0 + H[0] = t +} - // http://hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-0.html#tripling-tpl-2007-bl - // 5M + 10S + ... +function f1 (x, y, z) { + return ((x) ^ (y) ^ (z)) +} - // XX = X1^2 - var xx = this.x.redSqr(); - // YY = Y1^2 - var yy = this.y.redSqr(); - // ZZ = Z1^2 - var zz = this.z.redSqr(); - // YYYY = YY^2 - var yyyy = yy.redSqr(); - // M = 3 * XX + a * ZZ2; a = 0 - var m = xx.redAdd(xx).redIAdd(xx); - // MM = M^2 - var mm = m.redSqr(); - // E = 6 * ((X1 + YY)^2 - XX - YYYY) - MM - var e = this.x.redAdd(yy).redSqr().redISub(xx).redISub(yyyy); - e = e.redIAdd(e); - e = e.redAdd(e).redIAdd(e); - e = e.redISub(mm); - // EE = E^2 - var ee = e.redSqr(); - // T = 16*YYYY - var t = yyyy.redIAdd(yyyy); - t = t.redIAdd(t); - t = t.redIAdd(t); - t = t.redIAdd(t); - // U = (M + E)^2 - MM - EE - T - var u = m.redIAdd(e).redSqr().redISub(mm).redISub(ee).redISub(t); - // X3 = 4 * (X1 * EE - 4 * YY * U) - var yyu4 = yy.redMul(u); - yyu4 = yyu4.redIAdd(yyu4); - yyu4 = yyu4.redIAdd(yyu4); - var nx = this.x.redMul(ee).redISub(yyu4); - nx = nx.redIAdd(nx); - nx = nx.redIAdd(nx); - // Y3 = 8 * Y1 * (U * (T - U) - E * EE) - var ny = this.y.redMul(u.redMul(t.redISub(u)).redISub(e.redMul(ee))); - ny = ny.redIAdd(ny); - ny = ny.redIAdd(ny); - ny = ny.redIAdd(ny); - // Z3 = (Z1 + E)^2 - ZZ - EE - var nz = this.z.redAdd(e).redSqr().redISub(zz).redISub(ee); +function f2 (x, y, z) { + return (((x) & (y)) | ((~x) & (z))) +} - return this.curve.jpoint(nx, ny, nz); -}; +function f3 (x, y, z) { + return (((x) | (~(y))) ^ (z)) +} -JPoint.prototype.mul = function mul(k, kbase) { - k = new bn(k, kbase); +function f4 (x, y, z) { + return (((x) & (z)) | ((y) & (~(z)))) +} - return this.curve._wnafMul(this, k); -}; +function f5 (x, y, z) { + return ((x) ^ ((y) | (~(z)))) +} -JPoint.prototype.eq = function eq(p) { - if (p.type === 'affine') - return this.eq(p.toJ()); +function rotl (x, n) { + return (x << n) | (x >>> (32 - n)) +} - if (this === p) - return true; +function ripemd160 (message) { + var H = [0x67452301, 0xEFCDAB89, 0x98BADCFE, 0x10325476, 0xC3D2E1F0] - // x1 * z2^2 == x2 * z1^2 - var z2 = this.z.redSqr(); - var pz2 = p.z.redSqr(); - if (this.x.redMul(pz2).redISub(p.x.redMul(z2)).cmpn(0) !== 0) - return false; + if (typeof message === 'string') { + message = new Buffer(message, 'utf8') + } - // y1 * z2^3 == y2 * z1^3 - var z3 = z2.redMul(this.z); - var pz3 = pz2.redMul(p.z); - return this.y.redMul(pz3).redISub(p.y.redMul(z3)).cmpn(0) === 0; -}; + var m = bytesToWords(message) -JPoint.prototype.inspect = function inspect() { - if (this.isInfinity()) - return ''; - return ''; -}; + var nBitsLeft = message.length * 8 + var nBitsTotal = message.length * 8 -JPoint.prototype.isInfinity = function isInfinity() { - // XXX This code assumes that zero is always zero in red - return this.z.cmpn(0) === 0; -}; + // Add padding + m[nBitsLeft >>> 5] |= 0x80 << (24 - nBitsLeft % 32) + m[(((nBitsLeft + 64) >>> 9) << 4) + 14] = ( + (((nBitsTotal << 8) | (nBitsTotal >>> 24)) & 0x00ff00ff) | + (((nBitsTotal << 24) | (nBitsTotal >>> 8)) & 0xff00ff00) + ) -},{"../../elliptic":69,"../curve":72,"bn.js":67,"inherits":229}],75:[function(require,module,exports){ -var curves = exports; + for (var i = 0; i < m.length; i += 16) { + processBlock(H, m, i) + } -var hash = require('hash.js'); -var bn = require('bn.js'); -var elliptic = require('../elliptic'); + // swap endian + for (i = 0; i < 5; i++) { + // shortcut + var H_i = H[i] -var assert = elliptic.utils.assert; + // Swap + H[i] = (((H_i << 8) | (H_i >>> 24)) & 0x00ff00ff) | + (((H_i << 24) | (H_i >>> 8)) & 0xff00ff00) + } -function PresetCurve(options) { - if (options.type === 'short') - this.curve = new elliptic.curve.short(options); - else if (options.type === 'edwards') - this.curve = new elliptic.curve.edwards(options); - else - this.curve = new elliptic.curve.mont(options); - this.g = this.curve.g; - this.n = this.curve.n; - this.hash = options.hash; + var digestbytes = wordsToBytes(H) + return new Buffer(digestbytes) +} - assert(this.g.validate(), 'Invalid curve'); - assert(this.g.mul(this.n).isInfinity(), 'Invalid curve, G*N != O'); +module.exports = ripemd160 + +}).call(this,require("buffer").Buffer) +},{"buffer":47}],130:[function(require,module,exports){ +(function (Buffer){ +// prototype class for hash functions +function Hash (blockSize, finalSize) { + this._block = new Buffer(blockSize) + this._finalSize = finalSize + this._blockSize = blockSize + this._len = 0 + this._s = 0 } -curves.PresetCurve = PresetCurve; -function defineCurve(name, options) { - Object.defineProperty(curves, name, { - configurable: true, - enumerable: true, - get: function() { - var curve = new PresetCurve(options); - Object.defineProperty(curves, name, { - configurable: true, - enumerable: true, - value: curve - }); - return curve; +Hash.prototype.update = function (data, enc) { + if (typeof data === 'string') { + enc = enc || 'utf8' + data = new Buffer(data, enc) + } + + var l = this._len += data.length + var s = this._s || 0 + var f = 0 + var buffer = this._block + + while (s < l) { + var t = Math.min(data.length, f + this._blockSize - (s % this._blockSize)) + var ch = (t - f) + + for (var i = 0; i < ch; i++) { + buffer[(s % this._blockSize) + i] = data[i + f] } - }); + + s += ch + f += ch + + if ((s % this._blockSize) === 0) { + this._update(buffer) + } + } + this._s = s + + return this } -defineCurve('p192', { - type: 'short', - prime: 'p192', - p: 'ffffffff ffffffff ffffffff fffffffe ffffffff ffffffff', - a: 'ffffffff ffffffff ffffffff fffffffe ffffffff fffffffc', - b: '64210519 e59c80e7 0fa7e9ab 72243049 feb8deec c146b9b1', - n: 'ffffffff ffffffff ffffffff 99def836 146bc9b1 b4d22831', - hash: hash.sha256, - gRed: false, - g: [ - '188da80e b03090f6 7cbf20eb 43a18800 f4ff0afd 82ff1012', - '07192b95 ffc8da78 631011ed 6b24cdd5 73f977a1 1e794811' - ], -}); +Hash.prototype.digest = function (enc) { + // Suppose the length of the message M, in bits, is l + var l = this._len * 8 -defineCurve('p224', { - type: 'short', - prime: 'p224', - p: 'ffffffff ffffffff ffffffff ffffffff 00000000 00000000 00000001', - a: 'ffffffff ffffffff ffffffff fffffffe ffffffff ffffffff fffffffe', - b: 'b4050a85 0c04b3ab f5413256 5044b0b7 d7bfd8ba 270b3943 2355ffb4', - n: 'ffffffff ffffffff ffffffff ffff16a2 e0b8f03e 13dd2945 5c5c2a3d', - hash: hash.sha256, - gRed: false, - g: [ - 'b70e0cbd 6bb4bf7f 321390b9 4a03c1d3 56c21122 343280d6 115c1d21', - 'bd376388 b5f723fb 4c22dfe6 cd4375a0 5a074764 44d58199 85007e34' - ], -}); + // Append the bit 1 to the end of the message + this._block[this._len % this._blockSize] = 0x80 -defineCurve('p256', { - type: 'short', - prime: null, - p: 'ffffffff 00000001 00000000 00000000 00000000 ffffffff ffffffff ffffffff', - a: 'ffffffff 00000001 00000000 00000000 00000000 ffffffff ffffffff fffffffc', - b: '5ac635d8 aa3a93e7 b3ebbd55 769886bc 651d06b0 cc53b0f6 3bce3c3e 27d2604b', - n: 'ffffffff 00000000 ffffffff ffffffff bce6faad a7179e84 f3b9cac2 fc632551', - hash: hash.sha256, - gRed: false, - g: [ - '6b17d1f2 e12c4247 f8bce6e5 63a440f2 77037d81 2deb33a0 f4a13945 d898c296', - '4fe342e2 fe1a7f9b 8ee7eb4a 7c0f9e16 2bce3357 6b315ece cbb64068 37bf51f5' - ], -}); + // and then k zero bits, where k is the smallest non-negative solution to the equation (l + 1 + k) === finalSize mod blockSize + this._block.fill(0, this._len % this._blockSize + 1) -defineCurve('curve25519', { - type: 'mont', - prime: 'p25519', - p: '7fffffffffffffff ffffffffffffffff ffffffffffffffff ffffffffffffffed', - a: '76d06', - b: '0', - n: '1000000000000000 0000000000000000 14def9dea2f79cd6 5812631a5cf5d3ed', - hash: hash.sha256, - gRed: false, - g: [ - '9' - ] -}); + if (l % (this._blockSize * 8) >= this._finalSize * 8) { + this._update(this._block) + this._block.fill(0) + } -defineCurve('ed25519', { - type: 'edwards', - prime: 'p25519', - p: '7fffffffffffffff ffffffffffffffff ffffffffffffffff ffffffffffffffed', - a: '-1', - c: '1', - // -121665 * (121666^(-1)) (mod P) - d: '52036cee2b6ffe73 8cc740797779e898 00700a4d4141d8ab 75eb4dca135978a3', - n: '1000000000000000 0000000000000000 14def9dea2f79cd6 5812631a5cf5d3ed', - hash: hash.sha256, - gRed: false, - g: [ - '216936d3cd6e53fec0a4e231fdd6dc5c692cc7609525a7b2c9562d608f25d51a', + // to this append the block which is equal to the number l written in binary + // TODO: handle case where l is > Math.pow(2, 29) + this._block.writeInt32BE(l, this._blockSize - 4) - // 4/5 - '6666666666666666666666666666666666666666666666666666666666666658' - ] -}); + var hash = this._update(this._block) || this._hash() -defineCurve('secp256k1', { - type: 'short', - prime: 'k256', - p: 'ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff fffffffe fffffc2f', - a: '0', - b: '7', - n: 'ffffffff ffffffff ffffffff fffffffe baaedce6 af48a03b bfd25e8c d0364141', - h: '1', - hash: hash.sha256, + return enc ? hash.toString(enc) : hash +} - // Precomputed endomorphism - beta: '7ae96a2b657c07106e64479eac3434e99cf0497512f58995c1396c28719501ee', - lambda: '5363ad4cc05c30e0a5261c028812645a122e22ea20816678df02967c1b23bd72', - basis: [ - { - a: '3086d221a7d46bcde86c90e49284eb15', - b: '-e4437ed6010e88286f547fa90abfe4c3' - }, - { - a: '114ca50f7a8e2f3f657c1108d9d44cfd8', - b: '3086d221a7d46bcde86c90e49284eb15' - } - ], +Hash.prototype._update = function () { + throw new Error('_update must be implemented by subclass') +} - gRed: false, - g: [ - '79be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798', - '483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8', - { - 'doubles': { - 'step': 4, - 'points': [ - [ - 'e60fce93b59e9ec53011aabc21c23e97b2a31369b87a5ae9c44ee89e2a6dec0a', - 'f7e3507399e595929db99f34f57937101296891e44d23f0be1f32cce69616821' - ], - [ - '8282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508', - '11f8a8098557dfe45e8256e830b60ace62d613ac2f7b17bed31b6eaff6e26caf' - ], - [ - '175e159f728b865a72f99cc6c6fc846de0b93833fd2222ed73fce5b551e5b739', - 'd3506e0d9e3c79eba4ef97a51ff71f5eacb5955add24345c6efa6ffee9fed695' - ], - [ - '363d90d447b00c9c99ceac05b6262ee053441c7e55552ffe526bad8f83ff4640', - '4e273adfc732221953b445397f3363145b9a89008199ecb62003c7f3bee9de9' - ], - [ - '8b4b5f165df3c2be8c6244b5b745638843e4a781a15bcd1b69f79a55dffdf80c', - '4aad0a6f68d308b4b3fbd7813ab0da04f9e336546162ee56b3eff0c65fd4fd36' - ], - [ - '723cbaa6e5db996d6bf771c00bd548c7b700dbffa6c0e77bcb6115925232fcda', - '96e867b5595cc498a921137488824d6e2660a0653779494801dc069d9eb39f5f' - ], - [ - 'eebfa4d493bebf98ba5feec812c2d3b50947961237a919839a533eca0e7dd7fa', - '5d9a8ca3970ef0f269ee7edaf178089d9ae4cdc3a711f712ddfd4fdae1de8999' - ], - [ - '100f44da696e71672791d0a09b7bde459f1215a29b3c03bfefd7835b39a48db0', - 'cdd9e13192a00b772ec8f3300c090666b7ff4a18ff5195ac0fbd5cd62bc65a09' - ], - [ - 'e1031be262c7ed1b1dc9227a4a04c017a77f8d4464f3b3852c8acde6e534fd2d', - '9d7061928940405e6bb6a4176597535af292dd419e1ced79a44f18f29456a00d' - ], - [ - 'feea6cae46d55b530ac2839f143bd7ec5cf8b266a41d6af52d5e688d9094696d', - 'e57c6b6c97dce1bab06e4e12bf3ecd5c981c8957cc41442d3155debf18090088' - ], - [ - 'da67a91d91049cdcb367be4be6ffca3cfeed657d808583de33fa978bc1ec6cb1', - '9bacaa35481642bc41f463f7ec9780e5dec7adc508f740a17e9ea8e27a68be1d' - ], - [ - '53904faa0b334cdda6e000935ef22151ec08d0f7bb11069f57545ccc1a37b7c0', - '5bc087d0bc80106d88c9eccac20d3c1c13999981e14434699dcb096b022771c8' - ], - [ - '8e7bcd0bd35983a7719cca7764ca906779b53a043a9b8bcaeff959f43ad86047', - '10b7770b2a3da4b3940310420ca9514579e88e2e47fd68b3ea10047e8460372a' - ], - [ - '385eed34c1cdff21e6d0818689b81bde71a7f4f18397e6690a841e1599c43862', - '283bebc3e8ea23f56701de19e9ebf4576b304eec2086dc8cc0458fe5542e5453' - ], - [ - '6f9d9b803ecf191637c73a4413dfa180fddf84a5947fbc9c606ed86c3fac3a7', - '7c80c68e603059ba69b8e2a30e45c4d47ea4dd2f5c281002d86890603a842160' - ], - [ - '3322d401243c4e2582a2147c104d6ecbf774d163db0f5e5313b7e0e742d0e6bd', - '56e70797e9664ef5bfb019bc4ddaf9b72805f63ea2873af624f3a2e96c28b2a0' - ], - [ - '85672c7d2de0b7da2bd1770d89665868741b3f9af7643397721d74d28134ab83', - '7c481b9b5b43b2eb6374049bfa62c2e5e77f17fcc5298f44c8e3094f790313a6' - ], - [ - '948bf809b1988a46b06c9f1919413b10f9226c60f668832ffd959af60c82a0a', - '53a562856dcb6646dc6b74c5d1c3418c6d4dff08c97cd2bed4cb7f88d8c8e589' - ], - [ - '6260ce7f461801c34f067ce0f02873a8f1b0e44dfc69752accecd819f38fd8e8', - 'bc2da82b6fa5b571a7f09049776a1ef7ecd292238051c198c1a84e95b2b4ae17' - ], - [ - 'e5037de0afc1d8d43d8348414bbf4103043ec8f575bfdc432953cc8d2037fa2d', - '4571534baa94d3b5f9f98d09fb990bddbd5f5b03ec481f10e0e5dc841d755bda' - ], - [ - 'e06372b0f4a207adf5ea905e8f1771b4e7e8dbd1c6a6c5b725866a0ae4fce725', - '7a908974bce18cfe12a27bb2ad5a488cd7484a7787104870b27034f94eee31dd' - ], - [ - '213c7a715cd5d45358d0bbf9dc0ce02204b10bdde2a3f58540ad6908d0559754', - '4b6dad0b5ae462507013ad06245ba190bb4850f5f36a7eeddff2c27534b458f2' - ], - [ - '4e7c272a7af4b34e8dbb9352a5419a87e2838c70adc62cddf0cc3a3b08fbd53c', - '17749c766c9d0b18e16fd09f6def681b530b9614bff7dd33e0b3941817dcaae6' - ], - [ - 'fea74e3dbe778b1b10f238ad61686aa5c76e3db2be43057632427e2840fb27b6', - '6e0568db9b0b13297cf674deccb6af93126b596b973f7b77701d3db7f23cb96f' - ], - [ - '76e64113f677cf0e10a2570d599968d31544e179b760432952c02a4417bdde39', - 'c90ddf8dee4e95cf577066d70681f0d35e2a33d2b56d2032b4b1752d1901ac01' - ], - [ - 'c738c56b03b2abe1e8281baa743f8f9a8f7cc643df26cbee3ab150242bcbb891', - '893fb578951ad2537f718f2eacbfbbbb82314eef7880cfe917e735d9699a84c3' - ], - [ - 'd895626548b65b81e264c7637c972877d1d72e5f3a925014372e9f6588f6c14b', - 'febfaa38f2bc7eae728ec60818c340eb03428d632bb067e179363ed75d7d991f' - ], - [ - 'b8da94032a957518eb0f6433571e8761ceffc73693e84edd49150a564f676e03', - '2804dfa44805a1e4d7c99cc9762808b092cc584d95ff3b511488e4e74efdf6e7' - ], - [ - 'e80fea14441fb33a7d8adab9475d7fab2019effb5156a792f1a11778e3c0df5d', - 'eed1de7f638e00771e89768ca3ca94472d155e80af322ea9fcb4291b6ac9ec78' - ], - [ - 'a301697bdfcd704313ba48e51d567543f2a182031efd6915ddc07bbcc4e16070', - '7370f91cfb67e4f5081809fa25d40f9b1735dbf7c0a11a130c0d1a041e177ea1' - ], - [ - '90ad85b389d6b936463f9d0512678de208cc330b11307fffab7ac63e3fb04ed4', - 'e507a3620a38261affdcbd9427222b839aefabe1582894d991d4d48cb6ef150' - ], - [ - '8f68b9d2f63b5f339239c1ad981f162ee88c5678723ea3351b7b444c9ec4c0da', - '662a9f2dba063986de1d90c2b6be215dbbea2cfe95510bfdf23cbf79501fff82' - ], - [ - 'e4f3fb0176af85d65ff99ff9198c36091f48e86503681e3e6686fd5053231e11', - '1e63633ad0ef4f1c1661a6d0ea02b7286cc7e74ec951d1c9822c38576feb73bc' - ], - [ - '8c00fa9b18ebf331eb961537a45a4266c7034f2f0d4e1d0716fb6eae20eae29e', - 'efa47267fea521a1a9dc343a3736c974c2fadafa81e36c54e7d2a4c66702414b' - ], - [ - 'e7a26ce69dd4829f3e10cec0a9e98ed3143d084f308b92c0997fddfc60cb3e41', - '2a758e300fa7984b471b006a1aafbb18d0a6b2c0420e83e20e8a9421cf2cfd51' - ], - [ - 'b6459e0ee3662ec8d23540c223bcbdc571cbcb967d79424f3cf29eb3de6b80ef', - '67c876d06f3e06de1dadf16e5661db3c4b3ae6d48e35b2ff30bf0b61a71ba45' - ], - [ - 'd68a80c8280bb840793234aa118f06231d6f1fc67e73c5a5deda0f5b496943e8', - 'db8ba9fff4b586d00c4b1f9177b0e28b5b0e7b8f7845295a294c84266b133120' - ], - [ - '324aed7df65c804252dc0270907a30b09612aeb973449cea4095980fc28d3d5d', - '648a365774b61f2ff130c0c35aec1f4f19213b0c7e332843967224af96ab7c84' - ], - [ - '4df9c14919cde61f6d51dfdbe5fee5dceec4143ba8d1ca888e8bd373fd054c96', - '35ec51092d8728050974c23a1d85d4b5d506cdc288490192ebac06cad10d5d' - ], - [ - '9c3919a84a474870faed8a9c1cc66021523489054d7f0308cbfc99c8ac1f98cd', - 'ddb84f0f4a4ddd57584f044bf260e641905326f76c64c8e6be7e5e03d4fc599d' - ], - [ - '6057170b1dd12fdf8de05f281d8e06bb91e1493a8b91d4cc5a21382120a959e5', - '9a1af0b26a6a4807add9a2daf71df262465152bc3ee24c65e899be932385a2a8' - ], - [ - 'a576df8e23a08411421439a4518da31880cef0fba7d4df12b1a6973eecb94266', - '40a6bf20e76640b2c92b97afe58cd82c432e10a7f514d9f3ee8be11ae1b28ec8' - ], - [ - '7778a78c28dec3e30a05fe9629de8c38bb30d1f5cf9a3a208f763889be58ad71', - '34626d9ab5a5b22ff7098e12f2ff580087b38411ff24ac563b513fc1fd9f43ac' - ], - [ - '928955ee637a84463729fd30e7afd2ed5f96274e5ad7e5cb09eda9c06d903ac', - 'c25621003d3f42a827b78a13093a95eeac3d26efa8a8d83fc5180e935bcd091f' - ], - [ - '85d0fef3ec6db109399064f3a0e3b2855645b4a907ad354527aae75163d82751', - '1f03648413a38c0be29d496e582cf5663e8751e96877331582c237a24eb1f962' - ], - [ - 'ff2b0dce97eece97c1c9b6041798b85dfdfb6d8882da20308f5404824526087e', - '493d13fef524ba188af4c4dc54d07936c7b7ed6fb90e2ceb2c951e01f0c29907' - ], - [ - '827fbbe4b1e880ea9ed2b2e6301b212b57f1ee148cd6dd28780e5e2cf856e241', - 'c60f9c923c727b0b71bef2c67d1d12687ff7a63186903166d605b68baec293ec' - ], - [ - 'eaa649f21f51bdbae7be4ae34ce6e5217a58fdce7f47f9aa7f3b58fa2120e2b3', - 'be3279ed5bbbb03ac69a80f89879aa5a01a6b965f13f7e59d47a5305ba5ad93d' - ], - [ - 'e4a42d43c5cf169d9391df6decf42ee541b6d8f0c9a137401e23632dda34d24f', - '4d9f92e716d1c73526fc99ccfb8ad34ce886eedfa8d8e4f13a7f7131deba9414' - ], - [ - '1ec80fef360cbdd954160fadab352b6b92b53576a88fea4947173b9d4300bf19', - 'aeefe93756b5340d2f3a4958a7abbf5e0146e77f6295a07b671cdc1cc107cefd' - ], - [ - '146a778c04670c2f91b00af4680dfa8bce3490717d58ba889ddb5928366642be', - 'b318e0ec3354028add669827f9d4b2870aaa971d2f7e5ed1d0b297483d83efd0' - ], - [ - 'fa50c0f61d22e5f07e3acebb1aa07b128d0012209a28b9776d76a8793180eef9', - '6b84c6922397eba9b72cd2872281a68a5e683293a57a213b38cd8d7d3f4f2811' - ], - [ - 'da1d61d0ca721a11b1a5bf6b7d88e8421a288ab5d5bba5220e53d32b5f067ec2', - '8157f55a7c99306c79c0766161c91e2966a73899d279b48a655fba0f1ad836f1' - ], - [ - 'a8e282ff0c9706907215ff98e8fd416615311de0446f1e062a73b0610d064e13', - '7f97355b8db81c09abfb7f3c5b2515888b679a3e50dd6bd6cef7c73111f4cc0c' - ], - [ - '174a53b9c9a285872d39e56e6913cab15d59b1fa512508c022f382de8319497c', - 'ccc9dc37abfc9c1657b4155f2c47f9e6646b3a1d8cb9854383da13ac079afa73' - ], - [ - '959396981943785c3d3e57edf5018cdbe039e730e4918b3d884fdff09475b7ba', - '2e7e552888c331dd8ba0386a4b9cd6849c653f64c8709385e9b8abf87524f2fd' - ], - [ - 'd2a63a50ae401e56d645a1153b109a8fcca0a43d561fba2dbb51340c9d82b151', - 'e82d86fb6443fcb7565aee58b2948220a70f750af484ca52d4142174dcf89405' - ], - [ - '64587e2335471eb890ee7896d7cfdc866bacbdbd3839317b3436f9b45617e073', - 'd99fcdd5bf6902e2ae96dd6447c299a185b90a39133aeab358299e5e9faf6589' - ], - [ - '8481bde0e4e4d885b3a546d3e549de042f0aa6cea250e7fd358d6c86dd45e458', - '38ee7b8cba5404dd84a25bf39cecb2ca900a79c42b262e556d64b1b59779057e' - ], - [ - '13464a57a78102aa62b6979ae817f4637ffcfed3c4b1ce30bcd6303f6caf666b', - '69be159004614580ef7e433453ccb0ca48f300a81d0942e13f495a907f6ecc27' - ], - [ - 'bc4a9df5b713fe2e9aef430bcc1dc97a0cd9ccede2f28588cada3a0d2d83f366', - 'd3a81ca6e785c06383937adf4b798caa6e8a9fbfa547b16d758d666581f33c1' - ], - [ - '8c28a97bf8298bc0d23d8c749452a32e694b65e30a9472a3954ab30fe5324caa', - '40a30463a3305193378fedf31f7cc0eb7ae784f0451cb9459e71dc73cbef9482' - ], - [ - '8ea9666139527a8c1dd94ce4f071fd23c8b350c5a4bb33748c4ba111faccae0', - '620efabbc8ee2782e24e7c0cfb95c5d735b783be9cf0f8e955af34a30e62b945' - ], - [ - 'dd3625faef5ba06074669716bbd3788d89bdde815959968092f76cc4eb9a9787', - '7a188fa3520e30d461da2501045731ca941461982883395937f68d00c644a573' - ], - [ - 'f710d79d9eb962297e4f6232b40e8f7feb2bc63814614d692c12de752408221e', - 'ea98e67232d3b3295d3b535532115ccac8612c721851617526ae47a9c77bfc82' - ] - ] - }, - 'naf': { - 'wnd': 7, - 'points': [ - [ - 'f9308a019258c31049344f85f89d5229b531c845836f99b08601f113bce036f9', - '388f7b0f632de8140fe337e62a37f3566500a99934c2231b6cb9fd7584b8e672' - ], - [ - '2f8bde4d1a07209355b4a7250a5c5128e88b84bddc619ab7cba8d569b240efe4', - 'd8ac222636e5e3d6d4dba9dda6c9c426f788271bab0d6840dca87d3aa6ac62d6' - ], - [ - '5cbdf0646e5db4eaa398f365f2ea7a0e3d419b7e0330e39ce92bddedcac4f9bc', - '6aebca40ba255960a3178d6d861a54dba813d0b813fde7b5a5082628087264da' - ], - [ - 'acd484e2f0c7f65309ad178a9f559abde09796974c57e714c35f110dfc27ccbe', - 'cc338921b0a7d9fd64380971763b61e9add888a4375f8e0f05cc262ac64f9c37' - ], - [ - '774ae7f858a9411e5ef4246b70c65aac5649980be5c17891bbec17895da008cb', - 'd984a032eb6b5e190243dd56d7b7b365372db1e2dff9d6a8301d74c9c953c61b' - ], - [ - 'f28773c2d975288bc7d1d205c3748651b075fbc6610e58cddeeddf8f19405aa8', - 'ab0902e8d880a89758212eb65cdaf473a1a06da521fa91f29b5cb52db03ed81' - ], - [ - 'd7924d4f7d43ea965a465ae3095ff41131e5946f3c85f79e44adbcf8e27e080e', - '581e2872a86c72a683842ec228cc6defea40af2bd896d3a5c504dc9ff6a26b58' - ], - [ - 'defdea4cdb677750a420fee807eacf21eb9898ae79b9768766e4faa04a2d4a34', - '4211ab0694635168e997b0ead2a93daeced1f4a04a95c0f6cfb199f69e56eb77' - ], - [ - '2b4ea0a797a443d293ef5cff444f4979f06acfebd7e86d277475656138385b6c', - '85e89bc037945d93b343083b5a1c86131a01f60c50269763b570c854e5c09b7a' - ], - [ - '352bbf4a4cdd12564f93fa332ce333301d9ad40271f8107181340aef25be59d5', - '321eb4075348f534d59c18259dda3e1f4a1b3b2e71b1039c67bd3d8bcf81998c' - ], - [ - '2fa2104d6b38d11b0230010559879124e42ab8dfeff5ff29dc9cdadd4ecacc3f', - '2de1068295dd865b64569335bd5dd80181d70ecfc882648423ba76b532b7d67' - ], - [ - '9248279b09b4d68dab21a9b066edda83263c3d84e09572e269ca0cd7f5453714', - '73016f7bf234aade5d1aa71bdea2b1ff3fc0de2a887912ffe54a32ce97cb3402' - ], - [ - 'daed4f2be3a8bf278e70132fb0beb7522f570e144bf615c07e996d443dee8729', - 'a69dce4a7d6c98e8d4a1aca87ef8d7003f83c230f3afa726ab40e52290be1c55' - ], - [ - 'c44d12c7065d812e8acf28d7cbb19f9011ecd9e9fdf281b0e6a3b5e87d22e7db', - '2119a460ce326cdc76c45926c982fdac0e106e861edf61c5a039063f0e0e6482' - ], - [ - '6a245bf6dc698504c89a20cfded60853152b695336c28063b61c65cbd269e6b4', - 'e022cf42c2bd4a708b3f5126f16a24ad8b33ba48d0423b6efd5e6348100d8a82' - ], - [ - '1697ffa6fd9de627c077e3d2fe541084ce13300b0bec1146f95ae57f0d0bd6a5', - 'b9c398f186806f5d27561506e4557433a2cf15009e498ae7adee9d63d01b2396' - ], - [ - '605bdb019981718b986d0f07e834cb0d9deb8360ffb7f61df982345ef27a7479', - '2972d2de4f8d20681a78d93ec96fe23c26bfae84fb14db43b01e1e9056b8c49' - ], - [ - '62d14dab4150bf497402fdc45a215e10dcb01c354959b10cfe31c7e9d87ff33d', - '80fc06bd8cc5b01098088a1950eed0db01aa132967ab472235f5642483b25eaf' - ], - [ - '80c60ad0040f27dade5b4b06c408e56b2c50e9f56b9b8b425e555c2f86308b6f', - '1c38303f1cc5c30f26e66bad7fe72f70a65eed4cbe7024eb1aa01f56430bd57a' - ], - [ - '7a9375ad6167ad54aa74c6348cc54d344cc5dc9487d847049d5eabb0fa03c8fb', - 'd0e3fa9eca8726909559e0d79269046bdc59ea10c70ce2b02d499ec224dc7f7' - ], - [ - 'd528ecd9b696b54c907a9ed045447a79bb408ec39b68df504bb51f459bc3ffc9', - 'eecf41253136e5f99966f21881fd656ebc4345405c520dbc063465b521409933' - ], - [ - '49370a4b5f43412ea25f514e8ecdad05266115e4a7ecb1387231808f8b45963', - '758f3f41afd6ed428b3081b0512fd62a54c3f3afbb5b6764b653052a12949c9a' - ], - [ - '77f230936ee88cbbd73df930d64702ef881d811e0e1498e2f1c13eb1fc345d74', - '958ef42a7886b6400a08266e9ba1b37896c95330d97077cbbe8eb3c7671c60d6' - ], - [ - 'f2dac991cc4ce4b9ea44887e5c7c0bce58c80074ab9d4dbaeb28531b7739f530', - 'e0dedc9b3b2f8dad4da1f32dec2531df9eb5fbeb0598e4fd1a117dba703a3c37' - ], - [ - '463b3d9f662621fb1b4be8fbbe2520125a216cdfc9dae3debcba4850c690d45b', - '5ed430d78c296c3543114306dd8622d7c622e27c970a1de31cb377b01af7307e' - ], - [ - 'f16f804244e46e2a09232d4aff3b59976b98fac14328a2d1a32496b49998f247', - 'cedabd9b82203f7e13d206fcdf4e33d92a6c53c26e5cce26d6579962c4e31df6' - ], - [ - 'caf754272dc84563b0352b7a14311af55d245315ace27c65369e15f7151d41d1', - 'cb474660ef35f5f2a41b643fa5e460575f4fa9b7962232a5c32f908318a04476' - ], - [ - '2600ca4b282cb986f85d0f1709979d8b44a09c07cb86d7c124497bc86f082120', - '4119b88753c15bd6a693b03fcddbb45d5ac6be74ab5f0ef44b0be9475a7e4b40' - ], - [ - '7635ca72d7e8432c338ec53cd12220bc01c48685e24f7dc8c602a7746998e435', - '91b649609489d613d1d5e590f78e6d74ecfc061d57048bad9e76f302c5b9c61' - ], - [ - '754e3239f325570cdbbf4a87deee8a66b7f2b33479d468fbc1a50743bf56cc18', - '673fb86e5bda30fb3cd0ed304ea49a023ee33d0197a695d0c5d98093c536683' - ], - [ - 'e3e6bd1071a1e96aff57859c82d570f0330800661d1c952f9fe2694691d9b9e8', - '59c9e0bba394e76f40c0aa58379a3cb6a5a2283993e90c4167002af4920e37f5' - ], - [ - '186b483d056a033826ae73d88f732985c4ccb1f32ba35f4b4cc47fdcf04aa6eb', - '3b952d32c67cf77e2e17446e204180ab21fb8090895138b4a4a797f86e80888b' - ], - [ - 'df9d70a6b9876ce544c98561f4be4f725442e6d2b737d9c91a8321724ce0963f', - '55eb2dafd84d6ccd5f862b785dc39d4ab157222720ef9da217b8c45cf2ba2417' - ], - [ - '5edd5cc23c51e87a497ca815d5dce0f8ab52554f849ed8995de64c5f34ce7143', - 'efae9c8dbc14130661e8cec030c89ad0c13c66c0d17a2905cdc706ab7399a868' - ], - [ - '290798c2b6476830da12fe02287e9e777aa3fba1c355b17a722d362f84614fba', - 'e38da76dcd440621988d00bcf79af25d5b29c094db2a23146d003afd41943e7a' - ], - [ - 'af3c423a95d9f5b3054754efa150ac39cd29552fe360257362dfdecef4053b45', - 'f98a3fd831eb2b749a93b0e6f35cfb40c8cd5aa667a15581bc2feded498fd9c6' - ], - [ - '766dbb24d134e745cccaa28c99bf274906bb66b26dcf98df8d2fed50d884249a', - '744b1152eacbe5e38dcc887980da38b897584a65fa06cedd2c924f97cbac5996' - ], - [ - '59dbf46f8c94759ba21277c33784f41645f7b44f6c596a58ce92e666191abe3e', - 'c534ad44175fbc300f4ea6ce648309a042ce739a7919798cd85e216c4a307f6e' - ], - [ - 'f13ada95103c4537305e691e74e9a4a8dd647e711a95e73cb62dc6018cfd87b8', - 'e13817b44ee14de663bf4bc808341f326949e21a6a75c2570778419bdaf5733d' - ], - [ - '7754b4fa0e8aced06d4167a2c59cca4cda1869c06ebadfb6488550015a88522c', - '30e93e864e669d82224b967c3020b8fa8d1e4e350b6cbcc537a48b57841163a2' - ], - [ - '948dcadf5990e048aa3874d46abef9d701858f95de8041d2a6828c99e2262519', - 'e491a42537f6e597d5d28a3224b1bc25df9154efbd2ef1d2cbba2cae5347d57e' - ], - [ - '7962414450c76c1689c7b48f8202ec37fb224cf5ac0bfa1570328a8a3d7c77ab', - '100b610ec4ffb4760d5c1fc133ef6f6b12507a051f04ac5760afa5b29db83437' - ], - [ - '3514087834964b54b15b160644d915485a16977225b8847bb0dd085137ec47ca', - 'ef0afbb2056205448e1652c48e8127fc6039e77c15c2378b7e7d15a0de293311' - ], - [ - 'd3cc30ad6b483e4bc79ce2c9dd8bc54993e947eb8df787b442943d3f7b527eaf', - '8b378a22d827278d89c5e9be8f9508ae3c2ad46290358630afb34db04eede0a4' - ], - [ - '1624d84780732860ce1c78fcbfefe08b2b29823db913f6493975ba0ff4847610', - '68651cf9b6da903e0914448c6cd9d4ca896878f5282be4c8cc06e2a404078575' - ], - [ - '733ce80da955a8a26902c95633e62a985192474b5af207da6df7b4fd5fc61cd4', - 'f5435a2bd2badf7d485a4d8b8db9fcce3e1ef8e0201e4578c54673bc1dc5ea1d' - ], - [ - '15d9441254945064cf1a1c33bbd3b49f8966c5092171e699ef258dfab81c045c', - 'd56eb30b69463e7234f5137b73b84177434800bacebfc685fc37bbe9efe4070d' - ], - [ - 'a1d0fcf2ec9de675b612136e5ce70d271c21417c9d2b8aaaac138599d0717940', - 'edd77f50bcb5a3cab2e90737309667f2641462a54070f3d519212d39c197a629' - ], - [ - 'e22fbe15c0af8ccc5780c0735f84dbe9a790badee8245c06c7ca37331cb36980', - 'a855babad5cd60c88b430a69f53a1a7a38289154964799be43d06d77d31da06' - ], - [ - '311091dd9860e8e20ee13473c1155f5f69635e394704eaa74009452246cfa9b3', - '66db656f87d1f04fffd1f04788c06830871ec5a64feee685bd80f0b1286d8374' - ], - [ - '34c1fd04d301be89b31c0442d3e6ac24883928b45a9340781867d4232ec2dbdf', - '9414685e97b1b5954bd46f730174136d57f1ceeb487443dc5321857ba73abee' - ], - [ - 'f219ea5d6b54701c1c14de5b557eb42a8d13f3abbcd08affcc2a5e6b049b8d63', - '4cb95957e83d40b0f73af4544cccf6b1f4b08d3c07b27fb8d8c2962a400766d1' - ], - [ - 'd7b8740f74a8fbaab1f683db8f45de26543a5490bca627087236912469a0b448', - 'fa77968128d9c92ee1010f337ad4717eff15db5ed3c049b3411e0315eaa4593b' - ], - [ - '32d31c222f8f6f0ef86f7c98d3a3335ead5bcd32abdd94289fe4d3091aa824bf', - '5f3032f5892156e39ccd3d7915b9e1da2e6dac9e6f26e961118d14b8462e1661' - ], - [ - '7461f371914ab32671045a155d9831ea8793d77cd59592c4340f86cbc18347b5', - '8ec0ba238b96bec0cbdddcae0aa442542eee1ff50c986ea6b39847b3cc092ff6' - ], - [ - 'ee079adb1df1860074356a25aa38206a6d716b2c3e67453d287698bad7b2b2d6', - '8dc2412aafe3be5c4c5f37e0ecc5f9f6a446989af04c4e25ebaac479ec1c8c1e' - ], - [ - '16ec93e447ec83f0467b18302ee620f7e65de331874c9dc72bfd8616ba9da6b5', - '5e4631150e62fb40d0e8c2a7ca5804a39d58186a50e497139626778e25b0674d' - ], - [ - 'eaa5f980c245f6f038978290afa70b6bd8855897f98b6aa485b96065d537bd99', - 'f65f5d3e292c2e0819a528391c994624d784869d7e6ea67fb18041024edc07dc' - ], - [ - '78c9407544ac132692ee1910a02439958ae04877151342ea96c4b6b35a49f51', - 'f3e0319169eb9b85d5404795539a5e68fa1fbd583c064d2462b675f194a3ddb4' - ], - [ - '494f4be219a1a77016dcd838431aea0001cdc8ae7a6fc688726578d9702857a5', - '42242a969283a5f339ba7f075e36ba2af925ce30d767ed6e55f4b031880d562c' - ], - [ - 'a598a8030da6d86c6bc7f2f5144ea549d28211ea58faa70ebf4c1e665c1fe9b5', - '204b5d6f84822c307e4b4a7140737aec23fc63b65b35f86a10026dbd2d864e6b' - ], - [ - 'c41916365abb2b5d09192f5f2dbeafec208f020f12570a184dbadc3e58595997', - '4f14351d0087efa49d245b328984989d5caf9450f34bfc0ed16e96b58fa9913' - ], - [ - '841d6063a586fa475a724604da03bc5b92a2e0d2e0a36acfe4c73a5514742881', - '73867f59c0659e81904f9a1c7543698e62562d6744c169ce7a36de01a8d6154' - ], - [ - '5e95bb399a6971d376026947f89bde2f282b33810928be4ded112ac4d70e20d5', - '39f23f366809085beebfc71181313775a99c9aed7d8ba38b161384c746012865' - ], - [ - '36e4641a53948fd476c39f8a99fd974e5ec07564b5315d8bf99471bca0ef2f66', - 'd2424b1b1abe4eb8164227b085c9aa9456ea13493fd563e06fd51cf5694c78fc' - ], - [ - '336581ea7bfbbb290c191a2f507a41cf5643842170e914faeab27c2c579f726', - 'ead12168595fe1be99252129b6e56b3391f7ab1410cd1e0ef3dcdcabd2fda224' - ], - [ - '8ab89816dadfd6b6a1f2634fcf00ec8403781025ed6890c4849742706bd43ede', - '6fdcef09f2f6d0a044e654aef624136f503d459c3e89845858a47a9129cdd24e' - ], - [ - '1e33f1a746c9c5778133344d9299fcaa20b0938e8acff2544bb40284b8c5fb94', - '60660257dd11b3aa9c8ed618d24edff2306d320f1d03010e33a7d2057f3b3b6' - ], - [ - '85b7c1dcb3cec1b7ee7f30ded79dd20a0ed1f4cc18cbcfcfa410361fd8f08f31', - '3d98a9cdd026dd43f39048f25a8847f4fcafad1895d7a633c6fed3c35e999511' - ], - [ - '29df9fbd8d9e46509275f4b125d6d45d7fbe9a3b878a7af872a2800661ac5f51', - 'b4c4fe99c775a606e2d8862179139ffda61dc861c019e55cd2876eb2a27d84b' - ], - [ - 'a0b1cae06b0a847a3fea6e671aaf8adfdfe58ca2f768105c8082b2e449fce252', - 'ae434102edde0958ec4b19d917a6a28e6b72da1834aff0e650f049503a296cf2' - ], - [ - '4e8ceafb9b3e9a136dc7ff67e840295b499dfb3b2133e4ba113f2e4c0e121e5', - 'cf2174118c8b6d7a4b48f6d534ce5c79422c086a63460502b827ce62a326683c' - ], - [ - 'd24a44e047e19b6f5afb81c7ca2f69080a5076689a010919f42725c2b789a33b', - '6fb8d5591b466f8fc63db50f1c0f1c69013f996887b8244d2cdec417afea8fa3' - ], - [ - 'ea01606a7a6c9cdd249fdfcfacb99584001edd28abbab77b5104e98e8e3b35d4', - '322af4908c7312b0cfbfe369f7a7b3cdb7d4494bc2823700cfd652188a3ea98d' - ], - [ - 'af8addbf2b661c8a6c6328655eb96651252007d8c5ea31be4ad196de8ce2131f', - '6749e67c029b85f52a034eafd096836b2520818680e26ac8f3dfbcdb71749700' - ], - [ - 'e3ae1974566ca06cc516d47e0fb165a674a3dabcfca15e722f0e3450f45889', - '2aeabe7e4531510116217f07bf4d07300de97e4874f81f533420a72eeb0bd6a4' - ], - [ - '591ee355313d99721cf6993ffed1e3e301993ff3ed258802075ea8ced397e246', - 'b0ea558a113c30bea60fc4775460c7901ff0b053d25ca2bdeee98f1a4be5d196' - ], - [ - '11396d55fda54c49f19aa97318d8da61fa8584e47b084945077cf03255b52984', - '998c74a8cd45ac01289d5833a7beb4744ff536b01b257be4c5767bea93ea57a4' - ], - [ - '3c5d2a1ba39c5a1790000738c9e0c40b8dcdfd5468754b6405540157e017aa7a', - 'b2284279995a34e2f9d4de7396fc18b80f9b8b9fdd270f6661f79ca4c81bd257' - ], - [ - 'cc8704b8a60a0defa3a99a7299f2e9c3fbc395afb04ac078425ef8a1793cc030', - 'bdd46039feed17881d1e0862db347f8cf395b74fc4bcdc4e940b74e3ac1f1b13' - ], - [ - 'c533e4f7ea8555aacd9777ac5cad29b97dd4defccc53ee7ea204119b2889b197', - '6f0a256bc5efdf429a2fb6242f1a43a2d9b925bb4a4b3a26bb8e0f45eb596096' - ], - [ - 'c14f8f2ccb27d6f109f6d08d03cc96a69ba8c34eec07bbcf566d48e33da6593', - 'c359d6923bb398f7fd4473e16fe1c28475b740dd098075e6c0e8649113dc3a38' - ], - [ - 'a6cbc3046bc6a450bac24789fa17115a4c9739ed75f8f21ce441f72e0b90e6ef', - '21ae7f4680e889bb130619e2c0f95a360ceb573c70603139862afd617fa9b9f' - ], - [ - '347d6d9a02c48927ebfb86c1359b1caf130a3c0267d11ce6344b39f99d43cc38', - '60ea7f61a353524d1c987f6ecec92f086d565ab687870cb12689ff1e31c74448' - ], - [ - 'da6545d2181db8d983f7dcb375ef5866d47c67b1bf31c8cf855ef7437b72656a', - '49b96715ab6878a79e78f07ce5680c5d6673051b4935bd897fea824b77dc208a' - ], - [ - 'c40747cc9d012cb1a13b8148309c6de7ec25d6945d657146b9d5994b8feb1111', - '5ca560753be2a12fc6de6caf2cb489565db936156b9514e1bb5e83037e0fa2d4' - ], - [ - '4e42c8ec82c99798ccf3a610be870e78338c7f713348bd34c8203ef4037f3502', - '7571d74ee5e0fb92a7a8b33a07783341a5492144cc54bcc40a94473693606437' - ], - [ - '3775ab7089bc6af823aba2e1af70b236d251cadb0c86743287522a1b3b0dedea', - 'be52d107bcfa09d8bcb9736a828cfa7fac8db17bf7a76a2c42ad961409018cf7' - ], - [ - 'cee31cbf7e34ec379d94fb814d3d775ad954595d1314ba8846959e3e82f74e26', - '8fd64a14c06b589c26b947ae2bcf6bfa0149ef0be14ed4d80f448a01c43b1c6d' - ], - [ - 'b4f9eaea09b6917619f6ea6a4eb5464efddb58fd45b1ebefcdc1a01d08b47986', - '39e5c9925b5a54b07433a4f18c61726f8bb131c012ca542eb24a8ac07200682a' - ], - [ - 'd4263dfc3d2df923a0179a48966d30ce84e2515afc3dccc1b77907792ebcc60e', - '62dfaf07a0f78feb30e30d6295853ce189e127760ad6cf7fae164e122a208d54' - ], - [ - '48457524820fa65a4f8d35eb6930857c0032acc0a4a2de422233eeda897612c4', - '25a748ab367979d98733c38a1fa1c2e7dc6cc07db2d60a9ae7a76aaa49bd0f77' - ], - [ - 'dfeeef1881101f2cb11644f3a2afdfc2045e19919152923f367a1767c11cceda', - 'ecfb7056cf1de042f9420bab396793c0c390bde74b4bbdff16a83ae09a9a7517' - ], - [ - '6d7ef6b17543f8373c573f44e1f389835d89bcbc6062ced36c82df83b8fae859', - 'cd450ec335438986dfefa10c57fea9bcc521a0959b2d80bbf74b190dca712d10' - ], - [ - 'e75605d59102a5a2684500d3b991f2e3f3c88b93225547035af25af66e04541f', - 'f5c54754a8f71ee540b9b48728473e314f729ac5308b06938360990e2bfad125' - ], - [ - 'eb98660f4c4dfaa06a2be453d5020bc99a0c2e60abe388457dd43fefb1ed620c', - '6cb9a8876d9cb8520609af3add26cd20a0a7cd8a9411131ce85f44100099223e' - ], - [ - '13e87b027d8514d35939f2e6892b19922154596941888336dc3563e3b8dba942', - 'fef5a3c68059a6dec5d624114bf1e91aac2b9da568d6abeb2570d55646b8adf1' - ], - [ - 'ee163026e9fd6fe017c38f06a5be6fc125424b371ce2708e7bf4491691e5764a', - '1acb250f255dd61c43d94ccc670d0f58f49ae3fa15b96623e5430da0ad6c62b2' - ], - [ - 'b268f5ef9ad51e4d78de3a750c2dc89b1e626d43505867999932e5db33af3d80', - '5f310d4b3c99b9ebb19f77d41c1dee018cf0d34fd4191614003e945a1216e423' - ], - [ - 'ff07f3118a9df035e9fad85eb6c7bfe42b02f01ca99ceea3bf7ffdba93c4750d', - '438136d603e858a3a5c440c38eccbaddc1d2942114e2eddd4740d098ced1f0d8' - ], - [ - '8d8b9855c7c052a34146fd20ffb658bea4b9f69e0d825ebec16e8c3ce2b526a1', - 'cdb559eedc2d79f926baf44fb84ea4d44bcf50fee51d7ceb30e2e7f463036758' - ], - [ - '52db0b5384dfbf05bfa9d472d7ae26dfe4b851ceca91b1eba54263180da32b63', - 'c3b997d050ee5d423ebaf66a6db9f57b3180c902875679de924b69d84a7b375' - ], - [ - 'e62f9490d3d51da6395efd24e80919cc7d0f29c3f3fa48c6fff543becbd43352', - '6d89ad7ba4876b0b22c2ca280c682862f342c8591f1daf5170e07bfd9ccafa7d' - ], - [ - '7f30ea2476b399b4957509c88f77d0191afa2ff5cb7b14fd6d8e7d65aaab1193', - 'ca5ef7d4b231c94c3b15389a5f6311e9daff7bb67b103e9880ef4bff637acaec' - ], - [ - '5098ff1e1d9f14fb46a210fada6c903fef0fb7b4a1dd1d9ac60a0361800b7a00', - '9731141d81fc8f8084d37c6e7542006b3ee1b40d60dfe5362a5b132fd17ddc0' - ], - [ - '32b78c7de9ee512a72895be6b9cbefa6e2f3c4ccce445c96b9f2c81e2778ad58', - 'ee1849f513df71e32efc3896ee28260c73bb80547ae2275ba497237794c8753c' - ], - [ - 'e2cb74fddc8e9fbcd076eef2a7c72b0ce37d50f08269dfc074b581550547a4f7', - 'd3aa2ed71c9dd2247a62df062736eb0baddea9e36122d2be8641abcb005cc4a4' - ], - [ - '8438447566d4d7bedadc299496ab357426009a35f235cb141be0d99cd10ae3a8', - 'c4e1020916980a4da5d01ac5e6ad330734ef0d7906631c4f2390426b2edd791f' - ], - [ - '4162d488b89402039b584c6fc6c308870587d9c46f660b878ab65c82c711d67e', - '67163e903236289f776f22c25fb8a3afc1732f2b84b4e95dbda47ae5a0852649' - ], - [ - '3fad3fa84caf0f34f0f89bfd2dcf54fc175d767aec3e50684f3ba4a4bf5f683d', - 'cd1bc7cb6cc407bb2f0ca647c718a730cf71872e7d0d2a53fa20efcdfe61826' - ], - [ - '674f2600a3007a00568c1a7ce05d0816c1fb84bf1370798f1c69532faeb1a86b', - '299d21f9413f33b3edf43b257004580b70db57da0b182259e09eecc69e0d38a5' - ], - [ - 'd32f4da54ade74abb81b815ad1fb3b263d82d6c692714bcff87d29bd5ee9f08f', - 'f9429e738b8e53b968e99016c059707782e14f4535359d582fc416910b3eea87' - ], - [ - '30e4e670435385556e593657135845d36fbb6931f72b08cb1ed954f1e3ce3ff6', - '462f9bce619898638499350113bbc9b10a878d35da70740dc695a559eb88db7b' - ], - [ - 'be2062003c51cc3004682904330e4dee7f3dcd10b01e580bf1971b04d4cad297', - '62188bc49d61e5428573d48a74e1c655b1c61090905682a0d5558ed72dccb9bc' - ], - [ - '93144423ace3451ed29e0fb9ac2af211cb6e84a601df5993c419859fff5df04a', - '7c10dfb164c3425f5c71a3f9d7992038f1065224f72bb9d1d902a6d13037b47c' - ], - [ - 'b015f8044f5fcbdcf21ca26d6c34fb8197829205c7b7d2a7cb66418c157b112c', - 'ab8c1e086d04e813744a655b2df8d5f83b3cdc6faa3088c1d3aea1454e3a1d5f' - ], - [ - 'd5e9e1da649d97d89e4868117a465a3a4f8a18de57a140d36b3f2af341a21b52', - '4cb04437f391ed73111a13cc1d4dd0db1693465c2240480d8955e8592f27447a' - ], - [ - 'd3ae41047dd7ca065dbf8ed77b992439983005cd72e16d6f996a5316d36966bb', - 'bd1aeb21ad22ebb22a10f0303417c6d964f8cdd7df0aca614b10dc14d125ac46' - ], - [ - '463e2763d885f958fc66cdd22800f0a487197d0a82e377b49f80af87c897b065', - 'bfefacdb0e5d0fd7df3a311a94de062b26b80c61fbc97508b79992671ef7ca7f' - ], - [ - '7985fdfd127c0567c6f53ec1bb63ec3158e597c40bfe747c83cddfc910641917', - '603c12daf3d9862ef2b25fe1de289aed24ed291e0ec6708703a5bd567f32ed03' - ], - [ - '74a1ad6b5f76e39db2dd249410eac7f99e74c59cb83d2d0ed5ff1543da7703e9', - 'cc6157ef18c9c63cd6193d83631bbea0093e0968942e8c33d5737fd790e0db08' - ], - [ - '30682a50703375f602d416664ba19b7fc9bab42c72747463a71d0896b22f6da3', - '553e04f6b018b4fa6c8f39e7f311d3176290d0e0f19ca73f17714d9977a22ff8' - ], - [ - '9e2158f0d7c0d5f26c3791efefa79597654e7a2b2464f52b1ee6c1347769ef57', - '712fcdd1b9053f09003a3481fa7762e9ffd7c8ef35a38509e2fbf2629008373' - ], - [ - '176e26989a43c9cfeba4029c202538c28172e566e3c4fce7322857f3be327d66', - 'ed8cc9d04b29eb877d270b4878dc43c19aefd31f4eee09ee7b47834c1fa4b1c3' - ], - [ - '75d46efea3771e6e68abb89a13ad747ecf1892393dfc4f1b7004788c50374da8', - '9852390a99507679fd0b86fd2b39a868d7efc22151346e1a3ca4726586a6bed8' - ], - [ - '809a20c67d64900ffb698c4c825f6d5f2310fb0451c869345b7319f645605721', - '9e994980d9917e22b76b061927fa04143d096ccc54963e6a5ebfa5f3f8e286c1' - ], - [ - '1b38903a43f7f114ed4500b4eac7083fdefece1cf29c63528d563446f972c180', - '4036edc931a60ae889353f77fd53de4a2708b26b6f5da72ad3394119daf408f9' - ] - ] - } - } - ] -}); +module.exports = Hash -},{"../elliptic":69,"bn.js":67,"hash.js":82}],76:[function(require,module,exports){ -var bn = require('bn.js'); -var elliptic = require('../../elliptic'); -var utils = elliptic.utils; -var assert = utils.assert; +}).call(this,require("buffer").Buffer) +},{"buffer":47}],131:[function(require,module,exports){ +var exports = module.exports = function SHA (algorithm) { + algorithm = algorithm.toLowerCase() -var KeyPair = require('./key'); -var Signature = require('./signature'); + var Algorithm = exports[algorithm] + if (!Algorithm) throw new Error(algorithm + ' is not supported (we accept pull requests)') -function EC(options) { - if (!(this instanceof EC)) - return new EC(options); + return new Algorithm() +} - // Shortcut `elliptic.ec(curve-name)` - if (typeof options === 'string') { - assert(elliptic.curves.hasOwnProperty(options), 'Unknown curve ' + options); +exports.sha = require('./sha') +exports.sha1 = require('./sha1') +exports.sha224 = require('./sha224') +exports.sha256 = require('./sha256') +exports.sha384 = require('./sha384') +exports.sha512 = require('./sha512') - options = elliptic.curves[options]; - } +},{"./sha":132,"./sha1":133,"./sha224":134,"./sha256":135,"./sha384":136,"./sha512":137}],132:[function(require,module,exports){ +(function (Buffer){ +/* + * A JavaScript implementation of the Secure Hash Algorithm, SHA-0, as defined + * in FIPS PUB 180-1 + * This source code is derived from sha1.js of the same repository. + * The difference between SHA-0 and SHA-1 is just a bitwise rotate left + * operation was added. + */ - // Shortcut for `elliptic.ec(elliptic.curves.curveName)` - if (options instanceof elliptic.curves.PresetCurve) - options = { curve: options }; +var inherits = require('inherits') +var Hash = require('./hash') - this.curve = options.curve.curve; - this.n = this.curve.n; - this.nh = this.n.shrn(1); - this.g = this.curve.g; +var W = new Array(80) - // Point on curve - this.g = options.curve.g; - this.g.precompute(options.curve.n.bitLength() + 1); +function Sha () { + this.init() + this._w = W - // Hash for function for DRBG - this.hash = options.hash || options.curve.hash; + Hash.call(this, 64, 56) } -module.exports = EC; - -EC.prototype.keyPair = function keyPair(priv, pub) { - return new KeyPair(this, priv, pub); -}; - -EC.prototype.genKeyPair = function genKeyPair(options) { - if (!options) - options = {}; - - // Instantiate Hmac_DRBG - var drbg = new elliptic.hmacDRBG({ - hash: this.hash, - pers: options.pers, - entropy: options.entropy || elliptic.rand(this.hash.hmacStrength), - nonce: this.n.toArray() - }); - var bytes = this.n.byteLength(); - var ns2 = this.n.sub(new bn(2)); - do { - var priv = new bn(drbg.generate(bytes)); - if (priv.cmp(ns2) > 0) - continue; +inherits(Sha, Hash) - priv.iaddn(1); - return this.keyPair(priv); - } while (true); -}; +Sha.prototype.init = function () { + this._a = 0x67452301 | 0 + this._b = 0xefcdab89 | 0 + this._c = 0x98badcfe | 0 + this._d = 0x10325476 | 0 + this._e = 0xc3d2e1f0 | 0 -EC.prototype._truncateToN = function truncateToN(msg, truncOnly) { - var delta = msg.byteLength() * 8 - this.n.bitLength(); - if (delta > 0) - msg = msg.shrn(delta); - if (!truncOnly && msg.cmp(this.n) >= 0) - return msg.sub(this.n); - else - return msg; -}; + return this +} -EC.prototype.sign = function sign(msg, key, options) { - key = this.keyPair(key, 'hex'); - msg = this._truncateToN(new bn(msg, 16)); - if (!options) - options = {}; +/* + * Bitwise rotate a 32-bit number to the left. + */ +function rol (num, cnt) { + return (num << cnt) | (num >>> (32 - cnt)) +} - // Zero-extend key to provide enough entropy - var bytes = this.n.byteLength(); - var bkey = key.getPrivate().toArray(); - for (var i = bkey.length; i < 21; i++) - bkey.unshift(0); +Sha.prototype._update = function (M) { + var W = this._w - // Zero-extend nonce to have the same byte size as N - var nonce = msg.toArray(); - for (var i = nonce.length; i < bytes; i++) - nonce.unshift(0); + var a = this._a + var b = this._b + var c = this._c + var d = this._d + var e = this._e - // Instantiate Hmac_DRBG - var drbg = new elliptic.hmacDRBG({ - hash: this.hash, - entropy: bkey, - nonce: nonce - }); + var j = 0 + var k - // Number of bytes to generate - var ns1 = this.n.sub(new bn(1)); - do { - var k = new bn(drbg.generate(this.n.byteLength())); - k = this._truncateToN(k, true); - if (k.cmpn(1) <= 0 || k.cmp(ns1) >= 0) - continue; + /* + * SHA-1 has a bitwise rotate left operation. But, SHA is not + * function calcW() { return rol(W[j - 3] ^ W[j - 8] ^ W[j - 14] ^ W[j - 16], 1) } + */ + function calcW () { return W[j - 3] ^ W[j - 8] ^ W[j - 14] ^ W[j - 16] } + function loop (w, f) { + W[j] = w - var kp = this.g.mul(k); - if (kp.isInfinity()) - continue; + var t = rol(a, 5) + f + e + w + k - var r = kp.getX().mod(this.n); - if (r.cmpn(0) === 0) - continue; + e = d + d = c + c = rol(b, 30) + b = a + a = t + j++ + } - var s = k.invm(this.n).mul(r.mul(key.getPrivate()).iadd(msg)).mod(this.n); - if (s.cmpn(0) === 0) - continue; + k = 1518500249 + while (j < 16) loop(M.readInt32BE(j * 4), (b & c) | ((~b) & d)) + while (j < 20) loop(calcW(), (b & c) | ((~b) & d)) + k = 1859775393 + while (j < 40) loop(calcW(), b ^ c ^ d) + k = -1894007588 + while (j < 60) loop(calcW(), (b & c) | (b & d) | (c & d)) + k = -899497514 + while (j < 80) loop(calcW(), b ^ c ^ d) - // Use complement of `s`, if it is > `n / 2` - if (options.canonical && s.cmp(this.nh) > 0) - s = this.n.sub(s); + this._a = (a + this._a) | 0 + this._b = (b + this._b) | 0 + this._c = (c + this._c) | 0 + this._d = (d + this._d) | 0 + this._e = (e + this._e) | 0 +} - return new Signature(r, s); - } while (true); -}; +Sha.prototype._hash = function () { + var H = new Buffer(20) -EC.prototype.verify = function verify(msg, signature, key) { - msg = this._truncateToN(new bn(msg, 16)); - key = this.keyPair(key, 'hex'); - signature = new Signature(signature, 'hex'); + H.writeInt32BE(this._a | 0, 0) + H.writeInt32BE(this._b | 0, 4) + H.writeInt32BE(this._c | 0, 8) + H.writeInt32BE(this._d | 0, 12) + H.writeInt32BE(this._e | 0, 16) - // Perform primitive values validation - var r = signature.r; - var s = signature.s; - if (r.cmpn(1) < 0 || r.cmp(this.n) >= 0) - return false; - if (s.cmpn(1) < 0 || s.cmp(this.n) >= 0) - return false; + return H +} - // Validate signature - var sinv = s.invm(this.n); - var u1 = sinv.mul(msg).mod(this.n); - var u2 = sinv.mul(r).mod(this.n); +module.exports = Sha - var p = this.g.mulAdd(u1, key.getPublic(), u2); - if (p.isInfinity()) - return false; - return p.getX().mod(this.n).cmp(r) === 0; -}; +}).call(this,require("buffer").Buffer) +},{"./hash":130,"buffer":47,"inherits":240}],133:[function(require,module,exports){ +(function (Buffer){ +/* + * A JavaScript implementation of the Secure Hash Algorithm, SHA-1, as defined + * in FIPS PUB 180-1 + * Version 2.1a Copyright Paul Johnston 2000 - 2002. + * Other contributors: Greg Holt, Andrew Kepert, Ydnar, Lostinet + * Distributed under the BSD License + * See http://pajhome.org.uk/crypt/md5 for details. + */ -},{"../../elliptic":69,"./key":77,"./signature":78,"bn.js":67}],77:[function(require,module,exports){ -var bn = require('bn.js'); +var inherits = require('inherits') +var Hash = require('./hash') -var elliptic = require('../../elliptic'); -var utils = elliptic.utils; -var assert = utils.assert; +var W = new Array(80) -function KeyPair(ec, priv, pub) { - if (priv instanceof KeyPair) - return priv; - if (pub instanceof KeyPair) - return pub; +function Sha1 () { + this.init() + this._w = W - if (!priv) { - priv = pub; - pub = null; - } - if (priv !== null && typeof priv === 'object') { - if (priv.x) { - // KeyPair(public) - pub = priv; - priv = null; - } else if (priv.priv || priv.pub) { - // KeyPair({ priv: ..., pub: ... }) - pub = priv.pub; - priv = priv.priv; - } - } + Hash.call(this, 64, 56) +} - this.ec = ec; - this.priv = null; - this.pub = null; +inherits(Sha1, Hash) - // KeyPair(public, 'hex') - if (this._importPublicHex(priv, pub)) - return; +Sha1.prototype.init = function () { + this._a = 0x67452301 | 0 + this._b = 0xefcdab89 | 0 + this._c = 0x98badcfe | 0 + this._d = 0x10325476 | 0 + this._e = 0xc3d2e1f0 | 0 - if (pub === 'hex') - pub = null; + return this +} - // KeyPair(priv, pub) - if (priv) - this._importPrivate(priv); - if (pub) - this._importPublic(pub); +/* + * Bitwise rotate a 32-bit number to the left. + */ +function rol (num, cnt) { + return (num << cnt) | (num >>> (32 - cnt)) } -module.exports = KeyPair; -KeyPair.prototype.validate = function validate() { - var pub = this.getPublic(); +Sha1.prototype._update = function (M) { + var W = this._w - if (pub.isInfinity()) - return { result: false, reason: 'Invalid public key' }; - if (!pub.validate()) - return { result: false, reason: 'Public key is not a point' }; - if (!pub.mul(this.ec.curve.n).isInfinity()) - return { result: false, reason: 'Public key * N != O' }; + var a = this._a + var b = this._b + var c = this._c + var d = this._d + var e = this._e - return { result: true, reason: null }; -}; + var j = 0 + var k -KeyPair.prototype.getPublic = function getPublic(compact, enc) { - if (!this.pub) - this.pub = this.ec.g.mul(this.priv); + function calcW () { return rol(W[j - 3] ^ W[j - 8] ^ W[j - 14] ^ W[j - 16], 1) } + function loop (w, f) { + W[j] = w - // compact is optional argument - if (typeof compact === 'string') { - enc = compact; - compact = null; - } + var t = rol(a, 5) + f + e + w + k - if (!enc) - return this.pub; + e = d + d = c + c = rol(b, 30) + b = a + a = t + j++ + } - var len = this.ec.curve.p.byteLength(); - var x = this.pub.getX().toArray(); + k = 1518500249 + while (j < 16) loop(M.readInt32BE(j * 4), (b & c) | ((~b) & d)) + while (j < 20) loop(calcW(), (b & c) | ((~b) & d)) + k = 1859775393 + while (j < 40) loop(calcW(), b ^ c ^ d) + k = -1894007588 + while (j < 60) loop(calcW(), (b & c) | (b & d) | (c & d)) + k = -899497514 + while (j < 80) loop(calcW(), b ^ c ^ d) - for (var i = x.length; i < len; i++) - x.unshift(0); + this._a = (a + this._a) | 0 + this._b = (b + this._b) | 0 + this._c = (c + this._c) | 0 + this._d = (d + this._d) | 0 + this._e = (e + this._e) | 0 +} - if (compact) { - var res = [ this.pub.getY().isEven() ? 0x02 : 0x03 ].concat(x); - } else { - var y = this.pub.getY().toArray(); - for (var i = y.length; i < len; i++) - y.unshift(0); - var res = [ 0x04 ].concat(x, y); - } - return utils.encode(res, enc); -}; +Sha1.prototype._hash = function () { + var H = new Buffer(20) -KeyPair.prototype.getPrivate = function getPrivate(enc) { - if (enc === 'hex') - return this.priv.toString(16, 2); - else - return this.priv; -}; + H.writeInt32BE(this._a | 0, 0) + H.writeInt32BE(this._b | 0, 4) + H.writeInt32BE(this._c | 0, 8) + H.writeInt32BE(this._d | 0, 12) + H.writeInt32BE(this._e | 0, 16) -KeyPair.prototype._importPrivate = function _importPrivate(key) { - this.priv = new bn(key, 16); + return H +} - // Ensure that the priv won't be bigger than n, otherwise we may fail - // in fixed multiplication method - this.priv = this.priv.mod(this.ec.curve.n); -}; +module.exports = Sha1 -KeyPair.prototype._importPublic = function _importPublic(key) { - this.pub = this.ec.curve.point(key.x, key.y); -}; +}).call(this,require("buffer").Buffer) +},{"./hash":130,"buffer":47,"inherits":240}],134:[function(require,module,exports){ +(function (Buffer){ +/** + * A JavaScript implementation of the Secure Hash Algorithm, SHA-256, as defined + * in FIPS 180-2 + * Version 2.2-beta Copyright Angel Marin, Paul Johnston 2000 - 2009. + * Other contributors: Greg Holt, Andrew Kepert, Ydnar, Lostinet + * + */ -KeyPair.prototype._importPublicHex = function _importPublic(key, enc) { - key = utils.toArray(key, enc); - var len = this.ec.curve.p.byteLength(); - if (key[0] === 0x04 && key.length - 1 === 2 * len) { - this.pub = this.ec.curve.point( - key.slice(1, 1 + len), - key.slice(1 + len, 1 + 2 * len)); - } else if ((key[0] === 0x02 || key[0] === 0x03) && key.length - 1 === len) { - this.pub = this.ec.curve.pointFromX(key[0] === 0x03, - key.slice(1, 1 +len)); - } else { - return false; - } +var inherits = require('inherits') +var Sha256 = require('./sha256') +var Hash = require('./hash') - return true; -}; +var W = new Array(64) -// ECDH -KeyPair.prototype.derive = function derive(pub) { - return pub.mul(this.priv).getX(); -}; +function Sha224 () { + this.init() -// ECDSA -KeyPair.prototype.sign = function sign(msg) { - return this.ec.sign(msg, this); -}; + this._w = W // new Array(64) -KeyPair.prototype.verify = function verify(msg, signature) { - return this.ec.verify(msg, signature, this); -}; + Hash.call(this, 64, 56) +} -KeyPair.prototype.inspect = function inspect() { - return ''; -}; +inherits(Sha224, Sha256) -},{"../../elliptic":69,"bn.js":67}],78:[function(require,module,exports){ -var bn = require('bn.js'); +Sha224.prototype.init = function () { + this._a = 0xc1059ed8 | 0 + this._b = 0x367cd507 | 0 + this._c = 0x3070dd17 | 0 + this._d = 0xf70e5939 | 0 + this._e = 0xffc00b31 | 0 + this._f = 0x68581511 | 0 + this._g = 0x64f98fa7 | 0 + this._h = 0xbefa4fa4 | 0 -var elliptic = require('../../elliptic'); -var utils = elliptic.utils; -var assert = utils.assert; + return this +} -function Signature(r, s) { - if (r instanceof Signature) - return r; +Sha224.prototype._hash = function () { + var H = new Buffer(28) - if (this._importDER(r, s)) - return; + H.writeInt32BE(this._a, 0) + H.writeInt32BE(this._b, 4) + H.writeInt32BE(this._c, 8) + H.writeInt32BE(this._d, 12) + H.writeInt32BE(this._e, 16) + H.writeInt32BE(this._f, 20) + H.writeInt32BE(this._g, 24) - assert(r && s, 'Signature without r or s'); - this.r = new bn(r, 16); - this.s = new bn(s, 16); + return H } -module.exports = Signature; -Signature.prototype._importDER = function _importDER(data, enc) { - data = utils.toArray(data, enc); - if (data.length < 6 || data[0] !== 0x30 || data[2] !== 0x02) - return false; - var total = data[1]; - if (1 + total > data.length) - return false; - var rlen = data[3]; - // Short length notation - if (rlen >= 0x80) - return false; - if (4 + rlen + 2 >= data.length) - return false; - if (data[4 + rlen] !== 0x02) - return false; - var slen = data[5 + rlen]; - // Short length notation - if (slen >= 0x80) - return false; - if (4 + rlen + 2 + slen > data.length) - return false; +module.exports = Sha224 - this.r = new bn(data.slice(4, 4 + rlen)); - this.s = new bn(data.slice(4 + rlen + 2, 4 + rlen + 2 + slen)); +}).call(this,require("buffer").Buffer) +},{"./hash":130,"./sha256":135,"buffer":47,"inherits":240}],135:[function(require,module,exports){ +(function (Buffer){ +/** + * A JavaScript implementation of the Secure Hash Algorithm, SHA-256, as defined + * in FIPS 180-2 + * Version 2.2-beta Copyright Angel Marin, Paul Johnston 2000 - 2009. + * Other contributors: Greg Holt, Andrew Kepert, Ydnar, Lostinet + * + */ - return true; -}; +var inherits = require('inherits') +var Hash = require('./hash') -Signature.prototype.toDER = function toDER(enc) { - var r = this.r.toArray(); - var s = this.s.toArray(); +var K = [ + 0x428A2F98, 0x71374491, 0xB5C0FBCF, 0xE9B5DBA5, + 0x3956C25B, 0x59F111F1, 0x923F82A4, 0xAB1C5ED5, + 0xD807AA98, 0x12835B01, 0x243185BE, 0x550C7DC3, + 0x72BE5D74, 0x80DEB1FE, 0x9BDC06A7, 0xC19BF174, + 0xE49B69C1, 0xEFBE4786, 0x0FC19DC6, 0x240CA1CC, + 0x2DE92C6F, 0x4A7484AA, 0x5CB0A9DC, 0x76F988DA, + 0x983E5152, 0xA831C66D, 0xB00327C8, 0xBF597FC7, + 0xC6E00BF3, 0xD5A79147, 0x06CA6351, 0x14292967, + 0x27B70A85, 0x2E1B2138, 0x4D2C6DFC, 0x53380D13, + 0x650A7354, 0x766A0ABB, 0x81C2C92E, 0x92722C85, + 0xA2BFE8A1, 0xA81A664B, 0xC24B8B70, 0xC76C51A3, + 0xD192E819, 0xD6990624, 0xF40E3585, 0x106AA070, + 0x19A4C116, 0x1E376C08, 0x2748774C, 0x34B0BCB5, + 0x391C0CB3, 0x4ED8AA4A, 0x5B9CCA4F, 0x682E6FF3, + 0x748F82EE, 0x78A5636F, 0x84C87814, 0x8CC70208, + 0x90BEFFFA, 0xA4506CEB, 0xBEF9A3F7, 0xC67178F2 +] - // Pad values - if (r[0] & 0x80) - r = [ 0 ].concat(r); - // Pad values - if (s[0] & 0x80) - s = [ 0 ].concat(s); +var W = new Array(64) - var total = r.length + s.length + 4; - var res = [ 0x30, total, 0x02, r.length ]; - res = res.concat(r, [ 0x02, s.length ], s); - return utils.encode(res, enc); -}; +function Sha256 () { + this.init() -},{"../../elliptic":69,"bn.js":67}],79:[function(require,module,exports){ -var hash = require('hash.js'); -var elliptic = require('../elliptic'); -var utils = elliptic.utils; -var assert = utils.assert; + this._w = W // new Array(64) -function HmacDRBG(options) { - if (!(this instanceof HmacDRBG)) - return new HmacDRBG(options); - this.hash = options.hash; - this.predResist = !!options.predResist; + Hash.call(this, 64, 56) +} - this.outLen = this.hash.outSize; - this.minEntropy = options.minEntropy || this.hash.hmacStrength; +inherits(Sha256, Hash) - this.reseed = null; - this.reseedInterval = null; - this.K = null; - this.V = null; +Sha256.prototype.init = function () { + this._a = 0x6a09e667 | 0 + this._b = 0xbb67ae85 | 0 + this._c = 0x3c6ef372 | 0 + this._d = 0xa54ff53a | 0 + this._e = 0x510e527f | 0 + this._f = 0x9b05688c | 0 + this._g = 0x1f83d9ab | 0 + this._h = 0x5be0cd19 | 0 - var entropy = utils.toArray(options.entropy, options.entropyEnc); - var nonce = utils.toArray(options.nonce, options.nonceEnc); - var pers = utils.toArray(options.pers, options.persEnc); - assert(entropy.length >= (this.minEntropy / 8), - 'Not enough entropy. Minimum is: ' + this.minEntropy + ' bits'); - this._init(entropy, nonce, pers); + return this } -module.exports = HmacDRBG; -HmacDRBG.prototype._init = function init(entropy, nonce, pers) { - var seed = entropy.concat(nonce).concat(pers); +function Ch (x, y, z) { + return z ^ (x & (y ^ z)) +} - this.K = new Array(this.outLen / 8); - this.V = new Array(this.outLen / 8); - for (var i = 0; i < this.V.length; i++) { - this.K[i] = 0x00; - this.V[i] = 0x01; - } +function Maj (x, y, z) { + return (x & y) | (z & (x | y)) +} - this._update(seed); - this.reseed = 1; - this.reseedInterval = 0x1000000000000; // 2^48 -}; +function Sigma0 (x) { + return (x >>> 2 | x << 30) ^ (x >>> 13 | x << 19) ^ (x >>> 22 | x << 10) +} -HmacDRBG.prototype._hmac = function hmac() { - return new hash.hmac(this.hash, this.K); -}; +function Sigma1 (x) { + return (x >>> 6 | x << 26) ^ (x >>> 11 | x << 21) ^ (x >>> 25 | x << 7) +} -HmacDRBG.prototype._update = function update(seed) { - var kmac = this._hmac() - .update(this.V) - .update([ 0x00 ]); - if (seed) - kmac = kmac.update(seed); - this.K = kmac.digest(); - this.V = this._hmac().update(this.V).digest(); - if (!seed) - return; - - this.K = this._hmac() - .update(this.V) - .update([ 0x01 ]) - .update(seed) - .digest(); - this.V = this._hmac().update(this.V).digest(); -}; +function Gamma0 (x) { + return (x >>> 7 | x << 25) ^ (x >>> 18 | x << 14) ^ (x >>> 3) +} -HmacDRBG.prototype.reseed = function reseed(entropy, entropyEnc, add, addEnc) { - // Optional entropy enc - if (typeof entropyEnc !== 'string') { - addEnc = add; - add = entropyEnc; - entropyEnc = null; - } +function Gamma1 (x) { + return (x >>> 17 | x << 15) ^ (x >>> 19 | x << 13) ^ (x >>> 10) +} - entropy = utils.toBuffer(entropy, entropyEnc); - add = utils.toBuffer(add, addEnc); +Sha256.prototype._update = function (M) { + var W = this._w - assert(entropy.length >= (this.minEntropy / 8), - 'Not enough entropy. Minimum is: ' + this.minEntropy + ' bits'); + var a = this._a | 0 + var b = this._b | 0 + var c = this._c | 0 + var d = this._d | 0 + var e = this._e | 0 + var f = this._f | 0 + var g = this._g | 0 + var h = this._h | 0 - this._update(entropy.concat(add || [])); - this.reseed = 1; -}; + var j = 0 -HmacDRBG.prototype.generate = function generate(len, enc, add, addEnc) { - if (this.reseed > this.reseedInterval) - throw new Error('Reseed is required'); + function calcW () { return Gamma1(W[j - 2]) + W[j - 7] + Gamma0(W[j - 15]) + W[j - 16] } + function loop (w) { + W[j] = w - // Optional encoding - if (typeof enc !== 'string') { - addEnc = add; - add = enc; - enc = null; - } + var T1 = h + Sigma1(e) + Ch(e, f, g) + K[j] + w + var T2 = Sigma0(a) + Maj(a, b, c) - // Optional additional data - if (add) { - add = utils.toArray(add, addEnc); - this._update(add); - } + h = g + g = f + f = e + e = d + T1 + d = c + c = b + b = a + a = T1 + T2 - var temp = []; - while (temp.length < len) { - this.V = this._hmac().update(this.V).digest(); - temp = temp.concat(this.V); + j++ } - var res = temp.slice(0, len); - this._update(add); - this.reseed++; - return utils.encode(res, enc); -}; - -},{"../elliptic":69,"hash.js":82}],80:[function(require,module,exports){ -var bn = require('bn.js'); + while (j < 16) loop(M.readInt32BE(j * 4)) + while (j < 64) loop(calcW()) -var utils = exports; + this._a = (a + this._a) | 0 + this._b = (b + this._b) | 0 + this._c = (c + this._c) | 0 + this._d = (d + this._d) | 0 + this._e = (e + this._e) | 0 + this._f = (f + this._f) | 0 + this._g = (g + this._g) | 0 + this._h = (h + this._h) | 0 +} -utils.assert = function assert(val, msg) { - if (!val) - throw new Error(msg || 'Assertion failed'); -}; +Sha256.prototype._hash = function () { + var H = new Buffer(32) -function toArray(msg, enc) { - if (Array.isArray(msg)) - return msg.slice(); - if (!msg) - return []; - var res = []; - if (typeof msg === 'string') { - if (!enc) { - for (var i = 0; i < msg.length; i++) { - var c = msg.charCodeAt(i); - var hi = c >> 8; - var lo = c & 0xff; - if (hi) - res.push(hi, lo); - else - res.push(lo); - } - } else if (enc === 'hex') { - msg = msg.replace(/[^a-z0-9]+/ig, ''); - if (msg.length % 2 !== 0) - msg = '0' + msg; - for (var i = 0; i < msg.length; i += 2) - res.push(parseInt(msg[i] + msg[i + 1], 16)); - } - } else { - for (var i = 0; i < msg.length; i++) - res[i] = msg[i] | 0; - } - return res; -} -utils.toArray = toArray; + H.writeInt32BE(this._a, 0) + H.writeInt32BE(this._b, 4) + H.writeInt32BE(this._c, 8) + H.writeInt32BE(this._d, 12) + H.writeInt32BE(this._e, 16) + H.writeInt32BE(this._f, 20) + H.writeInt32BE(this._g, 24) + H.writeInt32BE(this._h, 28) -function toHex(msg) { - var res = ''; - for (var i = 0; i < msg.length; i++) - res += zero2(msg[i].toString(16)); - return res; + return H } -utils.toHex = toHex; -utils.encode = function encode(arr, enc) { - if (enc === 'hex') - return toHex(arr); - else - return arr; -}; +module.exports = Sha256 -function zero2(word) { - if (word.length === 1) - return '0' + word; - else - return word; -} -utils.zero2 = zero2; +}).call(this,require("buffer").Buffer) +},{"./hash":130,"buffer":47,"inherits":240}],136:[function(require,module,exports){ +(function (Buffer){ +var inherits = require('inherits') +var SHA512 = require('./sha512') +var Hash = require('./hash') -// Represent num in a w-NAF form -function getNAF(num, w) { - var naf = []; - var ws = 1 << (w + 1); - var k = num.clone(); - while (k.cmpn(1) >= 0) { - var z; - if (k.isOdd()) { - var mod = k.andln(ws - 1); - if (mod > (ws >> 1) - 1) - z = (ws >> 1) - mod; - else - z = mod; - k.isubn(z); - } else { - z = 0; - } - naf.push(z); +var W = new Array(160) - // Optimization, shift by word if possible - var shift = (k.cmpn(0) !== 0 && k.andln(ws - 1) === 0) ? (w + 1) : 1; - for (var i = 1; i < shift; i++) - naf.push(0); - k.ishrn(shift); - } +function Sha384 () { + this.init() + this._w = W - return naf; + Hash.call(this, 128, 112) } -utils.getNAF = getNAF; -// Represent k1, k2 in a Joint Sparse Form -function getJSF(k1, k2) { - var jsf = [ - [], - [] - ]; +inherits(Sha384, SHA512) - k1 = k1.clone(); - k2 = k2.clone(); - var d1 = 0; - var d2 = 0; - while (k1.cmpn(-d1) > 0 || k2.cmpn(-d2) > 0) { +Sha384.prototype.init = function () { + this._a = 0xcbbb9d5d | 0 + this._b = 0x629a292a | 0 + this._c = 0x9159015a | 0 + this._d = 0x152fecd8 | 0 + this._e = 0x67332667 | 0 + this._f = 0x8eb44a87 | 0 + this._g = 0xdb0c2e0d | 0 + this._h = 0x47b5481d | 0 + + this._al = 0xc1059ed8 | 0 + this._bl = 0x367cd507 | 0 + this._cl = 0x3070dd17 | 0 + this._dl = 0xf70e5939 | 0 + this._el = 0xffc00b31 | 0 + this._fl = 0x68581511 | 0 + this._gl = 0x64f98fa7 | 0 + this._hl = 0xbefa4fa4 | 0 - // First phase - var m14 = (k1.andln(3) + d1) & 3; - var m24 = (k2.andln(3) + d2) & 3; - if (m14 === 3) - m14 = -1; - if (m24 === 3) - m24 = -1; - var u1; - if ((m14 & 1) === 0) { - u1 = 0; - } else { - var m8 = (k1.andln(7) + d1) & 7; - if ((m8 === 3 || m8 === 5) && m24 === 2) - u1 = -m14; - else - u1 = m14; - } - jsf[0].push(u1); + return this +} - var u2; - if ((m24 & 1) === 0) { - u2 = 0; - } else { - var m8 = (k2.andln(7) + d2) & 7; - if ((m8 === 3 || m8 === 5) && m14 === 2) - u2 = -m24; - else - u2 = m24; - } - jsf[1].push(u2); +Sha384.prototype._hash = function () { + var H = new Buffer(48) - // Second phase - if (2 * d1 === u1 + 1) - d1 = 1 - d1; - if (2 * d2 === u2 + 1) - d2 = 1 - d2; - k1.ishrn(1); - k2.ishrn(1); + function writeInt64BE (h, l, offset) { + H.writeInt32BE(h, offset) + H.writeInt32BE(l, offset + 4) } - return jsf; + writeInt64BE(this._a, this._al, 0) + writeInt64BE(this._b, this._bl, 8) + writeInt64BE(this._c, this._cl, 16) + writeInt64BE(this._d, this._dl, 24) + writeInt64BE(this._e, this._el, 32) + writeInt64BE(this._f, this._fl, 40) + + return H } -utils.getJSF = getJSF; -},{"bn.js":67}],81:[function(require,module,exports){ -var r; +module.exports = Sha384 -module.exports = function rand(len) { - if (!r) - r = new Rand(null); +}).call(this,require("buffer").Buffer) +},{"./hash":130,"./sha512":137,"buffer":47,"inherits":240}],137:[function(require,module,exports){ +(function (Buffer){ +var inherits = require('inherits') +var Hash = require('./hash') - return r.generate(len); -}; +var K = [ + 0x428a2f98, 0xd728ae22, 0x71374491, 0x23ef65cd, + 0xb5c0fbcf, 0xec4d3b2f, 0xe9b5dba5, 0x8189dbbc, + 0x3956c25b, 0xf348b538, 0x59f111f1, 0xb605d019, + 0x923f82a4, 0xaf194f9b, 0xab1c5ed5, 0xda6d8118, + 0xd807aa98, 0xa3030242, 0x12835b01, 0x45706fbe, + 0x243185be, 0x4ee4b28c, 0x550c7dc3, 0xd5ffb4e2, + 0x72be5d74, 0xf27b896f, 0x80deb1fe, 0x3b1696b1, + 0x9bdc06a7, 0x25c71235, 0xc19bf174, 0xcf692694, + 0xe49b69c1, 0x9ef14ad2, 0xefbe4786, 0x384f25e3, + 0x0fc19dc6, 0x8b8cd5b5, 0x240ca1cc, 0x77ac9c65, + 0x2de92c6f, 0x592b0275, 0x4a7484aa, 0x6ea6e483, + 0x5cb0a9dc, 0xbd41fbd4, 0x76f988da, 0x831153b5, + 0x983e5152, 0xee66dfab, 0xa831c66d, 0x2db43210, + 0xb00327c8, 0x98fb213f, 0xbf597fc7, 0xbeef0ee4, + 0xc6e00bf3, 0x3da88fc2, 0xd5a79147, 0x930aa725, + 0x06ca6351, 0xe003826f, 0x14292967, 0x0a0e6e70, + 0x27b70a85, 0x46d22ffc, 0x2e1b2138, 0x5c26c926, + 0x4d2c6dfc, 0x5ac42aed, 0x53380d13, 0x9d95b3df, + 0x650a7354, 0x8baf63de, 0x766a0abb, 0x3c77b2a8, + 0x81c2c92e, 0x47edaee6, 0x92722c85, 0x1482353b, + 0xa2bfe8a1, 0x4cf10364, 0xa81a664b, 0xbc423001, + 0xc24b8b70, 0xd0f89791, 0xc76c51a3, 0x0654be30, + 0xd192e819, 0xd6ef5218, 0xd6990624, 0x5565a910, + 0xf40e3585, 0x5771202a, 0x106aa070, 0x32bbd1b8, + 0x19a4c116, 0xb8d2d0c8, 0x1e376c08, 0x5141ab53, + 0x2748774c, 0xdf8eeb99, 0x34b0bcb5, 0xe19b48a8, + 0x391c0cb3, 0xc5c95a63, 0x4ed8aa4a, 0xe3418acb, + 0x5b9cca4f, 0x7763e373, 0x682e6ff3, 0xd6b2b8a3, + 0x748f82ee, 0x5defb2fc, 0x78a5636f, 0x43172f60, + 0x84c87814, 0xa1f0ab72, 0x8cc70208, 0x1a6439ec, + 0x90befffa, 0x23631e28, 0xa4506ceb, 0xde82bde9, + 0xbef9a3f7, 0xb2c67915, 0xc67178f2, 0xe372532b, + 0xca273ece, 0xea26619c, 0xd186b8c7, 0x21c0c207, + 0xeada7dd6, 0xcde0eb1e, 0xf57d4f7f, 0xee6ed178, + 0x06f067aa, 0x72176fba, 0x0a637dc5, 0xa2c898a6, + 0x113f9804, 0xbef90dae, 0x1b710b35, 0x131c471b, + 0x28db77f5, 0x23047d84, 0x32caab7b, 0x40c72493, + 0x3c9ebe0a, 0x15c9bebc, 0x431d67c4, 0x9c100d4c, + 0x4cc5d4be, 0xcb3e42b6, 0x597f299c, 0xfc657e2a, + 0x5fcb6fab, 0x3ad6faec, 0x6c44198c, 0x4a475817 +] -function Rand(rand) { - this.rand = rand; +var W = new Array(160) + +function Sha512 () { + this.init() + this._w = W + + Hash.call(this, 128, 112) } -module.exports.Rand = Rand; -Rand.prototype.generate = function generate(len) { - return this._rand(len); -}; +inherits(Sha512, Hash) -if (typeof window === 'object') { - if (window.crypto && window.crypto.getRandomValues) { - // Modern browsers - Rand.prototype._rand = function _rand(n) { - var arr = new Uint8Array(n); - window.crypto.getRandomValues(arr); - return arr; - }; - } else if (window.msCrypto && window.msCrypto.getRandomValues) { - // IE - Rand.prototype._rand = function _rand(n) { - var arr = new Uint8Array(n); - window.msCrypto.getRandomValues(arr); - return arr; - }; - } else { - // Old junk - Rand.prototype._rand = function() { - throw new Error('Not implemented yet'); - }; - } -} else { - // Node.js or Web worker - try { - var crypto = require('cry' + 'pto'); +Sha512.prototype.init = function () { + this._a = 0x6a09e667 | 0 + this._b = 0xbb67ae85 | 0 + this._c = 0x3c6ef372 | 0 + this._d = 0xa54ff53a | 0 + this._e = 0x510e527f | 0 + this._f = 0x9b05688c | 0 + this._g = 0x1f83d9ab | 0 + this._h = 0x5be0cd19 | 0 + + this._al = 0xf3bcc908 | 0 + this._bl = 0x84caa73b | 0 + this._cl = 0xfe94f82b | 0 + this._dl = 0x5f1d36f1 | 0 + this._el = 0xade682d1 | 0 + this._fl = 0x2b3e6c1f | 0 + this._gl = 0xfb41bd6b | 0 + this._hl = 0x137e2179 | 0 - Rand.prototype._rand = function _rand(n) { - return crypto.randomBytes(n); - }; - } catch (e) { - // Emulate crypto API using randy - Rand.prototype._rand = function _rand(n) { - var res = new Uint8Array(n); - for (var i = 0; i < res.length; i++) - res[i] = this.rand.getByte(); - return res; - }; - } + return this } -},{}],82:[function(require,module,exports){ -var hash = exports; - -hash.utils = require('./hash/utils'); -hash.common = require('./hash/common'); -hash.sha = require('./hash/sha'); -hash.ripemd = require('./hash/ripemd'); -hash.hmac = require('./hash/hmac'); +function Ch (x, y, z) { + return z ^ (x & (y ^ z)) +} -// Proxy hash functions to the main object -hash.sha1 = hash.sha.sha1; -hash.sha256 = hash.sha.sha256; -hash.sha224 = hash.sha.sha224; -hash.sha384 = hash.sha.sha384; -hash.sha512 = hash.sha.sha512; -hash.ripemd160 = hash.ripemd.ripemd160; +function Maj (x, y, z) { + return (x & y) | (z & (x | y)) +} -},{"./hash/common":83,"./hash/hmac":84,"./hash/ripemd":85,"./hash/sha":86,"./hash/utils":87}],83:[function(require,module,exports){ -var hash = require('../hash'); -var utils = hash.utils; -var assert = utils.assert; +function Sigma0 (x, xl) { + return (x >>> 28 | xl << 4) ^ (xl >>> 2 | x << 30) ^ (xl >>> 7 | x << 25) +} -function BlockHash() { - this.pending = null; - this.pendingTotal = 0; - this.blockSize = this.constructor.blockSize; - this.outSize = this.constructor.outSize; - this.hmacStrength = this.constructor.hmacStrength; - this.padLength = this.constructor.padLength / 8; - this.endian = 'big'; +function Sigma1 (x, xl) { + return (x >>> 14 | xl << 18) ^ (x >>> 18 | xl << 14) ^ (xl >>> 9 | x << 23) +} - this._delta8 = this.blockSize / 8; - this._delta32 = this.blockSize / 32; +function Gamma0 (x, xl) { + return (x >>> 1 | xl << 31) ^ (x >>> 8 | xl << 24) ^ (x >>> 7) } -exports.BlockHash = BlockHash; -BlockHash.prototype.update = function update(msg, enc) { - // Convert message to array, pad it, and join into 32bit blocks - msg = utils.toArray(msg, enc); - if (!this.pending) - this.pending = msg; - else - this.pending = this.pending.concat(msg); - this.pendingTotal += msg.length; +function Gamma0l (x, xl) { + return (x >>> 1 | xl << 31) ^ (x >>> 8 | xl << 24) ^ (x >>> 7 | xl << 25) +} - // Enough data, try updating - if (this.pending.length >= this._delta8) { - msg = this.pending; +function Gamma1 (x, xl) { + return (x >>> 19 | xl << 13) ^ (xl >>> 29 | x << 3) ^ (x >>> 6) +} - // Process pending data in blocks - var r = msg.length % this._delta8; - this.pending = msg.slice(msg.length - r, msg.length); - if (this.pending.length === 0) - this.pending = null; +function Gamma1l (x, xl) { + return (x >>> 19 | xl << 13) ^ (xl >>> 29 | x << 3) ^ (x >>> 6 | xl << 26) +} - msg = utils.join32(msg, 0, msg.length - r, this.endian); - for (var i = 0; i < msg.length; i += this._delta32) - this._update(msg, i, i + this._delta32); - } +Sha512.prototype._update = function (M) { + var W = this._w - return this; -}; + var a = this._a | 0 + var b = this._b | 0 + var c = this._c | 0 + var d = this._d | 0 + var e = this._e | 0 + var f = this._f | 0 + var g = this._g | 0 + var h = this._h | 0 -BlockHash.prototype.digest = function digest(enc) { - this.update(this._pad()); - assert(this.pending === null); + var al = this._al | 0 + var bl = this._bl | 0 + var cl = this._cl | 0 + var dl = this._dl | 0 + var el = this._el | 0 + var fl = this._fl | 0 + var gl = this._gl | 0 + var hl = this._hl | 0 - return this._digest(enc); -}; + var i = 0 + var j = 0 + var Wi, Wil + function calcW () { + var x = W[j - 15 * 2] + var xl = W[j - 15 * 2 + 1] + var gamma0 = Gamma0(x, xl) + var gamma0l = Gamma0l(xl, x) -BlockHash.prototype._pad = function pad() { - var len = this.pendingTotal; - var bytes = this._delta8; - var k = bytes - ((len + this.padLength) % bytes); - var res = new Array(k + this.padLength); - res[0] = 0x80; - for (var i = 1; i < k; i++) - res[i] = 0; + x = W[j - 2 * 2] + xl = W[j - 2 * 2 + 1] + var gamma1 = Gamma1(x, xl) + var gamma1l = Gamma1l(xl, x) - // Append length - len <<= 3; - if (this.endian === 'big') { - for (var t = 8; t < this.padLength; t++) - res[i++] = 0; + // W[i] = gamma0 + W[i - 7] + gamma1 + W[i - 16] + var Wi7 = W[j - 7 * 2] + var Wi7l = W[j - 7 * 2 + 1] - res[i++] = 0; - res[i++] = 0; - res[i++] = 0; - res[i++] = 0; - res[i++] = (len >>> 24) & 0xff; - res[i++] = (len >>> 16) & 0xff; - res[i++] = (len >>> 8) & 0xff; - res[i++] = len & 0xff; - } else { - res[i++] = len & 0xff; - res[i++] = (len >>> 8) & 0xff; - res[i++] = (len >>> 16) & 0xff; - res[i++] = (len >>> 24) & 0xff; - res[i++] = 0; - res[i++] = 0; - res[i++] = 0; - res[i++] = 0; + var Wi16 = W[j - 16 * 2] + var Wi16l = W[j - 16 * 2 + 1] - for (var t = 8; t < this.padLength; t++) - res[i++] = 0; + Wil = gamma0l + Wi7l + Wi = gamma0 + Wi7 + ((Wil >>> 0) < (gamma0l >>> 0) ? 1 : 0) + Wil = Wil + gamma1l + Wi = Wi + gamma1 + ((Wil >>> 0) < (gamma1l >>> 0) ? 1 : 0) + Wil = Wil + Wi16l + Wi = Wi + Wi16 + ((Wil >>> 0) < (Wi16l >>> 0) ? 1 : 0) } - return res; -}; - -},{"../hash":82}],84:[function(require,module,exports){ -var hmac = exports; + function loop () { + W[j] = Wi + W[j + 1] = Wil -var hash = require('../hash'); -var utils = hash.utils; -var assert = utils.assert; + var maj = Maj(a, b, c) + var majl = Maj(al, bl, cl) -function Hmac(hash, key, enc) { - if (!(this instanceof Hmac)) - return new Hmac(hash, key, enc); - this.Hash = hash; - this.blockSize = hash.blockSize / 8; - this.outSize = hash.outSize / 8; - this.inner = null; - this.outer = null; + var sigma0h = Sigma0(a, al) + var sigma0l = Sigma0(al, a) + var sigma1h = Sigma1(e, el) + var sigma1l = Sigma1(el, e) - this._init(utils.toArray(key, enc)); -} -module.exports = Hmac; + // t1 = h + sigma1 + ch + K[i] + W[i] + var Ki = K[j] + var Kil = K[j + 1] -Hmac.prototype._init = function init(key) { - // Shorten key, if needed - if (key.length > this.blockSize) - key = new this.Hash().update(key).digest(); - assert(key.length <= this.blockSize); + var ch = Ch(e, f, g) + var chl = Ch(el, fl, gl) - // Add padding to key - for (var i = key.length; i < this.blockSize; i++) - key.push(0); + var t1l = hl + sigma1l + var t1 = h + sigma1h + ((t1l >>> 0) < (hl >>> 0) ? 1 : 0) + t1l = t1l + chl + t1 = t1 + ch + ((t1l >>> 0) < (chl >>> 0) ? 1 : 0) + t1l = t1l + Kil + t1 = t1 + Ki + ((t1l >>> 0) < (Kil >>> 0) ? 1 : 0) + t1l = t1l + Wil + t1 = t1 + Wi + ((t1l >>> 0) < (Wil >>> 0) ? 1 : 0) - for (var i = 0; i < key.length; i++) - key[i] ^= 0x36; - this.inner = new this.Hash().update(key); - - // 0x36 ^ 0x5c = 0x6a - for (var i = 0; i < key.length; i++) - key[i] ^= 0x6a; - this.outer = new this.Hash().update(key); -}; + // t2 = sigma0 + maj + var t2l = sigma0l + majl + var t2 = sigma0h + maj + ((t2l >>> 0) < (sigma0l >>> 0) ? 1 : 0) -Hmac.prototype.update = function update(msg, enc) { - this.inner.update(msg, enc); - return this; -}; + h = g + hl = gl + g = f + gl = fl + f = e + fl = el + el = (dl + t1l) | 0 + e = (d + t1 + ((el >>> 0) < (dl >>> 0) ? 1 : 0)) | 0 + d = c + dl = cl + c = b + cl = bl + b = a + bl = al + al = (t1l + t2l) | 0 + a = (t1 + t2 + ((al >>> 0) < (t1l >>> 0) ? 1 : 0)) | 0 -Hmac.prototype.digest = function digest(enc) { - this.outer.update(this.inner.digest()); - return this.outer.digest(enc); -}; + i++ + j += 2 + } -},{"../hash":82}],85:[function(require,module,exports){ -var hash = require('../hash'); -var utils = hash.utils; + while (i < 16) { + Wi = M.readInt32BE(j * 4) + Wil = M.readInt32BE(j * 4 + 4) -var rotl32 = utils.rotl32; -var sum32 = utils.sum32; -var sum32_3 = utils.sum32_3; -var sum32_4 = utils.sum32_4; -var BlockHash = hash.common.BlockHash; + loop() + } -function RIPEMD160() { - if (!(this instanceof RIPEMD160)) - return new RIPEMD160(); + while (i < 80) { + calcW() + loop() + } - BlockHash.call(this); + this._al = (this._al + al) | 0 + this._bl = (this._bl + bl) | 0 + this._cl = (this._cl + cl) | 0 + this._dl = (this._dl + dl) | 0 + this._el = (this._el + el) | 0 + this._fl = (this._fl + fl) | 0 + this._gl = (this._gl + gl) | 0 + this._hl = (this._hl + hl) | 0 - this.h = [ 0x67452301, 0xefcdab89, 0x98badcfe, 0x10325476, 0xc3d2e1f0 ]; - this.endian = 'little'; + this._a = (this._a + a + ((this._al >>> 0) < (al >>> 0) ? 1 : 0)) | 0 + this._b = (this._b + b + ((this._bl >>> 0) < (bl >>> 0) ? 1 : 0)) | 0 + this._c = (this._c + c + ((this._cl >>> 0) < (cl >>> 0) ? 1 : 0)) | 0 + this._d = (this._d + d + ((this._dl >>> 0) < (dl >>> 0) ? 1 : 0)) | 0 + this._e = (this._e + e + ((this._el >>> 0) < (el >>> 0) ? 1 : 0)) | 0 + this._f = (this._f + f + ((this._fl >>> 0) < (fl >>> 0) ? 1 : 0)) | 0 + this._g = (this._g + g + ((this._gl >>> 0) < (gl >>> 0) ? 1 : 0)) | 0 + this._h = (this._h + h + ((this._hl >>> 0) < (hl >>> 0) ? 1 : 0)) | 0 } -utils.inherits(RIPEMD160, BlockHash); -exports.ripemd160 = RIPEMD160; -RIPEMD160.blockSize = 512; -RIPEMD160.outSize = 160; -RIPEMD160.hmacStrength = 192; -RIPEMD160.padLength = 64; +Sha512.prototype._hash = function () { + var H = new Buffer(64) -RIPEMD160.prototype._update = function update(msg, start) { - var A = this.h[0]; - var B = this.h[1]; - var C = this.h[2]; - var D = this.h[3]; - var E = this.h[4]; - var Ah = A; - var Bh = B; - var Ch = C; - var Dh = D; - var Eh = E; - for (var j = 0; j < 80; j++) { - var T = sum32( - rotl32( - sum32_4(A, f(j, B, C, D), msg[r[j] + start], K(j)), - s[j]), - E); - A = E; - E = D; - D = rotl32(C, 10); - C = B; - B = T; - T = sum32( - rotl32( - sum32_4(Ah, f(79 - j, Bh, Ch, Dh), msg[rh[j] + start], Kh(j)), - sh[j]), - Eh); - Ah = Eh; - Eh = Dh; - Dh = rotl32(Ch, 10); - Ch = Bh; - Bh = T; + function writeInt64BE (h, l, offset) { + H.writeInt32BE(h, offset) + H.writeInt32BE(l, offset + 4) } - T = sum32_3(this.h[1], C, Dh); - this.h[1] = sum32_3(this.h[2], D, Eh); - this.h[2] = sum32_3(this.h[3], E, Ah); - this.h[3] = sum32_3(this.h[4], A, Bh); - this.h[4] = sum32_3(this.h[0], B, Ch); - this.h[0] = T; -}; - -RIPEMD160.prototype._digest = function digest(enc) { - if (enc === 'hex') - return utils.toHex32(this.h, 'little'); - else - return utils.split32(this.h, 'little'); -}; -function f(j, x, y, z) { - if (j <= 15) - return x ^ y ^ z; - else if (j <= 31) - return (x & y) | ((~x) & z); - else if (j <= 47) - return (x | (~y)) ^ z; - else if (j <= 63) - return (x & z) | (y & (~z)); - else - return x ^ (y | (~z)); -} + writeInt64BE(this._a, this._al, 0) + writeInt64BE(this._b, this._bl, 8) + writeInt64BE(this._c, this._cl, 16) + writeInt64BE(this._d, this._dl, 24) + writeInt64BE(this._e, this._el, 32) + writeInt64BE(this._f, this._fl, 40) + writeInt64BE(this._g, this._gl, 48) + writeInt64BE(this._h, this._hl, 56) -function K(j) { - if (j <= 15) - return 0x00000000; - else if (j <= 31) - return 0x5a827999; - else if (j <= 47) - return 0x6ed9eba1; - else if (j <= 63) - return 0x8f1bbcdc; - else - return 0xa953fd4e; + return H } -function Kh(j) { - if (j <= 15) - return 0x50a28be6; - else if (j <= 31) - return 0x5c4dd124; - else if (j <= 47) - return 0x6d703ef3; - else if (j <= 63) - return 0x7a6d76e9; - else - return 0x00000000; -} +module.exports = Sha512 -var r = [ - 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, - 7, 4, 13, 1, 10, 6, 15, 3, 12, 0, 9, 5, 2, 14, 11, 8, - 3, 10, 14, 4, 9, 15, 8, 1, 2, 7, 0, 6, 13, 11, 5, 12, - 1, 9, 11, 10, 0, 8, 12, 4, 13, 3, 7, 15, 14, 5, 6, 2, - 4, 0, 5, 9, 7, 12, 2, 10, 14, 1, 3, 8, 11, 6, 15, 13, -]; +}).call(this,require("buffer").Buffer) +},{"./hash":130,"buffer":47,"inherits":240}],138:[function(require,module,exports){ +(function (Buffer){ +'use strict'; +var createHash = require('create-hash/browser'); +var inherits = require('inherits') -var rh = [ - 5, 14, 7, 0, 9, 2, 11, 4, 13, 6, 15, 8, 1, 10, 3, 12, - 6, 11, 3, 7, 0, 13, 5, 10, 14, 15, 8, 12, 4, 9, 1, 2, - 15, 5, 1, 3, 7, 14, 6, 9, 11, 8, 12, 2, 10, 0, 4, 13, - 8, 6, 4, 1, 3, 11, 15, 0, 5, 12, 2, 13, 9, 7, 10, 14, - 12, 15, 10, 4, 1, 5, 8, 7, 6, 2, 13, 14, 0, 3, 9, 11 -]; +var Transform = require('stream').Transform -var s = [ - 11, 14, 15, 12, 5, 8, 7, 9, 11, 13, 14, 15, 6, 7, 9, 8, - 7, 6, 8, 13, 11, 9, 7, 15, 7, 12, 15, 9, 11, 7, 13, 12, - 11, 13, 6, 7, 14, 9, 13, 15, 14, 8, 13, 6, 5, 12, 7, 5, - 11, 12, 14, 15, 14, 15, 9, 8, 9, 14, 5, 6, 8, 6, 5, 12, - 9, 15, 5, 11, 6, 8, 13, 12, 5, 12, 13, 14, 11, 8, 5, 6, -]; +var ZEROS = new Buffer(128) +ZEROS.fill(0) -var sh = [ - 8, 9, 9, 11, 13, 15, 15, 5, 7, 7, 8, 11, 14, 14, 12, 6, - 9, 13, 15, 7, 12, 8, 9, 11, 7, 7, 12, 7, 6, 15, 13, 11, - 9, 7, 15, 11, 8, 6, 6, 14, 12, 13, 5, 14, 13, 13, 7, 5, - 15, 5, 8, 11, 14, 14, 6, 14, 6, 9, 12, 9, 12, 5, 15, 8, - 8, 5, 12, 9, 12, 5, 14, 6, 8, 13, 6, 5, 15, 13, 11, 11 -]; +function Hmac(alg, key) { + Transform.call(this) + alg = alg.toLowerCase() + if (typeof key === 'string') { + key = new Buffer(key) + } -},{"../hash":82}],86:[function(require,module,exports){ -var hash = require('../hash'); -var utils = hash.utils; -var assert = utils.assert; + var blocksize = (alg === 'sha512' || alg === 'sha384') ? 128 : 64 -var rotr32 = utils.rotr32; -var rotl32 = utils.rotl32; -var sum32 = utils.sum32; -var sum32_4 = utils.sum32_4; -var sum32_5 = utils.sum32_5; -var rotr64_hi = utils.rotr64_hi; -var rotr64_lo = utils.rotr64_lo; -var shr64_hi = utils.shr64_hi; -var shr64_lo = utils.shr64_lo; -var sum64 = utils.sum64; -var sum64_hi = utils.sum64_hi; -var sum64_lo = utils.sum64_lo; -var sum64_4_hi = utils.sum64_4_hi; -var sum64_4_lo = utils.sum64_4_lo; -var sum64_5_hi = utils.sum64_5_hi; -var sum64_5_lo = utils.sum64_5_lo; -var BlockHash = hash.common.BlockHash; + this._alg = alg + this._key = key -var sha256_K = [ - 0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, - 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5, - 0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3, - 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174, - 0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc, - 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da, - 0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7, - 0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967, - 0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13, - 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85, - 0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3, - 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070, - 0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5, - 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3, - 0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208, - 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2 -]; + if (key.length > blocksize) { + key = createHash(alg).update(key).digest() -var sha512_K = [ - 0x428a2f98, 0xd728ae22, 0x71374491, 0x23ef65cd, - 0xb5c0fbcf, 0xec4d3b2f, 0xe9b5dba5, 0x8189dbbc, - 0x3956c25b, 0xf348b538, 0x59f111f1, 0xb605d019, - 0x923f82a4, 0xaf194f9b, 0xab1c5ed5, 0xda6d8118, - 0xd807aa98, 0xa3030242, 0x12835b01, 0x45706fbe, - 0x243185be, 0x4ee4b28c, 0x550c7dc3, 0xd5ffb4e2, - 0x72be5d74, 0xf27b896f, 0x80deb1fe, 0x3b1696b1, - 0x9bdc06a7, 0x25c71235, 0xc19bf174, 0xcf692694, - 0xe49b69c1, 0x9ef14ad2, 0xefbe4786, 0x384f25e3, - 0x0fc19dc6, 0x8b8cd5b5, 0x240ca1cc, 0x77ac9c65, - 0x2de92c6f, 0x592b0275, 0x4a7484aa, 0x6ea6e483, - 0x5cb0a9dc, 0xbd41fbd4, 0x76f988da, 0x831153b5, - 0x983e5152, 0xee66dfab, 0xa831c66d, 0x2db43210, - 0xb00327c8, 0x98fb213f, 0xbf597fc7, 0xbeef0ee4, - 0xc6e00bf3, 0x3da88fc2, 0xd5a79147, 0x930aa725, - 0x06ca6351, 0xe003826f, 0x14292967, 0x0a0e6e70, - 0x27b70a85, 0x46d22ffc, 0x2e1b2138, 0x5c26c926, - 0x4d2c6dfc, 0x5ac42aed, 0x53380d13, 0x9d95b3df, - 0x650a7354, 0x8baf63de, 0x766a0abb, 0x3c77b2a8, - 0x81c2c92e, 0x47edaee6, 0x92722c85, 0x1482353b, - 0xa2bfe8a1, 0x4cf10364, 0xa81a664b, 0xbc423001, - 0xc24b8b70, 0xd0f89791, 0xc76c51a3, 0x0654be30, - 0xd192e819, 0xd6ef5218, 0xd6990624, 0x5565a910, - 0xf40e3585, 0x5771202a, 0x106aa070, 0x32bbd1b8, - 0x19a4c116, 0xb8d2d0c8, 0x1e376c08, 0x5141ab53, - 0x2748774c, 0xdf8eeb99, 0x34b0bcb5, 0xe19b48a8, - 0x391c0cb3, 0xc5c95a63, 0x4ed8aa4a, 0xe3418acb, - 0x5b9cca4f, 0x7763e373, 0x682e6ff3, 0xd6b2b8a3, - 0x748f82ee, 0x5defb2fc, 0x78a5636f, 0x43172f60, - 0x84c87814, 0xa1f0ab72, 0x8cc70208, 0x1a6439ec, - 0x90befffa, 0x23631e28, 0xa4506ceb, 0xde82bde9, - 0xbef9a3f7, 0xb2c67915, 0xc67178f2, 0xe372532b, - 0xca273ece, 0xea26619c, 0xd186b8c7, 0x21c0c207, - 0xeada7dd6, 0xcde0eb1e, 0xf57d4f7f, 0xee6ed178, - 0x06f067aa, 0x72176fba, 0x0a637dc5, 0xa2c898a6, - 0x113f9804, 0xbef90dae, 0x1b710b35, 0x131c471b, - 0x28db77f5, 0x23047d84, 0x32caab7b, 0x40c72493, - 0x3c9ebe0a, 0x15c9bebc, 0x431d67c4, 0x9c100d4c, - 0x4cc5d4be, 0xcb3e42b6, 0x597f299c, 0xfc657e2a, - 0x5fcb6fab, 0x3ad6faec, 0x6c44198c, 0x4a475817 -]; + } else if (key.length < blocksize) { + key = Buffer.concat([key, ZEROS], blocksize) + } -var sha1_K = [ - 0x5A827999, 0x6ED9EBA1, - 0x8F1BBCDC, 0xCA62C1D6 -]; + var ipad = this._ipad = new Buffer(blocksize) + var opad = this._opad = new Buffer(blocksize) -function SHA256() { - if (!(this instanceof SHA256)) - return new SHA256(); + for (var i = 0; i < blocksize; i++) { + ipad[i] = key[i] ^ 0x36 + opad[i] = key[i] ^ 0x5C + } - BlockHash.call(this); - this.h = [ 0x6a09e667, 0xbb67ae85, 0x3c6ef372, 0xa54ff53a, - 0x510e527f, 0x9b05688c, 0x1f83d9ab, 0x5be0cd19 ]; - this.k = sha256_K; - this.W = new Array(64); + this._hash = createHash(alg).update(ipad) } -utils.inherits(SHA256, BlockHash); -exports.sha256 = SHA256; -SHA256.blockSize = 512; -SHA256.outSize = 256; -SHA256.hmacStrength = 192; -SHA256.padLength = 64; +inherits(Hmac, Transform) -SHA256.prototype._update = function _update(msg, start) { - var W = this.W; +Hmac.prototype.update = function (data, enc) { + this._hash.update(data, enc) - for (var i = 0; i < 16; i++) - W[i] = msg[start + i]; - for (; i < W.length; i++) - W[i] = sum32_4(g1_256(W[i - 2]), W[i - 7], g0_256(W[i - 15]), W[i - 16]); + return this +} - var a = this.h[0]; - var b = this.h[1]; - var c = this.h[2]; - var d = this.h[3]; - var e = this.h[4]; - var f = this.h[5]; - var g = this.h[6]; - var h = this.h[7]; +Hmac.prototype._transform = function (data, _, next) { + this._hash.update(data) - assert(this.k.length === W.length); - for (var i = 0; i < W.length; i++) { - var T1 = sum32_5(h, s1_256(e), ch32(e, f, g), this.k[i], W[i]); - var T2 = sum32(s0_256(a), maj32(a, b, c)); - h = g; - g = f; - f = e; - e = sum32(d, T1); - d = c; - c = b; - b = a; - a = sum32(T1, T2); - } + next() +} - this.h[0] = sum32(this.h[0], a); - this.h[1] = sum32(this.h[1], b); - this.h[2] = sum32(this.h[2], c); - this.h[3] = sum32(this.h[3], d); - this.h[4] = sum32(this.h[4], e); - this.h[5] = sum32(this.h[5], f); - this.h[6] = sum32(this.h[6], g); - this.h[7] = sum32(this.h[7], h); -}; +Hmac.prototype._flush = function (next) { + this.push(this.digest()) -SHA256.prototype._digest = function digest(enc) { - if (enc === 'hex') - return utils.toHex32(this.h, 'big'); - else - return utils.split32(this.h, 'big'); -}; + next() +} -function SHA224() { - if (!(this instanceof SHA224)) - return new SHA224(); +Hmac.prototype.digest = function (enc) { + var h = this._hash.digest() - SHA256.call(this); - this.h = [ 0xc1059ed8, 0x367cd507, 0x3070dd17, 0xf70e5939, - 0xffc00b31, 0x68581511, 0x64f98fa7, 0xbefa4fa4 ]; + return createHash(this._alg).update(this._opad).update(h).digest(enc) } -utils.inherits(SHA224, SHA256); -exports.sha224 = SHA224; -SHA224.blockSize = 512; -SHA224.outSize = 224; -SHA224.hmacStrength = 192; -SHA224.padLength = 64; +module.exports = function createHmac(alg, key) { + return new Hmac(alg, key) +} -SHA224.prototype._digest = function digest(enc) { - // Just truncate output - if (enc === 'hex') - return utils.toHex32(this.h.slice(0, 7), 'big'); - else - return utils.split32(this.h.slice(0, 7), 'big'); -}; +}).call(this,require("buffer").Buffer) +},{"buffer":47,"create-hash/browser":125,"inherits":240,"stream":210}],139:[function(require,module,exports){ +(function (Buffer){ +var generatePrime = require('./lib/generatePrime'); +var primes = require('./lib/primes'); -function SHA512() { - if (!(this instanceof SHA512)) - return new SHA512(); +var DH = require('./lib/dh'); - BlockHash.call(this); - this.h = [ 0x6a09e667, 0xf3bcc908, - 0xbb67ae85, 0x84caa73b, - 0x3c6ef372, 0xfe94f82b, - 0xa54ff53a, 0x5f1d36f1, - 0x510e527f, 0xade682d1, - 0x9b05688c, 0x2b3e6c1f, - 0x1f83d9ab, 0xfb41bd6b, - 0x5be0cd19, 0x137e2179 ]; - this.k = sha512_K; - this.W = new Array(160); -} -utils.inherits(SHA512, BlockHash); -exports.sha512 = SHA512; +function getDiffieHellman(mod) { + var prime = new Buffer(primes[mod].prime, 'hex'); + var gen = new Buffer(primes[mod].gen, 'hex'); -SHA512.blockSize = 1024; -SHA512.outSize = 512; -SHA512.hmacStrength = 192; -SHA512.padLength = 128; + return new DH(prime, gen); +} -SHA512.prototype._prepareBlock = function _prepareBlock(msg, start) { - var W = this.W; +function createDiffieHellman(prime, enc, generator, genc) { + if (Buffer.isBuffer(enc) || (typeof enc === 'string' && ['hex', 'binary', 'base64'].indexOf(enc) === -1)) { + genc = generator; + generator = enc; + enc = undefined; + } - // 32 x 32bit words - for (var i = 0; i < 32; i++) - W[i] = msg[start + i]; - for (; i < W.length; i += 2) { - var c0_hi = g1_512_hi(W[i - 4], W[i - 3]); // i - 2 - var c0_lo = g1_512_lo(W[i - 4], W[i - 3]); - var c1_hi = W[i - 14]; // i - 7 - var c1_lo = W[i - 13]; - var c2_hi = g0_512_hi(W[i - 30], W[i - 29]); // i - 15 - var c2_lo = g0_512_lo(W[i - 30], W[i - 29]); - var c3_hi = W[i - 32]; // i - 16 - var c3_lo = W[i - 31]; + enc = enc || 'binary'; + genc = genc || 'binary'; + generator = generator || new Buffer([2]); - W[i] = sum64_4_hi(c0_hi, c0_lo, - c1_hi, c1_lo, - c2_hi, c2_lo, - c3_hi, c3_lo); - W[i + 1] = sum64_4_lo(c0_hi, c0_lo, - c1_hi, c1_lo, - c2_hi, c2_lo, - c3_hi, c3_lo); + if (!Buffer.isBuffer(generator)) { + generator = new Buffer(generator, genc); } -}; -SHA512.prototype._update = function _update(msg, start) { - this._prepareBlock(msg, start); + if (typeof prime === 'number') { + return new DH(generatePrime(prime, generator), generator, true); + } - var W = this.W; + if (!Buffer.isBuffer(prime)) { + prime = new Buffer(prime, enc); + } - var ah = this.h[0]; - var al = this.h[1]; - var bh = this.h[2]; - var bl = this.h[3]; - var ch = this.h[4]; - var cl = this.h[5]; - var dh = this.h[6]; - var dl = this.h[7]; - var eh = this.h[8]; - var el = this.h[9]; - var fh = this.h[10]; - var fl = this.h[11]; - var gh = this.h[12]; - var gl = this.h[13]; - var hh = this.h[14]; - var hl = this.h[15]; + return new DH(prime, generator, true); +} - assert(this.k.length === W.length); - for (var i = 0; i < W.length; i += 2) { - var c0_hi = hh; - var c0_lo = hl; - var c1_hi = s1_512_hi(eh, el); - var c1_lo = s1_512_lo(eh, el); - var c2_hi = ch64_hi(eh, el, fh, fl, gh, gl); - var c2_lo = ch64_lo(eh, el, fh, fl, gh, gl); - var c3_hi = this.k[i]; - var c3_lo = this.k[i + 1]; - var c4_hi = W[i]; - var c4_lo = W[i + 1]; +exports.DiffieHellmanGroup = exports.createDiffieHellmanGroup = exports.getDiffieHellman = getDiffieHellman; +exports.createDiffieHellman = exports.DiffieHellman = createDiffieHellman; - var T1_hi = sum64_5_hi(c0_hi, c0_lo, - c1_hi, c1_lo, - c2_hi, c2_lo, - c3_hi, c3_lo, - c4_hi, c4_lo); - var T1_lo = sum64_5_lo(c0_hi, c0_lo, - c1_hi, c1_lo, - c2_hi, c2_lo, - c3_hi, c3_lo, - c4_hi, c4_lo); - - var c0_hi = s0_512_hi(ah, al); - var c0_lo = s0_512_lo(ah, al); - var c1_hi = maj64_hi(ah, al, bh, bl, ch, cl); - var c1_lo = maj64_lo(ah, al, bh, bl, ch, cl); - - var T2_hi = sum64_hi(c0_hi, c0_lo, c1_hi, c1_lo); - var T2_lo = sum64_lo(c0_hi, c0_lo, c1_hi, c1_lo); +}).call(this,require("buffer").Buffer) +},{"./lib/dh":140,"./lib/generatePrime":141,"./lib/primes":142,"buffer":47}],140:[function(require,module,exports){ +(function (Buffer){ +var BN = require('bn.js'); +var MillerRabin = require('miller-rabin'); +var millerRabin = new MillerRabin(); +var TWENTYFOUR = new BN(24); +var ELEVEN = new BN(11); +var TEN = new BN(10); +var THREE = new BN(3); +var SEVEN = new BN(7); +var primes = require('./generatePrime'); +var randomBytes = require('randombytes'); +module.exports = DH; - hh = gh; - hl = gl; +function setPublicKey(pub, enc) { + enc = enc || 'utf8'; + if (!Buffer.isBuffer(pub)) { + pub = new Buffer(pub, enc); + } + this._pub = new BN(pub); + return this; +} - gh = fh; - gl = fl; +function setPrivateKey(priv, enc) { + enc = enc || 'utf8'; + if (!Buffer.isBuffer(priv)) { + priv = new Buffer(priv, enc); + } + this._priv = new BN(priv); + return this; +} - fh = eh; - fl = el; +var primeCache = {}; +function checkPrime(prime, generator) { + var gen = generator.toString('hex'); + var hex = [gen, prime.toString(16)].join('_'); + if (hex in primeCache) { + return primeCache[hex]; + } + var error = 0; + + if (prime.isEven() || + !primes.simpleSieve || + !primes.fermatTest(prime) || + !millerRabin.test(prime)) { + //not a prime so +1 + error += 1; + + if (gen === '02' || gen === '05') { + // we'd be able to check the generator + // it would fail so +8 + error += 8; + } else { + //we wouldn't be able to test the generator + // so +4 + error += 4; + } + primeCache[hex] = error; + return error; + } + if (!millerRabin.test(prime.shrn(1))) { + //not a safe prime + error += 2; + } + var rem; + switch (gen) { + case '02': + if (prime.mod(TWENTYFOUR).cmp(ELEVEN)) { + // unsuidable generator + error += 8; + } + break; + case '05': + rem = prime.mod(TEN); + if (rem.cmp(THREE) && rem.cmp(SEVEN)) { + // prime mod 10 needs to equal 3 or 7 + error += 8; + } + break; + default: + error += 4; + } + primeCache[hex] = error; + return error; +} - eh = sum64_hi(dh, dl, T1_hi, T1_lo); - el = sum64_lo(dl, dl, T1_hi, T1_lo); +function defineError (self, error) { + try { + Object.defineProperty(self, 'verifyError', { + enumerable: true, + value: error, + writable: false + }); + } catch(e) { + self.verifyError = error; + } +} +function DH(prime, generator, malleable) { + this.setGenerator(generator); + this.__prime = new BN(prime); + this._prime = BN.mont(this.__prime); + this._primeLen = prime.length; + this._pub = void 0; + this._priv = void 0; + + if (malleable) { + this.setPublicKey = setPublicKey; + this.setPrivateKey = setPrivateKey; + defineError(this, checkPrime(this.__prime, generator)); + } else { + defineError(this, 8); + } +} - dh = ch; - dl = cl; +DH.prototype.generateKeys = function () { + if (!this._priv) { + this._priv = new BN(randomBytes(this._primeLen)); + } + this._pub = this._gen.toRed(this._prime).redPow(this._priv).fromRed(); + return this.getPublicKey(); +}; - ch = bh; - cl = bl; +DH.prototype.computeSecret = function (other) { + other = new BN(other); + other = other.toRed(this._prime); + var secret = other.redPow(this._priv).fromRed(); + var out = new Buffer(secret.toArray()); + var prime = this.getPrime(); + if (out.length < prime.length) { + var front = new Buffer(prime.length - out.length); + front.fill(0); + out = Buffer.concat([front, out]); + } + return out; +}; - bh = ah; - bl = al; +DH.prototype.getPublicKey = function getPublicKey(enc) { + return formatReturnValue(this._pub, enc); +}; - ah = sum64_hi(T1_hi, T1_lo, T2_hi, T2_lo); - al = sum64_lo(T1_hi, T1_lo, T2_hi, T2_lo); - } +DH.prototype.getPrivateKey = function getPrivateKey(enc) { + return formatReturnValue(this._priv, enc); +}; - sum64(this.h, 0, ah, al); - sum64(this.h, 2, bh, bl); - sum64(this.h, 4, ch, cl); - sum64(this.h, 6, dh, dl); - sum64(this.h, 8, eh, el); - sum64(this.h, 10, fh, fl); - sum64(this.h, 12, gh, gl); - sum64(this.h, 14, hh, hl); +DH.prototype.getPrime = function (enc) { + return formatReturnValue(this.__prime, enc); }; -SHA512.prototype._digest = function digest(enc) { - if (enc === 'hex') - return utils.toHex32(this.h, 'big'); - else - return utils.split32(this.h, 'big'); +DH.prototype.getGenerator = function (enc) { + return formatReturnValue(this._gen, enc); }; -function SHA384() { - if (!(this instanceof SHA384)) - return new SHA384(); +DH.prototype.setGenerator = function (gen, enc) { + enc = enc || 'utf8'; + if (!Buffer.isBuffer(gen)) { + gen = new Buffer(gen, enc); + } + this._gen = new BN(gen); + return this; +}; - SHA512.call(this); - this.h = [ 0xcbbb9d5d, 0xc1059ed8, - 0x629a292a, 0x367cd507, - 0x9159015a, 0x3070dd17, - 0x152fecd8, 0xf70e5939, - 0x67332667, 0xffc00b31, - 0x8eb44a87, 0x68581511, - 0xdb0c2e0d, 0x64f98fa7, - 0x47b5481d, 0xbefa4fa4 ]; +function formatReturnValue(bn, enc) { + var buf = new Buffer(bn.toArray()); + if (!enc) { + return buf; + } else { + return buf.toString(enc); + } } -utils.inherits(SHA384, SHA512); -exports.sha384 = SHA384; +}).call(this,require("buffer").Buffer) +},{"./generatePrime":141,"bn.js":217,"buffer":47,"miller-rabin":143,"randombytes":190}],141:[function(require,module,exports){ +var randomBytes = require('randombytes'); +module.exports = findPrime; +findPrime.simpleSieve = simpleSieve; +findPrime.fermatTest = fermatTest; +var BN = require('bn.js'); +var TWENTYFOUR = new BN(24); +var MillerRabin = require('miller-rabin'); +var millerRabin = new MillerRabin(); +var ONE = new BN(1); +var TWO = new BN(2); +var FIVE = new BN(5); +var SIXTEEN = new BN(16); +var EIGHT = new BN(8); +var TEN = new BN(10); +var THREE = new BN(3); +var SEVEN = new BN(7); +var ELEVEN = new BN(11); +var FOUR = new BN(4); +var TWELVE = new BN(12); +var primes = null; -SHA384.blockSize = 1024; -SHA384.outSize = 384; -SHA384.hmacStrength = 192; -SHA384.padLength = 128; +function _getPrimes() { + if (primes !== null) + return primes; -SHA384.prototype._digest = function digest(enc) { - if (enc === 'hex') - return utils.toHex32(this.h.slice(0, 12), 'big'); - else - return utils.split32(this.h.slice(0, 12), 'big'); -}; + var limit = 0x100000; + var res = []; + res[0] = 2; + for (var i = 1, k = 3; k < limit; k += 2) { + var sqrt = Math.ceil(Math.sqrt(k)); + for (var j = 0; j < i && res[j] <= sqrt; j++) + if (k % res[j] === 0) + break; -function SHA1() { - if (!(this instanceof SHA1)) - return new SHA1(); + if (i !== j && res[j] <= sqrt) + continue; - BlockHash.call(this); - this.h = [ 0x67452301, 0xefcdab89, 0x98badcfe, - 0x10325476, 0xc3d2e1f0 ]; - this.W = new Array(80); + res[i++] = k; + } + primes = res; + return res; } -utils.inherits(SHA1, BlockHash); -exports.sha1 = SHA1; - -SHA1.blockSize = 512; -SHA1.outSize = 160; -SHA1.hmacStrength = 80; -SHA1.padLength = 64; - -SHA1.prototype._update = function _update(msg, start) { - var W = this.W; +function simpleSieve(p) { + var primes = _getPrimes(); - for (var i = 0; i < 16; i++) - W[i] = msg[start + i]; + for (var i = 0; i < primes.length; i++) + if (p.modn(primes[i]) === 0) { + if (p.cmpn(primes[i]) === 0) { + return true; + } else { + return false; + } + } - for(; i < W.length; i++) - W[i] = rotl32(W[i - 3] ^ W[i - 8] ^ W[i - 14] ^ W[i - 16], 1); + return true; +} - var a = this.h[0]; - var b = this.h[1]; - var c = this.h[2]; - var d = this.h[3]; - var e = this.h[4]; +function fermatTest(p) { + var red = BN.mont(p); + return TWO.toRed(red).redPow(p.subn(1)).fromRed().cmpn(1) === 0; +} - for (var i = 0; i < W.length; i++) { - var s = ~~(i / 20); - var t = sum32_5(rotl32(a, 5), ft_1(s, b, c, d), e, W[i], sha1_K[s]); - e = d; - d = c; - c = rotl32(b, 30); - b = a; - a = t; +function findPrime(bits, gen) { + if (bits < 16) { + // this is what openssl does + if (gen === 2 || gen === 5) { + return new BN([0x8c, 0x7b]); + } else { + return new BN([0x8c, 0x27]); + } + } + gen = new BN(gen); + var runs, comp; + function generateRandom(bits) { + runs = -1; + var out = new BN(randomBytes(Math.ceil(bits / 8))); + while (out.bitLength() > bits) { + out.ishrn(1); + } + if (out.isEven()) { + out.iadd(ONE); + } + if (!out.testn(1)) { + out.iadd(TWO); + } + if (!gen.cmp(TWO)) { + while (out.mod(TWENTYFOUR).cmp(ELEVEN)) { + out.iadd(FOUR); + } + comp = { + major: [TWENTYFOUR], + minor: [TWELVE] + }; + } else if (!gen.cmp(FIVE)) { + rem = out.mod(TEN); + while (rem.cmp(THREE)) { + out.iadd(FOUR); + rem = out.mod(TEN); + } + comp = { + major: [FOUR, SIXTEEN], + minor: [TWO, EIGHT] + }; + } else { + comp = { + major: [FOUR], + minor: [TWO] + }; + } + return out; } + var num = generateRandom(bits); - this.h[0] = sum32(this.h[0], a); - this.h[1] = sum32(this.h[1], b); - this.h[2] = sum32(this.h[2], c); - this.h[3] = sum32(this.h[3], d); - this.h[4] = sum32(this.h[4], e); -}; + var n2 = num.shrn(1); -SHA1.prototype._digest = function digest(enc) { - if (enc === 'hex') - return utils.toHex32(this.h, 'big'); - else - return utils.split32(this.h, 'big'); -}; + while (true) { + while (num.bitLength() > bits) { + num = generateRandom(bits); + n2 = num.shrn(1); + } + runs++; + if (simpleSieve(n2) && simpleSieve(num) && + fermatTest(n2) && fermatTest(num) && + millerRabin.test(n2) && millerRabin.test(num)) { + return num; + } + num.iadd(comp.major[runs%comp.major.length]); + n2.iadd(comp.minor[runs%comp.minor.length]); + } -function ch32(x, y, z) { - return (x & y) ^ ((~x) & z); } - -function maj32(x, y, z) { - return (x & y) ^ (x & z) ^ (y & z); +},{"bn.js":217,"miller-rabin":143,"randombytes":190}],142:[function(require,module,exports){ +module.exports={ + "modp1": { + "gen": "02", + "prime": "ffffffffffffffffc90fdaa22168c234c4c6628b80dc1cd129024e088a67cc74020bbea63b139b22514a08798e3404ddef9519b3cd3a431b302b0a6df25f14374fe1356d6d51c245e485b576625e7ec6f44c42e9a63a3620ffffffffffffffff" + }, + "modp2": { + "gen": "02", + "prime": "ffffffffffffffffc90fdaa22168c234c4c6628b80dc1cd129024e088a67cc74020bbea63b139b22514a08798e3404ddef9519b3cd3a431b302b0a6df25f14374fe1356d6d51c245e485b576625e7ec6f44c42e9a637ed6b0bff5cb6f406b7edee386bfb5a899fa5ae9f24117c4b1fe649286651ece65381ffffffffffffffff" + }, + "modp5": { + "gen": "02", + "prime": "ffffffffffffffffc90fdaa22168c234c4c6628b80dc1cd129024e088a67cc74020bbea63b139b22514a08798e3404ddef9519b3cd3a431b302b0a6df25f14374fe1356d6d51c245e485b576625e7ec6f44c42e9a637ed6b0bff5cb6f406b7edee386bfb5a899fa5ae9f24117c4b1fe649286651ece45b3dc2007cb8a163bf0598da48361c55d39a69163fa8fd24cf5f83655d23dca3ad961c62f356208552bb9ed529077096966d670c354e4abc9804f1746c08ca237327ffffffffffffffff" + }, + "modp14": { + "gen": "02", + "prime": "ffffffffffffffffc90fdaa22168c234c4c6628b80dc1cd129024e088a67cc74020bbea63b139b22514a08798e3404ddef9519b3cd3a431b302b0a6df25f14374fe1356d6d51c245e485b576625e7ec6f44c42e9a637ed6b0bff5cb6f406b7edee386bfb5a899fa5ae9f24117c4b1fe649286651ece45b3dc2007cb8a163bf0598da48361c55d39a69163fa8fd24cf5f83655d23dca3ad961c62f356208552bb9ed529077096966d670c354e4abc9804f1746c08ca18217c32905e462e36ce3be39e772c180e86039b2783a2ec07a28fb5c55df06f4c52c9de2bcbf6955817183995497cea956ae515d2261898fa051015728e5a8aacaa68ffffffffffffffff" + }, + "modp15": { + "gen": "02", + "prime": "ffffffffffffffffc90fdaa22168c234c4c6628b80dc1cd129024e088a67cc74020bbea63b139b22514a08798e3404ddef9519b3cd3a431b302b0a6df25f14374fe1356d6d51c245e485b576625e7ec6f44c42e9a637ed6b0bff5cb6f406b7edee386bfb5a899fa5ae9f24117c4b1fe649286651ece45b3dc2007cb8a163bf0598da48361c55d39a69163fa8fd24cf5f83655d23dca3ad961c62f356208552bb9ed529077096966d670c354e4abc9804f1746c08ca18217c32905e462e36ce3be39e772c180e86039b2783a2ec07a28fb5c55df06f4c52c9de2bcbf6955817183995497cea956ae515d2261898fa051015728e5a8aaac42dad33170d04507a33a85521abdf1cba64ecfb850458dbef0a8aea71575d060c7db3970f85a6e1e4c7abf5ae8cdb0933d71e8c94e04a25619dcee3d2261ad2ee6bf12ffa06d98a0864d87602733ec86a64521f2b18177b200cbbe117577a615d6c770988c0bad946e208e24fa074e5ab3143db5bfce0fd108e4b82d120a93ad2caffffffffffffffff" + }, + "modp16": { + "gen": "02", + "prime": "ffffffffffffffffc90fdaa22168c234c4c6628b80dc1cd129024e088a67cc74020bbea63b139b22514a08798e3404ddef9519b3cd3a431b302b0a6df25f14374fe1356d6d51c245e485b576625e7ec6f44c42e9a637ed6b0bff5cb6f406b7edee386bfb5a899fa5ae9f24117c4b1fe649286651ece45b3dc2007cb8a163bf0598da48361c55d39a69163fa8fd24cf5f83655d23dca3ad961c62f356208552bb9ed529077096966d670c354e4abc9804f1746c08ca18217c32905e462e36ce3be39e772c180e86039b2783a2ec07a28fb5c55df06f4c52c9de2bcbf6955817183995497cea956ae515d2261898fa051015728e5a8aaac42dad33170d04507a33a85521abdf1cba64ecfb850458dbef0a8aea71575d060c7db3970f85a6e1e4c7abf5ae8cdb0933d71e8c94e04a25619dcee3d2261ad2ee6bf12ffa06d98a0864d87602733ec86a64521f2b18177b200cbbe117577a615d6c770988c0bad946e208e24fa074e5ab3143db5bfce0fd108e4b82d120a92108011a723c12a787e6d788719a10bdba5b2699c327186af4e23c1a946834b6150bda2583e9ca2ad44ce8dbbbc2db04de8ef92e8efc141fbecaa6287c59474e6bc05d99b2964fa090c3a2233ba186515be7ed1f612970cee2d7afb81bdd762170481cd0069127d5b05aa993b4ea988d8fddc186ffb7dc90a6c08f4df435c934063199ffffffffffffffff" + }, + "modp17": { + "gen": "02", + "prime": "ffffffffffffffffc90fdaa22168c234c4c6628b80dc1cd129024e088a67cc74020bbea63b139b22514a08798e3404ddef9519b3cd3a431b302b0a6df25f14374fe1356d6d51c245e485b576625e7ec6f44c42e9a637ed6b0bff5cb6f406b7edee386bfb5a899fa5ae9f24117c4b1fe649286651ece45b3dc2007cb8a163bf0598da48361c55d39a69163fa8fd24cf5f83655d23dca3ad961c62f356208552bb9ed529077096966d670c354e4abc9804f1746c08ca18217c32905e462e36ce3be39e772c180e86039b2783a2ec07a28fb5c55df06f4c52c9de2bcbf6955817183995497cea956ae515d2261898fa051015728e5a8aaac42dad33170d04507a33a85521abdf1cba64ecfb850458dbef0a8aea71575d060c7db3970f85a6e1e4c7abf5ae8cdb0933d71e8c94e04a25619dcee3d2261ad2ee6bf12ffa06d98a0864d87602733ec86a64521f2b18177b200cbbe117577a615d6c770988c0bad946e208e24fa074e5ab3143db5bfce0fd108e4b82d120a92108011a723c12a787e6d788719a10bdba5b2699c327186af4e23c1a946834b6150bda2583e9ca2ad44ce8dbbbc2db04de8ef92e8efc141fbecaa6287c59474e6bc05d99b2964fa090c3a2233ba186515be7ed1f612970cee2d7afb81bdd762170481cd0069127d5b05aa993b4ea988d8fddc186ffb7dc90a6c08f4df435c93402849236c3fab4d27c7026c1d4dcb2602646dec9751e763dba37bdf8ff9406ad9e530ee5db382f413001aeb06a53ed9027d831179727b0865a8918da3edbebcf9b14ed44ce6cbaced4bb1bdb7f1447e6cc254b332051512bd7af426fb8f401378cd2bf5983ca01c64b92ecf032ea15d1721d03f482d7ce6e74fef6d55e702f46980c82b5a84031900b1c9e59e7c97fbec7e8f323a97a7e36cc88be0f1d45b7ff585ac54bd407b22b4154aacc8f6d7ebf48e1d814cc5ed20f8037e0a79715eef29be32806a1d58bb7c5da76f550aa3d8a1fbff0eb19ccb1a313d55cda56c9ec2ef29632387fe8d76e3c0468043e8f663f4860ee12bf2d5b0b7474d6e694f91e6dcc4024ffffffffffffffff" + }, + "modp18": { + "gen": "02", + "prime": "ffffffffffffffffc90fdaa22168c234c4c6628b80dc1cd129024e088a67cc74020bbea63b139b22514a08798e3404ddef9519b3cd3a431b302b0a6df25f14374fe1356d6d51c245e485b576625e7ec6f44c42e9a637ed6b0bff5cb6f406b7edee386bfb5a899fa5ae9f24117c4b1fe649286651ece45b3dc2007cb8a163bf0598da48361c55d39a69163fa8fd24cf5f83655d23dca3ad961c62f356208552bb9ed529077096966d670c354e4abc9804f1746c08ca18217c32905e462e36ce3be39e772c180e86039b2783a2ec07a28fb5c55df06f4c52c9de2bcbf6955817183995497cea956ae515d2261898fa051015728e5a8aaac42dad33170d04507a33a85521abdf1cba64ecfb850458dbef0a8aea71575d060c7db3970f85a6e1e4c7abf5ae8cdb0933d71e8c94e04a25619dcee3d2261ad2ee6bf12ffa06d98a0864d87602733ec86a64521f2b18177b200cbbe117577a615d6c770988c0bad946e208e24fa074e5ab3143db5bfce0fd108e4b82d120a92108011a723c12a787e6d788719a10bdba5b2699c327186af4e23c1a946834b6150bda2583e9ca2ad44ce8dbbbc2db04de8ef92e8efc141fbecaa6287c59474e6bc05d99b2964fa090c3a2233ba186515be7ed1f612970cee2d7afb81bdd762170481cd0069127d5b05aa993b4ea988d8fddc186ffb7dc90a6c08f4df435c93402849236c3fab4d27c7026c1d4dcb2602646dec9751e763dba37bdf8ff9406ad9e530ee5db382f413001aeb06a53ed9027d831179727b0865a8918da3edbebcf9b14ed44ce6cbaced4bb1bdb7f1447e6cc254b332051512bd7af426fb8f401378cd2bf5983ca01c64b92ecf032ea15d1721d03f482d7ce6e74fef6d55e702f46980c82b5a84031900b1c9e59e7c97fbec7e8f323a97a7e36cc88be0f1d45b7ff585ac54bd407b22b4154aacc8f6d7ebf48e1d814cc5ed20f8037e0a79715eef29be32806a1d58bb7c5da76f550aa3d8a1fbff0eb19ccb1a313d55cda56c9ec2ef29632387fe8d76e3c0468043e8f663f4860ee12bf2d5b0b7474d6e694f91e6dbe115974a3926f12fee5e438777cb6a932df8cd8bec4d073b931ba3bc832b68d9dd300741fa7bf8afc47ed2576f6936ba424663aab639c5ae4f5683423b4742bf1c978238f16cbe39d652de3fdb8befc848ad922222e04a4037c0713eb57a81a23f0c73473fc646cea306b4bcbc8862f8385ddfa9d4b7fa2c087e879683303ed5bdd3a062b3cf5b3a278a66d2a13f83f44f82ddf310ee074ab6a364597e899a0255dc164f31cc50846851df9ab48195ded7ea1b1d510bd7ee74d73faf36bc31ecfa268359046f4eb879f924009438b481c6cd7889a002ed5ee382bc9190da6fc026e479558e4475677e9aa9e3050e2765694dfc81f56e880b96e7160c980dd98edd3dfffffffffffffffff" + } } +},{}],143:[function(require,module,exports){ +var bn = require('bn.js'); +var brorand = require('brorand'); -function p32(x, y, z) { - return x ^ y ^ z; +function MillerRabin(rand) { + this.rand = rand || new brorand.Rand(); } +module.exports = MillerRabin; -function s0_256(x) { - return rotr32(x, 2) ^ rotr32(x, 13) ^ rotr32(x, 22); -} +MillerRabin.create = function create(rand) { + return new MillerRabin(rand); +}; -function s1_256(x) { - return rotr32(x, 6) ^ rotr32(x, 11) ^ rotr32(x, 25); -} +MillerRabin.prototype._rand = function _rand(n) { + var len = n.bitLength(); + var buf = this.rand.generate(Math.ceil(len / 8)); -function g0_256(x) { - return rotr32(x, 7) ^ rotr32(x, 18) ^ (x >>> 3); -} + // Set low bits + buf[0] |= 3; -function g1_256(x) { - return rotr32(x, 17) ^ rotr32(x, 19) ^ (x >>> 10); -} + // Mask high bits + var mask = len & 0x7; + if (mask !== 0) + buf[buf.length - 1] >>= 7 - mask; -function ft_1(s, x, y, z) { - if (s === 0) - return ch32(x, y, z); - if (s === 1 || s === 3) - return p32(x, y, z); - if (s === 2) - return maj32(x, y, z); + return new bn(buf); } -function ch64_hi(xh, xl, yh, yl, zh, zl) { - var r = (xh & yh) ^ ((~xh) & zh); - if (r < 0) - r += 0x100000000; - return r; -} +MillerRabin.prototype.test = function test(n, k, cb) { + var len = n.bitLength(); + var red = bn.mont(n); + var rone = new bn(1).toRed(red); -function ch64_lo(xh, xl, yh, yl, zh, zl) { - var r = (xl & yl) ^ ((~xl) & zl); - if (r < 0) - r += 0x100000000; - return r; -} + if (!k) + k = Math.max(1, (len / 48) | 0); -function maj64_hi(xh, xl, yh, yl, zh, zl) { - var r = (xh & yh) ^ (xh & zh) ^ (yh & zh); - if (r < 0) - r += 0x100000000; - return r; -} + // Find d and s, (n - 1) = (2 ^ s) * d; + var n1 = n.subn(1); + var n2 = n1.subn(1); + for (var s = 0; !n1.testn(s); s++) {} + var d = n.shrn(s); -function maj64_lo(xh, xl, yh, yl, zh, zl) { - var r = (xl & yl) ^ (xl & zl) ^ (yl & zl); - if (r < 0) - r += 0x100000000; - return r; -} + var rn1 = n1.toRed(red); -function s0_512_hi(xh, xl) { - var c0_hi = rotr64_hi(xh, xl, 28); - var c1_hi = rotr64_hi(xl, xh, 2); // 34 - var c2_hi = rotr64_hi(xl, xh, 7); // 39 + var prime = true; + for (; k > 0; k--) { + var a = this._rand(n2); + if (cb) + cb(a); - var r = c0_hi ^ c1_hi ^ c2_hi; - if (r < 0) - r += 0x100000000; - return r; -} - -function s0_512_lo(xh, xl) { - var c0_lo = rotr64_lo(xh, xl, 28); - var c1_lo = rotr64_lo(xl, xh, 2); // 34 - var c2_lo = rotr64_lo(xl, xh, 7); // 39 - - var r = c0_lo ^ c1_lo ^ c2_lo; - if (r < 0) - r += 0x100000000; - return r; -} + var x = a.toRed(red).redPow(d); + if (x.cmp(rone) === 0 || x.cmp(rn1) === 0) + continue; -function s1_512_hi(xh, xl) { - var c0_hi = rotr64_hi(xh, xl, 14); - var c1_hi = rotr64_hi(xh, xl, 18); - var c2_hi = rotr64_hi(xl, xh, 9); // 41 + for (var i = 1; i < s; i++) { + x = x.redSqr(); - var r = c0_hi ^ c1_hi ^ c2_hi; - if (r < 0) - r += 0x100000000; - return r; -} + if (x.cmp(rone) === 0) + return false; + if (x.cmp(rn1) === 0) + break; + } -function s1_512_lo(xh, xl) { - var c0_lo = rotr64_lo(xh, xl, 14); - var c1_lo = rotr64_lo(xh, xl, 18); - var c2_lo = rotr64_lo(xl, xh, 9); // 41 + if (i === s) + return false; + } - var r = c0_lo ^ c1_lo ^ c2_lo; - if (r < 0) - r += 0x100000000; - return r; -} + return prime; +}; -function g0_512_hi(xh, xl) { - var c0_hi = rotr64_hi(xh, xl, 1); - var c1_hi = rotr64_hi(xh, xl, 8); - var c2_hi = shr64_hi(xh, xl, 7); +MillerRabin.prototype.getDivisor = function getDivisor(n, k) { + var len = n.bitLength(); + var red = bn.mont(n); + var rone = new bn(1).toRed(red); - var r = c0_hi ^ c1_hi ^ c2_hi; - if (r < 0) - r += 0x100000000; - return r; -} + if (!k) + k = Math.max(1, (len / 48) | 0); -function g0_512_lo(xh, xl) { - var c0_lo = rotr64_lo(xh, xl, 1); - var c1_lo = rotr64_lo(xh, xl, 8); - var c2_lo = shr64_lo(xh, xl, 7); + // Find d and s, (n - 1) = (2 ^ s) * d; + var n1 = n.subn(1); + var n2 = n1.subn(1); + for (var s = 0; !n1.testn(s); s++) {} + var d = n.shrn(s); - var r = c0_lo ^ c1_lo ^ c2_lo; - if (r < 0) - r += 0x100000000; - return r; -} + var rn1 = n1.toRed(red); -function g1_512_hi(xh, xl) { - var c0_hi = rotr64_hi(xh, xl, 19); - var c1_hi = rotr64_hi(xl, xh, 29); // 61 - var c2_hi = shr64_hi(xh, xl, 6); + for (; k > 0; k--) { + var a = this._rand(n2); - var r = c0_hi ^ c1_hi ^ c2_hi; - if (r < 0) - r += 0x100000000; - return r; -} + var g = n.gcd(a); + if (g.cmpn(1) !== 0) + return g; -function g1_512_lo(xh, xl) { - var c0_lo = rotr64_lo(xh, xl, 19); - var c1_lo = rotr64_lo(xl, xh, 29); // 61 - var c2_lo = shr64_lo(xh, xl, 6); + var x = a.toRed(red).redPow(d); + if (x.cmp(rone) === 0 || x.cmp(rn1) === 0) + continue; - var r = c0_lo ^ c1_lo ^ c2_lo; - if (r < 0) - r += 0x100000000; - return r; -} + for (var i = 1; i < s; i++) { + x = x.redSqr(); -},{"../hash":82}],87:[function(require,module,exports){ -var utils = exports; -var inherits = require('inherits'); + if (x.cmp(rone) === 0) + return x.fromRed().subn(1).gcd(n); + if (x.cmp(rn1) === 0) + break; + } -function toArray(msg, enc) { - if (Array.isArray(msg)) - return msg.slice(); - if (!msg) - return []; - var res = []; - if (typeof msg === 'string') { - if (!enc) { - for (var i = 0; i < msg.length; i++) { - var c = msg.charCodeAt(i); - var hi = c >> 8; - var lo = c & 0xff; - if (hi) - res.push(hi, lo); - else - res.push(lo); - } - } else if (enc === 'hex') { - msg = msg.replace(/[^a-z0-9]+/ig, ''); - if (msg.length % 2 !== 0) - msg = '0' + msg; - for (var i = 0; i < msg.length; i += 2) - res.push(parseInt(msg[i] + msg[i + 1], 16)); + if (i === s) { + x = x.redSqr(); + return x.fromRed().subn(1).gcd(n); } - } else { - for (var i = 0; i < msg.length; i++) - res[i] = msg[i] | 0; } - return res; -} -utils.toArray = toArray; -function toHex(msg) { - var res = ''; - for (var i = 0; i < msg.length; i++) - res += zero2(msg[i].toString(16)); - return res; -} -utils.toHex = toHex; + return false; +}; -function htonl(w) { - var res = (w >>> 24) | - ((w >>> 8) & 0xff00) | - ((w << 8) & 0xff0000) | - ((w & 0xff) << 24); - return res >>> 0; -} -utils.htonl = htonl; +},{"bn.js":217,"brorand":144}],144:[function(require,module,exports){ +var r; -function toHex32(msg, endian) { - var res = ''; - for (var i = 0; i < msg.length; i++) { - var w = msg[i]; - if (endian === 'little') - w = htonl(w); - res += zero8(w.toString(16)); - } - return res; -} -utils.toHex32 = toHex32; +module.exports = function rand(len) { + if (!r) + r = new Rand(null); -function zero2(word) { - if (word.length === 1) - return '0' + word; - else - return word; -} -utils.zero2 = zero2; + return r.generate(len); +}; -function zero8(word) { - if (word.length === 7) - return '0' + word; - else if (word.length === 6) - return '00' + word; - else if (word.length === 5) - return '000' + word; - else if (word.length === 4) - return '0000' + word; - else if (word.length === 3) - return '00000' + word; - else if (word.length === 2) - return '000000' + word; - else if (word.length === 1) - return '0000000' + word; - else - return word; +function Rand(rand) { + this.rand = rand; } -utils.zero8 = zero8; +module.exports.Rand = Rand; -function join32(msg, start, end, endian) { - var len = end - start; - assert(len % 4 === 0); - var res = new Array(len / 4); - for (var i = 0, k = start; i < res.length; i++, k += 4) { - var w; - if (endian === 'big') - w = (msg[k] << 24) | (msg[k + 1] << 16) | (msg[k + 2] << 8) | msg[k + 3]; - else - w = (msg[k + 3] << 24) | (msg[k + 2] << 16) | (msg[k + 1] << 8) | msg[k]; - res[i] = w >>> 0; - } - return res; -} -utils.join32 = join32; +Rand.prototype.generate = function generate(len) { + return this._rand(len); +}; -function split32(msg, endian) { - var res = new Array(msg.length * 4); - for (var i = 0, k = 0; i < msg.length; i++, k += 4) { - var m = msg[i]; - if (endian === 'big') { - res[k] = m >>> 24; - res[k + 1] = (m >>> 16) & 0xff; - res[k + 2] = (m >>> 8) & 0xff; - res[k + 3] = m & 0xff; - } else { - res[k + 3] = m >>> 24; - res[k + 2] = (m >>> 16) & 0xff; - res[k + 1] = (m >>> 8) & 0xff; - res[k] = m & 0xff; - } +if (typeof window === 'object') { + if (window.crypto && window.crypto.getRandomValues) { + // Modern browsers + Rand.prototype._rand = function _rand(n) { + var arr = new Uint8Array(n); + window.crypto.getRandomValues(arr); + return arr; + }; + } else if (window.msCrypto && window.msCrypto.getRandomValues) { + // IE + Rand.prototype._rand = function _rand(n) { + var arr = new Uint8Array(n); + window.msCrypto.getRandomValues(arr); + return arr; + }; + } else { + // Old junk + Rand.prototype._rand = function() { + throw new Error('Not implemented yet'); + }; } - return res; -} -utils.split32 = split32; +} else { + // Node.js or Web worker + try { + var crypto = require('cry' + 'pto'); -function rotr32(w, b) { - return (w >>> b) | (w << (32 - b)); + Rand.prototype._rand = function _rand(n) { + return crypto.randomBytes(n); + }; + } catch (e) { + // Emulate crypto API using randy + Rand.prototype._rand = function _rand(n) { + var res = new Uint8Array(n); + for (var i = 0; i < res.length; i++) + res[i] = this.rand.getByte(); + return res; + }; + } } -utils.rotr32 = rotr32; -function rotl32(w, b) { - return (w << b) | (w >>> (32 - b)); -} -utils.rotl32 = rotl32; +},{}],145:[function(require,module,exports){ +(function (Buffer){ +var createHmac = require('create-hmac') +var MAX_ALLOC = Math.pow(2, 30) - 1 // default in iojs -function sum32(a, b) { - return (a + b) >>> 0; -} -utils.sum32 = sum32; +exports.pbkdf2 = pbkdf2 +function pbkdf2 (password, salt, iterations, keylen, digest, callback) { + if (typeof digest === 'function') { + callback = digest + digest = undefined + } -function sum32_3(a, b, c) { - return (a + b + c) >>> 0; -} -utils.sum32_3 = sum32_3; + if (typeof callback !== 'function') { + throw new Error('No callback provided to pbkdf2') + } -function sum32_4(a, b, c, d) { - return (a + b + c + d) >>> 0; + var result = pbkdf2Sync(password, salt, iterations, keylen, digest) + setTimeout(function () { + callback(undefined, result) + }) } -utils.sum32_4 = sum32_4; -function sum32_5(a, b, c, d, e) { - return (a + b + c + d + e) >>> 0; -} -utils.sum32_5 = sum32_5; +exports.pbkdf2Sync = pbkdf2Sync +function pbkdf2Sync (password, salt, iterations, keylen, digest) { + if (typeof iterations !== 'number') { + throw new TypeError('Iterations not a number') + } -function assert(cond, msg) { - if (!cond) - throw new Error(msg || 'Assertion failed'); -} -utils.assert = assert; + if (iterations < 0) { + throw new TypeError('Bad iterations') + } -utils.inherits = inherits; + if (typeof keylen !== 'number') { + throw new TypeError('Key length not a number') + } -function sum64(buf, pos, ah, al) { - var bh = buf[pos]; - var bl = buf[pos + 1]; + if (keylen < 0 || keylen > MAX_ALLOC) { + throw new TypeError('Bad key length') + } - var lo = (al + bl) >>> 0; - var hi = (lo < al ? 1 : 0) + ah + bh; - buf[pos] = hi >>> 0; - buf[pos + 1] = lo; -} -exports.sum64 = sum64; + digest = digest || 'sha1' -function sum64_hi(ah, al, bh, bl) { - var lo = (al + bl) >>> 0; - var hi = (lo < al ? 1 : 0) + ah + bh; - return hi >>> 0; -}; -exports.sum64_hi = sum64_hi; + if (!Buffer.isBuffer(password)) password = new Buffer(password, 'binary') + if (!Buffer.isBuffer(salt)) salt = new Buffer(salt, 'binary') -function sum64_lo(ah, al, bh, bl) { - var lo = al + bl; - return lo >>> 0; -}; -exports.sum64_lo = sum64_lo; + var hLen + var l = 1 + var DK = new Buffer(keylen) + var block1 = new Buffer(salt.length + 4) + salt.copy(block1, 0, 0, salt.length) -function sum64_4_hi(ah, al, bh, bl, ch, cl, dh, dl) { - var carry = 0; - var lo = al; - lo = (lo + bl) >>> 0; - carry += lo < al ? 1 : 0; - lo = (lo + cl) >>> 0; - carry += lo < cl ? 1 : 0; - lo = (lo + dl) >>> 0; - carry += lo < dl ? 1 : 0; + var r + var T - var hi = ah + bh + ch + dh + carry; - return hi >>> 0; -}; -exports.sum64_4_hi = sum64_4_hi; + for (var i = 1; i <= l; i++) { + block1.writeUInt32BE(i, salt.length) + var U = createHmac(digest, password).update(block1).digest() -function sum64_4_lo(ah, al, bh, bl, ch, cl, dh, dl) { - var lo = al + bl + cl + dl; - return lo >>> 0; -}; -exports.sum64_4_lo = sum64_4_lo; + if (!hLen) { + hLen = U.length + T = new Buffer(hLen) + l = Math.ceil(keylen / hLen) + r = keylen - (l - 1) * hLen + } -function sum64_5_hi(ah, al, bh, bl, ch, cl, dh, dl, eh, el) { - var carry = 0; - var lo = al; - lo = (lo + bl) >>> 0; - carry += lo < al ? 1 : 0; - lo = (lo + cl) >>> 0; - carry += lo < cl ? 1 : 0; - lo = (lo + dl) >>> 0; - carry += lo < dl ? 1 : 0; - lo = (lo + el) >>> 0; - carry += lo < el ? 1 : 0; + U.copy(T, 0, 0, hLen) - var hi = ah + bh + ch + dh + eh + carry; - return hi >>> 0; -}; -exports.sum64_5_hi = sum64_5_hi; + for (var j = 1; j < iterations; j++) { + U = createHmac(digest, password).update(U).digest() -function sum64_5_lo(ah, al, bh, bl, ch, cl, dh, dl, eh, el) { - var lo = al + bl + cl + dl + el; + for (var k = 0; k < hLen; k++) { + T[k] ^= U[k] + } + } - return lo >>> 0; -}; -exports.sum64_5_lo = sum64_5_lo; + var destPos = (i - 1) * hLen + var len = (i === l ? r : hLen) + T.copy(DK, destPos, 0, len) + } -function rotr64_hi(ah, al, num) { - var r = (al << (32 - num)) | (ah >>> num); - return r >>> 0; -}; -exports.rotr64_hi = rotr64_hi; + return DK +} -function rotr64_lo(ah, al, num) { - var r = (ah << (32 - num)) | (al >>> num); - return r >>> 0; -}; -exports.rotr64_lo = rotr64_lo; +}).call(this,require("buffer").Buffer) +},{"buffer":47,"create-hmac":138}],146:[function(require,module,exports){ +exports.publicEncrypt = require('./publicEncrypt'); +exports.privateDecrypt = require('./privateDecrypt'); -function shr64_hi(ah, al, num) { - return ah >>> num; +exports.privateEncrypt = function privateEncrypt(key, buf) { + return exports.publicEncrypt(key, buf, true); }; -exports.shr64_hi = shr64_hi; -function shr64_lo(ah, al, num) { - var r = (ah << (32 - num)) | (al >>> num); - return r >>> 0; +exports.publicDecrypt = function publicDecrypt(key, buf) { + return exports.privateDecrypt(key, buf, true); }; -exports.shr64_lo = shr64_lo; - -},{"inherits":229}],88:[function(require,module,exports){ -module.exports={ - "name": "elliptic", - "version": "1.0.1", - "description": "EC cryptography", - "main": "lib/elliptic.js", - "scripts": { - "test": "mocha --reporter=spec test/*-test.js" - }, - "repository": { - "type": "git", - "url": "git@github.com:indutny/elliptic" - }, - "keywords": [ - "EC", - "Elliptic", - "curve", - "Cryptography" - ], - "author": { - "name": "Fedor Indutny", - "email": "fedor@indutny.com" - }, - "license": "MIT", - "bugs": { - "url": "https://github.com/indutny/elliptic/issues" - }, - "homepage": "https://github.com/indutny/elliptic", - "devDependencies": { - "browserify": "^3.44.2", - "mocha": "^1.18.2", - "uglify-js": "^2.4.13" - }, - "dependencies": { - "bn.js": "^1.0.0", - "brorand": "^1.0.1", - "hash.js": "^1.0.0", - "inherits": "^2.0.1" - }, - "gitHead": "17dc013761dd1efcfb868e2b06b0b897627b40be", - "_id": "elliptic@1.0.1", - "_shasum": "d180376b66a17d74995c837796362ac4d22aefe3", - "_from": "elliptic@>=1.0.0 <2.0.0", - "_npmVersion": "1.4.28", - "_npmUser": { - "name": "indutny", - "email": "fedor@indutny.com" - }, - "maintainers": [ - { - "name": "indutny", - "email": "fedor@indutny.com" - } - ], - "dist": { - "shasum": "d180376b66a17d74995c837796362ac4d22aefe3", - "tarball": "http://registry.npmjs.org/elliptic/-/elliptic-1.0.1.tgz" - }, - "directories": {}, - "_resolved": "https://registry.npmjs.org/elliptic/-/elliptic-1.0.1.tgz", - "readme": "ERROR: No README data found!" -} - -},{}],89:[function(require,module,exports){ +},{"./privateDecrypt":186,"./publicEncrypt":187}],147:[function(require,module,exports){ (function (Buffer){ - -module.exports = function evp(crypto, password, salt, keyLen) { - keyLen = keyLen/8; - var ki = 0; - var ii = 0; - var key = new Buffer(keyLen); - var addmd = 0; - var md, md_buf; - var i; - while (true) { - md = crypto.createHash('md5'); - if(addmd++ > 0) { - md.update(md_buf); - } - md.update(password); - md.update(salt); - md_buf = md.digest(); - i = 0; - if(keyLen > 0) { - while(true) { - if(keyLen === 0) { - break; - } - if(i === md_buf.length) { - break; - } - key[ki++] = md_buf[i++]; - keyLen--; - } - } - if(keyLen === 0) { - break; - } - } - for(i=0;i k || new bn(enc).cmp(key.modulus) >= 0) { + throw new Error('decryption error'); + } + var msg; + if (reverse) { + msg = withPublic(new bn(enc), key); + } else { + msg = crt(enc, key); + } + var zBuffer = new Buffer(k - msg.length); + zBuffer.fill(0); + msg = Buffer.concat([zBuffer, msg], k); + if (padding === 4) { + return oaep(key, msg); + } else if (padding === 1) { + return pkcs1(key, msg, reverse); + } else if (padding === 3) { + return msg; + } else { + throw new Error('unknown padding'); + } +}; -var RSAPublicKey = asn1.define('RSAPublicKey', function() { - this.seq().obj( - this.key('modulus').int(), - this.key('publicExponent').int() - ); -}); -exports.RSAPublicKey = RSAPublicKey; +function oaep(key, msg){ + var n = key.modulus; + var k = key.modulus.byteLength(); + var mLen = msg.length; + var iHash = createHash('sha1').update(new Buffer('')).digest(); + var hLen = iHash.length; + var hLen2 = 2 * hLen; + if (msg[0] !== 0) { + throw new Error('decryption error'); + } + var maskedSeed = msg.slice(1, hLen + 1); + var maskedDb = msg.slice(hLen + 1); + var seed = xor(maskedSeed, mgf(maskedDb, hLen)); + var db = xor(maskedDb, mgf(seed, k - hLen - 1)); + if (compare(iHash, db.slice(0, hLen))) { + throw new Error('decryption error'); + } + var i = hLen; + while (db[i] === 0) { + i++; + } + if (db[i++] !== 1) { + throw new Error('decryption error'); + } + return db.slice(i); +} -var PublicKey = rfc3280.SubjectPublicKeyInfo; -exports.PublicKey = PublicKey; -var ECPublicKey = asn1.define('ECPublicKey', function() { - this.seq().obj( - this.key('algorithm').seq().obj( - this.key('id').objid(), - this.key('curve').objid() - ), - this.key('subjectPrivateKey').bitstr() - ); -}); -exports.ECPublicKey = ECPublicKey; -var ECPrivateWrap = asn1.define('ECPrivateWrap', function() { - this.seq().obj( - this.key('version').int(), - this.key('algorithm').seq().obj( - this.key('id').objid(), - this.key('curve').objid() - ), - this.key('subjectPrivateKey').octstr() - ); -}); -exports.ECPrivateWrap = ECPrivateWrap; +function pkcs1(key, msg, reverse){ + var p1 = msg.slice(0, 2); + var i = 2; + var status = 0; + while (msg[i++] !== 0) { + if (i >= msg.length) { + status++; + break; + } + } + var ps = msg.slice(2, i - 1); + var p2 = msg.slice(i - 1, i); -var PrivateKeyInfo = asn1.define('PrivateKeyInfo', function() { - this.seq().obj( - this.key('version').int(), - this.key('algorithm').use(rfc3280.AlgorithmIdentifier), - this.key('subjectPrivateKey').octstr() - ); -}); -exports.PrivateKey = PrivateKeyInfo; -var EncryptedPrivateKeyInfo = asn1.define('EncryptedPrivateKeyInfo', function() { - this.seq().obj( - this.key('algorithm').seq().obj( - this.key('id').objid(), - this.key('decrypt').seq().obj( - this.key('kde').seq().obj( - this.key('id').objid(), - this.key('kdeparams').seq().obj( - this.key('salt').octstr(), - this.key('iters').int() - ) - ), - this.key('cipher').seq().obj( - this.key('algo').objid(), - this.key('iv').octstr() - ) - ) - ), - this.key('subjectPrivateKey').octstr() - ); -}); -var dsaParams = asn1.define('dsaParams', function() { - this.seq().obj( - this.key('algorithm').objid(), - this.key('parameters').seq().obj( - this.key('p').int(), - this.key('q').int(), - this.key('g').int() - ) - ); -}); -exports.EncryptedPrivateKey = EncryptedPrivateKeyInfo; -var DSAPublicKey = asn1.define('DSAPublicKey', function() { - this.seq().obj( - this.key('algorithm').use(dsaParams), - this.key('subjectPublicKey').bitstr() - ); -}); -exports.DSAPublicKey = DSAPublicKey; -var DSAPrivateWrap = asn1.define('DSAPrivateWrap', function() { - this.seq().obj( - this.key('version').int(), - this.key('algorithm').seq().obj( - this.key('id').objid(), - this.key('parameters').seq().obj( - this.key('p').int(), - this.key('q').int(), - this.key('g').int() - ) - ), - this.key('subjectPrivateKey').octstr() - ); -}); -exports.DSAPrivateWrap = DSAPrivateWrap; -var DSAPrivateKey = asn1.define('DSAPrivateKey', function() { - this.seq().obj( - this.key('version').int(), - this.key('p').int(), - this.key('q').int(), - this.key('g').int(), - this.key('pub_key').int(), - this.key('priv_key').int() - ); -}); -exports.DSAPrivateKey = DSAPrivateKey; + if ((p1.toString('hex') !== '0002' && !reverse) || (p1.toString('hex') !== '0001' && reverse)){ + status++; + } + if (ps.length < 8) { + status++; + } + if (status) { + throw new Error('decryption error'); + } + return msg.slice(i); +} +function compare(a, b){ + a = new Buffer(a); + b = new Buffer(b); + var dif = 0; + var len = a.length; + if (a.length !== b.length) { + dif++; + len = Math.min(a.length, b.length); + } + var i = -1; + while (++i < len) { + dif += (a[i] ^ b[i]); + } + return dif; +} +}).call(this,require("buffer").Buffer) +},{"./mgf":147,"./withPublic":188,"./xor":189,"bn.js":217,"browserify-rsa":148,"buffer":47,"create-hash":125,"parse-asn1":152}],187:[function(require,module,exports){ +(function (Buffer){ +var parseKeys = require('parse-asn1'); +var randomBytes = require('randombytes'); +var createHash = require('create-hash'); +var mgf = require('./mgf'); +var xor = require('./xor'); +var bn = require('bn.js'); +var withPublic = require('./withPublic'); +var crt = require('browserify-rsa'); -exports.DSAparam = asn1.define('DSAparam', function () { - this.int(); -}); -var ECPrivateKey = asn1.define('ECPrivateKey', function() { - this.seq().obj( - this.key('version').int(), - this.key('privateKey').octstr(), - this.key('parameters').optional().explicit(0).use(ECParameters), - this.key('publicKey').optional().explicit(1).bitstr() - ); -}); -exports.ECPrivateKey = ECPrivateKey; -var ECParameters = asn1.define('ECParameters', function() { - this.choice({ - namedCurve: this.objid() - }); -}); +var constants = { + RSA_PKCS1_OAEP_PADDING: 4, + RSA_PKCS1_PADDIN: 1, + RSA_NO_PADDING: 3 +}; -var ECPrivateKey2 = asn1.define('ECPrivateKey2', function() { - this.seq().obj( - this.key('version').int(), - this.key('privateKey').octstr(), - this.key('publicKey').seq().obj( - this.key('key').bitstr() - ) - ); -}); -exports.ECPrivateKey2 = ECPrivateKey2; +module.exports = function publicEncrypt(public_key, msg, reverse) { + var padding; + if (public_key.padding) { + padding = public_key.padding; + } else if (reverse) { + padding = 1; + } else { + padding = 4; + } + var key = parseKeys(public_key); + var paddedMsg; + if (padding === 4) { + paddedMsg = oaep(key, msg); + } else if (padding === 1) { + paddedMsg = pkcs1(key, msg, reverse); + } else if (padding === 3) { + paddedMsg = new bn(msg); + if (paddedMsg.cmp(key.modulus) >= 0) { + throw new Error('data too long for modulus'); + } + } else { + throw new Error('unknown padding'); + } + if (reverse) { + return crt(paddedMsg, key); + } else { + return withPublic(paddedMsg, key); + } +}; -exports.signature = asn1.define('signature', function() { - this.seq().obj( - this.key('r').int(), - this.key('s').int() - ); -}); -},{"asn1.js":95,"asn1.js-rfc3280":94}],92:[function(require,module,exports){ -(function (Buffer){ -var findProc = /Proc-Type: 4,ENCRYPTED\n\r?DEK-Info: AES-((?:128)|(?:192)|(?:256))-CBC,([0-9A-H]+)\n\r?\n\r?([0-9A-z\n\r\+\/\=]+)\n\r?/m; -var startRegex = /^-----BEGIN (.*)-----\n/; -var evp = require('./EVP_BytesToKey'); -module.exports = function (okey, password, crypto) { - var key = okey.toString(); - var match = key.match(findProc); - if (!match) { - return okey; +function oaep(key, msg){ + var k = key.modulus.byteLength(); + var mLen = msg.length; + var iHash = createHash('sha1').update(new Buffer('')).digest(); + var hLen = iHash.length; + var hLen2 = 2 * hLen; + if (mLen > k - hLen2 - 2) { + throw new Error('message too long'); } - var suite = 'aes' + match[1]; - var iv = new Buffer(match[2], 'hex'); - var cipherText = new Buffer(match[3].replace(/\n\r?/g, ''), 'base64'); - var cipherKey = evp(crypto, password, iv.slice(0,8), parseInt(match[1])); - var out = []; - var cipher = crypto.createDecipheriv(suite, cipherKey, iv); - out.push(cipher.update(cipherText)); - out.push(cipher.final()); - var decrypted = Buffer.concat(out).toString('base64'); - var tag = key.match(startRegex)[1]; - return '-----BEGIN ' + tag + "-----\n" + wrap(decrypted) + "\n" + '-----END ' + tag + "-----\n"; -}; -// http://stackoverflow.com/a/7033705 -function wrap(str) { - var chunks = []; - while (str) { - if (str.length < 64) { - chunks.push(str); - break; + var ps = new Buffer(k - mLen - hLen2 - 2); + ps.fill(0); + var dblen = k - hLen - 1; + var seed = randomBytes(hLen); + var maskedDb = xor(Buffer.concat([iHash, ps, new Buffer([1]), msg], dblen), mgf(seed, dblen)); + var maskedSeed = xor(seed, mgf(maskedDb, hLen)); + return new bn(Buffer.concat([new Buffer([0]), maskedSeed, maskedDb], k)); +} +function pkcs1(key, msg, reverse){ + var mLen = msg.length; + var k = key.modulus.byteLength(); + if (mLen > k - 11) { + throw new Error('message too long'); + } + var ps; + if (reverse) { + ps = new Buffer(k - mLen - 3); + ps.fill(0xff); + } else { + ps = nonZero(k - mLen - 3); + } + return new bn(Buffer.concat([new Buffer([0, reverse?1:2]), ps, new Buffer([0]), msg], k)); +} +function nonZero(len, crypto) { + var out = new Buffer(len); + var i = 0; + var cache = randomBytes(len*2); + var cur = 0; + var num; + while (i < len) { + if (cur === cache.length) { + cache = randomBytes(len*2); + cur = 0; } - else { - chunks.push(str.slice(0, 64)); - str = str.slice(64); + num = cache[cur++]; + if (num) { + out[i++] = num; } } - return chunks.join("\n"); + return out; } }).call(this,require("buffer").Buffer) -},{"./EVP_BytesToKey":89,"buffer":42}],93:[function(require,module,exports){ +},{"./mgf":147,"./withPublic":188,"./xor":189,"bn.js":217,"browserify-rsa":148,"buffer":47,"create-hash":125,"parse-asn1":152,"randombytes":190}],188:[function(require,module,exports){ (function (Buffer){ -var pemstrip = require('pemstrip'); -var asn1 = require('./asn1'); -var aesid = require('./aesid.json'); -var fixProc = require('./fixProc'); -module.exports = parseKeys; - -function parseKeys(buffer, crypto) { - var password; - if (typeof buffer === 'object' && !Buffer.isBuffer(buffer)) { - password = buffer.passphrase; - buffer = buffer.key; - } - if (typeof buffer === 'string') { - buffer = new Buffer(buffer); - } - if (password) { - buffer = fixProc(buffer, password, crypto); - } - var stripped = pemstrip.strip(buffer); - var type = stripped.tag; - var data = new Buffer(stripped.base64, 'base64'); - var subtype,ndata; - switch (type) { - case 'PUBLIC KEY': - ndata = asn1.PublicKey.decode(data, 'der'); - subtype = ndata.algorithm.algorithm.join('.'); - switch(subtype) { - case '1.2.840.113549.1.1.1': - return asn1.RSAPublicKey.decode(ndata.subjectPublicKey.data, 'der'); - case '1.2.840.10045.2.1': - return { - type: 'ec', - data: asn1.ECPublicKey.decode(data, 'der') - }; - case '1.2.840.10040.4.1': - ndata = asn1.DSAPublicKey.decode(data, 'der'); - ndata.algorithm.parameters.pub_key = asn1.DSAparam.decode(ndata.subjectPublicKey.data, 'der'); - return { - type: 'dsa', - data: ndata.algorithm.parameters - }; - default: throw new Error('unknown key id ' + subtype); - } - throw new Error('unknown key type ' + type); - case 'ENCRYPTED PRIVATE KEY': - data = asn1.EncryptedPrivateKey.decode(data, 'der'); - data = decrypt(crypto, data, password); - //falling through - case 'PRIVATE KEY': - ndata = asn1.PrivateKey.decode(data, 'der'); - subtype = ndata.algorithm.algorithm.join('.'); - switch(subtype) { - case '1.2.840.113549.1.1.1': - return asn1.RSAPrivateKey.decode(ndata.subjectPrivateKey, 'der'); - case '1.2.840.10045.2.1': - ndata = asn1.ECPrivateWrap.decode(data, 'der'); - return { - curve: ndata.algorithm.curve, - privateKey: asn1.ECPrivateKey.decode(ndata.subjectPrivateKey, 'der').privateKey - }; - case '1.2.840.10040.4.1': - ndata = asn1.DSAPrivateWrap.decode(data, 'der'); - ndata.algorithm.parameters.priv_key = asn1.DSAparam.decode(ndata.subjectPrivateKey, 'der'); - return { - type: 'dsa', - params: ndata.algorithm.parameters - }; - default: throw new Error('unknown key id ' + subtype); - } - throw new Error('unknown key type ' + type); - case 'RSA PUBLIC KEY': - return asn1.RSAPublicKey.decode(data, 'der'); - case 'RSA PRIVATE KEY': - return asn1.RSAPrivateKey.decode(data, 'der'); - case 'DSA PRIVATE KEY': - return { - type: 'dsa', - params: asn1.DSAPrivateKey.decode(data, 'der') - }; - case 'EC PRIVATE KEY': - data = asn1.ECPrivateKey.decode(data, 'der'); - return { - curve: data.parameters.value, - privateKey: data.privateKey - }; - default: throw new Error('unknown key type ' + type); - } -} -parseKeys.signature = asn1.signature; -function decrypt(crypto, data, password) { - var salt = data.algorithm.decrypt.kde.kdeparams.salt; - var iters = data.algorithm.decrypt.kde.kdeparams.iters; - var algo = aesid[data.algorithm.decrypt.cipher.algo.join('.')]; - var iv = data.algorithm.decrypt.cipher.iv; - var cipherText = data.subjectPrivateKey; - var keylen = parseInt(algo.split('-')[1], 10)/8; - var key = crypto.pbkdf2Sync(password, salt, iters, keylen); - var cipher = crypto.createDecipheriv(algo, key, iv); - var out = []; - out.push(cipher.update(cipherText)); - out.push(cipher.final()); - return Buffer.concat(out); +var bn = require('bn.js'); +function withPublic(paddedMsg, key) { + return new Buffer(paddedMsg + .toRed(bn.mont(key.modulus)) + .redPow(new bn(key.publicExponent)) + .fromRed() + .toArray()); } -}).call(this,require("buffer").Buffer) -},{"./aesid.json":90,"./asn1":91,"./fixProc":92,"buffer":42,"pemstrip":108}],94:[function(require,module,exports){ -try { - var asn1 = require('asn1.js'); -} catch (e) { - var asn1 = require('../' + '..'); -} - -var CRLReason = asn1.define('CRLReason', function() { - this.enum({ - 0: 'unspecified', - 1: 'keyCompromise', - 2: 'CACompromise', - 3: 'affiliationChanged', - 4: 'superseded', - 5: 'cessationOfOperation', - 6: 'certificateHold', - 8: 'removeFromCRL', - 9: 'privilegeWithdrawn', - 10: 'AACompromise' - }); -}); -exports.CRLReason = CRLReason; -var AlgorithmIdentifier = asn1.define('AlgorithmIdentifier', function() { - this.seq().obj( - this.key('algorithm').objid(), - this.key('parameters').optional().any() - ); -}); -exports.AlgorithmIdentifier = AlgorithmIdentifier; +module.exports = withPublic; +}).call(this,require("buffer").Buffer) +},{"bn.js":217,"buffer":47}],189:[function(require,module,exports){ +module.exports = function xor(a, b) { + var len = a.length; + var i = -1; + while (++i < len) { + a[i] ^= b[i]; + } + return a +}; +},{}],190:[function(require,module,exports){ +(function (process,global,Buffer){ +'use strict'; -var Certificate = asn1.define('Certificate', function() { - this.seq().obj( - this.key('tbsCertificate').use(TBSCertificate), - this.key('signatureAlgorithm').use(AlgorithmIdentifier), - this.key('signature').bitstr() - ); -}); -exports.Certificate = Certificate; +var crypto = global.crypto || global.msCrypto +if(crypto && crypto.getRandomValues) { + module.exports = randomBytes; +} else { + module.exports = oldBrowser; +} +function randomBytes(size, cb) { + var bytes = new Buffer(size); //in browserify, this is an extended Uint8Array + /* This will not work in older browsers. + * See https://developer.mozilla.org/en-US/docs/Web/API/window.crypto.getRandomValues + */ -var TBSCertificate = asn1.define('TBSCertificate', function() { - this.seq().obj( - this.key('version').def('v1').explicit(0).use(Version), - this.key('serialNumber').use(CertificateSerialNumber), - this.key('signature').use(AlgorithmIdentifier), - this.key('issuer').use(Name), - this.key('validity').use(Validity), - this.key('subject').use(Name), - this.key('subjectPublicKeyInfo').use(SubjectPublicKeyInfo), - - // TODO(indutny): validate that version is v2 or v3 - this.key('issuerUniqueID').optional().explicit(1).use(UniqueIdentifier), - this.key('subjectUniqueID').optional().explicit(2).use(UniqueIdentifier), - - // TODO(indutny): validate that version is v3 - this.key('extensions').optional().explicit(3).use(Extensions) - ); -}); -exports.TBSCertificate = TBSCertificate; + crypto.getRandomValues(bytes); + if (typeof cb === 'function') { + return process.nextTick(function () { + cb(null, bytes); + }); + } + return bytes; +} +function oldBrowser() { + throw new Error( + 'secure random number generation not supported by this browser\n'+ + 'use chrome, FireFox or Internet Explorer 11' + ) +} -var Version = asn1.define('Version', function() { - this.int({ - 0: 'v1', - 1: 'v2', - 2: 'v3' - }); -}); -exports.Version = Version; +}).call(this,require('_process'),typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {},require("buffer").Buffer) +},{"_process":194,"buffer":47}],191:[function(require,module,exports){ +// Copyright Joyent, Inc. and other Node contributors. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to permit +// persons to whom the Software is furnished to do so, subject to the +// following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +// USE OR OTHER DEALINGS IN THE SOFTWARE. -var CertificateSerialNumber = asn1.define('CertificateSerialNumber', - function() { - this.int(); -}); -exports.CertificateSerialNumber = CertificateSerialNumber; +function EventEmitter() { + this._events = this._events || {}; + this._maxListeners = this._maxListeners || undefined; +} +module.exports = EventEmitter; -var Validity = asn1.define('Validity', function() { - this.seq().obj( - this.key('notBefore').use(Time), - this.key('notAfter').use(Time) - ); -}); -exports.Validity = Validity; +// Backwards-compat with node 0.10.x +EventEmitter.EventEmitter = EventEmitter; -var Time = asn1.define('Time', function() { - this.choice({ - utcTime: this.utctime(), - genTime: this.gentime() - }); -}); -exports.Time = Time; +EventEmitter.prototype._events = undefined; +EventEmitter.prototype._maxListeners = undefined; -var UniqueIdentifier = asn1.define('UniqueIdentifier', function() { - this.bitstr(); -}); -exports.UniqueIdentifier = UniqueIdentifier; +// By default EventEmitters will print a warning if more than 10 listeners are +// added to it. This is a useful default which helps finding memory leaks. +EventEmitter.defaultMaxListeners = 10; -var SubjectPublicKeyInfo = asn1.define('SubjectPublicKeyInfo', function() { - this.seq().obj( - this.key('algorithm').use(AlgorithmIdentifier), - this.key('subjectPublicKey').bitstr() - ); -}); -exports.SubjectPublicKeyInfo = SubjectPublicKeyInfo; +// Obviously not all Emitters should be limited to 10. This function allows +// that to be increased. Set to zero for unlimited. +EventEmitter.prototype.setMaxListeners = function(n) { + if (!isNumber(n) || n < 0 || isNaN(n)) + throw TypeError('n must be a positive number'); + this._maxListeners = n; + return this; +}; -var Extensions = asn1.define('Extensions', function() { - this.seqof(Extension); -}); -exports.Extensions = Extensions; +EventEmitter.prototype.emit = function(type) { + var er, handler, len, args, i, listeners; -var Extension = asn1.define('Extension', function() { - this.seq().obj( - this.key('extnID').objid(), - this.key('critical').bool().def(false), - this.key('extnValue').octstr() - ); -}); -exports.Extension = Extension; + if (!this._events) + this._events = {}; -var Name = asn1.define('Name', function() { - this.choice({ - rdn: this.use(RDNSequence) - }); -}); -exports.Name = Name; + // If there is no 'error' event listener then throw. + if (type === 'error') { + if (!this._events.error || + (isObject(this._events.error) && !this._events.error.length)) { + er = arguments[1]; + if (er instanceof Error) { + throw er; // Unhandled 'error' event + } + throw TypeError('Uncaught, unspecified "error" event.'); + } + } -var RDNSequence = asn1.define('RDNSequence', function() { - this.seqof(RelativeDistinguishedName); -}); -exports.RDNSequence = RDNSequence; + handler = this._events[type]; -var RelativeDistinguishedName = asn1.define('RelativeDistinguishedName', - function() { - this.setof(AttributeTypeAndValue); -}); -exports.RelativeDistinguishedName = RelativeDistinguishedName; + if (isUndefined(handler)) + return false; -var AttributeTypeAndValue = asn1.define('AttributeTypeAndValue', function() { - this.seq().obj( - this.key('type').use(AttributeType), - this.key('value').use(AttributeValue) - ); -}); -exports.AttributeTypeAndValue = AttributeTypeAndValue; + if (isFunction(handler)) { + switch (arguments.length) { + // fast cases + case 1: + handler.call(this); + break; + case 2: + handler.call(this, arguments[1]); + break; + case 3: + handler.call(this, arguments[1], arguments[2]); + break; + // slower + default: + len = arguments.length; + args = new Array(len - 1); + for (i = 1; i < len; i++) + args[i - 1] = arguments[i]; + handler.apply(this, args); + } + } else if (isObject(handler)) { + len = arguments.length; + args = new Array(len - 1); + for (i = 1; i < len; i++) + args[i - 1] = arguments[i]; -var AttributeType = asn1.define('AttributeType', function() { - this.objid(); -}); -exports.AttributeType = AttributeType; + listeners = handler.slice(); + len = listeners.length; + for (i = 0; i < len; i++) + listeners[i].apply(this, args); + } -var AttributeValue = asn1.define('AttributeValue', function() { - this.any(); -}); -exports.AttributeValue = AttributeValue; + return true; +}; -},{"asn1.js":95}],95:[function(require,module,exports){ -var asn1 = exports; +EventEmitter.prototype.addListener = function(type, listener) { + var m; -asn1.bignum = require('bn.js'); + if (!isFunction(listener)) + throw TypeError('listener must be a function'); -asn1.define = require('./asn1/api').define; -asn1.base = require('./asn1/base'); -asn1.constants = require('./asn1/constants'); -asn1.decoders = require('./asn1/decoders'); -asn1.encoders = require('./asn1/encoders'); + if (!this._events) + this._events = {}; -},{"./asn1/api":96,"./asn1/base":98,"./asn1/constants":102,"./asn1/decoders":104,"./asn1/encoders":106,"bn.js":67}],96:[function(require,module,exports){ -var asn1 = require('../asn1'); -var inherits = require('inherits'); -var vm = require('vm'); + // To avoid recursion in the case that type === "newListener"! Before + // adding it to the listeners, first emit "newListener". + if (this._events.newListener) + this.emit('newListener', type, + isFunction(listener.listener) ? + listener.listener : listener); -var api = exports; + if (!this._events[type]) + // Optimize the case of one listener. Don't need the extra array object. + this._events[type] = listener; + else if (isObject(this._events[type])) + // If we've already got an array, just append. + this._events[type].push(listener); + else + // Adding the second element, need to change to array. + this._events[type] = [this._events[type], listener]; -api.define = function define(name, body) { - return new Entity(name, body); -}; - -function Entity(name, body) { - this.name = name; - this.body = body; - - this.decoders = {}; - this.encoders = {}; -}; - -Entity.prototype._createNamed = function createNamed(base) { - var named = vm.runInThisContext('(function ' + this.name + '(entity) {\n' + - ' this._initNamed(entity);\n' + - '})'); - inherits(named, base); - named.prototype._initNamed = function initnamed(entity) { - base.call(this, entity); - }; + // Check for listener leak + if (isObject(this._events[type]) && !this._events[type].warned) { + var m; + if (!isUndefined(this._maxListeners)) { + m = this._maxListeners; + } else { + m = EventEmitter.defaultMaxListeners; + } - return new named(this); -}; + if (m && m > 0 && this._events[type].length > m) { + this._events[type].warned = true; + console.error('(node) warning: possible EventEmitter memory ' + + 'leak detected. %d listeners added. ' + + 'Use emitter.setMaxListeners() to increase limit.', + this._events[type].length); + if (typeof console.trace === 'function') { + // not supported in IE 10 + console.trace(); + } + } + } -Entity.prototype._getDecoder = function _getDecoder(enc) { - // Lazily create decoder - if (!this.decoders.hasOwnProperty(enc)) - this.decoders[enc] = this._createNamed(asn1.decoders[enc]); - return this.decoders[enc]; + return this; }; -Entity.prototype.decode = function decode(data, enc, options) { - return this._getDecoder(enc).decode(data, options); -}; +EventEmitter.prototype.on = EventEmitter.prototype.addListener; -Entity.prototype._getEncoder = function _getEncoder(enc) { - // Lazily create encoder - if (!this.encoders.hasOwnProperty(enc)) - this.encoders[enc] = this._createNamed(asn1.encoders[enc]); - return this.encoders[enc]; -}; +EventEmitter.prototype.once = function(type, listener) { + if (!isFunction(listener)) + throw TypeError('listener must be a function'); -Entity.prototype.encode = function encode(data, enc, /* internal */ reporter) { - return this._getEncoder(enc).encode(data, reporter); -}; + var fired = false; -},{"../asn1":95,"inherits":229,"vm":205}],97:[function(require,module,exports){ -var inherits = require('inherits'); -var Reporter = require('../base').Reporter; -var Buffer = require('buffer').Buffer; + function g() { + this.removeListener(type, g); -function DecoderBuffer(base, options) { - Reporter.call(this, options); - if (!Buffer.isBuffer(base)) { - this.error('Input not Buffer'); - return; + if (!fired) { + fired = true; + listener.apply(this, arguments); + } } - this.base = base; - this.offset = 0; - this.length = base.length; -} -inherits(DecoderBuffer, Reporter); -exports.DecoderBuffer = DecoderBuffer; - -DecoderBuffer.prototype.save = function save() { - return { offset: this.offset }; -}; - -DecoderBuffer.prototype.restore = function restore(save) { - // Return skipped data - var res = new DecoderBuffer(this.base); - res.offset = save.offset; - res.length = this.offset; - - this.offset = save.offset; - - return res; -}; + g.listener = listener; + this.on(type, g); -DecoderBuffer.prototype.isEmpty = function isEmpty() { - return this.offset === this.length; + return this; }; -DecoderBuffer.prototype.readUInt8 = function readUInt8(fail) { - if (this.offset + 1 <= this.length) - return this.base.readUInt8(this.offset++, true); - else - return this.error(fail || 'DecoderBuffer overrun'); -} - -DecoderBuffer.prototype.skip = function skip(bytes, fail) { - if (!(this.offset + bytes <= this.length)) - return this.error(fail || 'DecoderBuffer overrun'); +// emits a 'removeListener' event iff the listener was removed +EventEmitter.prototype.removeListener = function(type, listener) { + var list, position, length, i; - var res = new DecoderBuffer(this.base); + if (!isFunction(listener)) + throw TypeError('listener must be a function'); - // Share reporter state - res._reporterState = this._reporterState; + if (!this._events || !this._events[type]) + return this; - res.offset = this.offset; - res.length = this.offset + bytes; - this.offset += bytes; - return res; -} + list = this._events[type]; + length = list.length; + position = -1; -DecoderBuffer.prototype.raw = function raw(save) { - return this.base.slice(save ? save.offset : this.offset, this.length); -} + if (list === listener || + (isFunction(list.listener) && list.listener === listener)) { + delete this._events[type]; + if (this._events.removeListener) + this.emit('removeListener', type, listener); -function EncoderBuffer(value, reporter) { - if (Array.isArray(value)) { - this.length = 0; - this.value = value.map(function(item) { - if (!(item instanceof EncoderBuffer)) - item = new EncoderBuffer(item, reporter); - this.length += item.length; - return item; - }, this); - } else if (typeof value === 'number') { - if (!(0 <= value && value <= 0xff)) - return reporter.error('non-byte EncoderBuffer value'); - this.value = value; - this.length = 1; - } else if (typeof value === 'string') { - this.value = value; - this.length = Buffer.byteLength(value); - } else if (Buffer.isBuffer(value)) { - this.value = value; - this.length = value.length; - } else { - return reporter.error('Unsupported type: ' + typeof value); - } -} -exports.EncoderBuffer = EncoderBuffer; + } else if (isObject(list)) { + for (i = length; i-- > 0;) { + if (list[i] === listener || + (list[i].listener && list[i].listener === listener)) { + position = i; + break; + } + } -EncoderBuffer.prototype.join = function join(out, offset) { - if (!out) - out = new Buffer(this.length); - if (!offset) - offset = 0; + if (position < 0) + return this; - if (this.length === 0) - return out; + if (list.length === 1) { + list.length = 0; + delete this._events[type]; + } else { + list.splice(position, 1); + } - if (Array.isArray(this.value)) { - this.value.forEach(function(item) { - item.join(out, offset); - offset += item.length; - }); - } else { - if (typeof this.value === 'number') - out[offset] = this.value; - else if (typeof this.value === 'string') - out.write(this.value, offset); - else if (Buffer.isBuffer(this.value)) - this.value.copy(out, offset); - offset += this.length; + if (this._events.removeListener) + this.emit('removeListener', type, listener); } - return out; + return this; }; -},{"../base":98,"buffer":42,"inherits":229}],98:[function(require,module,exports){ -var base = exports; - -base.Reporter = require('./reporter').Reporter; -base.DecoderBuffer = require('./buffer').DecoderBuffer; -base.EncoderBuffer = require('./buffer').EncoderBuffer; -base.Node = require('./node'); - -},{"./buffer":97,"./node":99,"./reporter":100}],99:[function(require,module,exports){ -var Reporter = require('../base').Reporter; -var EncoderBuffer = require('../base').EncoderBuffer; -var assert = require('minimalistic-assert'); - -// Supported tags -var tags = [ - 'seq', 'seqof', 'set', 'setof', 'octstr', 'bitstr', 'objid', 'bool', - 'gentime', 'utctime', 'null_', 'enum', 'int', 'ia5str' -]; - -// Public methods list -var methods = [ - 'key', 'obj', 'use', 'optional', 'explicit', 'implicit', 'def', 'choice', - 'any' -].concat(tags); - -// Overrided methods list -var overrided = [ - '_peekTag', '_decodeTag', '_use', - '_decodeStr', '_decodeObjid', '_decodeTime', - '_decodeNull', '_decodeInt', '_decodeBool', '_decodeList', - - '_encodeComposite', '_encodeStr', '_encodeObjid', '_encodeTime', - '_encodeNull', '_encodeInt', '_encodeBool' -]; +EventEmitter.prototype.removeAllListeners = function(type) { + var key, listeners; -function Node(enc, parent) { - var state = {}; - this._baseState = state; + if (!this._events) + return this; - state.enc = enc; + // not listening for removeListener, no need to emit + if (!this._events.removeListener) { + if (arguments.length === 0) + this._events = {}; + else if (this._events[type]) + delete this._events[type]; + return this; + } - state.parent = parent || null; - state.children = null; + // emit removeListener for all listeners on all events + if (arguments.length === 0) { + for (key in this._events) { + if (key === 'removeListener') continue; + this.removeAllListeners(key); + } + this.removeAllListeners('removeListener'); + this._events = {}; + return this; + } - // State - state.tag = null; - state.args = null; - state.reverseArgs = null; - state.choice = null; - state.optional = false; - state.any = false; - state.obj = false; - state.use = null; - state.useDecoder = null; - state.key = null; - state['default'] = null; - state.explicit = null; - state.implicit = null; + listeners = this._events[type]; - // Should create new instance on each method - if (!state.parent) { - state.children = []; - this._wrap(); + if (isFunction(listeners)) { + this.removeListener(type, listeners); + } else { + // LIFO order + while (listeners.length) + this.removeListener(type, listeners[listeners.length - 1]); } -} -module.exports = Node; - -var stateProps = [ - 'enc', 'parent', 'children', 'tag', 'args', 'reverseArgs', 'choice', - 'optional', 'any', 'obj', 'use', 'alteredUse', 'key', 'default', 'explicit', - 'implicit' -]; + delete this._events[type]; -Node.prototype.clone = function clone() { - var state = this._baseState; - var cstate = {}; - stateProps.forEach(function(prop) { - cstate[prop] = state[prop]; - }); - var res = new this.constructor(cstate.parent); - res._baseState = cstate; - return res; + return this; }; -Node.prototype._wrap = function wrap() { - var state = this._baseState; - methods.forEach(function(method) { - this[method] = function _wrappedMethod() { - var clone = new this.constructor(this); - state.children.push(clone); - return clone[method].apply(clone, arguments); - }; - }, this); +EventEmitter.prototype.listeners = function(type) { + var ret; + if (!this._events || !this._events[type]) + ret = []; + else if (isFunction(this._events[type])) + ret = [this._events[type]]; + else + ret = this._events[type].slice(); + return ret; }; -Node.prototype._init = function init(body) { - var state = this._baseState; +EventEmitter.listenerCount = function(emitter, type) { + var ret; + if (!emitter._events || !emitter._events[type]) + ret = 0; + else if (isFunction(emitter._events[type])) + ret = 1; + else + ret = emitter._events[type].length; + return ret; +}; - assert(state.parent === null); - body.call(this); +function isFunction(arg) { + return typeof arg === 'function'; +} - // Filter children - state.children = state.children.filter(function(child) { - return child._baseState.parent === this; - }, this); - assert.equal(state.children.length, 1, 'Root node can have only one child'); -}; +function isNumber(arg) { + return typeof arg === 'number'; +} -Node.prototype._useArgs = function useArgs(args) { - var state = this._baseState; +function isObject(arg) { + return typeof arg === 'object' && arg !== null; +} - // Filter children and args - var children = args.filter(function(arg) { - return arg instanceof this.constructor; - }, this); - args = args.filter(function(arg) { - return !(arg instanceof this.constructor); - }, this); +function isUndefined(arg) { + return arg === void 0; +} - if (children.length !== 0) { - assert(state.children === null); - state.children = children; +},{}],192:[function(require,module,exports){ +/** + * Determine if an object is Buffer + * + * Author: Feross Aboukhadijeh + * License: MIT + * + * `npm install is-buffer` + */ - // Replace parent to maintain backward link - children.forEach(function(child) { - child._baseState.parent = this; - }, this); - } - if (args.length !== 0) { - assert(state.args === null); - state.args = args; - state.reverseArgs = args.map(function(arg) { - if (typeof arg !== 'object' || arg.constructor !== Object) - return arg; +module.exports = function (obj) { + return !!(obj != null && + (obj._isBuffer || // For Safari 5-7 (missing Object.prototype.constructor) + (obj.constructor && + typeof obj.constructor.isBuffer === 'function' && + obj.constructor.isBuffer(obj)) + )) +} - var res = {}; - Object.keys(arg).forEach(function(key) { - if (key == (key | 0)) - key |= 0; - var value = arg[key]; - res[value] = key; - }); - return res; - }); - } +},{}],193:[function(require,module,exports){ +module.exports = Array.isArray || function (arr) { + return Object.prototype.toString.call(arr) == '[object Array]'; }; -// -// Overrided methods -// - -overrided.forEach(function(method) { - Node.prototype[method] = function _overrided() { - var state = this._baseState; - throw new Error(method + ' not implemented for encoding: ' + state.enc); - }; -}); +},{}],194:[function(require,module,exports){ +// shim for using process in browser -// -// Public methods -// +var process = module.exports = {}; -tags.forEach(function(tag) { - Node.prototype[tag] = function _tagMethod() { - var state = this._baseState; - var args = Array.prototype.slice.call(arguments); +process.nextTick = (function () { + var canSetImmediate = typeof window !== 'undefined' + && window.setImmediate; + var canMutationObserver = typeof window !== 'undefined' + && window.MutationObserver; + var canPost = typeof window !== 'undefined' + && window.postMessage && window.addEventListener + ; - assert(state.tag === null); - state.tag = tag; + if (canSetImmediate) { + return function (f) { return window.setImmediate(f) }; + } - this._useArgs(args); + var queue = []; - return this; - }; -}); + if (canMutationObserver) { + var hiddenDiv = document.createElement("div"); + var observer = new MutationObserver(function () { + var queueList = queue.slice(); + queue.length = 0; + queueList.forEach(function (fn) { + fn(); + }); + }); -Node.prototype.use = function use(item) { - var state = this._baseState; + observer.observe(hiddenDiv, { attributes: true }); - assert(state.use === null); - state.use = item; + return function nextTick(fn) { + if (!queue.length) { + hiddenDiv.setAttribute('yes', 'no'); + } + queue.push(fn); + }; + } - return this; -}; + if (canPost) { + window.addEventListener('message', function (ev) { + var source = ev.source; + if ((source === window || source === null) && ev.data === 'process-tick') { + ev.stopPropagation(); + if (queue.length > 0) { + var fn = queue.shift(); + fn(); + } + } + }, true); -Node.prototype.optional = function optional() { - var state = this._baseState; + return function nextTick(fn) { + queue.push(fn); + window.postMessage('process-tick', '*'); + }; + } - state.optional = true; + return function nextTick(fn) { + setTimeout(fn, 0); + }; +})(); - return this; -}; +process.title = 'browser'; +process.browser = true; +process.env = {}; +process.argv = []; -Node.prototype.def = function def(val) { - var state = this._baseState; +function noop() {} - assert(state['default'] === null); - state['default'] = val; - state.optional = true; +process.on = noop; +process.addListener = noop; +process.once = noop; +process.off = noop; +process.removeListener = noop; +process.removeAllListeners = noop; +process.emit = noop; - return this; +process.binding = function (name) { + throw new Error('process.binding is not supported'); }; -Node.prototype.explicit = function explicit(num) { - var state = this._baseState; - - assert(state.explicit === null && state.implicit === null); - state.explicit = num; - - return this; +// TODO(shtylman) +process.cwd = function () { return '/' }; +process.chdir = function (dir) { + throw new Error('process.chdir is not supported'); }; -Node.prototype.implicit = function implicit(num) { - var state = this._baseState; +},{}],195:[function(require,module,exports){ +(function (global){ +/*! http://mths.be/punycode v1.2.4 by @mathias */ +;(function(root) { - assert(state.explicit === null && state.implicit === null); - state.implicit = num; + /** Detect free variables */ + var freeExports = typeof exports == 'object' && exports; + var freeModule = typeof module == 'object' && module && + module.exports == freeExports && module; + var freeGlobal = typeof global == 'object' && global; + if (freeGlobal.global === freeGlobal || freeGlobal.window === freeGlobal) { + root = freeGlobal; + } - return this; -}; + /** + * The `punycode` object. + * @name punycode + * @type Object + */ + var punycode, -Node.prototype.obj = function obj() { - var state = this._baseState; - var args = Array.prototype.slice.call(arguments); + /** Highest positive signed 32-bit float value */ + maxInt = 2147483647, // aka. 0x7FFFFFFF or 2^31-1 - state.obj = true; + /** Bootstring parameters */ + base = 36, + tMin = 1, + tMax = 26, + skew = 38, + damp = 700, + initialBias = 72, + initialN = 128, // 0x80 + delimiter = '-', // '\x2D' - if (args.length !== 0) - this._useArgs(args); + /** Regular expressions */ + regexPunycode = /^xn--/, + regexNonASCII = /[^ -~]/, // unprintable ASCII chars + non-ASCII chars + regexSeparators = /\x2E|\u3002|\uFF0E|\uFF61/g, // RFC 3490 separators - return this; -}; + /** Error messages */ + errors = { + 'overflow': 'Overflow: input needs wider integers to process', + 'not-basic': 'Illegal input >= 0x80 (not a basic code point)', + 'invalid-input': 'Invalid input' + }, -Node.prototype.key = function key(newKey) { - var state = this._baseState; + /** Convenience shortcuts */ + baseMinusTMin = base - tMin, + floor = Math.floor, + stringFromCharCode = String.fromCharCode, - assert(state.key === null); - state.key = newKey; + /** Temporary variable */ + key; - return this; -}; + /*--------------------------------------------------------------------------*/ -Node.prototype.any = function any() { - var state = this._baseState; + /** + * A generic error utility function. + * @private + * @param {String} type The error type. + * @returns {Error} Throws a `RangeError` with the applicable error message. + */ + function error(type) { + throw RangeError(errors[type]); + } - state.any = true; + /** + * A generic `Array#map` utility function. + * @private + * @param {Array} array The array to iterate over. + * @param {Function} callback The function that gets called for every array + * item. + * @returns {Array} A new array of values returned by the callback function. + */ + function map(array, fn) { + var length = array.length; + while (length--) { + array[length] = fn(array[length]); + } + return array; + } - return this; -}; + /** + * A simple `Array#map`-like wrapper to work with domain name strings. + * @private + * @param {String} domain The domain name. + * @param {Function} callback The function that gets called for every + * character. + * @returns {Array} A new string of characters returned by the callback + * function. + */ + function mapDomain(string, fn) { + return map(string.split(regexSeparators), fn).join('.'); + } -Node.prototype.choice = function choice(obj) { - var state = this._baseState; + /** + * Creates an array containing the numeric code points of each Unicode + * character in the string. While JavaScript uses UCS-2 internally, + * this function will convert a pair of surrogate halves (each of which + * UCS-2 exposes as separate characters) into a single code point, + * matching UTF-16. + * @see `punycode.ucs2.encode` + * @see + * @memberOf punycode.ucs2 + * @name decode + * @param {String} string The Unicode input string (UCS-2). + * @returns {Array} The new array of code points. + */ + function ucs2decode(string) { + var output = [], + counter = 0, + length = string.length, + value, + extra; + while (counter < length) { + value = string.charCodeAt(counter++); + if (value >= 0xD800 && value <= 0xDBFF && counter < length) { + // high surrogate, and there is a next character + extra = string.charCodeAt(counter++); + if ((extra & 0xFC00) == 0xDC00) { // low surrogate + output.push(((value & 0x3FF) << 10) + (extra & 0x3FF) + 0x10000); + } else { + // unmatched surrogate; only append this code unit, in case the next + // code unit is the high surrogate of a surrogate pair + output.push(value); + counter--; + } + } else { + output.push(value); + } + } + return output; + } - assert(state.choice === null); - state.choice = obj; - this._useArgs(Object.keys(obj).map(function(key) { - return obj[key]; - })); + /** + * Creates a string based on an array of numeric code points. + * @see `punycode.ucs2.decode` + * @memberOf punycode.ucs2 + * @name encode + * @param {Array} codePoints The array of numeric code points. + * @returns {String} The new Unicode string (UCS-2). + */ + function ucs2encode(array) { + return map(array, function(value) { + var output = ''; + if (value > 0xFFFF) { + value -= 0x10000; + output += stringFromCharCode(value >>> 10 & 0x3FF | 0xD800); + value = 0xDC00 | value & 0x3FF; + } + output += stringFromCharCode(value); + return output; + }).join(''); + } - return this; -}; + /** + * Converts a basic code point into a digit/integer. + * @see `digitToBasic()` + * @private + * @param {Number} codePoint The basic numeric code point value. + * @returns {Number} The numeric value of a basic code point (for use in + * representing integers) in the range `0` to `base - 1`, or `base` if + * the code point does not represent a value. + */ + function basicToDigit(codePoint) { + if (codePoint - 48 < 10) { + return codePoint - 22; + } + if (codePoint - 65 < 26) { + return codePoint - 65; + } + if (codePoint - 97 < 26) { + return codePoint - 97; + } + return base; + } -// -// Decoding -// + /** + * Converts a digit/integer into a basic code point. + * @see `basicToDigit()` + * @private + * @param {Number} digit The numeric value of a basic code point. + * @returns {Number} The basic code point whose value (when used for + * representing integers) is `digit`, which needs to be in the range + * `0` to `base - 1`. If `flag` is non-zero, the uppercase form is + * used; else, the lowercase form is used. The behavior is undefined + * if `flag` is non-zero and `digit` has no uppercase form. + */ + function digitToBasic(digit, flag) { + // 0..25 map to ASCII a..z or A..Z + // 26..35 map to ASCII 0..9 + return digit + 22 + 75 * (digit < 26) - ((flag != 0) << 5); + } -Node.prototype._decode = function decode(input) { - var state = this._baseState; + /** + * Bias adaptation function as per section 3.4 of RFC 3492. + * http://tools.ietf.org/html/rfc3492#section-3.4 + * @private + */ + function adapt(delta, numPoints, firstTime) { + var k = 0; + delta = firstTime ? floor(delta / damp) : delta >> 1; + delta += floor(delta / numPoints); + for (/* no initialization */; delta > baseMinusTMin * tMax >> 1; k += base) { + delta = floor(delta / baseMinusTMin); + } + return floor(k + (baseMinusTMin + 1) * delta / (delta + skew)); + } - // Decode root node - if (state.parent === null) - return input.wrapResult(state.children[0]._decode(input)); + /** + * Converts a Punycode string of ASCII-only symbols to a string of Unicode + * symbols. + * @memberOf punycode + * @param {String} input The Punycode string of ASCII-only symbols. + * @returns {String} The resulting string of Unicode symbols. + */ + function decode(input) { + // Don't use UCS-2 + var output = [], + inputLength = input.length, + out, + i = 0, + n = initialN, + bias = initialBias, + basic, + j, + index, + oldi, + w, + k, + digit, + t, + /** Cached calculation results */ + baseMinusT; - var result = state['default']; - var present = true; + // Handle the basic code points: let `basic` be the number of input code + // points before the last delimiter, or `0` if there is none, then copy + // the first basic code points to the output. - var prevKey; - if (state.key !== null) - prevKey = input.enterKey(state.key); + basic = input.lastIndexOf(delimiter); + if (basic < 0) { + basic = 0; + } - // Check if tag is there - if (state.optional) { - present = this._peekTag( - input, - state.explicit !== null ? state.explicit : - state.implicit !== null ? state.implicit : - state.tag || 0 - ); - if (input.isError(present)) - return present; - } + for (j = 0; j < basic; ++j) { + // if it's not a basic code point + if (input.charCodeAt(j) >= 0x80) { + error('not-basic'); + } + output.push(input.charCodeAt(j)); + } - // Push object on stack - var prevObj; - if (state.obj && present) - prevObj = input.enterObject(); + // Main decoding loop: start just after the last delimiter if any basic code + // points were copied; start at the beginning otherwise. - if (present) { - // Unwrap explicit values - if (state.explicit !== null) { - var explicit = this._decodeTag(input, state.explicit); - if (input.isError(explicit)) - return explicit; - input = explicit; - } + for (index = basic > 0 ? basic + 1 : 0; index < inputLength; /* no final expression */) { - // Unwrap implicit and normal values - if (state.use === null && state.choice === null) { - if (state.any) - var save = input.save(); - var body = this._decodeTag( - input, - state.implicit !== null ? state.implicit : state.tag, - state.any - ); - if (input.isError(body)) - return body; + // `index` is the index of the next character to be consumed. + // Decode a generalized variable-length integer into `delta`, + // which gets added to `i`. The overflow checking is easier + // if we increase `i` as we go, then subtract off its starting + // value at the end to obtain `delta`. + for (oldi = i, w = 1, k = base; /* no condition */; k += base) { - if (state.any) - result = input.raw(save); - else - input = body; - } + if (index >= inputLength) { + error('invalid-input'); + } - // Select proper method for tag - if (state.any) - result = result; - else if (state.choice === null) - result = this._decodeGeneric(state.tag, input); - else - result = this._decodeChoice(input); + digit = basicToDigit(input.charCodeAt(index++)); - if (input.isError(result)) - return result; + if (digit >= base || digit > floor((maxInt - i) / w)) { + error('overflow'); + } - // Decode children - if (!state.any && state.choice === null && state.children !== null) { - var fail = state.children.some(function decodeChildren(child) { - // NOTE: We are ignoring errors here, to let parser continue with other - // parts of encoded data - child._decode(input); - }); - if (fail) - return err; - } - } + i += digit * w; + t = k <= bias ? tMin : (k >= bias + tMax ? tMax : k - bias); - // Pop object - if (state.obj && present) - result = input.leaveObject(prevObj); + if (digit < t) { + break; + } - // Set key - if (state.key !== null && (result !== null || present === true)) - input.leaveKey(prevKey, state.key, result); + baseMinusT = base - t; + if (w > floor(maxInt / baseMinusT)) { + error('overflow'); + } - return result; -}; + w *= baseMinusT; -Node.prototype._decodeGeneric = function decodeGeneric(tag, input) { - var state = this._baseState; + } - if (tag === 'seq' || tag === 'set') - return null; - if (tag === 'seqof' || tag === 'setof') - return this._decodeList(input, tag, state.args[0]); - else if (tag === 'octstr' || tag === 'bitstr' || tag === 'ia5str') - return this._decodeStr(input, tag); - else if (tag === 'objid' && state.args) - return this._decodeObjid(input, state.args[0], state.args[1]); - else if (tag === 'objid') - return this._decodeObjid(input, null, null); - else if (tag === 'gentime' || tag === 'utctime') - return this._decodeTime(input, tag); - else if (tag === 'null_') - return this._decodeNull(input); - else if (tag === 'bool') - return this._decodeBool(input); - else if (tag === 'int' || tag === 'enum') - return this._decodeInt(input, state.args && state.args[0]); - else if (state.use !== null) - return this._getUse(state.use, input._reporterState.obj)._decode(input); - else - return input.error('unknown tag: ' + tag); + out = output.length + 1; + bias = adapt(i - oldi, out, oldi == 0); - return null; -}; + // `i` was supposed to wrap around from `out` to `0`, + // incrementing `n` each time, so we'll fix that now: + if (floor(i / out) > maxInt - n) { + error('overflow'); + } -Node.prototype._getUse = function _getUse(entity, obj) { + n += floor(i / out); + i %= out; - var state = this._baseState; - // Create altered use decoder if implicit is set - state.useDecoder = this._use(entity, obj); - assert(state.useDecoder._baseState.parent === null); - state.useDecoder = state.useDecoder._baseState.children[0]; - if (state.implicit !== state.useDecoder._baseState.implicit) { - state.useDecoder = state.useDecoder.clone(); - state.useDecoder._baseState.implicit = state.implicit; - } - return state.useDecoder; -}; + // Insert `n` at position `i` of the output + output.splice(i++, 0, n); -Node.prototype._decodeChoice = function decodeChoice(input) { - var state = this._baseState; - var result = null; - var match = false; + } - Object.keys(state.choice).some(function(key) { - var save = input.save(); - var node = state.choice[key]; - try { - var value = node._decode(input); - if (input.isError(value)) - return false; + return ucs2encode(output); + } - result = { type: key, value: value }; - match = true; - } catch (e) { - input.restore(save); - return false; - } - return true; - }, this); + /** + * Converts a string of Unicode symbols to a Punycode string of ASCII-only + * symbols. + * @memberOf punycode + * @param {String} input The string of Unicode symbols. + * @returns {String} The resulting Punycode string of ASCII-only symbols. + */ + function encode(input) { + var n, + delta, + handledCPCount, + basicLength, + bias, + j, + m, + q, + k, + t, + currentValue, + output = [], + /** `inputLength` will hold the number of code points in `input`. */ + inputLength, + /** Cached calculation results */ + handledCPCountPlusOne, + baseMinusT, + qMinusT; - if (!match) - return input.error('Choice not matched'); + // Convert the input in UCS-2 to Unicode + input = ucs2decode(input); - return result; -}; + // Cache the length + inputLength = input.length; -// -// Encoding -// + // Initialize the state + n = initialN; + delta = 0; + bias = initialBias; -Node.prototype._createEncoderBuffer = function createEncoderBuffer(data) { - return new EncoderBuffer(data, this.reporter); -}; + // Handle the basic code points + for (j = 0; j < inputLength; ++j) { + currentValue = input[j]; + if (currentValue < 0x80) { + output.push(stringFromCharCode(currentValue)); + } + } -Node.prototype._encode = function encode(data, reporter, parent) { - var state = this._baseState; - if (state['default'] !== null && state['default'] === data) - return; + handledCPCount = basicLength = output.length; - var result = this._encodeValue(data, reporter, parent); - if (result === undefined) - return; + // `handledCPCount` is the number of code points that have been handled; + // `basicLength` is the number of basic code points. - if (this._skipDefault(result, reporter, parent)) - return; + // Finish the basic string - if it is not empty - with a delimiter + if (basicLength) { + output.push(delimiter); + } - return result; -}; + // Main encoding loop: + while (handledCPCount < inputLength) { -Node.prototype._encodeValue = function encode(data, reporter, parent) { - var state = this._baseState; + // All non-basic code points < n have been handled already. Find the next + // larger one: + for (m = maxInt, j = 0; j < inputLength; ++j) { + currentValue = input[j]; + if (currentValue >= n && currentValue < m) { + m = currentValue; + } + } - // Decode root node - if (state.parent === null) - return state.children[0]._encode(data, reporter || new Reporter()); + // Increase `delta` enough to advance the decoder's state to , + // but guard against overflow + handledCPCountPlusOne = handledCPCount + 1; + if (m - n > floor((maxInt - delta) / handledCPCountPlusOne)) { + error('overflow'); + } - var result = null; - var present = true; + delta += (m - n) * handledCPCountPlusOne; + n = m; - // Set reporter to share it with a child class - this.reporter = reporter; + for (j = 0; j < inputLength; ++j) { + currentValue = input[j]; - // Check if data is there - if (state.optional && data === undefined) { - if (state['default'] !== null) - data = state['default'] - else - return; - } + if (currentValue < n && ++delta > maxInt) { + error('overflow'); + } - // For error reporting - var prevKey; + if (currentValue == n) { + // Represent delta as a generalized variable-length integer + for (q = delta, k = base; /* no condition */; k += base) { + t = k <= bias ? tMin : (k >= bias + tMax ? tMax : k - bias); + if (q < t) { + break; + } + qMinusT = q - t; + baseMinusT = base - t; + output.push( + stringFromCharCode(digitToBasic(t + qMinusT % baseMinusT, 0)) + ); + q = floor(qMinusT / baseMinusT); + } - // Encode children first - var content = null; - var primitive = false; - if (state.any) { - // Anything that was given is translated to buffer - result = this._createEncoderBuffer(data); - } else if (state.choice) { - result = this._encodeChoice(data, reporter); - } else if (state.children) { - content = state.children.map(function(child) { - if (child._baseState.tag === 'null_') - return child._encode(null, reporter, data); + output.push(stringFromCharCode(digitToBasic(q, 0))); + bias = adapt(delta, handledCPCountPlusOne, handledCPCount == basicLength); + delta = 0; + ++handledCPCount; + } + } - if (child._baseState.key === null) - return reporter.error('Child should have a key'); - var prevKey = reporter.enterKey(child._baseState.key); + ++delta; + ++n; - if (typeof data !== 'object') - return reporter.error('Child expected, but input is not object'); + } + return output.join(''); + } - var res = child._encode(data[child._baseState.key], reporter, data); - reporter.leaveKey(prevKey); + /** + * Converts a Punycode string representing a domain name to Unicode. Only the + * Punycoded parts of the domain name will be converted, i.e. it doesn't + * matter if you call it on a string that has already been converted to + * Unicode. + * @memberOf punycode + * @param {String} domain The Punycode domain name to convert to Unicode. + * @returns {String} The Unicode representation of the given Punycode + * string. + */ + function toUnicode(domain) { + return mapDomain(domain, function(string) { + return regexPunycode.test(string) + ? decode(string.slice(4).toLowerCase()) + : string; + }); + } - return res; - }, this).filter(function(child) { - return child; - }); + /** + * Converts a Unicode string representing a domain name to Punycode. Only the + * non-ASCII parts of the domain name will be converted, i.e. it doesn't + * matter if you call it with a domain that's already in ASCII. + * @memberOf punycode + * @param {String} domain The domain name to convert, as a Unicode string. + * @returns {String} The Punycode representation of the given domain name. + */ + function toASCII(domain) { + return mapDomain(domain, function(string) { + return regexNonASCII.test(string) + ? 'xn--' + encode(string) + : string; + }); + } - content = this._createEncoderBuffer(content); - } else { - if (state.tag === 'seqof' || state.tag === 'setof') { - // TODO(indutny): this should be thrown on DSL level - if (!(state.args && state.args.length === 1)) - return reporter.error('Too many args for : ' + state.tag); + /*--------------------------------------------------------------------------*/ - if (!Array.isArray(data)) - return reporter.error('seqof/setof, but data is not Array'); + /** Define the public API */ + punycode = { + /** + * A string representing the current Punycode.js version number. + * @memberOf punycode + * @type String + */ + 'version': '1.2.4', + /** + * An object of methods to convert from JavaScript's internal character + * representation (UCS-2) to Unicode code points, and back. + * @see + * @memberOf punycode + * @type Object + */ + 'ucs2': { + 'decode': ucs2decode, + 'encode': ucs2encode + }, + 'decode': decode, + 'encode': encode, + 'toASCII': toASCII, + 'toUnicode': toUnicode + }; - var child = this.clone(); - child._baseState.implicit = null; - content = this._createEncoderBuffer(data.map(function(item) { - var state = this._baseState; + /** Expose `punycode` */ + // Some AMD build optimizers, like r.js, check for specific condition patterns + // like the following: + if ( + typeof define == 'function' && + typeof define.amd == 'object' && + define.amd + ) { + define('punycode', function() { + return punycode; + }); + } else if (freeExports && !freeExports.nodeType) { + if (freeModule) { // in Node.js or RingoJS v0.8.0+ + freeModule.exports = punycode; + } else { // in Narwhal or RingoJS v0.7.0- + for (key in punycode) { + punycode.hasOwnProperty(key) && (freeExports[key] = punycode[key]); + } + } + } else { // in Rhino or a web browser + root.punycode = punycode; + } - return this._getUse(state.args[0], data)._encode(item, reporter); - }, child)); - } else if (state.use !== null) { - result = this._getUse(state.use, parent)._encode(data, reporter); +}(this)); + +}).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}) +},{}],196:[function(require,module,exports){ +// Copyright Joyent, Inc. and other Node contributors. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to permit +// persons to whom the Software is furnished to do so, subject to the +// following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +// USE OR OTHER DEALINGS IN THE SOFTWARE. + +'use strict'; + +// If obj.hasOwnProperty has been overridden, then calling +// obj.hasOwnProperty(prop) will break. +// See: https://github.com/joyent/node/issues/1707 +function hasOwnProperty(obj, prop) { + return Object.prototype.hasOwnProperty.call(obj, prop); +} + +module.exports = function(qs, sep, eq, options) { + sep = sep || '&'; + eq = eq || '='; + var obj = {}; + + if (typeof qs !== 'string' || qs.length === 0) { + return obj; + } + + var regexp = /\+/g; + qs = qs.split(sep); + + var maxKeys = 1000; + if (options && typeof options.maxKeys === 'number') { + maxKeys = options.maxKeys; + } + + var len = qs.length; + // maxKeys <= 0 means that we should not limit keys count + if (maxKeys > 0 && len > maxKeys) { + len = maxKeys; + } + + for (var i = 0; i < len; ++i) { + var x = qs[i].replace(regexp, '%20'), + idx = x.indexOf(eq), + kstr, vstr, k, v; + + if (idx >= 0) { + kstr = x.substr(0, idx); + vstr = x.substr(idx + 1); } else { - content = this._encodePrimitive(state.tag, data); - primitive = true; + kstr = x; + vstr = ''; } - } - // Encode data itself - var result; - if (!state.any && state.choice === null) { - var tag = state.implicit !== null ? state.implicit : state.tag; - var cls = state.implicit === null ? 'universal' : 'context'; + k = decodeURIComponent(kstr); + v = decodeURIComponent(vstr); - if (tag === null) { - if (state.use === null) - reporter.error('Tag could be ommited only for .use()'); + if (!hasOwnProperty(obj, k)) { + obj[k] = v; + } else if (isArray(obj[k])) { + obj[k].push(v); } else { - if (state.use === null) - result = this._encodeComposite(tag, primitive, cls, content); + obj[k] = [obj[k], v]; } } - // Wrap in explicit - if (state.explicit !== null) - result = this._encodeComposite(state.explicit, false, 'context', result); + return obj; +}; - return result; +var isArray = Array.isArray || function (xs) { + return Object.prototype.toString.call(xs) === '[object Array]'; }; -Node.prototype._encodeChoice = function encodeChoice(data, reporter) { - var state = this._baseState; +},{}],197:[function(require,module,exports){ +// Copyright Joyent, Inc. and other Node contributors. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to permit +// persons to whom the Software is furnished to do so, subject to the +// following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +// USE OR OTHER DEALINGS IN THE SOFTWARE. - var node = state.choice[data.type]; - if (!node) { - assert( - false, - data.type + ' not found in ' + - JSON.stringify(Object.keys(state.choice))); +'use strict'; + +var stringifyPrimitive = function(v) { + switch (typeof v) { + case 'string': + return v; + + case 'boolean': + return v ? 'true' : 'false'; + + case 'number': + return isFinite(v) ? v : ''; + + default: + return ''; } - return node._encode(data.value, reporter); }; -Node.prototype._encodePrimitive = function encodePrimitive(tag, data) { - var state = this._baseState; +module.exports = function(obj, sep, eq, name) { + sep = sep || '&'; + eq = eq || '='; + if (obj === null) { + obj = undefined; + } - if (tag === 'octstr' || tag === 'bitstr' || tag === 'ia5str') - return this._encodeStr(data, tag); - else if (tag === 'objid' && state.args) - return this._encodeObjid(data, state.reverseArgs[0], state.args[1]); - else if (tag === 'objid') - return this._encodeObjid(data, null, null); - else if (tag === 'gentime' || tag === 'utctime') - return this._encodeTime(data, tag); - else if (tag === 'null_') - return this._encodeNull(); - else if (tag === 'int' || tag === 'enum') - return this._encodeInt(data, state.args && state.reverseArgs[0]); - else if (tag === 'bool') - return this._encodeBool(data); - else - throw new Error('Unsupported tag: ' + tag); + if (typeof obj === 'object') { + return map(objectKeys(obj), function(k) { + var ks = encodeURIComponent(stringifyPrimitive(k)) + eq; + if (isArray(obj[k])) { + return map(obj[k], function(v) { + return ks + encodeURIComponent(stringifyPrimitive(v)); + }).join(sep); + } else { + return ks + encodeURIComponent(stringifyPrimitive(obj[k])); + } + }).join(sep); + + } + + if (!name) return ''; + return encodeURIComponent(stringifyPrimitive(name)) + eq + + encodeURIComponent(stringifyPrimitive(obj)); }; -},{"../base":98,"minimalistic-assert":107}],100:[function(require,module,exports){ -var inherits = require('inherits'); +var isArray = Array.isArray || function (xs) { + return Object.prototype.toString.call(xs) === '[object Array]'; +}; -function Reporter(options) { - this._reporterState = { - obj: null, - path: [], - options: options || {}, - errors: [] - }; +function map (xs, f) { + if (xs.map) return xs.map(f); + var res = []; + for (var i = 0; i < xs.length; i++) { + res.push(f(xs[i], i)); + } + return res; } -exports.Reporter = Reporter; -Reporter.prototype.isError = function isError(obj) { - return obj instanceof ReporterError; +var objectKeys = Object.keys || function (obj) { + var res = []; + for (var key in obj) { + if (Object.prototype.hasOwnProperty.call(obj, key)) res.push(key); + } + return res; }; -Reporter.prototype.enterKey = function enterKey(key) { - return this._reporterState.path.push(key); -}; +},{}],198:[function(require,module,exports){ +'use strict'; -Reporter.prototype.leaveKey = function leaveKey(index, key, value) { - var state = this._reporterState; +exports.decode = exports.parse = require('./decode'); +exports.encode = exports.stringify = require('./encode'); - state.path = state.path.slice(0, index - 1); - if (state.obj !== null) - state.obj[key] = value; -}; +},{"./decode":196,"./encode":197}],199:[function(require,module,exports){ +module.exports = require("./lib/_stream_duplex.js") -Reporter.prototype.enterObject = function enterObject() { - var state = this._reporterState; +},{"./lib/_stream_duplex.js":200}],200:[function(require,module,exports){ +(function (process){ +// Copyright Joyent, Inc. and other Node contributors. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to permit +// persons to whom the Software is furnished to do so, subject to the +// following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +// USE OR OTHER DEALINGS IN THE SOFTWARE. - var prev = state.obj; - state.obj = {}; - return prev; -}; +// a duplex stream is just a stream that is both readable and writable. +// Since JS doesn't have multiple prototypal inheritance, this class +// prototypally inherits from Readable, and then parasitically from +// Writable. -Reporter.prototype.leaveObject = function leaveObject(prev) { - var state = this._reporterState; +module.exports = Duplex; - var now = state.obj; - state.obj = prev; - return now; -}; +/**/ +var objectKeys = Object.keys || function (obj) { + var keys = []; + for (var key in obj) keys.push(key); + return keys; +} +/**/ -Reporter.prototype.error = function error(msg) { - var err; - var state = this._reporterState; - var inherited = msg instanceof ReporterError; - if (inherited) { - err = msg; - } else { - err = new ReporterError(state.path.map(function(elem) { - return '[' + JSON.stringify(elem) + ']'; - }).join(''), msg.message || msg, msg.stack); - } +/**/ +var util = require('core-util-is'); +util.inherits = require('inherits'); +/**/ - if (!state.options.partial) - throw err; +var Readable = require('./_stream_readable'); +var Writable = require('./_stream_writable'); - if (!inherited) - state.errors.push(err); +util.inherits(Duplex, Readable); - return err; -}; +forEach(objectKeys(Writable.prototype), function(method) { + if (!Duplex.prototype[method]) + Duplex.prototype[method] = Writable.prototype[method]; +}); -Reporter.prototype.wrapResult = function wrapResult(result) { - var state = this._reporterState; - if (!state.options.partial) - return result; +function Duplex(options) { + if (!(this instanceof Duplex)) + return new Duplex(options); - return { - result: this.isError(result) ? null : result, - errors: state.errors - }; -}; + Readable.call(this, options); + Writable.call(this, options); -function ReporterError(path, msg) { - this.path = path; - this.rethrow(msg); -}; -inherits(ReporterError, Error); + if (options && options.readable === false) + this.readable = false; -ReporterError.prototype.rethrow = function rethrow(msg) { - this.message = msg + ' at: ' + (this.path || '(shallow)'); - Error.captureStackTrace(this, ReporterError); + if (options && options.writable === false) + this.writable = false; - return this; -}; + this.allowHalfOpen = true; + if (options && options.allowHalfOpen === false) + this.allowHalfOpen = false; -},{"inherits":229}],101:[function(require,module,exports){ -var constants = require('../constants'); + this.once('end', onend); +} -exports.tagClass = { - 0: 'universal', - 1: 'application', - 2: 'context', - 3: 'private' -}; -exports.tagClassByName = constants._reverse(exports.tagClass); +// the no-half-open enforcer +function onend() { + // if we allow half-open state, or if the writable side ended, + // then we're ok. + if (this.allowHalfOpen || this._writableState.ended) + return; -exports.tag = { - 0x00: 'end', - 0x01: 'bool', - 0x02: 'int', - 0x03: 'bitstr', - 0x04: 'octstr', - 0x05: 'null_', - 0x06: 'objid', - 0x07: 'objDesc', - 0x08: 'external', - 0x09: 'real', - 0x0a: 'enum', - 0x0b: 'embed', - 0x0c: 'utf8str', - 0x0d: 'relativeOid', - 0x10: 'seq', - 0x11: 'set', - 0x12: 'numstr', - 0x13: 'printstr', - 0x14: 't61str', - 0x15: 'videostr', - 0x16: 'ia5str', - 0x17: 'utctime', - 0x18: 'gentime', - 0x19: 'graphstr', - 0x1a: 'iso646str', - 0x1b: 'genstr', - 0x1c: 'unistr', - 0x1d: 'charstr', - 0x1e: 'bmpstr' -}; -exports.tagByName = constants._reverse(exports.tag); - -},{"../constants":102}],102:[function(require,module,exports){ -var constants = exports; + // no more data can be written. + // But allow more writes to happen in this tick. + process.nextTick(this.end.bind(this)); +} -// Helper -constants._reverse = function reverse(map) { - var res = {}; +function forEach (xs, f) { + for (var i = 0, l = xs.length; i < l; i++) { + f(xs[i], i); + } +} - Object.keys(map).forEach(function(key) { - // Convert key to integer if it is stringified - if ((key | 0) == key) - key = key | 0; +}).call(this,require('_process')) +},{"./_stream_readable":202,"./_stream_writable":204,"_process":194,"core-util-is":205,"inherits":240}],201:[function(require,module,exports){ +// Copyright Joyent, Inc. and other Node contributors. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to permit +// persons to whom the Software is furnished to do so, subject to the +// following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +// USE OR OTHER DEALINGS IN THE SOFTWARE. - var value = map[key]; - res[value] = key; - }); +// a passthrough stream. +// basically just the most minimal sort of Transform stream. +// Every written chunk gets output as-is. - return res; -}; +module.exports = PassThrough; -constants.der = require('./der'); +var Transform = require('./_stream_transform'); -},{"./der":101}],103:[function(require,module,exports){ -var inherits = require('inherits'); +/**/ +var util = require('core-util-is'); +util.inherits = require('inherits'); +/**/ -var asn1 = require('../../asn1'); -var base = asn1.base; -var bignum = asn1.bignum; +util.inherits(PassThrough, Transform); -// Import DER constants -var der = asn1.constants.der; +function PassThrough(options) { + if (!(this instanceof PassThrough)) + return new PassThrough(options); -function DERDecoder(entity) { - this.enc = 'der'; - this.name = entity.name; - this.entity = entity; + Transform.call(this, options); +} - // Construct base tree - this.tree = new DERNode(); - this.tree._init(entity.body); +PassThrough.prototype._transform = function(chunk, encoding, cb) { + cb(null, chunk); }; -module.exports = DERDecoder; -DERDecoder.prototype.decode = function decode(data, options) { - if (!(data instanceof base.DecoderBuffer)) - data = new base.DecoderBuffer(data, options); +},{"./_stream_transform":203,"core-util-is":205,"inherits":240}],202:[function(require,module,exports){ +(function (process){ +// Copyright Joyent, Inc. and other Node contributors. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to permit +// persons to whom the Software is furnished to do so, subject to the +// following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +// USE OR OTHER DEALINGS IN THE SOFTWARE. - return this.tree._decode(data, options); -}; +module.exports = Readable; -// Tree methods +/**/ +var isArray = require('isarray'); +/**/ -function DERNode(parent) { - base.Node.call(this, 'der', parent); -} -inherits(DERNode, base.Node); -DERNode.prototype._peekTag = function peekTag(buffer, tag) { - if (buffer.isEmpty()) - return false; +/**/ +var Buffer = require('buffer').Buffer; +/**/ - var state = buffer.save(); - var decodedTag = derDecodeTag(buffer, 'Failed to peek tag: "' + tag + '"'); - if (buffer.isError(decodedTag)) - return decodedTag; +Readable.ReadableState = ReadableState; - buffer.restore(state); +var EE = require('events').EventEmitter; - return decodedTag.tag === tag || decodedTag.tagStr === tag; +/**/ +if (!EE.listenerCount) EE.listenerCount = function(emitter, type) { + return emitter.listeners(type).length; }; +/**/ -DERNode.prototype._decodeTag = function decodeTag(buffer, tag, any) { - var decodedTag = derDecodeTag(buffer, - 'Failed to decode tag of "' + tag + '"'); - if (buffer.isError(decodedTag)) - return decodedTag; +var Stream = require('stream'); - var len = derDecodeLen(buffer, - decodedTag.primitive, - 'Failed to get length of "' + tag + '"'); +/**/ +var util = require('core-util-is'); +util.inherits = require('inherits'); +/**/ - // Failure - if (buffer.isError(len)) - return len; +var StringDecoder; - if (!any && - decodedTag.tag !== tag && - decodedTag.tagStr !== tag && - decodedTag.tagStr + 'of' !== tag) { - return buffer.error('Failed to match tag: "' + tag + '"'); - } - if (decodedTag.primitive || len !== null) - return buffer.skip(len, 'Failed to match body of: "' + tag + '"'); +/**/ +var debug = require('util'); +if (debug && debug.debuglog) { + debug = debug.debuglog('stream'); +} else { + debug = function () {}; +} +/**/ - // Indefinite length... find END tag - var state = buffer.start(); - var res = this._skipUntilEnd( - buffer, - 'Failed to skip indefinite length body: "' + this.tag + '"'); - if (buffer.isError(res)) - return res; - return buffer.cut(state); -}; +util.inherits(Readable, Stream); -DERNode.prototype._skipUntilEnd = function skipUntilEnd(buffer, fail) { - while (true) { - var tag = derDecodeTag(buffer, fail); - if (buffer.isError(tag)) - return tag; - var len = derDecodeLen(buffer, tag.primitive, fail); - if (buffer.isError(len)) - return len; +function ReadableState(options, stream) { + var Duplex = require('./_stream_duplex'); - var res; - if (tag.primitive || len !== null) - res = buffer.skip(len) - else - res = this._skipUntilEnd(buffer, fail); + options = options || {}; - // Failure - if (buffer.isError(res)) - return res; + // the point at which it stops calling _read() to fill the buffer + // Note: 0 is a valid value, means "don't call _read preemptively ever" + var hwm = options.highWaterMark; + var defaultHwm = options.objectMode ? 16 : 16 * 1024; + this.highWaterMark = (hwm || hwm === 0) ? hwm : defaultHwm; - if (tag.tagStr === 'end') - break; - } -}; + // cast to ints. + this.highWaterMark = ~~this.highWaterMark; -DERNode.prototype._decodeList = function decodeList(buffer, tag, decoder) { - var result = []; - while (!buffer.isEmpty()) { - var possibleEnd = this._peekTag(buffer, 'end'); - if (buffer.isError(possibleEnd)) - return possibleEnd; + this.buffer = []; + this.length = 0; + this.pipes = null; + this.pipesCount = 0; + this.flowing = null; + this.ended = false; + this.endEmitted = false; + this.reading = false; - var res = decoder.decode(buffer, 'der'); - if (buffer.isError(res) && possibleEnd) - break; - result.push(res); - } - return result; -}; + // a flag to be able to tell if the onwrite cb is called immediately, + // or on a later tick. We set this to true at first, because any + // actions that shouldn't happen until "later" should generally also + // not happen before the first write call. + this.sync = true; -DERNode.prototype._decodeStr = function decodeStr(buffer, tag) { - if (tag === 'octstr') { - return buffer.raw(); - } else if (tag === 'bitstr') { - var unused = buffer.readUInt8(); - if (buffer.isError(unused)) - return unused; + // whenever we return null, then we set a flag to say + // that we're awaiting a 'readable' event emission. + this.needReadable = false; + this.emittedReadable = false; + this.readableListening = false; - return { unused: unused, data: buffer.raw() }; - } else if (tag === 'ia5str') { - return buffer.raw().toString(); - } else { - return this.error('Decoding of string type: ' + tag + ' unsupported'); - } -}; -DERNode.prototype._decodeObjid = function decodeObjid(buffer, values, relative) { - var identifiers = []; - var ident = 0; - while (!buffer.isEmpty()) { - var subident = buffer.readUInt8(); - ident <<= 7; - ident |= subident & 0x7f; - if ((subident & 0x80) === 0) { - identifiers.push(ident); - ident = 0; - } - } - if (subident & 0x80) - identifiers.push(ident); + // object stream flag. Used to make read(n) ignore n and to + // make all the buffer merging and length checks go away + this.objectMode = !!options.objectMode; - var first = (identifiers[0] / 40) | 0; - var second = identifiers[0] % 40; + if (stream instanceof Duplex) + this.objectMode = this.objectMode || !!options.readableObjectMode; - if (relative) - result = identifiers; - else - result = [first, second].concat(identifiers.slice(1)); + // Crypto is kind of old and crusty. Historically, its default string + // encoding is 'binary' so we have to make this configurable. + // Everything else in the universe uses 'utf8', though. + this.defaultEncoding = options.defaultEncoding || 'utf8'; - if (values) - result = values[result.join(' ')]; + // when piping, we only care about 'readable' events that happen + // after read()ing all the bytes and not getting any pushback. + this.ranOut = false; - return result; -}; + // the number of writers that are awaiting a drain event in .pipe()s + this.awaitDrain = 0; -DERNode.prototype._decodeTime = function decodeTime(buffer, tag) { - var str = buffer.raw().toString(); - if (tag === 'gentime') { - var year = str.slice(0, 4) | 0; - var mon = str.slice(4, 6) | 0; - var day = str.slice(6, 8) | 0; - var hour = str.slice(8, 10) | 0; - var min = str.slice(10, 12) | 0; - var sec = str.slice(12, 14) | 0; - } else if (tag === 'utctime') { - var year = str.slice(0, 2) | 0; - var mon = str.slice(2, 4) | 0; - var day = str.slice(4, 6) | 0; - var hour = str.slice(6, 8) | 0; - var min = str.slice(8, 10) | 0; - var sec = str.slice(10, 12) | 0; - if (year < 70) - year = 2000 + year; - else - year = 1900 + year; - } else { - return this.error('Decoding ' + tag + ' time is not supported yet'); + // if true, a maybeReadMore has been scheduled + this.readingMore = false; + + this.decoder = null; + this.encoding = null; + if (options.encoding) { + if (!StringDecoder) + StringDecoder = require('string_decoder/').StringDecoder; + this.decoder = new StringDecoder(options.encoding); + this.encoding = options.encoding; } +} - return Date.UTC(year, mon - 1, day, hour, min, sec, 0); -}; +function Readable(options) { + var Duplex = require('./_stream_duplex'); -DERNode.prototype._decodeNull = function decodeNull(buffer) { - return null; -}; + if (!(this instanceof Readable)) + return new Readable(options); -DERNode.prototype._decodeBool = function decodeBool(buffer) { - var res = buffer.readUInt8(); - if (buffer.isError(res)) - return res; - else - return res !== 0; -}; + this._readableState = new ReadableState(options, this); -DERNode.prototype._decodeInt = function decodeInt(buffer, values) { - var res = 0; + // legacy + this.readable = true; - // Bigint, return as it is (assume big endian) - var raw = buffer.raw(); - if (raw.length > 3) - return new bignum(raw); + Stream.call(this); +} - while (!buffer.isEmpty()) { - res <<= 8; - var i = buffer.readUInt8(); - if (buffer.isError(i)) - return i; - res |= i; - } +// Manually shove something into the read() buffer. +// This returns true if the highWaterMark has not been hit yet, +// similar to how Writable.write() returns true if you should +// write() some more. +Readable.prototype.push = function(chunk, encoding) { + var state = this._readableState; - if (values) - res = values[res] || res; + if (util.isString(chunk) && !state.objectMode) { + encoding = encoding || state.defaultEncoding; + if (encoding !== state.encoding) { + chunk = new Buffer(chunk, encoding); + encoding = ''; + } + } - return res; + return readableAddChunk(this, state, chunk, encoding, false); }; -DERNode.prototype._use = function use(entity, obj) { - if (typeof entity === 'function') - entity = entity(obj); - return entity._getDecoder('der').tree; +// Unshift should *always* be something directly out of read() +Readable.prototype.unshift = function(chunk) { + var state = this._readableState; + return readableAddChunk(this, state, chunk, '', true); }; -// Utility methods +function readableAddChunk(stream, state, chunk, encoding, addToFront) { + var er = chunkInvalid(state, chunk); + if (er) { + stream.emit('error', er); + } else if (util.isNullOrUndefined(chunk)) { + state.reading = false; + if (!state.ended) + onEofChunk(stream, state); + } else if (state.objectMode || chunk && chunk.length > 0) { + if (state.ended && !addToFront) { + var e = new Error('stream.push() after EOF'); + stream.emit('error', e); + } else if (state.endEmitted && addToFront) { + var e = new Error('stream.unshift() after end event'); + stream.emit('error', e); + } else { + if (state.decoder && !addToFront && !encoding) + chunk = state.decoder.write(chunk); -function derDecodeTag(buf, fail) { - var tag = buf.readUInt8(fail); - if (buf.isError(tag)) - return tag; + if (!addToFront) + state.reading = false; - var cls = der.tagClass[tag >> 6]; - var primitive = (tag & 0x20) === 0; + // if we want the data now, just emit it. + if (state.flowing && state.length === 0 && !state.sync) { + stream.emit('data', chunk); + stream.read(0); + } else { + // update the buffer info. + state.length += state.objectMode ? 1 : chunk.length; + if (addToFront) + state.buffer.unshift(chunk); + else + state.buffer.push(chunk); - // Multi-octet tag - load - if ((tag & 0x1f) === 0x1f) { - var oct = tag; - tag = 0; - while ((oct & 0x80) === 0x80) { - oct = buf.readUInt8(fail); - if (buf.isError(oct)) - return oct; + if (state.needReadable) + emitReadable(stream); + } - tag <<= 7; - tag |= oct & 0x7f; + maybeReadMore(stream, state); } - } else { - tag &= 0x1f; + } else if (!addToFront) { + state.reading = false; } - var tagStr = der.tag[tag]; - return { - cls: cls, - primitive: primitive, - tag: tag, - tagStr: tagStr - }; + return needMoreData(state); } -function derDecodeLen(buf, primitive, fail) { - var len = buf.readUInt8(fail); - if (buf.isError(len)) - return len; - // Indefinite form - if (!primitive && len === 0x80) - return null; - // Definite form - if ((len & 0x80) === 0) { - // Short form - return len; - } +// if it's past the high water mark, we can push in some more. +// Also, if we have no data yet, we can stand some +// more bytes. This is to work around cases where hwm=0, +// such as the repl. Also, if the push() triggered a +// readable event, and the user called read(largeNumber) such that +// needReadable was set, then we ought to push more, so that another +// 'readable' event will be triggered. +function needMoreData(state) { + return !state.ended && + (state.needReadable || + state.length < state.highWaterMark || + state.length === 0); +} - // Long form - var num = len & 0x7f; - if (num >= 4) - return buf.error('length octect is too long'); +// backwards compatibility. +Readable.prototype.setEncoding = function(enc) { + if (!StringDecoder) + StringDecoder = require('string_decoder/').StringDecoder; + this._readableState.decoder = new StringDecoder(enc); + this._readableState.encoding = enc; + return this; +}; - len = 0; - for (var i = 0; i < num; i++) { - len <<= 8; - var j = buf.readUInt8(fail); - if (buf.isError(j)) - return j; - len |= j; +// Don't raise the hwm > 128MB +var MAX_HWM = 0x800000; +function roundUpToNextPowerOf2(n) { + if (n >= MAX_HWM) { + n = MAX_HWM; + } else { + // Get the next highest power of 2 + n--; + for (var p = 1; p < 32; p <<= 1) n |= n >> p; + n++; } - - return len; + return n; } -},{"../../asn1":95,"inherits":229}],104:[function(require,module,exports){ -var decoders = exports; +function howMuchToRead(n, state) { + if (state.length === 0 && state.ended) + return 0; -decoders.der = require('./der'); + if (state.objectMode) + return n === 0 ? 0 : 1; -},{"./der":103}],105:[function(require,module,exports){ -var inherits = require('inherits'); -var Buffer = require('buffer').Buffer; + if (isNaN(n) || util.isNull(n)) { + // only flow one buffer at a time + if (state.flowing && state.buffer.length) + return state.buffer[0].length; + else + return state.length; + } -var asn1 = require('../../asn1'); -var base = asn1.base; -var bignum = asn1.bignum; + if (n <= 0) + return 0; -// Import DER constants -var der = asn1.constants.der; - -function DEREncoder(entity) { - this.enc = 'der'; - this.name = entity.name; - this.entity = entity; - - // Construct base tree - this.tree = new DERNode(); - this.tree._init(entity.body); -}; -module.exports = DEREncoder; - -DEREncoder.prototype.encode = function encode(data, reporter) { - return this.tree._encode(data, reporter).join(); -}; + // If we're asking for more than the target buffer level, + // then raise the water mark. Bump up to the next highest + // power of 2, to prevent increasing it excessively in tiny + // amounts. + if (n > state.highWaterMark) + state.highWaterMark = roundUpToNextPowerOf2(n); -// Tree methods + // don't have that much. return null, unless we've ended. + if (n > state.length) { + if (!state.ended) { + state.needReadable = true; + return 0; + } else + return state.length; + } -function DERNode(parent) { - base.Node.call(this, 'der', parent); + return n; } -inherits(DERNode, base.Node); -DERNode.prototype._encodeComposite = function encodeComposite(tag, - primitive, - cls, - content) { - var encodedTag = encodeTag(tag, primitive, cls, this.reporter); +// you can override either this method, or the async _read(n) below. +Readable.prototype.read = function(n) { + debug('read', n); + var state = this._readableState; + var nOrig = n; - // Short form - if (content.length < 0x80) { - var header = new Buffer(2); - header[0] = encodedTag; - header[1] = content.length; - return this._createEncoderBuffer([ header, content ]); - } + if (!util.isNumber(n) || n > 0) + state.emittedReadable = false; - // Long form - // Count octets required to store length - var lenOctets = 1; - for (var i = content.length; i >= 0x100; i >>= 8) - lenOctets++; + // if we're doing read(0) to trigger a readable event, but we + // already have a bunch of data in the buffer, then just trigger + // the 'readable' event and move on. + if (n === 0 && + state.needReadable && + (state.length >= state.highWaterMark || state.ended)) { + debug('read: emitReadable', state.length, state.ended); + if (state.length === 0 && state.ended) + endReadable(this); + else + emitReadable(this); + return null; + } - var header = new Buffer(1 + 1 + lenOctets); - header[0] = encodedTag; - header[1] = 0x80 | lenOctets; + n = howMuchToRead(n, state); - for (var i = 1 + lenOctets, j = content.length; j > 0; i--, j >>= 8) - header[i] = j & 0xff; + // if we've ended, and we're now clear, then finish it up. + if (n === 0 && state.ended) { + if (state.length === 0) + endReadable(this); + return null; + } - return this._createEncoderBuffer([ header, content ]); -}; + // All the actual chunk generation logic needs to be + // *below* the call to _read. The reason is that in certain + // synthetic stream cases, such as passthrough streams, _read + // may be a completely synchronous operation which may change + // the state of the read buffer, providing enough data when + // before there was *not* enough. + // + // So, the steps are: + // 1. Figure out what the state of things will be after we do + // a read from the buffer. + // + // 2. If that resulting state will trigger a _read, then call _read. + // Note that this may be asynchronous, or synchronous. Yes, it is + // deeply ugly to write APIs this way, but that still doesn't mean + // that the Readable class should behave improperly, as streams are + // designed to be sync/async agnostic. + // Take note if the _read call is sync or async (ie, if the read call + // has returned yet), so that we know whether or not it's safe to emit + // 'readable' etc. + // + // 3. Actually pull the requested chunks out of the buffer and return. -DERNode.prototype._encodeStr = function encodeStr(str, tag) { - if (tag === 'octstr') - return this._createEncoderBuffer(str); - else if (tag === 'bitstr') - return this._createEncoderBuffer([ str.unused | 0, str.data ]); - else if (tag === 'ia5str') - return this._createEncoderBuffer(str); - return this.reporter.error('Encoding of string type: ' + tag + - ' unsupported'); -}; + // if we need a readable event, then we need to do some reading. + var doRead = state.needReadable; + debug('need readable', doRead); -DERNode.prototype._encodeObjid = function encodeObjid(id, values, relative) { - if (typeof id === 'string') { - if (!values) - return this.reporter.error('string objid given, but no values map found'); - if (!values.hasOwnProperty(id)) - return this.reporter.error('objid not found in values map'); - id = values[id].split(/\s+/g); - for (var i = 0; i < id.length; i++) - id[i] |= 0; - } else if (Array.isArray(id)) { - id = id.slice(); + // if we currently have less than the highWaterMark, then also read some + if (state.length === 0 || state.length - n < state.highWaterMark) { + doRead = true; + debug('length less than watermark', doRead); } - if (!Array.isArray(id)) { - return this.reporter.error('objid() should be either array or string, ' + - 'got: ' + JSON.stringify(id)); + // however, if we've ended, then there's no point, and if we're already + // reading, then it's unnecessary. + if (state.ended || state.reading) { + doRead = false; + debug('reading or ended', doRead); } - if (!relative) { - if (id[1] >= 40) - return this.reporter.error('Second objid identifier OOB'); - id.splice(0, 2, id[0] * 40 + id[1]); + if (doRead) { + debug('do read'); + state.reading = true; + state.sync = true; + // if the length is currently zero, then we *need* a readable event. + if (state.length === 0) + state.needReadable = true; + // call internal read method + this._read(state.highWaterMark); + state.sync = false; } - // Count number of octets - var size = 0; - for (var i = 0; i < id.length; i++) { - var ident = id[i]; - for (size++; ident >= 0x80; ident >>= 7) - size++; - } + // If _read pushed data synchronously, then `reading` will be false, + // and we need to re-evaluate how much data we can return to the user. + if (doRead && !state.reading) + n = howMuchToRead(nOrig, state); - var objid = new Buffer(size); - var offset = objid.length - 1; - for (var i = id.length - 1; i >= 0; i--) { - var ident = id[i]; - objid[offset--] = ident & 0x7f; - while ((ident >>= 7) > 0) - objid[offset--] = 0x80 | (ident & 0x7f); - } + var ret; + if (n > 0) + ret = fromList(n, state); + else + ret = null; - return this._createEncoderBuffer(objid); -}; + if (util.isNull(ret)) { + state.needReadable = true; + n = 0; + } -function two(num) { - if (num <= 10) - return '0' + num; - else - return num; -} + state.length -= n; -DERNode.prototype._encodeTime = function encodeTime(time, tag) { - var str; - var date = new Date(time); + // If we have nothing in the buffer, then we want to know + // as soon as we *do* get something into the buffer. + if (state.length === 0 && !state.ended) + state.needReadable = true; - if (tag === 'gentime') { - str = [ - date.getFullYear(), - two(date.getUTCMonth() + 1), - two(date.getUTCDate()), - two(date.getUTCHours()), - two(date.getUTCMinutes()), - two(date.getUTCSeconds()), - 'Z' - ].join(''); - } else if (tag === 'utctime') { - str = [ - date.getFullYear() % 100, - two(date.getUTCMonth() + 1), - two(date.getUTCDate()), - two(date.getUTCHours()), - two(date.getUTCMinutes()), - two(date.getUTCSeconds()), - 'Z' - ].join(''); - } else { - this.reporter.error('Encoding ' + tag + ' time is not supported yet'); - } + // If we tried to read() past the EOF, then emit end on the next tick. + if (nOrig !== n && state.ended && state.length === 0) + endReadable(this); - return this._encodeStr(str, 'octstr'); -}; + if (!util.isNull(ret)) + this.emit('data', ret); -DERNode.prototype._encodeNull = function encodeNull() { - return this._createEncoderBuffer(''); + return ret; }; -DERNode.prototype._encodeInt = function encodeInt(num, values) { - if (typeof num === 'string') { - if (!values) - return this.reporter.error('String int or enum given, but no values map'); - if (!values.hasOwnProperty(num)) { - return this.reporter.error('Values map doesn\'t contain: ' + - JSON.stringify(num)); - } - num = values[num]; +function chunkInvalid(state, chunk) { + var er = null; + if (!util.isBuffer(chunk) && + !util.isString(chunk) && + !util.isNullOrUndefined(chunk) && + !state.objectMode) { + er = new TypeError('Invalid non-string/buffer chunk'); } + return er; +} - // Bignum, assume big endian - if (bignum !== null && num instanceof bignum) { - var numArray = num.toArray(); - if(num.sign === false && numArray[0] & 0x80) { - numArray.unshift(0); + +function onEofChunk(stream, state) { + if (state.decoder && !state.ended) { + var chunk = state.decoder.end(); + if (chunk && chunk.length) { + state.buffer.push(chunk); + state.length += state.objectMode ? 1 : chunk.length; } - num = new Buffer(numArray); } + state.ended = true; - if (Buffer.isBuffer(num)) { - var size = num.length; - if (num.length === 0) - size++; + // emit 'readable' now to make sure it gets picked up. + emitReadable(stream); +} - var out = new Buffer(size); - num.copy(out); - if (num.length === 0) - out[0] = 0 - return this._createEncoderBuffer(out); +// Don't emit readable right away in sync mode, because this can trigger +// another read() call => stack overflow. This way, it might trigger +// a nextTick recursion warning, but that's not so bad. +function emitReadable(stream) { + var state = stream._readableState; + state.needReadable = false; + if (!state.emittedReadable) { + debug('emitReadable', state.flowing); + state.emittedReadable = true; + if (state.sync) + process.nextTick(function() { + emitReadable_(stream); + }); + else + emitReadable_(stream); } +} - if (num < 0x80) - return this._createEncoderBuffer(num); - - if (num < 0x100) - return this._createEncoderBuffer([0, num]); +function emitReadable_(stream) { + debug('emit readable'); + stream.emit('readable'); + flow(stream); +} - var size = 1; - for (var i = num; i >= 0x100; i >>= 8) - size++; - var out = new Array(size); - for (var i = out.length - 1; i >= 0; i--) { - out[i] = num & 0xff; - num >>= 8; +// at this point, the user has presumably seen the 'readable' event, +// and called read() to consume some data. that may have triggered +// in turn another _read(n) call, in which case reading = true if +// it's in progress. +// However, if we're not ended, or reading, and the length < hwm, +// then go ahead and try to read some more preemptively. +function maybeReadMore(stream, state) { + if (!state.readingMore) { + state.readingMore = true; + process.nextTick(function() { + maybeReadMore_(stream, state); + }); } - if(out[0] & 0x80) { - out.unshift(0); +} + +function maybeReadMore_(stream, state) { + var len = state.length; + while (!state.reading && !state.flowing && !state.ended && + state.length < state.highWaterMark) { + debug('maybeReadMore read 0'); + stream.read(0); + if (len === state.length) + // didn't get any data, stop spinning. + break; + else + len = state.length; } + state.readingMore = false; +} - return this._createEncoderBuffer(new Buffer(out)); +// abstract method. to be overridden in specific implementation classes. +// call cb(er, data) where data is <= n in length. +// for virtual (non-string, non-buffer) streams, "length" is somewhat +// arbitrary, and perhaps not very meaningful. +Readable.prototype._read = function(n) { + this.emit('error', new Error('not implemented')); }; -DERNode.prototype._encodeBool = function encodeBool(value) { - return this._createEncoderBuffer(value ? 0xff : 0); -}; +Readable.prototype.pipe = function(dest, pipeOpts) { + var src = this; + var state = this._readableState; -DERNode.prototype._use = function use(entity, obj) { - if (typeof entity === 'function') - entity = entity(obj); - return entity._getEncoder('der').tree; -}; + switch (state.pipesCount) { + case 0: + state.pipes = dest; + break; + case 1: + state.pipes = [state.pipes, dest]; + break; + default: + state.pipes.push(dest); + break; + } + state.pipesCount += 1; + debug('pipe count=%d opts=%j', state.pipesCount, pipeOpts); -DERNode.prototype._skipDefault = function skipDefault(dataBuffer, reporter, parent) { - var state = this._baseState; - var i; - if (state['default'] === null) - return false; + var doEnd = (!pipeOpts || pipeOpts.end !== false) && + dest !== process.stdout && + dest !== process.stderr; - var data = dataBuffer.join(); - if (state.defaultBuffer === undefined) - state.defaultBuffer = this._encodeValue(state['default'], reporter, parent).join(); + var endFn = doEnd ? onend : cleanup; + if (state.endEmitted) + process.nextTick(endFn); + else + src.once('end', endFn); - if (data.length !== state.defaultBuffer.length) - return false; + dest.on('unpipe', onunpipe); + function onunpipe(readable) { + debug('onunpipe'); + if (readable === src) { + cleanup(); + } + } - for (i=0; i < data.length; i++) - if (data[i] !== state.defaultBuffer[i]) - return false; + function onend() { + debug('onend'); + dest.end(); + } - return true; -}; + // when the dest drains, it reduces the awaitDrain counter + // on the source. This would be more elegant with a .once() + // handler in flow(), but adding and removing repeatedly is + // too slow. + var ondrain = pipeOnDrain(src); + dest.on('drain', ondrain); -// Utility methods + function cleanup() { + debug('cleanup'); + // cleanup event handlers once the pipe is broken + dest.removeListener('close', onclose); + dest.removeListener('finish', onfinish); + dest.removeListener('drain', ondrain); + dest.removeListener('error', onerror); + dest.removeListener('unpipe', onunpipe); + src.removeListener('end', onend); + src.removeListener('end', cleanup); + src.removeListener('data', ondata); -function encodeTag(tag, primitive, cls, reporter) { - var res; + // if the reader is waiting for a drain event from this + // specific writer, then it would cause it to never start + // flowing again. + // So, if this is awaiting a drain, then we just call it now. + // If we don't know, then assume that we are waiting for one. + if (state.awaitDrain && + (!dest._writableState || dest._writableState.needDrain)) + ondrain(); + } - if (tag === 'seqof') - tag = 'seq'; - else if (tag === 'setof') - tag = 'set'; + src.on('data', ondata); + function ondata(chunk) { + debug('ondata'); + var ret = dest.write(chunk); + if (false === ret) { + debug('false write response, pause', + src._readableState.awaitDrain); + src._readableState.awaitDrain++; + src.pause(); + } + } - if (der.tagByName.hasOwnProperty(tag)) - res = der.tagByName[tag]; - else if (typeof tag === 'number' && (tag | 0) === tag) - res = tag; + // if the dest has an error, then stop piping into it. + // however, don't suppress the throwing behavior for this. + function onerror(er) { + debug('onerror', er); + unpipe(); + dest.removeListener('error', onerror); + if (EE.listenerCount(dest, 'error') === 0) + dest.emit('error', er); + } + // This is a brutally ugly hack to make sure that our error handler + // is attached before any userland ones. NEVER DO THIS. + if (!dest._events || !dest._events.error) + dest.on('error', onerror); + else if (isArray(dest._events.error)) + dest._events.error.unshift(onerror); else - return reporter.error('Unknown tag: ' + tag); + dest._events.error = [onerror, dest._events.error]; - if (res >= 0x1f) - return reporter.error('Multi-octet tag encoding unsupported'); - if (!primitive) - res |= 0x20; - res |= (der.tagClassByName[cls || 'universal'] << 6); + // Both close and finish should trigger unpipe, but only once. + function onclose() { + dest.removeListener('finish', onfinish); + unpipe(); + } + dest.once('close', onclose); + function onfinish() { + debug('onfinish'); + dest.removeListener('close', onclose); + unpipe(); + } + dest.once('finish', onfinish); - return res; -} + function unpipe() { + debug('unpipe'); + src.unpipe(dest); + } -},{"../../asn1":95,"buffer":42,"inherits":229}],106:[function(require,module,exports){ -var encoders = exports; + // tell the dest that it's being piped to + dest.emit('pipe', src); -encoders.der = require('./der'); + // start the flow if it hasn't been started already. + if (!state.flowing) { + debug('pipe resume'); + src.resume(); + } -},{"./der":105}],107:[function(require,module,exports){ -module.exports = assert; + return dest; +}; -function assert(val, msg) { - if (!val) - throw new Error(msg || 'Assertion failed'); +function pipeOnDrain(src) { + return function() { + var state = src._readableState; + debug('pipeOnDrain', state.awaitDrain); + if (state.awaitDrain) + state.awaitDrain--; + if (state.awaitDrain === 0 && EE.listenerCount(src, 'data')) { + state.flowing = true; + flow(src); + } + }; } -assert.equal = function assertEqual(l, r, msg) { - if (l != r) - throw new Error(msg || ('Assertion failed: ' + l + ' != ' + r)); -}; -},{}],108:[function(require,module,exports){ -exports.strip = function strip(artifact) { - artifact = artifact.toString() - var startRegex = /^-----BEGIN (.*)-----\n/; - var match = startRegex.exec(artifact); - var tag = match[1]; - var endRegex = new RegExp("\n-----END " + tag + "-----(\n*)$"); - var base64 = artifact.slice(match[0].length).replace(endRegex, "").replace(/\n/g, ""); - return {tag: tag, base64: base64}; -}; +Readable.prototype.unpipe = function(dest) { + var state = this._readableState; -// http://stackoverflow.com/a/7033705 -var wrap = function wrap(str, l) { - var chunks = []; - while (str) { - if (str.length < l) { - chunks.push(str); - break; - } - else { - chunks.push(str.substr(0, l)); - str = str.substr(l); - } - } - return chunks.join("\n"); -} + // if we're not piping anywhere, then do nothing. + if (state.pipesCount === 0) + return this; -exports.assemble = function assemble(info) { - var tag = info.tag; - var base64 = info.base64; - var startLine = "-----BEGIN " + tag + "-----"; - var endLine = "-----END " + tag + "-----"; - return startLine + "\n" + wrap(base64, 64) + "\n" + endLine + "\n"; -} -},{}],109:[function(require,module,exports){ -(function (Buffer){ -// much of this based on https://github.com/indutny/self-signed/blob/gh-pages/lib/rsa.js -var parseKeys = require('parse-asn1'); -var bn = require('bn.js'); -var elliptic = require('elliptic'); -var crt = require("browserify-rsa"); -module.exports = sign; -function sign(hash, key, hashType, crypto) { - var priv = parseKeys(key, crypto); - if (priv.curve) { - return ecSign(hash, priv, crypto); - } else if (priv.type === 'dsa') { - return dsaSign(hash, priv, hashType, crypto); - } - var len = priv.modulus.byteLength(); - var pad = [ 0, 1 ]; - while (hash.length + pad.length + 1 < len) { - pad.push(0xff); - } - pad.push(0x00); - var i = -1; - while (++i < hash.length) { - pad.push(hash[i]); - } - - var out = crt(pad, priv, crypto); - return out; -} -function ecSign(hash, priv, crypto) { - elliptic.rand = crypto.randomBytes; - var curve; - if (priv.curve.join('.') === '1.3.132.0.10') { - curve = new elliptic.ec('secp256k1'); - } - var key = curve.genKeyPair(); - key._importPrivate(priv.privateKey); - var out = key.sign(hash); - return new Buffer(out.toDER()); -} -function dsaSign(hash, priv, algo, crypto) { - var x = priv.params.priv_key; - var p = priv.params.p; - var q = priv.params.q; - var montq = bn.mont(q); - var g = priv.params.g; - var r = new bn(0); - var k; - var H = bits2int(hash, q).mod(q); - var s = false; - var kv = getKay(x, q, hash, algo, crypto); - while (s === false) { - k = makeKey(q, kv, algo, crypto); - r = makeR(g, k, p, q); - s = k.invm(q).imul(H.add(x.mul(r))).mod(q); - if (!s.cmpn(0)) { - s = false; - r = new bn(0); - } - } - return toDER(r,s); -} -function toDER(r, s) { - r = r.toArray(); - s = s.toArray(); + // just one destination. most common case. + if (state.pipesCount === 1) { + // passed in one, but it's not the right one. + if (dest && dest !== state.pipes) + return this; - // Pad values - if (r[0] & 0x80) - r = [ 0 ].concat(r); - // Pad values - if (s[0] & 0x80) - s = [0].concat(s); + if (!dest) + dest = state.pipes; - var total = r.length + s.length + 4; - var res = [ 0x30, total, 0x02, r.length ]; - res = res.concat(r, [ 0x02, s.length ], s); - return new Buffer(res); -} -module.exports.getKay = getKay; -function getKay(x, q, hash, algo, crypto) { - x = new Buffer(x.toArray()); - if (x.length < q.byteLength()) { - var zeros = new Buffer(q.byteLength() - x.length); - zeros.fill(0); - x = Buffer.concat([zeros, x]); - } - var hlen = hash.length; - var hbits = bits2octets(hash, q); - var v = new Buffer(hlen); - v.fill(1); - var k = new Buffer(hlen); - k.fill(0); - k = crypto.createHmac(algo, k) - .update(v) - .update(new Buffer([0])) - .update(x) - .update(hbits) - .digest(); - v = crypto.createHmac(algo, k) - .update(v) - .digest(); - k = crypto.createHmac(algo, k) - .update(v) - .update(new Buffer([1])) - .update(x) - .update(hbits) - .digest(); - v = crypto.createHmac(algo, k) - .update(v) - .digest(); - return { - k:k, - v:v - }; -} -function bits2int(obits, q) { - bits = new bn(obits); - var shift = obits.length * 8 - q.bitLength(); - if (shift > 0) { - bits.ishrn(shift); - } - return bits; -} -function bits2octets (bits, q) { - bits = bits2int(bits, q); - bits = bits.mod(q); - var out = new Buffer(bits.toArray()); - if (out.length < q.byteLength()) { - var zeros = new Buffer(q.byteLength() - out.length); - zeros.fill(0); - out = Buffer.concat([zeros, out]); - } - return out; -} -module.exports.makeKey = makeKey; -function makeKey(q, kv, algo, crypto) { - var t; - var k; - while (true) { - t = new Buffer(''); - while (t.length * 8 < q.bitLength()) { - kv.v = crypto.createHmac(algo, kv.k) - .update(kv.v) - .digest(); - t = Buffer.concat([t, kv.v]); - } - k = bits2int(t, q); - kv.k = crypto.createHmac(algo, kv.k) - .update(kv.v) - .update(new Buffer([0])) - .digest(); - kv.v = crypto.createHmac(algo, kv.k) - .update(kv.v) - .digest(); - if (k.cmp(q) === -1) { - return k; - } - } -} -function makeR(g, k, p, q) { - return g.toRed(bn.mont(p)).redPow(k).fromRed().mod(q); -} -}).call(this,require("buffer").Buffer) -},{"bn.js":67,"browserify-rsa":68,"buffer":42,"elliptic":69,"parse-asn1":93}],110:[function(require,module,exports){ -(function (Buffer){ -// much of this based on https://github.com/indutny/self-signed/blob/gh-pages/lib/rsa.js -var parseKeys = require('parse-asn1'); -var elliptic = require('elliptic'); -var bn = require('bn.js'); -module.exports = verify; -function verify(sig, hash, key) { - var pub = parseKeys(key); - if (pub.type === 'ec') { - return ecVerify(sig, hash, pub); - } else if (pub.type === 'dsa') { - return dsaVerify(sig, hash, pub); - } - var len = pub.modulus.byteLength(); - var pad = [ 0, 1 ]; - while (hash.length + pad.length + 1 < len) { - pad.push(0xff); - } - pad.push(0x00); - var i = -1; - while (++i < hash.length) { - pad.push(hash[i]); + // got a match. + state.pipes = null; + state.pipesCount = 0; + state.flowing = false; + if (dest) + dest.emit('unpipe', this); + return this; } - pad = hash; - var red = bn.mont(pub.modulus); - sig = new bn(sig).toRed(red); - sig = sig.redPow(new bn(pub.publicExponent)); + // slow case. multiple pipe destinations. - sig = new Buffer(sig.fromRed().toArray()); - sig = sig.slice(sig.length - hash.length); - var out = 0; - len = sig.length; - i = -1; - while (++i < len) { - out += (sig[i] ^ hash[i]); - } - return !out; -} -function ecVerify(sig, hash, pub) { - var curve; - if (pub.data.algorithm.curve.join('.') === '1.3.132.0.10') { - curve = new elliptic.ec('secp256k1'); - } - var pubkey = pub.data.subjectPrivateKey.data; - return curve.verify(hash.toString('hex'), sig.toString('hex'), pubkey.toString('hex')); -} -function dsaVerify(sig, hash, pub) { - var p = pub.data.p; - var q = pub.data.q; - var g = pub.data.g; - var y = pub.data.pub_key; - var unpacked = parseKeys.signature.decode(sig, 'der'); - var s = unpacked.s; - var r = unpacked.r; - checkValue(s, q); - checkValue(r, q); - var montq = bn.mont(q); - var montp = bn.mont(p); - var w = s.invm(q); - var v = g.toRed(montp) - .redPow(new bn(hash).mul(w).mod(q)) - .fromRed() - .mul( - y.toRed(montp) - .redPow(r.mul(w).mod(q)) - .fromRed() - ).mod(p).mod(q); - return !v.cmp(r); -} -function checkValue(b, q) { - if (b.cmpn(0) <= 0) { - throw new Error('invalid sig'); - } - if (b.cmp(q) >= q) { - throw new Error('invalid sig'); + if (!dest) { + // remove all. + var dests = state.pipes; + var len = state.pipesCount; + state.pipes = null; + state.pipesCount = 0; + state.flowing = false; + + for (var i = 0; i < len; i++) + dests[i].emit('unpipe', this); + return this; } -} -}).call(this,require("buffer").Buffer) -},{"bn.js":67,"buffer":42,"elliptic":69,"parse-asn1":93}],111:[function(require,module,exports){ -(function (Buffer){ -var elliptic = require('elliptic'); -var BN = require('bn.js'); -module.exports = ECDH; -function ECDH(curve, crypto) { - elliptic.rand = crypto.randomBytes; - this.curve = new elliptic.ec(curve); - this.keys = void 0; -} -ECDH.prototype.generateKeys = function (enc, format) { - this.keys = this.curve.genKeyPair(); - return this.getPublicKey(enc, format); -}; + // try to find the right one. + var i = indexOf(state.pipes, dest); + if (i === -1) + return this; -ECDH.prototype.computeSecret = function (other, inenc, enc) { - inenc = inenc || 'utf8'; - if (!Buffer.isBuffer(other)) { - other = new Buffer(other, inenc); - } - other = new BN(other); - other = other.toString(16); - var otherPub = this.curve.keyPair(other, 'hex').getPublic(); - var out = otherPub.mul(this.keys.getPrivate()).getX(); - return returnValue(out, enc); -}; -ECDH.prototype.getPublicKey = function (enc, format) { - var key = this.keys.getPublic(format === 'compressed', true); - if (format === 'hybrid') { - if (key[key.length - 1] % 2) { - key[0] = 7; - } else { - key [0] = 6; - } - } - return returnValue(key, enc); -}; -ECDH.prototype.getPrivateKey = function (enc) { - return returnValue(this.keys.getPrivate(), enc); -}; + state.pipes.splice(i, 1); + state.pipesCount -= 1; + if (state.pipesCount === 1) + state.pipes = state.pipes[0]; -ECDH.prototype.setPublicKey = function (pub, enc) { - enc = enc || 'utf8'; - if (!Buffer.isBuffer(pub)) { - pub = new Buffer(pub, enc); - } - var pkey = new BN(pub); - pkey = pkey.toArray(); - this.keys._importPublicHex(pkey); -}; -ECDH.prototype.setPrivateKey = function (priv, enc) { - enc = enc || 'utf8'; - if (!Buffer.isBuffer(priv)) { - priv = new Buffer(priv, enc); - } - var _priv = new BN(priv); - _priv = _priv.toString(16); - this.keys._importPrivate(_priv); -}; -function returnValue(bn, enc) { - if (!Array.isArray(bn)) { - bn = bn.toArray(); - } - var buf = new Buffer(bn); - if (!enc) { - return buf; - } else { - return buf.toString(enc); - } -} -}).call(this,require("buffer").Buffer) -},{"bn.js":113,"buffer":42,"elliptic":114}],112:[function(require,module,exports){ -var ECDH = require('./ecdh'); -module.exports = function (crypto, exports) { - exports.createECDH = function (curve) { - return new ECDH(curve, crypto); - }; + dest.emit('unpipe', this); + + return this; }; -},{"./ecdh":111}],113:[function(require,module,exports){ -module.exports=require(67) -},{"/Users/eordano/Code/bitcore/node_modules/bitcore-build/node_modules/browserify/node_modules/crypto-browserify/node_modules/browserify-sign/node_modules/bn.js/lib/bn.js":67}],114:[function(require,module,exports){ -module.exports=require(69) -},{"../package.json":133,"./elliptic/curve":117,"./elliptic/curves":120,"./elliptic/ec":121,"./elliptic/hmac-drbg":124,"./elliptic/utils":125,"/Users/eordano/Code/bitcore/node_modules/bitcore-build/node_modules/browserify/node_modules/crypto-browserify/node_modules/browserify-sign/node_modules/elliptic/lib/elliptic.js":69,"brorand":126}],115:[function(require,module,exports){ -module.exports=require(70) -},{"../../elliptic":114,"/Users/eordano/Code/bitcore/node_modules/bitcore-build/node_modules/browserify/node_modules/crypto-browserify/node_modules/browserify-sign/node_modules/elliptic/lib/elliptic/curve/base.js":70,"bn.js":113}],116:[function(require,module,exports){ -module.exports=require(71) -},{"../../elliptic":114,"../curve":117,"/Users/eordano/Code/bitcore/node_modules/bitcore-build/node_modules/browserify/node_modules/crypto-browserify/node_modules/browserify-sign/node_modules/elliptic/lib/elliptic/curve/edwards.js":71,"bn.js":113,"inherits":229}],117:[function(require,module,exports){ -module.exports=require(72) -},{"./base":115,"./edwards":116,"./mont":118,"./short":119,"/Users/eordano/Code/bitcore/node_modules/bitcore-build/node_modules/browserify/node_modules/crypto-browserify/node_modules/browserify-sign/node_modules/elliptic/lib/elliptic/curve/index.js":72}],118:[function(require,module,exports){ -module.exports=require(73) -},{"../../elliptic":114,"../curve":117,"/Users/eordano/Code/bitcore/node_modules/bitcore-build/node_modules/browserify/node_modules/crypto-browserify/node_modules/browserify-sign/node_modules/elliptic/lib/elliptic/curve/mont.js":73,"bn.js":113,"inherits":229}],119:[function(require,module,exports){ -module.exports=require(74) -},{"../../elliptic":114,"../curve":117,"/Users/eordano/Code/bitcore/node_modules/bitcore-build/node_modules/browserify/node_modules/crypto-browserify/node_modules/browserify-sign/node_modules/elliptic/lib/elliptic/curve/short.js":74,"bn.js":113,"inherits":229}],120:[function(require,module,exports){ -module.exports=require(75) -},{"../elliptic":114,"/Users/eordano/Code/bitcore/node_modules/bitcore-build/node_modules/browserify/node_modules/crypto-browserify/node_modules/browserify-sign/node_modules/elliptic/lib/elliptic/curves.js":75,"bn.js":113,"hash.js":127}],121:[function(require,module,exports){ -module.exports=require(76) -},{"../../elliptic":114,"./key":122,"./signature":123,"/Users/eordano/Code/bitcore/node_modules/bitcore-build/node_modules/browserify/node_modules/crypto-browserify/node_modules/browserify-sign/node_modules/elliptic/lib/elliptic/ec/index.js":76,"bn.js":113}],122:[function(require,module,exports){ -module.exports=require(77) -},{"../../elliptic":114,"/Users/eordano/Code/bitcore/node_modules/bitcore-build/node_modules/browserify/node_modules/crypto-browserify/node_modules/browserify-sign/node_modules/elliptic/lib/elliptic/ec/key.js":77,"bn.js":113}],123:[function(require,module,exports){ -module.exports=require(78) -},{"../../elliptic":114,"/Users/eordano/Code/bitcore/node_modules/bitcore-build/node_modules/browserify/node_modules/crypto-browserify/node_modules/browserify-sign/node_modules/elliptic/lib/elliptic/ec/signature.js":78,"bn.js":113}],124:[function(require,module,exports){ -module.exports=require(79) -},{"../elliptic":114,"/Users/eordano/Code/bitcore/node_modules/bitcore-build/node_modules/browserify/node_modules/crypto-browserify/node_modules/browserify-sign/node_modules/elliptic/lib/elliptic/hmac-drbg.js":79,"hash.js":127}],125:[function(require,module,exports){ -module.exports=require(80) -},{"/Users/eordano/Code/bitcore/node_modules/bitcore-build/node_modules/browserify/node_modules/crypto-browserify/node_modules/browserify-sign/node_modules/elliptic/lib/elliptic/utils.js":80,"bn.js":113}],126:[function(require,module,exports){ -module.exports=require(81) -},{"/Users/eordano/Code/bitcore/node_modules/bitcore-build/node_modules/browserify/node_modules/crypto-browserify/node_modules/browserify-sign/node_modules/elliptic/node_modules/brorand/index.js":81}],127:[function(require,module,exports){ -module.exports=require(82) -},{"./hash/common":128,"./hash/hmac":129,"./hash/ripemd":130,"./hash/sha":131,"./hash/utils":132,"/Users/eordano/Code/bitcore/node_modules/bitcore-build/node_modules/browserify/node_modules/crypto-browserify/node_modules/browserify-sign/node_modules/elliptic/node_modules/hash.js/lib/hash.js":82}],128:[function(require,module,exports){ -module.exports=require(83) -},{"../hash":127,"/Users/eordano/Code/bitcore/node_modules/bitcore-build/node_modules/browserify/node_modules/crypto-browserify/node_modules/browserify-sign/node_modules/elliptic/node_modules/hash.js/lib/hash/common.js":83}],129:[function(require,module,exports){ -module.exports=require(84) -},{"../hash":127,"/Users/eordano/Code/bitcore/node_modules/bitcore-build/node_modules/browserify/node_modules/crypto-browserify/node_modules/browserify-sign/node_modules/elliptic/node_modules/hash.js/lib/hash/hmac.js":84}],130:[function(require,module,exports){ -module.exports=require(85) -},{"../hash":127,"/Users/eordano/Code/bitcore/node_modules/bitcore-build/node_modules/browserify/node_modules/crypto-browserify/node_modules/browserify-sign/node_modules/elliptic/node_modules/hash.js/lib/hash/ripemd.js":85}],131:[function(require,module,exports){ -module.exports=require(86) -},{"../hash":127,"/Users/eordano/Code/bitcore/node_modules/bitcore-build/node_modules/browserify/node_modules/crypto-browserify/node_modules/browserify-sign/node_modules/elliptic/node_modules/hash.js/lib/hash/sha.js":86}],132:[function(require,module,exports){ -module.exports=require(87) -},{"/Users/eordano/Code/bitcore/node_modules/bitcore-build/node_modules/browserify/node_modules/crypto-browserify/node_modules/browserify-sign/node_modules/elliptic/node_modules/hash.js/lib/hash/utils.js":87,"inherits":229}],133:[function(require,module,exports){ -module.exports=require(88) -},{"/Users/eordano/Code/bitcore/node_modules/bitcore-build/node_modules/browserify/node_modules/crypto-browserify/node_modules/browserify-sign/node_modules/elliptic/package.json":88}],134:[function(require,module,exports){ -(function (Buffer){ -'use strict'; -var createHash = require('sha.js') -var md5 = require('./md5') -var rmd160 = require('ripemd160') -var Transform = require('stream').Transform; -var inherits = require('inherits') +// set up data events if they are asked for +// Ensure readable listeners eventually get something +Readable.prototype.on = function(ev, fn) { + var res = Stream.prototype.on.call(this, ev, fn); -module.exports = function (alg) { - if('md5' === alg) return new HashNoConstructor(md5) - if('rmd160' === alg) return new HashNoConstructor(rmd160) - return new Hash(createHash(alg)) -} -inherits(HashNoConstructor, Transform) + // If listening to data, and it has not explicitly been paused, + // then call resume to start the flow of data on the next tick. + if (ev === 'data' && false !== this._readableState.flowing) { + this.resume(); + } -function HashNoConstructor(hash) { - Transform.call(this); - this._hash = hash - this.buffers = [] -} + if (ev === 'readable' && this.readable) { + var state = this._readableState; + if (!state.readableListening) { + state.readableListening = true; + state.emittedReadable = false; + state.needReadable = true; + if (!state.reading) { + var self = this; + process.nextTick(function() { + debug('readable nexttick read 0'); + self.read(0); + }); + } else if (state.length) { + emitReadable(this, state); + } + } + } -HashNoConstructor.prototype._transform = function (data, _, done) { - this.buffers.push(data) - done() -} -HashNoConstructor.prototype._flush = function (done) { - var buf = Buffer.concat(this.buffers) - var r = this._hash(buf) - this.buffers = null - this.push(r) - done() -} -HashNoConstructor.prototype.update = function (data, enc) { - this.write(data, enc) - return this -} + return res; +}; +Readable.prototype.addListener = Readable.prototype.on; -HashNoConstructor.prototype.digest = function (enc) { - this.end() - var outData = new Buffer('') - var chunk - while ((chunk = this.read())) { - outData = Buffer.concat([outData, chunk]) - } - if (enc) { - outData = outData.toString(enc) +// pause() and resume() are remnants of the legacy readable stream API +// If the user uses them, then switch into old mode. +Readable.prototype.resume = function() { + var state = this._readableState; + if (!state.flowing) { + debug('resume'); + state.flowing = true; + if (!state.reading) { + debug('resume read 0'); + this.read(0); + } + resume(this, state); } - return outData -} - -inherits(Hash, Transform) + return this; +}; -function Hash(hash) { - Transform.call(this); - this._hash = hash +function resume(stream, state) { + if (!state.resumeScheduled) { + state.resumeScheduled = true; + process.nextTick(function() { + resume_(stream, state); + }); + } } -Hash.prototype._transform = function (data, _, done) { - this._hash.update(data) - done() -} -Hash.prototype._flush = function (done) { - this.push(this._hash.digest()) - this._hash = null - done() -} -Hash.prototype.update = function (data, enc) { - this.write(data, enc) - return this +function resume_(stream, state) { + state.resumeScheduled = false; + stream.emit('resume'); + flow(stream); + if (state.flowing && !state.reading) + stream.read(0); } -Hash.prototype.digest = function (enc) { - this.end() - var outData = new Buffer('') - var chunk - while ((chunk = this.read())) { - outData = Buffer.concat([outData, chunk]) +Readable.prototype.pause = function() { + debug('call pause flowing=%j', this._readableState.flowing); + if (false !== this._readableState.flowing) { + debug('pause'); + this._readableState.flowing = false; + this.emit('pause'); } - if (enc) { - outData = outData.toString(enc) + return this; +}; + +function flow(stream) { + var state = stream._readableState; + debug('flow', state.flowing); + if (state.flowing) { + do { + var chunk = stream.read(); + } while (null !== chunk && state.flowing); } - return outData } -}).call(this,require("buffer").Buffer) -},{"./md5":136,"buffer":42,"inherits":229,"ripemd160":137,"sha.js":139,"stream":200}],135:[function(require,module,exports){ -(function (Buffer){ -'use strict'; -var intSize = 4; -var zeroBuffer = new Buffer(intSize); zeroBuffer.fill(0); -var chrsz = 8; -function toArray(buf, bigEndian) { - if ((buf.length % intSize) !== 0) { - var len = buf.length + (intSize - (buf.length % intSize)); - buf = Buffer.concat([buf, zeroBuffer], len); - } +// wrap an old-style stream as the async data source. +// This is *not* part of the readable stream interface. +// It is an ugly unfortunate mess of history. +Readable.prototype.wrap = function(stream) { + var state = this._readableState; + var paused = false; - var arr = []; - var fn = bigEndian ? buf.readInt32BE : buf.readInt32LE; - for (var i = 0; i < buf.length; i += intSize) { - arr.push(fn.call(buf, i)); - } - return arr; -} + var self = this; + stream.on('end', function() { + debug('wrapped end'); + if (state.decoder && !state.ended) { + var chunk = state.decoder.end(); + if (chunk && chunk.length) + self.push(chunk); + } -function toBuffer(arr, size, bigEndian) { - var buf = new Buffer(size); - var fn = bigEndian ? buf.writeInt32BE : buf.writeInt32LE; - for (var i = 0; i < arr.length; i++) { - fn.call(buf, arr[i], i * 4, true); + self.push(null); + }); + + stream.on('data', function(chunk) { + debug('wrapped data'); + if (state.decoder) + chunk = state.decoder.write(chunk); + if (!chunk || !state.objectMode && !chunk.length) + return; + + var ret = self.push(chunk); + if (!ret) { + paused = true; + stream.pause(); + } + }); + + // proxy all the other methods. + // important when wrapping filters and duplexes. + for (var i in stream) { + if (util.isFunction(stream[i]) && util.isUndefined(this[i])) { + this[i] = function(method) { return function() { + return stream[method].apply(stream, arguments); + }}(i); + } } - return buf; -} -function hash(buf, fn, hashSize, bigEndian) { - if (!Buffer.isBuffer(buf)) buf = new Buffer(buf); - var arr = fn(toArray(buf, bigEndian), buf.length * chrsz); - return toBuffer(arr, hashSize, bigEndian); -} -exports.hash = hash; -}).call(this,require("buffer").Buffer) -},{"buffer":42}],136:[function(require,module,exports){ -'use strict'; -/* - * A JavaScript implementation of the RSA Data Security, Inc. MD5 Message - * Digest Algorithm, as defined in RFC 1321. - * Version 2.1 Copyright (C) Paul Johnston 1999 - 2002. - * Other contributors: Greg Holt, Andrew Kepert, Ydnar, Lostinet - * Distributed under the BSD License - * See http://pajhome.org.uk/crypt/md5 for more info. - */ + // proxy certain important events. + var events = ['error', 'close', 'destroy', 'pause', 'resume']; + forEach(events, function(ev) { + stream.on(ev, self.emit.bind(self, ev)); + }); -var helpers = require('./helpers'); + // when we try to consume some more bytes, simply unpause the + // underlying stream. + self._read = function(n) { + debug('wrapped _read', n); + if (paused) { + paused = false; + stream.resume(); + } + }; -/* - * Calculate the MD5 of an array of little-endian words, and a bit length - */ -function core_md5(x, len) -{ - /* append padding */ - x[len >> 5] |= 0x80 << ((len) % 32); - x[(((len + 64) >>> 9) << 4) + 14] = len; + return self; +}; - var a = 1732584193; - var b = -271733879; - var c = -1732584194; - var d = 271733878; - for(var i = 0; i < x.length; i += 16) - { - var olda = a; - var oldb = b; - var oldc = c; - var oldd = d; - a = md5_ff(a, b, c, d, x[i+ 0], 7 , -680876936); - d = md5_ff(d, a, b, c, x[i+ 1], 12, -389564586); - c = md5_ff(c, d, a, b, x[i+ 2], 17, 606105819); - b = md5_ff(b, c, d, a, x[i+ 3], 22, -1044525330); - a = md5_ff(a, b, c, d, x[i+ 4], 7 , -176418897); - d = md5_ff(d, a, b, c, x[i+ 5], 12, 1200080426); - c = md5_ff(c, d, a, b, x[i+ 6], 17, -1473231341); - b = md5_ff(b, c, d, a, x[i+ 7], 22, -45705983); - a = md5_ff(a, b, c, d, x[i+ 8], 7 , 1770035416); - d = md5_ff(d, a, b, c, x[i+ 9], 12, -1958414417); - c = md5_ff(c, d, a, b, x[i+10], 17, -42063); - b = md5_ff(b, c, d, a, x[i+11], 22, -1990404162); - a = md5_ff(a, b, c, d, x[i+12], 7 , 1804603682); - d = md5_ff(d, a, b, c, x[i+13], 12, -40341101); - c = md5_ff(c, d, a, b, x[i+14], 17, -1502002290); - b = md5_ff(b, c, d, a, x[i+15], 22, 1236535329); +// exposed for testing purposes only. +Readable._fromList = fromList; - a = md5_gg(a, b, c, d, x[i+ 1], 5 , -165796510); - d = md5_gg(d, a, b, c, x[i+ 6], 9 , -1069501632); - c = md5_gg(c, d, a, b, x[i+11], 14, 643717713); - b = md5_gg(b, c, d, a, x[i+ 0], 20, -373897302); - a = md5_gg(a, b, c, d, x[i+ 5], 5 , -701558691); - d = md5_gg(d, a, b, c, x[i+10], 9 , 38016083); - c = md5_gg(c, d, a, b, x[i+15], 14, -660478335); - b = md5_gg(b, c, d, a, x[i+ 4], 20, -405537848); - a = md5_gg(a, b, c, d, x[i+ 9], 5 , 568446438); - d = md5_gg(d, a, b, c, x[i+14], 9 , -1019803690); - c = md5_gg(c, d, a, b, x[i+ 3], 14, -187363961); - b = md5_gg(b, c, d, a, x[i+ 8], 20, 1163531501); - a = md5_gg(a, b, c, d, x[i+13], 5 , -1444681467); - d = md5_gg(d, a, b, c, x[i+ 2], 9 , -51403784); - c = md5_gg(c, d, a, b, x[i+ 7], 14, 1735328473); - b = md5_gg(b, c, d, a, x[i+12], 20, -1926607734); +// Pluck off n bytes from an array of buffers. +// Length is the combined lengths of all the buffers in the list. +function fromList(n, state) { + var list = state.buffer; + var length = state.length; + var stringMode = !!state.decoder; + var objectMode = !!state.objectMode; + var ret; - a = md5_hh(a, b, c, d, x[i+ 5], 4 , -378558); - d = md5_hh(d, a, b, c, x[i+ 8], 11, -2022574463); - c = md5_hh(c, d, a, b, x[i+11], 16, 1839030562); - b = md5_hh(b, c, d, a, x[i+14], 23, -35309556); - a = md5_hh(a, b, c, d, x[i+ 1], 4 , -1530992060); - d = md5_hh(d, a, b, c, x[i+ 4], 11, 1272893353); - c = md5_hh(c, d, a, b, x[i+ 7], 16, -155497632); - b = md5_hh(b, c, d, a, x[i+10], 23, -1094730640); - a = md5_hh(a, b, c, d, x[i+13], 4 , 681279174); - d = md5_hh(d, a, b, c, x[i+ 0], 11, -358537222); - c = md5_hh(c, d, a, b, x[i+ 3], 16, -722521979); - b = md5_hh(b, c, d, a, x[i+ 6], 23, 76029189); - a = md5_hh(a, b, c, d, x[i+ 9], 4 , -640364487); - d = md5_hh(d, a, b, c, x[i+12], 11, -421815835); - c = md5_hh(c, d, a, b, x[i+15], 16, 530742520); - b = md5_hh(b, c, d, a, x[i+ 2], 23, -995338651); + // nothing in the list, definitely empty. + if (list.length === 0) + return null; - a = md5_ii(a, b, c, d, x[i+ 0], 6 , -198630844); - d = md5_ii(d, a, b, c, x[i+ 7], 10, 1126891415); - c = md5_ii(c, d, a, b, x[i+14], 15, -1416354905); - b = md5_ii(b, c, d, a, x[i+ 5], 21, -57434055); - a = md5_ii(a, b, c, d, x[i+12], 6 , 1700485571); - d = md5_ii(d, a, b, c, x[i+ 3], 10, -1894986606); - c = md5_ii(c, d, a, b, x[i+10], 15, -1051523); - b = md5_ii(b, c, d, a, x[i+ 1], 21, -2054922799); - a = md5_ii(a, b, c, d, x[i+ 8], 6 , 1873313359); - d = md5_ii(d, a, b, c, x[i+15], 10, -30611744); - c = md5_ii(c, d, a, b, x[i+ 6], 15, -1560198380); - b = md5_ii(b, c, d, a, x[i+13], 21, 1309151649); - a = md5_ii(a, b, c, d, x[i+ 4], 6 , -145523070); - d = md5_ii(d, a, b, c, x[i+11], 10, -1120210379); - c = md5_ii(c, d, a, b, x[i+ 2], 15, 718787259); - b = md5_ii(b, c, d, a, x[i+ 9], 21, -343485551); + if (length === 0) + ret = null; + else if (objectMode) + ret = list.shift(); + else if (!n || n >= length) { + // read it all, truncate the array. + if (stringMode) + ret = list.join(''); + else + ret = Buffer.concat(list, length); + list.length = 0; + } else { + // read just some of it. + if (n < list[0].length) { + // just take a part of the first list item. + // slice is the same for buffers and strings. + var buf = list[0]; + ret = buf.slice(0, n); + list[0] = buf.slice(n); + } else if (n === list[0].length) { + // first list is a perfect match + ret = list.shift(); + } else { + // complex case. + // we have enough to cover it, but it spans past the first buffer. + if (stringMode) + ret = ''; + else + ret = new Buffer(n); - a = safe_add(a, olda); - b = safe_add(b, oldb); - c = safe_add(c, oldc); - d = safe_add(d, oldd); + var c = 0; + for (var i = 0, l = list.length; i < l && c < n; i++) { + var buf = list[0]; + var cpy = Math.min(n - c, buf.length); + + if (stringMode) + ret += buf.slice(0, cpy); + else + buf.copy(ret, c, 0, cpy); + + if (cpy < buf.length) + list[0] = buf.slice(cpy); + else + list.shift(); + + c += cpy; + } + } } - return Array(a, b, c, d); + return ret; } -/* - * These functions implement the four basic operations the algorithm uses. - */ -function md5_cmn(q, a, b, x, s, t) -{ - return safe_add(bit_rol(safe_add(safe_add(a, q), safe_add(x, t)), s),b); +function endReadable(stream) { + var state = stream._readableState; + + // If we get here before consuming all the bytes, then that is a + // bug in node. Should never happen. + if (state.length > 0) + throw new Error('endReadable called on non-empty stream'); + + if (!state.endEmitted) { + state.ended = true; + process.nextTick(function() { + // Check that we didn't get one last unshift. + if (!state.endEmitted && state.length === 0) { + state.endEmitted = true; + stream.readable = false; + stream.emit('end'); + } + }); + } } -function md5_ff(a, b, c, d, x, s, t) -{ - return md5_cmn((b & c) | ((~b) & d), a, b, x, s, t); + +function forEach (xs, f) { + for (var i = 0, l = xs.length; i < l; i++) { + f(xs[i], i); + } } -function md5_gg(a, b, c, d, x, s, t) -{ - return md5_cmn((b & d) | (c & (~d)), a, b, x, s, t); + +function indexOf (xs, x) { + for (var i = 0, l = xs.length; i < l; i++) { + if (xs[i] === x) return i; + } + return -1; } -function md5_hh(a, b, c, d, x, s, t) -{ - return md5_cmn(b ^ c ^ d, a, b, x, s, t); -} -function md5_ii(a, b, c, d, x, s, t) -{ - return md5_cmn(c ^ (b | (~d)), a, b, x, s, t); -} - -/* - * Add integers, wrapping at 2^32. This uses 16-bit operations internally - * to work around bugs in some JS interpreters. - */ -function safe_add(x, y) -{ - var lsw = (x & 0xFFFF) + (y & 0xFFFF); - var msw = (x >> 16) + (y >> 16) + (lsw >> 16); - return (msw << 16) | (lsw & 0xFFFF); -} - -/* - * Bitwise rotate a 32-bit number to the left. - */ -function bit_rol(num, cnt) -{ - return (num << cnt) | (num >>> (32 - cnt)); -} - -module.exports = function md5(buf) { - return helpers.hash(buf, core_md5, 16); -}; -},{"./helpers":135}],137:[function(require,module,exports){ -(function (Buffer){ -/* -CryptoJS v3.1.2 -code.google.com/p/crypto-js -(c) 2009-2013 by Jeff Mott. All rights reserved. -code.google.com/p/crypto-js/wiki/License -*/ -/** @preserve -(c) 2012 by Cédric Mesnil. All rights reserved. -Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: - - - Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. - - Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. +}).call(this,require('_process')) +},{"./_stream_duplex":200,"_process":194,"buffer":47,"core-util-is":205,"events":191,"inherits":240,"isarray":193,"stream":210,"string_decoder/":211,"util":46}],203:[function(require,module,exports){ +// Copyright Joyent, Inc. and other Node contributors. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to permit +// persons to whom the Software is furnished to do so, subject to the +// following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +// USE OR OTHER DEALINGS IN THE SOFTWARE. -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ -// constants table -var zl = [ - 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, - 7, 4, 13, 1, 10, 6, 15, 3, 12, 0, 9, 5, 2, 14, 11, 8, - 3, 10, 14, 4, 9, 15, 8, 1, 2, 7, 0, 6, 13, 11, 5, 12, - 1, 9, 11, 10, 0, 8, 12, 4, 13, 3, 7, 15, 14, 5, 6, 2, - 4, 0, 5, 9, 7, 12, 2, 10, 14, 1, 3, 8, 11, 6, 15, 13] +// a transform stream is a readable/writable stream where you do +// something with the data. Sometimes it's called a "filter", +// but that's not a great name for it, since that implies a thing where +// some bits pass through, and others are simply ignored. (That would +// be a valid example of a transform, of course.) +// +// While the output is causally related to the input, it's not a +// necessarily symmetric or synchronous transformation. For example, +// a zlib stream might take multiple plain-text writes(), and then +// emit a single compressed chunk some time in the future. +// +// Here's how this works: +// +// The Transform stream has all the aspects of the readable and writable +// stream classes. When you write(chunk), that calls _write(chunk,cb) +// internally, and returns false if there's a lot of pending writes +// buffered up. When you call read(), that calls _read(n) until +// there's enough pending readable data buffered up. +// +// In a transform stream, the written data is placed in a buffer. When +// _read(n) is called, it transforms the queued up data, calling the +// buffered _write cb's as it consumes chunks. If consuming a single +// written chunk would result in multiple output chunks, then the first +// outputted bit calls the readcb, and subsequent chunks just go into +// the read buffer, and will cause it to emit 'readable' if necessary. +// +// This way, back-pressure is actually determined by the reading side, +// since _read has to be called to start processing a new chunk. However, +// a pathological inflate type of transform can cause excessive buffering +// here. For example, imagine a stream where every byte of input is +// interpreted as an integer from 0-255, and then results in that many +// bytes of output. Writing the 4 bytes {ff,ff,ff,ff} would result in +// 1kb of data being output. In this case, you could write a very small +// amount of input, and end up with a very large amount of output. In +// such a pathological inflating mechanism, there'd be no way to tell +// the system to stop doing the transform. A single 4MB write could +// cause the system to run out of memory. +// +// However, even in such a pathological case, only a single written chunk +// would be consumed, and then the rest would wait (un-transformed) until +// the results of the previous transformed chunk were consumed. -var zr = [ - 5, 14, 7, 0, 9, 2, 11, 4, 13, 6, 15, 8, 1, 10, 3, 12, - 6, 11, 3, 7, 0, 13, 5, 10, 14, 15, 8, 12, 4, 9, 1, 2, - 15, 5, 1, 3, 7, 14, 6, 9, 11, 8, 12, 2, 10, 0, 4, 13, - 8, 6, 4, 1, 3, 11, 15, 0, 5, 12, 2, 13, 9, 7, 10, 14, - 12, 15, 10, 4, 1, 5, 8, 7, 6, 2, 13, 14, 0, 3, 9, 11] +module.exports = Transform; -var sl = [ - 11, 14, 15, 12, 5, 8, 7, 9, 11, 13, 14, 15, 6, 7, 9, 8, - 7, 6, 8, 13, 11, 9, 7, 15, 7, 12, 15, 9, 11, 7, 13, 12, - 11, 13, 6, 7, 14, 9, 13, 15, 14, 8, 13, 6, 5, 12, 7, 5, - 11, 12, 14, 15, 14, 15, 9, 8, 9, 14, 5, 6, 8, 6, 5, 12, - 9, 15, 5, 11, 6, 8, 13, 12, 5, 12, 13, 14, 11, 8, 5, 6 ] +var Duplex = require('./_stream_duplex'); -var sr = [ - 8, 9, 9, 11, 13, 15, 15, 5, 7, 7, 8, 11, 14, 14, 12, 6, - 9, 13, 15, 7, 12, 8, 9, 11, 7, 7, 12, 7, 6, 15, 13, 11, - 9, 7, 15, 11, 8, 6, 6, 14, 12, 13, 5, 14, 13, 13, 7, 5, - 15, 5, 8, 11, 14, 14, 6, 14, 6, 9, 12, 9, 12, 5, 15, 8, - 8, 5, 12, 9, 12, 5, 14, 6, 8, 13, 6, 5, 15, 13, 11, 11 ] +/**/ +var util = require('core-util-is'); +util.inherits = require('inherits'); +/**/ +util.inherits(Transform, Duplex); -var hl = [0x00000000, 0x5A827999, 0x6ED9EBA1, 0x8F1BBCDC, 0xA953FD4E] -var hr = [0x50A28BE6, 0x5C4DD124, 0x6D703EF3, 0x7A6D76E9, 0x00000000] -function bytesToWords(bytes) { - var words = [] - for (var i = 0, b = 0; i < bytes.length; i++, b += 8) { - words[b >>> 5] |= bytes[i] << (24 - b % 32) - } - return words -} +function TransformState(options, stream) { + this.afterTransform = function(er, data) { + return afterTransform(stream, er, data); + }; -function wordsToBytes(words) { - var bytes = [] - for (var b = 0; b < words.length * 32; b += 8) { - bytes.push((words[b >>> 5] >>> (24 - b % 32)) & 0xFF) - } - return bytes + this.needTransform = false; + this.transforming = false; + this.writecb = null; + this.writechunk = null; } -function processBlock(H, M, offset) { - // swap endian - for (var i = 0; i < 16; i++) { - var offset_i = offset + i; - var M_offset_i = M[offset_i] +function afterTransform(stream, er, data) { + var ts = stream._transformState; + ts.transforming = false; - // Swap - M[offset_i] = ( - (((M_offset_i << 8) | (M_offset_i >>> 24)) & 0x00ff00ff) | - (((M_offset_i << 24) | (M_offset_i >>> 8)) & 0xff00ff00) - ) - } + var cb = ts.writecb; - // Working variables - var al, bl, cl, dl, el - var ar, br, cr, dr, er + if (!cb) + return stream.emit('error', new Error('no writecb in Transform class')); - ar = al = H[0] - br = bl = H[1] - cr = cl = H[2] - dr = dl = H[3] - er = el = H[4] + ts.writechunk = null; + ts.writecb = null; - // computation - var t - for (var i = 0; i < 80; i += 1) { - t = (al + M[offset+zl[i]])|0 - if (i<16){ - t += f1(bl,cl,dl) + hl[0] - } else if (i<32) { - t += f2(bl,cl,dl) + hl[1] - } else if (i<48) { - t += f3(bl,cl,dl) + hl[2] - } else if (i<64) { - t += f4(bl,cl,dl) + hl[3] - } else {// if (i<80) { - t += f5(bl,cl,dl) + hl[4] - } - t = t|0 - t = rotl(t,sl[i]) - t = (t+el)|0 - al = el - el = dl - dl = rotl(cl, 10) - cl = bl - bl = t + if (!util.isNullOrUndefined(data)) + stream.push(data); - t = (ar + M[offset+zr[i]])|0 - if (i<16) { - t += f5(br,cr,dr) + hr[0] - } else if (i<32) { - t += f4(br,cr,dr) + hr[1] - } else if (i<48) { - t += f3(br,cr,dr) + hr[2] - } else if (i<64) { - t += f2(br,cr,dr) + hr[3] - } else {// if (i<80) { - t += f1(br,cr,dr) + hr[4] - } + if (cb) + cb(er); - t = t|0 - t = rotl(t,sr[i]) - t = (t+er)|0 - ar = er - er = dr - dr = rotl(cr, 10) - cr = br - br = t + var rs = stream._readableState; + rs.reading = false; + if (rs.needReadable || rs.length < rs.highWaterMark) { + stream._read(rs.highWaterMark); } - - // intermediate hash value - t = (H[1] + cl + dr)|0 - H[1] = (H[2] + dl + er)|0 - H[2] = (H[3] + el + ar)|0 - H[3] = (H[4] + al + br)|0 - H[4] = (H[0] + bl + cr)|0 - H[0] = t -} - -function f1(x, y, z) { - return ((x) ^ (y) ^ (z)) } -function f2(x, y, z) { - return (((x)&(y)) | ((~x)&(z))) -} -function f3(x, y, z) { - return (((x) | (~(y))) ^ (z)) -} +function Transform(options) { + if (!(this instanceof Transform)) + return new Transform(options); -function f4(x, y, z) { - return (((x) & (z)) | ((y)&(~(z)))) -} + Duplex.call(this, options); -function f5(x, y, z) { - return ((x) ^ ((y) |(~(z)))) -} + this._transformState = new TransformState(options, this); -function rotl(x,n) { - return (x<>>(32-n)) -} + // when the writable side finishes, then flush out anything remaining. + var stream = this; -function ripemd160(message) { - var H = [0x67452301, 0xEFCDAB89, 0x98BADCFE, 0x10325476, 0xC3D2E1F0] + // start out asking for a readable event once data is transformed. + this._readableState.needReadable = true; - if (typeof message == 'string') - message = new Buffer(message, 'utf8') + // we have implemented the _read method, and done the other things + // that Readable wants before the first _read call, so unset the + // sync guard flag. + this._readableState.sync = false; - var m = bytesToWords(message) + this.once('prefinish', function() { + if (util.isFunction(this._flush)) + this._flush(function(er) { + done(stream, er); + }); + else + done(stream); + }); +} - var nBitsLeft = message.length * 8 - var nBitsTotal = message.length * 8 +Transform.prototype.push = function(chunk, encoding) { + this._transformState.needTransform = false; + return Duplex.prototype.push.call(this, chunk, encoding); +}; - // Add padding - m[nBitsLeft >>> 5] |= 0x80 << (24 - nBitsLeft % 32) - m[(((nBitsLeft + 64) >>> 9) << 4) + 14] = ( - (((nBitsTotal << 8) | (nBitsTotal >>> 24)) & 0x00ff00ff) | - (((nBitsTotal << 24) | (nBitsTotal >>> 8)) & 0xff00ff00) - ) +// This is the part where you do stuff! +// override this function in implementation classes. +// 'chunk' is an input chunk. +// +// Call `push(newChunk)` to pass along transformed output +// to the readable side. You may call 'push' zero or more times. +// +// Call `cb(err)` when you are done with this chunk. If you pass +// an error, then that'll put the hurt on the whole operation. If you +// never call cb(), then you'll never get another chunk. +Transform.prototype._transform = function(chunk, encoding, cb) { + throw new Error('not implemented'); +}; - for (var i=0 ; i>> 24)) & 0x00ff00ff) | - (((H_i << 24) | (H_i >>> 8)) & 0xff00ff00) + if (!util.isNull(ts.writechunk) && ts.writecb && !ts.transforming) { + ts.transforming = true; + this._transform(ts.writechunk, ts.writeencoding, ts.afterTransform); + } else { + // mark that we need a transform, so that any data that comes in + // will get processed, now that we've asked for it. + ts.needTransform = true; } +}; - var digestbytes = wordsToBytes(H) - return new Buffer(digestbytes) -} - -module.exports = ripemd160 - -}).call(this,require("buffer").Buffer) -},{"buffer":42}],138:[function(require,module,exports){ -(function (Buffer){ -//prototype class for hash functions -function Hash (blockSize, finalSize) { - this._block = new Buffer(blockSize) //new Uint32Array(blockSize/4) - this._finalSize = finalSize - this._blockSize = blockSize - this._len = 0 - this._s = 0 -} -Hash.prototype.update = function (data, enc) { - if ("string" === typeof data) { - enc = enc || "utf8" - data = new Buffer(data, enc) - } +function done(stream, er) { + if (er) + return stream.emit('error', er); - var l = this._len += data.length - var s = this._s || 0 - var f = 0 - var buffer = this._block + // if there's nothing in the write buffer, then that means + // that nothing more will ever be provided + var ws = stream._writableState; + var ts = stream._transformState; - while (s < l) { - var t = Math.min(data.length, f + this._blockSize - (s % this._blockSize)) - var ch = (t - f) + if (ws.length) + throw new Error('calling transform done when ws.length != 0'); - for (var i = 0; i < ch; i++) { - buffer[(s % this._blockSize) + i] = data[i + f] - } + if (ts.transforming) + throw new Error('calling transform done when still transforming'); - s += ch - f += ch + return stream.push(null); +} - if ((s % this._blockSize) === 0) { - this._update(buffer) - } - } - this._s = s +},{"./_stream_duplex":200,"core-util-is":205,"inherits":240}],204:[function(require,module,exports){ +(function (process){ +// Copyright Joyent, Inc. and other Node contributors. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to permit +// persons to whom the Software is furnished to do so, subject to the +// following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +// USE OR OTHER DEALINGS IN THE SOFTWARE. - return this -} +// A bit simpler than readable streams. +// Implement an async ._write(chunk, cb), and it'll handle all +// the drain event emission and buffering. -Hash.prototype.digest = function (enc) { - // Suppose the length of the message M, in bits, is l - var l = this._len * 8 +module.exports = Writable; - // Append the bit 1 to the end of the message - this._block[this._len % this._blockSize] = 0x80 +/**/ +var Buffer = require('buffer').Buffer; +/**/ - // and then k zero bits, where k is the smallest non-negative solution to the equation (l + 1 + k) === finalSize mod blockSize - this._block.fill(0, this._len % this._blockSize + 1) +Writable.WritableState = WritableState; - if (l % (this._blockSize * 8) >= this._finalSize * 8) { - this._update(this._block) - this._block.fill(0) - } - // to this append the block which is equal to the number l written in binary - // TODO: handle case where l is > Math.pow(2, 29) - this._block.writeInt32BE(l, this._blockSize - 4) +/**/ +var util = require('core-util-is'); +util.inherits = require('inherits'); +/**/ - var hash = this._update(this._block) || this._hash() +var Stream = require('stream'); - return enc ? hash.toString(enc) : hash -} +util.inherits(Writable, Stream); -Hash.prototype._update = function () { - throw new Error('_update must be implemented by subclass') +function WriteReq(chunk, encoding, cb) { + this.chunk = chunk; + this.encoding = encoding; + this.callback = cb; } -module.exports = Hash +function WritableState(options, stream) { + var Duplex = require('./_stream_duplex'); -}).call(this,require("buffer").Buffer) -},{"buffer":42}],139:[function(require,module,exports){ -var exports = module.exports = function (alg) { - var Alg = exports[alg.toLowerCase()] - if(!Alg) throw new Error(alg + ' is not supported (we accept pull requests)') - return new Alg() -} + options = options || {}; + // the point at which write() starts returning false + // Note: 0 is a valid value, means that we always return false if + // the entire buffer is not flushed immediately on write() + var hwm = options.highWaterMark; + var defaultHwm = options.objectMode ? 16 : 16 * 1024; + this.highWaterMark = (hwm || hwm === 0) ? hwm : defaultHwm; -exports.sha1 = require('./sha1') -exports.sha224 = require('./sha224') -exports.sha256 = require('./sha256') -exports.sha384 = require('./sha384') -exports.sha512 = require('./sha512') + // object stream flag to indicate whether or not this stream + // contains buffers or objects. + this.objectMode = !!options.objectMode; -},{"./sha1":140,"./sha224":141,"./sha256":142,"./sha384":143,"./sha512":144}],140:[function(require,module,exports){ -(function (Buffer){ -/* - * A JavaScript implementation of the Secure Hash Algorithm, SHA-1, as defined - * in FIPS PUB 180-1 - * Version 2.1a Copyright Paul Johnston 2000 - 2002. - * Other contributors: Greg Holt, Andrew Kepert, Ydnar, Lostinet - * Distributed under the BSD License - * See http://pajhome.org.uk/crypt/md5 for details. - */ + if (stream instanceof Duplex) + this.objectMode = this.objectMode || !!options.writableObjectMode; -var inherits = require('inherits') -var Hash = require('./hash') + // cast to ints. + this.highWaterMark = ~~this.highWaterMark; -var W = new Array(80) + this.needDrain = false; + // at the start of calling end() + this.ending = false; + // when end() has been called, and returned + this.ended = false; + // when 'finish' is emitted + this.finished = false; -function Sha1() { - this.init() - this._w = W + // should we decode strings into buffers before passing to _write? + // this is here so that some node-core streams can optimize string + // handling at a lower level. + var noDecode = options.decodeStrings === false; + this.decodeStrings = !noDecode; - Hash.call(this, 64, 56) -} + // Crypto is kind of old and crusty. Historically, its default string + // encoding is 'binary' so we have to make this configurable. + // Everything else in the universe uses 'utf8', though. + this.defaultEncoding = options.defaultEncoding || 'utf8'; -inherits(Sha1, Hash) + // not an actual buffer we keep track of, but a measurement + // of how much we're waiting to get pushed to some underlying + // socket or file. + this.length = 0; -Sha1.prototype.init = function () { - this._a = 0x67452301 - this._b = 0xefcdab89 - this._c = 0x98badcfe - this._d = 0x10325476 - this._e = 0xc3d2e1f0 + // a flag to see when we're in the middle of a write. + this.writing = false; - return this -} + // when true all writes will be buffered until .uncork() call + this.corked = 0; -/* - * Bitwise rotate a 32-bit number to the left. - */ -function rol(num, cnt) { - return (num << cnt) | (num >>> (32 - cnt)); -} + // a flag to be able to tell if the onwrite cb is called immediately, + // or on a later tick. We set this to true at first, because any + // actions that shouldn't happen until "later" should generally also + // not happen before the first write call. + this.sync = true; -Sha1.prototype._update = function (M) { - var W = this._w + // a flag to know if we're processing previously buffered items, which + // may call the _write() callback in the same tick, so that we don't + // end up in an overlapped onwrite situation. + this.bufferProcessing = false; - var a = this._a - var b = this._b - var c = this._c - var d = this._d - var e = this._e + // the callback that's passed to _write(chunk,cb) + this.onwrite = function(er) { + onwrite(stream, er); + }; - var j = 0, k + // the callback that the user supplies to write(chunk,encoding,cb) + this.writecb = null; - function calcW() { return rol(W[j - 3] ^ W[j - 8] ^ W[j - 14] ^ W[j - 16], 1) } - function loop(w, f) { - W[j] = w + // the amount that is being written when _write is called. + this.writelen = 0; - var t = rol(a, 5) + f + e + w + k + this.buffer = []; - e = d - d = c - c = rol(b, 30) - b = a - a = t - j++ - } + // number of pending user-supplied write callbacks + // this must be 0 before 'finish' can be emitted + this.pendingcb = 0; - k = 1518500249 - while (j < 16) loop(M.readInt32BE(j * 4), (b & c) | ((~b) & d)) - while (j < 20) loop(calcW(), (b & c) | ((~b) & d)) - k = 1859775393 - while (j < 40) loop(calcW(), b ^ c ^ d) - k = -1894007588 - while (j < 60) loop(calcW(), (b & c) | (b & d) | (c & d)) - k = -899497514 - while (j < 80) loop(calcW(), b ^ c ^ d) + // emit prefinish if the only thing we're waiting for is _write cbs + // This is relevant for synchronous Transform streams + this.prefinished = false; - this._a = (a + this._a) | 0 - this._b = (b + this._b) | 0 - this._c = (c + this._c) | 0 - this._d = (d + this._d) | 0 - this._e = (e + this._e) | 0 + // True if the error was already emitted and should not be thrown again + this.errorEmitted = false; } -Sha1.prototype._hash = function () { - var H = new Buffer(20) +function Writable(options) { + var Duplex = require('./_stream_duplex'); - H.writeInt32BE(this._a|0, 0) - H.writeInt32BE(this._b|0, 4) - H.writeInt32BE(this._c|0, 8) - H.writeInt32BE(this._d|0, 12) - H.writeInt32BE(this._e|0, 16) + // Writable ctor is applied to Duplexes, though they're not + // instanceof Writable, they're instanceof Readable. + if (!(this instanceof Writable) && !(this instanceof Duplex)) + return new Writable(options); - return H + this._writableState = new WritableState(options, this); + + // legacy. + this.writable = true; + + Stream.call(this); } -module.exports = Sha1 +// Otherwise people can pipe Writable streams, which is just wrong. +Writable.prototype.pipe = function() { + this.emit('error', new Error('Cannot pipe. Not readable.')); +}; -}).call(this,require("buffer").Buffer) -},{"./hash":138,"buffer":42,"inherits":229}],141:[function(require,module,exports){ -(function (Buffer){ -/** - * A JavaScript implementation of the Secure Hash Algorithm, SHA-256, as defined - * in FIPS 180-2 - * Version 2.2-beta Copyright Angel Marin, Paul Johnston 2000 - 2009. - * Other contributors: Greg Holt, Andrew Kepert, Ydnar, Lostinet - * - */ - -var inherits = require('inherits') -var SHA256 = require('./sha256') -var Hash = require('./hash') +function writeAfterEnd(stream, state, cb) { + var er = new Error('write after end'); + // TODO: defer error events consistently everywhere, not just the cb + stream.emit('error', er); + process.nextTick(function() { + cb(er); + }); +} -var W = new Array(64) +// If we get something that is not a buffer, string, null, or undefined, +// and we're not in objectMode, then that's an error. +// Otherwise stream chunks are all considered to be of length=1, and the +// watermarks determine how many objects to keep in the buffer, rather than +// how many bytes or characters. +function validChunk(stream, state, chunk, cb) { + var valid = true; + if (!util.isBuffer(chunk) && + !util.isString(chunk) && + !util.isNullOrUndefined(chunk) && + !state.objectMode) { + var er = new TypeError('Invalid non-string/buffer chunk'); + stream.emit('error', er); + process.nextTick(function() { + cb(er); + }); + valid = false; + } + return valid; +} -function Sha224() { - this.init() +Writable.prototype.write = function(chunk, encoding, cb) { + var state = this._writableState; + var ret = false; - this._w = W // new Array(64) + if (util.isFunction(encoding)) { + cb = encoding; + encoding = null; + } - Hash.call(this, 64, 56) -} + if (util.isBuffer(chunk)) + encoding = 'buffer'; + else if (!encoding) + encoding = state.defaultEncoding; -inherits(Sha224, SHA256) + if (!util.isFunction(cb)) + cb = function() {}; -Sha224.prototype.init = function () { - this._a = 0xc1059ed8|0 - this._b = 0x367cd507|0 - this._c = 0x3070dd17|0 - this._d = 0xf70e5939|0 - this._e = 0xffc00b31|0 - this._f = 0x68581511|0 - this._g = 0x64f98fa7|0 - this._h = 0xbefa4fa4|0 + if (state.ended) + writeAfterEnd(this, state, cb); + else if (validChunk(this, state, chunk, cb)) { + state.pendingcb++; + ret = writeOrBuffer(this, state, chunk, encoding, cb); + } - return this -} + return ret; +}; -Sha224.prototype._hash = function () { - var H = new Buffer(28) +Writable.prototype.cork = function() { + var state = this._writableState; - H.writeInt32BE(this._a, 0) - H.writeInt32BE(this._b, 4) - H.writeInt32BE(this._c, 8) - H.writeInt32BE(this._d, 12) - H.writeInt32BE(this._e, 16) - H.writeInt32BE(this._f, 20) - H.writeInt32BE(this._g, 24) + state.corked++; +}; - return H -} +Writable.prototype.uncork = function() { + var state = this._writableState; -module.exports = Sha224 + if (state.corked) { + state.corked--; -}).call(this,require("buffer").Buffer) -},{"./hash":138,"./sha256":142,"buffer":42,"inherits":229}],142:[function(require,module,exports){ -(function (Buffer){ -/** - * A JavaScript implementation of the Secure Hash Algorithm, SHA-256, as defined - * in FIPS 180-2 - * Version 2.2-beta Copyright Angel Marin, Paul Johnston 2000 - 2009. - * Other contributors: Greg Holt, Andrew Kepert, Ydnar, Lostinet - * - */ + if (!state.writing && + !state.corked && + !state.finished && + !state.bufferProcessing && + state.buffer.length) + clearBuffer(this, state); + } +}; -var inherits = require('inherits') -var Hash = require('./hash') +function decodeChunk(state, chunk, encoding) { + if (!state.objectMode && + state.decodeStrings !== false && + util.isString(chunk)) { + chunk = new Buffer(chunk, encoding); + } + return chunk; +} -var K = [ - 0x428A2F98, 0x71374491, 0xB5C0FBCF, 0xE9B5DBA5, - 0x3956C25B, 0x59F111F1, 0x923F82A4, 0xAB1C5ED5, - 0xD807AA98, 0x12835B01, 0x243185BE, 0x550C7DC3, - 0x72BE5D74, 0x80DEB1FE, 0x9BDC06A7, 0xC19BF174, - 0xE49B69C1, 0xEFBE4786, 0x0FC19DC6, 0x240CA1CC, - 0x2DE92C6F, 0x4A7484AA, 0x5CB0A9DC, 0x76F988DA, - 0x983E5152, 0xA831C66D, 0xB00327C8, 0xBF597FC7, - 0xC6E00BF3, 0xD5A79147, 0x06CA6351, 0x14292967, - 0x27B70A85, 0x2E1B2138, 0x4D2C6DFC, 0x53380D13, - 0x650A7354, 0x766A0ABB, 0x81C2C92E, 0x92722C85, - 0xA2BFE8A1, 0xA81A664B, 0xC24B8B70, 0xC76C51A3, - 0xD192E819, 0xD6990624, 0xF40E3585, 0x106AA070, - 0x19A4C116, 0x1E376C08, 0x2748774C, 0x34B0BCB5, - 0x391C0CB3, 0x4ED8AA4A, 0x5B9CCA4F, 0x682E6FF3, - 0x748F82EE, 0x78A5636F, 0x84C87814, 0x8CC70208, - 0x90BEFFFA, 0xA4506CEB, 0xBEF9A3F7, 0xC67178F2 -] +// if we're already writing something, then just put this +// in the queue, and wait our turn. Otherwise, call _write +// If we return false, then we need a drain event, so set that flag. +function writeOrBuffer(stream, state, chunk, encoding, cb) { + chunk = decodeChunk(state, chunk, encoding); + if (util.isBuffer(chunk)) + encoding = 'buffer'; + var len = state.objectMode ? 1 : chunk.length; -var W = new Array(64) + state.length += len; -function Sha256() { - this.init() + var ret = state.length < state.highWaterMark; + // we must ensure that previous needDrain will not be reset to false. + if (!ret) + state.needDrain = true; - this._w = W // new Array(64) + if (state.writing || state.corked) + state.buffer.push(new WriteReq(chunk, encoding, cb)); + else + doWrite(stream, state, false, len, chunk, encoding, cb); - Hash.call(this, 64, 56) + return ret; } -inherits(Sha256, Hash) +function doWrite(stream, state, writev, len, chunk, encoding, cb) { + state.writelen = len; + state.writecb = cb; + state.writing = true; + state.sync = true; + if (writev) + stream._writev(chunk, state.onwrite); + else + stream._write(chunk, encoding, state.onwrite); + state.sync = false; +} -Sha256.prototype.init = function () { - this._a = 0x6a09e667|0 - this._b = 0xbb67ae85|0 - this._c = 0x3c6ef372|0 - this._d = 0xa54ff53a|0 - this._e = 0x510e527f|0 - this._f = 0x9b05688c|0 - this._g = 0x1f83d9ab|0 - this._h = 0x5be0cd19|0 +function onwriteError(stream, state, sync, er, cb) { + if (sync) + process.nextTick(function() { + state.pendingcb--; + cb(er); + }); + else { + state.pendingcb--; + cb(er); + } - return this + stream._writableState.errorEmitted = true; + stream.emit('error', er); } -function S (X, n) { - return (X >>> n) | (X << (32 - n)); +function onwriteStateUpdate(state) { + state.writing = false; + state.writecb = null; + state.length -= state.writelen; + state.writelen = 0; } -function R (X, n) { - return (X >>> n); -} +function onwrite(stream, er) { + var state = stream._writableState; + var sync = state.sync; + var cb = state.writecb; -function Ch (x, y, z) { - return ((x & y) ^ ((~x) & z)); -} + onwriteStateUpdate(state); -function Maj (x, y, z) { - return ((x & y) ^ (x & z) ^ (y & z)); -} + if (er) + onwriteError(stream, state, sync, er, cb); + else { + // Check if we're actually ready to finish, but don't emit yet + var finished = needFinish(stream, state); -function Sigma0256 (x) { - return (S(x, 2) ^ S(x, 13) ^ S(x, 22)); -} + if (!finished && + !state.corked && + !state.bufferProcessing && + state.buffer.length) { + clearBuffer(stream, state); + } -function Sigma1256 (x) { - return (S(x, 6) ^ S(x, 11) ^ S(x, 25)); + if (sync) { + process.nextTick(function() { + afterWrite(stream, state, finished, cb); + }); + } else { + afterWrite(stream, state, finished, cb); + } + } } -function Gamma0256 (x) { - return (S(x, 7) ^ S(x, 18) ^ R(x, 3)); +function afterWrite(stream, state, finished, cb) { + if (!finished) + onwriteDrain(stream, state); + state.pendingcb--; + cb(); + finishMaybe(stream, state); } -function Gamma1256 (x) { - return (S(x, 17) ^ S(x, 19) ^ R(x, 10)); +// Must force callback to be called on nextTick, so that we don't +// emit 'drain' before the write() consumer gets the 'false' return +// value, and has a chance to attach a 'drain' listener. +function onwriteDrain(stream, state) { + if (state.length === 0 && state.needDrain) { + state.needDrain = false; + stream.emit('drain'); + } } -Sha256.prototype._update = function(M) { - var W = this._w - - var a = this._a | 0 - var b = this._b | 0 - var c = this._c | 0 - var d = this._d | 0 - var e = this._e | 0 - var f = this._f | 0 - var g = this._g | 0 - var h = this._h | 0 - - var j = 0 - function calcW() { return Gamma1256(W[j - 2]) + W[j - 7] + Gamma0256(W[j - 15]) + W[j - 16] } - function loop(w) { - W[j] = w +// if there's something in the buffer waiting, then process it +function clearBuffer(stream, state) { + state.bufferProcessing = true; - var T1 = h + Sigma1256(e) + Ch(e, f, g) + K[j] + w - var T2 = Sigma0256(a) + Maj(a, b, c); + if (stream._writev && state.buffer.length > 1) { + // Fast case, write everything using _writev() + var cbs = []; + for (var c = 0; c < state.buffer.length; c++) + cbs.push(state.buffer[c].callback); + + // count the one we are adding, as well. + // TODO(isaacs) clean this up + state.pendingcb++; + doWrite(stream, state, true, state.length, state.buffer, '', function(err) { + for (var i = 0; i < cbs.length; i++) { + state.pendingcb--; + cbs[i](err); + } + }); - h = g; - g = f; - f = e; - e = d + T1; - d = c; - c = b; - b = a; - a = T1 + T2; + // Clear buffer + state.buffer = []; + } else { + // Slow case, write chunks one-by-one + for (var c = 0; c < state.buffer.length; c++) { + var entry = state.buffer[c]; + var chunk = entry.chunk; + var encoding = entry.encoding; + var cb = entry.callback; + var len = state.objectMode ? 1 : chunk.length; + + doWrite(stream, state, false, len, chunk, encoding, cb); + + // if we didn't call the onwrite immediately, then + // it means that we need to wait until it does. + // also, that means that the chunk and cb are currently + // being processed, so move the buffer counter past them. + if (state.writing) { + c++; + break; + } + } - j++ + if (c < state.buffer.length) + state.buffer = state.buffer.slice(c); + else + state.buffer.length = 0; } - while (j < 16) loop(M.readInt32BE(j * 4)) - while (j < 64) loop(calcW()) + state.bufferProcessing = false; +} + +Writable.prototype._write = function(chunk, encoding, cb) { + cb(new Error('not implemented')); - this._a = (a + this._a) | 0 - this._b = (b + this._b) | 0 - this._c = (c + this._c) | 0 - this._d = (d + this._d) | 0 - this._e = (e + this._e) | 0 - this._f = (f + this._f) | 0 - this._g = (g + this._g) | 0 - this._h = (h + this._h) | 0 }; -Sha256.prototype._hash = function () { - var H = new Buffer(32) +Writable.prototype._writev = null; - H.writeInt32BE(this._a, 0) - H.writeInt32BE(this._b, 4) - H.writeInt32BE(this._c, 8) - H.writeInt32BE(this._d, 12) - H.writeInt32BE(this._e, 16) - H.writeInt32BE(this._f, 20) - H.writeInt32BE(this._g, 24) - H.writeInt32BE(this._h, 28) +Writable.prototype.end = function(chunk, encoding, cb) { + var state = this._writableState; - return H -} + if (util.isFunction(chunk)) { + cb = chunk; + chunk = null; + encoding = null; + } else if (util.isFunction(encoding)) { + cb = encoding; + encoding = null; + } -module.exports = Sha256 + if (!util.isNullOrUndefined(chunk)) + this.write(chunk, encoding); -}).call(this,require("buffer").Buffer) -},{"./hash":138,"buffer":42,"inherits":229}],143:[function(require,module,exports){ -(function (Buffer){ -var inherits = require('inherits') -var SHA512 = require('./sha512'); -var Hash = require('./hash') + // .end() fully uncorks + if (state.corked) { + state.corked = 1; + this.uncork(); + } -var W = new Array(160) + // ignore unnecessary end() calls. + if (!state.ending && !state.finished) + endWritable(this, state, cb); +}; -function Sha384() { - this.init() - this._w = W - Hash.call(this, 128, 112) +function needFinish(stream, state) { + return (state.ending && + state.length === 0 && + !state.finished && + !state.writing); } -inherits(Sha384, SHA512) - -Sha384.prototype.init = function () { - this._a = 0xcbbb9d5d|0 - this._b = 0x629a292a|0 - this._c = 0x9159015a|0 - this._d = 0x152fecd8|0 - this._e = 0x67332667|0 - this._f = 0x8eb44a87|0 - this._g = 0xdb0c2e0d|0 - this._h = 0x47b5481d|0 - - this._al = 0xc1059ed8|0 - this._bl = 0x367cd507|0 - this._cl = 0x3070dd17|0 - this._dl = 0xf70e5939|0 - this._el = 0xffc00b31|0 - this._fl = 0x68581511|0 - this._gl = 0x64f98fa7|0 - this._hl = 0xbefa4fa4|0 - - return this +function prefinish(stream, state) { + if (!state.prefinished) { + state.prefinished = true; + stream.emit('prefinish'); + } } -Sha384.prototype._hash = function () { - var H = new Buffer(48) - - function writeInt64BE(h, l, offset) { - H.writeInt32BE(h, offset) - H.writeInt32BE(l, offset + 4) +function finishMaybe(stream, state) { + var need = needFinish(stream, state); + if (need) { + if (state.pendingcb === 0) { + prefinish(stream, state); + state.finished = true; + stream.emit('finish'); + } else + prefinish(stream, state); } - - writeInt64BE(this._a, this._al, 0) - writeInt64BE(this._b, this._bl, 8) - writeInt64BE(this._c, this._cl, 16) - writeInt64BE(this._d, this._dl, 24) - writeInt64BE(this._e, this._el, 32) - writeInt64BE(this._f, this._fl, 40) - - return H + return need; } -module.exports = Sha384 +function endWritable(stream, state, cb) { + state.ending = true; + finishMaybe(stream, state); + if (cb) { + if (state.finished) + process.nextTick(cb); + else + stream.once('finish', cb); + } + state.ended = true; +} -}).call(this,require("buffer").Buffer) -},{"./hash":138,"./sha512":144,"buffer":42,"inherits":229}],144:[function(require,module,exports){ +}).call(this,require('_process')) +},{"./_stream_duplex":200,"_process":194,"buffer":47,"core-util-is":205,"inherits":240,"stream":210}],205:[function(require,module,exports){ (function (Buffer){ -var inherits = require('inherits') -var Hash = require('./hash') +// Copyright Joyent, Inc. and other Node contributors. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to permit +// persons to whom the Software is furnished to do so, subject to the +// following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +// USE OR OTHER DEALINGS IN THE SOFTWARE. -var K = [ - 0x428a2f98, 0xd728ae22, 0x71374491, 0x23ef65cd, - 0xb5c0fbcf, 0xec4d3b2f, 0xe9b5dba5, 0x8189dbbc, - 0x3956c25b, 0xf348b538, 0x59f111f1, 0xb605d019, - 0x923f82a4, 0xaf194f9b, 0xab1c5ed5, 0xda6d8118, - 0xd807aa98, 0xa3030242, 0x12835b01, 0x45706fbe, - 0x243185be, 0x4ee4b28c, 0x550c7dc3, 0xd5ffb4e2, - 0x72be5d74, 0xf27b896f, 0x80deb1fe, 0x3b1696b1, - 0x9bdc06a7, 0x25c71235, 0xc19bf174, 0xcf692694, - 0xe49b69c1, 0x9ef14ad2, 0xefbe4786, 0x384f25e3, - 0x0fc19dc6, 0x8b8cd5b5, 0x240ca1cc, 0x77ac9c65, - 0x2de92c6f, 0x592b0275, 0x4a7484aa, 0x6ea6e483, - 0x5cb0a9dc, 0xbd41fbd4, 0x76f988da, 0x831153b5, - 0x983e5152, 0xee66dfab, 0xa831c66d, 0x2db43210, - 0xb00327c8, 0x98fb213f, 0xbf597fc7, 0xbeef0ee4, - 0xc6e00bf3, 0x3da88fc2, 0xd5a79147, 0x930aa725, - 0x06ca6351, 0xe003826f, 0x14292967, 0x0a0e6e70, - 0x27b70a85, 0x46d22ffc, 0x2e1b2138, 0x5c26c926, - 0x4d2c6dfc, 0x5ac42aed, 0x53380d13, 0x9d95b3df, - 0x650a7354, 0x8baf63de, 0x766a0abb, 0x3c77b2a8, - 0x81c2c92e, 0x47edaee6, 0x92722c85, 0x1482353b, - 0xa2bfe8a1, 0x4cf10364, 0xa81a664b, 0xbc423001, - 0xc24b8b70, 0xd0f89791, 0xc76c51a3, 0x0654be30, - 0xd192e819, 0xd6ef5218, 0xd6990624, 0x5565a910, - 0xf40e3585, 0x5771202a, 0x106aa070, 0x32bbd1b8, - 0x19a4c116, 0xb8d2d0c8, 0x1e376c08, 0x5141ab53, - 0x2748774c, 0xdf8eeb99, 0x34b0bcb5, 0xe19b48a8, - 0x391c0cb3, 0xc5c95a63, 0x4ed8aa4a, 0xe3418acb, - 0x5b9cca4f, 0x7763e373, 0x682e6ff3, 0xd6b2b8a3, - 0x748f82ee, 0x5defb2fc, 0x78a5636f, 0x43172f60, - 0x84c87814, 0xa1f0ab72, 0x8cc70208, 0x1a6439ec, - 0x90befffa, 0x23631e28, 0xa4506ceb, 0xde82bde9, - 0xbef9a3f7, 0xb2c67915, 0xc67178f2, 0xe372532b, - 0xca273ece, 0xea26619c, 0xd186b8c7, 0x21c0c207, - 0xeada7dd6, 0xcde0eb1e, 0xf57d4f7f, 0xee6ed178, - 0x06f067aa, 0x72176fba, 0x0a637dc5, 0xa2c898a6, - 0x113f9804, 0xbef90dae, 0x1b710b35, 0x131c471b, - 0x28db77f5, 0x23047d84, 0x32caab7b, 0x40c72493, - 0x3c9ebe0a, 0x15c9bebc, 0x431d67c4, 0x9c100d4c, - 0x4cc5d4be, 0xcb3e42b6, 0x597f299c, 0xfc657e2a, - 0x5fcb6fab, 0x3ad6faec, 0x6c44198c, 0x4a475817 -] +// NOTE: These type checking functions intentionally don't use `instanceof` +// because it is fragile and can be easily faked with `Object.create()`. +function isArray(ar) { + return Array.isArray(ar); +} +exports.isArray = isArray; -var W = new Array(160) +function isBoolean(arg) { + return typeof arg === 'boolean'; +} +exports.isBoolean = isBoolean; -function Sha512() { - this.init() - this._w = W +function isNull(arg) { + return arg === null; +} +exports.isNull = isNull; - Hash.call(this, 128, 112) +function isNullOrUndefined(arg) { + return arg == null; } +exports.isNullOrUndefined = isNullOrUndefined; -inherits(Sha512, Hash) +function isNumber(arg) { + return typeof arg === 'number'; +} +exports.isNumber = isNumber; -Sha512.prototype.init = function () { - this._a = 0x6a09e667|0 - this._b = 0xbb67ae85|0 - this._c = 0x3c6ef372|0 - this._d = 0xa54ff53a|0 - this._e = 0x510e527f|0 - this._f = 0x9b05688c|0 - this._g = 0x1f83d9ab|0 - this._h = 0x5be0cd19|0 - - this._al = 0xf3bcc908|0 - this._bl = 0x84caa73b|0 - this._cl = 0xfe94f82b|0 - this._dl = 0x5f1d36f1|0 - this._el = 0xade682d1|0 - this._fl = 0x2b3e6c1f|0 - this._gl = 0xfb41bd6b|0 - this._hl = 0x137e2179|0 +function isString(arg) { + return typeof arg === 'string'; +} +exports.isString = isString; - return this +function isSymbol(arg) { + return typeof arg === 'symbol'; } +exports.isSymbol = isSymbol; -function S (X, Xl, n) { - return (X >>> n) | (Xl << (32 - n)) +function isUndefined(arg) { + return arg === void 0; } +exports.isUndefined = isUndefined; -function Ch (x, y, z) { - return ((x & y) ^ ((~x) & z)); +function isRegExp(re) { + return isObject(re) && objectToString(re) === '[object RegExp]'; } +exports.isRegExp = isRegExp; -function Maj (x, y, z) { - return ((x & y) ^ (x & z) ^ (y & z)); +function isObject(arg) { + return typeof arg === 'object' && arg !== null; } +exports.isObject = isObject; -Sha512.prototype._update = function(M) { - var W = this._w +function isDate(d) { + return isObject(d) && objectToString(d) === '[object Date]'; +} +exports.isDate = isDate; - var a = this._a | 0 - var b = this._b | 0 - var c = this._c | 0 - var d = this._d | 0 - var e = this._e | 0 - var f = this._f | 0 - var g = this._g | 0 - var h = this._h | 0 +function isError(e) { + return isObject(e) && + (objectToString(e) === '[object Error]' || e instanceof Error); +} +exports.isError = isError; - var al = this._al | 0 - var bl = this._bl | 0 - var cl = this._cl | 0 - var dl = this._dl | 0 - var el = this._el | 0 - var fl = this._fl | 0 - var gl = this._gl | 0 - var hl = this._hl | 0 +function isFunction(arg) { + return typeof arg === 'function'; +} +exports.isFunction = isFunction; - var i = 0, j = 0 - var Wi, Wil - function calcW() { - var x = W[j - 15*2] - var xl = W[j - 15*2 + 1] - var gamma0 = S(x, xl, 1) ^ S(x, xl, 8) ^ (x >>> 7) - var gamma0l = S(xl, x, 1) ^ S(xl, x, 8) ^ S(xl, x, 7) +function isPrimitive(arg) { + return arg === null || + typeof arg === 'boolean' || + typeof arg === 'number' || + typeof arg === 'string' || + typeof arg === 'symbol' || // ES6 symbol + typeof arg === 'undefined'; +} +exports.isPrimitive = isPrimitive; - x = W[j - 2*2] - xl = W[j - 2*2 + 1] - var gamma1 = S(x, xl, 19) ^ S(xl, x, 29) ^ (x >>> 6) - var gamma1l = S(xl, x, 19) ^ S(x, xl, 29) ^ S(xl, x, 6) +function isBuffer(arg) { + return Buffer.isBuffer(arg); +} +exports.isBuffer = isBuffer; - // W[i] = gamma0 + W[i - 7] + gamma1 + W[i - 16] - var Wi7 = W[j - 7*2] - var Wi7l = W[j - 7*2 + 1] +function objectToString(o) { + return Object.prototype.toString.call(o); +} +}).call(this,{"isBuffer":require("/home/braydon/bitcore/node_modules/bitcore-build/node_modules/browserify/node_modules/insert-module-globals/node_modules/is-buffer/index.js")}) +},{"/home/braydon/bitcore/node_modules/bitcore-build/node_modules/browserify/node_modules/insert-module-globals/node_modules/is-buffer/index.js":192}],206:[function(require,module,exports){ +module.exports = require("./lib/_stream_passthrough.js") - var Wi16 = W[j - 16*2] - var Wi16l = W[j - 16*2 + 1] +},{"./lib/_stream_passthrough.js":201}],207:[function(require,module,exports){ +exports = module.exports = require('./lib/_stream_readable.js'); +exports.Stream = require('stream'); +exports.Readable = exports; +exports.Writable = require('./lib/_stream_writable.js'); +exports.Duplex = require('./lib/_stream_duplex.js'); +exports.Transform = require('./lib/_stream_transform.js'); +exports.PassThrough = require('./lib/_stream_passthrough.js'); - Wil = gamma0l + Wi7l - Wi = gamma0 + Wi7 + ((Wil >>> 0) < (gamma0l >>> 0) ? 1 : 0) - Wil = Wil + gamma1l - Wi = Wi + gamma1 + ((Wil >>> 0) < (gamma1l >>> 0) ? 1 : 0) - Wil = Wil + Wi16l - Wi = Wi + Wi16 + ((Wil >>> 0) < (Wi16l >>> 0) ? 1 : 0) - } +},{"./lib/_stream_duplex.js":200,"./lib/_stream_passthrough.js":201,"./lib/_stream_readable.js":202,"./lib/_stream_transform.js":203,"./lib/_stream_writable.js":204,"stream":210}],208:[function(require,module,exports){ +module.exports = require("./lib/_stream_transform.js") - function loop() { - W[j] = Wi - W[j + 1] = Wil +},{"./lib/_stream_transform.js":203}],209:[function(require,module,exports){ +module.exports = require("./lib/_stream_writable.js") - var maj = Maj(a, b, c) - var majl = Maj(al, bl, cl) +},{"./lib/_stream_writable.js":204}],210:[function(require,module,exports){ +// Copyright Joyent, Inc. and other Node contributors. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to permit +// persons to whom the Software is furnished to do so, subject to the +// following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +// USE OR OTHER DEALINGS IN THE SOFTWARE. - var sigma0h = S(a, al, 28) ^ S(al, a, 2) ^ S(al, a, 7) - var sigma0l = S(al, a, 28) ^ S(a, al, 2) ^ S(a, al, 7) - var sigma1h = S(e, el, 14) ^ S(e, el, 18) ^ S(el, e, 9) - var sigma1l = S(el, e, 14) ^ S(el, e, 18) ^ S(e, el, 9) +module.exports = Stream; - // t1 = h + sigma1 + ch + K[i] + W[i] - var Ki = K[j] - var Kil = K[j + 1] +var EE = require('events').EventEmitter; +var inherits = require('inherits'); - var ch = Ch(e, f, g) - var chl = Ch(el, fl, gl) +inherits(Stream, EE); +Stream.Readable = require('readable-stream/readable.js'); +Stream.Writable = require('readable-stream/writable.js'); +Stream.Duplex = require('readable-stream/duplex.js'); +Stream.Transform = require('readable-stream/transform.js'); +Stream.PassThrough = require('readable-stream/passthrough.js'); - var t1l = hl + sigma1l - var t1 = h + sigma1h + ((t1l >>> 0) < (hl >>> 0) ? 1 : 0) - t1l = t1l + chl - t1 = t1 + ch + ((t1l >>> 0) < (chl >>> 0) ? 1 : 0) - t1l = t1l + Kil - t1 = t1 + Ki + ((t1l >>> 0) < (Kil >>> 0) ? 1 : 0) - t1l = t1l + Wil - t1 = t1 + Wi + ((t1l >>> 0) < (Wil >>> 0) ? 1 : 0) +// Backwards-compat with node 0.4.x +Stream.Stream = Stream; - // t2 = sigma0 + maj - var t2l = sigma0l + majl - var t2 = sigma0h + maj + ((t2l >>> 0) < (sigma0l >>> 0) ? 1 : 0) - h = g - hl = gl - g = f - gl = fl - f = e - fl = el - el = (dl + t1l) | 0 - e = (d + t1 + ((el >>> 0) < (dl >>> 0) ? 1 : 0)) | 0 - d = c - dl = cl - c = b - cl = bl - b = a - bl = al - al = (t1l + t2l) | 0 - a = (t1 + t2 + ((al >>> 0) < (t1l >>> 0) ? 1 : 0)) | 0 - i++ - j += 2 - } +// old-style streams. Note that the pipe method (the only relevant +// part of this class) is overridden in the Readable class. - while (i < 16) { - Wi = M.readInt32BE(j * 4) - Wil = M.readInt32BE(j * 4 + 4) +function Stream() { + EE.call(this); +} - loop() - } +Stream.prototype.pipe = function(dest, options) { + var source = this; - while (i < 80) { - calcW() - loop() + function ondata(chunk) { + if (dest.writable) { + if (false === dest.write(chunk) && source.pause) { + source.pause(); + } + } } - this._al = (this._al + al) | 0 - this._bl = (this._bl + bl) | 0 - this._cl = (this._cl + cl) | 0 - this._dl = (this._dl + dl) | 0 - this._el = (this._el + el) | 0 - this._fl = (this._fl + fl) | 0 - this._gl = (this._gl + gl) | 0 - this._hl = (this._hl + hl) | 0 + source.on('data', ondata); - this._a = (this._a + a + ((this._al >>> 0) < (al >>> 0) ? 1 : 0)) | 0 - this._b = (this._b + b + ((this._bl >>> 0) < (bl >>> 0) ? 1 : 0)) | 0 - this._c = (this._c + c + ((this._cl >>> 0) < (cl >>> 0) ? 1 : 0)) | 0 - this._d = (this._d + d + ((this._dl >>> 0) < (dl >>> 0) ? 1 : 0)) | 0 - this._e = (this._e + e + ((this._el >>> 0) < (el >>> 0) ? 1 : 0)) | 0 - this._f = (this._f + f + ((this._fl >>> 0) < (fl >>> 0) ? 1 : 0)) | 0 - this._g = (this._g + g + ((this._gl >>> 0) < (gl >>> 0) ? 1 : 0)) | 0 - this._h = (this._h + h + ((this._hl >>> 0) < (hl >>> 0) ? 1 : 0)) | 0 -} + function ondrain() { + if (source.readable && source.resume) { + source.resume(); + } + } -Sha512.prototype._hash = function () { - var H = new Buffer(64) + dest.on('drain', ondrain); - function writeInt64BE(h, l, offset) { - H.writeInt32BE(h, offset) - H.writeInt32BE(l, offset + 4) + // If the 'end' option is not supplied, dest.end() will be called when + // source gets the 'end' or 'close' events. Only dest.end() once. + if (!dest._isStdio && (!options || options.end !== false)) { + source.on('end', onend); + source.on('close', onclose); } - writeInt64BE(this._a, this._al, 0) - writeInt64BE(this._b, this._bl, 8) - writeInt64BE(this._c, this._cl, 16) - writeInt64BE(this._d, this._dl, 24) - writeInt64BE(this._e, this._el, 32) - writeInt64BE(this._f, this._fl, 40) - writeInt64BE(this._g, this._gl, 48) - writeInt64BE(this._h, this._hl, 56) + var didOnEnd = false; + function onend() { + if (didOnEnd) return; + didOnEnd = true; - return H -} + dest.end(); + } -module.exports = Sha512 -}).call(this,require("buffer").Buffer) -},{"./hash":138,"buffer":42,"inherits":229}],145:[function(require,module,exports){ -(function (Buffer){ -'use strict'; -var createHash = require('create-hash/browser'); -var inherits = require('inherits') + function onclose() { + if (didOnEnd) return; + didOnEnd = true; -var Transform = require('stream').Transform + if (typeof dest.destroy === 'function') dest.destroy(); + } -var ZEROS = new Buffer(128) -ZEROS.fill(0) + // don't leave dangling pipes when there are errors. + function onerror(er) { + cleanup(); + if (EE.listenerCount(this, 'error') === 0) { + throw er; // Unhandled stream error in pipe. + } + } -function Hmac(alg, key) { - Transform.call(this) + source.on('error', onerror); + dest.on('error', onerror); - if (typeof key === 'string') { - key = new Buffer(key) - } + // remove all the event listeners that were added. + function cleanup() { + source.removeListener('data', ondata); + dest.removeListener('drain', ondrain); - var blocksize = (alg === 'sha512' || alg === 'sha384') ? 128 : 64 + source.removeListener('end', onend); + source.removeListener('close', onclose); - this._alg = alg - this._key = key + source.removeListener('error', onerror); + dest.removeListener('error', onerror); - if (key.length > blocksize) { - key = createHash(alg).update(key).digest() + source.removeListener('end', cleanup); + source.removeListener('close', cleanup); - } else if (key.length < blocksize) { - key = Buffer.concat([key, ZEROS], blocksize) + dest.removeListener('close', cleanup); } - var ipad = this._ipad = new Buffer(blocksize) - var opad = this._opad = new Buffer(blocksize) + source.on('end', cleanup); + source.on('close', cleanup); - for (var i = 0; i < blocksize; i++) { - ipad[i] = key[i] ^ 0x36 - opad[i] = key[i] ^ 0x5C - } + dest.on('close', cleanup); - this._hash = createHash(alg).update(ipad) -} + dest.emit('pipe', source); -inherits(Hmac, Transform) + // Allow for unix-like usage: A.pipe(B).pipe(C) + return dest; +}; -Hmac.prototype.update = function (data, enc) { - this._hash.update(data, enc) +},{"events":191,"inherits":240,"readable-stream/duplex.js":199,"readable-stream/passthrough.js":206,"readable-stream/readable.js":207,"readable-stream/transform.js":208,"readable-stream/writable.js":209}],211:[function(require,module,exports){ +// Copyright Joyent, Inc. and other Node contributors. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to permit +// persons to whom the Software is furnished to do so, subject to the +// following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +// USE OR OTHER DEALINGS IN THE SOFTWARE. - return this -} +var Buffer = require('buffer').Buffer; -Hmac.prototype._transform = function (data, _, next) { - this._hash.update(data) +var isBufferEncoding = Buffer.isEncoding + || function(encoding) { + switch (encoding && encoding.toLowerCase()) { + case 'hex': case 'utf8': case 'utf-8': case 'ascii': case 'binary': case 'base64': case 'ucs2': case 'ucs-2': case 'utf16le': case 'utf-16le': case 'raw': return true; + default: return false; + } + } - next() + +function assertEncoding(encoding) { + if (encoding && !isBufferEncoding(encoding)) { + throw new Error('Unknown encoding: ' + encoding); + } } -Hmac.prototype._flush = function (next) { - this.push(this.digest()) +// StringDecoder provides an interface for efficiently splitting a series of +// buffers into a series of JS strings without breaking apart multi-byte +// characters. CESU-8 is handled as part of the UTF-8 encoding. +// +// @TODO Handling all encodings inside a single object makes it very difficult +// to reason about this code, so it should be split up in the future. +// @TODO There should be a utf8-strict encoding that rejects invalid UTF-8 code +// points as used by CESU-8. +var StringDecoder = exports.StringDecoder = function(encoding) { + this.encoding = (encoding || 'utf8').toLowerCase().replace(/[-_]/, ''); + assertEncoding(encoding); + switch (this.encoding) { + case 'utf8': + // CESU-8 represents each of Surrogate Pair by 3-bytes + this.surrogateSize = 3; + break; + case 'ucs2': + case 'utf16le': + // UTF-16 represents each of Surrogate Pair by 2-bytes + this.surrogateSize = 2; + this.detectIncompleteChar = utf16DetectIncompleteChar; + break; + case 'base64': + // Base-64 stores 3 bytes in 4 chars, and pads the remainder. + this.surrogateSize = 3; + this.detectIncompleteChar = base64DetectIncompleteChar; + break; + default: + this.write = passThroughWrite; + return; + } - next() -} + // Enough space to store all bytes of a single character. UTF-8 needs 4 + // bytes, but CESU-8 may require up to 6 (3 bytes per surrogate). + this.charBuffer = new Buffer(6); + // Number of bytes received for the current incomplete multi-byte character. + this.charReceived = 0; + // Number of bytes expected for the current incomplete multi-byte character. + this.charLength = 0; +}; -Hmac.prototype.digest = function (enc) { - var h = this._hash.digest() - return createHash(this._alg).update(this._opad).update(h).digest(enc) -} +// write decodes the given buffer and returns it as JS string that is +// guaranteed to not contain any partial multi-byte characters. Any partial +// character found at the end of the buffer is buffered up, and will be +// returned when calling write again with the remaining bytes. +// +// Note: Converting a Buffer containing an orphan surrogate to a String +// currently works, but converting a String to a Buffer (via `new Buffer`, or +// Buffer#write) will replace incomplete surrogates with the unicode +// replacement character. See https://codereview.chromium.org/121173009/ . +StringDecoder.prototype.write = function(buffer) { + var charStr = ''; + // if our last write ended with an incomplete multibyte character + while (this.charLength) { + // determine how many remaining bytes this buffer has to offer for this char + var available = (buffer.length >= this.charLength - this.charReceived) ? + this.charLength - this.charReceived : + buffer.length; -module.exports = function createHmac(alg, key) { - return new Hmac(alg, key) -} + // add the new bytes to the char buffer + buffer.copy(this.charBuffer, this.charReceived, 0, available); + this.charReceived += available; -}).call(this,require("buffer").Buffer) -},{"buffer":42,"create-hash/browser":134,"inherits":229,"stream":200}],146:[function(require,module,exports){ -(function (Buffer){ -var generatePrime = require('./lib/generatePrime'); -var primes = require('./lib/primes'); + if (this.charReceived < this.charLength) { + // still not enough chars in this buffer? wait for more ... + return ''; + } -var DH = require('./lib/dh'); + // remove bytes belonging to the current character from the buffer + buffer = buffer.slice(available, buffer.length); -function getDiffieHellman(mod) { - var prime = new Buffer(primes[mod].prime, 'hex'); - var gen = new Buffer(primes[mod].gen, 'hex'); + // get the character that was split + charStr = this.charBuffer.slice(0, this.charLength).toString(this.encoding); - return new DH(prime, gen); -} + // CESU-8: lead surrogate (D800-DBFF) is also the incomplete character + var charCode = charStr.charCodeAt(charStr.length - 1); + if (charCode >= 0xD800 && charCode <= 0xDBFF) { + this.charLength += this.surrogateSize; + charStr = ''; + continue; + } + this.charReceived = this.charLength = 0; -function createDiffieHellman(prime, enc, generator, genc) { - if (Buffer.isBuffer(enc) || (typeof enc === 'string' && ['hex', 'binary', 'base64'].indexOf(enc) === -1)) { - genc = generator; - generator = enc; - enc = undefined; + // if there are no more bytes in this buffer, just emit our char + if (buffer.length === 0) { + return charStr; + } + break; } - enc = enc || 'binary'; - genc = genc || 'binary'; - generator = generator || new Buffer([2]); + // determine and set charLength / charReceived + this.detectIncompleteChar(buffer); - if (!Buffer.isBuffer(generator)) { - generator = new Buffer(generator, genc); + var end = buffer.length; + if (this.charLength) { + // buffer the incomplete character bytes we got + buffer.copy(this.charBuffer, 0, buffer.length - this.charReceived, end); + end -= this.charReceived; } - if (typeof prime === 'number') { - return new DH(generatePrime(prime, generator), generator, true); - } + charStr += buffer.toString(this.encoding, 0, end); - if (!Buffer.isBuffer(prime)) { - prime = new Buffer(prime, enc); + var end = charStr.length - 1; + var charCode = charStr.charCodeAt(end); + // CESU-8: lead surrogate (D800-DBFF) is also the incomplete character + if (charCode >= 0xD800 && charCode <= 0xDBFF) { + var size = this.surrogateSize; + this.charLength += size; + this.charReceived += size; + this.charBuffer.copy(this.charBuffer, size, 0, size); + buffer.copy(this.charBuffer, 0, 0, size); + return charStr.substring(0, end); } - return new DH(prime, generator, true); -} - -exports.DiffieHellmanGroup = exports.createDiffieHellmanGroup = exports.getDiffieHellman = getDiffieHellman; -exports.createDiffieHellman = exports.DiffieHellman = createDiffieHellman; + // or just emit the charStr + return charStr; +}; -}).call(this,require("buffer").Buffer) -},{"./lib/dh":147,"./lib/generatePrime":148,"./lib/primes":149,"buffer":42}],147:[function(require,module,exports){ -(function (Buffer){ -var BN = require('bn.js'); -var MillerRabin = require('miller-rabin'); -var millerRabin = new MillerRabin(); -var TWENTYFOUR = new BN(24); -var ELEVEN = new BN(11); -var TEN = new BN(10); -var THREE = new BN(3); -var SEVEN = new BN(7); -var primes = require('./generatePrime'); -var randomBytes = require('randombytes'); -module.exports = DH; +// detectIncompleteChar determines if there is an incomplete UTF-8 character at +// the end of the given buffer. If so, it sets this.charLength to the byte +// length that character, and sets this.charReceived to the number of bytes +// that are available for this character. +StringDecoder.prototype.detectIncompleteChar = function(buffer) { + // determine how many bytes we have to check at the end of this buffer + var i = (buffer.length >= 3) ? 3 : buffer.length; -function setPublicKey(pub, enc) { - enc = enc || 'utf8'; - if (!Buffer.isBuffer(pub)) { - pub = new Buffer(pub, enc); - } - this._pub = new BN(pub); - return this; -} + // Figure out if one of the last i bytes of our buffer announces an + // incomplete char. + for (; i > 0; i--) { + var c = buffer[buffer.length - i]; -function setPrivateKey(priv, enc) { - enc = enc || 'utf8'; - if (!Buffer.isBuffer(priv)) { - priv = new Buffer(priv, enc); - } - this._priv = new BN(priv); - return this; -} + // See http://en.wikipedia.org/wiki/UTF-8#Description -var primeCache = {}; -function checkPrime(prime, generator) { - var gen = generator.toString('hex'); - var hex = [gen, prime.toString(16)].join('_'); - if (hex in primeCache) { - return primeCache[hex]; - } - var error = 0; - - if (prime.isEven() || - !primes.simpleSieve || - !primes.fermatTest(prime) || - !millerRabin.test(prime)) { - //not a prime so +1 - error += 1; - - if (gen === '02' || gen === '05') { - // we'd be able to check the generator - // it would fail so +8 - error += 8; - } else { - //we wouldn't be able to test the generator - // so +4 - error += 4; + // 110XXXXX + if (i == 1 && c >> 5 == 0x06) { + this.charLength = 2; + break; } - primeCache[hex] = error; - return error; - } - if (!millerRabin.test(prime.shrn(1))) { - //not a safe prime - error += 2; - } - var rem; - switch (gen) { - case '02': - if (prime.mod(TWENTYFOUR).cmp(ELEVEN)) { - // unsuidable generator - error += 8; - } + + // 1110XXXX + if (i <= 2 && c >> 4 == 0x0E) { + this.charLength = 3; break; - case '05': - rem = prime.mod(TEN); - if (rem.cmp(THREE) && rem.cmp(SEVEN)) { - // prime mod 10 needs to equal 3 or 7 - error += 8; - } + } + + // 11110XXX + if (i <= 3 && c >> 3 == 0x1E) { + this.charLength = 4; break; - default: - error += 4; + } } - primeCache[hex] = error; - return error; -} + this.charReceived = i; +}; -function defineError (self, error) { - try { - Object.defineProperty(self, 'verifyError', { - enumerable: true, - value: error, - writable: false - }); - } catch(e) { - self.verifyError = error; - } -} -function DH(prime, generator, malleable) { - this.setGenerator(generator); - this.__prime = new BN(prime); - this._prime = BN.mont(this.__prime); - this._primeLen = prime.length; - this._pub = void 0; - this._priv = void 0; - - if (malleable) { - this.setPublicKey = setPublicKey; - this.setPrivateKey = setPrivateKey; - defineError(this, checkPrime(this.__prime, generator)); - } else { - defineError(this, 8); - } -} +StringDecoder.prototype.end = function(buffer) { + var res = ''; + if (buffer && buffer.length) + res = this.write(buffer); -DH.prototype.generateKeys = function () { - if (!this._priv) { - this._priv = new BN(randomBytes(this._primeLen)); + if (this.charReceived) { + var cr = this.charReceived; + var buf = this.charBuffer; + var enc = this.encoding; + res += buf.slice(0, cr).toString(enc); } - this._pub = this._gen.toRed(this._prime).redPow(this._priv).fromRed(); - return this.getPublicKey(); -}; -DH.prototype.computeSecret = function (other) { - other = new BN(other); - other = other.toRed(this._prime); - var secret = other.redPow(this._priv).fromRed(); - var out = new Buffer(secret.toArray()); - var prime = this.getPrime(); - if (out.length < prime.length) { - var front = new Buffer(prime.length - out.length); - front.fill(0); - out = Buffer.concat([front, out]); - } - return out; + return res; }; -DH.prototype.getPublicKey = function getPublicKey(enc) { - return formatReturnValue(this._pub, enc); -}; - -DH.prototype.getPrivateKey = function getPrivateKey(enc) { - return formatReturnValue(this._priv, enc); -}; - -DH.prototype.getPrime = function (enc) { - return formatReturnValue(this.__prime, enc); -}; - -DH.prototype.getGenerator = function (enc) { - return formatReturnValue(this._gen, enc); -}; - -DH.prototype.setGenerator = function (gen, enc) { - enc = enc || 'utf8'; - if (!Buffer.isBuffer(gen)) { - gen = new Buffer(gen, enc); - } - this._gen = new BN(gen); - return this; -}; - -function formatReturnValue(bn, enc) { - var buf = new Buffer(bn.toArray()); - if (!enc) { - return buf; - } else { - return buf.toString(enc); - } +function passThroughWrite(buffer) { + return buffer.toString(this.encoding); } -}).call(this,require("buffer").Buffer) -},{"./generatePrime":148,"bn.js":150,"buffer":42,"miller-rabin":151,"randombytes":181}],148:[function(require,module,exports){ -var randomBytes = require('randombytes'); -module.exports = findPrime; -findPrime.simpleSieve = simpleSieve; -findPrime.fermatTest = fermatTest; -var BN = require('bn.js'); -var TWENTYFOUR = new BN(24); -var MillerRabin = require('miller-rabin'); -var millerRabin = new MillerRabin(); -var ONE = new BN(1); -var TWO = new BN(2); -var FIVE = new BN(5); -var SIXTEEN = new BN(16); -var EIGHT = new BN(8); -var TEN = new BN(10); -var THREE = new BN(3); -var SEVEN = new BN(7); -var ELEVEN = new BN(11); -var FOUR = new BN(4); -var TWELVE = new BN(12); -var primes = null; -function _getPrimes() { - if (primes !== null) - return primes; +function utf16DetectIncompleteChar(buffer) { + this.charReceived = buffer.length % 2; + this.charLength = this.charReceived ? 2 : 0; +} - var limit = 0x100000; - var res = []; - res[0] = 2; - for (var i = 1, k = 3; k < limit; k += 2) { - var sqrt = Math.ceil(Math.sqrt(k)); - for (var j = 0; j < i && res[j] <= sqrt; j++) - if (k % res[j] === 0) - break; +function base64DetectIncompleteChar(buffer) { + this.charReceived = buffer.length % 3; + this.charLength = this.charReceived ? 3 : 0; +} - if (i !== j && res[j] <= sqrt) - continue; +},{"buffer":47}],212:[function(require,module,exports){ +// Copyright Joyent, Inc. and other Node contributors. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to permit +// persons to whom the Software is furnished to do so, subject to the +// following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +// USE OR OTHER DEALINGS IN THE SOFTWARE. - res[i++] = k; - } - primes = res; - return res; -} +var punycode = require('punycode'); -function simpleSieve(p) { - var primes = _getPrimes(); +exports.parse = urlParse; +exports.resolve = urlResolve; +exports.resolveObject = urlResolveObject; +exports.format = urlFormat; - for (var i = 0; i < primes.length; i++) - if (p.modn(primes[i]) === 0) { - if (p.cmpn(primes[i]) === 0) { - return true; - } else { - return false; - } - } +exports.Url = Url; - return true; +function Url() { + this.protocol = null; + this.slashes = null; + this.auth = null; + this.host = null; + this.port = null; + this.hostname = null; + this.hash = null; + this.search = null; + this.query = null; + this.pathname = null; + this.path = null; + this.href = null; } -function fermatTest(p) { - var red = BN.mont(p); - return TWO.toRed(red).redPow(p.subn(1)).fromRed().cmpn(1) === 0; -} +// Reference: RFC 3986, RFC 1808, RFC 2396 -function findPrime(bits, gen) { - if (bits < 16) { - // this is what openssl does - if (gen === 2 || gen === 5) { - return new BN([0x8c, 0x7b]); - } else { - return new BN([0x8c, 0x27]); - } - } - gen = new BN(gen); - var runs, comp; - function generateRandom(bits) { - runs = -1; - var out = new BN(randomBytes(Math.ceil(bits / 8))); - while (out.bitLength() > bits) { - out.ishrn(1); - } - if (out.isEven()) { - out.iadd(ONE); - } - if (!out.testn(1)) { - out.iadd(TWO); - } - if (!gen.cmp(TWO)) { - while (out.mod(TWENTYFOUR).cmp(ELEVEN)) { - out.iadd(FOUR); - } - comp = { - major: [TWENTYFOUR], - minor: [TWELVE] - }; - } else if (!gen.cmp(FIVE)) { - rem = out.mod(TEN); - while (rem.cmp(THREE)) { - out.iadd(FOUR); - rem = out.mod(TEN); - } - comp = { - major: [FOUR, SIXTEEN], - minor: [TWO, EIGHT] - }; - } else { - comp = { - major: [FOUR], - minor: [TWO] - }; - } - return out; - } - var num = generateRandom(bits); +// define these here so at least they only have to be +// compiled once on the first module load. +var protocolPattern = /^([a-z0-9.+-]+:)/i, + portPattern = /:[0-9]*$/, - var n2 = num.shrn(1); + // RFC 2396: characters reserved for delimiting URLs. + // We actually just auto-escape these. + delims = ['<', '>', '"', '`', ' ', '\r', '\n', '\t'], - while (true) { - while (num.bitLength() > bits) { - num = generateRandom(bits); - n2 = num.shrn(1); - } - runs++; - if (simpleSieve(n2) && simpleSieve(num) && - fermatTest(n2) && fermatTest(num) && - millerRabin.test(n2) && millerRabin.test(num)) { - return num; - } - num.iadd(comp.major[runs%comp.major.length]); - n2.iadd(comp.minor[runs%comp.minor.length]); - } + // RFC 2396: characters not allowed for various reasons. + unwise = ['{', '}', '|', '\\', '^', '`'].concat(delims), -} -},{"bn.js":150,"miller-rabin":151,"randombytes":181}],149:[function(require,module,exports){ -module.exports={ - "modp1": { - "gen": "02", - "prime": "ffffffffffffffffc90fdaa22168c234c4c6628b80dc1cd129024e088a67cc74020bbea63b139b22514a08798e3404ddef9519b3cd3a431b302b0a6df25f14374fe1356d6d51c245e485b576625e7ec6f44c42e9a63a3620ffffffffffffffff" - }, - "modp2": { - "gen": "02", - "prime": "ffffffffffffffffc90fdaa22168c234c4c6628b80dc1cd129024e088a67cc74020bbea63b139b22514a08798e3404ddef9519b3cd3a431b302b0a6df25f14374fe1356d6d51c245e485b576625e7ec6f44c42e9a637ed6b0bff5cb6f406b7edee386bfb5a899fa5ae9f24117c4b1fe649286651ece65381ffffffffffffffff" - }, - "modp5": { - "gen": "02", - "prime": "ffffffffffffffffc90fdaa22168c234c4c6628b80dc1cd129024e088a67cc74020bbea63b139b22514a08798e3404ddef9519b3cd3a431b302b0a6df25f14374fe1356d6d51c245e485b576625e7ec6f44c42e9a637ed6b0bff5cb6f406b7edee386bfb5a899fa5ae9f24117c4b1fe649286651ece45b3dc2007cb8a163bf0598da48361c55d39a69163fa8fd24cf5f83655d23dca3ad961c62f356208552bb9ed529077096966d670c354e4abc9804f1746c08ca237327ffffffffffffffff" - }, - "modp14": { - "gen": "02", - "prime": "ffffffffffffffffc90fdaa22168c234c4c6628b80dc1cd129024e088a67cc74020bbea63b139b22514a08798e3404ddef9519b3cd3a431b302b0a6df25f14374fe1356d6d51c245e485b576625e7ec6f44c42e9a637ed6b0bff5cb6f406b7edee386bfb5a899fa5ae9f24117c4b1fe649286651ece45b3dc2007cb8a163bf0598da48361c55d39a69163fa8fd24cf5f83655d23dca3ad961c62f356208552bb9ed529077096966d670c354e4abc9804f1746c08ca18217c32905e462e36ce3be39e772c180e86039b2783a2ec07a28fb5c55df06f4c52c9de2bcbf6955817183995497cea956ae515d2261898fa051015728e5a8aacaa68ffffffffffffffff" - }, - "modp15": { - "gen": "02", - "prime": "ffffffffffffffffc90fdaa22168c234c4c6628b80dc1cd129024e088a67cc74020bbea63b139b22514a08798e3404ddef9519b3cd3a431b302b0a6df25f14374fe1356d6d51c245e485b576625e7ec6f44c42e9a637ed6b0bff5cb6f406b7edee386bfb5a899fa5ae9f24117c4b1fe649286651ece45b3dc2007cb8a163bf0598da48361c55d39a69163fa8fd24cf5f83655d23dca3ad961c62f356208552bb9ed529077096966d670c354e4abc9804f1746c08ca18217c32905e462e36ce3be39e772c180e86039b2783a2ec07a28fb5c55df06f4c52c9de2bcbf6955817183995497cea956ae515d2261898fa051015728e5a8aaac42dad33170d04507a33a85521abdf1cba64ecfb850458dbef0a8aea71575d060c7db3970f85a6e1e4c7abf5ae8cdb0933d71e8c94e04a25619dcee3d2261ad2ee6bf12ffa06d98a0864d87602733ec86a64521f2b18177b200cbbe117577a615d6c770988c0bad946e208e24fa074e5ab3143db5bfce0fd108e4b82d120a93ad2caffffffffffffffff" + // Allowed by RFCs, but cause of XSS attacks. Always escape these. + autoEscape = ['\''].concat(unwise), + // Characters that are never ever allowed in a hostname. + // Note that any invalid chars are also handled, but these + // are the ones that are *expected* to be seen, so we fast-path + // them. + nonHostChars = ['%', '/', '?', ';', '#'].concat(autoEscape), + hostEndingChars = ['/', '?', '#'], + hostnameMaxLen = 255, + hostnamePartPattern = /^[a-z0-9A-Z_-]{0,63}$/, + hostnamePartStart = /^([a-z0-9A-Z_-]{0,63})(.*)$/, + // protocols that can allow "unsafe" and "unwise" chars. + unsafeProtocol = { + 'javascript': true, + 'javascript:': true }, - "modp16": { - "gen": "02", - "prime": "ffffffffffffffffc90fdaa22168c234c4c6628b80dc1cd129024e088a67cc74020bbea63b139b22514a08798e3404ddef9519b3cd3a431b302b0a6df25f14374fe1356d6d51c245e485b576625e7ec6f44c42e9a637ed6b0bff5cb6f406b7edee386bfb5a899fa5ae9f24117c4b1fe649286651ece45b3dc2007cb8a163bf0598da48361c55d39a69163fa8fd24cf5f83655d23dca3ad961c62f356208552bb9ed529077096966d670c354e4abc9804f1746c08ca18217c32905e462e36ce3be39e772c180e86039b2783a2ec07a28fb5c55df06f4c52c9de2bcbf6955817183995497cea956ae515d2261898fa051015728e5a8aaac42dad33170d04507a33a85521abdf1cba64ecfb850458dbef0a8aea71575d060c7db3970f85a6e1e4c7abf5ae8cdb0933d71e8c94e04a25619dcee3d2261ad2ee6bf12ffa06d98a0864d87602733ec86a64521f2b18177b200cbbe117577a615d6c770988c0bad946e208e24fa074e5ab3143db5bfce0fd108e4b82d120a92108011a723c12a787e6d788719a10bdba5b2699c327186af4e23c1a946834b6150bda2583e9ca2ad44ce8dbbbc2db04de8ef92e8efc141fbecaa6287c59474e6bc05d99b2964fa090c3a2233ba186515be7ed1f612970cee2d7afb81bdd762170481cd0069127d5b05aa993b4ea988d8fddc186ffb7dc90a6c08f4df435c934063199ffffffffffffffff" + // protocols that never have a hostname. + hostlessProtocol = { + 'javascript': true, + 'javascript:': true }, - "modp17": { - "gen": "02", - "prime": "ffffffffffffffffc90fdaa22168c234c4c6628b80dc1cd129024e088a67cc74020bbea63b139b22514a08798e3404ddef9519b3cd3a431b302b0a6df25f14374fe1356d6d51c245e485b576625e7ec6f44c42e9a637ed6b0bff5cb6f406b7edee386bfb5a899fa5ae9f24117c4b1fe649286651ece45b3dc2007cb8a163bf0598da48361c55d39a69163fa8fd24cf5f83655d23dca3ad961c62f356208552bb9ed529077096966d670c354e4abc9804f1746c08ca18217c32905e462e36ce3be39e772c180e86039b2783a2ec07a28fb5c55df06f4c52c9de2bcbf6955817183995497cea956ae515d2261898fa051015728e5a8aaac42dad33170d04507a33a85521abdf1cba64ecfb850458dbef0a8aea71575d060c7db3970f85a6e1e4c7abf5ae8cdb0933d71e8c94e04a25619dcee3d2261ad2ee6bf12ffa06d98a0864d87602733ec86a64521f2b18177b200cbbe117577a615d6c770988c0bad946e208e24fa074e5ab3143db5bfce0fd108e4b82d120a92108011a723c12a787e6d788719a10bdba5b2699c327186af4e23c1a946834b6150bda2583e9ca2ad44ce8dbbbc2db04de8ef92e8efc141fbecaa6287c59474e6bc05d99b2964fa090c3a2233ba186515be7ed1f612970cee2d7afb81bdd762170481cd0069127d5b05aa993b4ea988d8fddc186ffb7dc90a6c08f4df435c93402849236c3fab4d27c7026c1d4dcb2602646dec9751e763dba37bdf8ff9406ad9e530ee5db382f413001aeb06a53ed9027d831179727b0865a8918da3edbebcf9b14ed44ce6cbaced4bb1bdb7f1447e6cc254b332051512bd7af426fb8f401378cd2bf5983ca01c64b92ecf032ea15d1721d03f482d7ce6e74fef6d55e702f46980c82b5a84031900b1c9e59e7c97fbec7e8f323a97a7e36cc88be0f1d45b7ff585ac54bd407b22b4154aacc8f6d7ebf48e1d814cc5ed20f8037e0a79715eef29be32806a1d58bb7c5da76f550aa3d8a1fbff0eb19ccb1a313d55cda56c9ec2ef29632387fe8d76e3c0468043e8f663f4860ee12bf2d5b0b7474d6e694f91e6dcc4024ffffffffffffffff" + // protocols that always contain a // bit. + slashedProtocol = { + 'http': true, + 'https': true, + 'ftp': true, + 'gopher': true, + 'file': true, + 'http:': true, + 'https:': true, + 'ftp:': true, + 'gopher:': true, + 'file:': true }, - "modp18": { - "gen": "02", - "prime": "ffffffffffffffffc90fdaa22168c234c4c6628b80dc1cd129024e088a67cc74020bbea63b139b22514a08798e3404ddef9519b3cd3a431b302b0a6df25f14374fe1356d6d51c245e485b576625e7ec6f44c42e9a637ed6b0bff5cb6f406b7edee386bfb5a899fa5ae9f24117c4b1fe649286651ece45b3dc2007cb8a163bf0598da48361c55d39a69163fa8fd24cf5f83655d23dca3ad961c62f356208552bb9ed529077096966d670c354e4abc9804f1746c08ca18217c32905e462e36ce3be39e772c180e86039b2783a2ec07a28fb5c55df06f4c52c9de2bcbf6955817183995497cea956ae515d2261898fa051015728e5a8aaac42dad33170d04507a33a85521abdf1cba64ecfb850458dbef0a8aea71575d060c7db3970f85a6e1e4c7abf5ae8cdb0933d71e8c94e04a25619dcee3d2261ad2ee6bf12ffa06d98a0864d87602733ec86a64521f2b18177b200cbbe117577a615d6c770988c0bad946e208e24fa074e5ab3143db5bfce0fd108e4b82d120a92108011a723c12a787e6d788719a10bdba5b2699c327186af4e23c1a946834b6150bda2583e9ca2ad44ce8dbbbc2db04de8ef92e8efc141fbecaa6287c59474e6bc05d99b2964fa090c3a2233ba186515be7ed1f612970cee2d7afb81bdd762170481cd0069127d5b05aa993b4ea988d8fddc186ffb7dc90a6c08f4df435c93402849236c3fab4d27c7026c1d4dcb2602646dec9751e763dba37bdf8ff9406ad9e530ee5db382f413001aeb06a53ed9027d831179727b0865a8918da3edbebcf9b14ed44ce6cbaced4bb1bdb7f1447e6cc254b332051512bd7af426fb8f401378cd2bf5983ca01c64b92ecf032ea15d1721d03f482d7ce6e74fef6d55e702f46980c82b5a84031900b1c9e59e7c97fbec7e8f323a97a7e36cc88be0f1d45b7ff585ac54bd407b22b4154aacc8f6d7ebf48e1d814cc5ed20f8037e0a79715eef29be32806a1d58bb7c5da76f550aa3d8a1fbff0eb19ccb1a313d55cda56c9ec2ef29632387fe8d76e3c0468043e8f663f4860ee12bf2d5b0b7474d6e694f91e6dbe115974a3926f12fee5e438777cb6a932df8cd8bec4d073b931ba3bc832b68d9dd300741fa7bf8afc47ed2576f6936ba424663aab639c5ae4f5683423b4742bf1c978238f16cbe39d652de3fdb8befc848ad922222e04a4037c0713eb57a81a23f0c73473fc646cea306b4bcbc8862f8385ddfa9d4b7fa2c087e879683303ed5bdd3a062b3cf5b3a278a66d2a13f83f44f82ddf310ee074ab6a364597e899a0255dc164f31cc50846851df9ab48195ded7ea1b1d510bd7ee74d73faf36bc31ecfa268359046f4eb879f924009438b481c6cd7889a002ed5ee382bc9190da6fc026e479558e4475677e9aa9e3050e2765694dfc81f56e880b96e7160c980dd98edd3dfffffffffffffffff" - } -} -},{}],150:[function(require,module,exports){ -module.exports=require(67) -},{"/Users/eordano/Code/bitcore/node_modules/bitcore-build/node_modules/browserify/node_modules/crypto-browserify/node_modules/browserify-sign/node_modules/bn.js/lib/bn.js":67}],151:[function(require,module,exports){ -var bn = require('bn.js'); -var brorand = require('brorand'); + querystring = require('querystring'); -function MillerRabin(rand) { - this.rand = rand || new brorand.Rand(); -} -module.exports = MillerRabin; +function urlParse(url, parseQueryString, slashesDenoteHost) { + if (url && isObject(url) && url instanceof Url) return url; -MillerRabin.create = function create(rand) { - return new MillerRabin(rand); -}; + var u = new Url; + u.parse(url, parseQueryString, slashesDenoteHost); + return u; +} -MillerRabin.prototype._rand = function _rand(n) { - var len = n.bitLength(); - var buf = this.rand.generate(Math.ceil(len / 8)); +Url.prototype.parse = function(url, parseQueryString, slashesDenoteHost) { + if (!isString(url)) { + throw new TypeError("Parameter 'url' must be a string, not " + typeof url); + } - // Set low bits - buf[0] |= 3; + var rest = url; - // Mask high bits - var mask = len & 0x7; - if (mask !== 0) - buf[buf.length - 1] >>= 7 - mask; + // trim before proceeding. + // This is to support parse stuff like " http://foo.com \n" + rest = rest.trim(); - return new bn(buf); -} + var proto = protocolPattern.exec(rest); + if (proto) { + proto = proto[0]; + var lowerProto = proto.toLowerCase(); + this.protocol = lowerProto; + rest = rest.substr(proto.length); + } -MillerRabin.prototype.test = function test(n, k, cb) { - var len = n.bitLength(); - var red = bn.mont(n); - var rone = new bn(1).toRed(red); + // figure out if it's got a host + // user@server is *always* interpreted as a hostname, and url + // resolution will treat //foo/bar as host=foo,path=bar because that's + // how the browser resolves relative URLs. + if (slashesDenoteHost || proto || rest.match(/^\/\/[^@\/]+@[^@\/]+/)) { + var slashes = rest.substr(0, 2) === '//'; + if (slashes && !(proto && hostlessProtocol[proto])) { + rest = rest.substr(2); + this.slashes = true; + } + } - if (!k) - k = Math.max(1, (len / 48) | 0); + if (!hostlessProtocol[proto] && + (slashes || (proto && !slashedProtocol[proto]))) { - // Find d and s, (n - 1) = (2 ^ s) * d; - var n1 = n.subn(1); - var n2 = n1.subn(1); - for (var s = 0; !n1.testn(s); s++) {} - var d = n.shrn(s); + // there's a hostname. + // the first instance of /, ?, ;, or # ends the host. + // + // If there is an @ in the hostname, then non-host chars *are* allowed + // to the left of the last @ sign, unless some host-ending character + // comes *before* the @-sign. + // URLs are obnoxious. + // + // ex: + // http://a@b@c/ => user:a@b host:c + // http://a@b?@c => user:a host:c path:/?@c - var rn1 = n1.toRed(red); + // v0.12 TODO(isaacs): This is not quite how Chrome does things. + // Review our test case against browsers more comprehensively. - var prime = true; - for (; k > 0; k--) { - var a = this._rand(n2); - if (cb) - cb(a); + // find the first instance of any hostEndingChars + var hostEnd = -1; + for (var i = 0; i < hostEndingChars.length; i++) { + var hec = rest.indexOf(hostEndingChars[i]); + if (hec !== -1 && (hostEnd === -1 || hec < hostEnd)) + hostEnd = hec; + } - var x = a.toRed(red).redPow(d); - if (x.cmp(rone) === 0 || x.cmp(rn1) === 0) - continue; + // at this point, either we have an explicit point where the + // auth portion cannot go past, or the last @ char is the decider. + var auth, atSign; + if (hostEnd === -1) { + // atSign can be anywhere. + atSign = rest.lastIndexOf('@'); + } else { + // atSign must be in auth portion. + // http://a@b/c@d => host:b auth:a path:/c@d + atSign = rest.lastIndexOf('@', hostEnd); + } - for (var i = 1; i < s; i++) { - x = x.redSqr(); + // Now we have a portion which is definitely the auth. + // Pull that off. + if (atSign !== -1) { + auth = rest.slice(0, atSign); + rest = rest.slice(atSign + 1); + this.auth = decodeURIComponent(auth); + } - if (x.cmp(rone) === 0) - return false; - if (x.cmp(rn1) === 0) - break; + // the host is the remaining to the left of the first non-host char + hostEnd = -1; + for (var i = 0; i < nonHostChars.length; i++) { + var hec = rest.indexOf(nonHostChars[i]); + if (hec !== -1 && (hostEnd === -1 || hec < hostEnd)) + hostEnd = hec; } + // if we still have not hit it, then the entire thing is a host. + if (hostEnd === -1) + hostEnd = rest.length; - if (i === s) - return false; - } + this.host = rest.slice(0, hostEnd); + rest = rest.slice(hostEnd); - return prime; -}; + // pull out port. + this.parseHost(); -MillerRabin.prototype.getDivisor = function getDivisor(n, k) { - var len = n.bitLength(); - var red = bn.mont(n); - var rone = new bn(1).toRed(red); + // we've indicated that there is a hostname, + // so even if it's empty, it has to be present. + this.hostname = this.hostname || ''; - if (!k) - k = Math.max(1, (len / 48) | 0); + // if hostname begins with [ and ends with ] + // assume that it's an IPv6 address. + var ipv6Hostname = this.hostname[0] === '[' && + this.hostname[this.hostname.length - 1] === ']'; - // Find d and s, (n - 1) = (2 ^ s) * d; - var n1 = n.subn(1); - var n2 = n1.subn(1); - for (var s = 0; !n1.testn(s); s++) {} - var d = n.shrn(s); + // validate a little. + if (!ipv6Hostname) { + var hostparts = this.hostname.split(/\./); + for (var i = 0, l = hostparts.length; i < l; i++) { + var part = hostparts[i]; + if (!part) continue; + if (!part.match(hostnamePartPattern)) { + var newpart = ''; + for (var j = 0, k = part.length; j < k; j++) { + if (part.charCodeAt(j) > 127) { + // we replace non-ASCII char with a temporary placeholder + // we need this to make sure size of hostname is not + // broken by replacing non-ASCII by nothing + newpart += 'x'; + } else { + newpart += part[j]; + } + } + // we test again with ASCII char only + if (!newpart.match(hostnamePartPattern)) { + var validParts = hostparts.slice(0, i); + var notHost = hostparts.slice(i + 1); + var bit = part.match(hostnamePartStart); + if (bit) { + validParts.push(bit[1]); + notHost.unshift(bit[2]); + } + if (notHost.length) { + rest = '/' + notHost.join('.') + rest; + } + this.hostname = validParts.join('.'); + break; + } + } + } + } - var rn1 = n1.toRed(red); + if (this.hostname.length > hostnameMaxLen) { + this.hostname = ''; + } else { + // hostnames are always lower case. + this.hostname = this.hostname.toLowerCase(); + } - var prime = true; - for (; k > 0; k--) { - var a = this._rand(n2); + if (!ipv6Hostname) { + // IDNA Support: Returns a puny coded representation of "domain". + // It only converts the part of the domain name that + // has non ASCII characters. I.e. it dosent matter if + // you call it with a domain that already is in ASCII. + var domainArray = this.hostname.split('.'); + var newOut = []; + for (var i = 0; i < domainArray.length; ++i) { + var s = domainArray[i]; + newOut.push(s.match(/[^A-Za-z0-9_-]/) ? + 'xn--' + punycode.encode(s) : s); + } + this.hostname = newOut.join('.'); + } - var g = n.gcd(a); - if (g.cmpn(1) !== 0) - return g; + var p = this.port ? ':' + this.port : ''; + var h = this.hostname || ''; + this.host = h + p; + this.href += this.host; - var x = a.toRed(red).redPow(d); - if (x.cmp(rone) === 0 || x.cmp(rn1) === 0) - continue; + // strip [ and ] from the hostname + // the host field still retains them, though + if (ipv6Hostname) { + this.hostname = this.hostname.substr(1, this.hostname.length - 2); + if (rest[0] !== '/') { + rest = '/' + rest; + } + } + } - for (var i = 1; i < s; i++) { - x = x.redSqr(); + // now rest is set to the post-host stuff. + // chop off any delim chars. + if (!unsafeProtocol[lowerProto]) { - if (x.cmp(rone) === 0) - return x.fromRed().subn(1).gcd(n); - if (x.cmp(rn1) === 0) - break; + // First, make 100% sure that any "autoEscape" chars get + // escaped, even if encodeURIComponent doesn't think they + // need to be. + for (var i = 0, l = autoEscape.length; i < l; i++) { + var ae = autoEscape[i]; + var esc = encodeURIComponent(ae); + if (esc === ae) { + esc = escape(ae); + } + rest = rest.split(ae).join(esc); } + } - if (i === s) { - x = x.redSqr(); - return x.fromRed().subn(1).gcd(n); + + // chop off from the tail first. + var hash = rest.indexOf('#'); + if (hash !== -1) { + // got a fragment string. + this.hash = rest.substr(hash); + rest = rest.slice(0, hash); + } + var qm = rest.indexOf('?'); + if (qm !== -1) { + this.search = rest.substr(qm); + this.query = rest.substr(qm + 1); + if (parseQueryString) { + this.query = querystring.parse(this.query); } + rest = rest.slice(0, qm); + } else if (parseQueryString) { + // no query string, but parseQueryString still requested + this.search = ''; + this.query = {}; + } + if (rest) this.pathname = rest; + if (slashedProtocol[lowerProto] && + this.hostname && !this.pathname) { + this.pathname = '/'; } - return prime; + //to support http.request + if (this.pathname || this.search) { + var p = this.pathname || ''; + var s = this.search || ''; + this.path = p + s; + } + + // finally, reconstruct the href based on what has been validated. + this.href = this.format(); + return this; }; -},{"bn.js":150,"brorand":152}],152:[function(require,module,exports){ -module.exports=require(81) -},{"/Users/eordano/Code/bitcore/node_modules/bitcore-build/node_modules/browserify/node_modules/crypto-browserify/node_modules/browserify-sign/node_modules/elliptic/node_modules/brorand/index.js":81}],153:[function(require,module,exports){ -(function (Buffer){ -var createHmac = require('create-hmac') +// format a parsed object into a url string +function urlFormat(obj) { + // ensure it's an object, and not a string url. + // If it's an obj, this is a no-op. + // this way, you can call url_format() on strings + // to clean up potentially wonky urls. + if (isString(obj)) obj = urlParse(obj); + if (!(obj instanceof Url)) return Url.prototype.format.call(obj); + return obj.format(); +} -exports.pbkdf2 = pbkdf2 -function pbkdf2 (password, salt, iterations, keylen, digest, callback) { - if (typeof digest === 'function') { - callback = digest - digest = undefined +Url.prototype.format = function() { + var auth = this.auth || ''; + if (auth) { + auth = encodeURIComponent(auth); + auth = auth.replace(/%3A/i, ':'); + auth += '@'; } - if (typeof callback !== 'function') { - throw new Error('No callback provided to pbkdf2') + var protocol = this.protocol || '', + pathname = this.pathname || '', + hash = this.hash || '', + host = false, + query = ''; + + if (this.host) { + host = auth + this.host; + } else if (this.hostname) { + host = auth + (this.hostname.indexOf(':') === -1 ? + this.hostname : + '[' + this.hostname + ']'); + if (this.port) { + host += ':' + this.port; + } } - var result = pbkdf2Sync(password, salt, iterations, keylen, digest) - setTimeout(function () { - callback(undefined, result) - }) -} + if (this.query && + isObject(this.query) && + Object.keys(this.query).length) { + query = querystring.stringify(this.query); + } -exports.pbkdf2Sync = pbkdf2Sync -function pbkdf2Sync (password, salt, iterations, keylen, digest) { - if (typeof iterations !== 'number') - throw new TypeError('Iterations not a number') + var search = this.search || (query && ('?' + query)) || ''; - if (iterations < 0) - throw new TypeError('Bad iterations') + if (protocol && protocol.substr(-1) !== ':') protocol += ':'; - if (typeof keylen !== 'number') - throw new TypeError('Key length not a number') + // only the slashedProtocols get the //. Not mailto:, xmpp:, etc. + // unless they had them to begin with. + if (this.slashes || + (!protocol || slashedProtocol[protocol]) && host !== false) { + host = '//' + (host || ''); + if (pathname && pathname.charAt(0) !== '/') pathname = '/' + pathname; + } else if (!host) { + host = ''; + } - if (keylen < 0) - throw new TypeError('Bad key length') + if (hash && hash.charAt(0) !== '#') hash = '#' + hash; + if (search && search.charAt(0) !== '?') search = '?' + search; - digest = digest || 'sha1' + pathname = pathname.replace(/[?#]/g, function(match) { + return encodeURIComponent(match); + }); + search = search.replace('#', '%23'); + + return protocol + host + pathname + search + hash; +}; - if (!Buffer.isBuffer(password)) password = new Buffer(password) - if (!Buffer.isBuffer(salt)) salt = new Buffer(salt) +function urlResolve(source, relative) { + return urlParse(source, false, true).resolve(relative); +} - var hLen - var l = 1 - var DK = new Buffer(keylen) - var block1 = new Buffer(salt.length + 4) - salt.copy(block1, 0, 0, salt.length) +Url.prototype.resolve = function(relative) { + return this.resolveObject(urlParse(relative, false, true)).format(); +}; - var r - var T +function urlResolveObject(source, relative) { + if (!source) return relative; + return urlParse(source, false, true).resolveObject(relative); +} - for (var i = 1; i <= l; i++) { - block1.writeUInt32BE(i, salt.length) - var U = createHmac(digest, password).update(block1).digest() +Url.prototype.resolveObject = function(relative) { + if (isString(relative)) { + var rel = new Url(); + rel.parse(relative, false, true); + relative = rel; + } - if (!hLen) { - hLen = U.length - T = new Buffer(hLen) - l = Math.ceil(keylen / hLen) - r = keylen - (l - 1) * hLen + var result = new Url(); + Object.keys(this).forEach(function(k) { + result[k] = this[k]; + }, this); - if (keylen > (Math.pow(2, 32) - 1) * hLen) - throw new TypeError('keylen exceeds maximum length') - } + // hash is always overridden, no matter what. + // even href="" will remove it. + result.hash = relative.hash; - U.copy(T, 0, 0, hLen) + // if the relative url is empty, then there's nothing left to do here. + if (relative.href === '') { + result.href = result.format(); + return result; + } - for (var j = 1; j < iterations; j++) { - U = createHmac(digest, password).update(U).digest() + // hrefs like //foo/bar always cut to the protocol. + if (relative.slashes && !relative.protocol) { + // take everything except the protocol from relative + Object.keys(relative).forEach(function(k) { + if (k !== 'protocol') + result[k] = relative[k]; + }); - for (var k = 0; k < hLen; k++) { - T[k] ^= U[k] - } + //urlParse appends trailing / to urls like http://www.example.com + if (slashedProtocol[result.protocol] && + result.hostname && !result.pathname) { + result.path = result.pathname = '/'; } - var destPos = (i - 1) * hLen - var len = (i === l ? r : hLen) - T.copy(DK, destPos, 0, len) + result.href = result.format(); + return result; } - return DK -} + if (relative.protocol && relative.protocol !== result.protocol) { + // if it's a known url protocol, then changing + // the protocol does weird things + // first, if it's not file:, then we MUST have a host, + // and if there was a path + // to begin with, then we MUST have a path. + // if it is file:, then the host is dropped, + // because that's known to be hostless. + // anything else is assumed to be absolute. + if (!slashedProtocol[relative.protocol]) { + Object.keys(relative).forEach(function(k) { + result[k] = relative[k]; + }); + result.href = result.format(); + return result; + } -}).call(this,require("buffer").Buffer) -},{"buffer":42,"create-hmac":145}],154:[function(require,module,exports){ + result.protocol = relative.protocol; + if (!relative.host && !hostlessProtocol[relative.protocol]) { + var relPath = (relative.pathname || '').split('/'); + while (relPath.length && !(relative.host = relPath.shift())); + if (!relative.host) relative.host = ''; + if (!relative.hostname) relative.hostname = ''; + if (relPath[0] !== '') relPath.unshift(''); + if (relPath.length < 2) relPath.unshift(''); + result.pathname = relPath.join('/'); + } else { + result.pathname = relative.pathname; + } + result.search = relative.search; + result.query = relative.query; + result.host = relative.host || ''; + result.auth = relative.auth; + result.hostname = relative.hostname || relative.host; + result.port = relative.port; + // to support http.request + if (result.pathname || result.search) { + var p = result.pathname || ''; + var s = result.search || ''; + result.path = p + s; + } + result.slashes = result.slashes || relative.slashes; + result.href = result.format(); + return result; + } -module.exports = function (exports, crypto) { - exports.publicEncrypt = require('./publicEncrypt')(crypto); - exports.privateDecrypt = require('./privateDecrypt')(crypto); -}; -},{"./privateDecrypt":178,"./publicEncrypt":179}],155:[function(require,module,exports){ -(function (Buffer){ -module.exports = function (seed, len, crypto) { - var t = new Buffer(''); - var i = 0, c; - while (t.length < len) { - c = i2ops(i++); - t = Buffer.concat([t, crypto.createHash('sha1').update(seed).update(c).digest()]); + var isSourceAbs = (result.pathname && result.pathname.charAt(0) === '/'), + isRelAbs = ( + relative.host || + relative.pathname && relative.pathname.charAt(0) === '/' + ), + mustEndAbs = (isRelAbs || isSourceAbs || + (result.host && relative.pathname)), + removeAllDots = mustEndAbs, + srcPath = result.pathname && result.pathname.split('/') || [], + relPath = relative.pathname && relative.pathname.split('/') || [], + psychotic = result.protocol && !slashedProtocol[result.protocol]; + + // if the url is a non-slashed url, then relative + // links like ../.. should be able + // to crawl up to the hostname, as well. This is strange. + // result.protocol has already been set by now. + // Later on, put the first path part into the host field. + if (psychotic) { + result.hostname = ''; + result.port = null; + if (result.host) { + if (srcPath[0] === '') srcPath[0] = result.host; + else srcPath.unshift(result.host); + } + result.host = ''; + if (relative.protocol) { + relative.hostname = null; + relative.port = null; + if (relative.host) { + if (relPath[0] === '') relPath[0] = relative.host; + else relPath.unshift(relative.host); + } + relative.host = null; + } + mustEndAbs = mustEndAbs && (relPath[0] === '' || srcPath[0] === ''); } - return t.slice(0, len); -}; -function i2ops(c) { - var out = new Buffer(4); - out.writeUInt32BE(c,0); - return out; -} -}).call(this,require("buffer").Buffer) -},{"buffer":42}],156:[function(require,module,exports){ -module.exports=require(67) -},{"/Users/eordano/Code/bitcore/node_modules/bitcore-build/node_modules/browserify/node_modules/crypto-browserify/node_modules/browserify-sign/node_modules/bn.js/lib/bn.js":67}],157:[function(require,module,exports){ -module.exports=require(68) -},{"/Users/eordano/Code/bitcore/node_modules/bitcore-build/node_modules/browserify/node_modules/crypto-browserify/node_modules/browserify-sign/node_modules/browserify-rsa/index.js":68,"bn.js":156,"buffer":42}],158:[function(require,module,exports){ -module.exports=require(89) -},{"/Users/eordano/Code/bitcore/node_modules/bitcore-build/node_modules/browserify/node_modules/crypto-browserify/node_modules/browserify-sign/node_modules/parse-asn1/EVP_BytesToKey.js":89,"buffer":42}],159:[function(require,module,exports){ -module.exports=require(90) -},{"/Users/eordano/Code/bitcore/node_modules/bitcore-build/node_modules/browserify/node_modules/crypto-browserify/node_modules/browserify-sign/node_modules/parse-asn1/aesid.json":90}],160:[function(require,module,exports){ -module.exports=require(91) -},{"/Users/eordano/Code/bitcore/node_modules/bitcore-build/node_modules/browserify/node_modules/crypto-browserify/node_modules/browserify-sign/node_modules/parse-asn1/asn1.js":91,"asn1.js":164,"asn1.js-rfc3280":163}],161:[function(require,module,exports){ -module.exports=require(92) -},{"./EVP_BytesToKey":158,"/Users/eordano/Code/bitcore/node_modules/bitcore-build/node_modules/browserify/node_modules/crypto-browserify/node_modules/browserify-sign/node_modules/parse-asn1/fixProc.js":92,"buffer":42}],162:[function(require,module,exports){ -module.exports=require(93) -},{"./aesid.json":159,"./asn1":160,"./fixProc":161,"/Users/eordano/Code/bitcore/node_modules/bitcore-build/node_modules/browserify/node_modules/crypto-browserify/node_modules/browserify-sign/node_modules/parse-asn1/index.js":93,"buffer":42,"pemstrip":177}],163:[function(require,module,exports){ -module.exports=require(94) -},{"/Users/eordano/Code/bitcore/node_modules/bitcore-build/node_modules/browserify/node_modules/crypto-browserify/node_modules/browserify-sign/node_modules/parse-asn1/node_modules/asn1.js-rfc3280/index.js":94,"asn1.js":164}],164:[function(require,module,exports){ -module.exports=require(95) -},{"./asn1/api":165,"./asn1/base":167,"./asn1/constants":171,"./asn1/decoders":173,"./asn1/encoders":175,"/Users/eordano/Code/bitcore/node_modules/bitcore-build/node_modules/browserify/node_modules/crypto-browserify/node_modules/browserify-sign/node_modules/parse-asn1/node_modules/asn1.js/lib/asn1.js":95,"bn.js":156}],165:[function(require,module,exports){ -module.exports=require(96) -},{"../asn1":164,"/Users/eordano/Code/bitcore/node_modules/bitcore-build/node_modules/browserify/node_modules/crypto-browserify/node_modules/browserify-sign/node_modules/parse-asn1/node_modules/asn1.js/lib/asn1/api.js":96,"inherits":229,"vm":205}],166:[function(require,module,exports){ -module.exports=require(97) -},{"../base":167,"/Users/eordano/Code/bitcore/node_modules/bitcore-build/node_modules/browserify/node_modules/crypto-browserify/node_modules/browserify-sign/node_modules/parse-asn1/node_modules/asn1.js/lib/asn1/base/buffer.js":97,"buffer":42,"inherits":229}],167:[function(require,module,exports){ -module.exports=require(98) -},{"./buffer":166,"./node":168,"./reporter":169,"/Users/eordano/Code/bitcore/node_modules/bitcore-build/node_modules/browserify/node_modules/crypto-browserify/node_modules/browserify-sign/node_modules/parse-asn1/node_modules/asn1.js/lib/asn1/base/index.js":98}],168:[function(require,module,exports){ -module.exports=require(99) -},{"../base":167,"/Users/eordano/Code/bitcore/node_modules/bitcore-build/node_modules/browserify/node_modules/crypto-browserify/node_modules/browserify-sign/node_modules/parse-asn1/node_modules/asn1.js/lib/asn1/base/node.js":99,"minimalistic-assert":176}],169:[function(require,module,exports){ -module.exports=require(100) -},{"/Users/eordano/Code/bitcore/node_modules/bitcore-build/node_modules/browserify/node_modules/crypto-browserify/node_modules/browserify-sign/node_modules/parse-asn1/node_modules/asn1.js/lib/asn1/base/reporter.js":100,"inherits":229}],170:[function(require,module,exports){ -module.exports=require(101) -},{"../constants":171,"/Users/eordano/Code/bitcore/node_modules/bitcore-build/node_modules/browserify/node_modules/crypto-browserify/node_modules/browserify-sign/node_modules/parse-asn1/node_modules/asn1.js/lib/asn1/constants/der.js":101}],171:[function(require,module,exports){ -module.exports=require(102) -},{"./der":170,"/Users/eordano/Code/bitcore/node_modules/bitcore-build/node_modules/browserify/node_modules/crypto-browserify/node_modules/browserify-sign/node_modules/parse-asn1/node_modules/asn1.js/lib/asn1/constants/index.js":102}],172:[function(require,module,exports){ -module.exports=require(103) -},{"../../asn1":164,"/Users/eordano/Code/bitcore/node_modules/bitcore-build/node_modules/browserify/node_modules/crypto-browserify/node_modules/browserify-sign/node_modules/parse-asn1/node_modules/asn1.js/lib/asn1/decoders/der.js":103,"inherits":229}],173:[function(require,module,exports){ -module.exports=require(104) -},{"./der":172,"/Users/eordano/Code/bitcore/node_modules/bitcore-build/node_modules/browserify/node_modules/crypto-browserify/node_modules/browserify-sign/node_modules/parse-asn1/node_modules/asn1.js/lib/asn1/decoders/index.js":104}],174:[function(require,module,exports){ -module.exports=require(105) -},{"../../asn1":164,"/Users/eordano/Code/bitcore/node_modules/bitcore-build/node_modules/browserify/node_modules/crypto-browserify/node_modules/browserify-sign/node_modules/parse-asn1/node_modules/asn1.js/lib/asn1/encoders/der.js":105,"buffer":42,"inherits":229}],175:[function(require,module,exports){ -module.exports=require(106) -},{"./der":174,"/Users/eordano/Code/bitcore/node_modules/bitcore-build/node_modules/browserify/node_modules/crypto-browserify/node_modules/browserify-sign/node_modules/parse-asn1/node_modules/asn1.js/lib/asn1/encoders/index.js":106}],176:[function(require,module,exports){ -module.exports=require(107) -},{"/Users/eordano/Code/bitcore/node_modules/bitcore-build/node_modules/browserify/node_modules/crypto-browserify/node_modules/browserify-sign/node_modules/parse-asn1/node_modules/asn1.js/node_modules/minimalistic-assert/index.js":107}],177:[function(require,module,exports){ -module.exports=require(108) -},{"/Users/eordano/Code/bitcore/node_modules/bitcore-build/node_modules/browserify/node_modules/crypto-browserify/node_modules/browserify-sign/node_modules/parse-asn1/node_modules/pemstrip/index.js":108}],178:[function(require,module,exports){ -(function (Buffer){ -var parseKeys = require('parse-asn1'); -var mgf = require('./mgf'); -var xor = require('./xor'); -var bn = require('bn.js'); -var crt = require('browserify-rsa'); -module.exports = function (crypto) { - return privateDecrypt; - function privateDecrypt(private_key, enc) { - var padding; - if (private_key.padding) { - padding = private_key.padding; - } else { - padding = 4; + if (isRelAbs) { + // it's absolute. + result.host = (relative.host || relative.host === '') ? + relative.host : result.host; + result.hostname = (relative.hostname || relative.hostname === '') ? + relative.hostname : result.hostname; + result.search = relative.search; + result.query = relative.query; + srcPath = relPath; + // fall through to the dot-handling below. + } else if (relPath.length) { + // it's relative + // throw away the existing file, and take the new path instead. + if (!srcPath) srcPath = []; + srcPath.pop(); + srcPath = srcPath.concat(relPath); + result.search = relative.search; + result.query = relative.query; + } else if (!isNullOrUndefined(relative.search)) { + // just pull out the search. + // like href='?foo'. + // Put this after the other two cases because it simplifies the booleans + if (psychotic) { + result.hostname = result.host = srcPath.shift(); + //occationaly the auth can get stuck only in host + //this especialy happens in cases like + //url.resolveObject('mailto:local1@domain1', 'local2@domain2') + var authInHost = result.host && result.host.indexOf('@') > 0 ? + result.host.split('@') : false; + if (authInHost) { + result.auth = authInHost.shift(); + result.host = result.hostname = authInHost.shift(); + } } - - var key = parseKeys(private_key, crypto); - var k = key.modulus.byteLength(); - if (enc.length > k || new bn(enc).cmp(key.modulus) >= 0) { - throw new Error('decryption error'); - } - var msg = crt(enc, key, crypto); - var zBuffer = new Buffer(k - msg.length); - zBuffer.fill(0); - msg = Buffer.concat([zBuffer, msg], k); - if (padding === 4) { - return oaep(key, msg, crypto); - } else if (padding === 1) { - return pkcs1(key, msg, crypto); - } else if (padding === 3) { - return msg; + result.search = relative.search; + result.query = relative.query; + //to support http.request + if (!isNull(result.pathname) || !isNull(result.search)) { + result.path = (result.pathname ? result.pathname : '') + + (result.search ? result.search : ''); + } + result.href = result.format(); + return result; + } + + if (!srcPath.length) { + // no path at all. easy. + // we've already handled the other stuff above. + result.pathname = null; + //to support http.request + if (result.search) { + result.path = '/' + result.search; } else { - throw new Error('unknown padding'); + result.path = null; } + result.href = result.format(); + return result; } -}; -function oaep(key, msg, crypto){ - var n = key.modulus; - var k = key.modulus.byteLength(); - var mLen = msg.length; - var iHash = crypto.createHash('sha1').update(new Buffer('')).digest(); - var hLen = iHash.length; - var hLen2 = 2 * hLen; - if (msg[0] !== 0) { - throw new Error('decryption error'); + // if a url ENDs in . or .., then it must get a trailing slash. + // however, if it ends in anything else non-slashy, + // then it must NOT get a trailing slash. + var last = srcPath.slice(-1)[0]; + var hasTrailingSlash = ( + (result.host || relative.host) && (last === '.' || last === '..') || + last === ''); + + // strip single dots, resolve double dots to parent dir + // if the path tries to go above the root, `up` ends up > 0 + var up = 0; + for (var i = srcPath.length; i >= 0; i--) { + last = srcPath[i]; + if (last == '.') { + srcPath.splice(i, 1); + } else if (last === '..') { + srcPath.splice(i, 1); + up++; + } else if (up) { + srcPath.splice(i, 1); + up--; + } } - var maskedSeed = msg.slice(1, hLen + 1); - var maskedDb = msg.slice(hLen + 1); - var seed = xor(maskedSeed, mgf(maskedDb, hLen, crypto)); - var db = xor(maskedDb, mgf(seed, k - hLen - 1, crypto)); - if (compare(iHash, db.slice(0, hLen))) { - throw new Error('decryption error'); + + // if the path is allowed to go above the root, restore leading ..s + if (!mustEndAbs && !removeAllDots) { + for (; up--; up) { + srcPath.unshift('..'); + } } - var i = hLen; - while (db[i] === 0) { - i++; + + if (mustEndAbs && srcPath[0] !== '' && + (!srcPath[0] || srcPath[0].charAt(0) !== '/')) { + srcPath.unshift(''); } - if (db[i++] !== 1) { - throw new Error('decryption error'); + + if (hasTrailingSlash && (srcPath.join('/').substr(-1) !== '/')) { + srcPath.push(''); } - return db.slice(i); -} -function pkcs1(key, msg, crypto){ - var p1 = msg.slice(0, 2); - var i = 2; - var status = 0; - while (msg[i++] !== 0) { - if (i >= msg.length) { - status++; - break; + var isAbsolute = srcPath[0] === '' || + (srcPath[0] && srcPath[0].charAt(0) === '/'); + + // put the host back + if (psychotic) { + result.hostname = result.host = isAbsolute ? '' : + srcPath.length ? srcPath.shift() : ''; + //occationaly the auth can get stuck only in host + //this especialy happens in cases like + //url.resolveObject('mailto:local1@domain1', 'local2@domain2') + var authInHost = result.host && result.host.indexOf('@') > 0 ? + result.host.split('@') : false; + if (authInHost) { + result.auth = authInHost.shift(); + result.host = result.hostname = authInHost.shift(); } } - var ps = msg.slice(2, i - 1); - var p2 = msg.slice(i - 1, i); - if (p1.toString('hex') !== '0002') { - status++; - } - if (ps.length < 8) { - status++; + mustEndAbs = mustEndAbs || (result.host && srcPath.length); + + if (mustEndAbs && !isAbsolute) { + srcPath.unshift(''); } - return msg.slice(i); -} -function compare(a, b){ - var dif = 0; - var len = a.length; - if (a.length !== b.length) { - dif++; - len = Math.min(a.length, b.length); + + if (!srcPath.length) { + result.pathname = null; + result.path = null; + } else { + result.pathname = srcPath.join('/'); } - var i = -1; - while (++i < len) { - dif += (a[i] ^ b[i]); + + //to support request.http + if (!isNull(result.pathname) || !isNull(result.search)) { + result.path = (result.pathname ? result.pathname : '') + + (result.search ? result.search : ''); } - return dif; -} -}).call(this,require("buffer").Buffer) -},{"./mgf":155,"./xor":180,"bn.js":156,"browserify-rsa":157,"buffer":42,"parse-asn1":162}],179:[function(require,module,exports){ -(function (Buffer){ -var parseKeys = require('parse-asn1'); -var mgf = require('./mgf'); -var xor = require('./xor'); -var bn = require('bn.js'); -var constants = { - RSA_PKCS1_OAEP_PADDING: 4, - RSA_PKCS1_PADDIN: 1, - RSA_NO_PADDING: 3 + result.auth = relative.auth || result.auth; + result.slashes = result.slashes || relative.slashes; + result.href = result.format(); + return result; }; -module.exports = function (crypto) { - return publicEncrypt; - function publicEncrypt(public_key, msg) { - var padding; - if (public_key.padding) { - padding = public_key.padding; - } else { - padding = 4; - } - var key = parseKeys(public_key); - var paddedMsg; - if (padding === 4) { - paddedMsg = oaep(key, msg, crypto); - } else if (padding === 1) { - paddedMsg = pkcs1(key, msg, crypto); - } else if (padding === 3) { - paddedMsg = new bn(msg); - if (paddedMsg.cmp(key.modulus) >= 0) { - throw new Error('data too long for modulus'); - } - } else { - throw new Error('unknown padding'); +Url.prototype.parseHost = function() { + var host = this.host; + var port = portPattern.exec(host); + if (port) { + port = port[0]; + if (port !== ':') { + this.port = port.substr(1); } - var enc = paddedMsg - .toRed(bn.mont(key.modulus)) - .redPow(new bn(key.publicExponent)) - .fromRed() - .toArray(); - return new Buffer(enc); + host = host.substr(0, host.length - port.length); } + if (host) this.hostname = host; }; -function oaep(key, msg, crypto){ - var k = key.modulus.byteLength(); - var mLen = msg.length; - var iHash = crypto.createHash('sha1').update(new Buffer('')).digest(); - var hLen = iHash.length; - var hLen2 = 2 * hLen; - if (mLen > k - hLen2 - 2) { - throw new Error('message too long'); - } - var ps = new Buffer(k - mLen - hLen2 - 2); - ps.fill(0); - var dblen = k - hLen - 1; - var seed = crypto.randomBytes(hLen); - var maskedDb = xor(Buffer.concat([iHash, ps, new Buffer([1]), msg], dblen), mgf(seed, dblen, crypto)); - var maskedSeed = xor(seed, mgf(maskedDb, hLen, crypto)); - return new bn(Buffer.concat([new Buffer([0]), maskedSeed, maskedDb], k)); -} -function pkcs1(key, msg, crypto){ - var mLen = msg.length; - var k = key.modulus.byteLength(); - if (mLen > k - 11) { - throw new Error('message too long'); - } - var ps = nonZero(k - mLen - 3, crypto); - return new bn(Buffer.concat([new Buffer([0, 2]), ps, new Buffer([0]), msg], k)); -} -function nonZero(len, crypto) { - var out = new Buffer(len); - var i = 0; - var cache = crypto.randomBytes(len*2); - var cur = 0; - var num; - while (i < len) { - if (cur === cache.length) { - cache = crypto.randomBytes(len*2); - cur = 0; - } - num = cache[cur++]; - if (num) { - out[i++] = num; - } - } - return out; +function isString(arg) { + return typeof arg === "string"; } -}).call(this,require("buffer").Buffer) -},{"./mgf":155,"./xor":180,"bn.js":156,"buffer":42,"parse-asn1":162}],180:[function(require,module,exports){ -module.exports = function xor(a, b) { - var len = a.length; - var i = -1; - while (++i < len) { - a[i] ^= b[i]; - } - return a -}; -},{}],181:[function(require,module,exports){ -(function (process,global,Buffer){ -'use strict'; -var crypto = global.crypto || global.msCrypto -if(crypto && crypto.getRandomValues) { - module.exports = randomBytes; -} else { - module.exports = oldBrowser; +function isObject(arg) { + return typeof arg === 'object' && arg !== null; } -function randomBytes(size, cb) { - var bytes = new Buffer(size); //in browserify, this is an extended Uint8Array - /* This will not work in older browsers. - * See https://developer.mozilla.org/en-US/docs/Web/API/window.crypto.getRandomValues - */ - crypto.getRandomValues(bytes); - if (typeof cb === 'function') { - return process.nextTick(function () { - cb(null, bytes); - }); - } - return bytes; +function isNull(arg) { + return arg === null; } -function oldBrowser() { - throw new Error( - 'secure random number generation not supported by this browser\n'+ - 'use chrome, FireFox or Internet Explorer 11' - ) +function isNullOrUndefined(arg) { + return arg == null; } -}).call(this,require('_process'),typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {},require("buffer").Buffer) -},{"_process":184,"buffer":42}],182:[function(require,module,exports){ +},{"punycode":195,"querystring":198}],213:[function(require,module,exports){ +module.exports = function isBuffer(arg) { + return arg && typeof arg === 'object' + && typeof arg.copy === 'function' + && typeof arg.fill === 'function' + && typeof arg.readUInt8 === 'function'; +} +},{}],214:[function(require,module,exports){ +(function (process,global){ // Copyright Joyent, Inc. and other Node contributors. // // Permission is hereby granted, free of charge, to any person obtaining a @@ -23849,16555 +23787,18821 @@ function oldBrowser() { // OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE // USE OR OTHER DEALINGS IN THE SOFTWARE. -function EventEmitter() { - this._events = this._events || {}; - this._maxListeners = this._maxListeners || undefined; -} -module.exports = EventEmitter; - -// Backwards-compat with node 0.10.x -EventEmitter.EventEmitter = EventEmitter; - -EventEmitter.prototype._events = undefined; -EventEmitter.prototype._maxListeners = undefined; - -// By default EventEmitters will print a warning if more than 10 listeners are -// added to it. This is a useful default which helps finding memory leaks. -EventEmitter.defaultMaxListeners = 10; +var formatRegExp = /%[sdj%]/g; +exports.format = function(f) { + if (!isString(f)) { + var objects = []; + for (var i = 0; i < arguments.length; i++) { + objects.push(inspect(arguments[i])); + } + return objects.join(' '); + } -// Obviously not all Emitters should be limited to 10. This function allows -// that to be increased. Set to zero for unlimited. -EventEmitter.prototype.setMaxListeners = function(n) { - if (!isNumber(n) || n < 0 || isNaN(n)) - throw TypeError('n must be a positive number'); - this._maxListeners = n; - return this; + var i = 1; + var args = arguments; + var len = args.length; + var str = String(f).replace(formatRegExp, function(x) { + if (x === '%%') return '%'; + if (i >= len) return x; + switch (x) { + case '%s': return String(args[i++]); + case '%d': return Number(args[i++]); + case '%j': + try { + return JSON.stringify(args[i++]); + } catch (_) { + return '[Circular]'; + } + default: + return x; + } + }); + for (var x = args[i]; i < len; x = args[++i]) { + if (isNull(x) || !isObject(x)) { + str += ' ' + x; + } else { + str += ' ' + inspect(x); + } + } + return str; }; -EventEmitter.prototype.emit = function(type) { - var er, handler, len, args, i, listeners; - if (!this._events) - this._events = {}; +// Mark that a method should not be used. +// Returns a modified function which warns once by default. +// If --no-deprecation is set, then it is a no-op. +exports.deprecate = function(fn, msg) { + // Allow for deprecating things in the process of starting up. + if (isUndefined(global.process)) { + return function() { + return exports.deprecate(fn, msg).apply(this, arguments); + }; + } - // If there is no 'error' event listener then throw. - if (type === 'error') { - if (!this._events.error || - (isObject(this._events.error) && !this._events.error.length)) { - er = arguments[1]; - if (er instanceof Error) { - throw er; // Unhandled 'error' event + if (process.noDeprecation === true) { + return fn; + } + + var warned = false; + function deprecated() { + if (!warned) { + if (process.throwDeprecation) { + throw new Error(msg); + } else if (process.traceDeprecation) { + console.trace(msg); + } else { + console.error(msg); } - throw TypeError('Uncaught, unspecified "error" event.'); + warned = true; } + return fn.apply(this, arguments); } - handler = this._events[type]; + return deprecated; +}; - if (isUndefined(handler)) - return false; - if (isFunction(handler)) { - switch (arguments.length) { - // fast cases - case 1: - handler.call(this); - break; - case 2: - handler.call(this, arguments[1]); - break; - case 3: - handler.call(this, arguments[1], arguments[2]); - break; - // slower - default: - len = arguments.length; - args = new Array(len - 1); - for (i = 1; i < len; i++) - args[i - 1] = arguments[i]; - handler.apply(this, args); +var debugs = {}; +var debugEnviron; +exports.debuglog = function(set) { + if (isUndefined(debugEnviron)) + debugEnviron = process.env.NODE_DEBUG || ''; + set = set.toUpperCase(); + if (!debugs[set]) { + if (new RegExp('\\b' + set + '\\b', 'i').test(debugEnviron)) { + var pid = process.pid; + debugs[set] = function() { + var msg = exports.format.apply(exports, arguments); + console.error('%s %d: %s', set, pid, msg); + }; + } else { + debugs[set] = function() {}; } - } else if (isObject(handler)) { - len = arguments.length; - args = new Array(len - 1); - for (i = 1; i < len; i++) - args[i - 1] = arguments[i]; - - listeners = handler.slice(); - len = listeners.length; - for (i = 0; i < len; i++) - listeners[i].apply(this, args); } - - return true; + return debugs[set]; }; -EventEmitter.prototype.addListener = function(type, listener) { - var m; - if (!isFunction(listener)) - throw TypeError('listener must be a function'); +/** + * Echos the value of a value. Trys to print the value out + * in the best way possible given the different types. + * + * @param {Object} obj The object to print out. + * @param {Object} opts Optional options object that alters the output. + */ +/* legacy: obj, showHidden, depth, colors*/ +function inspect(obj, opts) { + // default options + var ctx = { + seen: [], + stylize: stylizeNoColor + }; + // legacy... + if (arguments.length >= 3) ctx.depth = arguments[2]; + if (arguments.length >= 4) ctx.colors = arguments[3]; + if (isBoolean(opts)) { + // legacy... + ctx.showHidden = opts; + } else if (opts) { + // got an "options" object + exports._extend(ctx, opts); + } + // set default options + if (isUndefined(ctx.showHidden)) ctx.showHidden = false; + if (isUndefined(ctx.depth)) ctx.depth = 2; + if (isUndefined(ctx.colors)) ctx.colors = false; + if (isUndefined(ctx.customInspect)) ctx.customInspect = true; + if (ctx.colors) ctx.stylize = stylizeWithColor; + return formatValue(ctx, obj, ctx.depth); +} +exports.inspect = inspect; - if (!this._events) - this._events = {}; - // To avoid recursion in the case that type === "newListener"! Before - // adding it to the listeners, first emit "newListener". - if (this._events.newListener) - this.emit('newListener', type, - isFunction(listener.listener) ? - listener.listener : listener); +// http://en.wikipedia.org/wiki/ANSI_escape_code#graphics +inspect.colors = { + 'bold' : [1, 22], + 'italic' : [3, 23], + 'underline' : [4, 24], + 'inverse' : [7, 27], + 'white' : [37, 39], + 'grey' : [90, 39], + 'black' : [30, 39], + 'blue' : [34, 39], + 'cyan' : [36, 39], + 'green' : [32, 39], + 'magenta' : [35, 39], + 'red' : [31, 39], + 'yellow' : [33, 39] +}; - if (!this._events[type]) - // Optimize the case of one listener. Don't need the extra array object. - this._events[type] = listener; - else if (isObject(this._events[type])) - // If we've already got an array, just append. - this._events[type].push(listener); - else - // Adding the second element, need to change to array. - this._events[type] = [this._events[type], listener]; +// Don't use 'blue' not visible on cmd.exe +inspect.styles = { + 'special': 'cyan', + 'number': 'yellow', + 'boolean': 'yellow', + 'undefined': 'grey', + 'null': 'bold', + 'string': 'green', + 'date': 'magenta', + // "name": intentionally not styling + 'regexp': 'red' +}; - // Check for listener leak - if (isObject(this._events[type]) && !this._events[type].warned) { - var m; - if (!isUndefined(this._maxListeners)) { - m = this._maxListeners; - } else { - m = EventEmitter.defaultMaxListeners; - } - if (m && m > 0 && this._events[type].length > m) { - this._events[type].warned = true; - console.error('(node) warning: possible EventEmitter memory ' + - 'leak detected. %d listeners added. ' + - 'Use emitter.setMaxListeners() to increase limit.', - this._events[type].length); - if (typeof console.trace === 'function') { - // not supported in IE 10 - console.trace(); - } - } - } +function stylizeWithColor(str, styleType) { + var style = inspect.styles[styleType]; - return this; -}; + if (style) { + return '\u001b[' + inspect.colors[style][0] + 'm' + str + + '\u001b[' + inspect.colors[style][1] + 'm'; + } else { + return str; + } +} -EventEmitter.prototype.on = EventEmitter.prototype.addListener; -EventEmitter.prototype.once = function(type, listener) { - if (!isFunction(listener)) - throw TypeError('listener must be a function'); +function stylizeNoColor(str, styleType) { + return str; +} - var fired = false; - function g() { - this.removeListener(type, g); +function arrayToHash(array) { + var hash = {}; - if (!fired) { - fired = true; - listener.apply(this, arguments); - } - } + array.forEach(function(val, idx) { + hash[val] = true; + }); - g.listener = listener; - this.on(type, g); + return hash; +} - return this; -}; -// emits a 'removeListener' event iff the listener was removed -EventEmitter.prototype.removeListener = function(type, listener) { - var list, position, length, i; +function formatValue(ctx, value, recurseTimes) { + // Provide a hook for user-specified inspect functions. + // Check that value is an object with an inspect function on it + if (ctx.customInspect && + value && + isFunction(value.inspect) && + // Filter out the util module, it's inspect function is special + value.inspect !== exports.inspect && + // Also filter out any prototype objects using the circular check. + !(value.constructor && value.constructor.prototype === value)) { + var ret = value.inspect(recurseTimes, ctx); + if (!isString(ret)) { + ret = formatValue(ctx, ret, recurseTimes); + } + return ret; + } - if (!isFunction(listener)) - throw TypeError('listener must be a function'); + // Primitive types cannot have properties + var primitive = formatPrimitive(ctx, value); + if (primitive) { + return primitive; + } - if (!this._events || !this._events[type]) - return this; + // Look up the keys of the object. + var keys = Object.keys(value); + var visibleKeys = arrayToHash(keys); - list = this._events[type]; - length = list.length; - position = -1; + if (ctx.showHidden) { + keys = Object.getOwnPropertyNames(value); + } - if (list === listener || - (isFunction(list.listener) && list.listener === listener)) { - delete this._events[type]; - if (this._events.removeListener) - this.emit('removeListener', type, listener); + // IE doesn't make error fields non-enumerable + // http://msdn.microsoft.com/en-us/library/ie/dww52sbt(v=vs.94).aspx + if (isError(value) + && (keys.indexOf('message') >= 0 || keys.indexOf('description') >= 0)) { + return formatError(value); + } - } else if (isObject(list)) { - for (i = length; i-- > 0;) { - if (list[i] === listener || - (list[i].listener && list[i].listener === listener)) { - position = i; - break; - } + // Some type of object without properties can be shortcutted. + if (keys.length === 0) { + if (isFunction(value)) { + var name = value.name ? ': ' + value.name : ''; + return ctx.stylize('[Function' + name + ']', 'special'); + } + if (isRegExp(value)) { + return ctx.stylize(RegExp.prototype.toString.call(value), 'regexp'); + } + if (isDate(value)) { + return ctx.stylize(Date.prototype.toString.call(value), 'date'); } + if (isError(value)) { + return formatError(value); + } + } - if (position < 0) - return this; + var base = '', array = false, braces = ['{', '}']; - if (list.length === 1) { - list.length = 0; - delete this._events[type]; - } else { - list.splice(position, 1); - } + // Make Array say that they are Array + if (isArray(value)) { + array = true; + braces = ['[', ']']; + } - if (this._events.removeListener) - this.emit('removeListener', type, listener); + // Make functions say that they are functions + if (isFunction(value)) { + var n = value.name ? ': ' + value.name : ''; + base = ' [Function' + n + ']'; } - return this; -}; + // Make RegExps say that they are RegExps + if (isRegExp(value)) { + base = ' ' + RegExp.prototype.toString.call(value); + } -EventEmitter.prototype.removeAllListeners = function(type) { - var key, listeners; + // Make dates with properties first say the date + if (isDate(value)) { + base = ' ' + Date.prototype.toUTCString.call(value); + } - if (!this._events) - return this; + // Make error with message first say the error + if (isError(value)) { + base = ' ' + formatError(value); + } - // not listening for removeListener, no need to emit - if (!this._events.removeListener) { - if (arguments.length === 0) - this._events = {}; - else if (this._events[type]) - delete this._events[type]; - return this; + if (keys.length === 0 && (!array || value.length == 0)) { + return braces[0] + base + braces[1]; } - // emit removeListener for all listeners on all events - if (arguments.length === 0) { - for (key in this._events) { - if (key === 'removeListener') continue; - this.removeAllListeners(key); + if (recurseTimes < 0) { + if (isRegExp(value)) { + return ctx.stylize(RegExp.prototype.toString.call(value), 'regexp'); + } else { + return ctx.stylize('[Object]', 'special'); } - this.removeAllListeners('removeListener'); - this._events = {}; - return this; } - listeners = this._events[type]; + ctx.seen.push(value); - if (isFunction(listeners)) { - this.removeListener(type, listeners); + var output; + if (array) { + output = formatArray(ctx, value, recurseTimes, visibleKeys, keys); } else { - // LIFO order - while (listeners.length) - this.removeListener(type, listeners[listeners.length - 1]); + output = keys.map(function(key) { + return formatProperty(ctx, value, recurseTimes, visibleKeys, key, array); + }); } - delete this._events[type]; - return this; -}; + ctx.seen.pop(); -EventEmitter.prototype.listeners = function(type) { - var ret; - if (!this._events || !this._events[type]) - ret = []; - else if (isFunction(this._events[type])) - ret = [this._events[type]]; - else - ret = this._events[type].slice(); - return ret; -}; + return reduceToSingleString(output, base, braces); +} -EventEmitter.listenerCount = function(emitter, type) { - var ret; - if (!emitter._events || !emitter._events[type]) - ret = 0; - else if (isFunction(emitter._events[type])) - ret = 1; - else - ret = emitter._events[type].length; - return ret; -}; -function isFunction(arg) { - return typeof arg === 'function'; +function formatPrimitive(ctx, value) { + if (isUndefined(value)) + return ctx.stylize('undefined', 'undefined'); + if (isString(value)) { + var simple = '\'' + JSON.stringify(value).replace(/^"|"$/g, '') + .replace(/'/g, "\\'") + .replace(/\\"/g, '"') + '\''; + return ctx.stylize(simple, 'string'); + } + if (isNumber(value)) + return ctx.stylize('' + value, 'number'); + if (isBoolean(value)) + return ctx.stylize('' + value, 'boolean'); + // For some reason typeof null is "object", so special case here. + if (isNull(value)) + return ctx.stylize('null', 'null'); +} + + +function formatError(value) { + return '[' + Error.prototype.toString.call(value) + ']'; +} + + +function formatArray(ctx, value, recurseTimes, visibleKeys, keys) { + var output = []; + for (var i = 0, l = value.length; i < l; ++i) { + if (hasOwnProperty(value, String(i))) { + output.push(formatProperty(ctx, value, recurseTimes, visibleKeys, + String(i), true)); + } else { + output.push(''); + } + } + keys.forEach(function(key) { + if (!key.match(/^\d+$/)) { + output.push(formatProperty(ctx, value, recurseTimes, visibleKeys, + key, true)); + } + }); + return output; +} + + +function formatProperty(ctx, value, recurseTimes, visibleKeys, key, array) { + var name, str, desc; + desc = Object.getOwnPropertyDescriptor(value, key) || { value: value[key] }; + if (desc.get) { + if (desc.set) { + str = ctx.stylize('[Getter/Setter]', 'special'); + } else { + str = ctx.stylize('[Getter]', 'special'); + } + } else { + if (desc.set) { + str = ctx.stylize('[Setter]', 'special'); + } + } + if (!hasOwnProperty(visibleKeys, key)) { + name = '[' + key + ']'; + } + if (!str) { + if (ctx.seen.indexOf(desc.value) < 0) { + if (isNull(recurseTimes)) { + str = formatValue(ctx, desc.value, null); + } else { + str = formatValue(ctx, desc.value, recurseTimes - 1); + } + if (str.indexOf('\n') > -1) { + if (array) { + str = str.split('\n').map(function(line) { + return ' ' + line; + }).join('\n').substr(2); + } else { + str = '\n' + str.split('\n').map(function(line) { + return ' ' + line; + }).join('\n'); + } + } + } else { + str = ctx.stylize('[Circular]', 'special'); + } + } + if (isUndefined(name)) { + if (array && key.match(/^\d+$/)) { + return str; + } + name = JSON.stringify('' + key); + if (name.match(/^"([a-zA-Z_][a-zA-Z_0-9]*)"$/)) { + name = name.substr(1, name.length - 2); + name = ctx.stylize(name, 'name'); + } else { + name = name.replace(/'/g, "\\'") + .replace(/\\"/g, '"') + .replace(/(^"|"$)/g, "'"); + name = ctx.stylize(name, 'string'); + } + } + + return name + ': ' + str; +} + + +function reduceToSingleString(output, base, braces) { + var numLinesEst = 0; + var length = output.reduce(function(prev, cur) { + numLinesEst++; + if (cur.indexOf('\n') >= 0) numLinesEst++; + return prev + cur.replace(/\u001b\[\d\d?m/g, '').length + 1; + }, 0); + + if (length > 60) { + return braces[0] + + (base === '' ? '' : base + '\n ') + + ' ' + + output.join(',\n ') + + ' ' + + braces[1]; + } + + return braces[0] + base + ' ' + output.join(', ') + ' ' + braces[1]; +} + + +// NOTE: These type checking functions intentionally don't use `instanceof` +// because it is fragile and can be easily faked with `Object.create()`. +function isArray(ar) { + return Array.isArray(ar); +} +exports.isArray = isArray; + +function isBoolean(arg) { + return typeof arg === 'boolean'; +} +exports.isBoolean = isBoolean; + +function isNull(arg) { + return arg === null; +} +exports.isNull = isNull; + +function isNullOrUndefined(arg) { + return arg == null; } +exports.isNullOrUndefined = isNullOrUndefined; function isNumber(arg) { return typeof arg === 'number'; } +exports.isNumber = isNumber; -function isObject(arg) { - return typeof arg === 'object' && arg !== null; +function isString(arg) { + return typeof arg === 'string'; +} +exports.isString = isString; + +function isSymbol(arg) { + return typeof arg === 'symbol'; } +exports.isSymbol = isSymbol; function isUndefined(arg) { return arg === void 0; } +exports.isUndefined = isUndefined; -},{}],183:[function(require,module,exports){ -module.exports = Array.isArray || function (arr) { - return Object.prototype.toString.call(arr) == '[object Array]'; -}; +function isRegExp(re) { + return isObject(re) && objectToString(re) === '[object RegExp]'; +} +exports.isRegExp = isRegExp; -},{}],184:[function(require,module,exports){ -// shim for using process in browser +function isObject(arg) { + return typeof arg === 'object' && arg !== null; +} +exports.isObject = isObject; -var process = module.exports = {}; +function isDate(d) { + return isObject(d) && objectToString(d) === '[object Date]'; +} +exports.isDate = isDate; -process.nextTick = (function () { - var canSetImmediate = typeof window !== 'undefined' - && window.setImmediate; - var canMutationObserver = typeof window !== 'undefined' - && window.MutationObserver; - var canPost = typeof window !== 'undefined' - && window.postMessage && window.addEventListener - ; +function isError(e) { + return isObject(e) && + (objectToString(e) === '[object Error]' || e instanceof Error); +} +exports.isError = isError; - if (canSetImmediate) { - return function (f) { return window.setImmediate(f) }; - } +function isFunction(arg) { + return typeof arg === 'function'; +} +exports.isFunction = isFunction; - var queue = []; +function isPrimitive(arg) { + return arg === null || + typeof arg === 'boolean' || + typeof arg === 'number' || + typeof arg === 'string' || + typeof arg === 'symbol' || // ES6 symbol + typeof arg === 'undefined'; +} +exports.isPrimitive = isPrimitive; - if (canMutationObserver) { - var hiddenDiv = document.createElement("div"); - var observer = new MutationObserver(function () { - var queueList = queue.slice(); - queue.length = 0; - queueList.forEach(function (fn) { - fn(); - }); - }); +exports.isBuffer = require('./support/isBuffer'); - observer.observe(hiddenDiv, { attributes: true }); +function objectToString(o) { + return Object.prototype.toString.call(o); +} - return function nextTick(fn) { - if (!queue.length) { - hiddenDiv.setAttribute('yes', 'no'); - } - queue.push(fn); - }; + +function pad(n) { + return n < 10 ? '0' + n.toString(10) : n.toString(10); +} + + +var months = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', + 'Oct', 'Nov', 'Dec']; + +// 26 Feb 16:19:34 +function timestamp() { + var d = new Date(); + var time = [pad(d.getHours()), + pad(d.getMinutes()), + pad(d.getSeconds())].join(':'); + return [d.getDate(), months[d.getMonth()], time].join(' '); +} + + +// log is just a thin wrapper to console.log that prepends a timestamp +exports.log = function() { + console.log('%s - %s', timestamp(), exports.format.apply(exports, arguments)); +}; + + +/** + * Inherit the prototype methods from one constructor into another. + * + * The Function.prototype.inherits from lang.js rewritten as a standalone + * function (not on Function.prototype). NOTE: If this file is to be loaded + * during bootstrapping this function needs to be rewritten using some native + * functions as prototype setup using normal JavaScript does not work as + * expected during bootstrapping (see mirror.js in r114903). + * + * @param {function} ctor Constructor function which needs to inherit the + * prototype. + * @param {function} superCtor Constructor function to inherit prototype from. + */ +exports.inherits = require('inherits'); + +exports._extend = function(origin, add) { + // Don't do anything if add isn't an object + if (!add || !isObject(add)) return origin; + + var keys = Object.keys(add); + var i = keys.length; + while (i--) { + origin[keys[i]] = add[keys[i]]; + } + return origin; +}; + +function hasOwnProperty(obj, prop) { + return Object.prototype.hasOwnProperty.call(obj, prop); +} + +}).call(this,require('_process'),typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}) +},{"./support/isBuffer":213,"_process":194,"inherits":240}],215:[function(require,module,exports){ +var indexOf = require('indexof'); + +var Object_keys = function (obj) { + if (Object.keys) return Object.keys(obj) + else { + var res = []; + for (var key in obj) res.push(key) + return res; } +}; - if (canPost) { - window.addEventListener('message', function (ev) { - var source = ev.source; - if ((source === window || source === null) && ev.data === 'process-tick') { - ev.stopPropagation(); - if (queue.length > 0) { - var fn = queue.shift(); - fn(); - } - } - }, true); +var forEach = function (xs, fn) { + if (xs.forEach) return xs.forEach(fn) + else for (var i = 0; i < xs.length; i++) { + fn(xs[i], i, xs); + } +}; - return function nextTick(fn) { - queue.push(fn); - window.postMessage('process-tick', '*'); +var defineProp = (function() { + try { + Object.defineProperty({}, '_', {}); + return function(obj, name, value) { + Object.defineProperty(obj, name, { + writable: true, + enumerable: false, + configurable: true, + value: value + }) + }; + } catch(e) { + return function(obj, name, value) { + obj[name] = value; }; } +}()); - return function nextTick(fn) { - setTimeout(fn, 0); - }; -})(); +var globals = ['Array', 'Boolean', 'Date', 'Error', 'EvalError', 'Function', +'Infinity', 'JSON', 'Math', 'NaN', 'Number', 'Object', 'RangeError', +'ReferenceError', 'RegExp', 'String', 'SyntaxError', 'TypeError', 'URIError', +'decodeURI', 'decodeURIComponent', 'encodeURI', 'encodeURIComponent', 'escape', +'eval', 'isFinite', 'isNaN', 'parseFloat', 'parseInt', 'undefined', 'unescape']; -process.title = 'browser'; -process.browser = true; -process.env = {}; -process.argv = []; +function Context() {} +Context.prototype = {}; -function noop() {} +var Script = exports.Script = function NodeScript (code) { + if (!(this instanceof Script)) return new Script(code); + this.code = code; +}; -process.on = noop; -process.addListener = noop; -process.once = noop; -process.off = noop; -process.removeListener = noop; -process.removeAllListeners = noop; -process.emit = noop; +Script.prototype.runInContext = function (context) { + if (!(context instanceof Context)) { + throw new TypeError("needs a 'context' argument."); + } + + var iframe = document.createElement('iframe'); + if (!iframe.style) iframe.style = {}; + iframe.style.display = 'none'; + + document.body.appendChild(iframe); + + var win = iframe.contentWindow; + var wEval = win.eval, wExecScript = win.execScript; -process.binding = function (name) { - throw new Error('process.binding is not supported'); + if (!wEval && wExecScript) { + // win.eval() magically appears when this is called in IE: + wExecScript.call(win, 'null'); + wEval = win.eval; + } + + forEach(Object_keys(context), function (key) { + win[key] = context[key]; + }); + forEach(globals, function (key) { + if (context[key]) { + win[key] = context[key]; + } + }); + + var winKeys = Object_keys(win); + + var res = wEval.call(win, this.code); + + forEach(Object_keys(win), function (key) { + // Avoid copying circular objects like `top` and `window` by only + // updating existing context properties or new properties in the `win` + // that was only introduced after the eval. + if (key in context || indexOf(winKeys, key) === -1) { + context[key] = win[key]; + } + }); + + forEach(globals, function (key) { + if (!(key in context)) { + defineProp(context, key, win[key]); + } + }); + + document.body.removeChild(iframe); + + return res; }; -// TODO(shtylman) -process.cwd = function () { return '/' }; -process.chdir = function (dir) { - throw new Error('process.chdir is not supported'); +Script.prototype.runInThisContext = function () { + return eval(this.code); // maybe... }; -},{}],185:[function(require,module,exports){ -(function (global){ -/*! http://mths.be/punycode v1.2.4 by @mathias */ -;(function(root) { +Script.prototype.runInNewContext = function (context) { + var ctx = Script.createContext(context); + var res = this.runInContext(ctx); - /** Detect free variables */ - var freeExports = typeof exports == 'object' && exports; - var freeModule = typeof module == 'object' && module && - module.exports == freeExports && module; - var freeGlobal = typeof global == 'object' && global; - if (freeGlobal.global === freeGlobal || freeGlobal.window === freeGlobal) { - root = freeGlobal; - } + forEach(Object_keys(ctx), function (key) { + context[key] = ctx[key]; + }); - /** - * The `punycode` object. - * @name punycode - * @type Object - */ - var punycode, + return res; +}; - /** Highest positive signed 32-bit float value */ - maxInt = 2147483647, // aka. 0x7FFFFFFF or 2^31-1 +forEach(Object_keys(Script.prototype), function (name) { + exports[name] = Script[name] = function (code) { + var s = Script(code); + return s[name].apply(s, [].slice.call(arguments, 1)); + }; +}); - /** Bootstring parameters */ - base = 36, - tMin = 1, - tMax = 26, - skew = 38, - damp = 700, - initialBias = 72, - initialN = 128, // 0x80 - delimiter = '-', // '\x2D' +exports.createScript = function (code) { + return exports.Script(code); +}; - /** Regular expressions */ - regexPunycode = /^xn--/, - regexNonASCII = /[^ -~]/, // unprintable ASCII chars + non-ASCII chars - regexSeparators = /\x2E|\u3002|\uFF0E|\uFF61/g, // RFC 3490 separators +exports.createContext = Script.createContext = function (context) { + var copy = new Context(); + if(typeof context === 'object') { + forEach(Object_keys(context), function (key) { + copy[key] = context[key]; + }); + } + return copy; +}; - /** Error messages */ - errors = { - 'overflow': 'Overflow: input needs wider integers to process', - 'not-basic': 'Illegal input >= 0x80 (not a basic code point)', - 'invalid-input': 'Invalid input' - }, +},{"indexof":216}],216:[function(require,module,exports){ - /** Convenience shortcuts */ - baseMinusTMin = base - tMin, - floor = Math.floor, - stringFromCharCode = String.fromCharCode, +var indexOf = [].indexOf; - /** Temporary variable */ - key; +module.exports = function(arr, obj){ + if (indexOf) return arr.indexOf(obj); + for (var i = 0; i < arr.length; ++i) { + if (arr[i] === obj) return i; + } + return -1; +}; +},{}],217:[function(require,module,exports){ +(function (module, exports) { - /*--------------------------------------------------------------------------*/ +'use strict'; - /** - * A generic error utility function. - * @private - * @param {String} type The error type. - * @returns {Error} Throws a `RangeError` with the applicable error message. - */ - function error(type) { - throw RangeError(errors[type]); - } - - /** - * A generic `Array#map` utility function. - * @private - * @param {Array} array The array to iterate over. - * @param {Function} callback The function that gets called for every array - * item. - * @returns {Array} A new array of values returned by the callback function. - */ - function map(array, fn) { - var length = array.length; - while (length--) { - array[length] = fn(array[length]); - } - return array; - } +// Utils - /** - * A simple `Array#map`-like wrapper to work with domain name strings. - * @private - * @param {String} domain The domain name. - * @param {Function} callback The function that gets called for every - * character. - * @returns {Array} A new string of characters returned by the callback - * function. - */ - function mapDomain(string, fn) { - return map(string.split(regexSeparators), fn).join('.'); - } +function assert(val, msg) { + if (!val) + throw new Error(msg || 'Assertion failed'); +} - /** - * Creates an array containing the numeric code points of each Unicode - * character in the string. While JavaScript uses UCS-2 internally, - * this function will convert a pair of surrogate halves (each of which - * UCS-2 exposes as separate characters) into a single code point, - * matching UTF-16. - * @see `punycode.ucs2.encode` - * @see - * @memberOf punycode.ucs2 - * @name decode - * @param {String} string The Unicode input string (UCS-2). - * @returns {Array} The new array of code points. - */ - function ucs2decode(string) { - var output = [], - counter = 0, - length = string.length, - value, - extra; - while (counter < length) { - value = string.charCodeAt(counter++); - if (value >= 0xD800 && value <= 0xDBFF && counter < length) { - // high surrogate, and there is a next character - extra = string.charCodeAt(counter++); - if ((extra & 0xFC00) == 0xDC00) { // low surrogate - output.push(((value & 0x3FF) << 10) + (extra & 0x3FF) + 0x10000); - } else { - // unmatched surrogate; only append this code unit, in case the next - // code unit is the high surrogate of a surrogate pair - output.push(value); - counter--; - } - } else { - output.push(value); - } - } - return output; - } +// Could use `inherits` module, but don't want to move from single file +// architecture yet. +function inherits(ctor, superCtor) { + ctor.super_ = superCtor; + var TempCtor = function () {}; + TempCtor.prototype = superCtor.prototype; + ctor.prototype = new TempCtor(); + ctor.prototype.constructor = ctor; +} - /** - * Creates a string based on an array of numeric code points. - * @see `punycode.ucs2.decode` - * @memberOf punycode.ucs2 - * @name encode - * @param {Array} codePoints The array of numeric code points. - * @returns {String} The new Unicode string (UCS-2). - */ - function ucs2encode(array) { - return map(array, function(value) { - var output = ''; - if (value > 0xFFFF) { - value -= 0x10000; - output += stringFromCharCode(value >>> 10 & 0x3FF | 0xD800); - value = 0xDC00 | value & 0x3FF; - } - output += stringFromCharCode(value); - return output; - }).join(''); - } +// BN - /** - * Converts a basic code point into a digit/integer. - * @see `digitToBasic()` - * @private - * @param {Number} codePoint The basic numeric code point value. - * @returns {Number} The numeric value of a basic code point (for use in - * representing integers) in the range `0` to `base - 1`, or `base` if - * the code point does not represent a value. - */ - function basicToDigit(codePoint) { - if (codePoint - 48 < 10) { - return codePoint - 22; - } - if (codePoint - 65 < 26) { - return codePoint - 65; - } - if (codePoint - 97 < 26) { - return codePoint - 97; - } - return base; - } +function BN(number, base, endian) { + // May be `new BN(bn)` ? + if (number !== null && + typeof number === 'object' && + Array.isArray(number.words)) { + return number; + } - /** - * Converts a digit/integer into a basic code point. - * @see `basicToDigit()` - * @private - * @param {Number} digit The numeric value of a basic code point. - * @returns {Number} The basic code point whose value (when used for - * representing integers) is `digit`, which needs to be in the range - * `0` to `base - 1`. If `flag` is non-zero, the uppercase form is - * used; else, the lowercase form is used. The behavior is undefined - * if `flag` is non-zero and `digit` has no uppercase form. - */ - function digitToBasic(digit, flag) { - // 0..25 map to ASCII a..z or A..Z - // 26..35 map to ASCII 0..9 - return digit + 22 + 75 * (digit < 26) - ((flag != 0) << 5); - } + this.sign = false; + this.words = null; + this.length = 0; - /** - * Bias adaptation function as per section 3.4 of RFC 3492. - * http://tools.ietf.org/html/rfc3492#section-3.4 - * @private - */ - function adapt(delta, numPoints, firstTime) { - var k = 0; - delta = firstTime ? floor(delta / damp) : delta >> 1; - delta += floor(delta / numPoints); - for (/* no initialization */; delta > baseMinusTMin * tMax >> 1; k += base) { - delta = floor(delta / baseMinusTMin); - } - return floor(k + (baseMinusTMin + 1) * delta / (delta + skew)); - } + // Reduction context + this.red = null; - /** - * Converts a Punycode string of ASCII-only symbols to a string of Unicode - * symbols. - * @memberOf punycode - * @param {String} input The Punycode string of ASCII-only symbols. - * @returns {String} The resulting string of Unicode symbols. - */ - function decode(input) { - // Don't use UCS-2 - var output = [], - inputLength = input.length, - out, - i = 0, - n = initialN, - bias = initialBias, - basic, - j, - index, - oldi, - w, - k, - digit, - t, - /** Cached calculation results */ - baseMinusT; + if (base === 'le' || base === 'be') { + endian = base; + base = 10; + } - // Handle the basic code points: let `basic` be the number of input code - // points before the last delimiter, or `0` if there is none, then copy - // the first basic code points to the output. + if (number !== null) + this._init(number || 0, base || 10, endian || 'be'); +} +if (typeof module === 'object') + module.exports = BN; +else + exports.BN = BN; - basic = input.lastIndexOf(delimiter); - if (basic < 0) { - basic = 0; - } +BN.BN = BN; +BN.wordSize = 26; - for (j = 0; j < basic; ++j) { - // if it's not a basic code point - if (input.charCodeAt(j) >= 0x80) { - error('not-basic'); - } - output.push(input.charCodeAt(j)); - } +BN.prototype._init = function init(number, base, endian) { + if (typeof number === 'number') { + if (number < 0) { + this.sign = true; + number = -number; + } + if (number < 0x4000000) { + this.words = [ number & 0x3ffffff ]; + this.length = 1; + } else if (number < 0x10000000000000) { + this.words = [ + number & 0x3ffffff, + (number / 0x4000000) & 0x3ffffff + ]; + this.length = 2; + } else { + assert(number < 0x20000000000000); // 2 ^ 53 (unsafe) + this.words = [ + number & 0x3ffffff, + (number / 0x4000000) & 0x3ffffff, + 1 + ]; + this.length = 3; + } + return; + } else if (typeof number === 'object') { + return this._initArray(number, base, endian); + } + if (base === 'hex') + base = 16; + assert(base === (base | 0) && base >= 2 && base <= 36); - // Main decoding loop: start just after the last delimiter if any basic code - // points were copied; start at the beginning otherwise. + number = number.toString().replace(/\s+/g, ''); + var start = 0; + if (number[0] === '-') + start++; - for (index = basic > 0 ? basic + 1 : 0; index < inputLength; /* no final expression */) { + if (base === 16) + this._parseHex(number, start); + else + this._parseBase(number, base, start); - // `index` is the index of the next character to be consumed. - // Decode a generalized variable-length integer into `delta`, - // which gets added to `i`. The overflow checking is easier - // if we increase `i` as we go, then subtract off its starting - // value at the end to obtain `delta`. - for (oldi = i, w = 1, k = base; /* no condition */; k += base) { + if (number[0] === '-') + this.sign = true; - if (index >= inputLength) { - error('invalid-input'); - } + this.strip(); +}; - digit = basicToDigit(input.charCodeAt(index++)); +BN.prototype._initArray = function _initArray(number, base, endian) { + // Perhaps a Uint8Array + assert(typeof number.length === 'number'); + if (number.length <= 0) { + this.words = [ 0 ]; + this.length = 1; + return this; + } - if (digit >= base || digit > floor((maxInt - i) / w)) { - error('overflow'); - } + this.length = Math.ceil(number.length / 3); + this.words = new Array(this.length); + for (var i = 0; i < this.length; i++) + this.words[i] = 0; - i += digit * w; - t = k <= bias ? tMin : (k >= bias + tMax ? tMax : k - bias); + var off = 0; + if (endian === 'be') { + for (var i = number.length - 1, j = 0; i >= 0; i -= 3) { + var w = number[i] | (number[i - 1] << 8) | (number[i - 2] << 16); + this.words[j] |= (w << off) & 0x3ffffff; + this.words[j + 1] = (w >>> (26 - off)) & 0x3ffffff; + off += 24; + if (off >= 26) { + off -= 26; + j++; + } + } + } else if (endian === 'le') { + for (var i = 0, j = 0; i < number.length; i += 3) { + var w = number[i] | (number[i + 1] << 8) | (number[i + 2] << 16); + this.words[j] |= (w << off) & 0x3ffffff; + this.words[j + 1] = (w >>> (26 - off)) & 0x3ffffff; + off += 24; + if (off >= 26) { + off -= 26; + j++; + } + } + } + return this.strip(); +}; - if (digit < t) { - break; - } +function parseHex(str, start, end) { + var r = 0; + var len = Math.min(str.length, end); + for (var i = start; i < len; i++) { + var c = str.charCodeAt(i) - 48; - baseMinusT = base - t; - if (w > floor(maxInt / baseMinusT)) { - error('overflow'); - } + r <<= 4; - w *= baseMinusT; + // 'a' - 'f' + if (c >= 49 && c <= 54) + r |= c - 49 + 0xa; - } + // 'A' - 'F' + else if (c >= 17 && c <= 22) + r |= c - 17 + 0xa; - out = output.length + 1; - bias = adapt(i - oldi, out, oldi == 0); + // '0' - '9' + else + r |= c & 0xf; + } + return r; +} - // `i` was supposed to wrap around from `out` to `0`, - // incrementing `n` each time, so we'll fix that now: - if (floor(i / out) > maxInt - n) { - error('overflow'); - } +BN.prototype._parseHex = function _parseHex(number, start) { + // Create possibly bigger array to ensure that it fits the number + this.length = Math.ceil((number.length - start) / 6); + this.words = new Array(this.length); + for (var i = 0; i < this.length; i++) + this.words[i] = 0; - n += floor(i / out); - i %= out; + // Scan 24-bit chunks and add them to the number + var off = 0; + for (var i = number.length - 6, j = 0; i >= start; i -= 6) { + var w = parseHex(number, i, i + 6); + this.words[j] |= (w << off) & 0x3ffffff; + this.words[j + 1] |= w >>> (26 - off) & 0x3fffff; + off += 24; + if (off >= 26) { + off -= 26; + j++; + } + } + if (i + 6 !== start) { + var w = parseHex(number, start, i + 6); + this.words[j] |= (w << off) & 0x3ffffff; + this.words[j + 1] |= w >>> (26 - off) & 0x3fffff; + } + this.strip(); +}; - // Insert `n` at position `i` of the output - output.splice(i++, 0, n); +function parseBase(str, start, end, mul) { + var r = 0; + var len = Math.min(str.length, end); + for (var i = start; i < len; i++) { + var c = str.charCodeAt(i) - 48; - } + r *= mul; - return ucs2encode(output); - } + // 'a' + if (c >= 49) + r += c - 49 + 0xa; - /** - * Converts a string of Unicode symbols to a Punycode string of ASCII-only - * symbols. - * @memberOf punycode - * @param {String} input The string of Unicode symbols. - * @returns {String} The resulting Punycode string of ASCII-only symbols. - */ - function encode(input) { - var n, - delta, - handledCPCount, - basicLength, - bias, - j, - m, - q, - k, - t, - currentValue, - output = [], - /** `inputLength` will hold the number of code points in `input`. */ - inputLength, - /** Cached calculation results */ - handledCPCountPlusOne, - baseMinusT, - qMinusT; + // 'A' + else if (c >= 17) + r += c - 17 + 0xa; - // Convert the input in UCS-2 to Unicode - input = ucs2decode(input); + // '0' - '9' + else + r += c; + } + return r; +} - // Cache the length - inputLength = input.length; +BN.prototype._parseBase = function _parseBase(number, base, start) { + // Initialize as zero + this.words = [ 0 ]; + this.length = 1; - // Initialize the state - n = initialN; - delta = 0; - bias = initialBias; + // Find length of limb in base + for (var limbLen = 0, limbPow = 1; limbPow <= 0x3ffffff; limbPow *= base) + limbLen++; + limbLen--; + limbPow = (limbPow / base) | 0; - // Handle the basic code points - for (j = 0; j < inputLength; ++j) { - currentValue = input[j]; - if (currentValue < 0x80) { - output.push(stringFromCharCode(currentValue)); - } - } + var total = number.length - start; + var mod = total % limbLen; + var end = Math.min(total, total - mod) + start; - handledCPCount = basicLength = output.length; + var word = 0; + for (var i = start; i < end; i += limbLen) { + word = parseBase(number, i, i + limbLen, base); - // `handledCPCount` is the number of code points that have been handled; - // `basicLength` is the number of basic code points. + this.imuln(limbPow); + if (this.words[0] + word < 0x4000000) + this.words[0] += word; + else + this._iaddn(word); + } - // Finish the basic string - if it is not empty - with a delimiter - if (basicLength) { - output.push(delimiter); - } + if (mod !== 0) { + var pow = 1; + var word = parseBase(number, i, number.length, base); - // Main encoding loop: - while (handledCPCount < inputLength) { + for (var i = 0; i < mod; i++) + pow *= base; + this.imuln(pow); + if (this.words[0] + word < 0x4000000) + this.words[0] += word; + else + this._iaddn(word); + } +}; - // All non-basic code points < n have been handled already. Find the next - // larger one: - for (m = maxInt, j = 0; j < inputLength; ++j) { - currentValue = input[j]; - if (currentValue >= n && currentValue < m) { - m = currentValue; - } - } +BN.prototype.copy = function copy(dest) { + dest.words = new Array(this.length); + for (var i = 0; i < this.length; i++) + dest.words[i] = this.words[i]; + dest.length = this.length; + dest.sign = this.sign; + dest.red = this.red; +}; - // Increase `delta` enough to advance the decoder's state to , - // but guard against overflow - handledCPCountPlusOne = handledCPCount + 1; - if (m - n > floor((maxInt - delta) / handledCPCountPlusOne)) { - error('overflow'); - } +BN.prototype.clone = function clone() { + var r = new BN(null); + this.copy(r); + return r; +}; - delta += (m - n) * handledCPCountPlusOne; - n = m; +// Remove leading `0` from `this` +BN.prototype.strip = function strip() { + while (this.length > 1 && this.words[this.length - 1] === 0) + this.length--; + return this._normSign(); +}; - for (j = 0; j < inputLength; ++j) { - currentValue = input[j]; +BN.prototype._normSign = function _normSign() { + // -0 = 0 + if (this.length === 1 && this.words[0] === 0) + this.sign = false; + return this; +}; - if (currentValue < n && ++delta > maxInt) { - error('overflow'); - } +BN.prototype.inspect = function inspect() { + return (this.red ? ''; +}; - if (currentValue == n) { - // Represent delta as a generalized variable-length integer - for (q = delta, k = base; /* no condition */; k += base) { - t = k <= bias ? tMin : (k >= bias + tMax ? tMax : k - bias); - if (q < t) { - break; - } - qMinusT = q - t; - baseMinusT = base - t; - output.push( - stringFromCharCode(digitToBasic(t + qMinusT % baseMinusT, 0)) - ); - q = floor(qMinusT / baseMinusT); - } +/* - output.push(stringFromCharCode(digitToBasic(q, 0))); - bias = adapt(delta, handledCPCountPlusOne, handledCPCount == basicLength); - delta = 0; - ++handledCPCount; - } - } +var zeros = []; +var groupSizes = []; +var groupBases = []; - ++delta; - ++n; +var s = ''; +var i = -1; +while (++i < BN.wordSize) { + zeros[i] = s; + s += '0'; +} +groupSizes[0] = 0; +groupSizes[1] = 0; +groupBases[0] = 0; +groupBases[1] = 0; +var base = 2 - 1; +while (++base < 36 + 1) { + var groupSize = 0; + var groupBase = 1; + while (groupBase < (1 << BN.wordSize) / base) { + groupBase *= base; + groupSize += 1; + } + groupSizes[base] = groupSize; + groupBases[base] = groupBase; +} - } - return output.join(''); - } +*/ - /** - * Converts a Punycode string representing a domain name to Unicode. Only the - * Punycoded parts of the domain name will be converted, i.e. it doesn't - * matter if you call it on a string that has already been converted to - * Unicode. - * @memberOf punycode - * @param {String} domain The Punycode domain name to convert to Unicode. - * @returns {String} The Unicode representation of the given Punycode - * string. - */ - function toUnicode(domain) { - return mapDomain(domain, function(string) { - return regexPunycode.test(string) - ? decode(string.slice(4).toLowerCase()) - : string; - }); - } +var zeros = [ + '', + '0', + '00', + '000', + '0000', + '00000', + '000000', + '0000000', + '00000000', + '000000000', + '0000000000', + '00000000000', + '000000000000', + '0000000000000', + '00000000000000', + '000000000000000', + '0000000000000000', + '00000000000000000', + '000000000000000000', + '0000000000000000000', + '00000000000000000000', + '000000000000000000000', + '0000000000000000000000', + '00000000000000000000000', + '000000000000000000000000', + '0000000000000000000000000' +]; - /** - * Converts a Unicode string representing a domain name to Punycode. Only the - * non-ASCII parts of the domain name will be converted, i.e. it doesn't - * matter if you call it with a domain that's already in ASCII. - * @memberOf punycode - * @param {String} domain The domain name to convert, as a Unicode string. - * @returns {String} The Punycode representation of the given domain name. - */ - function toASCII(domain) { - return mapDomain(domain, function(string) { - return regexNonASCII.test(string) - ? 'xn--' + encode(string) - : string; - }); - } +var groupSizes = [ + 0, 0, + 25, 16, 12, 11, 10, 9, 8, + 8, 7, 7, 7, 7, 6, 6, + 6, 6, 6, 6, 6, 5, 5, + 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5 +]; - /*--------------------------------------------------------------------------*/ +var groupBases = [ + 0, 0, + 33554432, 43046721, 16777216, 48828125, 60466176, 40353607, 16777216, + 43046721, 10000000, 19487171, 35831808, 62748517, 7529536, 11390625, + 16777216, 24137569, 34012224, 47045881, 64000000, 4084101, 5153632, + 6436343, 7962624, 9765625, 11881376, 14348907, 17210368, 20511149, + 24300000, 28629151, 33554432, 39135393, 45435424, 52521875, 60466176 +]; - /** Define the public API */ - punycode = { - /** - * A string representing the current Punycode.js version number. - * @memberOf punycode - * @type String - */ - 'version': '1.2.4', - /** - * An object of methods to convert from JavaScript's internal character - * representation (UCS-2) to Unicode code points, and back. - * @see - * @memberOf punycode - * @type Object - */ - 'ucs2': { - 'decode': ucs2decode, - 'encode': ucs2encode - }, - 'decode': decode, - 'encode': encode, - 'toASCII': toASCII, - 'toUnicode': toUnicode - }; +BN.prototype.toString = function toString(base, padding) { + base = base || 10; + if (base === 16 || base === 'hex') { + var out = ''; + var off = 0; + var padding = padding | 0 || 1; + var carry = 0; + for (var i = 0; i < this.length; i++) { + var w = this.words[i]; + var word = (((w << off) | carry) & 0xffffff).toString(16); + carry = (w >>> (24 - off)) & 0xffffff; + if (carry !== 0 || i !== this.length - 1) + out = zeros[6 - word.length] + word + out; + else + out = word + out; + off += 2; + if (off >= 26) { + off -= 26; + i--; + } + } + if (carry !== 0) + out = carry.toString(16) + out; + while (out.length % padding !== 0) + out = '0' + out; + if (this.sign) + out = '-' + out; + return out; + } else if (base === (base | 0) && base >= 2 && base <= 36) { + // var groupSize = Math.floor(BN.wordSize * Math.LN2 / Math.log(base)); + var groupSize = groupSizes[base]; + // var groupBase = Math.pow(base, groupSize); + var groupBase = groupBases[base]; + var out = ''; + var c = this.clone(); + c.sign = false; + while (c.cmpn(0) !== 0) { + var r = c.modn(groupBase).toString(base); + c = c.idivn(groupBase); - /** Expose `punycode` */ - // Some AMD build optimizers, like r.js, check for specific condition patterns - // like the following: - if ( - typeof define == 'function' && - typeof define.amd == 'object' && - define.amd - ) { - define('punycode', function() { - return punycode; - }); - } else if (freeExports && !freeExports.nodeType) { - if (freeModule) { // in Node.js or RingoJS v0.8.0+ - freeModule.exports = punycode; - } else { // in Narwhal or RingoJS v0.7.0- - for (key in punycode) { - punycode.hasOwnProperty(key) && (freeExports[key] = punycode[key]); - } - } - } else { // in Rhino or a web browser - root.punycode = punycode; - } + if (c.cmpn(0) !== 0) + out = zeros[groupSize - r.length] + r + out; + else + out = r + out; + } + if (this.cmpn(0) === 0) + out = '0' + out; + if (this.sign) + out = '-' + out; + return out; + } else { + assert(false, 'Base should be between 2 and 36'); + } +}; -}(this)); +BN.prototype.toJSON = function toJSON() { + return this.toString(16); +}; -}).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}) -},{}],186:[function(require,module,exports){ -// Copyright Joyent, Inc. and other Node contributors. -// -// Permission is hereby granted, free of charge, to any person obtaining a -// copy of this software and associated documentation files (the -// "Software"), to deal in the Software without restriction, including -// without limitation the rights to use, copy, modify, merge, publish, -// distribute, sublicense, and/or sell copies of the Software, and to permit -// persons to whom the Software is furnished to do so, subject to the -// following conditions: -// -// The above copyright notice and this permission notice shall be included -// in all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS -// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN -// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, -// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR -// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE -// USE OR OTHER DEALINGS IN THE SOFTWARE. +BN.prototype.toArray = function toArray() { + this.strip(); + var res = new Array(this.byteLength()); + res[0] = 0; -'use strict'; + var q = this.clone(); + for (var i = 0; q.cmpn(0) !== 0; i++) { + var b = q.andln(0xff); + q.ishrn(8); -// If obj.hasOwnProperty has been overridden, then calling -// obj.hasOwnProperty(prop) will break. -// See: https://github.com/joyent/node/issues/1707 -function hasOwnProperty(obj, prop) { - return Object.prototype.hasOwnProperty.call(obj, prop); -} + // Assume big-endian + res[res.length - i - 1] = b; + } -module.exports = function(qs, sep, eq, options) { - sep = sep || '&'; - eq = eq || '='; - var obj = {}; + return res; +}; - if (typeof qs !== 'string' || qs.length === 0) { - return obj; - } +if (Math.clz32) { + BN.prototype._countBits = function _countBits(w) { + return 32 - Math.clz32(w); + }; +} else { + BN.prototype._countBits = function _countBits(w) { + var t = w; + var r = 0; + if (t >= 0x1000) { + r += 13; + t >>>= 13; + } + if (t >= 0x40) { + r += 7; + t >>>= 7; + } + if (t >= 0x8) { + r += 4; + t >>>= 4; + } + if (t >= 0x02) { + r += 2; + t >>>= 2; + } + return r + t; + }; +} - var regexp = /\+/g; - qs = qs.split(sep); +BN.prototype._zeroBits = function _zeroBits(w) { + // Short-cut + if (w === 0) + return 26; - var maxKeys = 1000; - if (options && typeof options.maxKeys === 'number') { - maxKeys = options.maxKeys; + var t = w; + var r = 0; + if ((t & 0x1fff) === 0) { + r += 13; + t >>>= 13; } - - var len = qs.length; - // maxKeys <= 0 means that we should not limit keys count - if (maxKeys > 0 && len > maxKeys) { - len = maxKeys; + if ((t & 0x7f) === 0) { + r += 7; + t >>>= 7; } + if ((t & 0xf) === 0) { + r += 4; + t >>>= 4; + } + if ((t & 0x3) === 0) { + r += 2; + t >>>= 2; + } + if ((t & 0x1) === 0) + r++; + return r; +}; - for (var i = 0; i < len; ++i) { - var x = qs[i].replace(regexp, '%20'), - idx = x.indexOf(eq), - kstr, vstr, k, v; - - if (idx >= 0) { - kstr = x.substr(0, idx); - vstr = x.substr(idx + 1); - } else { - kstr = x; - vstr = ''; - } +// Return number of used bits in a BN +BN.prototype.bitLength = function bitLength() { + var hi = 0; + var w = this.words[this.length - 1]; + var hi = this._countBits(w); + return (this.length - 1) * 26 + hi; +}; - k = decodeURIComponent(kstr); - v = decodeURIComponent(vstr); +// Number of trailing zero bits +BN.prototype.zeroBits = function zeroBits() { + if (this.cmpn(0) === 0) + return 0; - if (!hasOwnProperty(obj, k)) { - obj[k] = v; - } else if (isArray(obj[k])) { - obj[k].push(v); - } else { - obj[k] = [obj[k], v]; - } + var r = 0; + for (var i = 0; i < this.length; i++) { + var b = this._zeroBits(this.words[i]); + r += b; + if (b !== 26) + break; } + return r; +}; - return obj; +BN.prototype.byteLength = function byteLength() { + return Math.ceil(this.bitLength() / 8); }; -var isArray = Array.isArray || function (xs) { - return Object.prototype.toString.call(xs) === '[object Array]'; +// Return negative clone of `this` +BN.prototype.neg = function neg() { + if (this.cmpn(0) === 0) + return this.clone(); + + var r = this.clone(); + r.sign = !this.sign; + return r; }; -},{}],187:[function(require,module,exports){ -// Copyright Joyent, Inc. and other Node contributors. -// -// Permission is hereby granted, free of charge, to any person obtaining a -// copy of this software and associated documentation files (the -// "Software"), to deal in the Software without restriction, including -// without limitation the rights to use, copy, modify, merge, publish, -// distribute, sublicense, and/or sell copies of the Software, and to permit -// persons to whom the Software is furnished to do so, subject to the -// following conditions: -// -// The above copyright notice and this permission notice shall be included -// in all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS -// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN -// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, -// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR -// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE -// USE OR OTHER DEALINGS IN THE SOFTWARE. -'use strict'; +// Or `num` with `this` in-place +BN.prototype.ior = function ior(num) { + this.sign = this.sign || num.sign; -var stringifyPrimitive = function(v) { - switch (typeof v) { - case 'string': - return v; + while (this.length < num.length) + this.words[this.length++] = 0; - case 'boolean': - return v ? 'true' : 'false'; + for (var i = 0; i < num.length; i++) + this.words[i] = this.words[i] | num.words[i]; - case 'number': - return isFinite(v) ? v : ''; + return this.strip(); +}; - default: - return ''; - } + +// Or `num` with `this` +BN.prototype.or = function or(num) { + if (this.length > num.length) + return this.clone().ior(num); + else + return num.clone().ior(this); }; -module.exports = function(obj, sep, eq, name) { - sep = sep || '&'; - eq = eq || '='; - if (obj === null) { - obj = undefined; - } - if (typeof obj === 'object') { - return map(objectKeys(obj), function(k) { - var ks = encodeURIComponent(stringifyPrimitive(k)) + eq; - if (isArray(obj[k])) { - return map(obj[k], function(v) { - return ks + encodeURIComponent(stringifyPrimitive(v)); - }).join(sep); - } else { - return ks + encodeURIComponent(stringifyPrimitive(obj[k])); - } - }).join(sep); +// And `num` with `this` in-place +BN.prototype.iand = function iand(num) { + this.sign = this.sign && num.sign; - } + // b = min-length(num, this) + var b; + if (this.length > num.length) + b = num; + else + b = this; - if (!name) return ''; - return encodeURIComponent(stringifyPrimitive(name)) + eq + - encodeURIComponent(stringifyPrimitive(obj)); -}; + for (var i = 0; i < b.length; i++) + this.words[i] = this.words[i] & num.words[i]; -var isArray = Array.isArray || function (xs) { - return Object.prototype.toString.call(xs) === '[object Array]'; + this.length = b.length; + + return this.strip(); }; -function map (xs, f) { - if (xs.map) return xs.map(f); - var res = []; - for (var i = 0; i < xs.length; i++) { - res.push(f(xs[i], i)); - } - return res; -} -var objectKeys = Object.keys || function (obj) { - var res = []; - for (var key in obj) { - if (Object.prototype.hasOwnProperty.call(obj, key)) res.push(key); - } - return res; +// And `num` with `this` +BN.prototype.and = function and(num) { + if (this.length > num.length) + return this.clone().iand(num); + else + return num.clone().iand(this); }; -},{}],188:[function(require,module,exports){ -'use strict'; - -exports.decode = exports.parse = require('./decode'); -exports.encode = exports.stringify = require('./encode'); -},{"./decode":186,"./encode":187}],189:[function(require,module,exports){ -module.exports = require("./lib/_stream_duplex.js") +// Xor `num` with `this` in-place +BN.prototype.ixor = function ixor(num) { + this.sign = this.sign || num.sign; -},{"./lib/_stream_duplex.js":190}],190:[function(require,module,exports){ -(function (process){ -// Copyright Joyent, Inc. and other Node contributors. -// -// Permission is hereby granted, free of charge, to any person obtaining a -// copy of this software and associated documentation files (the -// "Software"), to deal in the Software without restriction, including -// without limitation the rights to use, copy, modify, merge, publish, -// distribute, sublicense, and/or sell copies of the Software, and to permit -// persons to whom the Software is furnished to do so, subject to the -// following conditions: -// -// The above copyright notice and this permission notice shall be included -// in all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS -// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN -// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, -// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR -// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE -// USE OR OTHER DEALINGS IN THE SOFTWARE. + // a.length > b.length + var a; + var b; + if (this.length > num.length) { + a = this; + b = num; + } else { + a = num; + b = this; + } -// a duplex stream is just a stream that is both readable and writable. -// Since JS doesn't have multiple prototypal inheritance, this class -// prototypally inherits from Readable, and then parasitically from -// Writable. + for (var i = 0; i < b.length; i++) + this.words[i] = a.words[i] ^ b.words[i]; -module.exports = Duplex; + if (this !== a) + for (; i < a.length; i++) + this.words[i] = a.words[i]; -/**/ -var objectKeys = Object.keys || function (obj) { - var keys = []; - for (var key in obj) keys.push(key); - return keys; -} -/**/ + this.length = a.length; + return this.strip(); +}; -/**/ -var util = require('core-util-is'); -util.inherits = require('inherits'); -/**/ -var Readable = require('./_stream_readable'); -var Writable = require('./_stream_writable'); +// Xor `num` with `this` +BN.prototype.xor = function xor(num) { + if (this.length > num.length) + return this.clone().ixor(num); + else + return num.clone().ixor(this); +}; -util.inherits(Duplex, Readable); -forEach(objectKeys(Writable.prototype), function(method) { - if (!Duplex.prototype[method]) - Duplex.prototype[method] = Writable.prototype[method]; -}); +// Set `bit` of `this` +BN.prototype.setn = function setn(bit, val) { + assert(typeof bit === 'number' && bit >= 0); -function Duplex(options) { - if (!(this instanceof Duplex)) - return new Duplex(options); + var off = (bit / 26) | 0; + var wbit = bit % 26; - Readable.call(this, options); - Writable.call(this, options); + while (this.length <= off) + this.words[this.length++] = 0; - if (options && options.readable === false) - this.readable = false; + if (val) + this.words[off] = this.words[off] | (1 << wbit); + else + this.words[off] = this.words[off] & ~(1 << wbit); - if (options && options.writable === false) - this.writable = false; - - this.allowHalfOpen = true; - if (options && options.allowHalfOpen === false) - this.allowHalfOpen = false; + return this.strip(); +}; - this.once('end', onend); -} -// the no-half-open enforcer -function onend() { - // if we allow half-open state, or if the writable side ended, - // then we're ok. - if (this.allowHalfOpen || this._writableState.ended) - return; +// Add `num` to `this` in-place +BN.prototype.iadd = function iadd(num) { + // negative + positive + if (this.sign && !num.sign) { + this.sign = false; + var r = this.isub(num); + this.sign = !this.sign; + return this._normSign(); - // no more data can be written. - // But allow more writes to happen in this tick. - process.nextTick(this.end.bind(this)); -} + // positive + negative + } else if (!this.sign && num.sign) { + num.sign = false; + var r = this.isub(num); + num.sign = true; + return r._normSign(); + } -function forEach (xs, f) { - for (var i = 0, l = xs.length; i < l; i++) { - f(xs[i], i); + // a.length > b.length + var a; + var b; + if (this.length > num.length) { + a = this; + b = num; + } else { + a = num; + b = this; } -} -}).call(this,require('_process')) -},{"./_stream_readable":192,"./_stream_writable":194,"_process":184,"core-util-is":195,"inherits":229}],191:[function(require,module,exports){ -// Copyright Joyent, Inc. and other Node contributors. -// -// Permission is hereby granted, free of charge, to any person obtaining a -// copy of this software and associated documentation files (the -// "Software"), to deal in the Software without restriction, including -// without limitation the rights to use, copy, modify, merge, publish, -// distribute, sublicense, and/or sell copies of the Software, and to permit -// persons to whom the Software is furnished to do so, subject to the -// following conditions: -// -// The above copyright notice and this permission notice shall be included -// in all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS -// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN -// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, -// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR -// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE -// USE OR OTHER DEALINGS IN THE SOFTWARE. + var carry = 0; + for (var i = 0; i < b.length; i++) { + var r = a.words[i] + b.words[i] + carry; + this.words[i] = r & 0x3ffffff; + carry = r >>> 26; + } + for (; carry !== 0 && i < a.length; i++) { + var r = a.words[i] + carry; + this.words[i] = r & 0x3ffffff; + carry = r >>> 26; + } -// a passthrough stream. -// basically just the most minimal sort of Transform stream. -// Every written chunk gets output as-is. + this.length = a.length; + if (carry !== 0) { + this.words[this.length] = carry; + this.length++; + // Copy the rest of the words + } else if (a !== this) { + for (; i < a.length; i++) + this.words[i] = a.words[i]; + } -module.exports = PassThrough; + return this; +}; -var Transform = require('./_stream_transform'); +// Add `num` to `this` +BN.prototype.add = function add(num) { + if (num.sign && !this.sign) { + num.sign = false; + var res = this.sub(num); + num.sign = true; + return res; + } else if (!num.sign && this.sign) { + this.sign = false; + var res = num.sub(this); + this.sign = true; + return res; + } -/**/ -var util = require('core-util-is'); -util.inherits = require('inherits'); -/**/ + if (this.length > num.length) + return this.clone().iadd(num); + else + return num.clone().iadd(this); +}; -util.inherits(PassThrough, Transform); +// Subtract `num` from `this` in-place +BN.prototype.isub = function isub(num) { + // this - (-num) = this + num + if (num.sign) { + num.sign = false; + var r = this.iadd(num); + num.sign = true; + return r._normSign(); -function PassThrough(options) { - if (!(this instanceof PassThrough)) - return new PassThrough(options); + // -this - num = -(this + num) + } else if (this.sign) { + this.sign = false; + this.iadd(num); + this.sign = true; + return this._normSign(); + } - Transform.call(this, options); -} + // At this point both numbers are positive + var cmp = this.cmp(num); -PassThrough.prototype._transform = function(chunk, encoding, cb) { - cb(null, chunk); -}; + // Optimization - zeroify + if (cmp === 0) { + this.sign = false; + this.length = 1; + this.words[0] = 0; + return this; + } -},{"./_stream_transform":193,"core-util-is":195,"inherits":229}],192:[function(require,module,exports){ -(function (process){ -// Copyright Joyent, Inc. and other Node contributors. -// -// Permission is hereby granted, free of charge, to any person obtaining a -// copy of this software and associated documentation files (the -// "Software"), to deal in the Software without restriction, including -// without limitation the rights to use, copy, modify, merge, publish, -// distribute, sublicense, and/or sell copies of the Software, and to permit -// persons to whom the Software is furnished to do so, subject to the -// following conditions: -// -// The above copyright notice and this permission notice shall be included -// in all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS -// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN -// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, -// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR -// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE -// USE OR OTHER DEALINGS IN THE SOFTWARE. + // a > b + var a; + var b; + if (cmp > 0) { + a = this; + b = num; + } else { + a = num; + b = this; + } -module.exports = Readable; + var carry = 0; + for (var i = 0; i < b.length; i++) { + var r = a.words[i] - b.words[i] + carry; + carry = r >> 26; + this.words[i] = r & 0x3ffffff; + } + for (; carry !== 0 && i < a.length; i++) { + var r = a.words[i] + carry; + carry = r >> 26; + this.words[i] = r & 0x3ffffff; + } -/**/ -var isArray = require('isarray'); -/**/ + // Copy rest of the words + if (carry === 0 && i < a.length && a !== this) + for (; i < a.length; i++) + this.words[i] = a.words[i]; + this.length = Math.max(this.length, i); + if (a !== this) + this.sign = true; -/**/ -var Buffer = require('buffer').Buffer; -/**/ + return this.strip(); +}; -Readable.ReadableState = ReadableState; +// Subtract `num` from `this` +BN.prototype.sub = function sub(num) { + return this.clone().isub(num); +}; -var EE = require('events').EventEmitter; +/* +// NOTE: This could be potentionally used to generate loop-less multiplications +function _genCombMulTo(alen, blen) { + var len = alen + blen - 1; + var src = [ + 'var a = this.words, b = num.words, o = out.words, c = 0, w, ' + + 'mask = 0x3ffffff, shift = 0x4000000;', + 'out.length = ' + len + ';' + ]; + for (var k = 0; k < len; k++) { + var minJ = Math.max(0, k - alen + 1); + var maxJ = Math.min(k, blen - 1); -/**/ -if (!EE.listenerCount) EE.listenerCount = function(emitter, type) { - return emitter.listeners(type).length; -}; -/**/ + for (var j = minJ; j <= maxJ; j++) { + var i = k - j; + var mul = 'a[' + i + '] * b[' + j + ']'; -var Stream = require('stream'); + if (j === minJ) { + src.push('w = ' + mul + ' + c;'); + src.push('c = (w / shift) | 0;'); + } else { + src.push('w += ' + mul + ';'); + src.push('c += (w / shift) | 0;'); + } + src.push('w &= mask;'); + } + src.push('o[' + k + '] = w;'); + } + src.push('if (c !== 0) {', + ' o[' + k + '] = c;', + ' out.length++;', + '}', + 'return out;'); -/**/ -var util = require('core-util-is'); -util.inherits = require('inherits'); -/**/ + return src.join('\n'); +} +*/ -var StringDecoder; +BN.prototype._smallMulTo = function _smallMulTo(num, out) { + out.sign = num.sign !== this.sign; + out.length = this.length + num.length; -util.inherits(Readable, Stream); + var carry = 0; + for (var k = 0; k < out.length - 1; k++) { + // Sum all words with the same `i + j = k` and accumulate `ncarry`, + // note that ncarry could be >= 0x3ffffff + var ncarry = carry >>> 26; + var rword = carry & 0x3ffffff; + var maxJ = Math.min(k, num.length - 1); + for (var j = Math.max(0, k - this.length + 1); j <= maxJ; j++) { + var i = k - j; + var a = this.words[i] | 0; + var b = num.words[j] | 0; + var r = a * b; -function ReadableState(options, stream) { - options = options || {}; + var lo = r & 0x3ffffff; + ncarry = (ncarry + ((r / 0x4000000) | 0)) | 0; + lo = (lo + rword) | 0; + rword = lo & 0x3ffffff; + ncarry = (ncarry + (lo >>> 26)) | 0; + } + out.words[k] = rword; + carry = ncarry; + } + if (carry !== 0) { + out.words[k] = carry; + } else { + out.length--; + } - // the point at which it stops calling _read() to fill the buffer - // Note: 0 is a valid value, means "don't call _read preemptively ever" - var hwm = options.highWaterMark; - this.highWaterMark = (hwm || hwm === 0) ? hwm : 16 * 1024; + return out.strip(); +}; - // cast to ints. - this.highWaterMark = ~~this.highWaterMark; +BN.prototype._bigMulTo = function _bigMulTo(num, out) { + out.sign = num.sign !== this.sign; + out.length = this.length + num.length; - this.buffer = []; - this.length = 0; - this.pipes = null; - this.pipesCount = 0; - this.flowing = false; - this.ended = false; - this.endEmitted = false; - this.reading = false; + var carry = 0; + var hncarry = 0; + for (var k = 0; k < out.length - 1; k++) { + // Sum all words with the same `i + j = k` and accumulate `ncarry`, + // note that ncarry could be >= 0x3ffffff + var ncarry = hncarry; + hncarry = 0; + var rword = carry & 0x3ffffff; + var maxJ = Math.min(k, num.length - 1); + for (var j = Math.max(0, k - this.length + 1); j <= maxJ; j++) { + var i = k - j; + var a = this.words[i] | 0; + var b = num.words[j] | 0; + var r = a * b; - // In streams that never have any data, and do push(null) right away, - // the consumer can miss the 'end' event if they do some I/O before - // consuming the stream. So, we don't emit('end') until some reading - // happens. - this.calledRead = false; + var lo = r & 0x3ffffff; + ncarry = (ncarry + ((r / 0x4000000) | 0)) | 0; + lo = (lo + rword) | 0; + rword = lo & 0x3ffffff; + ncarry = (ncarry + (lo >>> 26)) | 0; - // a flag to be able to tell if the onwrite cb is called immediately, - // or on a later tick. We set this to true at first, becuase any - // actions that shouldn't happen until "later" should generally also - // not happen before the first write call. - this.sync = true; + hncarry += ncarry >>> 26; + ncarry &= 0x3ffffff; + } + out.words[k] = rword; + carry = ncarry; + ncarry = hncarry; + } + if (carry !== 0) { + out.words[k] = carry; + } else { + out.length--; + } - // whenever we return null, then we set a flag to say - // that we're awaiting a 'readable' event emission. - this.needReadable = false; - this.emittedReadable = false; - this.readableListening = false; + return out.strip(); +}; +BN.prototype.mulTo = function mulTo(num, out) { + var res; + if (this.length + num.length < 63) + res = this._smallMulTo(num, out); + else + res = this._bigMulTo(num, out); + return res; +}; - // object stream flag. Used to make read(n) ignore n and to - // make all the buffer merging and length checks go away - this.objectMode = !!options.objectMode; +// Multiply `this` by `num` +BN.prototype.mul = function mul(num) { + var out = new BN(null); + out.words = new Array(this.length + num.length); + return this.mulTo(num, out); +}; - // Crypto is kind of old and crusty. Historically, its default string - // encoding is 'binary' so we have to make this configurable. - // Everything else in the universe uses 'utf8', though. - this.defaultEncoding = options.defaultEncoding || 'utf8'; +// In-place Multiplication +BN.prototype.imul = function imul(num) { + if (this.cmpn(0) === 0 || num.cmpn(0) === 0) { + this.words[0] = 0; + this.length = 1; + return this; + } - // when piping, we only care about 'readable' events that happen - // after read()ing all the bytes and not getting any pushback. - this.ranOut = false; + var tlen = this.length; + var nlen = num.length; - // the number of writers that are awaiting a drain event in .pipe()s - this.awaitDrain = 0; + this.sign = num.sign !== this.sign; + this.length = this.length + num.length; + this.words[this.length - 1] = 0; - // if true, a maybeReadMore has been scheduled - this.readingMore = false; + for (var k = this.length - 2; k >= 0; k--) { + // Sum all words with the same `i + j = k` and accumulate `carry`, + // note that carry could be >= 0x3ffffff + var carry = 0; + var rword = 0; + var maxJ = Math.min(k, nlen - 1); + for (var j = Math.max(0, k - tlen + 1); j <= maxJ; j++) { + var i = k - j; + var a = this.words[i]; + var b = num.words[j]; + var r = a * b; - this.decoder = null; - this.encoding = null; - if (options.encoding) { - if (!StringDecoder) - StringDecoder = require('string_decoder/').StringDecoder; - this.decoder = new StringDecoder(options.encoding); - this.encoding = options.encoding; + var lo = r & 0x3ffffff; + carry += (r / 0x4000000) | 0; + lo += rword; + rword = lo & 0x3ffffff; + carry += lo >>> 26; + } + this.words[k] = rword; + this.words[k + 1] += carry; + carry = 0; } -} -function Readable(options) { - if (!(this instanceof Readable)) - return new Readable(options); - - this._readableState = new ReadableState(options, this); + // Propagate overflows + var carry = 0; + for (var i = 1; i < this.length; i++) { + var w = this.words[i] + carry; + this.words[i] = w & 0x3ffffff; + carry = w >>> 26; + } - // legacy - this.readable = true; + return this.strip(); +}; - Stream.call(this); -} +BN.prototype.imuln = function imuln(num) { + assert(typeof num === 'number'); -// Manually shove something into the read() buffer. -// This returns true if the highWaterMark has not been hit yet, -// similar to how Writable.write() returns true if you should -// write() some more. -Readable.prototype.push = function(chunk, encoding) { - var state = this._readableState; + // Carry + var carry = 0; + for (var i = 0; i < this.length; i++) { + var w = this.words[i] * num; + var lo = (w & 0x3ffffff) + (carry & 0x3ffffff); + carry >>= 26; + carry += (w / 0x4000000) | 0; + // NOTE: lo is 27bit maximum + carry += lo >>> 26; + this.words[i] = lo & 0x3ffffff; + } - if (typeof chunk === 'string' && !state.objectMode) { - encoding = encoding || state.defaultEncoding; - if (encoding !== state.encoding) { - chunk = new Buffer(chunk, encoding); - encoding = ''; - } + if (carry !== 0) { + this.words[i] = carry; + this.length++; } - return readableAddChunk(this, state, chunk, encoding, false); + return this; }; -// Unshift should *always* be something directly out of read() -Readable.prototype.unshift = function(chunk) { - var state = this._readableState; - return readableAddChunk(this, state, chunk, '', true); +// `this` * `this` +BN.prototype.sqr = function sqr() { + return this.mul(this); }; -function readableAddChunk(stream, state, chunk, encoding, addToFront) { - var er = chunkInvalid(state, chunk); - if (er) { - stream.emit('error', er); - } else if (chunk === null || chunk === undefined) { - state.reading = false; - if (!state.ended) - onEofChunk(stream, state); - } else if (state.objectMode || chunk && chunk.length > 0) { - if (state.ended && !addToFront) { - var e = new Error('stream.push() after EOF'); - stream.emit('error', e); - } else if (state.endEmitted && addToFront) { - var e = new Error('stream.unshift() after end event'); - stream.emit('error', e); - } else { - if (state.decoder && !addToFront && !encoding) - chunk = state.decoder.write(chunk); - - // update the buffer info. - state.length += state.objectMode ? 1 : chunk.length; - if (addToFront) { - state.buffer.unshift(chunk); - } else { - state.reading = false; - state.buffer.push(chunk); - } +// `this` * `this` in-place +BN.prototype.isqr = function isqr() { + return this.mul(this); +}; - if (state.needReadable) - emitReadable(stream); +// Shift-left in-place +BN.prototype.ishln = function ishln(bits) { + assert(typeof bits === 'number' && bits >= 0); + var r = bits % 26; + var s = (bits - r) / 26; + var carryMask = (0x3ffffff >>> (26 - r)) << (26 - r); - maybeReadMore(stream, state); + if (r !== 0) { + var carry = 0; + for (var i = 0; i < this.length; i++) { + var newCarry = this.words[i] & carryMask; + var c = (this.words[i] - newCarry) << r; + this.words[i] = c | carry; + carry = newCarry >>> (26 - r); + } + if (carry) { + this.words[i] = carry; + this.length++; } - } else if (!addToFront) { - state.reading = false; } - return needMoreData(state); -} + if (s !== 0) { + for (var i = this.length - 1; i >= 0; i--) + this.words[i + s] = this.words[i]; + for (var i = 0; i < s; i++) + this.words[i] = 0; + this.length += s; + } + return this.strip(); +}; +// Shift-right in-place +// NOTE: `hint` is a lowest bit before trailing zeroes +// NOTE: if `extended` is present - it will be filled with destroyed bits +BN.prototype.ishrn = function ishrn(bits, hint, extended) { + assert(typeof bits === 'number' && bits >= 0); + var h; + if (hint) + h = (hint - (hint % 26)) / 26; + else + h = 0; -// if it's past the high water mark, we can push in some more. -// Also, if we have no data yet, we can stand some -// more bytes. This is to work around cases where hwm=0, -// such as the repl. Also, if the push() triggered a -// readable event, and the user called read(largeNumber) such that -// needReadable was set, then we ought to push more, so that another -// 'readable' event will be triggered. -function needMoreData(state) { - return !state.ended && - (state.needReadable || - state.length < state.highWaterMark || - state.length === 0); -} + var r = bits % 26; + var s = Math.min((bits - r) / 26, this.length); + var mask = 0x3ffffff ^ ((0x3ffffff >>> r) << r); + var maskedWords = extended; -// backwards compatibility. -Readable.prototype.setEncoding = function(enc) { - if (!StringDecoder) - StringDecoder = require('string_decoder/').StringDecoder; - this._readableState.decoder = new StringDecoder(enc); - this._readableState.encoding = enc; -}; + h -= s; + h = Math.max(0, h); -// Don't raise the hwm > 128MB -var MAX_HWM = 0x800000; -function roundUpToNextPowerOf2(n) { - if (n >= MAX_HWM) { - n = MAX_HWM; + // Extended mode, copy masked part + if (maskedWords) { + for (var i = 0; i < s; i++) + maskedWords.words[i] = this.words[i]; + maskedWords.length = s; + } + + if (s === 0) { + // No-op, we should not move anything at all + } else if (this.length > s) { + this.length -= s; + for (var i = 0; i < this.length; i++) + this.words[i] = this.words[i + s]; } else { - // Get the next highest power of 2 - n--; - for (var p = 1; p < 32; p <<= 1) n |= n >> p; - n++; + this.words[0] = 0; + this.length = 1; } - return n; -} -function howMuchToRead(n, state) { - if (state.length === 0 && state.ended) - return 0; + var carry = 0; + for (var i = this.length - 1; i >= 0 && (carry !== 0 || i >= h); i--) { + var word = this.words[i]; + this.words[i] = (carry << (26 - r)) | (word >>> r); + carry = word & mask; + } - if (state.objectMode) - return n === 0 ? 0 : 1; + // Push carried bits as a mask + if (maskedWords && carry !== 0) + maskedWords.words[maskedWords.length++] = carry; - if (n === null || isNaN(n)) { - // only flow one buffer at a time - if (state.flowing && state.buffer.length) - return state.buffer[0].length; - else - return state.length; + if (this.length === 0) { + this.words[0] = 0; + this.length = 1; } - if (n <= 0) - return 0; - - // If we're asking for more than the target buffer level, - // then raise the water mark. Bump up to the next highest - // power of 2, to prevent increasing it excessively in tiny - // amounts. - if (n > state.highWaterMark) - state.highWaterMark = roundUpToNextPowerOf2(n); + this.strip(); - // don't have that much. return null, unless we've ended. - if (n > state.length) { - if (!state.ended) { - state.needReadable = true; - return 0; - } else - return state.length; - } + return this; +}; - return n; -} +// Shift-left +BN.prototype.shln = function shln(bits) { + return this.clone().ishln(bits); +}; -// you can override either this method, or the async _read(n) below. -Readable.prototype.read = function(n) { - var state = this._readableState; - state.calledRead = true; - var nOrig = n; - var ret; +// Shift-right +BN.prototype.shrn = function shrn(bits) { + return this.clone().ishrn(bits); +}; - if (typeof n !== 'number' || n > 0) - state.emittedReadable = false; +// Test if n bit is set +BN.prototype.testn = function testn(bit) { + assert(typeof bit === 'number' && bit >= 0); + var r = bit % 26; + var s = (bit - r) / 26; + var q = 1 << r; - // if we're doing read(0) to trigger a readable event, but we - // already have a bunch of data in the buffer, then just trigger - // the 'readable' event and move on. - if (n === 0 && - state.needReadable && - (state.length >= state.highWaterMark || state.ended)) { - emitReadable(this); - return null; + // Fast case: bit is much higher than all existing words + if (this.length <= s) { + return false; } - n = howMuchToRead(n, state); + // Check bit and return + var w = this.words[s]; - // if we've ended, and we're now clear, then finish it up. - if (n === 0 && state.ended) { - ret = null; + return !!(w & q); +}; - // In cases where the decoder did not receive enough data - // to produce a full chunk, then immediately received an - // EOF, state.buffer will contain [, ]. - // howMuchToRead will see this and coerce the amount to - // read to zero (because it's looking at the length of the - // first in state.buffer), and we'll end up here. - // - // This can only happen via state.decoder -- no other venue - // exists for pushing a zero-length chunk into state.buffer - // and triggering this behavior. In this case, we return our - // remaining data and end the stream, if appropriate. - if (state.length > 0 && state.decoder) { - ret = fromList(n, state); - state.length -= ret.length; - } +// Return only lowers bits of number (in-place) +BN.prototype.imaskn = function imaskn(bits) { + assert(typeof bits === 'number' && bits >= 0); + var r = bits % 26; + var s = (bits - r) / 26; - if (state.length === 0) - endReadable(this); + assert(!this.sign, 'imaskn works only with positive numbers'); - return ret; + if (r !== 0) + s++; + this.length = Math.min(s, this.length); + + if (r !== 0) { + var mask = 0x3ffffff ^ ((0x3ffffff >>> r) << r); + this.words[this.length - 1] &= mask; } - // All the actual chunk generation logic needs to be - // *below* the call to _read. The reason is that in certain - // synthetic stream cases, such as passthrough streams, _read - // may be a completely synchronous operation which may change - // the state of the read buffer, providing enough data when - // before there was *not* enough. - // - // So, the steps are: - // 1. Figure out what the state of things will be after we do - // a read from the buffer. - // - // 2. If that resulting state will trigger a _read, then call _read. - // Note that this may be asynchronous, or synchronous. Yes, it is - // deeply ugly to write APIs this way, but that still doesn't mean - // that the Readable class should behave improperly, as streams are - // designed to be sync/async agnostic. - // Take note if the _read call is sync or async (ie, if the read call - // has returned yet), so that we know whether or not it's safe to emit - // 'readable' etc. - // - // 3. Actually pull the requested chunks out of the buffer and return. + return this.strip(); +}; - // if we need a readable event, then we need to do some reading. - var doRead = state.needReadable; +// Return only lowers bits of number +BN.prototype.maskn = function maskn(bits) { + return this.clone().imaskn(bits); +}; - // if we currently have less than the highWaterMark, then also read some - if (state.length - n <= state.highWaterMark) - doRead = true; +// Add plain number `num` to `this` +BN.prototype.iaddn = function iaddn(num) { + assert(typeof num === 'number'); + if (num < 0) + return this.isubn(-num); - // however, if we've ended, then there's no point, and if we're already - // reading, then it's unnecessary. - if (state.ended || state.reading) - doRead = false; + // Possible sign change + if (this.sign) { + if (this.length === 1 && this.words[0] < num) { + this.words[0] = num - this.words[0]; + this.sign = false; + return this; + } - if (doRead) { - state.reading = true; - state.sync = true; - // if the length is currently zero, then we *need* a readable event. - if (state.length === 0) - state.needReadable = true; - // call internal read method - this._read(state.highWaterMark); - state.sync = false; + this.sign = false; + this.isubn(num); + this.sign = true; + return this; } - // If _read called its callback synchronously, then `reading` - // will be false, and we need to re-evaluate how much data we - // can return to the user. - if (doRead && !state.reading) - n = howMuchToRead(nOrig, state); + // Add without checks + return this._iaddn(num); +}; - if (n > 0) - ret = fromList(n, state); - else - ret = null; +BN.prototype._iaddn = function _iaddn(num) { + this.words[0] += num; - if (ret === null) { - state.needReadable = true; - n = 0; + // Carry + for (var i = 0; i < this.length && this.words[i] >= 0x4000000; i++) { + this.words[i] -= 0x4000000; + if (i === this.length - 1) + this.words[i + 1] = 1; + else + this.words[i + 1]++; } + this.length = Math.max(this.length, i + 1); - state.length -= n; - - // If we have nothing in the buffer, then we want to know - // as soon as we *do* get something into the buffer. - if (state.length === 0 && !state.ended) - state.needReadable = true; - - // If we happened to read() exactly the remaining amount in the - // buffer, and the EOF has been seen at this point, then make sure - // that we emit 'end' on the very next tick. - if (state.ended && !state.endEmitted && state.length === 0) - endReadable(this); - - return ret; + return this; }; -function chunkInvalid(state, chunk) { - var er = null; - if (!Buffer.isBuffer(chunk) && - 'string' !== typeof chunk && - chunk !== null && - chunk !== undefined && - !state.objectMode) { - er = new TypeError('Invalid non-string/buffer chunk'); - } - return er; -} - +// Subtract plain number `num` from `this` +BN.prototype.isubn = function isubn(num) { + assert(typeof num === 'number'); + if (num < 0) + return this.iaddn(-num); -function onEofChunk(stream, state) { - if (state.decoder && !state.ended) { - var chunk = state.decoder.end(); - if (chunk && chunk.length) { - state.buffer.push(chunk); - state.length += state.objectMode ? 1 : chunk.length; - } + if (this.sign) { + this.sign = false; + this.iaddn(num); + this.sign = true; + return this; } - state.ended = true; - - // if we've ended and we have some data left, then emit - // 'readable' now to make sure it gets picked up. - if (state.length > 0) - emitReadable(stream); - else - endReadable(stream); -} -// Don't emit readable right away in sync mode, because this can trigger -// another read() call => stack overflow. This way, it might trigger -// a nextTick recursion warning, but that's not so bad. -function emitReadable(stream) { - var state = stream._readableState; - state.needReadable = false; - if (state.emittedReadable) - return; + this.words[0] -= num; - state.emittedReadable = true; - if (state.sync) - process.nextTick(function() { - emitReadable_(stream); - }); - else - emitReadable_(stream); -} + // Carry + for (var i = 0; i < this.length && this.words[i] < 0; i++) { + this.words[i] += 0x4000000; + this.words[i + 1] -= 1; + } -function emitReadable_(stream) { - stream.emit('readable'); -} + return this.strip(); +}; +BN.prototype.addn = function addn(num) { + return this.clone().iaddn(num); +}; -// at this point, the user has presumably seen the 'readable' event, -// and called read() to consume some data. that may have triggered -// in turn another _read(n) call, in which case reading = true if -// it's in progress. -// However, if we're not ended, or reading, and the length < hwm, -// then go ahead and try to read some more preemptively. -function maybeReadMore(stream, state) { - if (!state.readingMore) { - state.readingMore = true; - process.nextTick(function() { - maybeReadMore_(stream, state); - }); - } -} +BN.prototype.subn = function subn(num) { + return this.clone().isubn(num); +}; -function maybeReadMore_(stream, state) { - var len = state.length; - while (!state.reading && !state.flowing && !state.ended && - state.length < state.highWaterMark) { - stream.read(0); - if (len === state.length) - // didn't get any data, stop spinning. - break; - else - len = state.length; - } - state.readingMore = false; -} +BN.prototype.iabs = function iabs() { + this.sign = false; -// abstract method. to be overridden in specific implementation classes. -// call cb(er, data) where data is <= n in length. -// for virtual (non-string, non-buffer) streams, "length" is somewhat -// arbitrary, and perhaps not very meaningful. -Readable.prototype._read = function(n) { - this.emit('error', new Error('not implemented')); + return this; }; -Readable.prototype.pipe = function(dest, pipeOpts) { - var src = this; - var state = this._readableState; +BN.prototype.abs = function abs() { + return this.clone().iabs(); +}; - switch (state.pipesCount) { - case 0: - state.pipes = dest; - break; - case 1: - state.pipes = [state.pipes, dest]; - break; - default: - state.pipes.push(dest); - break; +BN.prototype._ishlnsubmul = function _ishlnsubmul(num, mul, shift) { + // Bigger storage is needed + var len = num.length + shift; + var i; + if (this.words.length < len) { + var t = new Array(len); + for (var i = 0; i < this.length; i++) + t[i] = this.words[i]; + this.words = t; + } else { + i = this.length; } - state.pipesCount += 1; - - var doEnd = (!pipeOpts || pipeOpts.end !== false) && - dest !== process.stdout && - dest !== process.stderr; - var endFn = doEnd ? onend : cleanup; - if (state.endEmitted) - process.nextTick(endFn); - else - src.once('end', endFn); + // Zeroify rest + this.length = Math.max(this.length, len); + for (; i < this.length; i++) + this.words[i] = 0; - dest.on('unpipe', onunpipe); - function onunpipe(readable) { - if (readable !== src) return; - cleanup(); + var carry = 0; + for (var i = 0; i < num.length; i++) { + var w = this.words[i + shift] + carry; + var right = num.words[i] * mul; + w -= right & 0x3ffffff; + carry = (w >> 26) - ((right / 0x4000000) | 0); + this.words[i + shift] = w & 0x3ffffff; } - - function onend() { - dest.end(); + for (; i < this.length - shift; i++) { + var w = this.words[i + shift] + carry; + carry = w >> 26; + this.words[i + shift] = w & 0x3ffffff; } - // when the dest drains, it reduces the awaitDrain counter - // on the source. This would be more elegant with a .once() - // handler in flow(), but adding and removing repeatedly is - // too slow. - var ondrain = pipeOnDrain(src); - dest.on('drain', ondrain); - - function cleanup() { - // cleanup event handlers once the pipe is broken - dest.removeListener('close', onclose); - dest.removeListener('finish', onfinish); - dest.removeListener('drain', ondrain); - dest.removeListener('error', onerror); - dest.removeListener('unpipe', onunpipe); - src.removeListener('end', onend); - src.removeListener('end', cleanup); + if (carry === 0) + return this.strip(); - // if the reader is waiting for a drain event from this - // specific writer, then it would cause it to never start - // flowing again. - // So, if this is awaiting a drain, then we just call it now. - // If we don't know, then assume that we are waiting for one. - if (!dest._writableState || dest._writableState.needDrain) - ondrain(); + // Subtraction overflow + assert(carry === -1); + carry = 0; + for (var i = 0; i < this.length; i++) { + var w = -this.words[i] + carry; + carry = w >> 26; + this.words[i] = w & 0x3ffffff; } + this.sign = true; - // if the dest has an error, then stop piping into it. - // however, don't suppress the throwing behavior for this. - function onerror(er) { - unpipe(); - dest.removeListener('error', onerror); - if (EE.listenerCount(dest, 'error') === 0) - dest.emit('error', er); - } - // This is a brutally ugly hack to make sure that our error handler - // is attached before any userland ones. NEVER DO THIS. - if (!dest._events || !dest._events.error) - dest.on('error', onerror); - else if (isArray(dest._events.error)) - dest._events.error.unshift(onerror); - else - dest._events.error = [onerror, dest._events.error]; + return this.strip(); +}; +BN.prototype._wordDiv = function _wordDiv(num, mode) { + var shift = this.length - num.length; + var a = this.clone(); + var b = num; - // Both close and finish should trigger unpipe, but only once. - function onclose() { - dest.removeListener('finish', onfinish); - unpipe(); + // Normalize + var bhi = b.words[b.length - 1]; + var bhiBits = this._countBits(bhi); + shift = 26 - bhiBits; + if (shift !== 0) { + b = b.shln(shift); + a.ishln(shift); + bhi = b.words[b.length - 1]; } - dest.once('close', onclose); - function onfinish() { - dest.removeListener('close', onclose); - unpipe(); + + // Initialize quotient + var m = a.length - b.length; + var q; + + if (mode !== 'mod') { + q = new BN(null); + q.length = m + 1; + q.words = new Array(q.length); + for (var i = 0; i < q.length; i++) + q.words[i] = 0; } - dest.once('finish', onfinish); - function unpipe() { - src.unpipe(dest); + var diff = a.clone()._ishlnsubmul(b, 1, m); + if (!diff.sign) { + a = diff; + if (q) + q.words[m] = 1; } - // tell the dest that it's being piped to - dest.emit('pipe', src); + for (var j = m - 1; j >= 0; j--) { + var qj = a.words[b.length + j] * 0x4000000 + a.words[b.length + j - 1]; - // start the flow if it hasn't been started already. - if (!state.flowing) { - // the handler that waits for readable events after all - // the data gets sucked out in flow. - // This would be easier to follow with a .once() handler - // in flow(), but that is too slow. - this.on('readable', pipeOnReadable); + // NOTE: (qj / bhi) is (0x3ffffff * 0x4000000 + 0x3ffffff) / 0x2000000 max + // (0x7ffffff) + qj = Math.min((qj / bhi) | 0, 0x3ffffff); - state.flowing = true; - process.nextTick(function() { - flow(src); - }); + a._ishlnsubmul(b, qj, j); + while (a.sign) { + qj--; + a.sign = false; + a._ishlnsubmul(b, 1, j); + if (a.cmpn(0) !== 0) + a.sign = !a.sign; + } + if (q) + q.words[j] = qj; } + if (q) + q.strip(); + a.strip(); - return dest; + // Denormalize + if (mode !== 'div' && shift !== 0) + a.ishrn(shift); + return { div: q ? q : null, mod: a }; }; -function pipeOnDrain(src) { - return function() { - var dest = this; - var state = src._readableState; - state.awaitDrain--; - if (state.awaitDrain === 0) - flow(src); - }; -} - -function flow(src) { - var state = src._readableState; - var chunk; - state.awaitDrain = 0; +BN.prototype.divmod = function divmod(num, mode) { + assert(num.cmpn(0) !== 0); - function write(dest, i, list) { - var written = dest.write(chunk); - if (false === written) { - state.awaitDrain++; - } + if (this.sign && !num.sign) { + var res = this.neg().divmod(num, mode); + var div; + var mod; + if (mode !== 'mod') + div = res.div.neg(); + if (mode !== 'div') + mod = res.mod.cmpn(0) === 0 ? res.mod : num.sub(res.mod); + return { + div: div, + mod: mod + }; + } else if (!this.sign && num.sign) { + var res = this.divmod(num.neg(), mode); + var div; + if (mode !== 'mod') + div = res.div.neg(); + return { div: div, mod: res.mod }; + } else if (this.sign && num.sign) { + return this.neg().divmod(num.neg(), mode); } - while (state.pipesCount && null !== (chunk = src.read())) { - - if (state.pipesCount === 1) - write(state.pipes, 0, null); - else - forEach(state.pipes, write); + // Both numbers are positive at this point - src.emit('data', chunk); + // Strip both numbers to approximate shift value + if (num.length > this.length || this.cmp(num) < 0) + return { div: new BN(0), mod: this }; - // if anyone needs a drain, then we have to wait for that. - if (state.awaitDrain > 0) - return; + // Very short reduction + if (num.length === 1) { + if (mode === 'div') + return { div: this.divn(num.words[0]), mod: null }; + else if (mode === 'mod') + return { div: null, mod: new BN(this.modn(num.words[0])) }; + return { + div: this.divn(num.words[0]), + mod: new BN(this.modn(num.words[0])) + }; } - // if every destination was unpiped, either before entering this - // function, or in the while loop, then stop flowing. - // - // NB: This is a pretty rare edge case. - if (state.pipesCount === 0) { - state.flowing = false; - - // if there were data event listeners added, then switch to old mode. - if (EE.listenerCount(src, 'data') > 0) - emitDataEvents(src); - return; - } + return this._wordDiv(num, mode); +}; - // at this point, no one needed a drain, so we just ran out of data - // on the next readable event, start it over again. - state.ranOut = true; -} - -function pipeOnReadable() { - if (this._readableState.ranOut) { - this._readableState.ranOut = false; - flow(this); - } -} +// Find `this` / `num` +BN.prototype.div = function div(num) { + return this.divmod(num, 'div').div; +}; +// Find `this` % `num` +BN.prototype.mod = function mod(num) { + return this.divmod(num, 'mod').mod; +}; -Readable.prototype.unpipe = function(dest) { - var state = this._readableState; +// Find Round(`this` / `num`) +BN.prototype.divRound = function divRound(num) { + var dm = this.divmod(num); - // if we're not piping anywhere, then do nothing. - if (state.pipesCount === 0) - return this; + // Fast case - exact division + if (dm.mod.cmpn(0) === 0) + return dm.div; - // just one destination. most common case. - if (state.pipesCount === 1) { - // passed in one, but it's not the right one. - if (dest && dest !== state.pipes) - return this; + var mod = dm.div.sign ? dm.mod.isub(num) : dm.mod; - if (!dest) - dest = state.pipes; + var half = num.shrn(1); + var r2 = num.andln(1); + var cmp = mod.cmp(half); - // got a match. - state.pipes = null; - state.pipesCount = 0; - this.removeListener('readable', pipeOnReadable); - state.flowing = false; - if (dest) - dest.emit('unpipe', this); - return this; - } + // Round down + if (cmp < 0 || r2 === 1 && cmp === 0) + return dm.div; - // slow case. multiple pipe destinations. + // Round up + return dm.div.sign ? dm.div.isubn(1) : dm.div.iaddn(1); +}; - if (!dest) { - // remove all. - var dests = state.pipes; - var len = state.pipesCount; - state.pipes = null; - state.pipesCount = 0; - this.removeListener('readable', pipeOnReadable); - state.flowing = false; +BN.prototype.modn = function modn(num) { + assert(num <= 0x3ffffff); + var p = (1 << 26) % num; - for (var i = 0; i < len; i++) - dests[i].emit('unpipe', this); - return this; - } + var acc = 0; + for (var i = this.length - 1; i >= 0; i--) + acc = (p * acc + this.words[i]) % num; - // try to find the right one. - var i = indexOf(state.pipes, dest); - if (i === -1) - return this; + return acc; +}; - state.pipes.splice(i, 1); - state.pipesCount -= 1; - if (state.pipesCount === 1) - state.pipes = state.pipes[0]; +// In-place division by number +BN.prototype.idivn = function idivn(num) { + assert(num <= 0x3ffffff); - dest.emit('unpipe', this); + var carry = 0; + for (var i = this.length - 1; i >= 0; i--) { + var w = this.words[i] + carry * 0x4000000; + this.words[i] = (w / num) | 0; + carry = w % num; + } - return this; + return this.strip(); }; -// set up data events if they are asked for -// Ensure readable listeners eventually get something -Readable.prototype.on = function(ev, fn) { - var res = Stream.prototype.on.call(this, ev, fn); +BN.prototype.divn = function divn(num) { + return this.clone().idivn(num); +}; - if (ev === 'data' && !this._readableState.flowing) - emitDataEvents(this); +BN.prototype.egcd = function egcd(p) { + assert(!p.sign); + assert(p.cmpn(0) !== 0); - if (ev === 'readable' && this.readable) { - var state = this._readableState; - if (!state.readableListening) { - state.readableListening = true; - state.emittedReadable = false; - state.needReadable = true; - if (!state.reading) { - this.read(0); - } else if (state.length) { - emitReadable(this, state); - } - } - } + var x = this; + var y = p.clone(); - return res; -}; -Readable.prototype.addListener = Readable.prototype.on; + if (x.sign) + x = x.mod(p); + else + x = x.clone(); -// pause() and resume() are remnants of the legacy readable stream API -// If the user uses them, then switch into old mode. -Readable.prototype.resume = function() { - emitDataEvents(this); - this.read(0); - this.emit('resume'); -}; + // A * x + B * y = x + var A = new BN(1); + var B = new BN(0); -Readable.prototype.pause = function() { - emitDataEvents(this, true); - this.emit('pause'); -}; + // C * x + D * y = y + var C = new BN(0); + var D = new BN(1); -function emitDataEvents(stream, startPaused) { - var state = stream._readableState; + var g = 0; - if (state.flowing) { - // https://github.com/isaacs/readable-stream/issues/16 - throw new Error('Cannot switch to old mode now.'); + while (x.isEven() && y.isEven()) { + x.ishrn(1); + y.ishrn(1); + ++g; } - var paused = startPaused || false; - var readable = false; + var yp = y.clone(); + var xp = x.clone(); - // convert to an old-style stream. - stream.readable = true; - stream.pipe = Stream.prototype.pipe; - stream.on = stream.addListener = Stream.prototype.on; - - stream.on('readable', function() { - readable = true; + while (x.cmpn(0) !== 0) { + while (x.isEven()) { + x.ishrn(1); + if (A.isEven() && B.isEven()) { + A.ishrn(1); + B.ishrn(1); + } else { + A.iadd(yp).ishrn(1); + B.isub(xp).ishrn(1); + } + } - var c; - while (!paused && (null !== (c = stream.read()))) - stream.emit('data', c); + while (y.isEven()) { + y.ishrn(1); + if (C.isEven() && D.isEven()) { + C.ishrn(1); + D.ishrn(1); + } else { + C.iadd(yp).ishrn(1); + D.isub(xp).ishrn(1); + } + } - if (c === null) { - readable = false; - stream._readableState.needReadable = true; + if (x.cmp(y) >= 0) { + x.isub(y); + A.isub(C); + B.isub(D); + } else { + y.isub(x); + C.isub(A); + D.isub(B); } - }); + } - stream.pause = function() { - paused = true; - this.emit('pause'); + return { + a: C, + b: D, + gcd: y.ishln(g) }; +}; - stream.resume = function() { - paused = false; - if (readable) - process.nextTick(function() { - stream.emit('readable'); - }); - else - this.read(0); - this.emit('resume'); - }; +// This is reduced incarnation of the binary EEA +// above, designated to invert members of the +// _prime_ fields F(p) at a maximal speed +BN.prototype._invmp = function _invmp(p) { + assert(!p.sign); + assert(p.cmpn(0) !== 0); - // now make it start, just in case it hadn't already. - stream.emit('readable'); -} + var a = this; + var b = p.clone(); -// wrap an old-style stream as the async data source. -// This is *not* part of the readable stream interface. -// It is an ugly unfortunate mess of history. -Readable.prototype.wrap = function(stream) { - var state = this._readableState; - var paused = false; + if (a.sign) + a = a.mod(p); + else + a = a.clone(); - var self = this; - stream.on('end', function() { - if (state.decoder && !state.ended) { - var chunk = state.decoder.end(); - if (chunk && chunk.length) - self.push(chunk); - } + var x1 = new BN(1); + var x2 = new BN(0); - self.push(null); - }); + var delta = b.clone(); - stream.on('data', function(chunk) { - if (state.decoder) - chunk = state.decoder.write(chunk); + while (a.cmpn(1) > 0 && b.cmpn(1) > 0) { + while (a.isEven()) { + a.ishrn(1); + if (x1.isEven()) + x1.ishrn(1); + else + x1.iadd(delta).ishrn(1); + } + while (b.isEven()) { + b.ishrn(1); + if (x2.isEven()) + x2.ishrn(1); + else + x2.iadd(delta).ishrn(1); + } + if (a.cmp(b) >= 0) { + a.isub(b); + x1.isub(x2); + } else { + b.isub(a); + x2.isub(x1); + } + } + if (a.cmpn(1) === 0) + return x1; + else + return x2; +}; - // don't skip over falsy values in objectMode - //if (state.objectMode && util.isNullOrUndefined(chunk)) - if (state.objectMode && (chunk === null || chunk === undefined)) - return; - else if (!state.objectMode && (!chunk || !chunk.length)) - return; +BN.prototype.gcd = function gcd(num) { + if (this.cmpn(0) === 0) + return num.clone(); + if (num.cmpn(0) === 0) + return this.clone(); - var ret = self.push(chunk); - if (!ret) { - paused = true; - stream.pause(); - } - }); + var a = this.clone(); + var b = num.clone(); + a.sign = false; + b.sign = false; - // proxy all the other methods. - // important when wrapping filters and duplexes. - for (var i in stream) { - if (typeof stream[i] === 'function' && - typeof this[i] === 'undefined') { - this[i] = function(method) { return function() { - return stream[method].apply(stream, arguments); - }}(i); - } + // Remove common factor of two + for (var shift = 0; a.isEven() && b.isEven(); shift++) { + a.ishrn(1); + b.ishrn(1); } - // proxy certain important events. - var events = ['error', 'close', 'destroy', 'pause', 'resume']; - forEach(events, function(ev) { - stream.on(ev, self.emit.bind(self, ev)); - }); + do { + while (a.isEven()) + a.ishrn(1); + while (b.isEven()) + b.ishrn(1); - // when we try to consume some more bytes, simply unpause the - // underlying stream. - self._read = function(n) { - if (paused) { - paused = false; - stream.resume(); + var r = a.cmp(b); + if (r < 0) { + // Swap `a` and `b` to make `a` always bigger than `b` + var t = a; + a = b; + b = t; + } else if (r === 0 || b.cmpn(1) === 0) { + break; } - }; - return self; + a.isub(b); + } while (true); + + return b.ishln(shift); }; +// Invert number in the field F(num) +BN.prototype.invm = function invm(num) { + return this.egcd(num).a.mod(num); +}; +BN.prototype.isEven = function isEven() { + return (this.words[0] & 1) === 0; +}; -// exposed for testing purposes only. -Readable._fromList = fromList; +BN.prototype.isOdd = function isOdd() { + return (this.words[0] & 1) === 1; +}; -// Pluck off n bytes from an array of buffers. -// Length is the combined lengths of all the buffers in the list. -function fromList(n, state) { - var list = state.buffer; - var length = state.length; - var stringMode = !!state.decoder; - var objectMode = !!state.objectMode; - var ret; +// And first word and num +BN.prototype.andln = function andln(num) { + return this.words[0] & num; +}; - // nothing in the list, definitely empty. - if (list.length === 0) - return null; +// Increment at the bit position in-line +BN.prototype.bincn = function bincn(bit) { + assert(typeof bit === 'number'); + var r = bit % 26; + var s = (bit - r) / 26; + var q = 1 << r; - if (length === 0) - ret = null; - else if (objectMode) - ret = list.shift(); - else if (!n || n >= length) { - // read it all, truncate the array. - if (stringMode) - ret = list.join(''); - else - ret = Buffer.concat(list, length); - list.length = 0; - } else { - // read just some of it. - if (n < list[0].length) { - // just take a part of the first list item. - // slice is the same for buffers and strings. - var buf = list[0]; - ret = buf.slice(0, n); - list[0] = buf.slice(n); - } else if (n === list[0].length) { - // first list is a perfect match - ret = list.shift(); - } else { - // complex case. - // we have enough to cover it, but it spans past the first buffer. - if (stringMode) - ret = ''; - else - ret = new Buffer(n); + // Fast case: bit is much higher than all existing words + if (this.length <= s) { + for (var i = this.length; i < s + 1; i++) + this.words[i] = 0; + this.words[s] |= q; + this.length = s + 1; + return this; + } - var c = 0; - for (var i = 0, l = list.length; i < l && c < n; i++) { - var buf = list[0]; - var cpy = Math.min(n - c, buf.length); + // Add bit and propagate, if needed + var carry = q; + for (var i = s; carry !== 0 && i < this.length; i++) { + var w = this.words[i]; + w += carry; + carry = w >>> 26; + w &= 0x3ffffff; + this.words[i] = w; + } + if (carry !== 0) { + this.words[i] = carry; + this.length++; + } + return this; +}; - if (stringMode) - ret += buf.slice(0, cpy); - else - buf.copy(ret, c, 0, cpy); +BN.prototype.cmpn = function cmpn(num) { + var sign = num < 0; + if (sign) + num = -num; - if (cpy < buf.length) - list[0] = buf.slice(cpy); - else - list.shift(); + if (this.sign && !sign) + return -1; + else if (!this.sign && sign) + return 1; - c += cpy; - } - } - } + num &= 0x3ffffff; + this.strip(); - return ret; -} + var res; + if (this.length > 1) { + res = 1; + } else { + var w = this.words[0]; + res = w === num ? 0 : w < num ? -1 : 1; + } + if (this.sign) + res = -res; + return res; +}; -function endReadable(stream) { - var state = stream._readableState; +// Compare two numbers and return: +// 1 - if `this` > `num` +// 0 - if `this` == `num` +// -1 - if `this` < `num` +BN.prototype.cmp = function cmp(num) { + if (this.sign && !num.sign) + return -1; + else if (!this.sign && num.sign) + return 1; - // If we get here before consuming all the bytes, then that is a - // bug in node. Should never happen. - if (state.length > 0) - throw new Error('endReadable called on non-empty stream'); + var res = this.ucmp(num); + if (this.sign) + return -res; + else + return res; +}; - if (!state.endEmitted && state.calledRead) { - state.ended = true; - process.nextTick(function() { - // Check that we didn't get one last unshift. - if (!state.endEmitted && state.length === 0) { - state.endEmitted = true; - stream.readable = false; - stream.emit('end'); - } - }); - } -} +// Unsigned comparison +BN.prototype.ucmp = function ucmp(num) { + // At this point both numbers have the same sign + if (this.length > num.length) + return 1; + else if (this.length < num.length) + return -1; -function forEach (xs, f) { - for (var i = 0, l = xs.length; i < l; i++) { - f(xs[i], i); - } -} + var res = 0; + for (var i = this.length - 1; i >= 0; i--) { + var a = this.words[i]; + var b = num.words[i]; -function indexOf (xs, x) { - for (var i = 0, l = xs.length; i < l; i++) { - if (xs[i] === x) return i; + if (a === b) + continue; + if (a < b) + res = -1; + else if (a > b) + res = 1; + break; } - return -1; -} + return res; +}; -}).call(this,require('_process')) -},{"_process":184,"buffer":42,"core-util-is":195,"events":182,"inherits":229,"isarray":183,"stream":200,"string_decoder/":201}],193:[function(require,module,exports){ -// Copyright Joyent, Inc. and other Node contributors. -// -// Permission is hereby granted, free of charge, to any person obtaining a -// copy of this software and associated documentation files (the -// "Software"), to deal in the Software without restriction, including -// without limitation the rights to use, copy, modify, merge, publish, -// distribute, sublicense, and/or sell copies of the Software, and to permit -// persons to whom the Software is furnished to do so, subject to the -// following conditions: // -// The above copyright notice and this permission notice shall be included -// in all copies or substantial portions of the Software. +// A reduce context, could be using montgomery or something better, depending +// on the `m` itself. // -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS -// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN -// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, -// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR -// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE -// USE OR OTHER DEALINGS IN THE SOFTWARE. - +BN.red = function red(num) { + return new Red(num); +}; -// a transform stream is a readable/writable stream where you do -// something with the data. Sometimes it's called a "filter", -// but that's not a great name for it, since that implies a thing where -// some bits pass through, and others are simply ignored. (That would -// be a valid example of a transform, of course.) -// -// While the output is causally related to the input, it's not a -// necessarily symmetric or synchronous transformation. For example, -// a zlib stream might take multiple plain-text writes(), and then -// emit a single compressed chunk some time in the future. -// -// Here's how this works: -// -// The Transform stream has all the aspects of the readable and writable -// stream classes. When you write(chunk), that calls _write(chunk,cb) -// internally, and returns false if there's a lot of pending writes -// buffered up. When you call read(), that calls _read(n) until -// there's enough pending readable data buffered up. -// -// In a transform stream, the written data is placed in a buffer. When -// _read(n) is called, it transforms the queued up data, calling the -// buffered _write cb's as it consumes chunks. If consuming a single -// written chunk would result in multiple output chunks, then the first -// outputted bit calls the readcb, and subsequent chunks just go into -// the read buffer, and will cause it to emit 'readable' if necessary. -// -// This way, back-pressure is actually determined by the reading side, -// since _read has to be called to start processing a new chunk. However, -// a pathological inflate type of transform can cause excessive buffering -// here. For example, imagine a stream where every byte of input is -// interpreted as an integer from 0-255, and then results in that many -// bytes of output. Writing the 4 bytes {ff,ff,ff,ff} would result in -// 1kb of data being output. In this case, you could write a very small -// amount of input, and end up with a very large amount of output. In -// such a pathological inflating mechanism, there'd be no way to tell -// the system to stop doing the transform. A single 4MB write could -// cause the system to run out of memory. -// -// However, even in such a pathological case, only a single written chunk -// would be consumed, and then the rest would wait (un-transformed) until -// the results of the previous transformed chunk were consumed. +BN.prototype.toRed = function toRed(ctx) { + assert(!this.red, 'Already a number in reduction context'); + assert(!this.sign, 'red works only with positives'); + return ctx.convertTo(this)._forceRed(ctx); +}; -module.exports = Transform; +BN.prototype.fromRed = function fromRed() { + assert(this.red, 'fromRed works only with numbers in reduction context'); + return this.red.convertFrom(this); +}; -var Duplex = require('./_stream_duplex'); +BN.prototype._forceRed = function _forceRed(ctx) { + this.red = ctx; + return this; +}; -/**/ -var util = require('core-util-is'); -util.inherits = require('inherits'); -/**/ - -util.inherits(Transform, Duplex); - - -function TransformState(options, stream) { - this.afterTransform = function(er, data) { - return afterTransform(stream, er, data); - }; +BN.prototype.forceRed = function forceRed(ctx) { + assert(!this.red, 'Already a number in reduction context'); + return this._forceRed(ctx); +}; - this.needTransform = false; - this.transforming = false; - this.writecb = null; - this.writechunk = null; -} +BN.prototype.redAdd = function redAdd(num) { + assert(this.red, 'redAdd works only with red numbers'); + return this.red.add(this, num); +}; -function afterTransform(stream, er, data) { - var ts = stream._transformState; - ts.transforming = false; +BN.prototype.redIAdd = function redIAdd(num) { + assert(this.red, 'redIAdd works only with red numbers'); + return this.red.iadd(this, num); +}; - var cb = ts.writecb; +BN.prototype.redSub = function redSub(num) { + assert(this.red, 'redSub works only with red numbers'); + return this.red.sub(this, num); +}; - if (!cb) - return stream.emit('error', new Error('no writecb in Transform class')); +BN.prototype.redISub = function redISub(num) { + assert(this.red, 'redISub works only with red numbers'); + return this.red.isub(this, num); +}; - ts.writechunk = null; - ts.writecb = null; +BN.prototype.redShl = function redShl(num) { + assert(this.red, 'redShl works only with red numbers'); + return this.red.shl(this, num); +}; - if (data !== null && data !== undefined) - stream.push(data); +BN.prototype.redMul = function redMul(num) { + assert(this.red, 'redMul works only with red numbers'); + this.red._verify2(this, num); + return this.red.mul(this, num); +}; - if (cb) - cb(er); +BN.prototype.redIMul = function redIMul(num) { + assert(this.red, 'redMul works only with red numbers'); + this.red._verify2(this, num); + return this.red.imul(this, num); +}; - var rs = stream._readableState; - rs.reading = false; - if (rs.needReadable || rs.length < rs.highWaterMark) { - stream._read(rs.highWaterMark); - } -} +BN.prototype.redSqr = function redSqr() { + assert(this.red, 'redSqr works only with red numbers'); + this.red._verify1(this); + return this.red.sqr(this); +}; +BN.prototype.redISqr = function redISqr() { + assert(this.red, 'redISqr works only with red numbers'); + this.red._verify1(this); + return this.red.isqr(this); +}; -function Transform(options) { - if (!(this instanceof Transform)) - return new Transform(options); +// Square root over p +BN.prototype.redSqrt = function redSqrt() { + assert(this.red, 'redSqrt works only with red numbers'); + this.red._verify1(this); + return this.red.sqrt(this); +}; - Duplex.call(this, options); +BN.prototype.redInvm = function redInvm() { + assert(this.red, 'redInvm works only with red numbers'); + this.red._verify1(this); + return this.red.invm(this); +}; - var ts = this._transformState = new TransformState(options, this); +// Return negative clone of `this` % `red modulo` +BN.prototype.redNeg = function redNeg() { + assert(this.red, 'redNeg works only with red numbers'); + this.red._verify1(this); + return this.red.neg(this); +}; - // when the writable side finishes, then flush out anything remaining. - var stream = this; +BN.prototype.redPow = function redPow(num) { + assert(this.red && !num.red, 'redPow(normalNum)'); + this.red._verify1(this); + return this.red.pow(this, num); +}; - // start out asking for a readable event once data is transformed. - this._readableState.needReadable = true; +// Prime numbers with efficient reduction +var primes = { + k256: null, + p224: null, + p192: null, + p25519: null +}; - // we have implemented the _read method, and done the other things - // that Readable wants before the first _read call, so unset the - // sync guard flag. - this._readableState.sync = false; +// Pseudo-Mersenne prime +function MPrime(name, p) { + // P = 2 ^ N - K + this.name = name; + this.p = new BN(p, 16); + this.n = this.p.bitLength(); + this.k = new BN(1).ishln(this.n).isub(this.p); - this.once('finish', function() { - if ('function' === typeof this._flush) - this._flush(function(er) { - done(stream, er); - }); - else - done(stream); - }); + this.tmp = this._tmp(); } -Transform.prototype.push = function(chunk, encoding) { - this._transformState.needTransform = false; - return Duplex.prototype.push.call(this, chunk, encoding); -}; - -// This is the part where you do stuff! -// override this function in implementation classes. -// 'chunk' is an input chunk. -// -// Call `push(newChunk)` to pass along transformed output -// to the readable side. You may call 'push' zero or more times. -// -// Call `cb(err)` when you are done with this chunk. If you pass -// an error, then that'll put the hurt on the whole operation. If you -// never call cb(), then you'll never get another chunk. -Transform.prototype._transform = function(chunk, encoding, cb) { - throw new Error('not implemented'); +MPrime.prototype._tmp = function _tmp() { + var tmp = new BN(null); + tmp.words = new Array(Math.ceil(this.n / 13)); + return tmp; }; -Transform.prototype._write = function(chunk, encoding, cb) { - var ts = this._transformState; - ts.writecb = cb; - ts.writechunk = chunk; - ts.writeencoding = encoding; - if (!ts.transforming) { - var rs = this._readableState; - if (ts.needTransform || - rs.needReadable || - rs.length < rs.highWaterMark) - this._read(rs.highWaterMark); - } -}; +MPrime.prototype.ireduce = function ireduce(num) { + // Assumes that `num` is less than `P^2` + // num = HI * (2 ^ N - K) + HI * K + LO = HI * K + LO (mod P) + var r = num; + var rlen; -// Doesn't matter what the args are here. -// _transform does all the work. -// That we got here means that the readable side wants more data. -Transform.prototype._read = function(n) { - var ts = this._transformState; + do { + this.split(r, this.tmp); + r = this.imulK(r); + r = r.iadd(this.tmp); + rlen = r.bitLength(); + } while (rlen > this.n); - if (ts.writechunk !== null && ts.writecb && !ts.transforming) { - ts.transforming = true; - this._transform(ts.writechunk, ts.writeencoding, ts.afterTransform); + var cmp = rlen < this.n ? -1 : r.ucmp(this.p); + if (cmp === 0) { + r.words[0] = 0; + r.length = 1; + } else if (cmp > 0) { + r.isub(this.p); } else { - // mark that we need a transform, so that any data that comes in - // will get processed, now that we've asked for it. - ts.needTransform = true; + r.strip(); } -}; + return r; +}; -function done(stream, er) { - if (er) - return stream.emit('error', er); +MPrime.prototype.split = function split(input, out) { + input.ishrn(this.n, 0, out); +}; - // if there's nothing in the write buffer, then that means - // that nothing more will ever be provided - var ws = stream._writableState; - var rs = stream._readableState; - var ts = stream._transformState; +MPrime.prototype.imulK = function imulK(num) { + return num.imul(this.k); +}; - if (ws.length) - throw new Error('calling transform done when ws.length != 0'); +function K256() { + MPrime.call( + this, + 'k256', + 'ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff fffffffe fffffc2f'); +} +inherits(K256, MPrime); - if (ts.transforming) - throw new Error('calling transform done when still transforming'); +K256.prototype.split = function split(input, output) { + // 256 = 9 * 26 + 22 + var mask = 0x3fffff; - return stream.push(null); -} + var outLen = Math.min(input.length, 9); + for (var i = 0; i < outLen; i++) + output.words[i] = input.words[i]; + output.length = outLen; -},{"./_stream_duplex":190,"core-util-is":195,"inherits":229}],194:[function(require,module,exports){ -(function (process){ -// Copyright Joyent, Inc. and other Node contributors. -// -// Permission is hereby granted, free of charge, to any person obtaining a -// copy of this software and associated documentation files (the -// "Software"), to deal in the Software without restriction, including -// without limitation the rights to use, copy, modify, merge, publish, -// distribute, sublicense, and/or sell copies of the Software, and to permit -// persons to whom the Software is furnished to do so, subject to the -// following conditions: -// -// The above copyright notice and this permission notice shall be included -// in all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS -// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN -// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, -// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR -// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE -// USE OR OTHER DEALINGS IN THE SOFTWARE. + if (input.length <= 9) { + input.words[0] = 0; + input.length = 1; + return; + } -// A bit simpler than readable streams. -// Implement an async ._write(chunk, cb), and it'll handle all -// the drain event emission and buffering. + // Shift by 9 limbs + var prev = input.words[9]; + output.words[output.length++] = prev & mask; -module.exports = Writable; + for (var i = 10; i < input.length; i++) { + var next = input.words[i]; + input.words[i - 10] = ((next & mask) << 4) | (prev >>> 22); + prev = next; + } + input.words[i - 10] = prev >>> 22; + input.length -= 9; +}; -/**/ -var Buffer = require('buffer').Buffer; -/**/ +K256.prototype.imulK = function imulK(num) { + // K = 0x1000003d1 = [ 0x40, 0x3d1 ] + num.words[num.length] = 0; + num.words[num.length + 1] = 0; + num.length += 2; -Writable.WritableState = WritableState; + // bounded at: 0x40 * 0x3ffffff + 0x3d0 = 0x100000390 + var hi; + var lo = 0; + for (var i = 0; i < num.length; i++) { + var w = num.words[i]; + hi = w * 0x40; + lo += w * 0x3d1; + hi += (lo / 0x4000000) | 0; + lo &= 0x3ffffff; + num.words[i] = lo; -/**/ -var util = require('core-util-is'); -util.inherits = require('inherits'); -/**/ + lo = hi; + } -var Stream = require('stream'); + // Fast length reduction + if (num.words[num.length - 1] === 0) { + num.length--; + if (num.words[num.length - 1] === 0) + num.length--; + } + return num; +}; -util.inherits(Writable, Stream); +function P224() { + MPrime.call( + this, + 'p224', + 'ffffffff ffffffff ffffffff ffffffff 00000000 00000000 00000001'); +} +inherits(P224, MPrime); -function WriteReq(chunk, encoding, cb) { - this.chunk = chunk; - this.encoding = encoding; - this.callback = cb; +function P192() { + MPrime.call( + this, + 'p192', + 'ffffffff ffffffff ffffffff fffffffe ffffffff ffffffff'); } +inherits(P192, MPrime); -function WritableState(options, stream) { - options = options || {}; +function P25519() { + // 2 ^ 255 - 19 + MPrime.call( + this, + '25519', + '7fffffffffffffff ffffffffffffffff ffffffffffffffff ffffffffffffffed'); +} +inherits(P25519, MPrime); - // the point at which write() starts returning false - // Note: 0 is a valid value, means that we always return false if - // the entire buffer is not flushed immediately on write() - var hwm = options.highWaterMark; - this.highWaterMark = (hwm || hwm === 0) ? hwm : 16 * 1024; +P25519.prototype.imulK = function imulK(num) { + // K = 0x13 + var carry = 0; + for (var i = 0; i < num.length; i++) { + var hi = num.words[i] * 0x13 + carry; + var lo = hi & 0x3ffffff; + hi >>>= 26; - // object stream flag to indicate whether or not this stream - // contains buffers or objects. - this.objectMode = !!options.objectMode; + num.words[i] = lo; + carry = hi; + } + if (carry !== 0) + num.words[num.length++] = carry; + return num; +}; - // cast to ints. - this.highWaterMark = ~~this.highWaterMark; +// Exported mostly for testing purposes, use plain name instead +BN._prime = function prime(name) { + // Cached version of prime + if (primes[name]) + return primes[name]; - this.needDrain = false; - // at the start of calling end() - this.ending = false; - // when end() has been called, and returned - this.ended = false; - // when 'finish' is emitted - this.finished = false; + var prime; + if (name === 'k256') + prime = new K256(); + else if (name === 'p224') + prime = new P224(); + else if (name === 'p192') + prime = new P192(); + else if (name === 'p25519') + prime = new P25519(); + else + throw new Error('Unknown prime ' + name); + primes[name] = prime; - // should we decode strings into buffers before passing to _write? - // this is here so that some node-core streams can optimize string - // handling at a lower level. - var noDecode = options.decodeStrings === false; - this.decodeStrings = !noDecode; + return prime; +}; - // Crypto is kind of old and crusty. Historically, its default string - // encoding is 'binary' so we have to make this configurable. - // Everything else in the universe uses 'utf8', though. - this.defaultEncoding = options.defaultEncoding || 'utf8'; +// +// Base reduction engine +// +function Red(m) { + if (typeof m === 'string') { + var prime = BN._prime(m); + this.m = prime.p; + this.prime = prime; + } else { + this.m = m; + this.prime = null; + } +} - // not an actual buffer we keep track of, but a measurement - // of how much we're waiting to get pushed to some underlying - // socket or file. - this.length = 0; +Red.prototype._verify1 = function _verify1(a) { + assert(!a.sign, 'red works only with positives'); + assert(a.red, 'red works only with red numbers'); +}; - // a flag to see when we're in the middle of a write. - this.writing = false; +Red.prototype._verify2 = function _verify2(a, b) { + assert(!a.sign && !b.sign, 'red works only with positives'); + assert(a.red && a.red === b.red, + 'red works only with red numbers'); +}; - // a flag to be able to tell if the onwrite cb is called immediately, - // or on a later tick. We set this to true at first, becuase any - // actions that shouldn't happen until "later" should generally also - // not happen before the first write call. - this.sync = true; +Red.prototype.imod = function imod(a) { + if (this.prime) + return this.prime.ireduce(a)._forceRed(this); + return a.mod(this.m)._forceRed(this); +}; - // a flag to know if we're processing previously buffered items, which - // may call the _write() callback in the same tick, so that we don't - // end up in an overlapped onwrite situation. - this.bufferProcessing = false; +Red.prototype.neg = function neg(a) { + var r = a.clone(); + r.sign = !r.sign; + return r.iadd(this.m)._forceRed(this); +}; - // the callback that's passed to _write(chunk,cb) - this.onwrite = function(er) { - onwrite(stream, er); - }; +Red.prototype.add = function add(a, b) { + this._verify2(a, b); - // the callback that the user supplies to write(chunk,encoding,cb) - this.writecb = null; + var res = a.add(b); + if (res.cmp(this.m) >= 0) + res.isub(this.m); + return res._forceRed(this); +}; - // the amount that is being written when _write is called. - this.writelen = 0; +Red.prototype.iadd = function iadd(a, b) { + this._verify2(a, b); - this.buffer = []; + var res = a.iadd(b); + if (res.cmp(this.m) >= 0) + res.isub(this.m); + return res; +}; - // True if the error was already emitted and should not be thrown again - this.errorEmitted = false; -} +Red.prototype.sub = function sub(a, b) { + this._verify2(a, b); -function Writable(options) { - var Duplex = require('./_stream_duplex'); + var res = a.sub(b); + if (res.cmpn(0) < 0) + res.iadd(this.m); + return res._forceRed(this); +}; - // Writable ctor is applied to Duplexes, though they're not - // instanceof Writable, they're instanceof Readable. - if (!(this instanceof Writable) && !(this instanceof Duplex)) - return new Writable(options); +Red.prototype.isub = function isub(a, b) { + this._verify2(a, b); - this._writableState = new WritableState(options, this); + var res = a.isub(b); + if (res.cmpn(0) < 0) + res.iadd(this.m); + return res; +}; - // legacy. - this.writable = true; +Red.prototype.shl = function shl(a, num) { + this._verify1(a); + return this.imod(a.shln(num)); +}; - Stream.call(this); -} +Red.prototype.imul = function imul(a, b) { + this._verify2(a, b); + return this.imod(a.imul(b)); +}; -// Otherwise people can pipe Writable streams, which is just wrong. -Writable.prototype.pipe = function() { - this.emit('error', new Error('Cannot pipe. Not readable.')); +Red.prototype.mul = function mul(a, b) { + this._verify2(a, b); + return this.imod(a.mul(b)); }; +Red.prototype.isqr = function isqr(a) { + return this.imul(a, a); +}; -function writeAfterEnd(stream, state, cb) { - var er = new Error('write after end'); - // TODO: defer error events consistently everywhere, not just the cb - stream.emit('error', er); - process.nextTick(function() { - cb(er); - }); -} +Red.prototype.sqr = function sqr(a) { + return this.mul(a, a); +}; -// If we get something that is not a buffer, string, null, or undefined, -// and we're not in objectMode, then that's an error. -// Otherwise stream chunks are all considered to be of length=1, and the -// watermarks determine how many objects to keep in the buffer, rather than -// how many bytes or characters. -function validChunk(stream, state, chunk, cb) { - var valid = true; - if (!Buffer.isBuffer(chunk) && - 'string' !== typeof chunk && - chunk !== null && - chunk !== undefined && - !state.objectMode) { - var er = new TypeError('Invalid non-string/buffer chunk'); - stream.emit('error', er); - process.nextTick(function() { - cb(er); - }); - valid = false; - } - return valid; -} +Red.prototype.sqrt = function sqrt(a) { + if (a.cmpn(0) === 0) + return a.clone(); -Writable.prototype.write = function(chunk, encoding, cb) { - var state = this._writableState; - var ret = false; + var mod3 = this.m.andln(3); + assert(mod3 % 2 === 1); - if (typeof encoding === 'function') { - cb = encoding; - encoding = null; + // Fast case + if (mod3 === 3) { + var pow = this.m.add(new BN(1)).ishrn(2); + var r = this.pow(a, pow); + return r; } - if (Buffer.isBuffer(chunk)) - encoding = 'buffer'; - else if (!encoding) - encoding = state.defaultEncoding; + // Tonelli-Shanks algorithm (Totally unoptimized and slow) + // + // Find Q and S, that Q * 2 ^ S = (P - 1) + var q = this.m.subn(1); + var s = 0; + while (q.cmpn(0) !== 0 && q.andln(1) === 0) { + s++; + q.ishrn(1); + } + assert(q.cmpn(0) !== 0); - if (typeof cb !== 'function') - cb = function() {}; + var one = new BN(1).toRed(this); + var nOne = one.redNeg(); - if (state.ended) - writeAfterEnd(this, state, cb); - else if (validChunk(this, state, chunk, cb)) - ret = writeOrBuffer(this, state, chunk, encoding, cb); + // Find quadratic non-residue + // NOTE: Max is such because of generalized Riemann hypothesis. + var lpow = this.m.subn(1).ishrn(1); + var z = this.m.bitLength(); + z = new BN(2 * z * z).toRed(this); + while (this.pow(z, lpow).cmp(nOne) !== 0) + z.redIAdd(nOne); - return ret; -}; + var c = this.pow(z, q); + var r = this.pow(a, q.addn(1).ishrn(1)); + var t = this.pow(a, q); + var m = s; + while (t.cmp(one) !== 0) { + var tmp = t; + for (var i = 0; tmp.cmp(one) !== 0; i++) + tmp = tmp.redSqr(); + assert(i < m); + var b = this.pow(c, new BN(1).ishln(m - i - 1)); -function decodeChunk(state, chunk, encoding) { - if (!state.objectMode && - state.decodeStrings !== false && - typeof chunk === 'string') { - chunk = new Buffer(chunk, encoding); + r = r.redMul(b); + c = b.redSqr(); + t = t.redMul(c); + m = i; } - return chunk; -} -// if we're already writing something, then just put this -// in the queue, and wait our turn. Otherwise, call _write -// If we return false, then we need a drain event, so set that flag. -function writeOrBuffer(stream, state, chunk, encoding, cb) { - chunk = decodeChunk(state, chunk, encoding); - if (Buffer.isBuffer(chunk)) - encoding = 'buffer'; - var len = state.objectMode ? 1 : chunk.length; + return r; +}; - state.length += len; +Red.prototype.invm = function invm(a) { + var inv = a._invmp(this.m); + if (inv.sign) { + inv.sign = false; + return this.imod(inv).redNeg(); + } else { + return this.imod(inv); + } +}; - var ret = state.length < state.highWaterMark; - // we must ensure that previous needDrain will not be reset to false. - if (!ret) - state.needDrain = true; +Red.prototype.pow = function pow(a, num) { + var w = []; - if (state.writing) - state.buffer.push(new WriteReq(chunk, encoding, cb)); - else - doWrite(stream, state, len, chunk, encoding, cb); + if (num.cmpn(0) === 0) + return new BN(1); - return ret; -} + var q = num.clone(); -function doWrite(stream, state, len, chunk, encoding, cb) { - state.writelen = len; - state.writecb = cb; - state.writing = true; - state.sync = true; - stream._write(chunk, encoding, state.onwrite); - state.sync = false; -} + while (q.cmpn(0) !== 0) { + w.push(q.andln(1)); + q.ishrn(1); + } -function onwriteError(stream, state, sync, er, cb) { - if (sync) - process.nextTick(function() { - cb(er); - }); - else - cb(er); + // Skip leading zeroes + var res = a; + for (var i = 0; i < w.length; i++, res = this.sqr(res)) + if (w[i] !== 0) + break; - stream._writableState.errorEmitted = true; - stream.emit('error', er); -} + if (++i < w.length) { + for (var q = this.sqr(res); i < w.length; i++, q = this.sqr(q)) { + if (w[i] === 0) + continue; + res = this.mul(res, q); + } + } -function onwriteStateUpdate(state) { - state.writing = false; - state.writecb = null; - state.length -= state.writelen; - state.writelen = 0; -} + return res; +}; -function onwrite(stream, er) { - var state = stream._writableState; - var sync = state.sync; - var cb = state.writecb; +Red.prototype.convertTo = function convertTo(num) { + return num.clone(); +}; - onwriteStateUpdate(state); +Red.prototype.convertFrom = function convertFrom(num) { + var res = num.clone(); + res.red = null; + return res; +}; - if (er) - onwriteError(stream, state, sync, er, cb); - else { - // Check if we're actually ready to finish, but don't emit yet - var finished = needFinish(stream, state); +// +// Montgomery method engine +// - if (!finished && !state.bufferProcessing && state.buffer.length) - clearBuffer(stream, state); +BN.mont = function mont(num) { + return new Mont(num); +}; - if (sync) { - process.nextTick(function() { - afterWrite(stream, state, finished, cb); - }); - } else { - afterWrite(stream, state, finished, cb); - } - } -} +function Mont(m) { + Red.call(this, m); -function afterWrite(stream, state, finished, cb) { - if (!finished) - onwriteDrain(stream, state); - cb(); - if (finished) - finishMaybe(stream, state); -} + this.shift = this.m.bitLength(); + if (this.shift % 26 !== 0) + this.shift += 26 - (this.shift % 26); + this.r = new BN(1).ishln(this.shift); + this.r2 = this.imod(this.r.sqr()); + this.rinv = this.r._invmp(this.m); -// Must force callback to be called on nextTick, so that we don't -// emit 'drain' before the write() consumer gets the 'false' return -// value, and has a chance to attach a 'drain' listener. -function onwriteDrain(stream, state) { - if (state.length === 0 && state.needDrain) { - state.needDrain = false; - stream.emit('drain'); - } + this.minv = this.rinv.mul(this.r).isubn(1).div(this.m); + this.minv.sign = true; + this.minv = this.minv.mod(this.r); } +inherits(Mont, Red); +Mont.prototype.convertTo = function convertTo(num) { + return this.imod(num.shln(this.shift)); +}; -// if there's something in the buffer waiting, then process it -function clearBuffer(stream, state) { - state.bufferProcessing = true; +Mont.prototype.convertFrom = function convertFrom(num) { + var r = this.imod(num.mul(this.rinv)); + r.red = null; + return r; +}; - for (var c = 0; c < state.buffer.length; c++) { - var entry = state.buffer[c]; - var chunk = entry.chunk; - var encoding = entry.encoding; - var cb = entry.callback; - var len = state.objectMode ? 1 : chunk.length; - - doWrite(stream, state, len, chunk, encoding, cb); - - // if we didn't call the onwrite immediately, then - // it means that we need to wait until it does. - // also, that means that the chunk and cb are currently - // being processed, so move the buffer counter past them. - if (state.writing) { - c++; - break; - } +Mont.prototype.imul = function imul(a, b) { + if (a.cmpn(0) === 0 || b.cmpn(0) === 0) { + a.words[0] = 0; + a.length = 1; + return a; } - state.bufferProcessing = false; - if (c < state.buffer.length) - state.buffer = state.buffer.slice(c); - else - state.buffer.length = 0; -} + var t = a.imul(b); + var c = t.maskn(this.shift).mul(this.minv).imaskn(this.shift).mul(this.m); + var u = t.isub(c).ishrn(this.shift); + var res = u; + if (u.cmp(this.m) >= 0) + res = u.isub(this.m); + else if (u.cmpn(0) < 0) + res = u.iadd(this.m); -Writable.prototype._write = function(chunk, encoding, cb) { - cb(new Error('not implemented')); + return res._forceRed(this); }; -Writable.prototype.end = function(chunk, encoding, cb) { - var state = this._writableState; +Mont.prototype.mul = function mul(a, b) { + if (a.cmpn(0) === 0 || b.cmpn(0) === 0) + return new BN(0)._forceRed(this); - if (typeof chunk === 'function') { - cb = chunk; - chunk = null; - encoding = null; - } else if (typeof encoding === 'function') { - cb = encoding; - encoding = null; - } + var t = a.mul(b); + var c = t.maskn(this.shift).mul(this.minv).imaskn(this.shift).mul(this.m); + var u = t.isub(c).ishrn(this.shift); + var res = u; + if (u.cmp(this.m) >= 0) + res = u.isub(this.m); + else if (u.cmpn(0) < 0) + res = u.iadd(this.m); - if (typeof chunk !== 'undefined' && chunk !== null) - this.write(chunk, encoding); + return res._forceRed(this); +}; - // ignore unnecessary end() calls. - if (!state.ending && !state.finished) - endWritable(this, state, cb); +Mont.prototype.invm = function invm(a) { + // (AR)^-1 * R^2 = (A^-1 * R^-1) * R^2 = A^-1 * R + var res = this.imod(a._invmp(this.m).mul(this.r2)); + return res._forceRed(this); }; +})(typeof module === 'undefined' || module, this); -function needFinish(stream, state) { - return (state.ending && - state.length === 0 && - !state.finished && - !state.writing); -} +},{}],218:[function(require,module,exports){ +// Base58 encoding/decoding +// Originally written by Mike Hearn for BitcoinJ +// Copyright (c) 2011 Google Inc +// Ported to JavaScript by Stefan Thomas +// Merged Buffer refactorings from base58-native by Stephen Pair +// Copyright (c) 2013 BitPay Inc -function finishMaybe(stream, state) { - var need = needFinish(stream, state); - if (need) { - state.finished = true; - stream.emit('finish'); - } - return need; +var ALPHABET = '123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz' +var ALPHABET_MAP = {} +for(var i = 0; i < ALPHABET.length; i++) { + ALPHABET_MAP[ALPHABET.charAt(i)] = i } +var BASE = 58 -function endWritable(stream, state, cb) { - state.ending = true; - finishMaybe(stream, state); - if (cb) { - if (state.finished) - process.nextTick(cb); - else - stream.once('finish', cb); - } - state.ended = true; -} +function encode(buffer) { + if (buffer.length === 0) return '' -}).call(this,require('_process')) -},{"./_stream_duplex":190,"_process":184,"buffer":42,"core-util-is":195,"inherits":229,"stream":200}],195:[function(require,module,exports){ -(function (Buffer){ -// Copyright Joyent, Inc. and other Node contributors. -// -// Permission is hereby granted, free of charge, to any person obtaining a -// copy of this software and associated documentation files (the -// "Software"), to deal in the Software without restriction, including -// without limitation the rights to use, copy, modify, merge, publish, -// distribute, sublicense, and/or sell copies of the Software, and to permit -// persons to whom the Software is furnished to do so, subject to the -// following conditions: -// -// The above copyright notice and this permission notice shall be included -// in all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS -// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN -// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, -// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR -// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE -// USE OR OTHER DEALINGS IN THE SOFTWARE. + var i, j, digits = [0] + for (i = 0; i < buffer.length; i++) { + for (j = 0; j < digits.length; j++) digits[j] <<= 8 -// NOTE: These type checking functions intentionally don't use `instanceof` -// because it is fragile and can be easily faked with `Object.create()`. -function isArray(ar) { - return Array.isArray(ar); -} -exports.isArray = isArray; + digits[0] += buffer[i] -function isBoolean(arg) { - return typeof arg === 'boolean'; -} -exports.isBoolean = isBoolean; + var carry = 0 + for (j = 0; j < digits.length; ++j) { + digits[j] += carry -function isNull(arg) { - return arg === null; -} -exports.isNull = isNull; + carry = (digits[j] / BASE) | 0 + digits[j] %= BASE + } -function isNullOrUndefined(arg) { - return arg == null; -} -exports.isNullOrUndefined = isNullOrUndefined; + while (carry) { + digits.push(carry % BASE) -function isNumber(arg) { - return typeof arg === 'number'; -} -exports.isNumber = isNumber; + carry = (carry / BASE) | 0 + } + } -function isString(arg) { - return typeof arg === 'string'; -} -exports.isString = isString; + // deal with leading zeros + for (i = 0; buffer[i] === 0 && i < buffer.length - 1; i++) digits.push(0) -function isSymbol(arg) { - return typeof arg === 'symbol'; + return digits.reverse().map(function(digit) { return ALPHABET[digit] }).join('') } -exports.isSymbol = isSymbol; -function isUndefined(arg) { - return arg === void 0; -} -exports.isUndefined = isUndefined; +function decode(string) { + if (string.length === 0) return [] -function isRegExp(re) { - return isObject(re) && objectToString(re) === '[object RegExp]'; -} -exports.isRegExp = isRegExp; + var i, j, bytes = [0] + for (i = 0; i < string.length; i++) { + var c = string[i] + if (!(c in ALPHABET_MAP)) throw new Error('Non-base58 character') -function isObject(arg) { - return typeof arg === 'object' && arg !== null; -} -exports.isObject = isObject; + for (j = 0; j < bytes.length; j++) bytes[j] *= BASE + bytes[0] += ALPHABET_MAP[c] -function isDate(d) { - return isObject(d) && objectToString(d) === '[object Date]'; -} -exports.isDate = isDate; + var carry = 0 + for (j = 0; j < bytes.length; ++j) { + bytes[j] += carry -function isError(e) { - return isObject(e) && - (objectToString(e) === '[object Error]' || e instanceof Error); -} -exports.isError = isError; + carry = bytes[j] >> 8 + bytes[j] &= 0xff + } -function isFunction(arg) { - return typeof arg === 'function'; -} -exports.isFunction = isFunction; + while (carry) { + bytes.push(carry & 0xff) -function isPrimitive(arg) { - return arg === null || - typeof arg === 'boolean' || - typeof arg === 'number' || - typeof arg === 'string' || - typeof arg === 'symbol' || // ES6 symbol - typeof arg === 'undefined'; -} -exports.isPrimitive = isPrimitive; + carry >>= 8 + } + } -function isBuffer(arg) { - return Buffer.isBuffer(arg); + // deal with leading zeros + for (i = 0; string[i] === '1' && i < string.length - 1; i++) bytes.push(0) + + return bytes.reverse() } -exports.isBuffer = isBuffer; -function objectToString(o) { - return Object.prototype.toString.call(o); +module.exports = { + encode: encode, + decode: decode } -}).call(this,require("buffer").Buffer) -},{"buffer":42}],196:[function(require,module,exports){ -module.exports = require("./lib/_stream_passthrough.js") -},{"./lib/_stream_passthrough.js":191}],197:[function(require,module,exports){ -var Stream = require('stream'); // hack to fix a circular dependency issue when used with browserify -exports = module.exports = require('./lib/_stream_readable.js'); -exports.Stream = Stream; -exports.Readable = exports; -exports.Writable = require('./lib/_stream_writable.js'); -exports.Duplex = require('./lib/_stream_duplex.js'); -exports.Transform = require('./lib/_stream_transform.js'); -exports.PassThrough = require('./lib/_stream_passthrough.js'); +},{}],219:[function(require,module,exports){ +'use strict'; -},{"./lib/_stream_duplex.js":190,"./lib/_stream_passthrough.js":191,"./lib/_stream_readable.js":192,"./lib/_stream_transform.js":193,"./lib/_stream_writable.js":194,"stream":200}],198:[function(require,module,exports){ -module.exports = require("./lib/_stream_transform.js") +var elliptic = exports; -},{"./lib/_stream_transform.js":193}],199:[function(require,module,exports){ -module.exports = require("./lib/_stream_writable.js") +elliptic.version = require('../package.json').version; +elliptic.utils = require('./elliptic/utils'); +elliptic.rand = require('brorand'); +elliptic.hmacDRBG = require('./elliptic/hmac-drbg'); +elliptic.curve = require('./elliptic/curve'); +elliptic.curves = require('./elliptic/curves'); -},{"./lib/_stream_writable.js":194}],200:[function(require,module,exports){ -// Copyright Joyent, Inc. and other Node contributors. -// -// Permission is hereby granted, free of charge, to any person obtaining a -// copy of this software and associated documentation files (the -// "Software"), to deal in the Software without restriction, including -// without limitation the rights to use, copy, modify, merge, publish, -// distribute, sublicense, and/or sell copies of the Software, and to permit -// persons to whom the Software is furnished to do so, subject to the -// following conditions: -// -// The above copyright notice and this permission notice shall be included -// in all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS -// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN -// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, -// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR -// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE -// USE OR OTHER DEALINGS IN THE SOFTWARE. +// Protocols +elliptic.ec = require('./elliptic/ec'); -module.exports = Stream; +},{"../package.json":233,"./elliptic/curve":222,"./elliptic/curves":225,"./elliptic/ec":226,"./elliptic/hmac-drbg":229,"./elliptic/utils":231,"brorand":232}],220:[function(require,module,exports){ +'use strict'; -var EE = require('events').EventEmitter; -var inherits = require('inherits'); +var bn = require('bn.js'); +var elliptic = require('../../elliptic'); -inherits(Stream, EE); -Stream.Readable = require('readable-stream/readable.js'); -Stream.Writable = require('readable-stream/writable.js'); -Stream.Duplex = require('readable-stream/duplex.js'); -Stream.Transform = require('readable-stream/transform.js'); -Stream.PassThrough = require('readable-stream/passthrough.js'); +var getNAF = elliptic.utils.getNAF; +var getJSF = elliptic.utils.getJSF; +var assert = elliptic.utils.assert; -// Backwards-compat with node 0.4.x -Stream.Stream = Stream; +function BaseCurve(type, conf) { + this.type = type; + this.p = new bn(conf.p, 16); + // Use Montgomery, when there is no fast reduction for the prime + this.red = conf.prime ? bn.red(conf.prime) : bn.mont(this.p); + // Useful for many curves + this.zero = new bn(0).toRed(this.red); + this.one = new bn(1).toRed(this.red); + this.two = new bn(2).toRed(this.red); -// old-style streams. Note that the pipe method (the only relevant -// part of this class) is overridden in the Readable class. + // Curve configuration, optional + this.n = conf.n && new bn(conf.n, 16); + this.g = conf.g && this.pointFromJSON(conf.g, conf.gRed); -function Stream() { - EE.call(this); + // Temporary arrays + this._wnafT1 = new Array(4); + this._wnafT2 = new Array(4); + this._wnafT3 = new Array(4); + this._wnafT4 = new Array(4); } +module.exports = BaseCurve; -Stream.prototype.pipe = function(dest, options) { - var source = this; - - function ondata(chunk) { - if (dest.writable) { - if (false === dest.write(chunk) && source.pause) { - source.pause(); - } - } - } +BaseCurve.prototype.point = function point() { + throw new Error('Not implemented'); +}; - source.on('data', ondata); +BaseCurve.prototype.validate = function validate() { + throw new Error('Not implemented'); +}; - function ondrain() { - if (source.readable && source.resume) { - source.resume(); - } - } +BaseCurve.prototype._fixedNafMul = function _fixedNafMul(p, k) { + var doubles = p._getDoubles(); - dest.on('drain', ondrain); + var naf = getNAF(k, 1); + var I = (1 << (doubles.step + 1)) - (doubles.step % 2 === 0 ? 2 : 1); + I /= 3; - // If the 'end' option is not supplied, dest.end() will be called when - // source gets the 'end' or 'close' events. Only dest.end() once. - if (!dest._isStdio && (!options || options.end !== false)) { - source.on('end', onend); - source.on('close', onclose); + // Translate into more windowed form + var repr = []; + for (var j = 0; j < naf.length; j += doubles.step) { + var nafW = 0; + for (var k = j + doubles.step - 1; k >= j; k--) + nafW = (nafW << 1) + naf[k]; + repr.push(nafW); } - var didOnEnd = false; - function onend() { - if (didOnEnd) return; - didOnEnd = true; - - dest.end(); + var a = this.jpoint(null, null, null); + var b = this.jpoint(null, null, null); + for (var i = I; i > 0; i--) { + for (var j = 0; j < repr.length; j++) { + var nafW = repr[j]; + if (nafW === i) + b = b.mixedAdd(doubles.points[j]); + else if (nafW === -i) + b = b.mixedAdd(doubles.points[j].neg()); + } + a = a.add(b); } + return a.toP(); +}; +BaseCurve.prototype._wnafMul = function _wnafMul(p, k) { + var w = 4; - function onclose() { - if (didOnEnd) return; - didOnEnd = true; + // Precompute window + var nafPoints = p._getNAFPoints(w); + w = nafPoints.wnd; + var wnd = nafPoints.points; - if (typeof dest.destroy === 'function') dest.destroy(); - } + // Get NAF form + var naf = getNAF(k, w); - // don't leave dangling pipes when there are errors. - function onerror(er) { - cleanup(); - if (EE.listenerCount(this, 'error') === 0) { - throw er; // Unhandled stream error in pipe. + // Add `this`*(N+1) for every w-NAF index + var acc = this.jpoint(null, null, null); + for (var i = naf.length - 1; i >= 0; i--) { + // Count zeroes + for (var k = 0; i >= 0 && naf[i] === 0; i--) + k++; + if (i >= 0) + k++; + acc = acc.dblp(k); + + if (i < 0) + break; + var z = naf[i]; + assert(z !== 0); + if (p.type === 'affine') { + // J +- P + if (z > 0) + acc = acc.mixedAdd(wnd[(z - 1) >> 1]); + else + acc = acc.mixedAdd(wnd[(-z - 1) >> 1].neg()); + } else { + // J +- J + if (z > 0) + acc = acc.add(wnd[(z - 1) >> 1]); + else + acc = acc.add(wnd[(-z - 1) >> 1].neg()); } } + return p.type === 'affine' ? acc.toP() : acc; +}; - source.on('error', onerror); - dest.on('error', onerror); +BaseCurve.prototype._wnafMulAdd = function _wnafMulAdd(defW, + points, + coeffs, + len) { + var wndWidth = this._wnafT1; + var wnd = this._wnafT2; + var naf = this._wnafT3; - // remove all the event listeners that were added. - function cleanup() { - source.removeListener('data', ondata); - dest.removeListener('drain', ondrain); + // Fill all arrays + var max = 0; + for (var i = 0; i < len; i++) { + var p = points[i]; + var nafPoints = p._getNAFPoints(defW); + wndWidth[i] = nafPoints.wnd; + wnd[i] = nafPoints.points; + } - source.removeListener('end', onend); - source.removeListener('close', onclose); + // Comb small window NAFs + for (var i = len - 1; i >= 1; i -= 2) { + var a = i - 1; + var b = i; + if (wndWidth[a] !== 1 || wndWidth[b] !== 1) { + naf[a] = getNAF(coeffs[a], wndWidth[a]); + naf[b] = getNAF(coeffs[b], wndWidth[b]); + max = Math.max(naf[a].length, max); + max = Math.max(naf[b].length, max); + continue; + } - source.removeListener('error', onerror); - dest.removeListener('error', onerror); + var comb = [ + points[a], /* 1 */ + null, /* 3 */ + null, /* 5 */ + points[b] /* 7 */ + ]; - source.removeListener('end', cleanup); - source.removeListener('close', cleanup); + // Try to avoid Projective points, if possible + if (points[a].y.cmp(points[b].y) === 0) { + comb[1] = points[a].add(points[b]); + comb[2] = points[a].toJ().mixedAdd(points[b].neg()); + } else if (points[a].y.cmp(points[b].y.redNeg()) === 0) { + comb[1] = points[a].toJ().mixedAdd(points[b]); + comb[2] = points[a].add(points[b].neg()); + } else { + comb[1] = points[a].toJ().mixedAdd(points[b]); + comb[2] = points[a].toJ().mixedAdd(points[b].neg()); + } - dest.removeListener('close', cleanup); + var index = [ + -3, /* -1 -1 */ + -1, /* -1 0 */ + -5, /* -1 1 */ + -7, /* 0 -1 */ + 0, /* 0 0 */ + 7, /* 0 1 */ + 5, /* 1 -1 */ + 1, /* 1 0 */ + 3 /* 1 1 */ + ]; + + var jsf = getJSF(coeffs[a], coeffs[b]); + max = Math.max(jsf[0].length, max); + naf[a] = new Array(max); + naf[b] = new Array(max); + for (var j = 0; j < max; j++) { + var ja = jsf[0][j] | 0; + var jb = jsf[1][j] | 0; + + naf[a][j] = index[(ja + 1) * 3 + (jb + 1)]; + naf[b][j] = 0; + wnd[a] = comb; + } } - source.on('end', cleanup); - source.on('close', cleanup); + var acc = this.jpoint(null, null, null); + var tmp = this._wnafT4; + for (var i = max; i >= 0; i--) { + var k = 0; - dest.on('close', cleanup); + while (i >= 0) { + var zero = true; + for (var j = 0; j < len; j++) { + tmp[j] = naf[j][i] | 0; + if (tmp[j] !== 0) + zero = false; + } + if (!zero) + break; + k++; + i--; + } + if (i >= 0) + k++; + acc = acc.dblp(k); + if (i < 0) + break; - dest.emit('pipe', source); + for (var j = 0; j < len; j++) { + var z = tmp[j]; + var p; + if (z === 0) + continue; + else if (z > 0) + p = wnd[j][(z - 1) >> 1]; + else if (z < 0) + p = wnd[j][(-z - 1) >> 1].neg(); - // Allow for unix-like usage: A.pipe(B).pipe(C) - return dest; + if (p.type === 'affine') + acc = acc.mixedAdd(p); + else + acc = acc.add(p); + } + } + // Zeroify references + for (var i = 0; i < len; i++) + wnd[i] = null; + return acc.toP(); }; -},{"events":182,"inherits":229,"readable-stream/duplex.js":189,"readable-stream/passthrough.js":196,"readable-stream/readable.js":197,"readable-stream/transform.js":198,"readable-stream/writable.js":199}],201:[function(require,module,exports){ -// Copyright Joyent, Inc. and other Node contributors. -// -// Permission is hereby granted, free of charge, to any person obtaining a -// copy of this software and associated documentation files (the -// "Software"), to deal in the Software without restriction, including -// without limitation the rights to use, copy, modify, merge, publish, -// distribute, sublicense, and/or sell copies of the Software, and to permit -// persons to whom the Software is furnished to do so, subject to the -// following conditions: -// -// The above copyright notice and this permission notice shall be included -// in all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS -// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN -// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, -// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR -// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE -// USE OR OTHER DEALINGS IN THE SOFTWARE. +function BasePoint(curve, type) { + this.curve = curve; + this.type = type; + this.precomputed = null; +} +BaseCurve.BasePoint = BasePoint; -var Buffer = require('buffer').Buffer; +BasePoint.prototype.validate = function validate() { + return this.curve.validate(this); +}; -var isBufferEncoding = Buffer.isEncoding - || function(encoding) { - switch (encoding && encoding.toLowerCase()) { - case 'hex': case 'utf8': case 'utf-8': case 'ascii': case 'binary': case 'base64': case 'ucs2': case 'ucs-2': case 'utf16le': case 'utf-16le': case 'raw': return true; - default: return false; - } - } +BasePoint.prototype.precompute = function precompute(power) { + if (this.precomputed) + return this; + var precomputed = { + doubles: null, + naf: null, + beta: null + }; + precomputed.naf = this._getNAFPoints(8); + precomputed.doubles = this._getDoubles(4, power); + precomputed.beta = this._getBeta(); + this.precomputed = precomputed; -function assertEncoding(encoding) { - if (encoding && !isBufferEncoding(encoding)) { - throw new Error('Unknown encoding: ' + encoding); - } -} + return this; +}; -// StringDecoder provides an interface for efficiently splitting a series of -// buffers into a series of JS strings without breaking apart multi-byte -// characters. CESU-8 is handled as part of the UTF-8 encoding. -// -// @TODO Handling all encodings inside a single object makes it very difficult -// to reason about this code, so it should be split up in the future. -// @TODO There should be a utf8-strict encoding that rejects invalid UTF-8 code -// points as used by CESU-8. -var StringDecoder = exports.StringDecoder = function(encoding) { - this.encoding = (encoding || 'utf8').toLowerCase().replace(/[-_]/, ''); - assertEncoding(encoding); - switch (this.encoding) { - case 'utf8': - // CESU-8 represents each of Surrogate Pair by 3-bytes - this.surrogateSize = 3; - break; - case 'ucs2': - case 'utf16le': - // UTF-16 represents each of Surrogate Pair by 2-bytes - this.surrogateSize = 2; - this.detectIncompleteChar = utf16DetectIncompleteChar; - break; - case 'base64': - // Base-64 stores 3 bytes in 4 chars, and pads the remainder. - this.surrogateSize = 3; - this.detectIncompleteChar = base64DetectIncompleteChar; - break; - default: - this.write = passThroughWrite; - return; - } +BasePoint.prototype._getDoubles = function _getDoubles(step, power) { + if (this.precomputed && this.precomputed.doubles) + return this.precomputed.doubles; - // Enough space to store all bytes of a single character. UTF-8 needs 4 - // bytes, but CESU-8 may require up to 6 (3 bytes per surrogate). - this.charBuffer = new Buffer(6); - // Number of bytes received for the current incomplete multi-byte character. - this.charReceived = 0; - // Number of bytes expected for the current incomplete multi-byte character. - this.charLength = 0; + var doubles = [ this ]; + var acc = this; + for (var i = 0; i < power; i += step) { + for (var j = 0; j < step; j++) + acc = acc.dbl(); + doubles.push(acc); + } + return { + step: step, + points: doubles + }; }; +BasePoint.prototype._getNAFPoints = function _getNAFPoints(wnd) { + if (this.precomputed && this.precomputed.naf) + return this.precomputed.naf; -// write decodes the given buffer and returns it as JS string that is -// guaranteed to not contain any partial multi-byte characters. Any partial -// character found at the end of the buffer is buffered up, and will be -// returned when calling write again with the remaining bytes. -// -// Note: Converting a Buffer containing an orphan surrogate to a String -// currently works, but converting a String to a Buffer (via `new Buffer`, or -// Buffer#write) will replace incomplete surrogates with the unicode -// replacement character. See https://codereview.chromium.org/121173009/ . -StringDecoder.prototype.write = function(buffer) { - var charStr = ''; - // if our last write ended with an incomplete multibyte character - while (this.charLength) { - // determine how many remaining bytes this buffer has to offer for this char - var available = (buffer.length >= this.charLength - this.charReceived) ? - this.charLength - this.charReceived : - buffer.length; - - // add the new bytes to the char buffer - buffer.copy(this.charBuffer, this.charReceived, 0, available); - this.charReceived += available; + var res = [ this ]; + var max = (1 << wnd) - 1; + var dbl = max === 1 ? null : this.dbl(); + for (var i = 1; i < max; i++) + res[i] = res[i - 1].add(dbl); + return { + wnd: wnd, + points: res + }; +}; - if (this.charReceived < this.charLength) { - // still not enough chars in this buffer? wait for more ... - return ''; - } +BasePoint.prototype._getBeta = function _getBeta() { + return null; +}; - // remove bytes belonging to the current character from the buffer - buffer = buffer.slice(available, buffer.length); +BasePoint.prototype.dblp = function dblp(k) { + var r = this; + for (var i = 0; i < k; i++) + r = r.dbl(); + return r; +}; - // get the character that was split - charStr = this.charBuffer.slice(0, this.charLength).toString(this.encoding); +},{"../../elliptic":219,"bn.js":217}],221:[function(require,module,exports){ +'use strict'; - // CESU-8: lead surrogate (D800-DBFF) is also the incomplete character - var charCode = charStr.charCodeAt(charStr.length - 1); - if (charCode >= 0xD800 && charCode <= 0xDBFF) { - this.charLength += this.surrogateSize; - charStr = ''; - continue; - } - this.charReceived = this.charLength = 0; +var curve = require('../curve'); +var elliptic = require('../../elliptic'); +var bn = require('bn.js'); +var inherits = require('inherits'); +var Base = curve.base; - // if there are no more bytes in this buffer, just emit our char - if (buffer.length === 0) { - return charStr; - } - break; - } +var assert = elliptic.utils.assert; - // determine and set charLength / charReceived - this.detectIncompleteChar(buffer); +function EdwardsCurve(conf) { + // NOTE: Important as we are creating point in Base.call() + this.twisted = (conf.a | 0) !== 1; + this.mOneA = this.twisted && (conf.a | 0) === -1; + this.extended = this.mOneA; - var end = buffer.length; - if (this.charLength) { - // buffer the incomplete character bytes we got - buffer.copy(this.charBuffer, 0, buffer.length - this.charReceived, end); - end -= this.charReceived; - } + Base.call(this, 'edwards', conf); - charStr += buffer.toString(this.encoding, 0, end); + this.a = new bn(conf.a, 16).mod(this.red.m).toRed(this.red); + this.c = new bn(conf.c, 16).toRed(this.red); + this.c2 = this.c.redSqr(); + this.d = new bn(conf.d, 16).toRed(this.red); + this.dd = this.d.redAdd(this.d); - var end = charStr.length - 1; - var charCode = charStr.charCodeAt(end); - // CESU-8: lead surrogate (D800-DBFF) is also the incomplete character - if (charCode >= 0xD800 && charCode <= 0xDBFF) { - var size = this.surrogateSize; - this.charLength += size; - this.charReceived += size; - this.charBuffer.copy(this.charBuffer, size, 0, size); - buffer.copy(this.charBuffer, 0, 0, size); - return charStr.substring(0, end); - } + assert(!this.twisted || this.c.fromRed().cmpn(1) === 0); + this.oneC = (conf.c | 0) === 1; +} +inherits(EdwardsCurve, Base); +module.exports = EdwardsCurve; - // or just emit the charStr - return charStr; +EdwardsCurve.prototype._mulA = function _mulA(num) { + if (this.mOneA) + return num.redNeg(); + else + return this.a.redMul(num); }; -// detectIncompleteChar determines if there is an incomplete UTF-8 character at -// the end of the given buffer. If so, it sets this.charLength to the byte -// length that character, and sets this.charReceived to the number of bytes -// that are available for this character. -StringDecoder.prototype.detectIncompleteChar = function(buffer) { - // determine how many bytes we have to check at the end of this buffer - var i = (buffer.length >= 3) ? 3 : buffer.length; +EdwardsCurve.prototype._mulC = function _mulC(num) { + if (this.oneC) + return num; + else + return this.c.redMul(num); +}; - // Figure out if one of the last i bytes of our buffer announces an - // incomplete char. - for (; i > 0; i--) { - var c = buffer[buffer.length - i]; +// Just for compatibility with Short curve +EdwardsCurve.prototype.jpoint = function jpoint(x, y, z, t) { + return this.point(x, y, z, t); +}; - // See http://en.wikipedia.org/wiki/UTF-8#Description +EdwardsCurve.prototype.pointFromX = function pointFromX(odd, x) { + x = new bn(x, 16); + if (!x.red) + x = x.toRed(this.red); - // 110XXXXX - if (i == 1 && c >> 5 == 0x06) { - this.charLength = 2; - break; - } + var x2 = x.redSqr(); + var rhs = this.c2.redSub(this.a.redMul(x2)); + var lhs = this.one.redSub(this.c2.redMul(this.d).redMul(x2)); - // 1110XXXX - if (i <= 2 && c >> 4 == 0x0E) { - this.charLength = 3; - break; - } + var y = rhs.redMul(lhs.redInvm()).redSqrt(); + var isOdd = y.fromRed().isOdd(); + if (odd && !isOdd || !odd && isOdd) + y = y.redNeg(); - // 11110XXX - if (i <= 3 && c >> 3 == 0x1E) { - this.charLength = 4; - break; - } - } - this.charReceived = i; + return this.point(x, y, curve.one); }; -StringDecoder.prototype.end = function(buffer) { - var res = ''; - if (buffer && buffer.length) - res = this.write(buffer); - - if (this.charReceived) { - var cr = this.charReceived; - var buf = this.charBuffer; - var enc = this.encoding; - res += buf.slice(0, cr).toString(enc); - } - - return res; -}; +EdwardsCurve.prototype.validate = function validate(point) { + if (point.isInfinity()) + return true; -function passThroughWrite(buffer) { - return buffer.toString(this.encoding); -} + // Curve: A * X^2 + Y^2 = C^2 * (1 + D * X^2 * Y^2) + point.normalize(); -function utf16DetectIncompleteChar(buffer) { - this.charReceived = buffer.length % 2; - this.charLength = this.charReceived ? 2 : 0; -} + var x2 = point.x.redSqr(); + var y2 = point.y.redSqr(); + var lhs = x2.redMul(this.a).redAdd(y2); + var rhs = this.c2.redMul(this.one.redAdd(this.d.redMul(x2).redMul(y2))); -function base64DetectIncompleteChar(buffer) { - this.charReceived = buffer.length % 3; - this.charLength = this.charReceived ? 3 : 0; -} + return lhs.cmp(rhs) === 0; +}; -},{"buffer":42}],202:[function(require,module,exports){ -// Copyright Joyent, Inc. and other Node contributors. -// -// Permission is hereby granted, free of charge, to any person obtaining a -// copy of this software and associated documentation files (the -// "Software"), to deal in the Software without restriction, including -// without limitation the rights to use, copy, modify, merge, publish, -// distribute, sublicense, and/or sell copies of the Software, and to permit -// persons to whom the Software is furnished to do so, subject to the -// following conditions: -// -// The above copyright notice and this permission notice shall be included -// in all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS -// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN -// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, -// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR -// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE -// USE OR OTHER DEALINGS IN THE SOFTWARE. - -var punycode = require('punycode'); - -exports.parse = urlParse; -exports.resolve = urlResolve; -exports.resolveObject = urlResolveObject; -exports.format = urlFormat; - -exports.Url = Url; - -function Url() { - this.protocol = null; - this.slashes = null; - this.auth = null; - this.host = null; - this.port = null; - this.hostname = null; - this.hash = null; - this.search = null; - this.query = null; - this.pathname = null; - this.path = null; - this.href = null; -} - -// Reference: RFC 3986, RFC 1808, RFC 2396 - -// define these here so at least they only have to be -// compiled once on the first module load. -var protocolPattern = /^([a-z0-9.+-]+:)/i, - portPattern = /:[0-9]*$/, - - // RFC 2396: characters reserved for delimiting URLs. - // We actually just auto-escape these. - delims = ['<', '>', '"', '`', ' ', '\r', '\n', '\t'], - - // RFC 2396: characters not allowed for various reasons. - unwise = ['{', '}', '|', '\\', '^', '`'].concat(delims), - - // Allowed by RFCs, but cause of XSS attacks. Always escape these. - autoEscape = ['\''].concat(unwise), - // Characters that are never ever allowed in a hostname. - // Note that any invalid chars are also handled, but these - // are the ones that are *expected* to be seen, so we fast-path - // them. - nonHostChars = ['%', '/', '?', ';', '#'].concat(autoEscape), - hostEndingChars = ['/', '?', '#'], - hostnameMaxLen = 255, - hostnamePartPattern = /^[a-z0-9A-Z_-]{0,63}$/, - hostnamePartStart = /^([a-z0-9A-Z_-]{0,63})(.*)$/, - // protocols that can allow "unsafe" and "unwise" chars. - unsafeProtocol = { - 'javascript': true, - 'javascript:': true - }, - // protocols that never have a hostname. - hostlessProtocol = { - 'javascript': true, - 'javascript:': true - }, - // protocols that always contain a // bit. - slashedProtocol = { - 'http': true, - 'https': true, - 'ftp': true, - 'gopher': true, - 'file': true, - 'http:': true, - 'https:': true, - 'ftp:': true, - 'gopher:': true, - 'file:': true - }, - querystring = require('querystring'); - -function urlParse(url, parseQueryString, slashesDenoteHost) { - if (url && isObject(url) && url instanceof Url) return url; - - var u = new Url; - u.parse(url, parseQueryString, slashesDenoteHost); - return u; -} - -Url.prototype.parse = function(url, parseQueryString, slashesDenoteHost) { - if (!isString(url)) { - throw new TypeError("Parameter 'url' must be a string, not " + typeof url); - } - - var rest = url; - - // trim before proceeding. - // This is to support parse stuff like " http://foo.com \n" - rest = rest.trim(); - - var proto = protocolPattern.exec(rest); - if (proto) { - proto = proto[0]; - var lowerProto = proto.toLowerCase(); - this.protocol = lowerProto; - rest = rest.substr(proto.length); - } - - // figure out if it's got a host - // user@server is *always* interpreted as a hostname, and url - // resolution will treat //foo/bar as host=foo,path=bar because that's - // how the browser resolves relative URLs. - if (slashesDenoteHost || proto || rest.match(/^\/\/[^@\/]+@[^@\/]+/)) { - var slashes = rest.substr(0, 2) === '//'; - if (slashes && !(proto && hostlessProtocol[proto])) { - rest = rest.substr(2); - this.slashes = true; - } - } - - if (!hostlessProtocol[proto] && - (slashes || (proto && !slashedProtocol[proto]))) { - - // there's a hostname. - // the first instance of /, ?, ;, or # ends the host. - // - // If there is an @ in the hostname, then non-host chars *are* allowed - // to the left of the last @ sign, unless some host-ending character - // comes *before* the @-sign. - // URLs are obnoxious. - // - // ex: - // http://a@b@c/ => user:a@b host:c - // http://a@b?@c => user:a host:c path:/?@c - - // v0.12 TODO(isaacs): This is not quite how Chrome does things. - // Review our test case against browsers more comprehensively. - - // find the first instance of any hostEndingChars - var hostEnd = -1; - for (var i = 0; i < hostEndingChars.length; i++) { - var hec = rest.indexOf(hostEndingChars[i]); - if (hec !== -1 && (hostEnd === -1 || hec < hostEnd)) - hostEnd = hec; - } - - // at this point, either we have an explicit point where the - // auth portion cannot go past, or the last @ char is the decider. - var auth, atSign; - if (hostEnd === -1) { - // atSign can be anywhere. - atSign = rest.lastIndexOf('@'); - } else { - // atSign must be in auth portion. - // http://a@b/c@d => host:b auth:a path:/c@d - atSign = rest.lastIndexOf('@', hostEnd); - } - - // Now we have a portion which is definitely the auth. - // Pull that off. - if (atSign !== -1) { - auth = rest.slice(0, atSign); - rest = rest.slice(atSign + 1); - this.auth = decodeURIComponent(auth); - } - - // the host is the remaining to the left of the first non-host char - hostEnd = -1; - for (var i = 0; i < nonHostChars.length; i++) { - var hec = rest.indexOf(nonHostChars[i]); - if (hec !== -1 && (hostEnd === -1 || hec < hostEnd)) - hostEnd = hec; - } - // if we still have not hit it, then the entire thing is a host. - if (hostEnd === -1) - hostEnd = rest.length; - - this.host = rest.slice(0, hostEnd); - rest = rest.slice(hostEnd); - - // pull out port. - this.parseHost(); - - // we've indicated that there is a hostname, - // so even if it's empty, it has to be present. - this.hostname = this.hostname || ''; - - // if hostname begins with [ and ends with ] - // assume that it's an IPv6 address. - var ipv6Hostname = this.hostname[0] === '[' && - this.hostname[this.hostname.length - 1] === ']'; - - // validate a little. - if (!ipv6Hostname) { - var hostparts = this.hostname.split(/\./); - for (var i = 0, l = hostparts.length; i < l; i++) { - var part = hostparts[i]; - if (!part) continue; - if (!part.match(hostnamePartPattern)) { - var newpart = ''; - for (var j = 0, k = part.length; j < k; j++) { - if (part.charCodeAt(j) > 127) { - // we replace non-ASCII char with a temporary placeholder - // we need this to make sure size of hostname is not - // broken by replacing non-ASCII by nothing - newpart += 'x'; - } else { - newpart += part[j]; - } - } - // we test again with ASCII char only - if (!newpart.match(hostnamePartPattern)) { - var validParts = hostparts.slice(0, i); - var notHost = hostparts.slice(i + 1); - var bit = part.match(hostnamePartStart); - if (bit) { - validParts.push(bit[1]); - notHost.unshift(bit[2]); - } - if (notHost.length) { - rest = '/' + notHost.join('.') + rest; - } - this.hostname = validParts.join('.'); - break; - } - } - } - } - - if (this.hostname.length > hostnameMaxLen) { - this.hostname = ''; - } else { - // hostnames are always lower case. - this.hostname = this.hostname.toLowerCase(); - } - - if (!ipv6Hostname) { - // IDNA Support: Returns a puny coded representation of "domain". - // It only converts the part of the domain name that - // has non ASCII characters. I.e. it dosent matter if - // you call it with a domain that already is in ASCII. - var domainArray = this.hostname.split('.'); - var newOut = []; - for (var i = 0; i < domainArray.length; ++i) { - var s = domainArray[i]; - newOut.push(s.match(/[^A-Za-z0-9_-]/) ? - 'xn--' + punycode.encode(s) : s); - } - this.hostname = newOut.join('.'); - } - - var p = this.port ? ':' + this.port : ''; - var h = this.hostname || ''; - this.host = h + p; - this.href += this.host; - - // strip [ and ] from the hostname - // the host field still retains them, though - if (ipv6Hostname) { - this.hostname = this.hostname.substr(1, this.hostname.length - 2); - if (rest[0] !== '/') { - rest = '/' + rest; - } - } - } - - // now rest is set to the post-host stuff. - // chop off any delim chars. - if (!unsafeProtocol[lowerProto]) { - - // First, make 100% sure that any "autoEscape" chars get - // escaped, even if encodeURIComponent doesn't think they - // need to be. - for (var i = 0, l = autoEscape.length; i < l; i++) { - var ae = autoEscape[i]; - var esc = encodeURIComponent(ae); - if (esc === ae) { - esc = escape(ae); - } - rest = rest.split(ae).join(esc); - } - } - - - // chop off from the tail first. - var hash = rest.indexOf('#'); - if (hash !== -1) { - // got a fragment string. - this.hash = rest.substr(hash); - rest = rest.slice(0, hash); - } - var qm = rest.indexOf('?'); - if (qm !== -1) { - this.search = rest.substr(qm); - this.query = rest.substr(qm + 1); - if (parseQueryString) { - this.query = querystring.parse(this.query); - } - rest = rest.slice(0, qm); - } else if (parseQueryString) { - // no query string, but parseQueryString still requested - this.search = ''; - this.query = {}; - } - if (rest) this.pathname = rest; - if (slashedProtocol[lowerProto] && - this.hostname && !this.pathname) { - this.pathname = '/'; - } - - //to support http.request - if (this.pathname || this.search) { - var p = this.pathname || ''; - var s = this.search || ''; - this.path = p + s; - } - - // finally, reconstruct the href based on what has been validated. - this.href = this.format(); - return this; -}; - -// format a parsed object into a url string -function urlFormat(obj) { - // ensure it's an object, and not a string url. - // If it's an obj, this is a no-op. - // this way, you can call url_format() on strings - // to clean up potentially wonky urls. - if (isString(obj)) obj = urlParse(obj); - if (!(obj instanceof Url)) return Url.prototype.format.call(obj); - return obj.format(); -} - -Url.prototype.format = function() { - var auth = this.auth || ''; - if (auth) { - auth = encodeURIComponent(auth); - auth = auth.replace(/%3A/i, ':'); - auth += '@'; - } - - var protocol = this.protocol || '', - pathname = this.pathname || '', - hash = this.hash || '', - host = false, - query = ''; - - if (this.host) { - host = auth + this.host; - } else if (this.hostname) { - host = auth + (this.hostname.indexOf(':') === -1 ? - this.hostname : - '[' + this.hostname + ']'); - if (this.port) { - host += ':' + this.port; - } - } - - if (this.query && - isObject(this.query) && - Object.keys(this.query).length) { - query = querystring.stringify(this.query); - } - - var search = this.search || (query && ('?' + query)) || ''; - - if (protocol && protocol.substr(-1) !== ':') protocol += ':'; - - // only the slashedProtocols get the //. Not mailto:, xmpp:, etc. - // unless they had them to begin with. - if (this.slashes || - (!protocol || slashedProtocol[protocol]) && host !== false) { - host = '//' + (host || ''); - if (pathname && pathname.charAt(0) !== '/') pathname = '/' + pathname; - } else if (!host) { - host = ''; - } - - if (hash && hash.charAt(0) !== '#') hash = '#' + hash; - if (search && search.charAt(0) !== '?') search = '?' + search; - - pathname = pathname.replace(/[?#]/g, function(match) { - return encodeURIComponent(match); - }); - search = search.replace('#', '%23'); - - return protocol + host + pathname + search + hash; -}; - -function urlResolve(source, relative) { - return urlParse(source, false, true).resolve(relative); -} - -Url.prototype.resolve = function(relative) { - return this.resolveObject(urlParse(relative, false, true)).format(); -}; - -function urlResolveObject(source, relative) { - if (!source) return relative; - return urlParse(source, false, true).resolveObject(relative); -} - -Url.prototype.resolveObject = function(relative) { - if (isString(relative)) { - var rel = new Url(); - rel.parse(relative, false, true); - relative = rel; - } - - var result = new Url(); - Object.keys(this).forEach(function(k) { - result[k] = this[k]; - }, this); - - // hash is always overridden, no matter what. - // even href="" will remove it. - result.hash = relative.hash; - - // if the relative url is empty, then there's nothing left to do here. - if (relative.href === '') { - result.href = result.format(); - return result; - } - - // hrefs like //foo/bar always cut to the protocol. - if (relative.slashes && !relative.protocol) { - // take everything except the protocol from relative - Object.keys(relative).forEach(function(k) { - if (k !== 'protocol') - result[k] = relative[k]; - }); - - //urlParse appends trailing / to urls like http://www.example.com - if (slashedProtocol[result.protocol] && - result.hostname && !result.pathname) { - result.path = result.pathname = '/'; - } - - result.href = result.format(); - return result; - } - - if (relative.protocol && relative.protocol !== result.protocol) { - // if it's a known url protocol, then changing - // the protocol does weird things - // first, if it's not file:, then we MUST have a host, - // and if there was a path - // to begin with, then we MUST have a path. - // if it is file:, then the host is dropped, - // because that's known to be hostless. - // anything else is assumed to be absolute. - if (!slashedProtocol[relative.protocol]) { - Object.keys(relative).forEach(function(k) { - result[k] = relative[k]; - }); - result.href = result.format(); - return result; - } - - result.protocol = relative.protocol; - if (!relative.host && !hostlessProtocol[relative.protocol]) { - var relPath = (relative.pathname || '').split('/'); - while (relPath.length && !(relative.host = relPath.shift())); - if (!relative.host) relative.host = ''; - if (!relative.hostname) relative.hostname = ''; - if (relPath[0] !== '') relPath.unshift(''); - if (relPath.length < 2) relPath.unshift(''); - result.pathname = relPath.join('/'); - } else { - result.pathname = relative.pathname; - } - result.search = relative.search; - result.query = relative.query; - result.host = relative.host || ''; - result.auth = relative.auth; - result.hostname = relative.hostname || relative.host; - result.port = relative.port; - // to support http.request - if (result.pathname || result.search) { - var p = result.pathname || ''; - var s = result.search || ''; - result.path = p + s; - } - result.slashes = result.slashes || relative.slashes; - result.href = result.format(); - return result; - } - - var isSourceAbs = (result.pathname && result.pathname.charAt(0) === '/'), - isRelAbs = ( - relative.host || - relative.pathname && relative.pathname.charAt(0) === '/' - ), - mustEndAbs = (isRelAbs || isSourceAbs || - (result.host && relative.pathname)), - removeAllDots = mustEndAbs, - srcPath = result.pathname && result.pathname.split('/') || [], - relPath = relative.pathname && relative.pathname.split('/') || [], - psychotic = result.protocol && !slashedProtocol[result.protocol]; - - // if the url is a non-slashed url, then relative - // links like ../.. should be able - // to crawl up to the hostname, as well. This is strange. - // result.protocol has already been set by now. - // Later on, put the first path part into the host field. - if (psychotic) { - result.hostname = ''; - result.port = null; - if (result.host) { - if (srcPath[0] === '') srcPath[0] = result.host; - else srcPath.unshift(result.host); - } - result.host = ''; - if (relative.protocol) { - relative.hostname = null; - relative.port = null; - if (relative.host) { - if (relPath[0] === '') relPath[0] = relative.host; - else relPath.unshift(relative.host); - } - relative.host = null; - } - mustEndAbs = mustEndAbs && (relPath[0] === '' || srcPath[0] === ''); - } - - if (isRelAbs) { - // it's absolute. - result.host = (relative.host || relative.host === '') ? - relative.host : result.host; - result.hostname = (relative.hostname || relative.hostname === '') ? - relative.hostname : result.hostname; - result.search = relative.search; - result.query = relative.query; - srcPath = relPath; - // fall through to the dot-handling below. - } else if (relPath.length) { - // it's relative - // throw away the existing file, and take the new path instead. - if (!srcPath) srcPath = []; - srcPath.pop(); - srcPath = srcPath.concat(relPath); - result.search = relative.search; - result.query = relative.query; - } else if (!isNullOrUndefined(relative.search)) { - // just pull out the search. - // like href='?foo'. - // Put this after the other two cases because it simplifies the booleans - if (psychotic) { - result.hostname = result.host = srcPath.shift(); - //occationaly the auth can get stuck only in host - //this especialy happens in cases like - //url.resolveObject('mailto:local1@domain1', 'local2@domain2') - var authInHost = result.host && result.host.indexOf('@') > 0 ? - result.host.split('@') : false; - if (authInHost) { - result.auth = authInHost.shift(); - result.host = result.hostname = authInHost.shift(); - } - } - result.search = relative.search; - result.query = relative.query; - //to support http.request - if (!isNull(result.pathname) || !isNull(result.search)) { - result.path = (result.pathname ? result.pathname : '') + - (result.search ? result.search : ''); - } - result.href = result.format(); - return result; - } - - if (!srcPath.length) { - // no path at all. easy. - // we've already handled the other stuff above. - result.pathname = null; - //to support http.request - if (result.search) { - result.path = '/' + result.search; - } else { - result.path = null; - } - result.href = result.format(); - return result; - } - - // if a url ENDs in . or .., then it must get a trailing slash. - // however, if it ends in anything else non-slashy, - // then it must NOT get a trailing slash. - var last = srcPath.slice(-1)[0]; - var hasTrailingSlash = ( - (result.host || relative.host) && (last === '.' || last === '..') || - last === ''); - - // strip single dots, resolve double dots to parent dir - // if the path tries to go above the root, `up` ends up > 0 - var up = 0; - for (var i = srcPath.length; i >= 0; i--) { - last = srcPath[i]; - if (last == '.') { - srcPath.splice(i, 1); - } else if (last === '..') { - srcPath.splice(i, 1); - up++; - } else if (up) { - srcPath.splice(i, 1); - up--; - } - } - - // if the path is allowed to go above the root, restore leading ..s - if (!mustEndAbs && !removeAllDots) { - for (; up--; up) { - srcPath.unshift('..'); - } - } - - if (mustEndAbs && srcPath[0] !== '' && - (!srcPath[0] || srcPath[0].charAt(0) !== '/')) { - srcPath.unshift(''); - } - - if (hasTrailingSlash && (srcPath.join('/').substr(-1) !== '/')) { - srcPath.push(''); - } - - var isAbsolute = srcPath[0] === '' || - (srcPath[0] && srcPath[0].charAt(0) === '/'); - - // put the host back - if (psychotic) { - result.hostname = result.host = isAbsolute ? '' : - srcPath.length ? srcPath.shift() : ''; - //occationaly the auth can get stuck only in host - //this especialy happens in cases like - //url.resolveObject('mailto:local1@domain1', 'local2@domain2') - var authInHost = result.host && result.host.indexOf('@') > 0 ? - result.host.split('@') : false; - if (authInHost) { - result.auth = authInHost.shift(); - result.host = result.hostname = authInHost.shift(); - } - } - - mustEndAbs = mustEndAbs || (result.host && srcPath.length); - - if (mustEndAbs && !isAbsolute) { - srcPath.unshift(''); - } - - if (!srcPath.length) { - result.pathname = null; - result.path = null; - } else { - result.pathname = srcPath.join('/'); - } - - //to support request.http - if (!isNull(result.pathname) || !isNull(result.search)) { - result.path = (result.pathname ? result.pathname : '') + - (result.search ? result.search : ''); - } - result.auth = relative.auth || result.auth; - result.slashes = result.slashes || relative.slashes; - result.href = result.format(); - return result; -}; - -Url.prototype.parseHost = function() { - var host = this.host; - var port = portPattern.exec(host); - if (port) { - port = port[0]; - if (port !== ':') { - this.port = port.substr(1); - } - host = host.substr(0, host.length - port.length); - } - if (host) this.hostname = host; -}; - -function isString(arg) { - return typeof arg === "string"; -} - -function isObject(arg) { - return typeof arg === 'object' && arg !== null; -} - -function isNull(arg) { - return arg === null; -} -function isNullOrUndefined(arg) { - return arg == null; -} - -},{"punycode":185,"querystring":188}],203:[function(require,module,exports){ -module.exports = function isBuffer(arg) { - return arg && typeof arg === 'object' - && typeof arg.copy === 'function' - && typeof arg.fill === 'function' - && typeof arg.readUInt8 === 'function'; -} -},{}],204:[function(require,module,exports){ -(function (process,global){ -// Copyright Joyent, Inc. and other Node contributors. -// -// Permission is hereby granted, free of charge, to any person obtaining a -// copy of this software and associated documentation files (the -// "Software"), to deal in the Software without restriction, including -// without limitation the rights to use, copy, modify, merge, publish, -// distribute, sublicense, and/or sell copies of the Software, and to permit -// persons to whom the Software is furnished to do so, subject to the -// following conditions: -// -// The above copyright notice and this permission notice shall be included -// in all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS -// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN -// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, -// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR -// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE -// USE OR OTHER DEALINGS IN THE SOFTWARE. - -var formatRegExp = /%[sdj%]/g; -exports.format = function(f) { - if (!isString(f)) { - var objects = []; - for (var i = 0; i < arguments.length; i++) { - objects.push(inspect(arguments[i])); - } - return objects.join(' '); - } - - var i = 1; - var args = arguments; - var len = args.length; - var str = String(f).replace(formatRegExp, function(x) { - if (x === '%%') return '%'; - if (i >= len) return x; - switch (x) { - case '%s': return String(args[i++]); - case '%d': return Number(args[i++]); - case '%j': - try { - return JSON.stringify(args[i++]); - } catch (_) { - return '[Circular]'; - } - default: - return x; - } - }); - for (var x = args[i]; i < len; x = args[++i]) { - if (isNull(x) || !isObject(x)) { - str += ' ' + x; - } else { - str += ' ' + inspect(x); - } - } - return str; -}; - - -// Mark that a method should not be used. -// Returns a modified function which warns once by default. -// If --no-deprecation is set, then it is a no-op. -exports.deprecate = function(fn, msg) { - // Allow for deprecating things in the process of starting up. - if (isUndefined(global.process)) { - return function() { - return exports.deprecate(fn, msg).apply(this, arguments); - }; - } - - if (process.noDeprecation === true) { - return fn; - } - - var warned = false; - function deprecated() { - if (!warned) { - if (process.throwDeprecation) { - throw new Error(msg); - } else if (process.traceDeprecation) { - console.trace(msg); - } else { - console.error(msg); - } - warned = true; - } - return fn.apply(this, arguments); - } - - return deprecated; -}; - - -var debugs = {}; -var debugEnviron; -exports.debuglog = function(set) { - if (isUndefined(debugEnviron)) - debugEnviron = process.env.NODE_DEBUG || ''; - set = set.toUpperCase(); - if (!debugs[set]) { - if (new RegExp('\\b' + set + '\\b', 'i').test(debugEnviron)) { - var pid = process.pid; - debugs[set] = function() { - var msg = exports.format.apply(exports, arguments); - console.error('%s %d: %s', set, pid, msg); - }; - } else { - debugs[set] = function() {}; - } - } - return debugs[set]; -}; - - -/** - * Echos the value of a value. Trys to print the value out - * in the best way possible given the different types. - * - * @param {Object} obj The object to print out. - * @param {Object} opts Optional options object that alters the output. - */ -/* legacy: obj, showHidden, depth, colors*/ -function inspect(obj, opts) { - // default options - var ctx = { - seen: [], - stylize: stylizeNoColor - }; - // legacy... - if (arguments.length >= 3) ctx.depth = arguments[2]; - if (arguments.length >= 4) ctx.colors = arguments[3]; - if (isBoolean(opts)) { - // legacy... - ctx.showHidden = opts; - } else if (opts) { - // got an "options" object - exports._extend(ctx, opts); - } - // set default options - if (isUndefined(ctx.showHidden)) ctx.showHidden = false; - if (isUndefined(ctx.depth)) ctx.depth = 2; - if (isUndefined(ctx.colors)) ctx.colors = false; - if (isUndefined(ctx.customInspect)) ctx.customInspect = true; - if (ctx.colors) ctx.stylize = stylizeWithColor; - return formatValue(ctx, obj, ctx.depth); -} -exports.inspect = inspect; - - -// http://en.wikipedia.org/wiki/ANSI_escape_code#graphics -inspect.colors = { - 'bold' : [1, 22], - 'italic' : [3, 23], - 'underline' : [4, 24], - 'inverse' : [7, 27], - 'white' : [37, 39], - 'grey' : [90, 39], - 'black' : [30, 39], - 'blue' : [34, 39], - 'cyan' : [36, 39], - 'green' : [32, 39], - 'magenta' : [35, 39], - 'red' : [31, 39], - 'yellow' : [33, 39] -}; - -// Don't use 'blue' not visible on cmd.exe -inspect.styles = { - 'special': 'cyan', - 'number': 'yellow', - 'boolean': 'yellow', - 'undefined': 'grey', - 'null': 'bold', - 'string': 'green', - 'date': 'magenta', - // "name": intentionally not styling - 'regexp': 'red' -}; - - -function stylizeWithColor(str, styleType) { - var style = inspect.styles[styleType]; - - if (style) { - return '\u001b[' + inspect.colors[style][0] + 'm' + str + - '\u001b[' + inspect.colors[style][1] + 'm'; - } else { - return str; - } -} - - -function stylizeNoColor(str, styleType) { - return str; -} - - -function arrayToHash(array) { - var hash = {}; - - array.forEach(function(val, idx) { - hash[val] = true; - }); - - return hash; -} - - -function formatValue(ctx, value, recurseTimes) { - // Provide a hook for user-specified inspect functions. - // Check that value is an object with an inspect function on it - if (ctx.customInspect && - value && - isFunction(value.inspect) && - // Filter out the util module, it's inspect function is special - value.inspect !== exports.inspect && - // Also filter out any prototype objects using the circular check. - !(value.constructor && value.constructor.prototype === value)) { - var ret = value.inspect(recurseTimes, ctx); - if (!isString(ret)) { - ret = formatValue(ctx, ret, recurseTimes); - } - return ret; - } - - // Primitive types cannot have properties - var primitive = formatPrimitive(ctx, value); - if (primitive) { - return primitive; - } - - // Look up the keys of the object. - var keys = Object.keys(value); - var visibleKeys = arrayToHash(keys); - - if (ctx.showHidden) { - keys = Object.getOwnPropertyNames(value); - } - - // IE doesn't make error fields non-enumerable - // http://msdn.microsoft.com/en-us/library/ie/dww52sbt(v=vs.94).aspx - if (isError(value) - && (keys.indexOf('message') >= 0 || keys.indexOf('description') >= 0)) { - return formatError(value); - } - - // Some type of object without properties can be shortcutted. - if (keys.length === 0) { - if (isFunction(value)) { - var name = value.name ? ': ' + value.name : ''; - return ctx.stylize('[Function' + name + ']', 'special'); - } - if (isRegExp(value)) { - return ctx.stylize(RegExp.prototype.toString.call(value), 'regexp'); - } - if (isDate(value)) { - return ctx.stylize(Date.prototype.toString.call(value), 'date'); - } - if (isError(value)) { - return formatError(value); - } - } - - var base = '', array = false, braces = ['{', '}']; - - // Make Array say that they are Array - if (isArray(value)) { - array = true; - braces = ['[', ']']; - } - - // Make functions say that they are functions - if (isFunction(value)) { - var n = value.name ? ': ' + value.name : ''; - base = ' [Function' + n + ']'; - } - - // Make RegExps say that they are RegExps - if (isRegExp(value)) { - base = ' ' + RegExp.prototype.toString.call(value); - } - - // Make dates with properties first say the date - if (isDate(value)) { - base = ' ' + Date.prototype.toUTCString.call(value); - } - - // Make error with message first say the error - if (isError(value)) { - base = ' ' + formatError(value); - } - - if (keys.length === 0 && (!array || value.length == 0)) { - return braces[0] + base + braces[1]; - } - - if (recurseTimes < 0) { - if (isRegExp(value)) { - return ctx.stylize(RegExp.prototype.toString.call(value), 'regexp'); - } else { - return ctx.stylize('[Object]', 'special'); - } - } - - ctx.seen.push(value); - - var output; - if (array) { - output = formatArray(ctx, value, recurseTimes, visibleKeys, keys); - } else { - output = keys.map(function(key) { - return formatProperty(ctx, value, recurseTimes, visibleKeys, key, array); - }); - } - - ctx.seen.pop(); - - return reduceToSingleString(output, base, braces); -} - - -function formatPrimitive(ctx, value) { - if (isUndefined(value)) - return ctx.stylize('undefined', 'undefined'); - if (isString(value)) { - var simple = '\'' + JSON.stringify(value).replace(/^"|"$/g, '') - .replace(/'/g, "\\'") - .replace(/\\"/g, '"') + '\''; - return ctx.stylize(simple, 'string'); - } - if (isNumber(value)) - return ctx.stylize('' + value, 'number'); - if (isBoolean(value)) - return ctx.stylize('' + value, 'boolean'); - // For some reason typeof null is "object", so special case here. - if (isNull(value)) - return ctx.stylize('null', 'null'); -} - - -function formatError(value) { - return '[' + Error.prototype.toString.call(value) + ']'; -} - - -function formatArray(ctx, value, recurseTimes, visibleKeys, keys) { - var output = []; - for (var i = 0, l = value.length; i < l; ++i) { - if (hasOwnProperty(value, String(i))) { - output.push(formatProperty(ctx, value, recurseTimes, visibleKeys, - String(i), true)); - } else { - output.push(''); - } - } - keys.forEach(function(key) { - if (!key.match(/^\d+$/)) { - output.push(formatProperty(ctx, value, recurseTimes, visibleKeys, - key, true)); - } - }); - return output; -} - - -function formatProperty(ctx, value, recurseTimes, visibleKeys, key, array) { - var name, str, desc; - desc = Object.getOwnPropertyDescriptor(value, key) || { value: value[key] }; - if (desc.get) { - if (desc.set) { - str = ctx.stylize('[Getter/Setter]', 'special'); - } else { - str = ctx.stylize('[Getter]', 'special'); - } - } else { - if (desc.set) { - str = ctx.stylize('[Setter]', 'special'); - } - } - if (!hasOwnProperty(visibleKeys, key)) { - name = '[' + key + ']'; - } - if (!str) { - if (ctx.seen.indexOf(desc.value) < 0) { - if (isNull(recurseTimes)) { - str = formatValue(ctx, desc.value, null); - } else { - str = formatValue(ctx, desc.value, recurseTimes - 1); - } - if (str.indexOf('\n') > -1) { - if (array) { - str = str.split('\n').map(function(line) { - return ' ' + line; - }).join('\n').substr(2); - } else { - str = '\n' + str.split('\n').map(function(line) { - return ' ' + line; - }).join('\n'); - } - } - } else { - str = ctx.stylize('[Circular]', 'special'); - } - } - if (isUndefined(name)) { - if (array && key.match(/^\d+$/)) { - return str; - } - name = JSON.stringify('' + key); - if (name.match(/^"([a-zA-Z_][a-zA-Z_0-9]*)"$/)) { - name = name.substr(1, name.length - 2); - name = ctx.stylize(name, 'name'); - } else { - name = name.replace(/'/g, "\\'") - .replace(/\\"/g, '"') - .replace(/(^"|"$)/g, "'"); - name = ctx.stylize(name, 'string'); - } - } - - return name + ': ' + str; -} - - -function reduceToSingleString(output, base, braces) { - var numLinesEst = 0; - var length = output.reduce(function(prev, cur) { - numLinesEst++; - if (cur.indexOf('\n') >= 0) numLinesEst++; - return prev + cur.replace(/\u001b\[\d\d?m/g, '').length + 1; - }, 0); +function Point(curve, x, y, z, t) { + Base.BasePoint.call(this, curve, 'projective'); + if (x === null && y === null && z === null) { + this.x = this.curve.zero; + this.y = this.curve.one; + this.z = this.curve.one; + this.t = this.curve.zero; + this.zOne = true; + } else { + this.x = new bn(x, 16); + this.y = new bn(y, 16); + this.z = z ? new bn(z, 16) : this.curve.one; + this.t = t && new bn(t, 16); + if (!this.x.red) + this.x = this.x.toRed(this.curve.red); + if (!this.y.red) + this.y = this.y.toRed(this.curve.red); + if (!this.z.red) + this.z = this.z.toRed(this.curve.red); + if (this.t && !this.t.red) + this.t = this.t.toRed(this.curve.red); + this.zOne = this.z === this.curve.one; - if (length > 60) { - return braces[0] + - (base === '' ? '' : base + '\n ') + - ' ' + - output.join(',\n ') + - ' ' + - braces[1]; + // Use extended coordinates + if (this.curve.extended && !this.t) { + this.t = this.x.redMul(this.y); + if (!this.zOne) + this.t = this.t.redMul(this.z.redInvm()); + } } - - return braces[0] + base + ' ' + output.join(', ') + ' ' + braces[1]; -} - - -// NOTE: These type checking functions intentionally don't use `instanceof` -// because it is fragile and can be easily faked with `Object.create()`. -function isArray(ar) { - return Array.isArray(ar); -} -exports.isArray = isArray; - -function isBoolean(arg) { - return typeof arg === 'boolean'; -} -exports.isBoolean = isBoolean; - -function isNull(arg) { - return arg === null; -} -exports.isNull = isNull; - -function isNullOrUndefined(arg) { - return arg == null; -} -exports.isNullOrUndefined = isNullOrUndefined; - -function isNumber(arg) { - return typeof arg === 'number'; -} -exports.isNumber = isNumber; - -function isString(arg) { - return typeof arg === 'string'; -} -exports.isString = isString; - -function isSymbol(arg) { - return typeof arg === 'symbol'; -} -exports.isSymbol = isSymbol; - -function isUndefined(arg) { - return arg === void 0; -} -exports.isUndefined = isUndefined; - -function isRegExp(re) { - return isObject(re) && objectToString(re) === '[object RegExp]'; -} -exports.isRegExp = isRegExp; - -function isObject(arg) { - return typeof arg === 'object' && arg !== null; -} -exports.isObject = isObject; - -function isDate(d) { - return isObject(d) && objectToString(d) === '[object Date]'; -} -exports.isDate = isDate; - -function isError(e) { - return isObject(e) && - (objectToString(e) === '[object Error]' || e instanceof Error); -} -exports.isError = isError; - -function isFunction(arg) { - return typeof arg === 'function'; -} -exports.isFunction = isFunction; - -function isPrimitive(arg) { - return arg === null || - typeof arg === 'boolean' || - typeof arg === 'number' || - typeof arg === 'string' || - typeof arg === 'symbol' || // ES6 symbol - typeof arg === 'undefined'; -} -exports.isPrimitive = isPrimitive; - -exports.isBuffer = require('./support/isBuffer'); - -function objectToString(o) { - return Object.prototype.toString.call(o); -} - - -function pad(n) { - return n < 10 ? '0' + n.toString(10) : n.toString(10); } +inherits(Point, Base.BasePoint); +EdwardsCurve.prototype.pointFromJSON = function pointFromJSON(obj) { + return Point.fromJSON(this, obj); +}; -var months = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', - 'Oct', 'Nov', 'Dec']; - -// 26 Feb 16:19:34 -function timestamp() { - var d = new Date(); - var time = [pad(d.getHours()), - pad(d.getMinutes()), - pad(d.getSeconds())].join(':'); - return [d.getDate(), months[d.getMonth()], time].join(' '); -} - +EdwardsCurve.prototype.point = function point(x, y, z, t) { + return new Point(this, x, y, z, t); +}; -// log is just a thin wrapper to console.log that prepends a timestamp -exports.log = function() { - console.log('%s - %s', timestamp(), exports.format.apply(exports, arguments)); +Point.fromJSON = function fromJSON(curve, obj) { + return new Point(curve, obj[0], obj[1], obj[2]); }; +Point.prototype.inspect = function inspect() { + if (this.isInfinity()) + return ''; + return ''; +}; -/** - * Inherit the prototype methods from one constructor into another. - * - * The Function.prototype.inherits from lang.js rewritten as a standalone - * function (not on Function.prototype). NOTE: If this file is to be loaded - * during bootstrapping this function needs to be rewritten using some native - * functions as prototype setup using normal JavaScript does not work as - * expected during bootstrapping (see mirror.js in r114903). - * - * @param {function} ctor Constructor function which needs to inherit the - * prototype. - * @param {function} superCtor Constructor function to inherit prototype from. - */ -exports.inherits = require('inherits'); +Point.prototype.isInfinity = function isInfinity() { + // XXX This code assumes that zero is always zero in red + return this.x.cmpn(0) === 0 && + this.y.cmp(this.z) === 0; +}; -exports._extend = function(origin, add) { - // Don't do anything if add isn't an object - if (!add || !isObject(add)) return origin; +Point.prototype._extDbl = function _extDbl() { + // hyperelliptic.org/EFD/g1p/auto-twisted-extended-1.html + // #doubling-dbl-2008-hwcd + // 4M + 4S - var keys = Object.keys(add); - var i = keys.length; - while (i--) { - origin[keys[i]] = add[keys[i]]; - } - return origin; + // A = X1^2 + var a = this.x.redSqr(); + // B = Y1^2 + var b = this.y.redSqr(); + // C = 2 * Z1^2 + var c = this.z.redSqr(); + c = c.redIAdd(c); + // D = a * A + var d = this.curve._mulA(a); + // E = (X1 + Y1)^2 - A - B + var e = this.x.redAdd(this.y).redSqr().redISub(a).redISub(b); + // G = D + B + var g = d.redAdd(b); + // F = G - C + var f = g.redSub(c); + // H = D - B + var h = d.redSub(b); + // X3 = E * F + var nx = e.redMul(f); + // Y3 = G * H + var ny = g.redMul(h); + // T3 = E * H + var nt = e.redMul(h); + // Z3 = F * G + var nz = f.redMul(g); + return this.curve.point(nx, ny, nz, nt); }; -function hasOwnProperty(obj, prop) { - return Object.prototype.hasOwnProperty.call(obj, prop); -} - -}).call(this,require('_process'),typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}) -},{"./support/isBuffer":203,"_process":184,"inherits":229}],205:[function(require,module,exports){ -var indexOf = require('indexof'); +Point.prototype._projDbl = function _projDbl() { + // hyperelliptic.org/EFD/g1p/auto-twisted-projective.html + // #doubling-dbl-2008-bbjlp + // #doubling-dbl-2007-bl + // and others + // Generally 3M + 4S or 2M + 4S -var Object_keys = function (obj) { - if (Object.keys) return Object.keys(obj) - else { - var res = []; - for (var key in obj) res.push(key) - return res; - } -}; + // B = (X1 + Y1)^2 + var b = this.x.redAdd(this.y).redSqr(); + // C = X1^2 + var c = this.x.redSqr(); + // D = Y1^2 + var d = this.y.redSqr(); -var forEach = function (xs, fn) { - if (xs.forEach) return xs.forEach(fn) - else for (var i = 0; i < xs.length; i++) { - fn(xs[i], i, xs); + var nx; + var ny; + var nz; + if (this.curve.twisted) { + // E = a * C + var e = this.curve._mulA(c); + // F = E + D + var f = e.redAdd(d); + if (this.zOne) { + // X3 = (B - C - D) * (F - 2) + nx = b.redSub(c).redSub(d).redMul(f.redSub(this.curve.two)); + // Y3 = F * (E - D) + ny = f.redMul(e.redSub(d)); + // Z3 = F^2 - 2 * F + nz = f.redSqr().redSub(f).redSub(f); + } else { + // H = Z1^2 + var h = this.z.redSqr(); + // J = F - 2 * H + var j = f.redSub(h).redISub(h); + // X3 = (B-C-D)*J + nx = b.redSub(c).redISub(d).redMul(j); + // Y3 = F * (E - D) + ny = f.redMul(e.redSub(d)); + // Z3 = F * J + nz = f.redMul(j); } + } else { + // E = C + D + var e = c.redAdd(d); + // H = (c * Z1)^2 + var h = this.curve._mulC(this.c.redMul(this.z)).redSqr(); + // J = E - 2 * H + var j = e.redSub(h).redSub(h); + // X3 = c * (B - E) * J + nx = this.curve._mulC(b.redISub(e)).redMul(j); + // Y3 = c * E * (C - D) + ny = this.curve._mulC(e).redMul(c.redISub(d)); + // Z3 = E * J + nz = e.redMul(j); + } + return this.curve.point(nx, ny, nz); }; -var defineProp = (function() { - try { - Object.defineProperty({}, '_', {}); - return function(obj, name, value) { - Object.defineProperty(obj, name, { - writable: true, - enumerable: false, - configurable: true, - value: value - }) - }; - } catch(e) { - return function(obj, name, value) { - obj[name] = value; - }; - } -}()); +Point.prototype.dbl = function dbl() { + if (this.isInfinity()) + return this; -var globals = ['Array', 'Boolean', 'Date', 'Error', 'EvalError', 'Function', -'Infinity', 'JSON', 'Math', 'NaN', 'Number', 'Object', 'RangeError', -'ReferenceError', 'RegExp', 'String', 'SyntaxError', 'TypeError', 'URIError', -'decodeURI', 'decodeURIComponent', 'encodeURI', 'encodeURIComponent', 'escape', -'eval', 'isFinite', 'isNaN', 'parseFloat', 'parseInt', 'undefined', 'unescape']; + // Double in extended coordinates + if (this.curve.extended) + return this._extDbl(); + else + return this._projDbl(); +}; -function Context() {} -Context.prototype = {}; +Point.prototype._extAdd = function _extAdd(p) { + // hyperelliptic.org/EFD/g1p/auto-twisted-extended-1.html + // #addition-add-2008-hwcd-3 + // 8M -var Script = exports.Script = function NodeScript (code) { - if (!(this instanceof Script)) return new Script(code); - this.code = code; + // A = (Y1 - X1) * (Y2 - X2) + var a = this.y.redSub(this.x).redMul(p.y.redSub(p.x)); + // B = (Y1 + X1) * (Y2 + X2) + var b = this.y.redAdd(this.x).redMul(p.y.redAdd(p.x)); + // C = T1 * k * T2 + var c = this.t.redMul(this.curve.dd).redMul(p.t); + // D = Z1 * 2 * Z2 + var d = this.z.redMul(p.z.redAdd(p.z)); + // E = B - A + var e = b.redSub(a); + // F = D - C + var f = d.redSub(c); + // G = D + C + var g = d.redAdd(c); + // H = B + A + var h = b.redAdd(a); + // X3 = E * F + var nx = e.redMul(f); + // Y3 = G * H + var ny = g.redMul(h); + // T3 = E * H + var nt = e.redMul(h); + // Z3 = F * G + var nz = f.redMul(g); + return this.curve.point(nx, ny, nz, nt); }; -Script.prototype.runInContext = function (context) { - if (!(context instanceof Context)) { - throw new TypeError("needs a 'context' argument."); - } - - var iframe = document.createElement('iframe'); - if (!iframe.style) iframe.style = {}; - iframe.style.display = 'none'; - - document.body.appendChild(iframe); - - var win = iframe.contentWindow; - var wEval = win.eval, wExecScript = win.execScript; +Point.prototype._projAdd = function _projAdd(p) { + // hyperelliptic.org/EFD/g1p/auto-twisted-projective.html + // #addition-add-2008-bbjlp + // #addition-add-2007-bl + // 10M + 1S - if (!wEval && wExecScript) { - // win.eval() magically appears when this is called in IE: - wExecScript.call(win, 'null'); - wEval = win.eval; - } - - forEach(Object_keys(context), function (key) { - win[key] = context[key]; - }); - forEach(globals, function (key) { - if (context[key]) { - win[key] = context[key]; - } - }); - - var winKeys = Object_keys(win); + // A = Z1 * Z2 + var a = this.z.redMul(p.z); + // B = A^2 + var b = a.redSqr(); + // C = X1 * X2 + var c = this.x.redMul(p.x); + // D = Y1 * Y2 + var d = this.y.redMul(p.y); + // E = d * C * D + var e = this.curve.d.redMul(c).redMul(d); + // F = B - E + var f = b.redSub(e); + // G = B + E + var g = b.redAdd(e); + // X3 = A * F * ((X1 + Y1) * (X2 + Y2) - C - D) + var tmp = this.x.redAdd(this.y).redMul(p.x.redAdd(p.y)).redISub(c).redISub(d); + var nx = a.redMul(f).redMul(tmp); + var ny; + var nz; + if (this.curve.twisted) { + // Y3 = A * G * (D - a * C) + ny = a.redMul(g).redMul(d.redSub(this.curve._mulA(c))); + // Z3 = F * G + nz = f.redMul(g); + } else { + // Y3 = A * G * (D - C) + ny = a.redMul(g).redMul(d.redSub(c)); + // Z3 = c * F * G + nz = this.curve._mulC(f).redMul(g); + } + return this.curve.point(nx, ny, nz); +}; - var res = wEval.call(win, this.code); - - forEach(Object_keys(win), function (key) { - // Avoid copying circular objects like `top` and `window` by only - // updating existing context properties or new properties in the `win` - // that was only introduced after the eval. - if (key in context || indexOf(winKeys, key) === -1) { - context[key] = win[key]; - } - }); +Point.prototype.add = function add(p) { + if (this.isInfinity()) + return p; + if (p.isInfinity()) + return this; - forEach(globals, function (key) { - if (!(key in context)) { - defineProp(context, key, win[key]); - } - }); - - document.body.removeChild(iframe); - - return res; + if (this.curve.extended) + return this._extAdd(p); + else + return this._projAdd(p); }; -Script.prototype.runInThisContext = function () { - return eval(this.code); // maybe... +Point.prototype.mul = function mul(k) { + if (this.precomputed && this.precomputed.doubles) + return this.curve._fixedNafMul(this, k); + else + return this.curve._wnafMul(this, k); }; -Script.prototype.runInNewContext = function (context) { - var ctx = Script.createContext(context); - var res = this.runInContext(ctx); - - forEach(Object_keys(ctx), function (key) { - context[key] = ctx[key]; - }); - - return res; +Point.prototype.mulAdd = function mulAdd(k1, p, k2) { + return this.curve._wnafMulAdd(1, [ this, p ], [ k1, k2 ], 2); }; -forEach(Object_keys(Script.prototype), function (name) { - exports[name] = Script[name] = function (code) { - var s = Script(code); - return s[name].apply(s, [].slice.call(arguments, 1)); - }; -}); +Point.prototype.normalize = function normalize() { + if (this.zOne) + return this; -exports.createScript = function (code) { - return exports.Script(code); + // Normalize coordinates + var zi = this.z.redInvm(); + this.x = this.x.redMul(zi); + this.y = this.y.redMul(zi); + if (this.t) + this.t = this.t.redMul(zi); + this.z = this.curve.one; + this.zOne = true; + return this; }; -exports.createContext = Script.createContext = function (context) { - var copy = new Context(); - if(typeof context === 'object') { - forEach(Object_keys(context), function (key) { - copy[key] = context[key]; - }); - } - return copy; +Point.prototype.neg = function neg() { + return this.curve.point(this.x.redNeg(), + this.y, + this.z, + this.t && this.t.redNeg()); }; -},{"indexof":206}],206:[function(require,module,exports){ - -var indexOf = [].indexOf; - -module.exports = function(arr, obj){ - if (indexOf) return arr.indexOf(obj); - for (var i = 0; i < arr.length; ++i) { - if (arr[i] === obj) return i; - } - return -1; +Point.prototype.getX = function getX() { + this.normalize(); + return this.x.fromRed(); }; -},{}],207:[function(require,module,exports){ -// Utils -function assert(val, msg) { - if (!val) - throw new Error(msg || 'Assertion failed'); -} +Point.prototype.getY = function getY() { + this.normalize(); + return this.y.fromRed(); +}; -function assertEqual(l, r, msg) { - if (l != r) - throw new Error(msg || ('Assertion failed: ' + l + ' != ' + r)); -} +// Compatibility with BaseCurve +Point.prototype.toP = Point.prototype.normalize; +Point.prototype.mixedAdd = Point.prototype.add; -// Could use `inherits` module, but don't want to move from single file -// architecture yet. -function inherits(ctor, superCtor) { - ctor.super_ = superCtor - var TempCtor = function () {} - TempCtor.prototype = superCtor.prototype - ctor.prototype = new TempCtor() - ctor.prototype.constructor = ctor -} +},{"../../elliptic":219,"../curve":222,"bn.js":217,"inherits":240}],222:[function(require,module,exports){ +'use strict'; -// BN +var curve = exports; -function BN(number, base, endian) { - // May be `new BN(bn)` ? - if (number !== null && - typeof number === 'object' && - Array.isArray(number.words)) { - return number; - } +curve.base = require('./base'); +curve.short = require('./short'); +curve.mont = require('./mont'); +curve.edwards = require('./edwards'); - this.sign = false; - this.words = null; - this.length = 0; +},{"./base":220,"./edwards":221,"./mont":223,"./short":224}],223:[function(require,module,exports){ +'use strict'; - // Reduction context - this.red = null; +var curve = require('../curve'); +var bn = require('bn.js'); +var inherits = require('inherits'); +var Base = curve.base; - if (base === 'le' || base === 'be') { - endian = base; - base = 10; - } +function MontCurve(conf) { + Base.call(this, 'mont', conf); - if (number !== null) - this._init(number || 0, base || 10, endian || 'be'); + this.a = new bn(conf.a, 16).toRed(this.red); + this.b = new bn(conf.b, 16).toRed(this.red); + this.i4 = new bn(4).toRed(this.red).redInvm(); + this.two = new bn(2).toRed(this.red); + this.a24 = this.i4.redMul(this.a.redAdd(this.two)); } -if (typeof module === 'object') - module.exports = BN; +inherits(MontCurve, Base); +module.exports = MontCurve; -BN.BN = BN; -BN.wordSize = 26; +MontCurve.prototype.validate = function validate(point) { + var x = point.normalize().x; + var x2 = x.redSqr(); + var rhs = x2.redMul(x).redAdd(x2.redMul(this.a)).redAdd(x); + var y = rhs.redSqrt(); -BN.prototype._init = function init(number, base, endian) { - if (typeof number === 'number') { - if (number < 0) { - this.sign = true; - number = -number; - } - if (number < 0x4000000) { - this.words = [ number & 0x3ffffff ]; - this.length = 1; - } else { - this.words = [ - number & 0x3ffffff, - (number / 0x4000000) & 0x3ffffff - ]; - this.length = 2; - } - return; - } else if (typeof number === 'object') { - return this._initArray(number, base, endian); + return y.redSqr().cmp(rhs) === 0; +}; + +function Point(curve, x, z) { + Base.BasePoint.call(this, curve, 'projective'); + if (x === null && z === null) { + this.x = this.curve.one; + this.z = this.curve.zero; + } else { + this.x = new bn(x, 16); + this.z = new bn(z, 16); + if (!this.x.red) + this.x = this.x.toRed(this.curve.red); + if (!this.z.red) + this.z = this.z.toRed(this.curve.red); } - if (base === 'hex') - base = 16; - assert(base === (base | 0) && base >= 2 && base <= 36); +} +inherits(Point, Base.BasePoint); - number = number.toString().replace(/\s+/g, ''); - var start = 0; - if (number[0] === '-') - start++; +MontCurve.prototype.point = function point(x, z) { + return new Point(this, x, z); +}; - if (base === 16) - this._parseHex(number, start); - else - this._parseBase(number, base, start); +MontCurve.prototype.pointFromJSON = function pointFromJSON(obj) { + return Point.fromJSON(this, obj); +}; - if (number[0] === '-') - this.sign = true; +Point.prototype.precompute = function precompute() { + // No-op +}; - this.strip(); +Point.fromJSON = function fromJSON(curve, obj) { + return new Point(curve, obj[0], obj[1] || curve.one); }; -BN.prototype._initArray = function _initArray(number, base, endian) { - // Perhaps a Uint8Array - assert(typeof number.length === 'number'); - this.length = Math.ceil(number.length / 3); - this.words = new Array(this.length); - for (var i = 0; i < this.length; i++) - this.words[i] = 0; +Point.prototype.inspect = function inspect() { + if (this.isInfinity()) + return ''; + return ''; +}; - var off = 0; - if (endian === 'be') { - for (var i = number.length - 1, j = 0; i >= 0; i -= 3) { - var w = number[i] | (number[i - 1] << 8) | (number[i - 2] << 16); - this.words[j] |= (w << off) & 0x3ffffff; - this.words[j + 1] = (w >>> (26 - off)) & 0x3ffffff; - off += 24; - if (off >= 26) { - off -= 26; - j++; - } - } - } else if (endian === 'le') { - for (var i = 0, j = 0; i < number.length; i += 3) { - var w = number[i] | (number[i + 1] << 8) | (number[i + 2] << 16); - this.words[j] |= (w << off) & 0x3ffffff; - this.words[j + 1] = (w >>> (26 - off)) & 0x3ffffff; - off += 24; - if (off >= 26) { - off -= 26; - j++; - } - } - } - return this.strip(); +Point.prototype.isInfinity = function isInfinity() { + // XXX This code assumes that zero is always zero in red + return this.z.cmpn(0) === 0; }; -BN.prototype._parseHex = function parseHex(number, start) { - // Create possibly bigger array to ensure that it fits the number - this.length = Math.ceil((number.length - start) / 6); - this.words = new Array(this.length); - for (var i = 0; i < this.length; i++) - this.words[i] = 0; +Point.prototype.dbl = function dbl() { + // http://hyperelliptic.org/EFD/g1p/auto-montgom-xz.html#doubling-dbl-1987-m-3 + // 2M + 2S + 4A - // Scan 24-bit chunks and add them to the number - var off = 0; - for (var i = number.length - 6, j = 0; i >= start; i -= 6) { - var w = parseInt(number.slice(i, i + 6), 16); - this.words[j] |= (w << off) & 0x3ffffff; - this.words[j + 1] |= w >>> (26 - off) & 0x3fffff; - off += 24; - if (off >= 26) { - off -= 26; - j++; - } - } - if (i + 6 !== start) { - var w = parseInt(number.slice(start, i + 6), 16); - this.words[j] |= (w << off) & 0x3ffffff; - this.words[j + 1] |= w >>> (26 - off) & 0x3fffff; - } - this.strip(); + // A = X1 + Z1 + var a = this.x.redAdd(this.z); + // AA = A^2 + var aa = a.redSqr(); + // B = X1 - Z1 + var b = this.x.redSub(this.z); + // BB = B^2 + var bb = b.redSqr(); + // C = AA - BB + var c = aa.redSub(bb); + // X3 = AA * BB + var nx = aa.redMul(bb); + // Z3 = C * (BB + A24 * C) + var nz = c.redMul(bb.redAdd(this.curve.a24.redMul(c))); + return this.curve.point(nx, nz); }; -BN.prototype._parseBase = function parseBase(number, base, start) { - // Initialize as zero - this.words = [ 0 ]; - this.length = 1; +Point.prototype.add = function add() { + throw new Error('Not supported on Montgomery curve'); +}; - var word = 0; - var q = 1; - var p = 0; - var bigQ = null; - for (var i = start; i < number.length; i++) { - var digit; - var ch = number[i]; - if (base === 10 || ch <= '9') - digit = ch | 0; - else if (ch >= 'a') - digit = ch.charCodeAt(0) - 97 + 10; - else - digit = ch.charCodeAt(0) - 65 + 10; - word *= base; - word += digit; - q *= base; - p++; +Point.prototype.diffAdd = function diffAdd(p, diff) { + // http://hyperelliptic.org/EFD/g1p/auto-montgom-xz.html#diffadd-dadd-1987-m-3 + // 4M + 2S + 6A - if (q > 0xfffff) { - assert(q <= 0x3ffffff); - if (!bigQ) - bigQ = new BN(q); - this.mul(bigQ).copy(this); - this.iadd(new BN(word)); - word = 0; - q = 1; - p = 0; - } - } - if (p !== 0) { - this.mul(new BN(q)).copy(this); - this.iadd(new BN(word)); - } + // A = X2 + Z2 + var a = this.x.redAdd(this.z); + // B = X2 - Z2 + var b = this.x.redSub(this.z); + // C = X3 + Z3 + var c = p.x.redAdd(p.z); + // D = X3 - Z3 + var d = p.x.redSub(p.z); + // DA = D * A + var da = d.redMul(a); + // CB = C * B + var cb = c.redMul(b); + // X5 = Z1 * (DA + CB)^2 + var nx = diff.z.redMul(da.redAdd(cb).redSqr()); + // Z5 = X1 * (DA - CB)^2 + var nz = diff.x.redMul(da.redISub(cb).redSqr()); + return this.curve.point(nx, nz); }; -BN.prototype.copy = function copy(dest) { - dest.words = new Array(this.length); - for (var i = 0; i < this.length; i++) - dest.words[i] = this.words[i]; - dest.length = this.length; - dest.sign = this.sign; - dest.red = this.red; -}; +Point.prototype.mul = function mul(k) { + var t = k.clone(); + var a = this; // (N / 2) * Q + Q + var b = this.curve.point(null, null); // (N / 2) * Q + var c = this; // Q -BN.prototype.clone = function clone() { - var r = new BN(null); - this.copy(r); - return r; + for (var bits = []; t.cmpn(0) !== 0; t.ishrn(1)) + bits.push(t.andln(1)); + + for (var i = bits.length - 1; i >= 0; i--) { + if (bits[i] === 0) { + // N * Q + Q = ((N / 2) * Q + Q)) + (N / 2) * Q + a = a.diffAdd(b, c); + // N * Q = 2 * ((N / 2) * Q + Q)) + b = b.dbl(); + } else { + // N * Q = ((N / 2) * Q + Q) + ((N / 2) * Q) + b = a.diffAdd(b, c); + // N * Q + Q = 2 * ((N / 2) * Q + Q) + a = a.dbl(); + } + } + return b; }; -// Remove leading `0` from `this` -BN.prototype.strip = function strip() { - while (this.length > 1 && this.words[this.length - 1] === 0) - this.length--; - return this._normSign(); +Point.prototype.mulAdd = function mulAdd() { + throw new Error('Not supported on Montgomery curve'); }; -BN.prototype._normSign = function _normSign() { - // -0 = 0 - if (this.length === 1 && this.words[0] === 0) - this.sign = false; +Point.prototype.normalize = function normalize() { + this.x = this.x.redMul(this.z.redInvm()); + this.z = this.curve.one; return this; }; -BN.prototype.inspect = function inspect() { - return (this.red ? ''; +Point.prototype.getX = function getX() { + // Normalize coordinates + this.normalize(); + + return this.x.fromRed(); }; -/* +},{"../curve":222,"bn.js":217,"inherits":240}],224:[function(require,module,exports){ +'use strict'; -var zeros = []; -var groupSizes = []; -var groupBases = []; +var curve = require('../curve'); +var elliptic = require('../../elliptic'); +var bn = require('bn.js'); +var inherits = require('inherits'); +var Base = curve.base; -var s = ''; -var i = -1; -while (++i < BN.wordSize) { - zeros[i] = s; - s += '0'; -} -groupSizes[0] = 0; -groupSizes[1] = 0; -groupBases[0] = 0; -groupBases[1] = 0; -var base = 2 - 1; -while (++base < 36 + 1) { - var groupSize = 0; - var groupBase = 1; - // TODO: <= - while (groupBase < (1 << BN.wordSize) / base) { - groupBase *= base; - groupSize += 1; - } - groupSizes[base] = groupSize; - groupBases[base] = groupBase; -} +var assert = elliptic.utils.assert; -*/ +function ShortCurve(conf) { + Base.call(this, 'short', conf); -var zeros = [ - '', - '0', - '00', - '000', - '0000', - '00000', - '000000', - '0000000', - '00000000', - '000000000', - '0000000000', - '00000000000', - '000000000000', - '0000000000000', - '00000000000000', - '000000000000000', - '0000000000000000', - '00000000000000000', - '000000000000000000', - '0000000000000000000', - '00000000000000000000', - '000000000000000000000', - '0000000000000000000000', - '00000000000000000000000', - '000000000000000000000000', - '0000000000000000000000000' -]; + this.a = new bn(conf.a, 16).toRed(this.red); + this.b = new bn(conf.b, 16).toRed(this.red); + this.tinv = this.two.redInvm(); -var groupSizes = [ - 0, 0, - 25, 16, 12, 11, 10, 9, 8, - 8, 7, 7, 7, 7, 6, 6, - 6, 6, 6, 6, 6, 5, 5, - 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5 -]; + this.zeroA = this.a.fromRed().cmpn(0) === 0; + this.threeA = this.a.fromRed().sub(this.p).cmpn(-3) === 0; -var groupBases = [ - 0, 0, - 33554432, 43046721, 16777216, 48828125, 60466176, 40353607, 16777216, - 43046721, 10000000, 19487171, 35831808, 62748517, 7529536, 11390625, - 16777216, 24137569, 34012224, 47045881, 64000000, 4084101, 5153632, - 6436343, 7962624, 9765625, 11881376, 14348907, 17210368, 20511149, - 24300000, 28629151, 33554432, 39135393, 45435424, 52521875, 60466176 -]; + // If the curve is endomorphic, precalculate beta and lambda + this.endo = this._getEndomorphism(conf); + this._endoWnafT1 = new Array(4); + this._endoWnafT2 = new Array(4); +} +inherits(ShortCurve, Base); +module.exports = ShortCurve; -BN.prototype.toString = function toString(base, padding) { - base = base || 10; - if (base === 16 || base === 'hex') { - var out = ''; - var off = 0; - var padding = padding | 0 || 1; - var carry = 0; - for (var i = 0; i < this.length; i++) { - var w = this.words[i]; - var word = (((w << off) | carry) & 0xffffff).toString(16); - carry = (w >>> (24 - off)) & 0xffffff; - if (carry !== 0 || i !== this.length - 1) - out = zeros[6 - word.length] + word + out; - else - out = word + out; - off += 2; - if (off >= 26) { - off -= 26; - i--; - } - } - if (carry !== 0) - out = carry.toString(16) + out; - while (out.length % padding !== 0) - out = '0' + out; - if (this.sign) - out = '-' + out; - return out; - } else if (base === (base | 0) && base >= 2 && base <= 36) { - // var groupSize = Math.floor(BN.wordSize * Math.LN2 / Math.log(base)); - var groupSize = groupSizes[base]; - // var groupBase = Math.pow(base, groupSize); - var groupBase = groupBases[base]; - var out = ''; - var c = this.clone(); - c.sign = false; - while (c.cmpn(0) !== 0) { - var r = c.modn(groupBase).toString(base); - c = c.idivn(groupBase); +ShortCurve.prototype._getEndomorphism = function _getEndomorphism(conf) { + // No efficient endomorphism + if (!this.zeroA || !this.g || !this.n || this.p.modn(3) !== 1) + return; - if (c.cmpn(0) !== 0) - out = zeros[groupSize - r.length] + r + out; - else - out = r + out; + // Compute beta and lambda, that lambda * P = (beta * Px; Py) + var beta; + var lambda; + if (conf.beta) { + beta = new bn(conf.beta, 16).toRed(this.red); + } else { + var betas = this._getEndoRoots(this.p); + // Choose the smallest beta + beta = betas[0].cmp(betas[1]) < 0 ? betas[0] : betas[1]; + beta = beta.toRed(this.red); + } + if (conf.lambda) { + lambda = new bn(conf.lambda, 16); + } else { + // Choose the lambda that is matching selected beta + var lambdas = this._getEndoRoots(this.n); + if (this.g.mul(lambdas[0]).x.cmp(this.g.x.redMul(beta)) === 0) { + lambda = lambdas[0]; + } else { + lambda = lambdas[1]; + assert(this.g.mul(lambda).x.cmp(this.g.x.redMul(beta)) === 0); } - if (this.cmpn(0) === 0) - out = '0' + out; - if (this.sign) - out = '-' + out; - return out; + } + + // Get basis vectors, used for balanced length-two representation + var basis; + if (conf.basis) { + basis = conf.basis.map(function(vec) { + return { + a: new bn(vec.a, 16), + b: new bn(vec.b, 16) + }; + }); } else { - assert(false, 'Base should be between 2 and 36'); + basis = this._getEndoBasis(lambda); } + + return { + beta: beta, + lambda: lambda, + basis: basis + }; +}; + +ShortCurve.prototype._getEndoRoots = function _getEndoRoots(num) { + // Find roots of for x^2 + x + 1 in F + // Root = (-1 +- Sqrt(-3)) / 2 + // + var red = num === this.p ? this.red : bn.mont(num); + var tinv = new bn(2).toRed(red).redInvm(); + var ntinv = tinv.redNeg(); + + var s = new bn(3).toRed(red).redNeg().redSqrt().redMul(tinv); + + var l1 = ntinv.redAdd(s).fromRed(); + var l2 = ntinv.redSub(s).fromRed(); + return [ l1, l2 ]; }; -BN.prototype.toJSON = function toJSON() { - return this.toString(16); -}; +ShortCurve.prototype._getEndoBasis = function _getEndoBasis(lambda) { + // aprxSqrt >= sqrt(this.n) + var aprxSqrt = this.n.shrn(Math.floor(this.n.bitLength() / 2)); + + // 3.74 + // Run EGCD, until r(L + 1) < aprxSqrt + var u = lambda; + var v = this.n.clone(); + var x1 = new bn(1); + var y1 = new bn(0); + var x2 = new bn(0); + var y2 = new bn(1); + + // NOTE: all vectors are roots of: a + b * lambda = 0 (mod n) + var a0; + var b0; + // First vector + var a1; + var b1; + // Second vector + var a2; + var b2; + + var prevR; + var i = 0; + var r; + var x; + while (u.cmpn(0) !== 0) { + var q = v.div(u); + r = v.sub(q.mul(u)); + x = x2.sub(q.mul(x1)); + var y = y2.sub(q.mul(y1)); -BN.prototype.toArray = function toArray() { - this.strip(); - var res = new Array(this.byteLength()); - res[0] = 0; + if (!a1 && r.cmp(aprxSqrt) < 0) { + a0 = prevR.neg(); + b0 = x1; + a1 = r.neg(); + b1 = x; + } else if (a1 && ++i === 2) { + break; + } + prevR = r; - var q = this.clone(); - for (var i = 0; q.cmpn(0) !== 0; i++) { - var b = q.andln(0xff); - q.ishrn(8); + v = u; + u = r; + x2 = x1; + x1 = x; + y2 = y1; + y1 = y; + } + a2 = r.neg(); + b2 = x; - // Assume big-endian - res[res.length - i - 1] = b; + var len1 = a1.sqr().add(b1.sqr()); + var len2 = a2.sqr().add(b2.sqr()); + if (len2.cmp(len1) >= 0) { + a2 = a0; + b2 = b0; } - return res; + // Normalize signs + if (a1.sign) { + a1 = a1.neg(); + b1 = b1.neg(); + } + if (a2.sign) { + a2 = a2.neg(); + b2 = b2.neg(); + } + + return [ + { a: a1, b: b1 }, + { a: a2, b: b2 } + ]; }; -/* -function genCountBits(bits) { - var arr = []; +ShortCurve.prototype._endoSplit = function _endoSplit(k) { + var basis = this.endo.basis; + var v1 = basis[0]; + var v2 = basis[1]; - for (var i = bits - 1; i >= 0; i--) { - var bit = '0x' + (1 << i).toString(16); - arr.push('w >= ' + bit + ' ? ' + (i + 1)); - } + var c1 = v2.b.mul(k).divRound(this.n); + var c2 = v1.b.neg().mul(k).divRound(this.n); + + var p1 = c1.mul(v1.a); + var p2 = c2.mul(v2.a); + var q1 = c1.mul(v1.b); + var q2 = c2.mul(v2.b); - return new Function('w', 'return ' + arr.join(' :\n') + ' :\n0;'); + // Calculate answer + var k1 = k.sub(p1).sub(p2); + var k2 = q1.add(q2).neg(); + return { k1: k1, k2: k2 }; }; -BN.prototype._countBits = genCountBits(26); -*/ +ShortCurve.prototype.pointFromX = function pointFromX(odd, x) { + x = new bn(x, 16); + if (!x.red) + x = x.toRed(this.red); -// Sadly chrome apps could not contain `new Function()` calls -BN.prototype._countBits = function _countBits(w) { - return w >= 0x2000000 ? 26 : - w >= 0x1000000 ? 25 : - w >= 0x800000 ? 24 : - w >= 0x400000 ? 23 : - w >= 0x200000 ? 22 : - w >= 0x100000 ? 21 : - w >= 0x80000 ? 20 : - w >= 0x40000 ? 19 : - w >= 0x20000 ? 18 : - w >= 0x10000 ? 17 : - w >= 0x8000 ? 16 : - w >= 0x4000 ? 15 : - w >= 0x2000 ? 14 : - w >= 0x1000 ? 13 : - w >= 0x800 ? 12 : - w >= 0x400 ? 11 : - w >= 0x200 ? 10 : - w >= 0x100 ? 9 : - w >= 0x80 ? 8 : - w >= 0x40 ? 7 : - w >= 0x20 ? 6 : - w >= 0x10 ? 5 : - w >= 0x8 ? 4 : - w >= 0x4 ? 3 : - w >= 0x2 ? 2 : - w >= 0x1 ? 1 : - 0; -}; + var y2 = x.redSqr().redMul(x).redIAdd(x.redMul(this.a)).redIAdd(this.b); + var y = y2.redSqrt(); -// Return number of used bits in a BN -BN.prototype.bitLength = function bitLength() { - var hi = 0; - var w = this.words[this.length - 1]; - var hi = this._countBits(w); - return (this.length - 1) * 26 + hi; -}; + // XXX Is there any way to tell if the number is odd without converting it + // to non-red form? + var isOdd = y.fromRed().isOdd(); + if (odd && !isOdd || !odd && isOdd) + y = y.redNeg(); -BN.prototype.byteLength = function byteLength() { - var hi = 0; - var w = this.words[this.length - 1]; - return Math.ceil(this.bitLength() / 8); + return this.point(x, y); }; -// Return negative clone of `this` -BN.prototype.neg = function neg() { - if (this.cmpn(0) === 0) - return this.clone(); +ShortCurve.prototype.validate = function validate(point) { + if (point.inf) + return true; - var r = this.clone(); - r.sign = !this.sign; - return r; + var x = point.x; + var y = point.y; + + var ax = this.a.redMul(x); + var rhs = x.redSqr().redMul(x).redIAdd(ax).redIAdd(this.b); + return y.redSqr().redISub(rhs).cmpn(0) === 0; }; -// Add `num` to `this` in-place -BN.prototype.iadd = function iadd(num) { - // negative + positive - if (this.sign && !num.sign) { - this.sign = false; - var r = this.isub(num); - this.sign = !this.sign; - return this._normSign(); +ShortCurve.prototype._endoWnafMulAdd = + function _endoWnafMulAdd(points, coeffs) { + var npoints = this._endoWnafT1; + var ncoeffs = this._endoWnafT2; + for (var i = 0; i < points.length; i++) { + var split = this._endoSplit(coeffs[i]); + var p = points[i]; + var beta = p._getBeta(); - // positive + negative - } else if (!this.sign && num.sign) { - num.sign = false; - var r = this.isub(num); - num.sign = true; - return r._normSign(); - } + if (split.k1.sign) { + split.k1.sign = !split.k1.sign; + p = p.neg(true); + } + if (split.k2.sign) { + split.k2.sign = !split.k2.sign; + beta = beta.neg(true); + } - // a.length > b.length - var a; - var b; - if (this.length > num.length) { - a = this; - b = num; - } else { - a = num; - b = this; + npoints[i * 2] = p; + npoints[i * 2 + 1] = beta; + ncoeffs[i * 2] = split.k1; + ncoeffs[i * 2 + 1] = split.k2; } + var res = this._wnafMulAdd(1, npoints, ncoeffs, i * 2); - var carry = 0; - for (var i = 0; i < b.length; i++) { - var r = a.words[i] + b.words[i] + carry; - this.words[i] = r & 0x3ffffff; - carry = r >>> 26; + // Clean-up references to points and coefficients + for (var j = 0; j < i * 2; j++) { + npoints[j] = null; + ncoeffs[j] = null; } - for (; carry !== 0 && i < a.length; i++) { - var r = a.words[i] + carry; - this.words[i] = r & 0x3ffffff; - carry = r >>> 26; + return res; +}; + +function Point(curve, x, y, isRed) { + Base.BasePoint.call(this, curve, 'affine'); + if (x === null && y === null) { + this.x = null; + this.y = null; + this.inf = true; + } else { + this.x = new bn(x, 16); + this.y = new bn(y, 16); + // Force redgomery representation when loading from JSON + if (isRed) { + this.x.forceRed(this.curve.red); + this.y.forceRed(this.curve.red); + } + if (!this.x.red) + this.x = this.x.toRed(this.curve.red); + if (!this.y.red) + this.y = this.y.toRed(this.curve.red); + this.inf = false; } +} +inherits(Point, Base.BasePoint); - this.length = a.length; - if (carry !== 0) { - this.words[this.length] = carry; - this.length++; - // Copy the rest of the words - } else if (a !== this) { - for (; i < a.length; i++) - this.words[i] = a.words[i]; +ShortCurve.prototype.point = function point(x, y, isRed) { + return new Point(this, x, y, isRed); +}; + +ShortCurve.prototype.pointFromJSON = function pointFromJSON(obj, red) { + return Point.fromJSON(this, obj, red); +}; + +Point.prototype._getBeta = function _getBeta() { + if (!this.curve.endo) + return; + + var pre = this.precomputed; + if (pre && pre.beta) + return pre.beta; + + var beta = this.curve.point(this.x.redMul(this.curve.endo.beta), this.y); + if (pre) { + var curve = this.curve; + var endoMul = function(p) { + return curve.point(p.x.redMul(curve.endo.beta), p.y); + }; + pre.beta = beta; + beta.precomputed = { + beta: null, + naf: pre.naf && { + wnd: pre.naf.wnd, + points: pre.naf.points.map(endoMul) + }, + doubles: pre.doubles && { + step: pre.doubles.step, + points: pre.doubles.points.map(endoMul) + } + }; } + return beta; +}; - return this; +Point.prototype.toJSON = function toJSON() { + if (!this.precomputed) + return [ this.x, this.y ]; + + return [ this.x, this.y, this.precomputed && { + doubles: this.precomputed.doubles && { + step: this.precomputed.doubles.step, + points: this.precomputed.doubles.points.slice(1) + }, + naf: this.precomputed.naf && { + wnd: this.precomputed.naf.wnd, + points: this.precomputed.naf.points.slice(1) + } + } ]; }; -// Add `num` to `this` -BN.prototype.add = function add(num) { - if (num.sign && !this.sign) { - num.sign = false; - var res = this.sub(num); - num.sign = true; - return res; - } else if (!num.sign && this.sign) { - this.sign = false; - var res = num.sub(this); - this.sign = true; +Point.fromJSON = function fromJSON(curve, obj, red) { + if (typeof obj === 'string') + obj = JSON.parse(obj); + var res = curve.point(obj[0], obj[1], red); + if (!obj[2]) return res; + + function obj2point(obj) { + return curve.point(obj[0], obj[1], red); } - if (this.length > num.length) - return this.clone().iadd(num); - else - return num.clone().iadd(this); + var pre = obj[2]; + res.precomputed = { + beta: null, + doubles: pre.doubles && { + step: pre.doubles.step, + points: [ res ].concat(pre.doubles.points.map(obj2point)) + }, + naf: pre.naf && { + wnd: pre.naf.wnd, + points: [ res ].concat(pre.naf.points.map(obj2point)) + } + }; + return res; }; -// Subtract `num` from `this` in-place -BN.prototype.isub = function isub(num) { - // this - (-num) = this + num - if (num.sign) { - num.sign = false; - var r = this.iadd(num); - num.sign = true; - return r._normSign(); +Point.prototype.inspect = function inspect() { + if (this.isInfinity()) + return ''; + return ''; +}; - // -this - num = -(this + num) - } else if (this.sign) { - this.sign = false; - this.iadd(num); - this.sign = true; - return this._normSign(); - } +Point.prototype.isInfinity = function isInfinity() { + return this.inf; +}; - // At this point both numbers are positive - var cmp = this.cmp(num); +Point.prototype.add = function add(p) { + // O + P = P + if (this.inf) + return p; - // Optimization - zeroify - if (cmp === 0) { - this.sign = false; - this.length = 1; - this.words[0] = 0; + // P + O = P + if (p.inf) return this; - } - - // a > b - if (cmp > 0) { - var a = this; - var b = num; - } else { - var a = num; - var b = this; - } - var carry = 0; - for (var i = 0; i < b.length; i++) { - var r = a.words[i] - b.words[i] - carry; - if (r < 0) { - r += 0x4000000; - carry = 1; - } else { - carry = 0; - } - this.words[i] = r; - } - for (; carry !== 0 && i < a.length; i++) { - var r = a.words[i] - carry; - if (r < 0) { - r += 0x4000000; - carry = 1; - } else { - carry = 0; - } - this.words[i] = r; - } + // P + P = 2P + if (this.eq(p)) + return this.dbl(); - // Copy rest of the words - if (carry === 0 && i < a.length && a !== this) - for (; i < a.length; i++) - this.words[i] = a.words[i]; - this.length = Math.max(this.length, i); + // P + (-P) = O + if (this.neg().eq(p)) + return this.curve.point(null, null); - if (a !== this) - this.sign = true; + // P + Q = O + if (this.x.cmp(p.x) === 0) + return this.curve.point(null, null); - return this.strip(); + var c = this.y.redSub(p.y); + if (c.cmpn(0) !== 0) + c = c.redMul(this.x.redSub(p.x).redInvm()); + var nx = c.redSqr().redISub(this.x).redISub(p.x); + var ny = c.redMul(this.x.redSub(nx)).redISub(this.y); + return this.curve.point(nx, ny); }; -// Subtract `num` from `this` -BN.prototype.sub = function sub(num) { - return this.clone().isub(num); -}; +Point.prototype.dbl = function dbl() { + if (this.inf) + return this; -/* -// NOTE: This could be potentionally used to generate loop-less multiplications -function _genCombMulTo(alen, blen) { - var len = alen + blen - 1; - var src = [ - 'var a = this.words, b = num.words, o = out.words, c = 0, w, ' + - 'mask = 0x3ffffff, shift = 0x4000000;', - 'out.length = ' + len + ';' - ]; - for (var k = 0; k < len; k++) { - var minJ = Math.max(0, k - alen + 1); - var maxJ = Math.min(k, blen - 1); + // 2P = O + var ys1 = this.y.redAdd(this.y); + if (ys1.cmpn(0) === 0) + return this.curve.point(null, null); - for (var j = minJ; j <= maxJ; j++) { - var i = k - j; - var mul = 'a[' + i + '] * b[' + j + ']'; + var a = this.curve.a; - if (j === minJ) { - src.push('w = ' + mul + ' + c;'); - src.push('c = (w / shift) | 0;'); - } else { - src.push('w += ' + mul + ';'); - src.push('c += (w / shift) | 0;'); - } - src.push('w &= mask;'); - } - src.push('o[' + k + '] = w;'); - } - src.push('if (c !== 0) {', - ' o[' + k + '] = c;', - ' out.length++;', - '}', - 'return out;'); + var x2 = this.x.redSqr(); + var dyinv = ys1.redInvm(); + var c = x2.redAdd(x2).redIAdd(x2).redIAdd(a).redMul(dyinv); - return src.join('\n'); -} -*/ + var nx = c.redSqr().redISub(this.x.redAdd(this.x)); + var ny = c.redMul(this.x.redSub(nx)).redISub(this.y); + return this.curve.point(nx, ny); +}; -BN.prototype._smallMulTo = function _smallMulTo(num, out) { - out.sign = num.sign !== this.sign; - out.length = this.length + num.length; +Point.prototype.getX = function getX() { + return this.x.fromRed(); +}; - var carry = 0; - for (var k = 0; k < out.length - 1; k++) { - // Sum all words with the same `i + j = k` and accumulate `ncarry`, - // note that ncarry could be >= 0x3ffffff - var ncarry = carry >>> 26; - var rword = carry & 0x3ffffff; - var maxJ = Math.min(k, num.length - 1); - for (var j = Math.max(0, k - this.length + 1); j <= maxJ; j++) { - var i = k - j; - var a = this.words[i] | 0; - var b = num.words[j] | 0; - var r = a * b; +Point.prototype.getY = function getY() { + return this.y.fromRed(); +}; - var lo = r & 0x3ffffff; - ncarry = (ncarry + ((r / 0x4000000) | 0)) | 0; - lo = (lo + rword) | 0; - rword = lo & 0x3ffffff; - ncarry = (ncarry + (lo >>> 26)) | 0; - } - out.words[k] = rword; - carry = ncarry; - } - if (carry !== 0) { - out.words[k] = carry; - } else { - out.length--; - } +Point.prototype.mul = function mul(k) { + k = new bn(k, 16); - return out.strip(); + if (this.precomputed && this.precomputed.doubles) + return this.curve._fixedNafMul(this, k); + else if (this.curve.endo) + return this.curve._endoWnafMulAdd([ this ], [ k ]); + else + return this.curve._wnafMul(this, k); }; -BN.prototype._bigMulTo = function _bigMulTo(num, out) { - out.sign = num.sign !== this.sign; - out.length = this.length + num.length; +Point.prototype.mulAdd = function mulAdd(k1, p2, k2) { + var points = [ this, p2 ]; + var coeffs = [ k1, k2 ]; + if (this.curve.endo) + return this.curve._endoWnafMulAdd(points, coeffs); + else + return this.curve._wnafMulAdd(1, points, coeffs, 2); +}; - var carry = 0; - var hncarry = 0; - for (var k = 0; k < out.length - 1; k++) { - // Sum all words with the same `i + j = k` and accumulate `ncarry`, - // note that ncarry could be >= 0x3ffffff - var ncarry = hncarry; - hncarry = 0; - var rword = carry & 0x3ffffff; - var maxJ = Math.min(k, num.length - 1); - for (var j = Math.max(0, k - this.length + 1); j <= maxJ; j++) { - var i = k - j; - var a = this.words[i] | 0; - var b = num.words[j] | 0; - var r = a * b; +Point.prototype.eq = function eq(p) { + return this === p || + this.inf === p.inf && + (this.inf || this.x.cmp(p.x) === 0 && this.y.cmp(p.y) === 0); +}; + +Point.prototype.neg = function neg(_precompute) { + if (this.inf) + return this; + + var res = this.curve.point(this.x, this.y.redNeg()); + if (_precompute && this.precomputed) { + var pre = this.precomputed; + var negate = function(p) { + return p.neg(); + }; + res.precomputed = { + naf: pre.naf && { + wnd: pre.naf.wnd, + points: pre.naf.points.map(negate) + }, + doubles: pre.doubles && { + step: pre.doubles.step, + points: pre.doubles.points.map(negate) + } + }; + } + return res; +}; - var lo = r & 0x3ffffff; - ncarry = (ncarry + ((r / 0x4000000) | 0)) | 0; - lo = (lo + rword) | 0; - rword = lo & 0x3ffffff; - ncarry = (ncarry + (lo >>> 26)) | 0; +Point.prototype.toJ = function toJ() { + if (this.inf) + return this.curve.jpoint(null, null, null); - hncarry += ncarry >>> 26; - ncarry &= 0x3ffffff; - } - out.words[k] = rword; - carry = ncarry; - ncarry = hncarry; - } - if (carry !== 0) { - out.words[k] = carry; + var res = this.curve.jpoint(this.x, this.y, this.curve.one); + return res; +}; + +function JPoint(curve, x, y, z) { + Base.BasePoint.call(this, curve, 'jacobian'); + if (x === null && y === null && z === null) { + this.x = this.curve.one; + this.y = this.curve.one; + this.z = new bn(0); } else { - out.length--; + this.x = new bn(x, 16); + this.y = new bn(y, 16); + this.z = new bn(z, 16); } + if (!this.x.red) + this.x = this.x.toRed(this.curve.red); + if (!this.y.red) + this.y = this.y.toRed(this.curve.red); + if (!this.z.red) + this.z = this.z.toRed(this.curve.red); - return out.strip(); + this.zOne = this.z === this.curve.one; +} +inherits(JPoint, Base.BasePoint); + +ShortCurve.prototype.jpoint = function jpoint(x, y, z) { + return new JPoint(this, x, y, z); }; -BN.prototype.mulTo = function mulTo(num, out) { - var res; - if (this.length + num.length < 63) - res = this._smallMulTo(num, out); - else - res = this._bigMulTo(num, out); - return res; +JPoint.prototype.toP = function toP() { + if (this.isInfinity()) + return this.curve.point(null, null); + + var zinv = this.z.redInvm(); + var zinv2 = zinv.redSqr(); + var ax = this.x.redMul(zinv2); + var ay = this.y.redMul(zinv2).redMul(zinv); + + return this.curve.point(ax, ay); }; -// Multiply `this` by `num` -BN.prototype.mul = function mul(num) { - var out = new BN(null); - out.words = new Array(this.length + num.length); - return this.mulTo(num, out); +JPoint.prototype.neg = function neg() { + return this.curve.jpoint(this.x, this.y.redNeg(), this.z); }; -// In-place Multiplication -BN.prototype.imul = function imul(num) { - if (this.cmpn(0) === 0 || num.cmpn(0) === 0) { - this.words[0] = 0; - this.length = 1; +JPoint.prototype.add = function add(p) { + // O + P = P + if (this.isInfinity()) + return p; + + // P + O = P + if (p.isInfinity()) return this; + + // 12M + 4S + 7A + var pz2 = p.z.redSqr(); + var z2 = this.z.redSqr(); + var u1 = this.x.redMul(pz2); + var u2 = p.x.redMul(z2); + var s1 = this.y.redMul(pz2.redMul(p.z)); + var s2 = p.y.redMul(z2.redMul(this.z)); + + var h = u1.redSub(u2); + var r = s1.redSub(s2); + if (h.cmpn(0) === 0) { + if (r.cmpn(0) !== 0) + return this.curve.jpoint(null, null, null); + else + return this.dbl(); } - var tlen = this.length; - var nlen = num.length; + var h2 = h.redSqr(); + var h3 = h2.redMul(h); + var v = u1.redMul(h2); - this.sign = num.sign !== this.sign; - this.length = this.length + num.length; - this.words[this.length - 1] = 0; + var nx = r.redSqr().redIAdd(h3).redISub(v).redISub(v); + var ny = r.redMul(v.redISub(nx)).redISub(s1.redMul(h3)); + var nz = this.z.redMul(p.z).redMul(h); - var lastCarry = 0; - for (var k = this.length - 2; k >= 0; k--) { - // Sum all words with the same `i + j = k` and accumulate `carry`, - // note that carry could be >= 0x3ffffff - var carry = 0; - var rword = 0; - var maxJ = Math.min(k, nlen - 1); - for (var j = Math.max(0, k - tlen + 1); j <= maxJ; j++) { - var i = k - j; - var a = this.words[i]; - var b = num.words[j]; - var r = a * b; + return this.curve.jpoint(nx, ny, nz); +}; - var lo = r & 0x3ffffff; - carry += (r / 0x4000000) | 0; - lo += rword; - rword = lo & 0x3ffffff; - carry += lo >>> 26; - } - this.words[k] = rword; - this.words[k + 1] += carry; - carry = 0; - } +JPoint.prototype.mixedAdd = function mixedAdd(p) { + // O + P = P + if (this.isInfinity()) + return p.toJ(); - // Propagate overflows - var carry = 0; - for (var i = 1; i < this.length; i++) { - var w = this.words[i] + carry; - this.words[i] = w & 0x3ffffff; - carry = w >>> 26; + // P + O = P + if (p.isInfinity()) + return this; + + // 8M + 3S + 7A + var z2 = this.z.redSqr(); + var u1 = this.x; + var u2 = p.x.redMul(z2); + var s1 = this.y; + var s2 = p.y.redMul(z2).redMul(this.z); + + var h = u1.redSub(u2); + var r = s1.redSub(s2); + if (h.cmpn(0) === 0) { + if (r.cmpn(0) !== 0) + return this.curve.jpoint(null, null, null); + else + return this.dbl(); } - return this.strip(); -}; + var h2 = h.redSqr(); + var h3 = h2.redMul(h); + var v = u1.redMul(h2); -// `this` * `this` -BN.prototype.sqr = function sqr() { - return this.mul(this); -}; + var nx = r.redSqr().redIAdd(h3).redISub(v).redISub(v); + var ny = r.redMul(v.redISub(nx)).redISub(s1.redMul(h3)); + var nz = this.z.redMul(h); -// `this` * `this` in-place -BN.prototype.isqr = function isqr() { - return this.mul(this); + return this.curve.jpoint(nx, ny, nz); }; -// Shift-left in-place -BN.prototype.ishln = function ishln(bits) { - assert(typeof bits === 'number' && bits >= 0); - var r = bits % 26; - var s = (bits - r) / 26; - var carryMask = (0x3ffffff >>> (26 - r)) << (26 - r); +JPoint.prototype.dblp = function dblp(pow) { + if (pow === 0) + return this; + if (this.isInfinity()) + return this; + if (!pow) + return this.dbl(); - var o = this.clone(); - if (r !== 0) { - var carry = 0; - for (var i = 0; i < this.length; i++) { - var newCarry = this.words[i] & carryMask; - var c = (this.words[i] - newCarry) << r; - this.words[i] = c | carry; - carry = newCarry >>> (26 - r); - } - if (carry) { - this.words[i] = carry; - this.length++; - } + if (this.curve.zeroA || this.curve.threeA) { + var r = this; + for (var i = 0; i < pow; i++) + r = r.dbl(); + return r; } - if (s !== 0) { - for (var i = this.length - 1; i >= 0; i--) - this.words[i + s] = this.words[i]; - for (var i = 0; i < s; i++) - this.words[i] = 0; - this.length += s; + // 1M + 2S + 1A + N * (4S + 5M + 8A) + // N = 1 => 6M + 6S + 9A + var a = this.curve.a; + var tinv = this.curve.tinv; + + var jx = this.x; + var jy = this.y; + var jz = this.z; + var jz4 = jz.redSqr().redSqr(); + + // Reuse results + var jyd = jy.redAdd(jy); + for (var i = 0; i < pow; i++) { + var jx2 = jx.redSqr(); + var jyd2 = jyd.redSqr(); + var jyd4 = jyd2.redSqr(); + var c = jx2.redAdd(jx2).redIAdd(jx2).redIAdd(a.redMul(jz4)); + + var t1 = jx.redMul(jyd2); + var nx = c.redSqr().redISub(t1.redAdd(t1)); + var t2 = t1.redISub(nx); + var dny = c.redMul(t2); + dny = dny.redIAdd(dny).redISub(jyd4); + var nz = jyd.redMul(jz); + if (i + 1 < pow) + jz4 = jz4.redMul(jyd4); + + jx = nx; + jz = nz; + jyd = dny; } - return this.strip(); + return this.curve.jpoint(jx, jyd.redMul(tinv), jz); }; -// Shift-right in-place -// NOTE: `hint` is a lowest bit before trailing zeroes -// NOTE: if `extended` is true - { lo: ..., hi: } object will be returned -BN.prototype.ishrn = function ishrn(bits, hint, extended) { - assert(typeof bits === 'number' && bits >= 0); - if (hint) - hint = (hint - (hint % 26)) / 26; +JPoint.prototype.dbl = function dbl() { + if (this.isInfinity()) + return this; + + if (this.curve.zeroA) + return this._zeroDbl(); + else if (this.curve.threeA) + return this._threeDbl(); else - hint = 0; + return this._dbl(); +}; - var r = bits % 26; - var s = Math.min((bits - r) / 26, this.length); - var mask = 0x3ffffff ^ ((0x3ffffff >>> r) << r); - var maskedWords = extended; +JPoint.prototype._zeroDbl = function _zeroDbl() { + var nx; + var ny; + var nz; + // Z = 1 + if (this.zOne) { + // hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-0.html + // #doubling-mdbl-2007-bl + // 1M + 5S + 14A - hint -= s; - hint = Math.max(0, hint); + // XX = X1^2 + var xx = this.x.redSqr(); + // YY = Y1^2 + var yy = this.y.redSqr(); + // YYYY = YY^2 + var yyyy = yy.redSqr(); + // S = 2 * ((X1 + YY)^2 - XX - YYYY) + var s = this.x.redAdd(yy).redSqr().redISub(xx).redISub(yyyy); + s = s.redIAdd(s); + // M = 3 * XX + a; a = 0 + var m = xx.redAdd(xx).redIAdd(xx); + // T = M ^ 2 - 2*S + var t = m.redSqr().redISub(s).redISub(s); - // Extended mode, copy masked part - if (maskedWords) { - for (var i = 0; i < s; i++) - maskedWords.words[i] = this.words[i]; - maskedWords.length = s; - } + // 8 * YYYY + var yyyy8 = yyyy.redIAdd(yyyy); + yyyy8 = yyyy8.redIAdd(yyyy8); + yyyy8 = yyyy8.redIAdd(yyyy8); - if (s === 0) { - // No-op, we should not move anything at all - } else if (this.length > s) { - this.length -= s; - for (var i = 0; i < this.length; i++) - this.words[i] = this.words[i + s]; + // X3 = T + nx = t; + // Y3 = M * (S - T) - 8 * YYYY + ny = m.redMul(s.redISub(t)).redISub(yyyy8); + // Z3 = 2*Y1 + nz = this.y.redAdd(this.y); } else { - this.words[0] = 0; - this.length = 1; - } + // hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-0.html + // #doubling-dbl-2009-l + // 2M + 5S + 13A - var carry = 0; - for (var i = this.length - 1; i >= 0 && (carry !== 0 || i >= hint); i--) { - var word = this.words[i]; - this.words[i] = (carry << (26 - r)) | (word >>> r); - carry = word & mask; - } + // A = X1^2 + var a = this.x.redSqr(); + // B = Y1^2 + var b = this.y.redSqr(); + // C = B^2 + var c = b.redSqr(); + // D = 2 * ((X1 + B)^2 - A - C) + var d = this.x.redAdd(b).redSqr().redISub(a).redISub(c); + d = d.redIAdd(d); + // E = 3 * A + var e = a.redAdd(a).redIAdd(a); + // F = E^2 + var f = e.redSqr(); - // Push carried bits as a mask - if (maskedWords && carry !== 0) - maskedWords.words[maskedWords.length++] = carry; + // 8 * C + var c8 = c.redIAdd(c); + c8 = c8.redIAdd(c8); + c8 = c8.redIAdd(c8); - if (this.length === 0) { - this.words[0] = 0; - this.length = 1; + // X3 = F - 2 * D + nx = f.redISub(d).redISub(d); + // Y3 = E * (D - X3) - 8 * C + ny = e.redMul(d.redISub(nx)).redISub(c8); + // Z3 = 2 * Y1 * Z1 + nz = this.y.redMul(this.z); + nz = nz.redIAdd(nz); } - this.strip(); - if (extended) - return { hi: this, lo: maskedWords }; - - return this; -}; - -// Shift-left -BN.prototype.shln = function shln(bits) { - return this.clone().ishln(bits); + return this.curve.jpoint(nx, ny, nz); }; -// Shift-right -BN.prototype.shrn = function shrn(bits) { - return this.clone().ishrn(bits); -}; +JPoint.prototype._threeDbl = function _threeDbl() { + var nx; + var ny; + var nz; + // Z = 1 + if (this.zOne) { + // hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-3.html + // #doubling-mdbl-2007-bl + // 1M + 5S + 15A -// Test if n bit is set -BN.prototype.testn = function testn(bit) { - assert(typeof bit === 'number' && bit >= 0); - var r = bit % 26; - var s = (bit - r) / 26; - var q = 1 << r; + // XX = X1^2 + var xx = this.x.redSqr(); + // YY = Y1^2 + var yy = this.y.redSqr(); + // YYYY = YY^2 + var yyyy = yy.redSqr(); + // S = 2 * ((X1 + YY)^2 - XX - YYYY) + var s = this.x.redAdd(yy).redSqr().redISub(xx).redISub(yyyy); + s = s.redIAdd(s); + // M = 3 * XX + a + var m = xx.redAdd(xx).redIAdd(xx).redIAdd(this.curve.a); + // T = M^2 - 2 * S + var t = m.redSqr().redISub(s).redISub(s); + // X3 = T + nx = t; + // Y3 = M * (S - T) - 8 * YYYY + var yyyy8 = yyyy.redIAdd(yyyy); + yyyy8 = yyyy8.redIAdd(yyyy8); + yyyy8 = yyyy8.redIAdd(yyyy8); + ny = m.redMul(s.redISub(t)).redISub(yyyy8); + // Z3 = 2 * Y1 + nz = this.y.redAdd(this.y); + } else { + // hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-3.html#doubling-dbl-2001-b + // 3M + 5S - // Fast case: bit is much higher than all existing words - if (this.length <= s) { - return false; + // delta = Z1^2 + var delta = this.z.redSqr(); + // gamma = Y1^2 + var gamma = this.y.redSqr(); + // beta = X1 * gamma + var beta = this.x.redMul(gamma); + // alpha = 3 * (X1 - delta) * (X1 + delta) + var alpha = this.x.redSub(delta).redMul(this.x.redAdd(delta)); + alpha = alpha.redAdd(alpha).redIAdd(alpha); + // X3 = alpha^2 - 8 * beta + var beta4 = beta.redIAdd(beta); + beta4 = beta4.redIAdd(beta4); + var beta8 = beta4.redAdd(beta4); + nx = alpha.redSqr().redISub(beta8); + // Z3 = (Y1 + Z1)^2 - gamma - delta + nz = this.y.redAdd(this.z).redSqr().redISub(gamma).redISub(delta); + // Y3 = alpha * (4 * beta - X3) - 8 * gamma^2 + var ggamma8 = gamma.redSqr(); + ggamma8 = ggamma8.redIAdd(ggamma8); + ggamma8 = ggamma8.redIAdd(ggamma8); + ggamma8 = ggamma8.redIAdd(ggamma8); + ny = alpha.redMul(beta4.redISub(nx)).redISub(ggamma8); } - // Check bit and return - var w = this.words[s]; - - return !!(w & q); + return this.curve.jpoint(nx, ny, nz); }; -// Return only lowers bits of number (in-place) -BN.prototype.imaskn = function imaskn(bits) { - assert(typeof bits === 'number' && bits >= 0); - var r = bits % 26; - var s = (bits - r) / 26; +JPoint.prototype._dbl = function _dbl() { + var a = this.curve.a; - assert(!this.sign, 'imaskn works only with positive numbers'); + // 4M + 6S + 10A + var jx = this.x; + var jy = this.y; + var jz = this.z; + var jz4 = jz.redSqr().redSqr(); - if (r !== 0) - s++; - this.length = Math.min(s, this.length); + var jx2 = jx.redSqr(); + var jy2 = jy.redSqr(); - if (r !== 0) { - var mask = 0x3ffffff ^ ((0x3ffffff >>> r) << r); - this.words[this.length - 1] &= mask; - } + var c = jx2.redAdd(jx2).redIAdd(jx2).redIAdd(a.redMul(jz4)); - return this.strip(); -}; + var jxd4 = jx.redAdd(jx); + jxd4 = jxd4.redIAdd(jxd4); + var t1 = jxd4.redMul(jy2); + var nx = c.redSqr().redISub(t1.redAdd(t1)); + var t2 = t1.redISub(nx); -// Return only lowers bits of number -BN.prototype.maskn = function maskn(bits) { - return this.clone().imaskn(bits); -}; + var jyd8 = jy2.redSqr(); + jyd8 = jyd8.redIAdd(jyd8); + jyd8 = jyd8.redIAdd(jyd8); + jyd8 = jyd8.redIAdd(jyd8); + var ny = c.redMul(t2).redISub(jyd8); + var nz = jy.redAdd(jy).redMul(jz); -// Add plain number `num` to `this` -BN.prototype.iaddn = function iaddn(num) { - assert(typeof num === 'number'); - if (num < 0) - return this.isubn(-num); + return this.curve.jpoint(nx, ny, nz); +}; - // Possible sign change - if (this.sign) { - if (this.length === 1 && this.words[0] < num) { - this.words[0] = num - this.words[0]; - this.sign = false; - return this; - } +JPoint.prototype.trpl = function trpl() { + if (!this.curve.zeroA) + return this.dbl().add(this); - this.sign = false; - this.isubn(num); - this.sign = true; - return this; - } - this.words[0] += num; + // hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-0.html#tripling-tpl-2007-bl + // 5M + 10S + ... - // Carry - for (var i = 0; i < this.length && this.words[i] >= 0x4000000; i++) { - this.words[i] -= 0x4000000; - if (i === this.length - 1) - this.words[i + 1] = 1; - else - this.words[i + 1]++; - } - this.length = Math.max(this.length, i + 1); + // XX = X1^2 + var xx = this.x.redSqr(); + // YY = Y1^2 + var yy = this.y.redSqr(); + // ZZ = Z1^2 + var zz = this.z.redSqr(); + // YYYY = YY^2 + var yyyy = yy.redSqr(); + // M = 3 * XX + a * ZZ2; a = 0 + var m = xx.redAdd(xx).redIAdd(xx); + // MM = M^2 + var mm = m.redSqr(); + // E = 6 * ((X1 + YY)^2 - XX - YYYY) - MM + var e = this.x.redAdd(yy).redSqr().redISub(xx).redISub(yyyy); + e = e.redIAdd(e); + e = e.redAdd(e).redIAdd(e); + e = e.redISub(mm); + // EE = E^2 + var ee = e.redSqr(); + // T = 16*YYYY + var t = yyyy.redIAdd(yyyy); + t = t.redIAdd(t); + t = t.redIAdd(t); + t = t.redIAdd(t); + // U = (M + E)^2 - MM - EE - T + var u = m.redIAdd(e).redSqr().redISub(mm).redISub(ee).redISub(t); + // X3 = 4 * (X1 * EE - 4 * YY * U) + var yyu4 = yy.redMul(u); + yyu4 = yyu4.redIAdd(yyu4); + yyu4 = yyu4.redIAdd(yyu4); + var nx = this.x.redMul(ee).redISub(yyu4); + nx = nx.redIAdd(nx); + nx = nx.redIAdd(nx); + // Y3 = 8 * Y1 * (U * (T - U) - E * EE) + var ny = this.y.redMul(u.redMul(t.redISub(u)).redISub(e.redMul(ee))); + ny = ny.redIAdd(ny); + ny = ny.redIAdd(ny); + ny = ny.redIAdd(ny); + // Z3 = (Z1 + E)^2 - ZZ - EE + var nz = this.z.redAdd(e).redSqr().redISub(zz).redISub(ee); - return this; + return this.curve.jpoint(nx, ny, nz); }; -// Subtract plain number `num` from `this` -BN.prototype.isubn = function isubn(num) { - assert(typeof num === 'number'); - if (num < 0) - return this.iaddn(-num); +JPoint.prototype.mul = function mul(k, kbase) { + k = new bn(k, kbase); - if (this.sign) { - this.sign = false; - this.iaddn(num); - this.sign = true; - return this; - } + return this.curve._wnafMul(this, k); +}; - this.words[0] -= num; +JPoint.prototype.eq = function eq(p) { + if (p.type === 'affine') + return this.eq(p.toJ()); - // Carry - for (var i = 0; i < this.length && this.words[i] < 0; i++) { - this.words[i] += 0x4000000; - this.words[i + 1] -= 1; - } + if (this === p) + return true; - return this.strip(); -}; + // x1 * z2^2 == x2 * z1^2 + var z2 = this.z.redSqr(); + var pz2 = p.z.redSqr(); + if (this.x.redMul(pz2).redISub(p.x.redMul(z2)).cmpn(0) !== 0) + return false; -BN.prototype.addn = function addn(num) { - return this.clone().iaddn(num); + // y1 * z2^3 == y2 * z1^3 + var z3 = z2.redMul(this.z); + var pz3 = pz2.redMul(p.z); + return this.y.redMul(pz3).redISub(p.y.redMul(z3)).cmpn(0) === 0; }; -BN.prototype.subn = function subn(num) { - return this.clone().isubn(num); +JPoint.prototype.inspect = function inspect() { + if (this.isInfinity()) + return ''; + return ''; }; -BN.prototype.iabs = function iabs() { - this.sign = false; - - return this +JPoint.prototype.isInfinity = function isInfinity() { + // XXX This code assumes that zero is always zero in red + return this.z.cmpn(0) === 0; }; -BN.prototype.abs = function abs() { - return this.clone().iabs(); -}; +},{"../../elliptic":219,"../curve":222,"bn.js":217,"inherits":240}],225:[function(require,module,exports){ +'use strict'; -BN.prototype._wordDiv = function _wordDiv(num, mode) { - var shift = this.length - num.length; +var curves = exports; - var a = this.clone(); - var b = num; +var hash = require('hash.js'); +var elliptic = require('../elliptic'); - var q = mode !== 'mod' && new BN(0); - var sign = false; - - // Approximate quotient at each step - while (a.length > b.length) { - // NOTE: a.length is always >= 2, because of the condition .div() - var hi = a.words[a.length - 1] * 0x4000000 + a.words[a.length - 2]; - var sq = (hi / b.words[b.length - 1]); - var sqhi = (sq / 0x4000000) | 0; - var sqlo = sq & 0x3ffffff; - sq = new BN(null); - sq.words = [ sqlo, sqhi ]; - sq.length = 2; - - // Collect quotient - var shift = (a.length - b.length - 1) * 26; - if (q) { - var t = sq.shln(shift); - if (a.sign) - q.isub(t); - else - q.iadd(t); - } +var assert = elliptic.utils.assert; - sq = sq.mul(b).ishln(shift); - if (a.sign) - a.iadd(sq) - else - a.isub(sq); - } - // At this point a.length <= b.length - while (a.ucmp(b) >= 0) { - // NOTE: a.length is always >= 2, because of the condition above - var hi = a.words[a.length - 1]; - var sq = new BN((hi / b.words[b.length - 1]) | 0); - var shift = (a.length - b.length) * 26; - - if (q) { - var t = sq.shln(shift); - if (a.sign) - q.isub(t); - else - q.iadd(t); - } +function PresetCurve(options) { + if (options.type === 'short') + this.curve = new elliptic.curve.short(options); + else if (options.type === 'edwards') + this.curve = new elliptic.curve.edwards(options); + else + this.curve = new elliptic.curve.mont(options); + this.g = this.curve.g; + this.n = this.curve.n; + this.hash = options.hash; - sq = sq.mul(b).ishln(shift); + assert(this.g.validate(), 'Invalid curve'); + assert(this.g.mul(this.n).isInfinity(), 'Invalid curve, G*N != O'); +} +curves.PresetCurve = PresetCurve; - if (a.sign) - a.iadd(sq); - else - a.isub(sq); - } +function defineCurve(name, options) { + Object.defineProperty(curves, name, { + configurable: true, + enumerable: true, + get: function() { + var curve = new PresetCurve(options); + Object.defineProperty(curves, name, { + configurable: true, + enumerable: true, + value: curve + }); + return curve; + } + }); +} - if (a.sign) { - if (q) - q.isubn(1); - a.iadd(b); - } - return { div: q ? q : null, mod: a }; -}; +defineCurve('p192', { + type: 'short', + prime: 'p192', + p: 'ffffffff ffffffff ffffffff fffffffe ffffffff ffffffff', + a: 'ffffffff ffffffff ffffffff fffffffe ffffffff fffffffc', + b: '64210519 e59c80e7 0fa7e9ab 72243049 feb8deec c146b9b1', + n: 'ffffffff ffffffff ffffffff 99def836 146bc9b1 b4d22831', + hash: hash.sha256, + gRed: false, + g: [ + '188da80e b03090f6 7cbf20eb 43a18800 f4ff0afd 82ff1012', + '07192b95 ffc8da78 631011ed 6b24cdd5 73f977a1 1e794811' + ] +}); -BN.prototype.divmod = function divmod(num, mode) { - assert(num.cmpn(0) !== 0); +defineCurve('p224', { + type: 'short', + prime: 'p224', + p: 'ffffffff ffffffff ffffffff ffffffff 00000000 00000000 00000001', + a: 'ffffffff ffffffff ffffffff fffffffe ffffffff ffffffff fffffffe', + b: 'b4050a85 0c04b3ab f5413256 5044b0b7 d7bfd8ba 270b3943 2355ffb4', + n: 'ffffffff ffffffff ffffffff ffff16a2 e0b8f03e 13dd2945 5c5c2a3d', + hash: hash.sha256, + gRed: false, + g: [ + 'b70e0cbd 6bb4bf7f 321390b9 4a03c1d3 56c21122 343280d6 115c1d21', + 'bd376388 b5f723fb 4c22dfe6 cd4375a0 5a074764 44d58199 85007e34' + ] +}); - if (this.sign && !num.sign) { - var res = this.neg().divmod(num, mode); - var div; - var mod; - if (mode !== 'mod') - div = res.div.neg(); - if (mode !== 'div') - mod = res.mod.cmpn(0) === 0 ? res.mod : num.sub(res.mod); - return { - div: div, - mod: mod - }; - } else if (!this.sign && num.sign) { - var res = this.divmod(num.neg(), mode); - var div; - if (mode !== 'mod') - div = res.div.neg(); - return { div: div, mod: res.mod }; - } else if (this.sign && num.sign) { - return this.neg().divmod(num.neg(), mode); - } +defineCurve('p256', { + type: 'short', + prime: null, + p: 'ffffffff 00000001 00000000 00000000 00000000 ffffffff ffffffff ffffffff', + a: 'ffffffff 00000001 00000000 00000000 00000000 ffffffff ffffffff fffffffc', + b: '5ac635d8 aa3a93e7 b3ebbd55 769886bc 651d06b0 cc53b0f6 3bce3c3e 27d2604b', + n: 'ffffffff 00000000 ffffffff ffffffff bce6faad a7179e84 f3b9cac2 fc632551', + hash: hash.sha256, + gRed: false, + g: [ + '6b17d1f2 e12c4247 f8bce6e5 63a440f2 77037d81 2deb33a0 f4a13945 d898c296', + '4fe342e2 fe1a7f9b 8ee7eb4a 7c0f9e16 2bce3357 6b315ece cbb64068 37bf51f5' + ] +}); - // Both numbers are positive at this point +defineCurve('curve25519', { + type: 'mont', + prime: 'p25519', + p: '7fffffffffffffff ffffffffffffffff ffffffffffffffff ffffffffffffffed', + a: '76d06', + b: '0', + n: '1000000000000000 0000000000000000 14def9dea2f79cd6 5812631a5cf5d3ed', + hash: hash.sha256, + gRed: false, + g: [ + '9' + ] +}); - // Strip both numbers to approximate shift value - if (num.length > this.length || this.cmp(num) < 0) - return { div: new BN(0), mod: this }; +defineCurve('ed25519', { + type: 'edwards', + prime: 'p25519', + p: '7fffffffffffffff ffffffffffffffff ffffffffffffffff ffffffffffffffed', + a: '-1', + c: '1', + // -121665 * (121666^(-1)) (mod P) + d: '52036cee2b6ffe73 8cc740797779e898 00700a4d4141d8ab 75eb4dca135978a3', + n: '1000000000000000 0000000000000000 14def9dea2f79cd6 5812631a5cf5d3ed', + hash: hash.sha256, + gRed: false, + g: [ + '216936d3cd6e53fec0a4e231fdd6dc5c692cc7609525a7b2c9562d608f25d51a', - // Very short reduction - if (num.length === 1) { - if (mode === 'div') - return { div: this.divn(num.words[0]), mod: null }; - else if (mode === 'mod') - return { div: null, mod: new BN(this.modn(num.words[0])) }; - return { - div: this.divn(num.words[0]), - mod: new BN(this.modn(num.words[0])) - }; - } + // 4/5 + '6666666666666666666666666666666666666666666666666666666666666658' + ] +}); - return this._wordDiv(num, mode); -}; +var pre; +try { + pre = require('./precomputed/secp256k1'); +} catch (e) { + pre = undefined; +} -// Find `this` / `num` -BN.prototype.div = function div(num) { - return this.divmod(num, 'div').div; -}; +defineCurve('secp256k1', { + type: 'short', + prime: 'k256', + p: 'ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff fffffffe fffffc2f', + a: '0', + b: '7', + n: 'ffffffff ffffffff ffffffff fffffffe baaedce6 af48a03b bfd25e8c d0364141', + h: '1', + hash: hash.sha256, -// Find `this` % `num` -BN.prototype.mod = function mod(num) { - return this.divmod(num, 'mod').mod; -}; + // Precomputed endomorphism + beta: '7ae96a2b657c07106e64479eac3434e99cf0497512f58995c1396c28719501ee', + lambda: '5363ad4cc05c30e0a5261c028812645a122e22ea20816678df02967c1b23bd72', + basis: [ + { + a: '3086d221a7d46bcde86c90e49284eb15', + b: '-e4437ed6010e88286f547fa90abfe4c3' + }, + { + a: '114ca50f7a8e2f3f657c1108d9d44cfd8', + b: '3086d221a7d46bcde86c90e49284eb15' + } + ], -// Find Round(`this` / `num`) -BN.prototype.divRound = function divRound(num) { - var dm = this.divmod(num); + gRed: false, + g: [ + '79be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798', + '483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8', + pre + ] +}); - // Fast case - exact division - if (dm.mod.cmpn(0) === 0) - return dm.div; +},{"../elliptic":219,"./precomputed/secp256k1":230,"hash.js":234}],226:[function(require,module,exports){ +'use strict'; - var mod = dm.div.sign ? dm.mod.isub(num) : dm.mod; +var bn = require('bn.js'); +var elliptic = require('../../elliptic'); +var utils = elliptic.utils; +var assert = utils.assert; - var half = num.shrn(1); - var r2 = num.andln(1); - var cmp = mod.cmp(half); +var KeyPair = require('./key'); +var Signature = require('./signature'); - // Round down - if (cmp < 0 || r2 === 1 && cmp === 0) - return dm.div; +function EC(options) { + if (!(this instanceof EC)) + return new EC(options); - // Round up - return dm.div.sign ? dm.div.isubn(1) : dm.div.iaddn(1); -}; + // Shortcut `elliptic.ec(curve-name)` + if (typeof options === 'string') { + assert(elliptic.curves.hasOwnProperty(options), 'Unknown curve ' + options); -BN.prototype.modn = function modn(num) { - assert(num <= 0x3ffffff); - var p = (1 << 26) % num; + options = elliptic.curves[options]; + } - var acc = 0; - for (var i = this.length - 1; i >= 0; i--) - acc = (p * acc + this.words[i]) % num; + // Shortcut for `elliptic.ec(elliptic.curves.curveName)` + if (options instanceof elliptic.curves.PresetCurve) + options = { curve: options }; - return acc; -}; + this.curve = options.curve.curve; + this.n = this.curve.n; + this.nh = this.n.shrn(1); + this.g = this.curve.g; -// In-place division by number -BN.prototype.idivn = function idivn(num) { - assert(num <= 0x3ffffff); + // Point on curve + this.g = options.curve.g; + this.g.precompute(options.curve.n.bitLength() + 1); - var carry = 0; - for (var i = this.length - 1; i >= 0; i--) { - var w = this.words[i] + carry * 0x4000000; - this.words[i] = (w / num) | 0; - carry = w % num; - } + // Hash for function for DRBG + this.hash = options.hash || options.curve.hash; +} +module.exports = EC; - return this.strip(); +EC.prototype.keyPair = function keyPair(options) { + return new KeyPair(this, options); }; -BN.prototype.divn = function divn(num) { - return this.clone().idivn(num); +EC.prototype.keyFromPrivate = function keyFromPrivate(priv, enc) { + return KeyPair.fromPrivate(this, priv, enc); }; -BN.prototype._egcd = function _egcd(x1, p) { - assert(!p.sign); - assert(p.cmpn(0) !== 0); - - var a = this; - var b = p.clone(); - - if (a.sign) - a = a.mod(p); - else - a = a.clone(); - - var x2 = new BN(0); - while (b.isEven()) - b.ishrn(1); - var delta = b.clone(); - while (a.cmpn(1) > 0 && b.cmpn(1) > 0) { - while (a.isEven()) { - a.ishrn(1); - if (x1.isEven()) - x1.ishrn(1); - else - x1.iadd(delta).ishrn(1); - } - while (b.isEven()) { - b.ishrn(1); - if (x2.isEven()) - x2.ishrn(1); - else - x2.iadd(delta).ishrn(1); - } - if (a.cmp(b) >= 0) { - a.isub(b); - x1.isub(x2); - } else { - b.isub(a); - x2.isub(x1); - } - } - if (a.cmpn(1) === 0) - return x1; - else - return x2; +EC.prototype.keyFromPublic = function keyFromPublic(pub, enc) { + return KeyPair.fromPublic(this, pub, enc); }; -BN.prototype.gcd = function gcd(num) { - if (this.cmpn(0) === 0) - return num.clone(); - if (num.cmpn(0) === 0) - return this.clone(); - - var a = this.clone(); - var b = num.clone(); - a.sign = false; - b.sign = false; - - // Remove common factor of two - for (var shift = 0; a.isEven() && b.isEven(); shift++) { - a.ishrn(1); - b.ishrn(1); - } +EC.prototype.genKeyPair = function genKeyPair(options) { + if (!options) + options = {}; - while (a.isEven()) - a.ishrn(1); + // Instantiate Hmac_DRBG + var drbg = new elliptic.hmacDRBG({ + hash: this.hash, + pers: options.pers, + entropy: options.entropy || elliptic.rand(this.hash.hmacStrength), + nonce: this.n.toArray() + }); + var bytes = this.n.byteLength(); + var ns2 = this.n.sub(new bn(2)); do { - while (b.isEven()) - b.ishrn(1); - - // Swap `a` and `b` to make `a` always bigger than `b` - if (a.cmp(b) < 0) { - var t = a; - a = b; - b = t; - } - a.isub(a.div(b).mul(b)); - } while (a.cmpn(0) !== 0 && b.cmpn(0) !== 0); - if (a.cmpn(0) === 0) - return b.ishln(shift); - else - return a.ishln(shift); -}; - -// Invert number in the field F(num) -BN.prototype.invm = function invm(num) { - return this._egcd(new BN(1), num).mod(num); -}; - -BN.prototype.isEven = function isEven(num) { - return (this.words[0] & 1) === 0; -}; + var priv = new bn(drbg.generate(bytes)); + if (priv.cmp(ns2) > 0) + continue; -BN.prototype.isOdd = function isOdd(num) { - return (this.words[0] & 1) === 1; + priv.iaddn(1); + return this.keyFromPrivate(priv); + } while (true); }; -// And first word and num -BN.prototype.andln = function andln(num) { - return this.words[0] & num; +EC.prototype._truncateToN = function truncateToN(msg, truncOnly) { + var delta = msg.byteLength() * 8 - this.n.bitLength(); + if (delta > 0) + msg = msg.shrn(delta); + if (!truncOnly && msg.cmp(this.n) >= 0) + return msg.sub(this.n); + else + return msg; }; -// Increment at the bit position in-line -BN.prototype.bincn = function bincn(bit) { - assert(typeof bit === 'number'); - var r = bit % 26; - var s = (bit - r) / 26; - var q = 1 << r; - - // Fast case: bit is much higher than all existing words - if (this.length <= s) { - for (var i = this.length; i < s + 1; i++) - this.words[i] = 0; - this.words[s] |= q; - this.length = s + 1; - return this; - } - - // Add bit and propagate, if needed - var carry = q; - for (var i = s; carry !== 0 && i < this.length; i++) { - var w = this.words[i]; - w += carry; - carry = w >>> 26; - w &= 0x3ffffff; - this.words[i] = w; - } - if (carry !== 0) { - this.words[i] = carry; - this.length++; +EC.prototype.sign = function sign(msg, key, enc, options) { + if (typeof enc === 'object') { + options = enc; + enc = null; } - return this; -}; - -BN.prototype.cmpn = function cmpn(num) { - var sign = num < 0; - if (sign) - num = -num; - - if (this.sign && !sign) - return -1; - else if (!this.sign && sign) - return 1; + if (!options) + options = {}; - num &= 0x3ffffff; - this.strip(); + key = this.keyFromPrivate(key, enc); + msg = this._truncateToN(new bn(msg, 16)); - var res; - if (this.length > 1) { - res = 1; - } else { - var w = this.words[0]; - res = w === num ? 0 : w < num ? -1 : 1; - } - if (this.sign) - res = -res; - return res; -}; + // Zero-extend key to provide enough entropy + var bytes = this.n.byteLength(); + var bkey = key.getPrivate().toArray(); + for (var i = bkey.length; i < 21; i++) + bkey.unshift(0); -// Compare two numbers and return: -// 1 - if `this` > `num` -// 0 - if `this` == `num` -// -1 - if `this` < `num` -BN.prototype.cmp = function cmp(num) { - if (this.sign && !num.sign) - return -1; - else if (!this.sign && num.sign) - return 1; + // Zero-extend nonce to have the same byte size as N + var nonce = msg.toArray(); + for (var i = nonce.length; i < bytes; i++) + nonce.unshift(0); - var res = this.ucmp(num); - if (this.sign) - return -res; - else - return res; -}; + // Instantiate Hmac_DRBG + var drbg = new elliptic.hmacDRBG({ + hash: this.hash, + entropy: bkey, + nonce: nonce + }); -// Unsigned comparison -BN.prototype.ucmp = function ucmp(num) { - // At this point both numbers have the same sign - if (this.length > num.length) - return 1; - else if (this.length < num.length) - return -1; + // Number of bytes to generate + var ns1 = this.n.sub(new bn(1)); + do { + var k = new bn(drbg.generate(this.n.byteLength())); + k = this._truncateToN(k, true); + if (k.cmpn(1) <= 0 || k.cmp(ns1) >= 0) + continue; - var res = 0; - for (var i = this.length - 1; i >= 0; i--) { - var a = this.words[i]; - var b = num.words[i]; + var kp = this.g.mul(k); + if (kp.isInfinity()) + continue; - if (a === b) + var r = kp.getX().mod(this.n); + if (r.cmpn(0) === 0) continue; - if (a < b) - res = -1; - else if (a > b) - res = 1; - break; - } - return res; -}; -// -// A reduce context, could be using montgomery or something better, depending -// on the `m` itself. -// -BN.red = function red(num) { - return new Red(num); -}; + var s = k.invm(this.n).mul(r.mul(key.getPrivate()).iadd(msg)).mod(this.n); + if (s.cmpn(0) === 0) + continue; -BN.prototype.toRed = function toRed(ctx) { - assert(!this.red, 'Already a number in reduction context'); - assert(!this.sign, 'red works only with positives'); - return ctx.convertTo(this)._forceRed(ctx); -}; + // Use complement of `s`, if it is > `n / 2` + if (options.canonical && s.cmp(this.nh) > 0) + s = this.n.sub(s); -BN.prototype.fromRed = function fromRed() { - assert(this.red, 'fromRed works only with numbers in reduction context'); - return this.red.convertFrom(this); + return new Signature({ r: r, s: s }); + } while (true); }; -BN.prototype._forceRed = function _forceRed(ctx) { - this.red = ctx; - return this; -}; +EC.prototype.verify = function verify(msg, signature, key, enc) { + msg = this._truncateToN(new bn(msg, 16)); + key = this.keyFromPublic(key, enc); + signature = new Signature(signature, 'hex'); -BN.prototype.forceRed = function forceRed(ctx) { - assert(!this.red, 'Already a number in reduction context'); - return this._forceRed(ctx); -}; + // Perform primitive values validation + var r = signature.r; + var s = signature.s; + if (r.cmpn(1) < 0 || r.cmp(this.n) >= 0) + return false; + if (s.cmpn(1) < 0 || s.cmp(this.n) >= 0) + return false; -BN.prototype.redAdd = function redAdd(num) { - assert(this.red, 'redAdd works only with red numbers'); - return this.red.add(this, num); -}; + // Validate signature + var sinv = s.invm(this.n); + var u1 = sinv.mul(msg).mod(this.n); + var u2 = sinv.mul(r).mod(this.n); -BN.prototype.redIAdd = function redIAdd(num) { - assert(this.red, 'redIAdd works only with red numbers'); - return this.red.iadd(this, num); -}; + var p = this.g.mulAdd(u1, key.getPublic(), u2); + if (p.isInfinity()) + return false; -BN.prototype.redSub = function redSub(num) { - assert(this.red, 'redSub works only with red numbers'); - return this.red.sub(this, num); + return p.getX().mod(this.n).cmp(r) === 0; }; -BN.prototype.redISub = function redISub(num) { - assert(this.red, 'redISub works only with red numbers'); - return this.red.isub(this, num); -}; +},{"../../elliptic":219,"./key":227,"./signature":228,"bn.js":217}],227:[function(require,module,exports){ +'use strict'; -BN.prototype.redShl = function redShl(num) { - assert(this.red, 'redShl works only with red numbers'); - return this.red.shl(this, num); -}; +var bn = require('bn.js'); -BN.prototype.redMul = function redMul(num) { - assert(this.red, 'redMul works only with red numbers'); - this.red._verify2(this, num); - return this.red.mul(this, num); -}; +var elliptic = require('../../elliptic'); +var utils = elliptic.utils; -BN.prototype.redIMul = function redIMul(num) { - assert(this.red, 'redMul works only with red numbers'); - this.red._verify2(this, num); - return this.red.imul(this, num); -}; +function KeyPair(ec, options) { + this.ec = ec; + this.priv = null; + this.pub = null; -BN.prototype.redSqr = function redSqr() { - assert(this.red, 'redSqr works only with red numbers'); - this.red._verify1(this); - return this.red.sqr(this); -}; + // KeyPair(ec, { priv: ..., pub: ... }) + if (options.priv) + this._importPrivate(options.priv, options.privEnc); + if (options.pub) + this._importPublic(options.pub, options.pubEnc); +} +module.exports = KeyPair; -BN.prototype.redISqr = function redISqr() { - assert(this.red, 'redISqr works only with red numbers'); - this.red._verify1(this); - return this.red.isqr(this); -}; +KeyPair.fromPublic = function fromPublic(ec, pub, enc) { + if (pub instanceof KeyPair) + return pub; -// Square root over p -BN.prototype.redSqrt = function redSqrt() { - assert(this.red, 'redSqrt works only with red numbers'); - this.red._verify1(this); - return this.red.sqrt(this); + return new KeyPair(ec, { + pub: pub, + pubEnc: enc + }); }; -BN.prototype.redInvm = function redInvm() { - assert(this.red, 'redInvm works only with red numbers'); - this.red._verify1(this); - return this.red.invm(this); -}; +KeyPair.fromPrivate = function fromPrivate(ec, priv, enc) { + if (priv instanceof KeyPair) + return priv; -// Return negative clone of `this` % `red modulo` -BN.prototype.redNeg = function redNeg() { - assert(this.red, 'redNeg works only with red numbers'); - this.red._verify1(this); - return this.red.neg(this); + return new KeyPair(ec, { + priv: priv, + privEnc: enc + }); }; -BN.prototype.redPow = function redPow(num) { - assert(this.red && !num.red, 'redPow(normalNum)'); - this.red._verify1(this); - return this.red.pow(this, num); -}; +KeyPair.prototype.validate = function validate() { + var pub = this.getPublic(); -// Prime numbers with efficient reduction -var primes = { - k256: null, - p224: null, - p192: null, - p25519: null + if (pub.isInfinity()) + return { result: false, reason: 'Invalid public key' }; + if (!pub.validate()) + return { result: false, reason: 'Public key is not a point' }; + if (!pub.mul(this.ec.curve.n).isInfinity()) + return { result: false, reason: 'Public key * N != O' }; + + return { result: true, reason: null }; }; -// Pseudo-Mersenne prime -function MPrime(name, p) { - // P = 2 ^ N - K - this.name = name; - this.p = new BN(p, 16); - this.n = this.p.bitLength(); - this.k = new BN(1).ishln(this.n).isub(this.p); +KeyPair.prototype.getPublic = function getPublic(compact, enc) { + if (!this.pub) + this.pub = this.ec.g.mul(this.priv); - this.tmp = this._tmp(); -} + // compact is optional argument + if (typeof compact === 'string') { + enc = compact; + compact = null; + } -MPrime.prototype._tmp = function _tmp() { - var tmp = new BN(null); - tmp.words = new Array(Math.ceil(this.n / 13)); - return tmp; -}; + if (!enc) + return this.pub; -MPrime.prototype.ireduce = function ireduce(num) { - // Assumes that `num` is less than `P^2` - // num = HI * (2 ^ N - K) + HI * K + LO = HI * K + LO (mod P) - var r = num; - var rlen; + var len = this.ec.curve.p.byteLength(); + var x = this.pub.getX().toArray(); - do { - var pair = r.ishrn(this.n, 0, this.tmp); - r = this.imulK(pair.hi); - r = r.iadd(pair.lo); - rlen = r.bitLength(); - } while (rlen > this.n); + for (var i = x.length; i < len; i++) + x.unshift(0); - var cmp = rlen < this.n ? -1 : r.cmp(this.p); - if (cmp === 0) { - r.words[0] = 0; - r.length = 1; - } else if (cmp > 0) { - r.isub(this.p); + var res; + if (this.ec.curve.type !== 'mont') { + if (compact) { + res = [ this.pub.getY().isEven() ? 0x02 : 0x03 ].concat(x); + } else { + var y = this.pub.getY().toArray(); + for (var i = y.length; i < len; i++) + y.unshift(0); + var res = [ 0x04 ].concat(x, y); + } } else { - r.strip(); + res = x; } - return r; + return utils.encode(res, enc); }; -MPrime.prototype.imulK = function imulK(num) { - return num.imul(this.k); +KeyPair.prototype.getPrivate = function getPrivate(enc) { + if (enc === 'hex') + return this.priv.toString(16, 2); + else + return this.priv; }; -function K256() { - MPrime.call( - this, - 'k256', - 'ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff fffffffe fffffc2f'); -} -inherits(K256, MPrime); +KeyPair.prototype._importPrivate = function _importPrivate(key, enc) { + this.priv = new bn(key, enc || 16); -K256.prototype.imulK = function imulK(num) { - // K = 0x1000003d1 = [ 0x40, 0x3d1 ] - num.words[num.length] = 0; - num.words[num.length + 1] = 0; - num.length += 2; + // Ensure that the priv won't be bigger than n, otherwise we may fail + // in fixed multiplication method + this.priv = this.priv.mod(this.ec.curve.n); +}; - var uhi = 0; - var hi = 0; - var lo = 0; - for (var i = 0; i < num.length; i++) { - var w = num.words[i]; - hi += w * 0x40; - lo += w * 0x3d1; - hi += (lo / 0x4000000) | 0; - uhi += (hi / 0x4000000) | 0; - hi &= 0x3ffffff; - lo &= 0x3ffffff; +KeyPair.prototype._importPublic = function _importPublic(key, enc) { + if (key.x || key.y) { + this.pub = this.ec.curve.point(key.x, key.y); + return; + } - num.words[i] = lo; + key = utils.toArray(key, enc); + if (this.ec.curve.type !== 'mont') + return this._importPublicShort(key); + else + return this._importPublicMont(key); +}; - lo = hi; - hi = uhi; - uhi = 0; +KeyPair.prototype._importPublicShort = function _importPublicShort(key) { + var len = this.ec.curve.p.byteLength(); + if (key[0] === 0x04 && key.length - 1 === 2 * len) { + this.pub = this.ec.curve.point( + key.slice(1, 1 + len), + key.slice(1 + len, 1 + 2 * len)); + } else if ((key[0] === 0x02 || key[0] === 0x03) && key.length - 1 === len) { + this.pub = this.ec.curve.pointFromX(key[0] === 0x03, key.slice(1, 1 + len)); } - - // Fast length reduction - if (num.words[num.length - 1] === 0) - num.length--; - if (num.words[num.length - 1] === 0) - num.length--; - return num; }; -function P224() { - MPrime.call( - this, - 'p224', - 'ffffffff ffffffff ffffffff ffffffff 00000000 00000000 00000001'); -} -inherits(P224, MPrime); +KeyPair.prototype._importPublicMont = function _importPublicMont(key) { + this.pub = this.ec.curve.point(key, 1); +}; -function P192() { - MPrime.call( - this, - 'p192', - 'ffffffff ffffffff ffffffff fffffffe ffffffff ffffffff'); -} -inherits(P192, MPrime); +// ECDH +KeyPair.prototype.derive = function derive(pub) { + return pub.mul(this.priv).getX(); +}; -function P25519() { - // 2 ^ 255 - 19 - MPrime.call( - this, - '25519', - '7fffffffffffffff ffffffffffffffff ffffffffffffffff ffffffffffffffed'); -} -inherits(P25519, MPrime); +// ECDSA +KeyPair.prototype.sign = function sign(msg) { + return this.ec.sign(msg, this); +}; -P25519.prototype.imulK = function imulK(num) { - // K = 0x13 - var carry = 0; - for (var i = 0; i < num.length; i++) { - var hi = num.words[i] * 0x13 + carry; - var lo = hi & 0x3ffffff; - hi >>>= 26; +KeyPair.prototype.verify = function verify(msg, signature) { + return this.ec.verify(msg, signature, this); +}; - num.words[i] = lo; - carry = hi; - } - if (carry !== 0) - num.words[num.length++] = carry; - return num; +KeyPair.prototype.inspect = function inspect() { + return ''; }; -// Exported mostly for testing purposes, use plain name instead -BN._prime = function prime(name) { - // Cached version of prime - if (primes[name]) - return primes[name]; +},{"../../elliptic":219,"bn.js":217}],228:[function(require,module,exports){ +'use strict'; - var prime; - if (name === 'k256') - prime = new K256(); - else if (name === 'p224') - prime = new P224(); - else if (name === 'p192') - prime = new P192(); - else if (name === 'p25519') - prime = new P25519(); - else - throw new Error('Unknown prime ' + name); - primes[name] = prime; +var bn = require('bn.js'); - return prime; -} +var elliptic = require('../../elliptic'); +var utils = elliptic.utils; +var assert = utils.assert; -// -// Base reduction engine -// -function Red(m) { - if (typeof m === 'string') { - var prime = BN._prime(m); - this.m = prime.p; - this.prime = prime; - } else { - this.m = m; - this.prime = null; - } +function Signature(options, enc) { + if (options instanceof Signature) + return options; + + if (this._importDER(options, enc)) + return; + + assert(options.r && options.s, 'Signature without r or s'); + this.r = new bn(options.r, 16); + this.s = new bn(options.s, 16); } +module.exports = Signature; -Red.prototype._verify1 = function _verify1(a) { - assert(!a.sign, 'red works only with positives'); - assert(a.red, 'red works only with red numbers'); -}; +Signature.prototype._importDER = function _importDER(data, enc) { + data = utils.toArray(data, enc); + if (data.length < 6 || data[0] !== 0x30 || data[2] !== 0x02) + return false; + var total = data[1]; + if (1 + total > data.length) + return false; + var rlen = data[3]; + // Short length notation + if (rlen >= 0x80) + return false; + if (4 + rlen + 2 >= data.length) + return false; + if (data[4 + rlen] !== 0x02) + return false; + var slen = data[5 + rlen]; + // Short length notation + if (slen >= 0x80) + return false; + if (4 + rlen + 2 + slen > data.length) + return false; -Red.prototype._verify2 = function _verify2(a, b) { - assert(!a.sign && !b.sign, 'red works only with positives'); - assert(a.red && a.red === b.red, - 'red works only with red numbers'); -}; + this.r = new bn(data.slice(4, 4 + rlen)); + this.s = new bn(data.slice(4 + rlen + 2, 4 + rlen + 2 + slen)); -Red.prototype.imod = function imod(a) { - if (this.prime) - return this.prime.ireduce(a)._forceRed(this); - return a.mod(this.m)._forceRed(this); + return true; }; -Red.prototype.neg = function neg(a) { - var r = a.clone(); - r.sign = !r.sign; - return r.iadd(this.m)._forceRed(this); -}; +Signature.prototype.toDER = function toDER(enc) { + var r = this.r.toArray(); + var s = this.s.toArray(); -Red.prototype.add = function add(a, b) { - this._verify2(a, b); + // Pad values + if (r[0] & 0x80) + r = [ 0 ].concat(r); + // Pad values + if (s[0] & 0x80) + s = [ 0 ].concat(s); - var res = a.add(b); - if (res.cmp(this.m) >= 0) - res.isub(this.m); - return res._forceRed(this); + var total = r.length + s.length + 4; + var res = [ 0x30, total, 0x02, r.length ]; + res = res.concat(r, [ 0x02, s.length ], s); + return utils.encode(res, enc); }; -Red.prototype.iadd = function iadd(a, b) { - this._verify2(a, b); +},{"../../elliptic":219,"bn.js":217}],229:[function(require,module,exports){ +'use strict'; - var res = a.iadd(b); - if (res.cmp(this.m) >= 0) - res.isub(this.m); - return res; -}; +var hash = require('hash.js'); +var elliptic = require('../elliptic'); +var utils = elliptic.utils; +var assert = utils.assert; -Red.prototype.sub = function sub(a, b) { - this._verify2(a, b); +function HmacDRBG(options) { + if (!(this instanceof HmacDRBG)) + return new HmacDRBG(options); + this.hash = options.hash; + this.predResist = !!options.predResist; - var res = a.sub(b); - if (res.cmpn(0) < 0) - res.iadd(this.m); - return res._forceRed(this); -}; + this.outLen = this.hash.outSize; + this.minEntropy = options.minEntropy || this.hash.hmacStrength; -Red.prototype.isub = function isub(a, b) { - this._verify2(a, b); + this.reseed = null; + this.reseedInterval = null; + this.K = null; + this.V = null; - var res = a.isub(b); - if (res.cmpn(0) < 0) - res.iadd(this.m); - return res; + var entropy = utils.toArray(options.entropy, options.entropyEnc); + var nonce = utils.toArray(options.nonce, options.nonceEnc); + var pers = utils.toArray(options.pers, options.persEnc); + assert(entropy.length >= (this.minEntropy / 8), + 'Not enough entropy. Minimum is: ' + this.minEntropy + ' bits'); + this._init(entropy, nonce, pers); +} +module.exports = HmacDRBG; + +HmacDRBG.prototype._init = function init(entropy, nonce, pers) { + var seed = entropy.concat(nonce).concat(pers); + + this.K = new Array(this.outLen / 8); + this.V = new Array(this.outLen / 8); + for (var i = 0; i < this.V.length; i++) { + this.K[i] = 0x00; + this.V[i] = 0x01; + } + + this._update(seed); + this.reseed = 1; + this.reseedInterval = 0x1000000000000; // 2^48 }; -Red.prototype.shl = function shl(a, num) { - this._verify1(a); - return this.imod(a.shln(num)); +HmacDRBG.prototype._hmac = function hmac() { + return new hash.hmac(this.hash, this.K); }; -Red.prototype.imul = function imul(a, b) { - this._verify2(a, b); - return this.imod(a.imul(b)); +HmacDRBG.prototype._update = function update(seed) { + var kmac = this._hmac() + .update(this.V) + .update([ 0x00 ]); + if (seed) + kmac = kmac.update(seed); + this.K = kmac.digest(); + this.V = this._hmac().update(this.V).digest(); + if (!seed) + return; + + this.K = this._hmac() + .update(this.V) + .update([ 0x01 ]) + .update(seed) + .digest(); + this.V = this._hmac().update(this.V).digest(); }; -Red.prototype.mul = function mul(a, b) { - this._verify2(a, b); - return this.imod(a.mul(b)); -}; +HmacDRBG.prototype.reseed = function reseed(entropy, entropyEnc, add, addEnc) { + // Optional entropy enc + if (typeof entropyEnc !== 'string') { + addEnc = add; + add = entropyEnc; + entropyEnc = null; + } -Red.prototype.isqr = function isqr(a) { - return this.imul(a, a); -}; + entropy = utils.toBuffer(entropy, entropyEnc); + add = utils.toBuffer(add, addEnc); -Red.prototype.sqr = function sqr(a) { - return this.mul(a, a); -}; + assert(entropy.length >= (this.minEntropy / 8), + 'Not enough entropy. Minimum is: ' + this.minEntropy + ' bits'); -Red.prototype.sqrt = function sqrt(a) { - if (a.cmpn(0) === 0) - return a.clone(); + this._update(entropy.concat(add || [])); + this.reseed = 1; +}; - var mod3 = this.m.andln(3); - assert(mod3 % 2 === 1); +HmacDRBG.prototype.generate = function generate(len, enc, add, addEnc) { + if (this.reseed > this.reseedInterval) + throw new Error('Reseed is required'); - // Fast case - if (mod3 === 3) { - var pow = this.m.add(new BN(1)).ishrn(2); - var r = this.pow(a, pow); - return r; + // Optional encoding + if (typeof enc !== 'string') { + addEnc = add; + add = enc; + enc = null; } - // Tonelli-Shanks algorithm (Totally unoptimized and slow) - // - // Find Q and S, that Q * 2 ^ S = (P - 1) - var q = this.m.subn(1); - var s = 0; - while (q.cmpn(0) !== 0 && q.andln(1) === 0) { - s++; - q.ishrn(1); + // Optional additional data + if (add) { + add = utils.toArray(add, addEnc); + this._update(add); } - assert(q.cmpn(0) !== 0); - - var one = new BN(1).toRed(this); - var nOne = one.redNeg(); - - // Find quadratic non-residue - // NOTE: Max is such because of generalized Riemann hypothesis. - var lpow = this.m.subn(1).ishrn(1); - var z = this.m.bitLength(); - z = new BN(2 * z * z).toRed(this); - while (this.pow(z, lpow).cmp(nOne) !== 0) - z.redIAdd(nOne); - - var c = this.pow(z, q); - var r = this.pow(a, q.addn(1).ishrn(1)); - var t = this.pow(a, q); - var m = s; - while (t.cmp(one) !== 0) { - var tmp = t; - for (var i = 0; tmp.cmp(one) !== 0; i++) - tmp = tmp.redSqr(); - assert(i < m); - var b = this.pow(c, new BN(1).ishln(m - i - 1)); - r = r.redMul(b); - c = b.redSqr(); - t = t.redMul(c); - m = i; + var temp = []; + while (temp.length < len) { + this.V = this._hmac().update(this.V).digest(); + temp = temp.concat(this.V); } - return r; + var res = temp.slice(0, len); + this._update(add); + this.reseed++; + return utils.encode(res, enc); }; -Red.prototype.invm = function invm(a) { - var inv = a._egcd(new BN(1), this.m); - if (inv.sign) { - inv.sign = false; - return this.imod(inv).redNeg(); - } else { - return this.imod(inv); +},{"../elliptic":219,"hash.js":234}],230:[function(require,module,exports){ +module.exports = { + doubles: { + step: 4, + points: [ + [ + 'e60fce93b59e9ec53011aabc21c23e97b2a31369b87a5ae9c44ee89e2a6dec0a', + 'f7e3507399e595929db99f34f57937101296891e44d23f0be1f32cce69616821' + ], + [ + '8282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508', + '11f8a8098557dfe45e8256e830b60ace62d613ac2f7b17bed31b6eaff6e26caf' + ], + [ + '175e159f728b865a72f99cc6c6fc846de0b93833fd2222ed73fce5b551e5b739', + 'd3506e0d9e3c79eba4ef97a51ff71f5eacb5955add24345c6efa6ffee9fed695' + ], + [ + '363d90d447b00c9c99ceac05b6262ee053441c7e55552ffe526bad8f83ff4640', + '4e273adfc732221953b445397f3363145b9a89008199ecb62003c7f3bee9de9' + ], + [ + '8b4b5f165df3c2be8c6244b5b745638843e4a781a15bcd1b69f79a55dffdf80c', + '4aad0a6f68d308b4b3fbd7813ab0da04f9e336546162ee56b3eff0c65fd4fd36' + ], + [ + '723cbaa6e5db996d6bf771c00bd548c7b700dbffa6c0e77bcb6115925232fcda', + '96e867b5595cc498a921137488824d6e2660a0653779494801dc069d9eb39f5f' + ], + [ + 'eebfa4d493bebf98ba5feec812c2d3b50947961237a919839a533eca0e7dd7fa', + '5d9a8ca3970ef0f269ee7edaf178089d9ae4cdc3a711f712ddfd4fdae1de8999' + ], + [ + '100f44da696e71672791d0a09b7bde459f1215a29b3c03bfefd7835b39a48db0', + 'cdd9e13192a00b772ec8f3300c090666b7ff4a18ff5195ac0fbd5cd62bc65a09' + ], + [ + 'e1031be262c7ed1b1dc9227a4a04c017a77f8d4464f3b3852c8acde6e534fd2d', + '9d7061928940405e6bb6a4176597535af292dd419e1ced79a44f18f29456a00d' + ], + [ + 'feea6cae46d55b530ac2839f143bd7ec5cf8b266a41d6af52d5e688d9094696d', + 'e57c6b6c97dce1bab06e4e12bf3ecd5c981c8957cc41442d3155debf18090088' + ], + [ + 'da67a91d91049cdcb367be4be6ffca3cfeed657d808583de33fa978bc1ec6cb1', + '9bacaa35481642bc41f463f7ec9780e5dec7adc508f740a17e9ea8e27a68be1d' + ], + [ + '53904faa0b334cdda6e000935ef22151ec08d0f7bb11069f57545ccc1a37b7c0', + '5bc087d0bc80106d88c9eccac20d3c1c13999981e14434699dcb096b022771c8' + ], + [ + '8e7bcd0bd35983a7719cca7764ca906779b53a043a9b8bcaeff959f43ad86047', + '10b7770b2a3da4b3940310420ca9514579e88e2e47fd68b3ea10047e8460372a' + ], + [ + '385eed34c1cdff21e6d0818689b81bde71a7f4f18397e6690a841e1599c43862', + '283bebc3e8ea23f56701de19e9ebf4576b304eec2086dc8cc0458fe5542e5453' + ], + [ + '6f9d9b803ecf191637c73a4413dfa180fddf84a5947fbc9c606ed86c3fac3a7', + '7c80c68e603059ba69b8e2a30e45c4d47ea4dd2f5c281002d86890603a842160' + ], + [ + '3322d401243c4e2582a2147c104d6ecbf774d163db0f5e5313b7e0e742d0e6bd', + '56e70797e9664ef5bfb019bc4ddaf9b72805f63ea2873af624f3a2e96c28b2a0' + ], + [ + '85672c7d2de0b7da2bd1770d89665868741b3f9af7643397721d74d28134ab83', + '7c481b9b5b43b2eb6374049bfa62c2e5e77f17fcc5298f44c8e3094f790313a6' + ], + [ + '948bf809b1988a46b06c9f1919413b10f9226c60f668832ffd959af60c82a0a', + '53a562856dcb6646dc6b74c5d1c3418c6d4dff08c97cd2bed4cb7f88d8c8e589' + ], + [ + '6260ce7f461801c34f067ce0f02873a8f1b0e44dfc69752accecd819f38fd8e8', + 'bc2da82b6fa5b571a7f09049776a1ef7ecd292238051c198c1a84e95b2b4ae17' + ], + [ + 'e5037de0afc1d8d43d8348414bbf4103043ec8f575bfdc432953cc8d2037fa2d', + '4571534baa94d3b5f9f98d09fb990bddbd5f5b03ec481f10e0e5dc841d755bda' + ], + [ + 'e06372b0f4a207adf5ea905e8f1771b4e7e8dbd1c6a6c5b725866a0ae4fce725', + '7a908974bce18cfe12a27bb2ad5a488cd7484a7787104870b27034f94eee31dd' + ], + [ + '213c7a715cd5d45358d0bbf9dc0ce02204b10bdde2a3f58540ad6908d0559754', + '4b6dad0b5ae462507013ad06245ba190bb4850f5f36a7eeddff2c27534b458f2' + ], + [ + '4e7c272a7af4b34e8dbb9352a5419a87e2838c70adc62cddf0cc3a3b08fbd53c', + '17749c766c9d0b18e16fd09f6def681b530b9614bff7dd33e0b3941817dcaae6' + ], + [ + 'fea74e3dbe778b1b10f238ad61686aa5c76e3db2be43057632427e2840fb27b6', + '6e0568db9b0b13297cf674deccb6af93126b596b973f7b77701d3db7f23cb96f' + ], + [ + '76e64113f677cf0e10a2570d599968d31544e179b760432952c02a4417bdde39', + 'c90ddf8dee4e95cf577066d70681f0d35e2a33d2b56d2032b4b1752d1901ac01' + ], + [ + 'c738c56b03b2abe1e8281baa743f8f9a8f7cc643df26cbee3ab150242bcbb891', + '893fb578951ad2537f718f2eacbfbbbb82314eef7880cfe917e735d9699a84c3' + ], + [ + 'd895626548b65b81e264c7637c972877d1d72e5f3a925014372e9f6588f6c14b', + 'febfaa38f2bc7eae728ec60818c340eb03428d632bb067e179363ed75d7d991f' + ], + [ + 'b8da94032a957518eb0f6433571e8761ceffc73693e84edd49150a564f676e03', + '2804dfa44805a1e4d7c99cc9762808b092cc584d95ff3b511488e4e74efdf6e7' + ], + [ + 'e80fea14441fb33a7d8adab9475d7fab2019effb5156a792f1a11778e3c0df5d', + 'eed1de7f638e00771e89768ca3ca94472d155e80af322ea9fcb4291b6ac9ec78' + ], + [ + 'a301697bdfcd704313ba48e51d567543f2a182031efd6915ddc07bbcc4e16070', + '7370f91cfb67e4f5081809fa25d40f9b1735dbf7c0a11a130c0d1a041e177ea1' + ], + [ + '90ad85b389d6b936463f9d0512678de208cc330b11307fffab7ac63e3fb04ed4', + 'e507a3620a38261affdcbd9427222b839aefabe1582894d991d4d48cb6ef150' + ], + [ + '8f68b9d2f63b5f339239c1ad981f162ee88c5678723ea3351b7b444c9ec4c0da', + '662a9f2dba063986de1d90c2b6be215dbbea2cfe95510bfdf23cbf79501fff82' + ], + [ + 'e4f3fb0176af85d65ff99ff9198c36091f48e86503681e3e6686fd5053231e11', + '1e63633ad0ef4f1c1661a6d0ea02b7286cc7e74ec951d1c9822c38576feb73bc' + ], + [ + '8c00fa9b18ebf331eb961537a45a4266c7034f2f0d4e1d0716fb6eae20eae29e', + 'efa47267fea521a1a9dc343a3736c974c2fadafa81e36c54e7d2a4c66702414b' + ], + [ + 'e7a26ce69dd4829f3e10cec0a9e98ed3143d084f308b92c0997fddfc60cb3e41', + '2a758e300fa7984b471b006a1aafbb18d0a6b2c0420e83e20e8a9421cf2cfd51' + ], + [ + 'b6459e0ee3662ec8d23540c223bcbdc571cbcb967d79424f3cf29eb3de6b80ef', + '67c876d06f3e06de1dadf16e5661db3c4b3ae6d48e35b2ff30bf0b61a71ba45' + ], + [ + 'd68a80c8280bb840793234aa118f06231d6f1fc67e73c5a5deda0f5b496943e8', + 'db8ba9fff4b586d00c4b1f9177b0e28b5b0e7b8f7845295a294c84266b133120' + ], + [ + '324aed7df65c804252dc0270907a30b09612aeb973449cea4095980fc28d3d5d', + '648a365774b61f2ff130c0c35aec1f4f19213b0c7e332843967224af96ab7c84' + ], + [ + '4df9c14919cde61f6d51dfdbe5fee5dceec4143ba8d1ca888e8bd373fd054c96', + '35ec51092d8728050974c23a1d85d4b5d506cdc288490192ebac06cad10d5d' + ], + [ + '9c3919a84a474870faed8a9c1cc66021523489054d7f0308cbfc99c8ac1f98cd', + 'ddb84f0f4a4ddd57584f044bf260e641905326f76c64c8e6be7e5e03d4fc599d' + ], + [ + '6057170b1dd12fdf8de05f281d8e06bb91e1493a8b91d4cc5a21382120a959e5', + '9a1af0b26a6a4807add9a2daf71df262465152bc3ee24c65e899be932385a2a8' + ], + [ + 'a576df8e23a08411421439a4518da31880cef0fba7d4df12b1a6973eecb94266', + '40a6bf20e76640b2c92b97afe58cd82c432e10a7f514d9f3ee8be11ae1b28ec8' + ], + [ + '7778a78c28dec3e30a05fe9629de8c38bb30d1f5cf9a3a208f763889be58ad71', + '34626d9ab5a5b22ff7098e12f2ff580087b38411ff24ac563b513fc1fd9f43ac' + ], + [ + '928955ee637a84463729fd30e7afd2ed5f96274e5ad7e5cb09eda9c06d903ac', + 'c25621003d3f42a827b78a13093a95eeac3d26efa8a8d83fc5180e935bcd091f' + ], + [ + '85d0fef3ec6db109399064f3a0e3b2855645b4a907ad354527aae75163d82751', + '1f03648413a38c0be29d496e582cf5663e8751e96877331582c237a24eb1f962' + ], + [ + 'ff2b0dce97eece97c1c9b6041798b85dfdfb6d8882da20308f5404824526087e', + '493d13fef524ba188af4c4dc54d07936c7b7ed6fb90e2ceb2c951e01f0c29907' + ], + [ + '827fbbe4b1e880ea9ed2b2e6301b212b57f1ee148cd6dd28780e5e2cf856e241', + 'c60f9c923c727b0b71bef2c67d1d12687ff7a63186903166d605b68baec293ec' + ], + [ + 'eaa649f21f51bdbae7be4ae34ce6e5217a58fdce7f47f9aa7f3b58fa2120e2b3', + 'be3279ed5bbbb03ac69a80f89879aa5a01a6b965f13f7e59d47a5305ba5ad93d' + ], + [ + 'e4a42d43c5cf169d9391df6decf42ee541b6d8f0c9a137401e23632dda34d24f', + '4d9f92e716d1c73526fc99ccfb8ad34ce886eedfa8d8e4f13a7f7131deba9414' + ], + [ + '1ec80fef360cbdd954160fadab352b6b92b53576a88fea4947173b9d4300bf19', + 'aeefe93756b5340d2f3a4958a7abbf5e0146e77f6295a07b671cdc1cc107cefd' + ], + [ + '146a778c04670c2f91b00af4680dfa8bce3490717d58ba889ddb5928366642be', + 'b318e0ec3354028add669827f9d4b2870aaa971d2f7e5ed1d0b297483d83efd0' + ], + [ + 'fa50c0f61d22e5f07e3acebb1aa07b128d0012209a28b9776d76a8793180eef9', + '6b84c6922397eba9b72cd2872281a68a5e683293a57a213b38cd8d7d3f4f2811' + ], + [ + 'da1d61d0ca721a11b1a5bf6b7d88e8421a288ab5d5bba5220e53d32b5f067ec2', + '8157f55a7c99306c79c0766161c91e2966a73899d279b48a655fba0f1ad836f1' + ], + [ + 'a8e282ff0c9706907215ff98e8fd416615311de0446f1e062a73b0610d064e13', + '7f97355b8db81c09abfb7f3c5b2515888b679a3e50dd6bd6cef7c73111f4cc0c' + ], + [ + '174a53b9c9a285872d39e56e6913cab15d59b1fa512508c022f382de8319497c', + 'ccc9dc37abfc9c1657b4155f2c47f9e6646b3a1d8cb9854383da13ac079afa73' + ], + [ + '959396981943785c3d3e57edf5018cdbe039e730e4918b3d884fdff09475b7ba', + '2e7e552888c331dd8ba0386a4b9cd6849c653f64c8709385e9b8abf87524f2fd' + ], + [ + 'd2a63a50ae401e56d645a1153b109a8fcca0a43d561fba2dbb51340c9d82b151', + 'e82d86fb6443fcb7565aee58b2948220a70f750af484ca52d4142174dcf89405' + ], + [ + '64587e2335471eb890ee7896d7cfdc866bacbdbd3839317b3436f9b45617e073', + 'd99fcdd5bf6902e2ae96dd6447c299a185b90a39133aeab358299e5e9faf6589' + ], + [ + '8481bde0e4e4d885b3a546d3e549de042f0aa6cea250e7fd358d6c86dd45e458', + '38ee7b8cba5404dd84a25bf39cecb2ca900a79c42b262e556d64b1b59779057e' + ], + [ + '13464a57a78102aa62b6979ae817f4637ffcfed3c4b1ce30bcd6303f6caf666b', + '69be159004614580ef7e433453ccb0ca48f300a81d0942e13f495a907f6ecc27' + ], + [ + 'bc4a9df5b713fe2e9aef430bcc1dc97a0cd9ccede2f28588cada3a0d2d83f366', + 'd3a81ca6e785c06383937adf4b798caa6e8a9fbfa547b16d758d666581f33c1' + ], + [ + '8c28a97bf8298bc0d23d8c749452a32e694b65e30a9472a3954ab30fe5324caa', + '40a30463a3305193378fedf31f7cc0eb7ae784f0451cb9459e71dc73cbef9482' + ], + [ + '8ea9666139527a8c1dd94ce4f071fd23c8b350c5a4bb33748c4ba111faccae0', + '620efabbc8ee2782e24e7c0cfb95c5d735b783be9cf0f8e955af34a30e62b945' + ], + [ + 'dd3625faef5ba06074669716bbd3788d89bdde815959968092f76cc4eb9a9787', + '7a188fa3520e30d461da2501045731ca941461982883395937f68d00c644a573' + ], + [ + 'f710d79d9eb962297e4f6232b40e8f7feb2bc63814614d692c12de752408221e', + 'ea98e67232d3b3295d3b535532115ccac8612c721851617526ae47a9c77bfc82' + ] + ] + }, + naf: { + wnd: 7, + points: [ + [ + 'f9308a019258c31049344f85f89d5229b531c845836f99b08601f113bce036f9', + '388f7b0f632de8140fe337e62a37f3566500a99934c2231b6cb9fd7584b8e672' + ], + [ + '2f8bde4d1a07209355b4a7250a5c5128e88b84bddc619ab7cba8d569b240efe4', + 'd8ac222636e5e3d6d4dba9dda6c9c426f788271bab0d6840dca87d3aa6ac62d6' + ], + [ + '5cbdf0646e5db4eaa398f365f2ea7a0e3d419b7e0330e39ce92bddedcac4f9bc', + '6aebca40ba255960a3178d6d861a54dba813d0b813fde7b5a5082628087264da' + ], + [ + 'acd484e2f0c7f65309ad178a9f559abde09796974c57e714c35f110dfc27ccbe', + 'cc338921b0a7d9fd64380971763b61e9add888a4375f8e0f05cc262ac64f9c37' + ], + [ + '774ae7f858a9411e5ef4246b70c65aac5649980be5c17891bbec17895da008cb', + 'd984a032eb6b5e190243dd56d7b7b365372db1e2dff9d6a8301d74c9c953c61b' + ], + [ + 'f28773c2d975288bc7d1d205c3748651b075fbc6610e58cddeeddf8f19405aa8', + 'ab0902e8d880a89758212eb65cdaf473a1a06da521fa91f29b5cb52db03ed81' + ], + [ + 'd7924d4f7d43ea965a465ae3095ff41131e5946f3c85f79e44adbcf8e27e080e', + '581e2872a86c72a683842ec228cc6defea40af2bd896d3a5c504dc9ff6a26b58' + ], + [ + 'defdea4cdb677750a420fee807eacf21eb9898ae79b9768766e4faa04a2d4a34', + '4211ab0694635168e997b0ead2a93daeced1f4a04a95c0f6cfb199f69e56eb77' + ], + [ + '2b4ea0a797a443d293ef5cff444f4979f06acfebd7e86d277475656138385b6c', + '85e89bc037945d93b343083b5a1c86131a01f60c50269763b570c854e5c09b7a' + ], + [ + '352bbf4a4cdd12564f93fa332ce333301d9ad40271f8107181340aef25be59d5', + '321eb4075348f534d59c18259dda3e1f4a1b3b2e71b1039c67bd3d8bcf81998c' + ], + [ + '2fa2104d6b38d11b0230010559879124e42ab8dfeff5ff29dc9cdadd4ecacc3f', + '2de1068295dd865b64569335bd5dd80181d70ecfc882648423ba76b532b7d67' + ], + [ + '9248279b09b4d68dab21a9b066edda83263c3d84e09572e269ca0cd7f5453714', + '73016f7bf234aade5d1aa71bdea2b1ff3fc0de2a887912ffe54a32ce97cb3402' + ], + [ + 'daed4f2be3a8bf278e70132fb0beb7522f570e144bf615c07e996d443dee8729', + 'a69dce4a7d6c98e8d4a1aca87ef8d7003f83c230f3afa726ab40e52290be1c55' + ], + [ + 'c44d12c7065d812e8acf28d7cbb19f9011ecd9e9fdf281b0e6a3b5e87d22e7db', + '2119a460ce326cdc76c45926c982fdac0e106e861edf61c5a039063f0e0e6482' + ], + [ + '6a245bf6dc698504c89a20cfded60853152b695336c28063b61c65cbd269e6b4', + 'e022cf42c2bd4a708b3f5126f16a24ad8b33ba48d0423b6efd5e6348100d8a82' + ], + [ + '1697ffa6fd9de627c077e3d2fe541084ce13300b0bec1146f95ae57f0d0bd6a5', + 'b9c398f186806f5d27561506e4557433a2cf15009e498ae7adee9d63d01b2396' + ], + [ + '605bdb019981718b986d0f07e834cb0d9deb8360ffb7f61df982345ef27a7479', + '2972d2de4f8d20681a78d93ec96fe23c26bfae84fb14db43b01e1e9056b8c49' + ], + [ + '62d14dab4150bf497402fdc45a215e10dcb01c354959b10cfe31c7e9d87ff33d', + '80fc06bd8cc5b01098088a1950eed0db01aa132967ab472235f5642483b25eaf' + ], + [ + '80c60ad0040f27dade5b4b06c408e56b2c50e9f56b9b8b425e555c2f86308b6f', + '1c38303f1cc5c30f26e66bad7fe72f70a65eed4cbe7024eb1aa01f56430bd57a' + ], + [ + '7a9375ad6167ad54aa74c6348cc54d344cc5dc9487d847049d5eabb0fa03c8fb', + 'd0e3fa9eca8726909559e0d79269046bdc59ea10c70ce2b02d499ec224dc7f7' + ], + [ + 'd528ecd9b696b54c907a9ed045447a79bb408ec39b68df504bb51f459bc3ffc9', + 'eecf41253136e5f99966f21881fd656ebc4345405c520dbc063465b521409933' + ], + [ + '49370a4b5f43412ea25f514e8ecdad05266115e4a7ecb1387231808f8b45963', + '758f3f41afd6ed428b3081b0512fd62a54c3f3afbb5b6764b653052a12949c9a' + ], + [ + '77f230936ee88cbbd73df930d64702ef881d811e0e1498e2f1c13eb1fc345d74', + '958ef42a7886b6400a08266e9ba1b37896c95330d97077cbbe8eb3c7671c60d6' + ], + [ + 'f2dac991cc4ce4b9ea44887e5c7c0bce58c80074ab9d4dbaeb28531b7739f530', + 'e0dedc9b3b2f8dad4da1f32dec2531df9eb5fbeb0598e4fd1a117dba703a3c37' + ], + [ + '463b3d9f662621fb1b4be8fbbe2520125a216cdfc9dae3debcba4850c690d45b', + '5ed430d78c296c3543114306dd8622d7c622e27c970a1de31cb377b01af7307e' + ], + [ + 'f16f804244e46e2a09232d4aff3b59976b98fac14328a2d1a32496b49998f247', + 'cedabd9b82203f7e13d206fcdf4e33d92a6c53c26e5cce26d6579962c4e31df6' + ], + [ + 'caf754272dc84563b0352b7a14311af55d245315ace27c65369e15f7151d41d1', + 'cb474660ef35f5f2a41b643fa5e460575f4fa9b7962232a5c32f908318a04476' + ], + [ + '2600ca4b282cb986f85d0f1709979d8b44a09c07cb86d7c124497bc86f082120', + '4119b88753c15bd6a693b03fcddbb45d5ac6be74ab5f0ef44b0be9475a7e4b40' + ], + [ + '7635ca72d7e8432c338ec53cd12220bc01c48685e24f7dc8c602a7746998e435', + '91b649609489d613d1d5e590f78e6d74ecfc061d57048bad9e76f302c5b9c61' + ], + [ + '754e3239f325570cdbbf4a87deee8a66b7f2b33479d468fbc1a50743bf56cc18', + '673fb86e5bda30fb3cd0ed304ea49a023ee33d0197a695d0c5d98093c536683' + ], + [ + 'e3e6bd1071a1e96aff57859c82d570f0330800661d1c952f9fe2694691d9b9e8', + '59c9e0bba394e76f40c0aa58379a3cb6a5a2283993e90c4167002af4920e37f5' + ], + [ + '186b483d056a033826ae73d88f732985c4ccb1f32ba35f4b4cc47fdcf04aa6eb', + '3b952d32c67cf77e2e17446e204180ab21fb8090895138b4a4a797f86e80888b' + ], + [ + 'df9d70a6b9876ce544c98561f4be4f725442e6d2b737d9c91a8321724ce0963f', + '55eb2dafd84d6ccd5f862b785dc39d4ab157222720ef9da217b8c45cf2ba2417' + ], + [ + '5edd5cc23c51e87a497ca815d5dce0f8ab52554f849ed8995de64c5f34ce7143', + 'efae9c8dbc14130661e8cec030c89ad0c13c66c0d17a2905cdc706ab7399a868' + ], + [ + '290798c2b6476830da12fe02287e9e777aa3fba1c355b17a722d362f84614fba', + 'e38da76dcd440621988d00bcf79af25d5b29c094db2a23146d003afd41943e7a' + ], + [ + 'af3c423a95d9f5b3054754efa150ac39cd29552fe360257362dfdecef4053b45', + 'f98a3fd831eb2b749a93b0e6f35cfb40c8cd5aa667a15581bc2feded498fd9c6' + ], + [ + '766dbb24d134e745cccaa28c99bf274906bb66b26dcf98df8d2fed50d884249a', + '744b1152eacbe5e38dcc887980da38b897584a65fa06cedd2c924f97cbac5996' + ], + [ + '59dbf46f8c94759ba21277c33784f41645f7b44f6c596a58ce92e666191abe3e', + 'c534ad44175fbc300f4ea6ce648309a042ce739a7919798cd85e216c4a307f6e' + ], + [ + 'f13ada95103c4537305e691e74e9a4a8dd647e711a95e73cb62dc6018cfd87b8', + 'e13817b44ee14de663bf4bc808341f326949e21a6a75c2570778419bdaf5733d' + ], + [ + '7754b4fa0e8aced06d4167a2c59cca4cda1869c06ebadfb6488550015a88522c', + '30e93e864e669d82224b967c3020b8fa8d1e4e350b6cbcc537a48b57841163a2' + ], + [ + '948dcadf5990e048aa3874d46abef9d701858f95de8041d2a6828c99e2262519', + 'e491a42537f6e597d5d28a3224b1bc25df9154efbd2ef1d2cbba2cae5347d57e' + ], + [ + '7962414450c76c1689c7b48f8202ec37fb224cf5ac0bfa1570328a8a3d7c77ab', + '100b610ec4ffb4760d5c1fc133ef6f6b12507a051f04ac5760afa5b29db83437' + ], + [ + '3514087834964b54b15b160644d915485a16977225b8847bb0dd085137ec47ca', + 'ef0afbb2056205448e1652c48e8127fc6039e77c15c2378b7e7d15a0de293311' + ], + [ + 'd3cc30ad6b483e4bc79ce2c9dd8bc54993e947eb8df787b442943d3f7b527eaf', + '8b378a22d827278d89c5e9be8f9508ae3c2ad46290358630afb34db04eede0a4' + ], + [ + '1624d84780732860ce1c78fcbfefe08b2b29823db913f6493975ba0ff4847610', + '68651cf9b6da903e0914448c6cd9d4ca896878f5282be4c8cc06e2a404078575' + ], + [ + '733ce80da955a8a26902c95633e62a985192474b5af207da6df7b4fd5fc61cd4', + 'f5435a2bd2badf7d485a4d8b8db9fcce3e1ef8e0201e4578c54673bc1dc5ea1d' + ], + [ + '15d9441254945064cf1a1c33bbd3b49f8966c5092171e699ef258dfab81c045c', + 'd56eb30b69463e7234f5137b73b84177434800bacebfc685fc37bbe9efe4070d' + ], + [ + 'a1d0fcf2ec9de675b612136e5ce70d271c21417c9d2b8aaaac138599d0717940', + 'edd77f50bcb5a3cab2e90737309667f2641462a54070f3d519212d39c197a629' + ], + [ + 'e22fbe15c0af8ccc5780c0735f84dbe9a790badee8245c06c7ca37331cb36980', + 'a855babad5cd60c88b430a69f53a1a7a38289154964799be43d06d77d31da06' + ], + [ + '311091dd9860e8e20ee13473c1155f5f69635e394704eaa74009452246cfa9b3', + '66db656f87d1f04fffd1f04788c06830871ec5a64feee685bd80f0b1286d8374' + ], + [ + '34c1fd04d301be89b31c0442d3e6ac24883928b45a9340781867d4232ec2dbdf', + '9414685e97b1b5954bd46f730174136d57f1ceeb487443dc5321857ba73abee' + ], + [ + 'f219ea5d6b54701c1c14de5b557eb42a8d13f3abbcd08affcc2a5e6b049b8d63', + '4cb95957e83d40b0f73af4544cccf6b1f4b08d3c07b27fb8d8c2962a400766d1' + ], + [ + 'd7b8740f74a8fbaab1f683db8f45de26543a5490bca627087236912469a0b448', + 'fa77968128d9c92ee1010f337ad4717eff15db5ed3c049b3411e0315eaa4593b' + ], + [ + '32d31c222f8f6f0ef86f7c98d3a3335ead5bcd32abdd94289fe4d3091aa824bf', + '5f3032f5892156e39ccd3d7915b9e1da2e6dac9e6f26e961118d14b8462e1661' + ], + [ + '7461f371914ab32671045a155d9831ea8793d77cd59592c4340f86cbc18347b5', + '8ec0ba238b96bec0cbdddcae0aa442542eee1ff50c986ea6b39847b3cc092ff6' + ], + [ + 'ee079adb1df1860074356a25aa38206a6d716b2c3e67453d287698bad7b2b2d6', + '8dc2412aafe3be5c4c5f37e0ecc5f9f6a446989af04c4e25ebaac479ec1c8c1e' + ], + [ + '16ec93e447ec83f0467b18302ee620f7e65de331874c9dc72bfd8616ba9da6b5', + '5e4631150e62fb40d0e8c2a7ca5804a39d58186a50e497139626778e25b0674d' + ], + [ + 'eaa5f980c245f6f038978290afa70b6bd8855897f98b6aa485b96065d537bd99', + 'f65f5d3e292c2e0819a528391c994624d784869d7e6ea67fb18041024edc07dc' + ], + [ + '78c9407544ac132692ee1910a02439958ae04877151342ea96c4b6b35a49f51', + 'f3e0319169eb9b85d5404795539a5e68fa1fbd583c064d2462b675f194a3ddb4' + ], + [ + '494f4be219a1a77016dcd838431aea0001cdc8ae7a6fc688726578d9702857a5', + '42242a969283a5f339ba7f075e36ba2af925ce30d767ed6e55f4b031880d562c' + ], + [ + 'a598a8030da6d86c6bc7f2f5144ea549d28211ea58faa70ebf4c1e665c1fe9b5', + '204b5d6f84822c307e4b4a7140737aec23fc63b65b35f86a10026dbd2d864e6b' + ], + [ + 'c41916365abb2b5d09192f5f2dbeafec208f020f12570a184dbadc3e58595997', + '4f14351d0087efa49d245b328984989d5caf9450f34bfc0ed16e96b58fa9913' + ], + [ + '841d6063a586fa475a724604da03bc5b92a2e0d2e0a36acfe4c73a5514742881', + '73867f59c0659e81904f9a1c7543698e62562d6744c169ce7a36de01a8d6154' + ], + [ + '5e95bb399a6971d376026947f89bde2f282b33810928be4ded112ac4d70e20d5', + '39f23f366809085beebfc71181313775a99c9aed7d8ba38b161384c746012865' + ], + [ + '36e4641a53948fd476c39f8a99fd974e5ec07564b5315d8bf99471bca0ef2f66', + 'd2424b1b1abe4eb8164227b085c9aa9456ea13493fd563e06fd51cf5694c78fc' + ], + [ + '336581ea7bfbbb290c191a2f507a41cf5643842170e914faeab27c2c579f726', + 'ead12168595fe1be99252129b6e56b3391f7ab1410cd1e0ef3dcdcabd2fda224' + ], + [ + '8ab89816dadfd6b6a1f2634fcf00ec8403781025ed6890c4849742706bd43ede', + '6fdcef09f2f6d0a044e654aef624136f503d459c3e89845858a47a9129cdd24e' + ], + [ + '1e33f1a746c9c5778133344d9299fcaa20b0938e8acff2544bb40284b8c5fb94', + '60660257dd11b3aa9c8ed618d24edff2306d320f1d03010e33a7d2057f3b3b6' + ], + [ + '85b7c1dcb3cec1b7ee7f30ded79dd20a0ed1f4cc18cbcfcfa410361fd8f08f31', + '3d98a9cdd026dd43f39048f25a8847f4fcafad1895d7a633c6fed3c35e999511' + ], + [ + '29df9fbd8d9e46509275f4b125d6d45d7fbe9a3b878a7af872a2800661ac5f51', + 'b4c4fe99c775a606e2d8862179139ffda61dc861c019e55cd2876eb2a27d84b' + ], + [ + 'a0b1cae06b0a847a3fea6e671aaf8adfdfe58ca2f768105c8082b2e449fce252', + 'ae434102edde0958ec4b19d917a6a28e6b72da1834aff0e650f049503a296cf2' + ], + [ + '4e8ceafb9b3e9a136dc7ff67e840295b499dfb3b2133e4ba113f2e4c0e121e5', + 'cf2174118c8b6d7a4b48f6d534ce5c79422c086a63460502b827ce62a326683c' + ], + [ + 'd24a44e047e19b6f5afb81c7ca2f69080a5076689a010919f42725c2b789a33b', + '6fb8d5591b466f8fc63db50f1c0f1c69013f996887b8244d2cdec417afea8fa3' + ], + [ + 'ea01606a7a6c9cdd249fdfcfacb99584001edd28abbab77b5104e98e8e3b35d4', + '322af4908c7312b0cfbfe369f7a7b3cdb7d4494bc2823700cfd652188a3ea98d' + ], + [ + 'af8addbf2b661c8a6c6328655eb96651252007d8c5ea31be4ad196de8ce2131f', + '6749e67c029b85f52a034eafd096836b2520818680e26ac8f3dfbcdb71749700' + ], + [ + 'e3ae1974566ca06cc516d47e0fb165a674a3dabcfca15e722f0e3450f45889', + '2aeabe7e4531510116217f07bf4d07300de97e4874f81f533420a72eeb0bd6a4' + ], + [ + '591ee355313d99721cf6993ffed1e3e301993ff3ed258802075ea8ced397e246', + 'b0ea558a113c30bea60fc4775460c7901ff0b053d25ca2bdeee98f1a4be5d196' + ], + [ + '11396d55fda54c49f19aa97318d8da61fa8584e47b084945077cf03255b52984', + '998c74a8cd45ac01289d5833a7beb4744ff536b01b257be4c5767bea93ea57a4' + ], + [ + '3c5d2a1ba39c5a1790000738c9e0c40b8dcdfd5468754b6405540157e017aa7a', + 'b2284279995a34e2f9d4de7396fc18b80f9b8b9fdd270f6661f79ca4c81bd257' + ], + [ + 'cc8704b8a60a0defa3a99a7299f2e9c3fbc395afb04ac078425ef8a1793cc030', + 'bdd46039feed17881d1e0862db347f8cf395b74fc4bcdc4e940b74e3ac1f1b13' + ], + [ + 'c533e4f7ea8555aacd9777ac5cad29b97dd4defccc53ee7ea204119b2889b197', + '6f0a256bc5efdf429a2fb6242f1a43a2d9b925bb4a4b3a26bb8e0f45eb596096' + ], + [ + 'c14f8f2ccb27d6f109f6d08d03cc96a69ba8c34eec07bbcf566d48e33da6593', + 'c359d6923bb398f7fd4473e16fe1c28475b740dd098075e6c0e8649113dc3a38' + ], + [ + 'a6cbc3046bc6a450bac24789fa17115a4c9739ed75f8f21ce441f72e0b90e6ef', + '21ae7f4680e889bb130619e2c0f95a360ceb573c70603139862afd617fa9b9f' + ], + [ + '347d6d9a02c48927ebfb86c1359b1caf130a3c0267d11ce6344b39f99d43cc38', + '60ea7f61a353524d1c987f6ecec92f086d565ab687870cb12689ff1e31c74448' + ], + [ + 'da6545d2181db8d983f7dcb375ef5866d47c67b1bf31c8cf855ef7437b72656a', + '49b96715ab6878a79e78f07ce5680c5d6673051b4935bd897fea824b77dc208a' + ], + [ + 'c40747cc9d012cb1a13b8148309c6de7ec25d6945d657146b9d5994b8feb1111', + '5ca560753be2a12fc6de6caf2cb489565db936156b9514e1bb5e83037e0fa2d4' + ], + [ + '4e42c8ec82c99798ccf3a610be870e78338c7f713348bd34c8203ef4037f3502', + '7571d74ee5e0fb92a7a8b33a07783341a5492144cc54bcc40a94473693606437' + ], + [ + '3775ab7089bc6af823aba2e1af70b236d251cadb0c86743287522a1b3b0dedea', + 'be52d107bcfa09d8bcb9736a828cfa7fac8db17bf7a76a2c42ad961409018cf7' + ], + [ + 'cee31cbf7e34ec379d94fb814d3d775ad954595d1314ba8846959e3e82f74e26', + '8fd64a14c06b589c26b947ae2bcf6bfa0149ef0be14ed4d80f448a01c43b1c6d' + ], + [ + 'b4f9eaea09b6917619f6ea6a4eb5464efddb58fd45b1ebefcdc1a01d08b47986', + '39e5c9925b5a54b07433a4f18c61726f8bb131c012ca542eb24a8ac07200682a' + ], + [ + 'd4263dfc3d2df923a0179a48966d30ce84e2515afc3dccc1b77907792ebcc60e', + '62dfaf07a0f78feb30e30d6295853ce189e127760ad6cf7fae164e122a208d54' + ], + [ + '48457524820fa65a4f8d35eb6930857c0032acc0a4a2de422233eeda897612c4', + '25a748ab367979d98733c38a1fa1c2e7dc6cc07db2d60a9ae7a76aaa49bd0f77' + ], + [ + 'dfeeef1881101f2cb11644f3a2afdfc2045e19919152923f367a1767c11cceda', + 'ecfb7056cf1de042f9420bab396793c0c390bde74b4bbdff16a83ae09a9a7517' + ], + [ + '6d7ef6b17543f8373c573f44e1f389835d89bcbc6062ced36c82df83b8fae859', + 'cd450ec335438986dfefa10c57fea9bcc521a0959b2d80bbf74b190dca712d10' + ], + [ + 'e75605d59102a5a2684500d3b991f2e3f3c88b93225547035af25af66e04541f', + 'f5c54754a8f71ee540b9b48728473e314f729ac5308b06938360990e2bfad125' + ], + [ + 'eb98660f4c4dfaa06a2be453d5020bc99a0c2e60abe388457dd43fefb1ed620c', + '6cb9a8876d9cb8520609af3add26cd20a0a7cd8a9411131ce85f44100099223e' + ], + [ + '13e87b027d8514d35939f2e6892b19922154596941888336dc3563e3b8dba942', + 'fef5a3c68059a6dec5d624114bf1e91aac2b9da568d6abeb2570d55646b8adf1' + ], + [ + 'ee163026e9fd6fe017c38f06a5be6fc125424b371ce2708e7bf4491691e5764a', + '1acb250f255dd61c43d94ccc670d0f58f49ae3fa15b96623e5430da0ad6c62b2' + ], + [ + 'b268f5ef9ad51e4d78de3a750c2dc89b1e626d43505867999932e5db33af3d80', + '5f310d4b3c99b9ebb19f77d41c1dee018cf0d34fd4191614003e945a1216e423' + ], + [ + 'ff07f3118a9df035e9fad85eb6c7bfe42b02f01ca99ceea3bf7ffdba93c4750d', + '438136d603e858a3a5c440c38eccbaddc1d2942114e2eddd4740d098ced1f0d8' + ], + [ + '8d8b9855c7c052a34146fd20ffb658bea4b9f69e0d825ebec16e8c3ce2b526a1', + 'cdb559eedc2d79f926baf44fb84ea4d44bcf50fee51d7ceb30e2e7f463036758' + ], + [ + '52db0b5384dfbf05bfa9d472d7ae26dfe4b851ceca91b1eba54263180da32b63', + 'c3b997d050ee5d423ebaf66a6db9f57b3180c902875679de924b69d84a7b375' + ], + [ + 'e62f9490d3d51da6395efd24e80919cc7d0f29c3f3fa48c6fff543becbd43352', + '6d89ad7ba4876b0b22c2ca280c682862f342c8591f1daf5170e07bfd9ccafa7d' + ], + [ + '7f30ea2476b399b4957509c88f77d0191afa2ff5cb7b14fd6d8e7d65aaab1193', + 'ca5ef7d4b231c94c3b15389a5f6311e9daff7bb67b103e9880ef4bff637acaec' + ], + [ + '5098ff1e1d9f14fb46a210fada6c903fef0fb7b4a1dd1d9ac60a0361800b7a00', + '9731141d81fc8f8084d37c6e7542006b3ee1b40d60dfe5362a5b132fd17ddc0' + ], + [ + '32b78c7de9ee512a72895be6b9cbefa6e2f3c4ccce445c96b9f2c81e2778ad58', + 'ee1849f513df71e32efc3896ee28260c73bb80547ae2275ba497237794c8753c' + ], + [ + 'e2cb74fddc8e9fbcd076eef2a7c72b0ce37d50f08269dfc074b581550547a4f7', + 'd3aa2ed71c9dd2247a62df062736eb0baddea9e36122d2be8641abcb005cc4a4' + ], + [ + '8438447566d4d7bedadc299496ab357426009a35f235cb141be0d99cd10ae3a8', + 'c4e1020916980a4da5d01ac5e6ad330734ef0d7906631c4f2390426b2edd791f' + ], + [ + '4162d488b89402039b584c6fc6c308870587d9c46f660b878ab65c82c711d67e', + '67163e903236289f776f22c25fb8a3afc1732f2b84b4e95dbda47ae5a0852649' + ], + [ + '3fad3fa84caf0f34f0f89bfd2dcf54fc175d767aec3e50684f3ba4a4bf5f683d', + 'cd1bc7cb6cc407bb2f0ca647c718a730cf71872e7d0d2a53fa20efcdfe61826' + ], + [ + '674f2600a3007a00568c1a7ce05d0816c1fb84bf1370798f1c69532faeb1a86b', + '299d21f9413f33b3edf43b257004580b70db57da0b182259e09eecc69e0d38a5' + ], + [ + 'd32f4da54ade74abb81b815ad1fb3b263d82d6c692714bcff87d29bd5ee9f08f', + 'f9429e738b8e53b968e99016c059707782e14f4535359d582fc416910b3eea87' + ], + [ + '30e4e670435385556e593657135845d36fbb6931f72b08cb1ed954f1e3ce3ff6', + '462f9bce619898638499350113bbc9b10a878d35da70740dc695a559eb88db7b' + ], + [ + 'be2062003c51cc3004682904330e4dee7f3dcd10b01e580bf1971b04d4cad297', + '62188bc49d61e5428573d48a74e1c655b1c61090905682a0d5558ed72dccb9bc' + ], + [ + '93144423ace3451ed29e0fb9ac2af211cb6e84a601df5993c419859fff5df04a', + '7c10dfb164c3425f5c71a3f9d7992038f1065224f72bb9d1d902a6d13037b47c' + ], + [ + 'b015f8044f5fcbdcf21ca26d6c34fb8197829205c7b7d2a7cb66418c157b112c', + 'ab8c1e086d04e813744a655b2df8d5f83b3cdc6faa3088c1d3aea1454e3a1d5f' + ], + [ + 'd5e9e1da649d97d89e4868117a465a3a4f8a18de57a140d36b3f2af341a21b52', + '4cb04437f391ed73111a13cc1d4dd0db1693465c2240480d8955e8592f27447a' + ], + [ + 'd3ae41047dd7ca065dbf8ed77b992439983005cd72e16d6f996a5316d36966bb', + 'bd1aeb21ad22ebb22a10f0303417c6d964f8cdd7df0aca614b10dc14d125ac46' + ], + [ + '463e2763d885f958fc66cdd22800f0a487197d0a82e377b49f80af87c897b065', + 'bfefacdb0e5d0fd7df3a311a94de062b26b80c61fbc97508b79992671ef7ca7f' + ], + [ + '7985fdfd127c0567c6f53ec1bb63ec3158e597c40bfe747c83cddfc910641917', + '603c12daf3d9862ef2b25fe1de289aed24ed291e0ec6708703a5bd567f32ed03' + ], + [ + '74a1ad6b5f76e39db2dd249410eac7f99e74c59cb83d2d0ed5ff1543da7703e9', + 'cc6157ef18c9c63cd6193d83631bbea0093e0968942e8c33d5737fd790e0db08' + ], + [ + '30682a50703375f602d416664ba19b7fc9bab42c72747463a71d0896b22f6da3', + '553e04f6b018b4fa6c8f39e7f311d3176290d0e0f19ca73f17714d9977a22ff8' + ], + [ + '9e2158f0d7c0d5f26c3791efefa79597654e7a2b2464f52b1ee6c1347769ef57', + '712fcdd1b9053f09003a3481fa7762e9ffd7c8ef35a38509e2fbf2629008373' + ], + [ + '176e26989a43c9cfeba4029c202538c28172e566e3c4fce7322857f3be327d66', + 'ed8cc9d04b29eb877d270b4878dc43c19aefd31f4eee09ee7b47834c1fa4b1c3' + ], + [ + '75d46efea3771e6e68abb89a13ad747ecf1892393dfc4f1b7004788c50374da8', + '9852390a99507679fd0b86fd2b39a868d7efc22151346e1a3ca4726586a6bed8' + ], + [ + '809a20c67d64900ffb698c4c825f6d5f2310fb0451c869345b7319f645605721', + '9e994980d9917e22b76b061927fa04143d096ccc54963e6a5ebfa5f3f8e286c1' + ], + [ + '1b38903a43f7f114ed4500b4eac7083fdefece1cf29c63528d563446f972c180', + '4036edc931a60ae889353f77fd53de4a2708b26b6f5da72ad3394119daf408f9' + ] + ] } }; -Red.prototype.pow = function pow(a, num) { - var w = []; - var q = num.clone(); - while (q.cmpn(0) !== 0) { - w.push(q.andln(1)); - q.ishrn(1); - } +},{}],231:[function(require,module,exports){ +'use strict'; - // Skip leading zeroes - var res = a; - for (var i = 0; i < w.length; i++, res = this.sqr(res)) - if (w[i] !== 0) - break; +var utils = exports; - if (++i < w.length) { - for (var q = this.sqr(res); i < w.length; i++, q = this.sqr(q)) { - if (w[i] === 0) - continue; - res = this.mul(res, q); +utils.assert = function assert(val, msg) { + if (!val) + throw new Error(msg || 'Assertion failed'); +}; + +function toArray(msg, enc) { + if (Array.isArray(msg)) + return msg.slice(); + if (!msg) + return []; + var res = []; + if (typeof msg !== 'string') { + for (var i = 0; i < msg.length; i++) + res[i] = msg[i] | 0; + return res; + } + if (!enc) { + for (var i = 0; i < msg.length; i++) { + var c = msg.charCodeAt(i); + var hi = c >> 8; + var lo = c & 0xff; + if (hi) + res.push(hi, lo); + else + res.push(lo); } + } else if (enc === 'hex') { + msg = msg.replace(/[^a-z0-9]+/ig, ''); + if (msg.length % 2 !== 0) + msg = '0' + msg; + for (var i = 0; i < msg.length; i += 2) + res.push(parseInt(msg[i] + msg[i + 1], 16)); } - return res; -}; +} +utils.toArray = toArray; -Red.prototype.convertTo = function convertTo(num) { - return num.clone(); -}; +function zero2(word) { + if (word.length === 1) + return '0' + word; + else + return word; +} +utils.zero2 = zero2; -Red.prototype.convertFrom = function convertFrom(num) { - var res = num.clone(); - res.red = null; +function toHex(msg) { + var res = ''; + for (var i = 0; i < msg.length; i++) + res += zero2(msg[i].toString(16)); return res; -}; - -// -// Montgomery method engine -// +} +utils.toHex = toHex; -BN.mont = function mont(num) { - return new Mont(num); +utils.encode = function encode(arr, enc) { + if (enc === 'hex') + return toHex(arr); + else + return arr; }; -function Mont(m) { - Red.call(this, m); +// Represent num in a w-NAF form +function getNAF(num, w) { + var naf = []; + var ws = 1 << (w + 1); + var k = num.clone(); + while (k.cmpn(1) >= 0) { + var z; + if (k.isOdd()) { + var mod = k.andln(ws - 1); + if (mod > (ws >> 1) - 1) + z = (ws >> 1) - mod; + else + z = mod; + k.isubn(z); + } else { + z = 0; + } + naf.push(z); - this.shift = this.m.bitLength(); - if (this.shift % 26 !== 0) - this.shift += 26 - (this.shift % 26); - this.r = new BN(1).ishln(this.shift); - this.r2 = this.imod(this.r.sqr()); - this.rinv = this.r.invm(this.m); + // Optimization, shift by word if possible + var shift = (k.cmpn(0) !== 0 && k.andln(ws - 1) === 0) ? (w + 1) : 1; + for (var i = 1; i < shift; i++) + naf.push(0); + k.ishrn(shift); + } - // TODO(indutny): simplify it - this.minv = this.rinv.mul(this.r) - .sub(new BN(1)) - .div(this.m) - .neg() - .mod(this.r); + return naf; } -inherits(Mont, Red); +utils.getNAF = getNAF; -Mont.prototype.convertTo = function convertTo(num) { - return this.imod(num.shln(this.shift)); -}; +// Represent k1, k2 in a Joint Sparse Form +function getJSF(k1, k2) { + var jsf = [ + [], + [] + ]; -Mont.prototype.convertFrom = function convertFrom(num) { - var r = this.imod(num.mul(this.rinv)); - r.red = null; - return r; -}; + k1 = k1.clone(); + k2 = k2.clone(); + var d1 = 0; + var d2 = 0; + while (k1.cmpn(-d1) > 0 || k2.cmpn(-d2) > 0) { -Mont.prototype.imul = function imul(a, b) { - if (a.cmpn(0) === 0 || b.cmpn(0) === 0) { - a.words[0] = 0; - a.length = 1; - return a; + // First phase + var m14 = (k1.andln(3) + d1) & 3; + var m24 = (k2.andln(3) + d2) & 3; + if (m14 === 3) + m14 = -1; + if (m24 === 3) + m24 = -1; + var u1; + if ((m14 & 1) === 0) { + u1 = 0; + } else { + var m8 = (k1.andln(7) + d1) & 7; + if ((m8 === 3 || m8 === 5) && m24 === 2) + u1 = -m14; + else + u1 = m14; + } + jsf[0].push(u1); + + var u2; + if ((m24 & 1) === 0) { + u2 = 0; + } else { + var m8 = (k2.andln(7) + d2) & 7; + if ((m8 === 3 || m8 === 5) && m14 === 2) + u2 = -m24; + else + u2 = m24; + } + jsf[1].push(u2); + + // Second phase + if (2 * d1 === u1 + 1) + d1 = 1 - d1; + if (2 * d2 === u2 + 1) + d2 = 1 - d2; + k1.ishrn(1); + k2.ishrn(1); } - var t = a.imul(b); - var c = t.maskn(this.shift).mul(this.minv).imaskn(this.shift).mul(this.m); - var u = t.isub(c).ishrn(this.shift); - var res = u; - if (u.cmp(this.m) >= 0) - res = u.isub(this.m); - else if (u.cmpn(0) < 0) - res = u.iadd(this.m); + return jsf; +} +utils.getJSF = getJSF; - return res._forceRed(this); -}; +},{}],232:[function(require,module,exports){ +module.exports=require(144) +},{"/home/braydon/bitcore/node_modules/bitcore-build/node_modules/browserify/node_modules/crypto-browserify/node_modules/diffie-hellman/node_modules/miller-rabin/node_modules/brorand/index.js":144}],233:[function(require,module,exports){ +module.exports={ + "name": "elliptic", + "version": "3.0.3", + "description": "EC cryptography", + "main": "lib/elliptic.js", + "scripts": { + "test": "make lint && mocha --reporter=spec test/*-test.js" + }, + "repository": { + "type": "git", + "url": "git+ssh://git@github.com/indutny/elliptic.git" + }, + "keywords": [ + "EC", + "Elliptic", + "curve", + "Cryptography" + ], + "author": { + "name": "Fedor Indutny", + "email": "fedor@indutny.com" + }, + "license": "MIT", + "bugs": { + "url": "https://github.com/indutny/elliptic/issues" + }, + "homepage": "https://github.com/indutny/elliptic", + "devDependencies": { + "browserify": "^3.44.2", + "jscs": "^1.11.3", + "jshint": "^2.6.0", + "mocha": "^2.1.0", + "uglify-js": "^2.4.13" + }, + "dependencies": { + "bn.js": "^2.0.0", + "brorand": "^1.0.1", + "hash.js": "^1.0.0", + "inherits": "^2.0.1" + }, + "readme": "# Elliptic [![Build Status](https://secure.travis-ci.org/indutny/elliptic.png)](http://travis-ci.org/indutny/elliptic)\n\nFast elliptic-curve cryptography in a plain javascript implementation.\n\nNOTE: Please take a look at http://safecurves.cr.yp.to/ before choosing a curve\nfor your cryptography operations.\n\n## Incentive\n\nECC is much slower than regular RSA cryptography, the JS implementations are\neven more slower.\n\n## Benchmarks\n\n```bash\n$ node benchmarks/index.js\nBenchmarking: sign\nelliptic#sign x 262 ops/sec ±0.51% (177 runs sampled)\neccjs#sign x 55.91 ops/sec ±0.90% (144 runs sampled)\n------------------------\nFastest is elliptic#sign\n========================\nBenchmarking: verify\nelliptic#verify x 113 ops/sec ±0.50% (166 runs sampled)\neccjs#verify x 48.56 ops/sec ±0.36% (125 runs sampled)\n------------------------\nFastest is elliptic#verify\n========================\nBenchmarking: gen\nelliptic#gen x 294 ops/sec ±0.43% (176 runs sampled)\neccjs#gen x 62.25 ops/sec ±0.63% (129 runs sampled)\n------------------------\nFastest is elliptic#gen\n========================\nBenchmarking: ecdh\nelliptic#ecdh x 136 ops/sec ±0.85% (156 runs sampled)\n------------------------\nFastest is elliptic#ecdh\n========================\n```\n\n## API\n\n### ECDSA\n\n```javascript\nvar EC = require('elliptic').ec;\n\n// Create and initialize EC context\n// (better do it once and reuse it)\nvar ec = new EC('secp256k1');\n\n// Generate keys\nvar key = ec.genKeyPair();\n\n// Sign message (must be an array, or it'll be treated as a hex sequence)\nvar msg = [ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 ];\nvar signature = key.sign(msg);\n\n// Export DER encoded signature in Array\nvar derSign = signature.toDER();\n\n// Verify signature\nconsole.log(key.verify(msg, derSign));\n```\n\n### ECDH\n\n```javascript\n// Generate keys\nvar key1 = ec.genKeyPair();\nvar key2 = ec.genKeyPair();\n\nvar shared1 = key1.derive(key2.getPublic());\nvar shared2 = key2.derive(key1.getPublic());\n\nconsole.log('Both shared secrets are BN instances');\nconsole.log(shared1.toString(16));\nconsole.log(shared2.toString(16));\n```\n\nNOTE: `.derive()` returns a [BN][1] instance.\n\n## Supported curves\n\nElliptic.js support following curve types:\n\n* Short Weierstrass\n* Montgomery\n* Edwards\n* Twisted Edwards\n\nFollowing curve 'presets' are embedded into the library:\n\n* `secp256k1`\n* `p192`\n* `p224`\n* `p256`\n* `curve25519`\n* `ed25519`\n\nNOTE: That `curve25519` could not be used for ECDSA, use `ed25519` instead.\n\n### Implementation details\n\nECDSA is using deterministic `k` value generation as per [RFC6979][0]. Most of\nthe curve operations are performed on non-affine coordinates (either projective\nor extended), various windowing techniques are used for different cases.\n\nAll operations are performed in reduction context using [bn.js][1], hashing is\nprovided by [hash.js][2]\n\n### Related projects\n\n* [eccrypto][3]: isomorphic implementation of ECDSA, ECDH and ECIES for both\n browserify and node (uses `elliptic` for browser and [secp256k1-node][4] for\n node)\n\n#### LICENSE\n\nThis software is licensed under the MIT License.\n\nCopyright Fedor Indutny, 2014.\n\nPermission is hereby granted, free of charge, to any person obtaining a\ncopy of this software and associated documentation files (the\n\"Software\"), to deal in the Software without restriction, including\nwithout limitation the rights to use, copy, modify, merge, publish,\ndistribute, sublicense, and/or sell copies of the Software, and to permit\npersons to whom the Software is furnished to do so, subject to the\nfollowing conditions:\n\nThe above copyright notice and this permission notice shall be included\nin all copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS\nOR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\nMERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN\nNO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,\nDAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\nOTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE\nUSE OR OTHER DEALINGS IN THE SOFTWARE.\n\n[0]: http://tools.ietf.org/html/rfc6979\n[1]: https://github.com/indutny/bn.js\n[2]: https://github.com/indutny/hash.js\n[3]: https://github.com/bitchan/eccrypto\n[4]: https://github.com/wanderer/secp256k1-node\n", + "readmeFilename": "README.md", + "_id": "elliptic@3.0.3", + "_shasum": "865c9b420bfbe55006b9f969f97a0d2c44966595", + "_resolved": "https://registry.npmjs.org/elliptic/-/elliptic-3.0.3.tgz", + "_from": "https://registry.npmjs.org/elliptic/-/elliptic-3.0.3.tgz" +} -Mont.prototype.mul = function mul(a, b) { - if (a.cmpn(0) === 0 || b.cmpn(0) === 0) - return new BN(0)._forceRed(this); +},{}],234:[function(require,module,exports){ +var hash = exports; - var t = a.mul(b); - var c = t.maskn(this.shift).mul(this.minv).imaskn(this.shift).mul(this.m); - var u = t.isub(c).ishrn(this.shift); - var res = u; - if (u.cmp(this.m) >= 0) - res = u.isub(this.m); - else if (u.cmpn(0) < 0) - res = u.iadd(this.m); +hash.utils = require('./hash/utils'); +hash.common = require('./hash/common'); +hash.sha = require('./hash/sha'); +hash.ripemd = require('./hash/ripemd'); +hash.hmac = require('./hash/hmac'); - return res._forceRed(this); -}; +// Proxy hash functions to the main object +hash.sha1 = hash.sha.sha1; +hash.sha256 = hash.sha.sha256; +hash.sha224 = hash.sha.sha224; +hash.sha384 = hash.sha.sha384; +hash.sha512 = hash.sha.sha512; +hash.ripemd160 = hash.ripemd.ripemd160; -Mont.prototype.invm = function invm(a) { - // (AR)^-1 * R^2 = (A^-1 * R^-1) * R^2 = A^-1 * R - var res = this.imod(a.invm(this.m).mul(this.r2)); - return res._forceRed(this); -}; +},{"./hash/common":235,"./hash/hmac":236,"./hash/ripemd":237,"./hash/sha":238,"./hash/utils":239}],235:[function(require,module,exports){ +var hash = require('../hash'); +var utils = hash.utils; +var assert = utils.assert; -},{}],208:[function(require,module,exports){ -// Base58 encoding/decoding -// Originally written by Mike Hearn for BitcoinJ -// Copyright (c) 2011 Google Inc -// Ported to JavaScript by Stefan Thomas -// Merged Buffer refactorings from base58-native by Stephen Pair -// Copyright (c) 2013 BitPay Inc +function BlockHash() { + this.pending = null; + this.pendingTotal = 0; + this.blockSize = this.constructor.blockSize; + this.outSize = this.constructor.outSize; + this.hmacStrength = this.constructor.hmacStrength; + this.padLength = this.constructor.padLength / 8; + this.endian = 'big'; -var ALPHABET = '123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz' -var ALPHABET_MAP = {} -for(var i = 0; i < ALPHABET.length; i++) { - ALPHABET_MAP[ALPHABET.charAt(i)] = i + this._delta8 = this.blockSize / 8; + this._delta32 = this.blockSize / 32; } -var BASE = 58 +exports.BlockHash = BlockHash; -function encode(buffer) { - if (buffer.length === 0) return '' +BlockHash.prototype.update = function update(msg, enc) { + // Convert message to array, pad it, and join into 32bit blocks + msg = utils.toArray(msg, enc); + if (!this.pending) + this.pending = msg; + else + this.pending = this.pending.concat(msg); + this.pendingTotal += msg.length; - var i, j, digits = [0] - for (i = 0; i < buffer.length; i++) { - for (j = 0; j < digits.length; j++) digits[j] <<= 8 + // Enough data, try updating + if (this.pending.length >= this._delta8) { + msg = this.pending; - digits[0] += buffer[i] + // Process pending data in blocks + var r = msg.length % this._delta8; + this.pending = msg.slice(msg.length - r, msg.length); + if (this.pending.length === 0) + this.pending = null; - var carry = 0 - for (j = 0; j < digits.length; ++j) { - digits[j] += carry + msg = utils.join32(msg, 0, msg.length - r, this.endian); + for (var i = 0; i < msg.length; i += this._delta32) + this._update(msg, i, i + this._delta32); + } - carry = (digits[j] / BASE) | 0 - digits[j] %= BASE - } + return this; +}; - while (carry) { - digits.push(carry % BASE) +BlockHash.prototype.digest = function digest(enc) { + this.update(this._pad()); + assert(this.pending === null); - carry = (carry / BASE) | 0 - } - } + return this._digest(enc); +}; - // deal with leading zeros - for (i = 0; buffer[i] === 0 && i < buffer.length - 1; i++) digits.push(0) +BlockHash.prototype._pad = function pad() { + var len = this.pendingTotal; + var bytes = this._delta8; + var k = bytes - ((len + this.padLength) % bytes); + var res = new Array(k + this.padLength); + res[0] = 0x80; + for (var i = 1; i < k; i++) + res[i] = 0; - return digits.reverse().map(function(digit) { return ALPHABET[digit] }).join('') -} + // Append length + len <<= 3; + if (this.endian === 'big') { + for (var t = 8; t < this.padLength; t++) + res[i++] = 0; -function decode(string) { - if (string.length === 0) return [] + res[i++] = 0; + res[i++] = 0; + res[i++] = 0; + res[i++] = 0; + res[i++] = (len >>> 24) & 0xff; + res[i++] = (len >>> 16) & 0xff; + res[i++] = (len >>> 8) & 0xff; + res[i++] = len & 0xff; + } else { + res[i++] = len & 0xff; + res[i++] = (len >>> 8) & 0xff; + res[i++] = (len >>> 16) & 0xff; + res[i++] = (len >>> 24) & 0xff; + res[i++] = 0; + res[i++] = 0; + res[i++] = 0; + res[i++] = 0; - var i, j, bytes = [0] - for (i = 0; i < string.length; i++) { - var c = string[i] - if (!(c in ALPHABET_MAP)) throw new Error('Non-base58 character') + for (var t = 8; t < this.padLength; t++) + res[i++] = 0; + } - for (j = 0; j < bytes.length; j++) bytes[j] *= BASE - bytes[0] += ALPHABET_MAP[c] + return res; +}; - var carry = 0 - for (j = 0; j < bytes.length; ++j) { - bytes[j] += carry +},{"../hash":234}],236:[function(require,module,exports){ +var hmac = exports; - carry = bytes[j] >> 8 - bytes[j] &= 0xff - } +var hash = require('../hash'); +var utils = hash.utils; +var assert = utils.assert; - while (carry) { - bytes.push(carry & 0xff) +function Hmac(hash, key, enc) { + if (!(this instanceof Hmac)) + return new Hmac(hash, key, enc); + this.Hash = hash; + this.blockSize = hash.blockSize / 8; + this.outSize = hash.outSize / 8; + this.inner = null; + this.outer = null; - carry >>= 8 - } - } + this._init(utils.toArray(key, enc)); +} +module.exports = Hmac; - // deal with leading zeros - for (i = 0; string[i] === '1' && i < string.length - 1; i++) bytes.push(0) +Hmac.prototype._init = function init(key) { + // Shorten key, if needed + if (key.length > this.blockSize) + key = new this.Hash().update(key).digest(); + assert(key.length <= this.blockSize); - return bytes.reverse() -} + // Add padding to key + for (var i = key.length; i < this.blockSize; i++) + key.push(0); -module.exports = { - encode: encode, - decode: decode -} + for (var i = 0; i < key.length; i++) + key[i] ^= 0x36; + this.inner = new this.Hash().update(key); + + // 0x36 ^ 0x5c = 0x6a + for (var i = 0; i < key.length; i++) + key[i] ^= 0x6a; + this.outer = new this.Hash().update(key); +}; -},{}],209:[function(require,module,exports){ -arguments[4][69][0].apply(exports,arguments) -},{"../package.json":222,"./elliptic/curve":212,"./elliptic/curves":215,"./elliptic/ec":216,"./elliptic/hmac-drbg":219,"./elliptic/utils":220,"/Users/eordano/Code/bitcore/node_modules/bitcore-build/node_modules/browserify/node_modules/crypto-browserify/node_modules/browserify-sign/node_modules/elliptic/lib/elliptic.js":69,"brorand":221}],210:[function(require,module,exports){ -var assert = require('assert'); -var bn = require('bn.js'); -var elliptic = require('../../elliptic'); +Hmac.prototype.update = function update(msg, enc) { + this.inner.update(msg, enc); + return this; +}; -var getNAF = elliptic.utils.getNAF; -var getJSF = elliptic.utils.getJSF; +Hmac.prototype.digest = function digest(enc) { + this.outer.update(this.inner.digest()); + return this.outer.digest(enc); +}; -function BaseCurve(type, conf) { - this.type = type; - this.p = new bn(conf.p, 16); +},{"../hash":234}],237:[function(require,module,exports){ +var hash = require('../hash'); +var utils = hash.utils; - // Use Montgomery, when there is no fast reduction for the prime - this.red = conf.prime ? bn.red(conf.prime) : bn.mont(this.p); +var rotl32 = utils.rotl32; +var sum32 = utils.sum32; +var sum32_3 = utils.sum32_3; +var sum32_4 = utils.sum32_4; +var BlockHash = hash.common.BlockHash; - // Useful for many curves - this.zero = new bn(0).toRed(this.red); - this.one = new bn(1).toRed(this.red); - this.two = new bn(2).toRed(this.red); +function RIPEMD160() { + if (!(this instanceof RIPEMD160)) + return new RIPEMD160(); - // Curve configuration, optional - this.n = conf.n && new bn(conf.n, 16); - this.g = conf.g && this.pointFromJSON(conf.g, conf.gRed); + BlockHash.call(this); - // Temporary arrays - this._wnafT1 = new Array(4); - this._wnafT2 = new Array(4); - this._wnafT3 = new Array(4); - this._wnafT4 = new Array(4); + this.h = [ 0x67452301, 0xefcdab89, 0x98badcfe, 0x10325476, 0xc3d2e1f0 ]; + this.endian = 'little'; } -module.exports = BaseCurve; +utils.inherits(RIPEMD160, BlockHash); +exports.ripemd160 = RIPEMD160; -BaseCurve.prototype.point = function point() { - throw new Error('Not implemented'); +RIPEMD160.blockSize = 512; +RIPEMD160.outSize = 160; +RIPEMD160.hmacStrength = 192; +RIPEMD160.padLength = 64; + +RIPEMD160.prototype._update = function update(msg, start) { + var A = this.h[0]; + var B = this.h[1]; + var C = this.h[2]; + var D = this.h[3]; + var E = this.h[4]; + var Ah = A; + var Bh = B; + var Ch = C; + var Dh = D; + var Eh = E; + for (var j = 0; j < 80; j++) { + var T = sum32( + rotl32( + sum32_4(A, f(j, B, C, D), msg[r[j] + start], K(j)), + s[j]), + E); + A = E; + E = D; + D = rotl32(C, 10); + C = B; + B = T; + T = sum32( + rotl32( + sum32_4(Ah, f(79 - j, Bh, Ch, Dh), msg[rh[j] + start], Kh(j)), + sh[j]), + Eh); + Ah = Eh; + Eh = Dh; + Dh = rotl32(Ch, 10); + Ch = Bh; + Bh = T; + } + T = sum32_3(this.h[1], C, Dh); + this.h[1] = sum32_3(this.h[2], D, Eh); + this.h[2] = sum32_3(this.h[3], E, Ah); + this.h[3] = sum32_3(this.h[4], A, Bh); + this.h[4] = sum32_3(this.h[0], B, Ch); + this.h[0] = T; }; -BaseCurve.prototype.validate = function validate(point) { - throw new Error('Not implemented'); +RIPEMD160.prototype._digest = function digest(enc) { + if (enc === 'hex') + return utils.toHex32(this.h, 'little'); + else + return utils.split32(this.h, 'little'); }; -BaseCurve.prototype._fixedNafMul = function _fixedNafMul(p, k) { - var doubles = p._getDoubles(); +function f(j, x, y, z) { + if (j <= 15) + return x ^ y ^ z; + else if (j <= 31) + return (x & y) | ((~x) & z); + else if (j <= 47) + return (x | (~y)) ^ z; + else if (j <= 63) + return (x & z) | (y & (~z)); + else + return x ^ (y | (~z)); +} - var naf = getNAF(k, 1); - var I = (1 << (doubles.step + 1)) - (doubles.step % 2 === 0 ? 2 : 1); - I /= 3; +function K(j) { + if (j <= 15) + return 0x00000000; + else if (j <= 31) + return 0x5a827999; + else if (j <= 47) + return 0x6ed9eba1; + else if (j <= 63) + return 0x8f1bbcdc; + else + return 0xa953fd4e; +} - // Translate into more windowed form - var repr = []; - for (var j = 0; j < naf.length; j += doubles.step) { - var nafW = 0; - for (var k = j + doubles.step - 1; k >= j; k--) - nafW = (nafW << 1) + naf[k]; - repr.push(nafW); - } +function Kh(j) { + if (j <= 15) + return 0x50a28be6; + else if (j <= 31) + return 0x5c4dd124; + else if (j <= 47) + return 0x6d703ef3; + else if (j <= 63) + return 0x7a6d76e9; + else + return 0x00000000; +} - var a = this.jpoint(null, null, null); - var b = this.jpoint(null, null, null); - for (var i = I; i > 0; i--) { - for (var j = 0; j < repr.length; j++) { - var nafW = repr[j]; - if (nafW === i) - b = b.mixedAdd(doubles.points[j]); - else if (nafW === -i) - b = b.mixedAdd(doubles.points[j].neg()); - } - a = a.add(b); - } - return a.toP(); -}; +var r = [ + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, + 7, 4, 13, 1, 10, 6, 15, 3, 12, 0, 9, 5, 2, 14, 11, 8, + 3, 10, 14, 4, 9, 15, 8, 1, 2, 7, 0, 6, 13, 11, 5, 12, + 1, 9, 11, 10, 0, 8, 12, 4, 13, 3, 7, 15, 14, 5, 6, 2, + 4, 0, 5, 9, 7, 12, 2, 10, 14, 1, 3, 8, 11, 6, 15, 13, +]; -BaseCurve.prototype._wnafMul = function _wnafMul(p, k) { - var w = 4; +var rh = [ + 5, 14, 7, 0, 9, 2, 11, 4, 13, 6, 15, 8, 1, 10, 3, 12, + 6, 11, 3, 7, 0, 13, 5, 10, 14, 15, 8, 12, 4, 9, 1, 2, + 15, 5, 1, 3, 7, 14, 6, 9, 11, 8, 12, 2, 10, 0, 4, 13, + 8, 6, 4, 1, 3, 11, 15, 0, 5, 12, 2, 13, 9, 7, 10, 14, + 12, 15, 10, 4, 1, 5, 8, 7, 6, 2, 13, 14, 0, 3, 9, 11 +]; - // Precompute window - var nafPoints = p._getNAFPoints(w); - w = nafPoints.wnd; - var wnd = nafPoints.points; +var s = [ + 11, 14, 15, 12, 5, 8, 7, 9, 11, 13, 14, 15, 6, 7, 9, 8, + 7, 6, 8, 13, 11, 9, 7, 15, 7, 12, 15, 9, 11, 7, 13, 12, + 11, 13, 6, 7, 14, 9, 13, 15, 14, 8, 13, 6, 5, 12, 7, 5, + 11, 12, 14, 15, 14, 15, 9, 8, 9, 14, 5, 6, 8, 6, 5, 12, + 9, 15, 5, 11, 6, 8, 13, 12, 5, 12, 13, 14, 11, 8, 5, 6, +]; - // Get NAF form - var naf = getNAF(k, w); +var sh = [ + 8, 9, 9, 11, 13, 15, 15, 5, 7, 7, 8, 11, 14, 14, 12, 6, + 9, 13, 15, 7, 12, 8, 9, 11, 7, 7, 12, 7, 6, 15, 13, 11, + 9, 7, 15, 11, 8, 6, 6, 14, 12, 13, 5, 14, 13, 13, 7, 5, + 15, 5, 8, 11, 14, 14, 6, 14, 6, 9, 12, 9, 12, 5, 15, 8, + 8, 5, 12, 9, 12, 5, 14, 6, 8, 13, 6, 5, 15, 13, 11, 11 +]; - // Add `this`*(N+1) for every w-NAF index - var acc = this.jpoint(null, null, null); - for (var i = naf.length - 1; i >= 0; i--) { - // Count zeroes - for (var k = 0; i >= 0 && naf[i] === 0; i--) - k++; - if (i >= 0) - k++; - acc = acc.dblp(k); +},{"../hash":234}],238:[function(require,module,exports){ +var hash = require('../hash'); +var utils = hash.utils; +var assert = utils.assert; - if (i < 0) - break; - var z = naf[i]; - assert(z !== 0); - if (p.type === 'affine') { - // J +- P - if (z > 0) - acc = acc.mixedAdd(wnd[(z - 1) >> 1]); - else - acc = acc.mixedAdd(wnd[(-z - 1) >> 1].neg()); - } else { - // J +- J - if (z > 0) - acc = acc.add(wnd[(z - 1) >> 1]); - else - acc = acc.add(wnd[(-z - 1) >> 1].neg()); - } - } - return p.type === 'affine' ? acc.toP() : acc; -}; +var rotr32 = utils.rotr32; +var rotl32 = utils.rotl32; +var sum32 = utils.sum32; +var sum32_4 = utils.sum32_4; +var sum32_5 = utils.sum32_5; +var rotr64_hi = utils.rotr64_hi; +var rotr64_lo = utils.rotr64_lo; +var shr64_hi = utils.shr64_hi; +var shr64_lo = utils.shr64_lo; +var sum64 = utils.sum64; +var sum64_hi = utils.sum64_hi; +var sum64_lo = utils.sum64_lo; +var sum64_4_hi = utils.sum64_4_hi; +var sum64_4_lo = utils.sum64_4_lo; +var sum64_5_hi = utils.sum64_5_hi; +var sum64_5_lo = utils.sum64_5_lo; +var BlockHash = hash.common.BlockHash; -BaseCurve.prototype._wnafMulAdd = function _wnafMulAdd(defW, - points, - coeffs, - len) { - var wndWidth = this._wnafT1; - var wnd = this._wnafT2; - var naf = this._wnafT3; +var sha256_K = [ + 0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, + 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5, + 0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3, + 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174, + 0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc, + 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da, + 0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7, + 0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967, + 0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13, + 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85, + 0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3, + 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070, + 0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5, + 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3, + 0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208, + 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2 +]; - // Fill all arrays - var max = 0; - for (var i = 0; i < len; i++) { - var p = points[i]; - var nafPoints = p._getNAFPoints(defW); - wndWidth[i] = nafPoints.wnd; - wnd[i] = nafPoints.points; - } +var sha512_K = [ + 0x428a2f98, 0xd728ae22, 0x71374491, 0x23ef65cd, + 0xb5c0fbcf, 0xec4d3b2f, 0xe9b5dba5, 0x8189dbbc, + 0x3956c25b, 0xf348b538, 0x59f111f1, 0xb605d019, + 0x923f82a4, 0xaf194f9b, 0xab1c5ed5, 0xda6d8118, + 0xd807aa98, 0xa3030242, 0x12835b01, 0x45706fbe, + 0x243185be, 0x4ee4b28c, 0x550c7dc3, 0xd5ffb4e2, + 0x72be5d74, 0xf27b896f, 0x80deb1fe, 0x3b1696b1, + 0x9bdc06a7, 0x25c71235, 0xc19bf174, 0xcf692694, + 0xe49b69c1, 0x9ef14ad2, 0xefbe4786, 0x384f25e3, + 0x0fc19dc6, 0x8b8cd5b5, 0x240ca1cc, 0x77ac9c65, + 0x2de92c6f, 0x592b0275, 0x4a7484aa, 0x6ea6e483, + 0x5cb0a9dc, 0xbd41fbd4, 0x76f988da, 0x831153b5, + 0x983e5152, 0xee66dfab, 0xa831c66d, 0x2db43210, + 0xb00327c8, 0x98fb213f, 0xbf597fc7, 0xbeef0ee4, + 0xc6e00bf3, 0x3da88fc2, 0xd5a79147, 0x930aa725, + 0x06ca6351, 0xe003826f, 0x14292967, 0x0a0e6e70, + 0x27b70a85, 0x46d22ffc, 0x2e1b2138, 0x5c26c926, + 0x4d2c6dfc, 0x5ac42aed, 0x53380d13, 0x9d95b3df, + 0x650a7354, 0x8baf63de, 0x766a0abb, 0x3c77b2a8, + 0x81c2c92e, 0x47edaee6, 0x92722c85, 0x1482353b, + 0xa2bfe8a1, 0x4cf10364, 0xa81a664b, 0xbc423001, + 0xc24b8b70, 0xd0f89791, 0xc76c51a3, 0x0654be30, + 0xd192e819, 0xd6ef5218, 0xd6990624, 0x5565a910, + 0xf40e3585, 0x5771202a, 0x106aa070, 0x32bbd1b8, + 0x19a4c116, 0xb8d2d0c8, 0x1e376c08, 0x5141ab53, + 0x2748774c, 0xdf8eeb99, 0x34b0bcb5, 0xe19b48a8, + 0x391c0cb3, 0xc5c95a63, 0x4ed8aa4a, 0xe3418acb, + 0x5b9cca4f, 0x7763e373, 0x682e6ff3, 0xd6b2b8a3, + 0x748f82ee, 0x5defb2fc, 0x78a5636f, 0x43172f60, + 0x84c87814, 0xa1f0ab72, 0x8cc70208, 0x1a6439ec, + 0x90befffa, 0x23631e28, 0xa4506ceb, 0xde82bde9, + 0xbef9a3f7, 0xb2c67915, 0xc67178f2, 0xe372532b, + 0xca273ece, 0xea26619c, 0xd186b8c7, 0x21c0c207, + 0xeada7dd6, 0xcde0eb1e, 0xf57d4f7f, 0xee6ed178, + 0x06f067aa, 0x72176fba, 0x0a637dc5, 0xa2c898a6, + 0x113f9804, 0xbef90dae, 0x1b710b35, 0x131c471b, + 0x28db77f5, 0x23047d84, 0x32caab7b, 0x40c72493, + 0x3c9ebe0a, 0x15c9bebc, 0x431d67c4, 0x9c100d4c, + 0x4cc5d4be, 0xcb3e42b6, 0x597f299c, 0xfc657e2a, + 0x5fcb6fab, 0x3ad6faec, 0x6c44198c, 0x4a475817 +]; - // Comb small window NAFs - for (var i = len - 1; i >= 1; i -= 2) { - var a = i - 1; - var b = i; - if (wndWidth[a] !== 1 || wndWidth[b] !== 1) { - naf[a] = getNAF(coeffs[a], wndWidth[a]); - naf[b] = getNAF(coeffs[b], wndWidth[b]); - max = Math.max(naf[a].length, max); - max = Math.max(naf[b].length, max); - continue; - } +var sha1_K = [ + 0x5A827999, 0x6ED9EBA1, + 0x8F1BBCDC, 0xCA62C1D6 +]; - var comb = [ - points[a], /* 1 */ - null, /* 3 */ - null, /* 5 */ - points[b] /* 7 */ - ]; +function SHA256() { + if (!(this instanceof SHA256)) + return new SHA256(); - // Try to avoid Projective points, if possible - if (points[a].y.cmp(points[b].y) === 0) { - comb[1] = points[a].add(points[b]); - comb[2] = points[a].toJ().mixedAdd(points[b].neg()); - } else if (points[a].y.cmp(points[b].y.redNeg()) === 0) { - comb[1] = points[a].toJ().mixedAdd(points[b]); - comb[2] = points[a].add(points[b].neg()); - } else { - comb[1] = points[a].toJ().mixedAdd(points[b]); - comb[2] = points[a].toJ().mixedAdd(points[b].neg()); - } + BlockHash.call(this); + this.h = [ 0x6a09e667, 0xbb67ae85, 0x3c6ef372, 0xa54ff53a, + 0x510e527f, 0x9b05688c, 0x1f83d9ab, 0x5be0cd19 ]; + this.k = sha256_K; + this.W = new Array(64); +} +utils.inherits(SHA256, BlockHash); +exports.sha256 = SHA256; - var index = [ - -3, /* -1 -1 */ - -1, /* -1 0 */ - -5, /* -1 1 */ - -7, /* 0 -1 */ - 0, /* 0 0 */ - 7, /* 0 1 */ - 5, /* 1 -1 */ - 1, /* 1 0 */ - 3 /* 1 1 */ - ]; +SHA256.blockSize = 512; +SHA256.outSize = 256; +SHA256.hmacStrength = 192; +SHA256.padLength = 64; - var jsf = getJSF(coeffs[a], coeffs[b]); - max = Math.max(jsf[0].length, max); - naf[a] = new Array(max); - naf[b] = new Array(max); - for (var j = 0; j < max; j++) { - var ja = jsf[0][j] | 0; - var jb = jsf[1][j] | 0; +SHA256.prototype._update = function _update(msg, start) { + var W = this.W; - naf[a][j] = index[(ja + 1) * 3 + (jb + 1)]; - naf[b][j] = 0; - wnd[a] = comb; - } - } + for (var i = 0; i < 16; i++) + W[i] = msg[start + i]; + for (; i < W.length; i++) + W[i] = sum32_4(g1_256(W[i - 2]), W[i - 7], g0_256(W[i - 15]), W[i - 16]); - var acc = this.jpoint(null, null, null); - var tmp = this._wnafT4; - for (var i = max; i >= 0; i--) { - var k = 0; + var a = this.h[0]; + var b = this.h[1]; + var c = this.h[2]; + var d = this.h[3]; + var e = this.h[4]; + var f = this.h[5]; + var g = this.h[6]; + var h = this.h[7]; - while (i >= 0) { - var zero = true; - for (var j = 0; j < len; j++) { - tmp[j] = naf[j][i] | 0; - if (tmp[j] !== 0) - zero = false; - } - if (!zero) - break; - k++; - i--; - } - if (i >= 0) - k++; - acc = acc.dblp(k); - if (i < 0) - break; + assert(this.k.length === W.length); + for (var i = 0; i < W.length; i++) { + var T1 = sum32_5(h, s1_256(e), ch32(e, f, g), this.k[i], W[i]); + var T2 = sum32(s0_256(a), maj32(a, b, c)); + h = g; + g = f; + f = e; + e = sum32(d, T1); + d = c; + c = b; + b = a; + a = sum32(T1, T2); + } - for (var j = 0; j < len; j++) { - var z = tmp[j]; - var p; - if (z === 0) - continue; - else if (z > 0) - p = wnd[j][(z - 1) >> 1]; - else if (z < 0) - p = wnd[j][(-z - 1) >> 1].neg(); + this.h[0] = sum32(this.h[0], a); + this.h[1] = sum32(this.h[1], b); + this.h[2] = sum32(this.h[2], c); + this.h[3] = sum32(this.h[3], d); + this.h[4] = sum32(this.h[4], e); + this.h[5] = sum32(this.h[5], f); + this.h[6] = sum32(this.h[6], g); + this.h[7] = sum32(this.h[7], h); +}; - if (p.type === 'affine') - acc = acc.mixedAdd(p); - else - acc = acc.add(p); - } - } - // Zeroify references - for (var i = 0; i < len; i++) - wnd[i] = null; - return acc.toP(); +SHA256.prototype._digest = function digest(enc) { + if (enc === 'hex') + return utils.toHex32(this.h, 'big'); + else + return utils.split32(this.h, 'big'); }; -BaseCurve.BasePoint = BasePoint; +function SHA224() { + if (!(this instanceof SHA224)) + return new SHA224(); -function BasePoint(curve, type) { - this.curve = curve; - this.type = type; - this.precomputed = null; + SHA256.call(this); + this.h = [ 0xc1059ed8, 0x367cd507, 0x3070dd17, 0xf70e5939, + 0xffc00b31, 0x68581511, 0x64f98fa7, 0xbefa4fa4 ]; } +utils.inherits(SHA224, SHA256); +exports.sha224 = SHA224; -BasePoint.prototype.validate = function validate() { - return this.curve.validate(this); -}; - -BasePoint.prototype.precompute = function precompute(power, _beta) { - if (this.precomputed) - return this; - - var precomputed = { - doubles: null, - naf: null, - beta: null - }; - precomputed.naf = this._getNAFPoints(8); - precomputed.doubles = this._getDoubles(4, power); - precomputed.beta = this._getBeta(); - this.precomputed = precomputed; +SHA224.blockSize = 512; +SHA224.outSize = 224; +SHA224.hmacStrength = 192; +SHA224.padLength = 64; - return this; +SHA224.prototype._digest = function digest(enc) { + // Just truncate output + if (enc === 'hex') + return utils.toHex32(this.h.slice(0, 7), 'big'); + else + return utils.split32(this.h.slice(0, 7), 'big'); }; -BasePoint.prototype._getDoubles = function _getDoubles(step, power) { - if (this.precomputed && this.precomputed.doubles) - return this.precomputed.doubles; +function SHA512() { + if (!(this instanceof SHA512)) + return new SHA512(); - var doubles = [ this ]; - var acc = this; - for (var i = 0; i < power; i += step) { - for (var j = 0; j < step; j++) - acc = acc.dbl(); - doubles.push(acc); - } - return { - step: step, - points: doubles - }; -}; + BlockHash.call(this); + this.h = [ 0x6a09e667, 0xf3bcc908, + 0xbb67ae85, 0x84caa73b, + 0x3c6ef372, 0xfe94f82b, + 0xa54ff53a, 0x5f1d36f1, + 0x510e527f, 0xade682d1, + 0x9b05688c, 0x2b3e6c1f, + 0x1f83d9ab, 0xfb41bd6b, + 0x5be0cd19, 0x137e2179 ]; + this.k = sha512_K; + this.W = new Array(160); +} +utils.inherits(SHA512, BlockHash); +exports.sha512 = SHA512; -BasePoint.prototype._getNAFPoints = function _getNAFPoints(wnd) { - if (this.precomputed && this.precomputed.naf) - return this.precomputed.naf; +SHA512.blockSize = 1024; +SHA512.outSize = 512; +SHA512.hmacStrength = 192; +SHA512.padLength = 128; - var res = [ this ]; - var max = (1 << wnd) - 1; - var dbl = max === 1 ? null : this.dbl(); - for (var i = 1; i < max; i++) - res[i] = res[i - 1].add(dbl); - return { - wnd: wnd, - points: res - }; -}; +SHA512.prototype._prepareBlock = function _prepareBlock(msg, start) { + var W = this.W; -BasePoint.prototype._getBeta = function _getBeta() { - return null; -}; + // 32 x 32bit words + for (var i = 0; i < 32; i++) + W[i] = msg[start + i]; + for (; i < W.length; i += 2) { + var c0_hi = g1_512_hi(W[i - 4], W[i - 3]); // i - 2 + var c0_lo = g1_512_lo(W[i - 4], W[i - 3]); + var c1_hi = W[i - 14]; // i - 7 + var c1_lo = W[i - 13]; + var c2_hi = g0_512_hi(W[i - 30], W[i - 29]); // i - 15 + var c2_lo = g0_512_lo(W[i - 30], W[i - 29]); + var c3_hi = W[i - 32]; // i - 16 + var c3_lo = W[i - 31]; -BasePoint.prototype.dblp = function dblp(k) { - var r = this; - for (var i = 0; i < k; i++) - r = r.dbl(); - return r; + W[i] = sum64_4_hi(c0_hi, c0_lo, + c1_hi, c1_lo, + c2_hi, c2_lo, + c3_hi, c3_lo); + W[i + 1] = sum64_4_lo(c0_hi, c0_lo, + c1_hi, c1_lo, + c2_hi, c2_lo, + c3_hi, c3_lo); + } }; -},{"../../elliptic":209,"assert":41,"bn.js":207}],211:[function(require,module,exports){ -var assert = require('assert'); -var curve = require('../curve'); -var elliptic = require('../../elliptic'); -var bn = require('bn.js'); -var inherits = require('inherits'); -var Base = curve.base; +SHA512.prototype._update = function _update(msg, start) { + this._prepareBlock(msg, start); -var getNAF = elliptic.utils.getNAF; + var W = this.W; -function EdwardsCurve(conf) { - // NOTE: Important as we are creating point in Base.call() - this.twisted = conf.a != 1; - this.mOneA = this.twisted && conf.a == -1; - this.extended = this.mOneA; + var ah = this.h[0]; + var al = this.h[1]; + var bh = this.h[2]; + var bl = this.h[3]; + var ch = this.h[4]; + var cl = this.h[5]; + var dh = this.h[6]; + var dl = this.h[7]; + var eh = this.h[8]; + var el = this.h[9]; + var fh = this.h[10]; + var fl = this.h[11]; + var gh = this.h[12]; + var gl = this.h[13]; + var hh = this.h[14]; + var hl = this.h[15]; - Base.call(this, 'mont', conf); + assert(this.k.length === W.length); + for (var i = 0; i < W.length; i += 2) { + var c0_hi = hh; + var c0_lo = hl; + var c1_hi = s1_512_hi(eh, el); + var c1_lo = s1_512_lo(eh, el); + var c2_hi = ch64_hi(eh, el, fh, fl, gh, gl); + var c2_lo = ch64_lo(eh, el, fh, fl, gh, gl); + var c3_hi = this.k[i]; + var c3_lo = this.k[i + 1]; + var c4_hi = W[i]; + var c4_lo = W[i + 1]; - this.a = new bn(conf.a, 16).mod(this.red.m).toRed(this.red); - this.c = new bn(conf.c, 16).toRed(this.red); - this.c2 = this.c.redSqr(); - this.d = new bn(conf.d, 16).toRed(this.red); - this.dd = this.d.redAdd(this.d); + var T1_hi = sum64_5_hi(c0_hi, c0_lo, + c1_hi, c1_lo, + c2_hi, c2_lo, + c3_hi, c3_lo, + c4_hi, c4_lo); + var T1_lo = sum64_5_lo(c0_hi, c0_lo, + c1_hi, c1_lo, + c2_hi, c2_lo, + c3_hi, c3_lo, + c4_hi, c4_lo); - assert(!this.twisted || this.c.fromRed().cmpn(1) === 0); - this.oneC = conf.c == 1; -} -inherits(EdwardsCurve, Base); -module.exports = EdwardsCurve; + var c0_hi = s0_512_hi(ah, al); + var c0_lo = s0_512_lo(ah, al); + var c1_hi = maj64_hi(ah, al, bh, bl, ch, cl); + var c1_lo = maj64_lo(ah, al, bh, bl, ch, cl); -EdwardsCurve.prototype._mulA = function _mulA(num) { - if (this.mOneA) - return num.redNeg(); - else - return this.a.redMul(num); -}; + var T2_hi = sum64_hi(c0_hi, c0_lo, c1_hi, c1_lo); + var T2_lo = sum64_lo(c0_hi, c0_lo, c1_hi, c1_lo); -EdwardsCurve.prototype._mulC = function _mulC(num) { - if (this.oneC) - return num; - else - return this.c.redMul(num); -}; + hh = gh; + hl = gl; -EdwardsCurve.prototype.point = function point(x, y, z, t) { - return new Point(this, x, y, z, t); -}; + gh = fh; + gl = fl; -// Just for compatibility with Short curve -EdwardsCurve.prototype.jpoint = function jpoint(x, y, z, t) { - return this.point(x, y, z, t); -}; + fh = eh; + fl = el; -EdwardsCurve.prototype.pointFromJSON = function pointFromJSON(obj) { - return Point.fromJSON(this, obj); -}; + eh = sum64_hi(dh, dl, T1_hi, T1_lo); + el = sum64_lo(dl, dl, T1_hi, T1_lo); -EdwardsCurve.prototype.pointFromX = function pointFromX(odd, x) { - x = new bn(x, 16); - if (!x.red) - x = x.toRed(this.red); + dh = ch; + dl = cl; - var x2 = x.redSqr(); - var rhs = this.c2.redSub(this.a.redMul(x2)); - var lhs = this.one.redSub(this.c2.redMul(this.d).redMul(x2)); + ch = bh; + cl = bl; - var y = rhs.redMul(lhs.redInvm()).redSqrt(); - var isOdd = y.fromRed().isOdd(); - if (odd && !isOdd || !odd && isOdd) - y = y.redNeg(); + bh = ah; + bl = al; - return this.point(x, y, curve.one); + ah = sum64_hi(T1_hi, T1_lo, T2_hi, T2_lo); + al = sum64_lo(T1_hi, T1_lo, T2_hi, T2_lo); + } + + sum64(this.h, 0, ah, al); + sum64(this.h, 2, bh, bl); + sum64(this.h, 4, ch, cl); + sum64(this.h, 6, dh, dl); + sum64(this.h, 8, eh, el); + sum64(this.h, 10, fh, fl); + sum64(this.h, 12, gh, gl); + sum64(this.h, 14, hh, hl); }; -EdwardsCurve.prototype.validate = function validate(point) { - if (point.isInfinity()) - return true; +SHA512.prototype._digest = function digest(enc) { + if (enc === 'hex') + return utils.toHex32(this.h, 'big'); + else + return utils.split32(this.h, 'big'); +}; - // Curve: A * X^2 + Y^2 = C^2 * (1 + D * X^2 * Y^2) - point.normalize(); +function SHA384() { + if (!(this instanceof SHA384)) + return new SHA384(); - var x2 = point.x.redSqr(); - var y2 = point.y.redSqr(); - var lhs = x2.redMul(this.a).redAdd(y2); - var rhs = this.c2.redMul(this.one.redAdd(this.d.redMul(x2).redMul(y2))); + SHA512.call(this); + this.h = [ 0xcbbb9d5d, 0xc1059ed8, + 0x629a292a, 0x367cd507, + 0x9159015a, 0x3070dd17, + 0x152fecd8, 0xf70e5939, + 0x67332667, 0xffc00b31, + 0x8eb44a87, 0x68581511, + 0xdb0c2e0d, 0x64f98fa7, + 0x47b5481d, 0xbefa4fa4 ]; +} +utils.inherits(SHA384, SHA512); +exports.sha384 = SHA384; - return lhs.cmp(rhs) === 0; +SHA384.blockSize = 1024; +SHA384.outSize = 384; +SHA384.hmacStrength = 192; +SHA384.padLength = 128; + +SHA384.prototype._digest = function digest(enc) { + if (enc === 'hex') + return utils.toHex32(this.h.slice(0, 12), 'big'); + else + return utils.split32(this.h.slice(0, 12), 'big'); }; -function Point(curve, x, y, z, t) { - Base.BasePoint.call(this, curve, 'projective'); - if (x === null && y === null && z === null) { - this.x = this.curve.zero; - this.y = this.curve.one; - this.z = this.curve.one; - this.t = this.curve.zero; - this.zOne = true; - } else { - this.x = new bn(x, 16); - this.y = new bn(y, 16); - this.z = z ? new bn(z, 16) : this.curve.one; - this.t = t && new bn(t, 16); - if (!this.x.red) - this.x = this.x.toRed(this.curve.red); - if (!this.y.red) - this.y = this.y.toRed(this.curve.red); - if (!this.z.red) - this.z = this.z.toRed(this.curve.red); - if (this.t && !this.t.red) - this.t = this.t.toRed(this.curve.red); - this.zOne = this.z === this.curve.one; +function SHA1() { + if (!(this instanceof SHA1)) + return new SHA1(); - // Use extended coordinates - if (this.curve.extended && !this.t) { - this.t = this.x.redMul(this.y); - if (!this.zOne) - this.t = this.t.redMul(this.z.redInvm()); - } - } + BlockHash.call(this); + this.h = [ 0x67452301, 0xefcdab89, 0x98badcfe, + 0x10325476, 0xc3d2e1f0 ]; + this.W = new Array(80); } -inherits(Point, Base.BasePoint); - -Point.fromJSON = function fromJSON(curve, obj) { - return new Point(curve, obj[0], obj[1], obj[2]); -}; -Point.prototype.inspect = function inspect() { - if (this.isInfinity()) - return ''; - return ''; -}; +utils.inherits(SHA1, BlockHash); +exports.sha1 = SHA1; -Point.prototype.isInfinity = function isInfinity() { - // XXX This code assumes that zero is always zero in red - return this.x.cmpn(0) === 0 && - this.y.cmp(this.z) === 0; -}; +SHA1.blockSize = 512; +SHA1.outSize = 160; +SHA1.hmacStrength = 80; +SHA1.padLength = 64; -Point.prototype._extDbl = function _extDbl() { - // http://hyperelliptic.org/EFD/g1p/auto-twisted-extended-1.html#doubling-dbl-2008-hwcd - // 4M + 4S +SHA1.prototype._update = function _update(msg, start) { + var W = this.W; - // A = X1^2 - var a = this.x.redSqr(); - // B = Y1^2 - var b = this.y.redSqr(); - // C = 2 * Z1^2 - var c = this.z.redSqr(); - c = c.redIAdd(c); - // D = a * A - var d = this.curve._mulA(a); - // E = (X1 + Y1)^2 - A - B - var e = this.x.redAdd(this.y).redSqr().redISub(a).redISub(b); - // G = D + B - var g = d.redAdd(b); - // F = G - C - var f = g.redSub(c); - // H = D - B - var h = d.redSub(b); - // X3 = E * F - var nx = e.redMul(f); - // Y3 = G * H - var ny = g.redMul(h); - // T3 = E * H - var nt = e.redMul(h); - // Z3 = F * G - var nz = f.redMul(g); - return this.curve.point(nx, ny, nz, nt); -}; + for (var i = 0; i < 16; i++) + W[i] = msg[start + i]; -Point.prototype._projDbl = function _projDbl() { - // http://hyperelliptic.org/EFD/g1p/auto-twisted-projective.html#doubling-dbl-2008-bbjlp - // http://hyperelliptic.org/EFD/g1p/auto-edwards-projective.html#doubling-dbl-2007-bl - // and others - // Generally 3M + 4S or 2M + 4S + for(; i < W.length; i++) + W[i] = rotl32(W[i - 3] ^ W[i - 8] ^ W[i - 14] ^ W[i - 16], 1); - // B = (X1 + Y1)^2 - var b = this.x.redAdd(this.y).redSqr(); - // C = X1^2 - var c = this.x.redSqr(); - // D = Y1^2 - var d = this.y.redSqr(); + var a = this.h[0]; + var b = this.h[1]; + var c = this.h[2]; + var d = this.h[3]; + var e = this.h[4]; - if (this.curve.twisted) { - // E = a * C - var e = this.curve._mulA(c); - // F = E + D - var f = e.redAdd(d); - if (this.zOne) { - // X3 = (B - C - D) * (F - 2) - var nx = b.redSub(c).redSub(d).redMul(f.redSub(this.curve.two)); - // Y3 = F * (E - D) - var ny = f.redMul(e.redSub(d)); - // Z3 = F^2 - 2 * F - var nz = f.redSqr().redSub(f).redSub(f); - } else { - // H = Z1^2 - var h = this.z.redSqr(); - // J = F - 2 * H - var j = f.redSub(h).redISub(h); - // X3 = (B-C-D)*J - var nx = b.redSub(c).redISub(d).redMul(j); - // Y3 = F * (E - D) - var ny = f.redMul(e.redSub(d)); - // Z3 = F * J - var nz = f.redMul(j); - } - } else { - // E = C + D - var e = c.redAdd(d); - // H = (c * Z1)^2 - var h = this.curve._mulC(redMul(this.z)).redSqr(); - // J = E - 2 * H - var j = e.redSub(h).redSub(h); - // X3 = c * (B - E) * J - var nx = this.curve._mulC(b.redISub(e)).redMul(j); - // Y3 = c * E * (C - D) - var ny = this.curve._mulC(e).redMul(c.redISub(d)); - // Z3 = E * J - var nz = e.redMul(j); + for (var i = 0; i < W.length; i++) { + var s = ~~(i / 20); + var t = sum32_5(rotl32(a, 5), ft_1(s, b, c, d), e, W[i], sha1_K[s]); + e = d; + d = c; + c = rotl32(b, 30); + b = a; + a = t; } - return this.curve.point(nx, ny, nz); -}; -Point.prototype.dbl = function dbl() { - if (this.isInfinity()) - return this; + this.h[0] = sum32(this.h[0], a); + this.h[1] = sum32(this.h[1], b); + this.h[2] = sum32(this.h[2], c); + this.h[3] = sum32(this.h[3], d); + this.h[4] = sum32(this.h[4], e); +}; - // Double in extended coordinates - if (this.curve.extended) - return this._extDbl(); +SHA1.prototype._digest = function digest(enc) { + if (enc === 'hex') + return utils.toHex32(this.h, 'big'); else - return this._projDbl(); + return utils.split32(this.h, 'big'); }; -Point.prototype._extAdd = function _extAdd(p) { - // http://hyperelliptic.org/EFD/g1p/auto-twisted-extended-1.html#addition-add-2008-hwcd-3 - // 8M +function ch32(x, y, z) { + return (x & y) ^ ((~x) & z); +} - // A = (Y1 - X1) * (Y2 - X2) - var a = this.y.redSub(this.x).redMul(p.y.redSub(p.x)); - // B = (Y1 + X1) * (Y2 + X2) - var b = this.y.redAdd(this.x).redMul(p.y.redAdd(p.x)); - // C = T1 * k * T2 - var c = this.t.redMul(this.curve.dd).redMul(p.t); - // D = Z1 * 2 * Z2 - var d = this.z.redMul(p.z.redAdd(p.z)); - // E = B - A - var e = b.redSub(a); - // F = D - C - var f = d.redSub(c); - // G = D + C - var g = d.redAdd(c); - // H = B + A - var h = b.redAdd(a); - // X3 = E * F - var nx = e.redMul(f); - // Y3 = G * H - var ny = g.redMul(h); - // T3 = E * H - var nt = e.redMul(h); - // Z3 = F * G - var nz = f.redMul(g); - return this.curve.point(nx, ny, nz, nt); -}; +function maj32(x, y, z) { + return (x & y) ^ (x & z) ^ (y & z); +} -Point.prototype._projAdd = function _projAdd(p) { - // http://hyperelliptic.org/EFD/g1p/auto-twisted-projective.html#addition-add-2008-bbjlp - // http://hyperelliptic.org/EFD/g1p/auto-edwards-projective.html#addition-add-2007-bl - // 10M + 1S +function p32(x, y, z) { + return x ^ y ^ z; +} - // A = Z1 * Z2 - var a = this.z.redMul(p.z); - // B = A^2 - var b = a.redSqr(); - // C = X1 * X2 - var c = this.x.redMul(p.x); - // D = Y1 * Y2 - var d = this.y.redMul(p.y); - // E = d * C * D - var e = this.curve.d.redMul(c).redMul(d); - // F = B - E - var f = b.redSub(e); - // G = B + E - var g = b.redAdd(e); - // X3 = A * F * ((X1 + Y1) * (X2 + Y2) - C - D) - var tmp = this.x.redAdd(this.y).redMul(p.x.redAdd(p.y)).redISub(c).redISub(d); - var nx = a.redMul(f).redMul(tmp); - if (this.curve.twisted) { - // Y3 = A * G * (D - a * C) - var ny = a.redMul(g).redMul(d.redSub(this.curve._mulA(c))); - // Z3 = F * G - var nz = f.redMul(g); - } else { - // Y3 = A * G * (D - C) - var ny = a.redMul(g).redMul(d.redSub(c)); - // Z3 = c * F * G - var nz = this.curve._mulC(f).redMul(g); - } - return this.curve.point(nx, ny, nz); -}; +function s0_256(x) { + return rotr32(x, 2) ^ rotr32(x, 13) ^ rotr32(x, 22); +} -Point.prototype.add = function add(p) { - if (this.isInfinity()) - return p; - if (p.isInfinity()) - return this; +function s1_256(x) { + return rotr32(x, 6) ^ rotr32(x, 11) ^ rotr32(x, 25); +} - if (this.curve.extended) - return this._extAdd(p); - else - return this._projAdd(p); -}; +function g0_256(x) { + return rotr32(x, 7) ^ rotr32(x, 18) ^ (x >>> 3); +} -Point.prototype.mul = function mul(k) { - if (this.precomputed && this.precomputed.doubles) - return this.curve._fixedNafMul(this, k); - else - return this.curve._wnafMul(this, k); -}; +function g1_256(x) { + return rotr32(x, 17) ^ rotr32(x, 19) ^ (x >>> 10); +} -Point.prototype.mulAdd = function mulAdd(k1, p, k2) { - return this.curve._wnafMulAdd(1, [ this, p ], [ k1, k2 ], 2); -}; +function ft_1(s, x, y, z) { + if (s === 0) + return ch32(x, y, z); + if (s === 1 || s === 3) + return p32(x, y, z); + if (s === 2) + return maj32(x, y, z); +} -Point.prototype.normalize = function normalize() { - if (this.zOne) - return this; +function ch64_hi(xh, xl, yh, yl, zh, zl) { + var r = (xh & yh) ^ ((~xh) & zh); + if (r < 0) + r += 0x100000000; + return r; +} - // Normalize coordinates - var zi = this.z.redInvm(); - this.x = this.x.redMul(zi); - this.y = this.y.redMul(zi); - if (this.t) - this.t = this.t.redMul(zi); - this.z = this.curve.one; - this.zOne = true; - return this; -}; +function ch64_lo(xh, xl, yh, yl, zh, zl) { + var r = (xl & yl) ^ ((~xl) & zl); + if (r < 0) + r += 0x100000000; + return r; +} -Point.prototype.neg = function neg() { - return this.curve.point(this.x.redNeg(), - this.y, - this.z, - this.t && this.t.redNeg()); -}; +function maj64_hi(xh, xl, yh, yl, zh, zl) { + var r = (xh & yh) ^ (xh & zh) ^ (yh & zh); + if (r < 0) + r += 0x100000000; + return r; +} -Point.prototype.getX = function getX() { - this.normalize(); - return this.x.fromRed(); -}; +function maj64_lo(xh, xl, yh, yl, zh, zl) { + var r = (xl & yl) ^ (xl & zl) ^ (yl & zl); + if (r < 0) + r += 0x100000000; + return r; +} -Point.prototype.getY = function getY() { - this.normalize(); - return this.y.fromRed(); -}; +function s0_512_hi(xh, xl) { + var c0_hi = rotr64_hi(xh, xl, 28); + var c1_hi = rotr64_hi(xl, xh, 2); // 34 + var c2_hi = rotr64_hi(xl, xh, 7); // 39 -// Compatibility with BaseCurve -Point.prototype.toP = Point.prototype.normalize; -Point.prototype.mixedAdd = Point.prototype.add; + var r = c0_hi ^ c1_hi ^ c2_hi; + if (r < 0) + r += 0x100000000; + return r; +} -},{"../../elliptic":209,"../curve":212,"assert":41,"bn.js":207,"inherits":229}],212:[function(require,module,exports){ -arguments[4][72][0].apply(exports,arguments) -},{"./base":210,"./edwards":211,"./mont":213,"./short":214,"/Users/eordano/Code/bitcore/node_modules/bitcore-build/node_modules/browserify/node_modules/crypto-browserify/node_modules/browserify-sign/node_modules/elliptic/lib/elliptic/curve/index.js":72}],213:[function(require,module,exports){ -var assert = require('assert'); -var curve = require('../curve'); -var elliptic = require('../../elliptic'); -var bn = require('bn.js'); -var inherits = require('inherits'); -var Base = curve.base; +function s0_512_lo(xh, xl) { + var c0_lo = rotr64_lo(xh, xl, 28); + var c1_lo = rotr64_lo(xl, xh, 2); // 34 + var c2_lo = rotr64_lo(xl, xh, 7); // 39 -var getNAF = elliptic.utils.getNAF; + var r = c0_lo ^ c1_lo ^ c2_lo; + if (r < 0) + r += 0x100000000; + return r; +} -function MontCurve(conf) { - Base.call(this, 'mont', conf); +function s1_512_hi(xh, xl) { + var c0_hi = rotr64_hi(xh, xl, 14); + var c1_hi = rotr64_hi(xh, xl, 18); + var c2_hi = rotr64_hi(xl, xh, 9); // 41 - this.a = new bn(conf.a, 16).toRed(this.red); - this.b = new bn(conf.b, 16).toRed(this.red); - this.i4 = new bn(4).toRed(this.red).redInvm(); - this.two = new bn(2).toRed(this.red); - this.a24 = this.i4.redMul(this.a.redAdd(this.two)); + var r = c0_hi ^ c1_hi ^ c2_hi; + if (r < 0) + r += 0x100000000; + return r; } -inherits(MontCurve, Base); -module.exports = MontCurve; -MontCurve.prototype.point = function point(x, z) { - return new Point(this, x, z); -}; +function s1_512_lo(xh, xl) { + var c0_lo = rotr64_lo(xh, xl, 14); + var c1_lo = rotr64_lo(xh, xl, 18); + var c2_lo = rotr64_lo(xl, xh, 9); // 41 -MontCurve.prototype.pointFromJSON = function pointFromJSON(obj) { - return Point.fromJSON(this, obj); + var r = c0_lo ^ c1_lo ^ c2_lo; + if (r < 0) + r += 0x100000000; + return r; } -MontCurve.prototype.validate = function validate(point) { - var x = point.normalize().x; - var x2 = x.redSqr(); - var rhs = x2.redMul(x).redAdd(x2.redMul(this.a)).redAdd(x); - var y = rhs.redSqrt(); +function g0_512_hi(xh, xl) { + var c0_hi = rotr64_hi(xh, xl, 1); + var c1_hi = rotr64_hi(xh, xl, 8); + var c2_hi = shr64_hi(xh, xl, 7); - return y.redSqr().cmp(rhs) === 0; -}; + var r = c0_hi ^ c1_hi ^ c2_hi; + if (r < 0) + r += 0x100000000; + return r; +} -function Point(curve, x, z) { - Base.BasePoint.call(this, curve, 'projective'); - if (x === null && z === null) { - this.x = this.curve.one; - this.z = this.curve.zero; - } else { - this.x = new bn(x, 16); - this.z = new bn(z, 16); - if (!this.x.red) - this.x = this.x.toRed(this.curve.red); - if (!this.z.red) - this.z = this.z.toRed(this.curve.red); - } +function g0_512_lo(xh, xl) { + var c0_lo = rotr64_lo(xh, xl, 1); + var c1_lo = rotr64_lo(xh, xl, 8); + var c2_lo = shr64_lo(xh, xl, 7); + + var r = c0_lo ^ c1_lo ^ c2_lo; + if (r < 0) + r += 0x100000000; + return r; } -inherits(Point, Base.BasePoint); -Point.prototype.precompute = function precompute() { - // No-op -}; +function g1_512_hi(xh, xl) { + var c0_hi = rotr64_hi(xh, xl, 19); + var c1_hi = rotr64_hi(xl, xh, 29); // 61 + var c2_hi = shr64_hi(xh, xl, 6); -Point.fromJSON = function fromJSON(curve, obj) { - return new Point(curve, obj[0], obj[1] || curve.one); -}; + var r = c0_hi ^ c1_hi ^ c2_hi; + if (r < 0) + r += 0x100000000; + return r; +} -Point.prototype.inspect = function inspect() { - if (this.isInfinity()) - return ''; - return ''; -}; +function g1_512_lo(xh, xl) { + var c0_lo = rotr64_lo(xh, xl, 19); + var c1_lo = rotr64_lo(xl, xh, 29); // 61 + var c2_lo = shr64_lo(xh, xl, 6); -Point.prototype.isInfinity = function isInfinity() { - // XXX This code assumes that zero is always zero in red - return this.z.cmpn(0) === 0; -}; + var r = c0_lo ^ c1_lo ^ c2_lo; + if (r < 0) + r += 0x100000000; + return r; +} -Point.prototype.dbl = function dbl() { - // http://hyperelliptic.org/EFD/g1p/auto-montgom-xz.html#doubling-dbl-1987-m-3 - // 2M + 2S + 4A +},{"../hash":234}],239:[function(require,module,exports){ +var utils = exports; +var inherits = require('inherits'); - // A = X1 + Z1 - var a = this.x.redAdd(this.z); - // AA = A^2 - var aa = a.redSqr(); - // B = X1 - Z1 - var b = this.x.redSub(this.z); - // BB = B^2 - var bb = b.redSqr(); - // C = AA - BB - var c = aa.redSub(bb); - // X3 = AA * BB - var nx = aa.redMul(bb); - // Z3 = C * (BB + A24 * C) - var nz = c.redMul(bb.redAdd(this.curve.a24.redMul(c))); - return this.curve.point(nx, nz); -}; +function toArray(msg, enc) { + if (Array.isArray(msg)) + return msg.slice(); + if (!msg) + return []; + var res = []; + if (typeof msg === 'string') { + if (!enc) { + for (var i = 0; i < msg.length; i++) { + var c = msg.charCodeAt(i); + var hi = c >> 8; + var lo = c & 0xff; + if (hi) + res.push(hi, lo); + else + res.push(lo); + } + } else if (enc === 'hex') { + msg = msg.replace(/[^a-z0-9]+/ig, ''); + if (msg.length % 2 !== 0) + msg = '0' + msg; + for (var i = 0; i < msg.length; i += 2) + res.push(parseInt(msg[i] + msg[i + 1], 16)); + } + } else { + for (var i = 0; i < msg.length; i++) + res[i] = msg[i] | 0; + } + return res; +} +utils.toArray = toArray; -Point.prototype.add = function add(p) { - throw new Error('Not supported on Montgomery curve'); -}; +function toHex(msg) { + var res = ''; + for (var i = 0; i < msg.length; i++) + res += zero2(msg[i].toString(16)); + return res; +} +utils.toHex = toHex; -Point.prototype.diffAdd = function diffAdd(p, diff) { - // http://hyperelliptic.org/EFD/g1p/auto-montgom-xz.html#diffadd-dadd-1987-m-3 - // 4M + 2S + 6A +function htonl(w) { + var res = (w >>> 24) | + ((w >>> 8) & 0xff00) | + ((w << 8) & 0xff0000) | + ((w & 0xff) << 24); + return res >>> 0; +} +utils.htonl = htonl; - // A = X2 + Z2 - var a = this.x.redAdd(this.z); - // B = X2 - Z2 - var b = this.x.redSub(this.z); - // C = X3 + Z3 - var c = p.x.redAdd(p.z); - // D = X3 - Z3 - var d = p.x.redSub(p.z); - // DA = D * A - var da = d.redMul(a); - // CB = C * B - var cb = c.redMul(b); - // X5 = Z1 * (DA + CB)^2 - var nx = diff.z.redMul(da.redAdd(cb).redSqr()); - // Z5 = X1 * (DA - CB)^2 - var nz = diff.x.redMul(da.redISub(cb).redSqr()); - return this.curve.point(nx, nz); -}; +function toHex32(msg, endian) { + var res = ''; + for (var i = 0; i < msg.length; i++) { + var w = msg[i]; + if (endian === 'little') + w = htonl(w); + res += zero8(w.toString(16)); + } + return res; +} +utils.toHex32 = toHex32; -Point.prototype.mul = function mul(k) { - var t = k.clone(); - var a = this; // (N / 2) * Q + Q - var b = this.curve.point(null, null); // (N / 2) * Q - var c = this; // Q +function zero2(word) { + if (word.length === 1) + return '0' + word; + else + return word; +} +utils.zero2 = zero2; - for (var bits = []; t.cmpn(0) !== 0; t.ishrn(1)) - bits.push(t.andln(1)); +function zero8(word) { + if (word.length === 7) + return '0' + word; + else if (word.length === 6) + return '00' + word; + else if (word.length === 5) + return '000' + word; + else if (word.length === 4) + return '0000' + word; + else if (word.length === 3) + return '00000' + word; + else if (word.length === 2) + return '000000' + word; + else if (word.length === 1) + return '0000000' + word; + else + return word; +} +utils.zero8 = zero8; - for (var i = bits.length - 1; i >= 0; i--) { - if (bits[i] === 0) { - // N * Q + Q = ((N / 2) * Q + Q)) + (N / 2) * Q - a = a.diffAdd(b, c); - // N * Q = 2 * ((N / 2) * Q + Q)) - b = b.dbl(); +function join32(msg, start, end, endian) { + var len = end - start; + assert(len % 4 === 0); + var res = new Array(len / 4); + for (var i = 0, k = start; i < res.length; i++, k += 4) { + var w; + if (endian === 'big') + w = (msg[k] << 24) | (msg[k + 1] << 16) | (msg[k + 2] << 8) | msg[k + 3]; + else + w = (msg[k + 3] << 24) | (msg[k + 2] << 16) | (msg[k + 1] << 8) | msg[k]; + res[i] = w >>> 0; + } + return res; +} +utils.join32 = join32; + +function split32(msg, endian) { + var res = new Array(msg.length * 4); + for (var i = 0, k = 0; i < msg.length; i++, k += 4) { + var m = msg[i]; + if (endian === 'big') { + res[k] = m >>> 24; + res[k + 1] = (m >>> 16) & 0xff; + res[k + 2] = (m >>> 8) & 0xff; + res[k + 3] = m & 0xff; } else { - // N * Q = ((N / 2) * Q + Q) + ((N / 2) * Q) - b = a.diffAdd(b, c); - // N * Q + Q = 2 * ((N / 2) * Q + Q) - a = a.dbl(); + res[k + 3] = m >>> 24; + res[k + 2] = (m >>> 16) & 0xff; + res[k + 1] = (m >>> 8) & 0xff; + res[k] = m & 0xff; } } - return b; -}; + return res; +} +utils.split32 = split32; -Point.prototype.mulAdd = function mulAdd() { - throw new Error('Not supported on Montgomery curve'); -}; +function rotr32(w, b) { + return (w >>> b) | (w << (32 - b)); +} +utils.rotr32 = rotr32; -Point.prototype.normalize = function normalize() { - this.x = this.x.redMul(this.z.redInvm()); - this.z = this.curve.one; - return this; -}; +function rotl32(w, b) { + return (w << b) | (w >>> (32 - b)); +} +utils.rotl32 = rotl32; -Point.prototype.getX = function getX() { - // Normalize coordinates - this.normalize(); +function sum32(a, b) { + return (a + b) >>> 0; +} +utils.sum32 = sum32; - return this.x.fromRed(); -}; +function sum32_3(a, b, c) { + return (a + b + c) >>> 0; +} +utils.sum32_3 = sum32_3; -},{"../../elliptic":209,"../curve":212,"assert":41,"bn.js":207,"inherits":229}],214:[function(require,module,exports){ -var assert = require('assert'); -var curve = require('../curve'); -var elliptic = require('../../elliptic'); -var bn = require('bn.js'); -var inherits = require('inherits'); -var Base = curve.base; +function sum32_4(a, b, c, d) { + return (a + b + c + d) >>> 0; +} +utils.sum32_4 = sum32_4; -var getNAF = elliptic.utils.getNAF; +function sum32_5(a, b, c, d, e) { + return (a + b + c + d + e) >>> 0; +} +utils.sum32_5 = sum32_5; -function ShortCurve(conf) { - Base.call(this, 'short', conf); +function assert(cond, msg) { + if (!cond) + throw new Error(msg || 'Assertion failed'); +} +utils.assert = assert; - this.a = new bn(conf.a, 16).toRed(this.red); - this.b = new bn(conf.b, 16).toRed(this.red); - this.tinv = this.two.redInvm(); +utils.inherits = inherits; - this.zeroA = this.a.fromRed().cmpn(0) === 0; - this.threeA = this.a.fromRed().sub(this.p).cmpn(-3) === 0; +function sum64(buf, pos, ah, al) { + var bh = buf[pos]; + var bl = buf[pos + 1]; - // If the curve is endomorphic, precalculate beta and lambda - this.endo = this._getEndomorphism(conf); - this._endoWnafT1 = new Array(4); - this._endoWnafT2 = new Array(4); + var lo = (al + bl) >>> 0; + var hi = (lo < al ? 1 : 0) + ah + bh; + buf[pos] = hi >>> 0; + buf[pos + 1] = lo; } -inherits(ShortCurve, Base); -module.exports = ShortCurve; +exports.sum64 = sum64; -ShortCurve.prototype._getEndomorphism = function _getEndomorphism(conf) { - // No efficient endomorphism - if (!this.zeroA || !this.g || !this.n || this.p.modn(3) !== 1) - return; +function sum64_hi(ah, al, bh, bl) { + var lo = (al + bl) >>> 0; + var hi = (lo < al ? 1 : 0) + ah + bh; + return hi >>> 0; +}; +exports.sum64_hi = sum64_hi; - // Compute beta and lambda, that lambda * P = (beta * Px; Py) - var beta; - var lambda; - if (conf.beta) { - beta = new bn(conf.beta, 16).toRed(this.red); - } else { - var betas = this._getEndoRoots(this.p); - // Choose the smallest beta - beta = betas[0].cmp(betas[1]) < 0 ? betas[0] : betas[1]; - beta = beta.toRed(this.red); - } - if (conf.lambda) { - lambda = new bn(conf.lambda, 16); - } else { - // Choose the lambda that is matching selected beta - var lambdas = this._getEndoRoots(this.n); - if (this.g.mul(lambdas[0]).x.cmp(this.g.x.redMul(beta)) === 0) { - lambda = lambdas[0]; - } else { - lambda = lambdas[1]; - assert(this.g.mul(lambda).x.cmp(this.g.x.redMul(beta)) === 0); - } - } +function sum64_lo(ah, al, bh, bl) { + var lo = al + bl; + return lo >>> 0; +}; +exports.sum64_lo = sum64_lo; - // Get basis vectors, used for balanced length-two representation - var basis; - if (conf.basis) { - basis = conf.basis.map(function(vec) { - return { - a: new bn(vec.a, 16), - b: new bn(vec.b, 16), - }; - }); - } else { - basis = this._getEndoBasis(lambda); - } +function sum64_4_hi(ah, al, bh, bl, ch, cl, dh, dl) { + var carry = 0; + var lo = al; + lo = (lo + bl) >>> 0; + carry += lo < al ? 1 : 0; + lo = (lo + cl) >>> 0; + carry += lo < cl ? 1 : 0; + lo = (lo + dl) >>> 0; + carry += lo < dl ? 1 : 0; - return { - beta: beta, - lambda: lambda, - basis: basis - }; + var hi = ah + bh + ch + dh + carry; + return hi >>> 0; }; +exports.sum64_4_hi = sum64_4_hi; -ShortCurve.prototype._getEndoRoots = function _getEndoRoots(num) { - // Find roots of for x^2 + x + 1 in F - // Root = (-1 +- Sqrt(-3)) / 2 - // - var red = num === this.p ? this.red : bn.mont(num); - var tinv = new bn(2).toRed(red).redInvm(); - var ntinv = tinv.redNeg(); - var one = new bn(1).toRed(red); +function sum64_4_lo(ah, al, bh, bl, ch, cl, dh, dl) { + var lo = al + bl + cl + dl; + return lo >>> 0; +}; +exports.sum64_4_lo = sum64_4_lo; - var s = new bn(3).toRed(red).redNeg().redSqrt().redMul(tinv); +function sum64_5_hi(ah, al, bh, bl, ch, cl, dh, dl, eh, el) { + var carry = 0; + var lo = al; + lo = (lo + bl) >>> 0; + carry += lo < al ? 1 : 0; + lo = (lo + cl) >>> 0; + carry += lo < cl ? 1 : 0; + lo = (lo + dl) >>> 0; + carry += lo < dl ? 1 : 0; + lo = (lo + el) >>> 0; + carry += lo < el ? 1 : 0; - var l1 = ntinv.redAdd(s).fromRed(); - var l2 = ntinv.redSub(s).fromRed(); - return [ l1, l2 ]; + var hi = ah + bh + ch + dh + eh + carry; + return hi >>> 0; }; +exports.sum64_5_hi = sum64_5_hi; -ShortCurve.prototype._getEndoBasis = function _getEndoBasis(lambda) { - // aprxSqrt >= sqrt(this.n) - var aprxSqrt = this.n.shrn(Math.floor(this.n.bitLength() / 2)); +function sum64_5_lo(ah, al, bh, bl, ch, cl, dh, dl, eh, el) { + var lo = al + bl + cl + dl + el; - // 3.74 - // Run EGCD, until r(L + 1) < aprxSqrt - var u = lambda; - var v = this.n.clone(); - var x1 = new bn(1); - var y1 = new bn(0); - var x2 = new bn(0); - var y2 = new bn(1); + return lo >>> 0; +}; +exports.sum64_5_lo = sum64_5_lo; - // NOTE: all vectors are roots of: a + b * lambda = 0 (mod n) - var a0; - var b0; - // First vector - var a1; - var b1; - // Second vector - var a2; - var b2; +function rotr64_hi(ah, al, num) { + var r = (al << (32 - num)) | (ah >>> num); + return r >>> 0; +}; +exports.rotr64_hi = rotr64_hi; - var prevR; - var i = 0; - while (u.cmpn(0) !== 0) { - var q = v.div(u); - var r = v.sub(q.mul(u)); - var x = x2.sub(q.mul(x1)); - var y = y2.sub(q.mul(y1)); +function rotr64_lo(ah, al, num) { + var r = (ah << (32 - num)) | (al >>> num); + return r >>> 0; +}; +exports.rotr64_lo = rotr64_lo; - if (!a1 && r.cmp(aprxSqrt) < 0) { - a0 = prevR.neg(); - b0 = x1; - a1 = r.neg(); - b1 = x; - } else if (a1 && ++i === 2) { - break; - } - prevR = r; +function shr64_hi(ah, al, num) { + return ah >>> num; +}; +exports.shr64_hi = shr64_hi; - v = u; - u = r; - x2 = x1; - x1 = x; - y2 = y1; - y1 = y; - } - a2 = r.neg(); - b2 = x; +function shr64_lo(ah, al, num) { + var r = (ah << (32 - num)) | (al >>> num); + return r >>> 0; +}; +exports.shr64_lo = shr64_lo; - var len1 = a1.sqr().add(b1.sqr()); - var len2 = a2.sqr().add(b2.sqr()); - if (len2.cmp(len1) >= 0) { - a2 = a0; - b2 = b0; +},{"inherits":240}],240:[function(require,module,exports){ +if (typeof Object.create === 'function') { + // implementation from standard node.js 'util' module + module.exports = function inherits(ctor, superCtor) { + ctor.super_ = superCtor + ctor.prototype = Object.create(superCtor.prototype, { + constructor: { + value: ctor, + enumerable: false, + writable: true, + configurable: true + } + }); + }; +} else { + // old school shim for old browsers + module.exports = function inherits(ctor, superCtor) { + ctor.super_ = superCtor + var TempCtor = function () {} + TempCtor.prototype = superCtor.prototype + ctor.prototype = new TempCtor() + ctor.prototype.constructor = ctor } +} - // Normalize signs - if (a1.sign) { - a1 = a1.neg(); - b1 = b1.neg(); - } - if (a2.sign) { - a2 = a2.neg(); - b2 = b2.neg(); - } +},{}],241:[function(require,module,exports){ +(function (global){ +/** + * @license + * lodash 3.10.1 (Custom Build) + * Build: `lodash modern -d -o ./index.js` + * Copyright 2012-2015 The Dojo Foundation + * Based on Underscore.js 1.8.3 + * Copyright 2009-2015 Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors + * Available under MIT license + */ +;(function() { - return [ - { a: a1, b: b1 }, - { a: a2, b: b2 } - ]; -}; + /** Used as a safe reference for `undefined` in pre-ES5 environments. */ + var undefined; -ShortCurve.prototype._endoSplit = function _endoSplit(k) { - var basis = this.endo.basis; - var v1 = basis[0]; - var v2 = basis[1]; + /** Used as the semantic version number. */ + var VERSION = '3.10.1'; + + /** Used to compose bitmasks for wrapper metadata. */ + var BIND_FLAG = 1, + BIND_KEY_FLAG = 2, + CURRY_BOUND_FLAG = 4, + CURRY_FLAG = 8, + CURRY_RIGHT_FLAG = 16, + PARTIAL_FLAG = 32, + PARTIAL_RIGHT_FLAG = 64, + ARY_FLAG = 128, + REARG_FLAG = 256; + + /** Used as default options for `_.trunc`. */ + var DEFAULT_TRUNC_LENGTH = 30, + DEFAULT_TRUNC_OMISSION = '...'; + + /** Used to detect when a function becomes hot. */ + var HOT_COUNT = 150, + HOT_SPAN = 16; + + /** Used as the size to enable large array optimizations. */ + var LARGE_ARRAY_SIZE = 200; + + /** Used to indicate the type of lazy iteratees. */ + var LAZY_FILTER_FLAG = 1, + LAZY_MAP_FLAG = 2; + + /** Used as the `TypeError` message for "Functions" methods. */ + var FUNC_ERROR_TEXT = 'Expected a function'; + + /** Used as the internal argument placeholder. */ + var PLACEHOLDER = '__lodash_placeholder__'; + + /** `Object#toString` result references. */ + var argsTag = '[object Arguments]', + arrayTag = '[object Array]', + boolTag = '[object Boolean]', + dateTag = '[object Date]', + errorTag = '[object Error]', + funcTag = '[object Function]', + mapTag = '[object Map]', + numberTag = '[object Number]', + objectTag = '[object Object]', + regexpTag = '[object RegExp]', + setTag = '[object Set]', + stringTag = '[object String]', + weakMapTag = '[object WeakMap]'; + + var arrayBufferTag = '[object ArrayBuffer]', + float32Tag = '[object Float32Array]', + float64Tag = '[object Float64Array]', + int8Tag = '[object Int8Array]', + int16Tag = '[object Int16Array]', + int32Tag = '[object Int32Array]', + uint8Tag = '[object Uint8Array]', + uint8ClampedTag = '[object Uint8ClampedArray]', + uint16Tag = '[object Uint16Array]', + uint32Tag = '[object Uint32Array]'; + + /** Used to match empty string literals in compiled template source. */ + var reEmptyStringLeading = /\b__p \+= '';/g, + reEmptyStringMiddle = /\b(__p \+=) '' \+/g, + reEmptyStringTrailing = /(__e\(.*?\)|\b__t\)) \+\n'';/g; - var c1 = v2.b.mul(k).divRound(this.n); - var c2 = v1.b.neg().mul(k).divRound(this.n); + /** Used to match HTML entities and HTML characters. */ + var reEscapedHtml = /&(?:amp|lt|gt|quot|#39|#96);/g, + reUnescapedHtml = /[&<>"'`]/g, + reHasEscapedHtml = RegExp(reEscapedHtml.source), + reHasUnescapedHtml = RegExp(reUnescapedHtml.source); - var p1 = c1.mul(v1.a); - var p2 = c2.mul(v2.a); - var q1 = c1.mul(v1.b); - var q2 = c2.mul(v2.b); + /** Used to match template delimiters. */ + var reEscape = /<%-([\s\S]+?)%>/g, + reEvaluate = /<%([\s\S]+?)%>/g, + reInterpolate = /<%=([\s\S]+?)%>/g; - // Calculate answer - var k1 = k.sub(p1).sub(p2); - var k2 = q1.add(q2).neg(); - return { k1: k1, k2: k2 }; -}; + /** Used to match property names within property paths. */ + var reIsDeepProp = /\.|\[(?:[^[\]]*|(["'])(?:(?!\1)[^\n\\]|\\.)*?\1)\]/, + reIsPlainProp = /^\w*$/, + rePropName = /[^.[\]]+|\[(?:(-?\d+(?:\.\d+)?)|(["'])((?:(?!\2)[^\n\\]|\\.)*?)\2)\]/g; -ShortCurve.prototype.point = function point(x, y, isRed) { - return new Point(this, x, y, isRed); -}; + /** + * Used to match `RegExp` [syntax characters](http://ecma-international.org/ecma-262/6.0/#sec-patterns) + * and those outlined by [`EscapeRegExpPattern`](http://ecma-international.org/ecma-262/6.0/#sec-escaperegexppattern). + */ + var reRegExpChars = /^[:!,]|[\\^$.*+?()[\]{}|\/]|(^[0-9a-fA-Fnrtuvx])|([\n\r\u2028\u2029])/g, + reHasRegExpChars = RegExp(reRegExpChars.source); -ShortCurve.prototype.pointFromX = function pointFromX(odd, x) { - x = new bn(x, 16); - if (!x.red) - x = x.toRed(this.red); + /** Used to match [combining diacritical marks](https://en.wikipedia.org/wiki/Combining_Diacritical_Marks). */ + var reComboMark = /[\u0300-\u036f\ufe20-\ufe23]/g; - var y2 = x.redSqr().redMul(x).redIAdd(x.redMul(this.a)).redIAdd(this.b); - var y = y2.redSqrt(); + /** Used to match backslashes in property paths. */ + var reEscapeChar = /\\(\\)?/g; - // XXX Is there any way to tell if the number is odd without converting it - // to non-red form? - var isOdd = y.fromRed().isOdd(); - if (odd && !isOdd || !odd && isOdd) - y = y.redNeg(); + /** Used to match [ES template delimiters](http://ecma-international.org/ecma-262/6.0/#sec-template-literal-lexical-components). */ + var reEsTemplate = /\$\{([^\\}]*(?:\\.[^\\}]*)*)\}/g; - return this.point(x, y); -}; + /** Used to match `RegExp` flags from their coerced string values. */ + var reFlags = /\w*$/; -ShortCurve.prototype.jpoint = function jpoint(x, y, z) { - return new JPoint(this, x, y, z); -}; + /** Used to detect hexadecimal string values. */ + var reHasHexPrefix = /^0[xX]/; -ShortCurve.prototype.pointFromJSON = function pointFromJSON(obj, red) { - return Point.fromJSON(this, obj, red); -}; + /** Used to detect host constructors (Safari > 5). */ + var reIsHostCtor = /^\[object .+?Constructor\]$/; -ShortCurve.prototype.validate = function validate(point) { - if (point.inf) - return true; + /** Used to detect unsigned integer values. */ + var reIsUint = /^\d+$/; - var x = point.x; - var y = point.y; + /** Used to match latin-1 supplementary letters (excluding mathematical operators). */ + var reLatin1 = /[\xc0-\xd6\xd8-\xde\xdf-\xf6\xf8-\xff]/g; - var ax = this.a.redMul(x); - var rhs = x.redSqr().redMul(x).redIAdd(ax).redIAdd(this.b); - return y.redSqr().redISub(rhs).cmpn(0) === 0; -}; + /** Used to ensure capturing order of template delimiters. */ + var reNoMatch = /($^)/; -ShortCurve.prototype._endoWnafMulAdd = function _endoWnafMulAdd(points, coeffs) { - var npoints = this._endoWnafT1; - var ncoeffs = this._endoWnafT2; - for (var i = 0; i < points.length; i++) { - var split = this._endoSplit(coeffs[i]); - var p = points[i]; - var beta = p._getBeta(); + /** Used to match unescaped characters in compiled string literals. */ + var reUnescapedString = /['\n\r\u2028\u2029\\]/g; - if (split.k1.sign) { - split.k1.sign = !split.k1.sign; - p = p.neg(true); - } - if (split.k2.sign) { - split.k2.sign = !split.k2.sign; - beta = beta.neg(true); - } + /** Used to match words to create compound words. */ + var reWords = (function() { + var upper = '[A-Z\\xc0-\\xd6\\xd8-\\xde]', + lower = '[a-z\\xdf-\\xf6\\xf8-\\xff]+'; - npoints[i * 2] = p; - npoints[i * 2 + 1] = beta; - ncoeffs[i * 2] = split.k1; - ncoeffs[i * 2 + 1] = split.k2; - } - var res = this._wnafMulAdd(1, npoints, ncoeffs, i * 2); + return RegExp(upper + '+(?=' + upper + lower + ')|' + upper + '?' + lower + '|' + upper + '+|[0-9]+', 'g'); + }()); - // Clean-up references to points and coefficients - for (var j = 0; j < i * 2; j++) { - npoints[j] = null; - ncoeffs[j] = null; - } - return res; -}; + /** Used to assign default `context` object properties. */ + var contextProps = [ + 'Array', 'ArrayBuffer', 'Date', 'Error', 'Float32Array', 'Float64Array', + 'Function', 'Int8Array', 'Int16Array', 'Int32Array', 'Math', 'Number', + 'Object', 'RegExp', 'Set', 'String', '_', 'clearTimeout', 'isFinite', + 'parseFloat', 'parseInt', 'setTimeout', 'TypeError', 'Uint8Array', + 'Uint8ClampedArray', 'Uint16Array', 'Uint32Array', 'WeakMap' + ]; -function Point(curve, x, y, isRed) { - Base.BasePoint.call(this, curve, 'affine'); - if (x === null && y === null) { - this.x = null; - this.y = null; - this.inf = true; - } else { - this.x = new bn(x, 16); - this.y = new bn(y, 16); - // Force redgomery representation when loading from JSON - if (isRed) { - this.x.forceRed(this.curve.red); - this.y.forceRed(this.curve.red); - } - if (!this.x.red) - this.x = this.x.toRed(this.curve.red); - if (!this.y.red) - this.y = this.y.toRed(this.curve.red); - this.inf = false; - } -} -inherits(Point, Base.BasePoint); + /** Used to make template sourceURLs easier to identify. */ + var templateCounter = -1; + + /** Used to identify `toStringTag` values of typed arrays. */ + var typedArrayTags = {}; + typedArrayTags[float32Tag] = typedArrayTags[float64Tag] = + typedArrayTags[int8Tag] = typedArrayTags[int16Tag] = + typedArrayTags[int32Tag] = typedArrayTags[uint8Tag] = + typedArrayTags[uint8ClampedTag] = typedArrayTags[uint16Tag] = + typedArrayTags[uint32Tag] = true; + typedArrayTags[argsTag] = typedArrayTags[arrayTag] = + typedArrayTags[arrayBufferTag] = typedArrayTags[boolTag] = + typedArrayTags[dateTag] = typedArrayTags[errorTag] = + typedArrayTags[funcTag] = typedArrayTags[mapTag] = + typedArrayTags[numberTag] = typedArrayTags[objectTag] = + typedArrayTags[regexpTag] = typedArrayTags[setTag] = + typedArrayTags[stringTag] = typedArrayTags[weakMapTag] = false; + + /** Used to identify `toStringTag` values supported by `_.clone`. */ + var cloneableTags = {}; + cloneableTags[argsTag] = cloneableTags[arrayTag] = + cloneableTags[arrayBufferTag] = cloneableTags[boolTag] = + cloneableTags[dateTag] = cloneableTags[float32Tag] = + cloneableTags[float64Tag] = cloneableTags[int8Tag] = + cloneableTags[int16Tag] = cloneableTags[int32Tag] = + cloneableTags[numberTag] = cloneableTags[objectTag] = + cloneableTags[regexpTag] = cloneableTags[stringTag] = + cloneableTags[uint8Tag] = cloneableTags[uint8ClampedTag] = + cloneableTags[uint16Tag] = cloneableTags[uint32Tag] = true; + cloneableTags[errorTag] = cloneableTags[funcTag] = + cloneableTags[mapTag] = cloneableTags[setTag] = + cloneableTags[weakMapTag] = false; + + /** Used to map latin-1 supplementary letters to basic latin letters. */ + var deburredLetters = { + '\xc0': 'A', '\xc1': 'A', '\xc2': 'A', '\xc3': 'A', '\xc4': 'A', '\xc5': 'A', + '\xe0': 'a', '\xe1': 'a', '\xe2': 'a', '\xe3': 'a', '\xe4': 'a', '\xe5': 'a', + '\xc7': 'C', '\xe7': 'c', + '\xd0': 'D', '\xf0': 'd', + '\xc8': 'E', '\xc9': 'E', '\xca': 'E', '\xcb': 'E', + '\xe8': 'e', '\xe9': 'e', '\xea': 'e', '\xeb': 'e', + '\xcC': 'I', '\xcd': 'I', '\xce': 'I', '\xcf': 'I', + '\xeC': 'i', '\xed': 'i', '\xee': 'i', '\xef': 'i', + '\xd1': 'N', '\xf1': 'n', + '\xd2': 'O', '\xd3': 'O', '\xd4': 'O', '\xd5': 'O', '\xd6': 'O', '\xd8': 'O', + '\xf2': 'o', '\xf3': 'o', '\xf4': 'o', '\xf5': 'o', '\xf6': 'o', '\xf8': 'o', + '\xd9': 'U', '\xda': 'U', '\xdb': 'U', '\xdc': 'U', + '\xf9': 'u', '\xfa': 'u', '\xfb': 'u', '\xfc': 'u', + '\xdd': 'Y', '\xfd': 'y', '\xff': 'y', + '\xc6': 'Ae', '\xe6': 'ae', + '\xde': 'Th', '\xfe': 'th', + '\xdf': 'ss' + }; -Point.prototype._getBeta = function _getBeta() { - if (!this.curve.endo) - return; + /** Used to map characters to HTML entities. */ + var htmlEscapes = { + '&': '&', + '<': '<', + '>': '>', + '"': '"', + "'": ''', + '`': '`' + }; - var pre = this.precomputed; - if (pre && pre.beta) - return pre.beta; + /** Used to map HTML entities to characters. */ + var htmlUnescapes = { + '&': '&', + '<': '<', + '>': '>', + '"': '"', + ''': "'", + '`': '`' + }; - var beta = this.curve.point(this.x.redMul(this.curve.endo.beta), this.y); - if (pre) { - var curve = this.curve; - function endoMul(p) { - return curve.point(p.x.redMul(curve.endo.beta), p.y); - } - pre.beta = beta; - beta.precomputed = { - beta: null, - naf: pre.naf && { - wnd: pre.naf.wnd, - points: pre.naf.points.map(endoMul) - }, - doubles: pre.doubles && { - step: pre.doubles.step, - points: pre.doubles.points.map(endoMul) - } - }; - } - return beta; -}; + /** Used to determine if values are of the language type `Object`. */ + var objectTypes = { + 'function': true, + 'object': true + }; -Point.prototype.toJSON = function toJSON() { - if (!this.precomputed) - return [ this.x, this.y ]; + /** Used to escape characters for inclusion in compiled regexes. */ + var regexpEscapes = { + '0': 'x30', '1': 'x31', '2': 'x32', '3': 'x33', '4': 'x34', + '5': 'x35', '6': 'x36', '7': 'x37', '8': 'x38', '9': 'x39', + 'A': 'x41', 'B': 'x42', 'C': 'x43', 'D': 'x44', 'E': 'x45', 'F': 'x46', + 'a': 'x61', 'b': 'x62', 'c': 'x63', 'd': 'x64', 'e': 'x65', 'f': 'x66', + 'n': 'x6e', 'r': 'x72', 't': 'x74', 'u': 'x75', 'v': 'x76', 'x': 'x78' + }; - return [ this.x, this.y, this.precomputed && { - doubles: this.precomputed.doubles && { - step: this.precomputed.doubles.step, - points: this.precomputed.doubles.points.slice(1) - }, - naf: this.precomputed.naf && { - wnd: this.precomputed.naf.wnd, - points: this.precomputed.naf.points.slice(1) - } - }]; -}; + /** Used to escape characters for inclusion in compiled string literals. */ + var stringEscapes = { + '\\': '\\', + "'": "'", + '\n': 'n', + '\r': 'r', + '\u2028': 'u2028', + '\u2029': 'u2029' + }; -Point.fromJSON = function fromJSON(curve, obj, red) { - if (typeof obj === 'string') - obj = JSON.parse(obj); - var res = curve.point(obj[0], obj[1], red); - if (!obj[2]) - return res; + /** Detect free variable `exports`. */ + var freeExports = objectTypes[typeof exports] && exports && !exports.nodeType && exports; - function obj2point(obj) { - return curve.point(obj[0], obj[1], red); - } + /** Detect free variable `module`. */ + var freeModule = objectTypes[typeof module] && module && !module.nodeType && module; - var pre = obj[2]; - res.precomputed = { - beta: null, - doubles: pre.doubles && { - step: pre.doubles.step, - points: [ res ].concat(pre.doubles.points.map(obj2point)) - }, - naf: pre.naf && { - wnd: pre.naf.wnd, - points: [ res ].concat(pre.naf.points.map(obj2point)) - } - }; - return res; -}; + /** Detect free variable `global` from Node.js. */ + var freeGlobal = freeExports && freeModule && typeof global == 'object' && global && global.Object && global; -Point.prototype.inspect = function inspect() { - if (this.isInfinity()) - return ''; - return ''; -}; + /** Detect free variable `self`. */ + var freeSelf = objectTypes[typeof self] && self && self.Object && self; -Point.prototype.isInfinity = function isInfinity() { - return this.inf; -}; + /** Detect free variable `window`. */ + var freeWindow = objectTypes[typeof window] && window && window.Object && window; -Point.prototype.add = function add(p) { - // O + P = P - if (this.inf) - return p; + /** Detect the popular CommonJS extension `module.exports`. */ + var moduleExports = freeModule && freeModule.exports === freeExports && freeExports; - // P + O = P - if (p.inf) - return this; + /** + * Used as a reference to the global object. + * + * The `this` value is used if it's the global object to avoid Greasemonkey's + * restricted `window` object, otherwise the `window` object is used. + */ + var root = freeGlobal || ((freeWindow !== (this && this.window)) && freeWindow) || freeSelf || this; - // P + P = 2P - if (this.eq(p)) - return this.dbl(); + /*--------------------------------------------------------------------------*/ - // P + (-P) = O - if (this.neg().eq(p)) - return this.curve.point(null, null); + /** + * The base implementation of `compareAscending` which compares values and + * sorts them in ascending order without guaranteeing a stable sort. + * + * @private + * @param {*} value The value to compare. + * @param {*} other The other value to compare. + * @returns {number} Returns the sort order indicator for `value`. + */ + function baseCompareAscending(value, other) { + if (value !== other) { + var valIsNull = value === null, + valIsUndef = value === undefined, + valIsReflexive = value === value; + + var othIsNull = other === null, + othIsUndef = other === undefined, + othIsReflexive = other === other; + + if ((value > other && !othIsNull) || !valIsReflexive || + (valIsNull && !othIsUndef && othIsReflexive) || + (valIsUndef && othIsReflexive)) { + return 1; + } + if ((value < other && !valIsNull) || !othIsReflexive || + (othIsNull && !valIsUndef && valIsReflexive) || + (othIsUndef && valIsReflexive)) { + return -1; + } + } + return 0; + } - // P + Q = O - if (this.x.cmp(p.x) === 0) - return this.curve.point(null, null); + /** + * The base implementation of `_.findIndex` and `_.findLastIndex` without + * support for callback shorthands and `this` binding. + * + * @private + * @param {Array} array The array to search. + * @param {Function} predicate The function invoked per iteration. + * @param {boolean} [fromRight] Specify iterating from right to left. + * @returns {number} Returns the index of the matched value, else `-1`. + */ + function baseFindIndex(array, predicate, fromRight) { + var length = array.length, + index = fromRight ? length : -1; - var c = this.y.redSub(p.y); - if (c.cmpn(0) !== 0) - c = c.redMul(this.x.redSub(p.x).redInvm()); - var nx = c.redSqr().redISub(this.x).redISub(p.x); - var ny = c.redMul(this.x.redSub(nx)).redISub(this.y); - return this.curve.point(nx, ny); -}; + while ((fromRight ? index-- : ++index < length)) { + if (predicate(array[index], index, array)) { + return index; + } + } + return -1; + } -Point.prototype.dbl = function dbl() { - if (this.inf) - return this; + /** + * The base implementation of `_.indexOf` without support for binary searches. + * + * @private + * @param {Array} array The array to search. + * @param {*} value The value to search for. + * @param {number} fromIndex The index to search from. + * @returns {number} Returns the index of the matched value, else `-1`. + */ + function baseIndexOf(array, value, fromIndex) { + if (value !== value) { + return indexOfNaN(array, fromIndex); + } + var index = fromIndex - 1, + length = array.length; - // 2P = O - var ys1 = this.y.redAdd(this.y); - if (ys1.cmpn(0) === 0) - return this.curve.point(null, null); + while (++index < length) { + if (array[index] === value) { + return index; + } + } + return -1; + } - var a = this.curve.a; + /** + * The base implementation of `_.isFunction` without support for environments + * with incorrect `typeof` results. + * + * @private + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is correctly classified, else `false`. + */ + function baseIsFunction(value) { + // Avoid a Chakra JIT bug in compatibility modes of IE 11. + // See https://github.com/jashkenas/underscore/issues/1621 for more details. + return typeof value == 'function' || false; + } - var x2 = this.x.redSqr(); - var dyinv = ys1.redInvm(); - var c = x2.redAdd(x2).redIAdd(x2).redIAdd(a).redMul(dyinv); + /** + * Converts `value` to a string if it's not one. An empty string is returned + * for `null` or `undefined` values. + * + * @private + * @param {*} value The value to process. + * @returns {string} Returns the string. + */ + function baseToString(value) { + return value == null ? '' : (value + ''); + } - var nx = c.redSqr().redISub(this.x.redAdd(this.x)); - var ny = c.redMul(this.x.redSub(nx)).redISub(this.y); - return this.curve.point(nx, ny); -}; + /** + * Used by `_.trim` and `_.trimLeft` to get the index of the first character + * of `string` that is not found in `chars`. + * + * @private + * @param {string} string The string to inspect. + * @param {string} chars The characters to find. + * @returns {number} Returns the index of the first character not found in `chars`. + */ + function charsLeftIndex(string, chars) { + var index = -1, + length = string.length; -Point.prototype.getX = function getX() { - return this.x.fromRed(); -}; + while (++index < length && chars.indexOf(string.charAt(index)) > -1) {} + return index; + } -Point.prototype.getY = function getY() { - return this.y.fromRed(); -}; + /** + * Used by `_.trim` and `_.trimRight` to get the index of the last character + * of `string` that is not found in `chars`. + * + * @private + * @param {string} string The string to inspect. + * @param {string} chars The characters to find. + * @returns {number} Returns the index of the last character not found in `chars`. + */ + function charsRightIndex(string, chars) { + var index = string.length; -Point.prototype.mul = function mul(k) { - k = new bn(k, 16); + while (index-- && chars.indexOf(string.charAt(index)) > -1) {} + return index; + } - if (this.precomputed && this.precomputed.doubles) - return this.curve._fixedNafMul(this, k); - else if (this.curve.endo) - return this.curve._endoWnafMulAdd([ this ], [ k ]); - else - return this.curve._wnafMul(this, k); -}; + /** + * Used by `_.sortBy` to compare transformed elements of a collection and stable + * sort them in ascending order. + * + * @private + * @param {Object} object The object to compare. + * @param {Object} other The other object to compare. + * @returns {number} Returns the sort order indicator for `object`. + */ + function compareAscending(object, other) { + return baseCompareAscending(object.criteria, other.criteria) || (object.index - other.index); + } -Point.prototype.mulAdd = function mulAdd(k1, p2, k2) { - var points = [ this, p2 ]; - var coeffs = [ k1, k2 ]; - if (this.curve.endo) - return this.curve._endoWnafMulAdd(points, coeffs); - else - return this.curve._wnafMulAdd(1, points, coeffs, 2); -}; + /** + * Used by `_.sortByOrder` to compare multiple properties of a value to another + * and stable sort them. + * + * If `orders` is unspecified, all valuess are sorted in ascending order. Otherwise, + * a value is sorted in ascending order if its corresponding order is "asc", and + * descending if "desc". + * + * @private + * @param {Object} object The object to compare. + * @param {Object} other The other object to compare. + * @param {boolean[]} orders The order to sort by for each property. + * @returns {number} Returns the sort order indicator for `object`. + */ + function compareMultiple(object, other, orders) { + var index = -1, + objCriteria = object.criteria, + othCriteria = other.criteria, + length = objCriteria.length, + ordersLength = orders.length; -Point.prototype.eq = function eq(p) { - return this === p || - this.inf === p.inf && - (this.inf || this.x.cmp(p.x) === 0 && this.y.cmp(p.y) === 0); -}; + while (++index < length) { + var result = baseCompareAscending(objCriteria[index], othCriteria[index]); + if (result) { + if (index >= ordersLength) { + return result; + } + var order = orders[index]; + return result * ((order === 'asc' || order === true) ? 1 : -1); + } + } + // Fixes an `Array#sort` bug in the JS engine embedded in Adobe applications + // that causes it, under certain circumstances, to provide the same value for + // `object` and `other`. See https://github.com/jashkenas/underscore/pull/1247 + // for more details. + // + // This also ensures a stable sort in V8 and other engines. + // See https://code.google.com/p/v8/issues/detail?id=90 for more details. + return object.index - other.index; + } -Point.prototype.neg = function neg(_precompute) { - if (this.inf) - return this; + /** + * Used by `_.deburr` to convert latin-1 supplementary letters to basic latin letters. + * + * @private + * @param {string} letter The matched letter to deburr. + * @returns {string} Returns the deburred letter. + */ + function deburrLetter(letter) { + return deburredLetters[letter]; + } - var res = this.curve.point(this.x, this.y.redNeg()); - if (_precompute && this.precomputed) { - var pre = this.precomputed; - function negate(p) { - return p.neg(); + /** + * Used by `_.escape` to convert characters to HTML entities. + * + * @private + * @param {string} chr The matched character to escape. + * @returns {string} Returns the escaped character. + */ + function escapeHtmlChar(chr) { + return htmlEscapes[chr]; + } + + /** + * Used by `_.escapeRegExp` to escape characters for inclusion in compiled regexes. + * + * @private + * @param {string} chr The matched character to escape. + * @param {string} leadingChar The capture group for a leading character. + * @param {string} whitespaceChar The capture group for a whitespace character. + * @returns {string} Returns the escaped character. + */ + function escapeRegExpChar(chr, leadingChar, whitespaceChar) { + if (leadingChar) { + chr = regexpEscapes[chr]; + } else if (whitespaceChar) { + chr = stringEscapes[chr]; } - res.precomputed = { - naf: pre.naf && { - wnd: pre.naf.wnd, - points: pre.naf.points.map(negate) - }, - doubles: pre.doubles && { - step: pre.doubles.step, - points: pre.doubles.points.map(negate) - } - }; + return '\\' + chr; + } + + /** + * Used by `_.template` to escape characters for inclusion in compiled string literals. + * + * @private + * @param {string} chr The matched character to escape. + * @returns {string} Returns the escaped character. + */ + function escapeStringChar(chr) { + return '\\' + stringEscapes[chr]; } - return res; -}; - -Point.prototype.toJ = function toJ() { - if (this.inf) - return this.curve.jpoint(null, null, null); - var res = this.curve.jpoint(this.x, this.y, this.curve.one); - return res; -}; + /** + * Gets the index at which the first occurrence of `NaN` is found in `array`. + * + * @private + * @param {Array} array The array to search. + * @param {number} fromIndex The index to search from. + * @param {boolean} [fromRight] Specify iterating from right to left. + * @returns {number} Returns the index of the matched `NaN`, else `-1`. + */ + function indexOfNaN(array, fromIndex, fromRight) { + var length = array.length, + index = fromIndex + (fromRight ? 0 : -1); -function JPoint(curve, x, y, z) { - Base.BasePoint.call(this, curve, 'jacobian'); - if (x === null && y === null && z === null) { - this.x = this.curve.one; - this.y = this.curve.one; - this.z = new bn(0); - } else { - this.x = new bn(x, 16); - this.y = new bn(y, 16); - this.z = new bn(z, 16); + while ((fromRight ? index-- : ++index < length)) { + var other = array[index]; + if (other !== other) { + return index; + } + } + return -1; } - if (!this.x.red) - this.x = this.x.toRed(this.curve.red); - if (!this.y.red) - this.y = this.y.toRed(this.curve.red); - if (!this.z.red) - this.z = this.z.toRed(this.curve.red); - this.zOne = this.z === this.curve.one; -} -inherits(JPoint, Base.BasePoint); + /** + * Checks if `value` is object-like. + * + * @private + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is object-like, else `false`. + */ + function isObjectLike(value) { + return !!value && typeof value == 'object'; + } -JPoint.prototype.toP = function toP() { - if (this.isInfinity()) - return this.curve.point(null, null); + /** + * Used by `trimmedLeftIndex` and `trimmedRightIndex` to determine if a + * character code is whitespace. + * + * @private + * @param {number} charCode The character code to inspect. + * @returns {boolean} Returns `true` if `charCode` is whitespace, else `false`. + */ + function isSpace(charCode) { + return ((charCode <= 160 && (charCode >= 9 && charCode <= 13) || charCode == 32 || charCode == 160) || charCode == 5760 || charCode == 6158 || + (charCode >= 8192 && (charCode <= 8202 || charCode == 8232 || charCode == 8233 || charCode == 8239 || charCode == 8287 || charCode == 12288 || charCode == 65279))); + } - var zinv = this.z.redInvm(); - var zinv2 = zinv.redSqr(); - var ax = this.x.redMul(zinv2); - var ay = this.y.redMul(zinv2).redMul(zinv); + /** + * Replaces all `placeholder` elements in `array` with an internal placeholder + * and returns an array of their indexes. + * + * @private + * @param {Array} array The array to modify. + * @param {*} placeholder The placeholder to replace. + * @returns {Array} Returns the new array of placeholder indexes. + */ + function replaceHolders(array, placeholder) { + var index = -1, + length = array.length, + resIndex = -1, + result = []; - return this.curve.point(ax, ay); -}; + while (++index < length) { + if (array[index] === placeholder) { + array[index] = PLACEHOLDER; + result[++resIndex] = index; + } + } + return result; + } -JPoint.prototype.neg = function neg() { - return this.curve.jpoint(this.x, this.y.redNeg(), this.z); -}; + /** + * An implementation of `_.uniq` optimized for sorted arrays without support + * for callback shorthands and `this` binding. + * + * @private + * @param {Array} array The array to inspect. + * @param {Function} [iteratee] The function invoked per iteration. + * @returns {Array} Returns the new duplicate-value-free array. + */ + function sortedUniq(array, iteratee) { + var seen, + index = -1, + length = array.length, + resIndex = -1, + result = []; -JPoint.prototype.add = function add(p) { - // O + P = P - if (this.isInfinity()) - return p; + while (++index < length) { + var value = array[index], + computed = iteratee ? iteratee(value, index, array) : value; - // P + O = P - if (p.isInfinity()) - return this; + if (!index || seen !== computed) { + seen = computed; + result[++resIndex] = value; + } + } + return result; + } - // 12M + 4S + 7A - var pz2 = p.z.redSqr(); - var z2 = this.z.redSqr(); - var u1 = this.x.redMul(pz2); - var u2 = p.x.redMul(z2); - var s1 = this.y.redMul(pz2.redMul(p.z)); - var s2 = p.y.redMul(z2.redMul(this.z)); + /** + * Used by `_.trim` and `_.trimLeft` to get the index of the first non-whitespace + * character of `string`. + * + * @private + * @param {string} string The string to inspect. + * @returns {number} Returns the index of the first non-whitespace character. + */ + function trimmedLeftIndex(string) { + var index = -1, + length = string.length; - var h = u1.redSub(u2); - var r = s1.redSub(s2); - if (h.cmpn(0) === 0) { - if (r.cmpn(0) !== 0) - return this.curve.jpoint(null, null, null); - else - return this.dbl(); + while (++index < length && isSpace(string.charCodeAt(index))) {} + return index; } - var h2 = h.redSqr(); - var h3 = h2.redMul(h); - var v = u1.redMul(h2); + /** + * Used by `_.trim` and `_.trimRight` to get the index of the last non-whitespace + * character of `string`. + * + * @private + * @param {string} string The string to inspect. + * @returns {number} Returns the index of the last non-whitespace character. + */ + function trimmedRightIndex(string) { + var index = string.length; - var nx = r.redSqr().redIAdd(h3).redISub(v).redISub(v); - var ny = r.redMul(v.redISub(nx)).redISub(s1.redMul(h3)); - var nz = this.z.redMul(p.z).redMul(h); + while (index-- && isSpace(string.charCodeAt(index))) {} + return index; + } - return this.curve.jpoint(nx, ny, nz); -}; + /** + * Used by `_.unescape` to convert HTML entities to characters. + * + * @private + * @param {string} chr The matched character to unescape. + * @returns {string} Returns the unescaped character. + */ + function unescapeHtmlChar(chr) { + return htmlUnescapes[chr]; + } -JPoint.prototype.mixedAdd = function mixedAdd(p) { - // O + P = P - if (this.isInfinity()) - return p.toJ(); + /*--------------------------------------------------------------------------*/ - // P + O = P - if (p.isInfinity()) - return this; + /** + * Create a new pristine `lodash` function using the given `context` object. + * + * @static + * @memberOf _ + * @category Utility + * @param {Object} [context=root] The context object. + * @returns {Function} Returns a new `lodash` function. + * @example + * + * _.mixin({ 'foo': _.constant('foo') }); + * + * var lodash = _.runInContext(); + * lodash.mixin({ 'bar': lodash.constant('bar') }); + * + * _.isFunction(_.foo); + * // => true + * _.isFunction(_.bar); + * // => false + * + * lodash.isFunction(lodash.foo); + * // => false + * lodash.isFunction(lodash.bar); + * // => true + * + * // using `context` to mock `Date#getTime` use in `_.now` + * var mock = _.runInContext({ + * 'Date': function() { + * return { 'getTime': getTimeMock }; + * } + * }); + * + * // or creating a suped-up `defer` in Node.js + * var defer = _.runInContext({ 'setTimeout': setImmediate }).defer; + */ + function runInContext(context) { + // Avoid issues with some ES3 environments that attempt to use values, named + // after built-in constructors like `Object`, for the creation of literals. + // ES5 clears this up by stating that literals must use built-in constructors. + // See https://es5.github.io/#x11.1.5 for more details. + context = context ? _.defaults(root.Object(), context, _.pick(root, contextProps)) : root; - // 8M + 3S + 7A - var z2 = this.z.redSqr(); - var u1 = this.x; - var u2 = p.x.redMul(z2); - var s1 = this.y; - var s2 = p.y.redMul(z2).redMul(this.z); + /** Native constructor references. */ + var Array = context.Array, + Date = context.Date, + Error = context.Error, + Function = context.Function, + Math = context.Math, + Number = context.Number, + Object = context.Object, + RegExp = context.RegExp, + String = context.String, + TypeError = context.TypeError; - var h = u1.redSub(u2); - var r = s1.redSub(s2); - if (h.cmpn(0) === 0) { - if (r.cmpn(0) !== 0) - return this.curve.jpoint(null, null, null); - else - return this.dbl(); - } + /** Used for native method references. */ + var arrayProto = Array.prototype, + objectProto = Object.prototype, + stringProto = String.prototype; - var h2 = h.redSqr(); - var h3 = h2.redMul(h); - var v = u1.redMul(h2); + /** Used to resolve the decompiled source of functions. */ + var fnToString = Function.prototype.toString; - var nx = r.redSqr().redIAdd(h3).redISub(v).redISub(v); - var ny = r.redMul(v.redISub(nx)).redISub(s1.redMul(h3)); - var nz = this.z.redMul(h); + /** Used to check objects for own properties. */ + var hasOwnProperty = objectProto.hasOwnProperty; - return this.curve.jpoint(nx, ny, nz); -}; + /** Used to generate unique IDs. */ + var idCounter = 0; -JPoint.prototype.dblp = function dblp(pow) { - if (pow === 0) - return this; - if (this.isInfinity()) - return this; - if (!pow) - return this.dbl(); + /** + * Used to resolve the [`toStringTag`](http://ecma-international.org/ecma-262/6.0/#sec-object.prototype.tostring) + * of values. + */ + var objToString = objectProto.toString; - if (this.curve.zeroA || this.curve.threeA) { - var r = this; - for (var i = 0; i < pow; i++) - r = r.dbl(); - return r; - } + /** Used to restore the original `_` reference in `_.noConflict`. */ + var oldDash = root._; - // 1M + 2S + 1A + N * (4S + 5M + 8A) - // N = 1 => 6M + 6S + 9A - var a = this.curve.a; - var tinv = this.curve.tinv; + /** Used to detect if a method is native. */ + var reIsNative = RegExp('^' + + fnToString.call(hasOwnProperty).replace(/[\\^$.*+?()[\]{}|]/g, '\\$&') + .replace(/hasOwnProperty|(function).*?(?=\\\()| for .+?(?=\\\])/g, '$1.*?') + '$' + ); - var jx = this.x; - var jy = this.y; - var jz = this.z; - var jz4 = jz.redSqr().redSqr(); + /** Native method references. */ + var ArrayBuffer = context.ArrayBuffer, + clearTimeout = context.clearTimeout, + parseFloat = context.parseFloat, + pow = Math.pow, + propertyIsEnumerable = objectProto.propertyIsEnumerable, + Set = getNative(context, 'Set'), + setTimeout = context.setTimeout, + splice = arrayProto.splice, + Uint8Array = context.Uint8Array, + WeakMap = getNative(context, 'WeakMap'); + + /* Native method references for those with the same name as other `lodash` methods. */ + var nativeCeil = Math.ceil, + nativeCreate = getNative(Object, 'create'), + nativeFloor = Math.floor, + nativeIsArray = getNative(Array, 'isArray'), + nativeIsFinite = context.isFinite, + nativeKeys = getNative(Object, 'keys'), + nativeMax = Math.max, + nativeMin = Math.min, + nativeNow = getNative(Date, 'now'), + nativeParseInt = context.parseInt, + nativeRandom = Math.random; - // Reuse results - var jyd = jy.redAdd(jy); - for (var i = 0; i < pow; i++) { - var jx2 = jx.redSqr(); - var jyd2 = jyd.redSqr(); - var jyd4 = jyd2.redSqr(); - var c = jx2.redAdd(jx2).redIAdd(jx2).redIAdd(a.redMul(jz4)); + /** Used as references for `-Infinity` and `Infinity`. */ + var NEGATIVE_INFINITY = Number.NEGATIVE_INFINITY, + POSITIVE_INFINITY = Number.POSITIVE_INFINITY; - var t1 = jx.redMul(jyd2); - var nx = c.redSqr().redISub(t1.redAdd(t1)); - var t2 = t1.redISub(nx); - var dny = c.redMul(t2); - dny = dny.redIAdd(dny).redISub(jyd4); - var nz = jyd.redMul(jz); - if (i + 1 < pow) - jz4 = jz4.redMul(jyd4); + /** Used as references for the maximum length and index of an array. */ + var MAX_ARRAY_LENGTH = 4294967295, + MAX_ARRAY_INDEX = MAX_ARRAY_LENGTH - 1, + HALF_MAX_ARRAY_LENGTH = MAX_ARRAY_LENGTH >>> 1; - jx = nx; - jz = nz; - jyd = dny; - } + /** + * Used as the [maximum length](http://ecma-international.org/ecma-262/6.0/#sec-number.max_safe_integer) + * of an array-like value. + */ + var MAX_SAFE_INTEGER = 9007199254740991; - return this.curve.jpoint(jx, jyd.redMul(tinv), jz); -}; + /** Used to store function metadata. */ + var metaMap = WeakMap && new WeakMap; -JPoint.prototype.dbl = function dbl() { - if (this.isInfinity()) - return this; + /** Used to lookup unminified function names. */ + var realNames = {}; - if (this.curve.zeroA) - return this._zeroDbl(); - else if (this.curve.threeA) - return this._threeDbl(); - else - return this._dbl(); -}; + /*------------------------------------------------------------------------*/ -JPoint.prototype._zeroDbl = function _zeroDbl() { - // Z = 1 - if (this.zOne) { - // http://hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-0.html#doubling-mdbl-2007-bl - // 1M + 5S + 14A + /** + * Creates a `lodash` object which wraps `value` to enable implicit chaining. + * Methods that operate on and return arrays, collections, and functions can + * be chained together. Methods that retrieve a single value or may return a + * primitive value will automatically end the chain returning the unwrapped + * value. Explicit chaining may be enabled using `_.chain`. The execution of + * chained methods is lazy, that is, execution is deferred until `_#value` + * is implicitly or explicitly called. + * + * Lazy evaluation allows several methods to support shortcut fusion. Shortcut + * fusion is an optimization strategy which merge iteratee calls; this can help + * to avoid the creation of intermediate data structures and greatly reduce the + * number of iteratee executions. + * + * Chaining is supported in custom builds as long as the `_#value` method is + * directly or indirectly included in the build. + * + * In addition to lodash methods, wrappers have `Array` and `String` methods. + * + * The wrapper `Array` methods are: + * `concat`, `join`, `pop`, `push`, `reverse`, `shift`, `slice`, `sort`, + * `splice`, and `unshift` + * + * The wrapper `String` methods are: + * `replace` and `split` + * + * The wrapper methods that support shortcut fusion are: + * `compact`, `drop`, `dropRight`, `dropRightWhile`, `dropWhile`, `filter`, + * `first`, `initial`, `last`, `map`, `pluck`, `reject`, `rest`, `reverse`, + * `slice`, `take`, `takeRight`, `takeRightWhile`, `takeWhile`, `toArray`, + * and `where` + * + * The chainable wrapper methods are: + * `after`, `ary`, `assign`, `at`, `before`, `bind`, `bindAll`, `bindKey`, + * `callback`, `chain`, `chunk`, `commit`, `compact`, `concat`, `constant`, + * `countBy`, `create`, `curry`, `debounce`, `defaults`, `defaultsDeep`, + * `defer`, `delay`, `difference`, `drop`, `dropRight`, `dropRightWhile`, + * `dropWhile`, `fill`, `filter`, `flatten`, `flattenDeep`, `flow`, `flowRight`, + * `forEach`, `forEachRight`, `forIn`, `forInRight`, `forOwn`, `forOwnRight`, + * `functions`, `groupBy`, `indexBy`, `initial`, `intersection`, `invert`, + * `invoke`, `keys`, `keysIn`, `map`, `mapKeys`, `mapValues`, `matches`, + * `matchesProperty`, `memoize`, `merge`, `method`, `methodOf`, `mixin`, + * `modArgs`, `negate`, `omit`, `once`, `pairs`, `partial`, `partialRight`, + * `partition`, `pick`, `plant`, `pluck`, `property`, `propertyOf`, `pull`, + * `pullAt`, `push`, `range`, `rearg`, `reject`, `remove`, `rest`, `restParam`, + * `reverse`, `set`, `shuffle`, `slice`, `sort`, `sortBy`, `sortByAll`, + * `sortByOrder`, `splice`, `spread`, `take`, `takeRight`, `takeRightWhile`, + * `takeWhile`, `tap`, `throttle`, `thru`, `times`, `toArray`, `toPlainObject`, + * `transform`, `union`, `uniq`, `unshift`, `unzip`, `unzipWith`, `values`, + * `valuesIn`, `where`, `without`, `wrap`, `xor`, `zip`, `zipObject`, `zipWith` + * + * The wrapper methods that are **not** chainable by default are: + * `add`, `attempt`, `camelCase`, `capitalize`, `ceil`, `clone`, `cloneDeep`, + * `deburr`, `endsWith`, `escape`, `escapeRegExp`, `every`, `find`, `findIndex`, + * `findKey`, `findLast`, `findLastIndex`, `findLastKey`, `findWhere`, `first`, + * `floor`, `get`, `gt`, `gte`, `has`, `identity`, `includes`, `indexOf`, + * `inRange`, `isArguments`, `isArray`, `isBoolean`, `isDate`, `isElement`, + * `isEmpty`, `isEqual`, `isError`, `isFinite` `isFunction`, `isMatch`, + * `isNative`, `isNaN`, `isNull`, `isNumber`, `isObject`, `isPlainObject`, + * `isRegExp`, `isString`, `isUndefined`, `isTypedArray`, `join`, `kebabCase`, + * `last`, `lastIndexOf`, `lt`, `lte`, `max`, `min`, `noConflict`, `noop`, + * `now`, `pad`, `padLeft`, `padRight`, `parseInt`, `pop`, `random`, `reduce`, + * `reduceRight`, `repeat`, `result`, `round`, `runInContext`, `shift`, `size`, + * `snakeCase`, `some`, `sortedIndex`, `sortedLastIndex`, `startCase`, + * `startsWith`, `sum`, `template`, `trim`, `trimLeft`, `trimRight`, `trunc`, + * `unescape`, `uniqueId`, `value`, and `words` + * + * The wrapper method `sample` will return a wrapped value when `n` is provided, + * otherwise an unwrapped value is returned. + * + * @name _ + * @constructor + * @category Chain + * @param {*} value The value to wrap in a `lodash` instance. + * @returns {Object} Returns the new `lodash` wrapper instance. + * @example + * + * var wrapped = _([1, 2, 3]); + * + * // returns an unwrapped value + * wrapped.reduce(function(total, n) { + * return total + n; + * }); + * // => 6 + * + * // returns a wrapped value + * var squares = wrapped.map(function(n) { + * return n * n; + * }); + * + * _.isArray(squares); + * // => false + * + * _.isArray(squares.value()); + * // => true + */ + function lodash(value) { + if (isObjectLike(value) && !isArray(value) && !(value instanceof LazyWrapper)) { + if (value instanceof LodashWrapper) { + return value; + } + if (hasOwnProperty.call(value, '__chain__') && hasOwnProperty.call(value, '__wrapped__')) { + return wrapperClone(value); + } + } + return new LodashWrapper(value); + } - // XX = X1^2 - var xx = this.x.redSqr(); - // YY = Y1^2 - var yy = this.y.redSqr(); - // YYYY = YY^2 - var yyyy = yy.redSqr(); - // S = 2 * ((X1 + YY)^2 - XX - YYYY) - var s = this.x.redAdd(yy).redSqr().redISub(xx).redISub(yyyy); - s = s.redIAdd(s); - // M = 3 * XX + a; a = 0 - var m = xx.redAdd(xx).redIAdd(xx); - // T = M ^ 2 - 2*S - var t = m.redSqr().redISub(s).redISub(s); + /** + * The function whose prototype all chaining wrappers inherit from. + * + * @private + */ + function baseLodash() { + // No operation performed. + } - // 8 * YYYY - var yyyy8 = yyyy.redIAdd(yyyy); - yyyy8 = yyyy8.redIAdd(yyyy8); - yyyy8 = yyyy8.redIAdd(yyyy8); + /** + * The base constructor for creating `lodash` wrapper objects. + * + * @private + * @param {*} value The value to wrap. + * @param {boolean} [chainAll] Enable chaining for all wrapper methods. + * @param {Array} [actions=[]] Actions to peform to resolve the unwrapped value. + */ + function LodashWrapper(value, chainAll, actions) { + this.__wrapped__ = value; + this.__actions__ = actions || []; + this.__chain__ = !!chainAll; + } - // X3 = T - var nx = t; - // Y3 = M * (S - T) - 8 * YYYY - var ny = m.redMul(s.redISub(t)).redISub(yyyy8); - // Z3 = 2*Y1 - var nz = this.y.redAdd(this.y); - } else { - // http://hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-0.html#doubling-dbl-2009-l - // 2M + 5S + 13A + /** + * An object environment feature flags. + * + * @static + * @memberOf _ + * @type Object + */ + var support = lodash.support = {}; - // A = X1^2 - var a = this.x.redSqr(); - // B = Y1^2 - var b = this.y.redSqr(); - // C = B^2 - var c = b.redSqr(); - // D = 2 * ((X1 + B)^2 - A - C) - var d = this.x.redAdd(b).redSqr().redISub(a).redISub(c); - d = d.redIAdd(d); - // E = 3 * A - var e = a.redAdd(a).redIAdd(a); - // F = E^2 - var f = e.redSqr(); + /** + * By default, the template delimiters used by lodash are like those in + * embedded Ruby (ERB). Change the following template settings to use + * alternative delimiters. + * + * @static + * @memberOf _ + * @type Object + */ + lodash.templateSettings = { - // 8 * C - var c8 = c.redIAdd(c); - c8 = c8.redIAdd(c8); - c8 = c8.redIAdd(c8); + /** + * Used to detect `data` property values to be HTML-escaped. + * + * @memberOf _.templateSettings + * @type RegExp + */ + 'escape': reEscape, - // X3 = F - 2 * D - var nx = f.redISub(d).redISub(d); - // Y3 = E * (D - X3) - 8 * C - var ny = e.redMul(d.redISub(nx)).redISub(c8); - // Z3 = 2 * Y1 * Z1 - var nz = this.y.redMul(this.z); - nz = nz.redIAdd(nz); - } + /** + * Used to detect code to be evaluated. + * + * @memberOf _.templateSettings + * @type RegExp + */ + 'evaluate': reEvaluate, - return this.curve.jpoint(nx, ny, nz); -}; + /** + * Used to detect `data` property values to inject. + * + * @memberOf _.templateSettings + * @type RegExp + */ + 'interpolate': reInterpolate, -JPoint.prototype._threeDbl = function _threeDbl() { - // Z = 1 - if (this.zOne) { - // http://hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-3.html#doubling-mdbl-2007-bl - // 1M + 5S + 15A + /** + * Used to reference the data object in the template text. + * + * @memberOf _.templateSettings + * @type string + */ + 'variable': '', - // XX = X1^2 - var xx = this.x.redSqr(); - // YY = Y1^2 - var yy = this.y.redSqr(); - // YYYY = YY^2 - var yyyy = yy.redSqr(); - // S = 2 * ((X1 + YY)^2 - XX - YYYY) - var s = this.x.redAdd(yy).redSqr().redISub(xx).redISub(yyyy); - s = s.redIAdd(s); - // M = 3 * XX + a - var m = xx.redAdd(xx).redIAdd(xx).redIAdd(this.curve.a); - // T = M^2 - 2 * S - var t = m.redSqr().redISub(s).redISub(s); - // X3 = T - var nx = t; - // Y3 = M * (S - T) - 8 * YYYY - var yyyy8 = yyyy.redIAdd(yyyy); - yyyy8 = yyyy8.redIAdd(yyyy8); - yyyy8 = yyyy8.redIAdd(yyyy8); - var ny = m.redMul(s.redISub(t)).redISub(yyyy8); - // Z3 = 2 * Y1 - var nz = this.y.redAdd(this.y); - } else { - // http://hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-3.html#doubling-dbl-2001-b - // 3M + 5S + /** + * Used to import variables into the compiled template. + * + * @memberOf _.templateSettings + * @type Object + */ + 'imports': { - // delta = Z1^2 - var delta = this.z.redSqr(); - // gamma = Y1^2 - var gamma = this.y.redSqr(); - // beta = X1 * gamma - var beta = this.x.redMul(gamma); - // alpha = 3 * (X1 - delta) * (X1 + delta) - var alpha = this.x.redSub(delta).redMul(this.x.redAdd(delta)); - alpha = alpha.redAdd(alpha).redIAdd(alpha); - // X3 = alpha^2 - 8 * beta - var beta4 = beta.redIAdd(beta); - beta4 = beta4.redIAdd(beta4); - var beta8 = beta4.redAdd(beta4); - var nx = alpha.redSqr().redISub(beta8); - // Z3 = (Y1 + Z1)^2 - gamma - delta - var nz = this.y.redAdd(this.z).redSqr().redISub(gamma).redISub(delta); - // Y3 = alpha * (4 * beta - X3) - 8 * gamma^2 - var ggamma8 = gamma.redSqr(); - ggamma8 = ggamma8.redIAdd(ggamma8); - ggamma8 = ggamma8.redIAdd(ggamma8); - ggamma8 = ggamma8.redIAdd(ggamma8); - var ny = alpha.redMul(beta4.redISub(nx)).redISub(ggamma8); - } + /** + * A reference to the `lodash` function. + * + * @memberOf _.templateSettings.imports + * @type Function + */ + '_': lodash + } + }; - return this.curve.jpoint(nx, ny, nz); -}; + /*------------------------------------------------------------------------*/ -JPoint.prototype._dbl = function _dbl() { - var a = this.curve.a; - var tinv = this.curve.tinv; + /** + * Creates a lazy wrapper object which wraps `value` to enable lazy evaluation. + * + * @private + * @param {*} value The value to wrap. + */ + function LazyWrapper(value) { + this.__wrapped__ = value; + this.__actions__ = []; + this.__dir__ = 1; + this.__filtered__ = false; + this.__iteratees__ = []; + this.__takeCount__ = POSITIVE_INFINITY; + this.__views__ = []; + } - // 4M + 6S + 10A - var jx = this.x; - var jy = this.y; - var jz = this.z; - var jz4 = jz.redSqr().redSqr(); + /** + * Creates a clone of the lazy wrapper object. + * + * @private + * @name clone + * @memberOf LazyWrapper + * @returns {Object} Returns the cloned `LazyWrapper` object. + */ + function lazyClone() { + var result = new LazyWrapper(this.__wrapped__); + result.__actions__ = arrayCopy(this.__actions__); + result.__dir__ = this.__dir__; + result.__filtered__ = this.__filtered__; + result.__iteratees__ = arrayCopy(this.__iteratees__); + result.__takeCount__ = this.__takeCount__; + result.__views__ = arrayCopy(this.__views__); + return result; + } - var jx2 = jx.redSqr(); - var jy2 = jy.redSqr(); + /** + * Reverses the direction of lazy iteration. + * + * @private + * @name reverse + * @memberOf LazyWrapper + * @returns {Object} Returns the new reversed `LazyWrapper` object. + */ + function lazyReverse() { + if (this.__filtered__) { + var result = new LazyWrapper(this); + result.__dir__ = -1; + result.__filtered__ = true; + } else { + result = this.clone(); + result.__dir__ *= -1; + } + return result; + } - var c = jx2.redAdd(jx2).redIAdd(jx2).redIAdd(a.redMul(jz4)); + /** + * Extracts the unwrapped value from its lazy wrapper. + * + * @private + * @name value + * @memberOf LazyWrapper + * @returns {*} Returns the unwrapped value. + */ + function lazyValue() { + var array = this.__wrapped__.value(), + dir = this.__dir__, + isArr = isArray(array), + isRight = dir < 0, + arrLength = isArr ? array.length : 0, + view = getView(0, arrLength, this.__views__), + start = view.start, + end = view.end, + length = end - start, + index = isRight ? end : (start - 1), + iteratees = this.__iteratees__, + iterLength = iteratees.length, + resIndex = 0, + takeCount = nativeMin(length, this.__takeCount__); + + if (!isArr || arrLength < LARGE_ARRAY_SIZE || (arrLength == length && takeCount == length)) { + return baseWrapperValue((isRight && isArr) ? array.reverse() : array, this.__actions__); + } + var result = []; - var jxd4 = jx.redAdd(jx); - jxd4 = jxd4.redIAdd(jxd4); - var t1 = jxd4.redMul(jy2); - var nx = c.redSqr().redISub(t1.redAdd(t1)); - var t2 = t1.redISub(nx); + outer: + while (length-- && resIndex < takeCount) { + index += dir; + + var iterIndex = -1, + value = array[index]; + + while (++iterIndex < iterLength) { + var data = iteratees[iterIndex], + iteratee = data.iteratee, + type = data.type, + computed = iteratee(value); + + if (type == LAZY_MAP_FLAG) { + value = computed; + } else if (!computed) { + if (type == LAZY_FILTER_FLAG) { + continue outer; + } else { + break outer; + } + } + } + result[resIndex++] = value; + } + return result; + } - var jyd8 = jy2.redSqr(); - jyd8 = jyd8.redIAdd(jyd8); - jyd8 = jyd8.redIAdd(jyd8); - jyd8 = jyd8.redIAdd(jyd8); - var ny = c.redMul(t2).redISub(jyd8); - var nz = jy.redAdd(jy).redMul(jz); + /*------------------------------------------------------------------------*/ + + /** + * Creates a cache object to store key/value pairs. + * + * @private + * @static + * @name Cache + * @memberOf _.memoize + */ + function MapCache() { + this.__data__ = {}; + } - return this.curve.jpoint(nx, ny, nz); -}; + /** + * Removes `key` and its value from the cache. + * + * @private + * @name delete + * @memberOf _.memoize.Cache + * @param {string} key The key of the value to remove. + * @returns {boolean} Returns `true` if the entry was removed successfully, else `false`. + */ + function mapDelete(key) { + return this.has(key) && delete this.__data__[key]; + } -JPoint.prototype.trpl = function trpl() { - if (!this.curve.zeroA) - return this.dbl().add(this); + /** + * Gets the cached value for `key`. + * + * @private + * @name get + * @memberOf _.memoize.Cache + * @param {string} key The key of the value to get. + * @returns {*} Returns the cached value. + */ + function mapGet(key) { + return key == '__proto__' ? undefined : this.__data__[key]; + } - // http://hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-0.html#tripling-tpl-2007-bl - // 5M + 10S + ... + /** + * Checks if a cached value for `key` exists. + * + * @private + * @name has + * @memberOf _.memoize.Cache + * @param {string} key The key of the entry to check. + * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`. + */ + function mapHas(key) { + return key != '__proto__' && hasOwnProperty.call(this.__data__, key); + } - // XX = X1^2 - var xx = this.x.redSqr(); - // YY = Y1^2 - var yy = this.y.redSqr(); - // ZZ = Z1^2 - var zz = this.z.redSqr(); - // YYYY = YY^2 - var yyyy = yy.redSqr(); - // M = 3 * XX + a * ZZ2; a = 0 - var m = xx.redAdd(xx).redIAdd(xx); - // MM = M^2 - var mm = m.redSqr(); - // E = 6 * ((X1 + YY)^2 - XX - YYYY) - MM - var e = this.x.redAdd(yy).redSqr().redISub(xx).redISub(yyyy); - e = e.redIAdd(e); - e = e.redAdd(e).redIAdd(e); - e = e.redISub(mm); - // EE = E^2 - var ee = e.redSqr(); - // T = 16*YYYY - var t = yyyy.redIAdd(yyyy); - t = t.redIAdd(t); - t = t.redIAdd(t); - t = t.redIAdd(t); - // U = (M + E)^2 - MM - EE - T - var u = m.redIAdd(e).redSqr().redISub(mm).redISub(ee).redISub(t); - // X3 = 4 * (X1 * EE - 4 * YY * U) - var yyu4 = yy.redMul(u); - yyu4 = yyu4.redIAdd(yyu4); - yyu4 = yyu4.redIAdd(yyu4); - var nx = this.x.redMul(ee).redISub(yyu4); - nx = nx.redIAdd(nx); - nx = nx.redIAdd(nx); - // Y3 = 8 * Y1 * (U * (T - U) - E * EE) - var ny = this.y.redMul(u.redMul(t.redISub(u)).redISub(e.redMul(ee))); - ny = ny.redIAdd(ny); - ny = ny.redIAdd(ny); - ny = ny.redIAdd(ny); - // Z3 = (Z1 + E)^2 - ZZ - EE - var nz = this.z.redAdd(e).redSqr().redISub(zz).redISub(ee); + /** + * Sets `value` to `key` of the cache. + * + * @private + * @name set + * @memberOf _.memoize.Cache + * @param {string} key The key of the value to cache. + * @param {*} value The value to cache. + * @returns {Object} Returns the cache object. + */ + function mapSet(key, value) { + if (key != '__proto__') { + this.__data__[key] = value; + } + return this; + } - return this.curve.jpoint(nx, ny, nz); -}; + /*------------------------------------------------------------------------*/ -JPoint.prototype.mul = function mul(k, kbase) { - k = new bn(k, kbase); + /** + * + * Creates a cache object to store unique values. + * + * @private + * @param {Array} [values] The values to cache. + */ + function SetCache(values) { + var length = values ? values.length : 0; - return this.curve._wnafMul(this, k); -}; + this.data = { 'hash': nativeCreate(null), 'set': new Set }; + while (length--) { + this.push(values[length]); + } + } -JPoint.prototype.eq = function eq(p) { - if (p.type === 'affine') - return this.eq(p.toJ()); + /** + * Checks if `value` is in `cache` mimicking the return signature of + * `_.indexOf` by returning `0` if the value is found, else `-1`. + * + * @private + * @param {Object} cache The cache to search. + * @param {*} value The value to search for. + * @returns {number} Returns `0` if `value` is found, else `-1`. + */ + function cacheIndexOf(cache, value) { + var data = cache.data, + result = (typeof value == 'string' || isObject(value)) ? data.set.has(value) : data.hash[value]; - if (this === p) - return true; + return result ? 0 : -1; + } - // x1 * z2^2 == x2 * z1^2 - var z2 = this.z.redSqr(); - var pz2 = p.z.redSqr(); - if (this.x.redMul(pz2).redISub(p.x.redMul(z2)).cmpn(0) !== 0) - return false; + /** + * Adds `value` to the cache. + * + * @private + * @name push + * @memberOf SetCache + * @param {*} value The value to cache. + */ + function cachePush(value) { + var data = this.data; + if (typeof value == 'string' || isObject(value)) { + data.set.add(value); + } else { + data.hash[value] = true; + } + } - // y1 * z2^3 == y2 * z1^3 - var z3 = z2.redMul(this.z); - var pz3 = pz2.redMul(p.z); - return this.y.redMul(pz3).redISub(p.y.redMul(z3)).cmpn(0) === 0; -}; + /*------------------------------------------------------------------------*/ -JPoint.prototype.inspect = function inspect() { - if (this.isInfinity()) - return ''; - return ''; -}; + /** + * Creates a new array joining `array` with `other`. + * + * @private + * @param {Array} array The array to join. + * @param {Array} other The other array to join. + * @returns {Array} Returns the new concatenated array. + */ + function arrayConcat(array, other) { + var index = -1, + length = array.length, + othIndex = -1, + othLength = other.length, + result = Array(length + othLength); -JPoint.prototype.isInfinity = function isInfinity() { - // XXX This code assumes that zero is always zero in red - return this.z.cmpn(0) === 0; -}; + while (++index < length) { + result[index] = array[index]; + } + while (++othIndex < othLength) { + result[index++] = other[othIndex]; + } + return result; + } -},{"../../elliptic":209,"../curve":212,"assert":41,"bn.js":207,"inherits":229}],215:[function(require,module,exports){ -var curves = exports; + /** + * Copies the values of `source` to `array`. + * + * @private + * @param {Array} source The array to copy values from. + * @param {Array} [array=[]] The array to copy values to. + * @returns {Array} Returns `array`. + */ + function arrayCopy(source, array) { + var index = -1, + length = source.length; -var assert = require('assert'); -var hash = require('hash.js'); -var bn = require('bn.js'); -var elliptic = require('../elliptic'); + array || (array = Array(length)); + while (++index < length) { + array[index] = source[index]; + } + return array; + } -function PresetCurve(options) { - if (options.type === 'short') - this.curve = new elliptic.curve.short(options); - else if (options.type === 'edwards') - this.curve = new elliptic.curve.edwards(options); - else - this.curve = new elliptic.curve.mont(options); - this.g = this.curve.g; - this.n = this.curve.n; - this.hash = options.hash; + /** + * A specialized version of `_.forEach` for arrays without support for callback + * shorthands and `this` binding. + * + * @private + * @param {Array} array The array to iterate over. + * @param {Function} iteratee The function invoked per iteration. + * @returns {Array} Returns `array`. + */ + function arrayEach(array, iteratee) { + var index = -1, + length = array.length; - assert(this.g.validate(), 'Invalid curve'); - assert(this.g.mul(this.n).isInfinity(), 'Invalid curve, G*N != O'); -} -curves.PresetCurve = PresetCurve; + while (++index < length) { + if (iteratee(array[index], index, array) === false) { + break; + } + } + return array; + } -function defineCurve(name, options) { - Object.defineProperty(curves, name, { - configurable: true, - enumerable: true, - get: function() { - var curve = new PresetCurve(options); - Object.defineProperty(curves, name, { - configurable: true, - enumerable: true, - value: curve - }); - return curve; + /** + * A specialized version of `_.forEachRight` for arrays without support for + * callback shorthands and `this` binding. + * + * @private + * @param {Array} array The array to iterate over. + * @param {Function} iteratee The function invoked per iteration. + * @returns {Array} Returns `array`. + */ + function arrayEachRight(array, iteratee) { + var length = array.length; + + while (length--) { + if (iteratee(array[length], length, array) === false) { + break; + } + } + return array; } - }); -} -defineCurve('p192', { - type: 'short', - prime: 'p192', - p: 'ffffffff ffffffff ffffffff fffffffe ffffffff ffffffff', - a: 'ffffffff ffffffff ffffffff fffffffe ffffffff fffffffc', - b: '64210519 e59c80e7 0fa7e9ab 72243049 feb8deec c146b9b1', - n: 'ffffffff ffffffff ffffffff 99def836 146bc9b1 b4d22831', - hash: hash.sha256, - gRed: false, - g: [ - '188da80e b03090f6 7cbf20eb 43a18800 f4ff0afd 82ff1012', - '07192b95 ffc8da78 631011ed 6b24cdd5 73f977a1 1e794811' - ], -}); + /** + * A specialized version of `_.every` for arrays without support for callback + * shorthands and `this` binding. + * + * @private + * @param {Array} array The array to iterate over. + * @param {Function} predicate The function invoked per iteration. + * @returns {boolean} Returns `true` if all elements pass the predicate check, + * else `false`. + */ + function arrayEvery(array, predicate) { + var index = -1, + length = array.length; -defineCurve('p224', { - type: 'short', - prime: 'p224', - p: 'ffffffff ffffffff ffffffff ffffffff 00000000 00000000 00000001', - a: 'ffffffff ffffffff ffffffff fffffffe ffffffff ffffffff fffffffe', - b: 'b4050a85 0c04b3ab f5413256 5044b0b7 d7bfd8ba 270b3943 2355ffb4', - n: 'ffffffff ffffffff ffffffff ffff16a2 e0b8f03e 13dd2945 5c5c2a3d', - hash: hash.sha256, - gRed: false, - g: [ - 'b70e0cbd 6bb4bf7f 321390b9 4a03c1d3 56c21122 343280d6 115c1d21', - 'bd376388 b5f723fb 4c22dfe6 cd4375a0 5a074764 44d58199 85007e34' - ], -}); + while (++index < length) { + if (!predicate(array[index], index, array)) { + return false; + } + } + return true; + } -defineCurve('p256', { - type: 'short', - prime: null, - p: 'ffffffff 00000001 00000000 00000000 00000000 ffffffff ffffffff ffffffff', - a: 'ffffffff 00000001 00000000 00000000 00000000 ffffffff ffffffff fffffffc', - b: '5ac635d8 aa3a93e7 b3ebbd55 769886bc 651d06b0 cc53b0f6 3bce3c3e 27d2604b', - n: 'ffffffff 00000000 ffffffff ffffffff bce6faad a7179e84 f3b9cac2 fc632551', - hash: hash.sha256, - gRed: false, - g: [ - '6b17d1f2 e12c4247 f8bce6e5 63a440f2 77037d81 2deb33a0 f4a13945 d898c296', - '4fe342e2 fe1a7f9b 8ee7eb4a 7c0f9e16 2bce3357 6b315ece cbb64068 37bf51f5' - ], -}); + /** + * A specialized version of `baseExtremum` for arrays which invokes `iteratee` + * with one argument: (value). + * + * @private + * @param {Array} array The array to iterate over. + * @param {Function} iteratee The function invoked per iteration. + * @param {Function} comparator The function used to compare values. + * @param {*} exValue The initial extremum value. + * @returns {*} Returns the extremum value. + */ + function arrayExtremum(array, iteratee, comparator, exValue) { + var index = -1, + length = array.length, + computed = exValue, + result = computed; -defineCurve('curve25519', { - type: 'mont', - prime: 'p25519', - p: '7fffffffffffffff ffffffffffffffff ffffffffffffffff ffffffffffffffed', - a: '76d06', - b: '0', - n: '1000000000000000 0000000000000000 14def9dea2f79cd6 5812631a5cf5d3ed', - hash: hash.sha256, - gRed: false, - g: [ - '9' - ] -}); + while (++index < length) { + var value = array[index], + current = +iteratee(value); -defineCurve('ed25519', { - type: 'edwards', - prime: 'p25519', - p: '7fffffffffffffff ffffffffffffffff ffffffffffffffff ffffffffffffffed', - a: '-1', - c: '1', - // -121665 * (121666^(-1)) (mod P) - d: '52036cee2b6ffe73 8cc740797779e898 00700a4d4141d8ab 75eb4dca135978a3', - n: '1000000000000000 0000000000000000 14def9dea2f79cd6 5812631a5cf5d3ed', - hash: hash.sha256, - gRed: false, - g: [ - '216936d3cd6e53fec0a4e231fdd6dc5c692cc7609525a7b2c9562d608f25d51a', + if (comparator(current, computed)) { + computed = current; + result = value; + } + } + return result; + } - // 4/5 - '6666666666666666666666666666666666666666666666666666666666666658' - ] -}); + /** + * A specialized version of `_.filter` for arrays without support for callback + * shorthands and `this` binding. + * + * @private + * @param {Array} array The array to iterate over. + * @param {Function} predicate The function invoked per iteration. + * @returns {Array} Returns the new filtered array. + */ + function arrayFilter(array, predicate) { + var index = -1, + length = array.length, + resIndex = -1, + result = []; -defineCurve('secp256k1', { - type: 'short', - prime: 'k256', - p: 'ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff fffffffe fffffc2f', - a: '0', - b: '7', - n: 'ffffffff ffffffff ffffffff fffffffe baaedce6 af48a03b bfd25e8c d0364141', - h: '1', - hash: hash.sha256, + while (++index < length) { + var value = array[index]; + if (predicate(value, index, array)) { + result[++resIndex] = value; + } + } + return result; + } - // Precomputed endomorphism - beta: '7ae96a2b657c07106e64479eac3434e99cf0497512f58995c1396c28719501ee', - lambda: '5363ad4cc05c30e0a5261c028812645a122e22ea20816678df02967c1b23bd72', - basis: [ - { - a: '3086d221a7d46bcde86c90e49284eb15', - b: '-e4437ed6010e88286f547fa90abfe4c3' - }, - { - a: '114ca50f7a8e2f3f657c1108d9d44cfd8', - b: '3086d221a7d46bcde86c90e49284eb15' + /** + * A specialized version of `_.map` for arrays without support for callback + * shorthands and `this` binding. + * + * @private + * @param {Array} array The array to iterate over. + * @param {Function} iteratee The function invoked per iteration. + * @returns {Array} Returns the new mapped array. + */ + function arrayMap(array, iteratee) { + var index = -1, + length = array.length, + result = Array(length); + + while (++index < length) { + result[index] = iteratee(array[index], index, array); + } + return result; } - ], - gRed: false, - g: [ - '79be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798', - '483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8', - { - 'doubles': { - 'step': 4, - 'points': [ - [ - 'e60fce93b59e9ec53011aabc21c23e97b2a31369b87a5ae9c44ee89e2a6dec0a', - 'f7e3507399e595929db99f34f57937101296891e44d23f0be1f32cce69616821' - ], - [ - '8282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508', - '11f8a8098557dfe45e8256e830b60ace62d613ac2f7b17bed31b6eaff6e26caf' - ], - [ - '175e159f728b865a72f99cc6c6fc846de0b93833fd2222ed73fce5b551e5b739', - 'd3506e0d9e3c79eba4ef97a51ff71f5eacb5955add24345c6efa6ffee9fed695' - ], - [ - '363d90d447b00c9c99ceac05b6262ee053441c7e55552ffe526bad8f83ff4640', - '4e273adfc732221953b445397f3363145b9a89008199ecb62003c7f3bee9de9' - ], - [ - '8b4b5f165df3c2be8c6244b5b745638843e4a781a15bcd1b69f79a55dffdf80c', - '4aad0a6f68d308b4b3fbd7813ab0da04f9e336546162ee56b3eff0c65fd4fd36' - ], - [ - '723cbaa6e5db996d6bf771c00bd548c7b700dbffa6c0e77bcb6115925232fcda', - '96e867b5595cc498a921137488824d6e2660a0653779494801dc069d9eb39f5f' - ], - [ - 'eebfa4d493bebf98ba5feec812c2d3b50947961237a919839a533eca0e7dd7fa', - '5d9a8ca3970ef0f269ee7edaf178089d9ae4cdc3a711f712ddfd4fdae1de8999' - ], - [ - '100f44da696e71672791d0a09b7bde459f1215a29b3c03bfefd7835b39a48db0', - 'cdd9e13192a00b772ec8f3300c090666b7ff4a18ff5195ac0fbd5cd62bc65a09' - ], - [ - 'e1031be262c7ed1b1dc9227a4a04c017a77f8d4464f3b3852c8acde6e534fd2d', - '9d7061928940405e6bb6a4176597535af292dd419e1ced79a44f18f29456a00d' - ], - [ - 'feea6cae46d55b530ac2839f143bd7ec5cf8b266a41d6af52d5e688d9094696d', - 'e57c6b6c97dce1bab06e4e12bf3ecd5c981c8957cc41442d3155debf18090088' - ], - [ - 'da67a91d91049cdcb367be4be6ffca3cfeed657d808583de33fa978bc1ec6cb1', - '9bacaa35481642bc41f463f7ec9780e5dec7adc508f740a17e9ea8e27a68be1d' - ], - [ - '53904faa0b334cdda6e000935ef22151ec08d0f7bb11069f57545ccc1a37b7c0', - '5bc087d0bc80106d88c9eccac20d3c1c13999981e14434699dcb096b022771c8' - ], - [ - '8e7bcd0bd35983a7719cca7764ca906779b53a043a9b8bcaeff959f43ad86047', - '10b7770b2a3da4b3940310420ca9514579e88e2e47fd68b3ea10047e8460372a' - ], - [ - '385eed34c1cdff21e6d0818689b81bde71a7f4f18397e6690a841e1599c43862', - '283bebc3e8ea23f56701de19e9ebf4576b304eec2086dc8cc0458fe5542e5453' - ], - [ - '6f9d9b803ecf191637c73a4413dfa180fddf84a5947fbc9c606ed86c3fac3a7', - '7c80c68e603059ba69b8e2a30e45c4d47ea4dd2f5c281002d86890603a842160' - ], - [ - '3322d401243c4e2582a2147c104d6ecbf774d163db0f5e5313b7e0e742d0e6bd', - '56e70797e9664ef5bfb019bc4ddaf9b72805f63ea2873af624f3a2e96c28b2a0' - ], - [ - '85672c7d2de0b7da2bd1770d89665868741b3f9af7643397721d74d28134ab83', - '7c481b9b5b43b2eb6374049bfa62c2e5e77f17fcc5298f44c8e3094f790313a6' - ], - [ - '948bf809b1988a46b06c9f1919413b10f9226c60f668832ffd959af60c82a0a', - '53a562856dcb6646dc6b74c5d1c3418c6d4dff08c97cd2bed4cb7f88d8c8e589' - ], - [ - '6260ce7f461801c34f067ce0f02873a8f1b0e44dfc69752accecd819f38fd8e8', - 'bc2da82b6fa5b571a7f09049776a1ef7ecd292238051c198c1a84e95b2b4ae17' - ], - [ - 'e5037de0afc1d8d43d8348414bbf4103043ec8f575bfdc432953cc8d2037fa2d', - '4571534baa94d3b5f9f98d09fb990bddbd5f5b03ec481f10e0e5dc841d755bda' - ], - [ - 'e06372b0f4a207adf5ea905e8f1771b4e7e8dbd1c6a6c5b725866a0ae4fce725', - '7a908974bce18cfe12a27bb2ad5a488cd7484a7787104870b27034f94eee31dd' - ], - [ - '213c7a715cd5d45358d0bbf9dc0ce02204b10bdde2a3f58540ad6908d0559754', - '4b6dad0b5ae462507013ad06245ba190bb4850f5f36a7eeddff2c27534b458f2' - ], - [ - '4e7c272a7af4b34e8dbb9352a5419a87e2838c70adc62cddf0cc3a3b08fbd53c', - '17749c766c9d0b18e16fd09f6def681b530b9614bff7dd33e0b3941817dcaae6' - ], - [ - 'fea74e3dbe778b1b10f238ad61686aa5c76e3db2be43057632427e2840fb27b6', - '6e0568db9b0b13297cf674deccb6af93126b596b973f7b77701d3db7f23cb96f' - ], - [ - '76e64113f677cf0e10a2570d599968d31544e179b760432952c02a4417bdde39', - 'c90ddf8dee4e95cf577066d70681f0d35e2a33d2b56d2032b4b1752d1901ac01' - ], - [ - 'c738c56b03b2abe1e8281baa743f8f9a8f7cc643df26cbee3ab150242bcbb891', - '893fb578951ad2537f718f2eacbfbbbb82314eef7880cfe917e735d9699a84c3' - ], - [ - 'd895626548b65b81e264c7637c972877d1d72e5f3a925014372e9f6588f6c14b', - 'febfaa38f2bc7eae728ec60818c340eb03428d632bb067e179363ed75d7d991f' - ], - [ - 'b8da94032a957518eb0f6433571e8761ceffc73693e84edd49150a564f676e03', - '2804dfa44805a1e4d7c99cc9762808b092cc584d95ff3b511488e4e74efdf6e7' - ], - [ - 'e80fea14441fb33a7d8adab9475d7fab2019effb5156a792f1a11778e3c0df5d', - 'eed1de7f638e00771e89768ca3ca94472d155e80af322ea9fcb4291b6ac9ec78' - ], - [ - 'a301697bdfcd704313ba48e51d567543f2a182031efd6915ddc07bbcc4e16070', - '7370f91cfb67e4f5081809fa25d40f9b1735dbf7c0a11a130c0d1a041e177ea1' - ], - [ - '90ad85b389d6b936463f9d0512678de208cc330b11307fffab7ac63e3fb04ed4', - 'e507a3620a38261affdcbd9427222b839aefabe1582894d991d4d48cb6ef150' - ], - [ - '8f68b9d2f63b5f339239c1ad981f162ee88c5678723ea3351b7b444c9ec4c0da', - '662a9f2dba063986de1d90c2b6be215dbbea2cfe95510bfdf23cbf79501fff82' - ], - [ - 'e4f3fb0176af85d65ff99ff9198c36091f48e86503681e3e6686fd5053231e11', - '1e63633ad0ef4f1c1661a6d0ea02b7286cc7e74ec951d1c9822c38576feb73bc' - ], - [ - '8c00fa9b18ebf331eb961537a45a4266c7034f2f0d4e1d0716fb6eae20eae29e', - 'efa47267fea521a1a9dc343a3736c974c2fadafa81e36c54e7d2a4c66702414b' - ], - [ - 'e7a26ce69dd4829f3e10cec0a9e98ed3143d084f308b92c0997fddfc60cb3e41', - '2a758e300fa7984b471b006a1aafbb18d0a6b2c0420e83e20e8a9421cf2cfd51' - ], - [ - 'b6459e0ee3662ec8d23540c223bcbdc571cbcb967d79424f3cf29eb3de6b80ef', - '67c876d06f3e06de1dadf16e5661db3c4b3ae6d48e35b2ff30bf0b61a71ba45' - ], - [ - 'd68a80c8280bb840793234aa118f06231d6f1fc67e73c5a5deda0f5b496943e8', - 'db8ba9fff4b586d00c4b1f9177b0e28b5b0e7b8f7845295a294c84266b133120' - ], - [ - '324aed7df65c804252dc0270907a30b09612aeb973449cea4095980fc28d3d5d', - '648a365774b61f2ff130c0c35aec1f4f19213b0c7e332843967224af96ab7c84' - ], - [ - '4df9c14919cde61f6d51dfdbe5fee5dceec4143ba8d1ca888e8bd373fd054c96', - '35ec51092d8728050974c23a1d85d4b5d506cdc288490192ebac06cad10d5d' - ], - [ - '9c3919a84a474870faed8a9c1cc66021523489054d7f0308cbfc99c8ac1f98cd', - 'ddb84f0f4a4ddd57584f044bf260e641905326f76c64c8e6be7e5e03d4fc599d' - ], - [ - '6057170b1dd12fdf8de05f281d8e06bb91e1493a8b91d4cc5a21382120a959e5', - '9a1af0b26a6a4807add9a2daf71df262465152bc3ee24c65e899be932385a2a8' - ], - [ - 'a576df8e23a08411421439a4518da31880cef0fba7d4df12b1a6973eecb94266', - '40a6bf20e76640b2c92b97afe58cd82c432e10a7f514d9f3ee8be11ae1b28ec8' - ], - [ - '7778a78c28dec3e30a05fe9629de8c38bb30d1f5cf9a3a208f763889be58ad71', - '34626d9ab5a5b22ff7098e12f2ff580087b38411ff24ac563b513fc1fd9f43ac' - ], - [ - '928955ee637a84463729fd30e7afd2ed5f96274e5ad7e5cb09eda9c06d903ac', - 'c25621003d3f42a827b78a13093a95eeac3d26efa8a8d83fc5180e935bcd091f' - ], - [ - '85d0fef3ec6db109399064f3a0e3b2855645b4a907ad354527aae75163d82751', - '1f03648413a38c0be29d496e582cf5663e8751e96877331582c237a24eb1f962' - ], - [ - 'ff2b0dce97eece97c1c9b6041798b85dfdfb6d8882da20308f5404824526087e', - '493d13fef524ba188af4c4dc54d07936c7b7ed6fb90e2ceb2c951e01f0c29907' - ], - [ - '827fbbe4b1e880ea9ed2b2e6301b212b57f1ee148cd6dd28780e5e2cf856e241', - 'c60f9c923c727b0b71bef2c67d1d12687ff7a63186903166d605b68baec293ec' - ], - [ - 'eaa649f21f51bdbae7be4ae34ce6e5217a58fdce7f47f9aa7f3b58fa2120e2b3', - 'be3279ed5bbbb03ac69a80f89879aa5a01a6b965f13f7e59d47a5305ba5ad93d' - ], - [ - 'e4a42d43c5cf169d9391df6decf42ee541b6d8f0c9a137401e23632dda34d24f', - '4d9f92e716d1c73526fc99ccfb8ad34ce886eedfa8d8e4f13a7f7131deba9414' - ], - [ - '1ec80fef360cbdd954160fadab352b6b92b53576a88fea4947173b9d4300bf19', - 'aeefe93756b5340d2f3a4958a7abbf5e0146e77f6295a07b671cdc1cc107cefd' - ], - [ - '146a778c04670c2f91b00af4680dfa8bce3490717d58ba889ddb5928366642be', - 'b318e0ec3354028add669827f9d4b2870aaa971d2f7e5ed1d0b297483d83efd0' - ], - [ - 'fa50c0f61d22e5f07e3acebb1aa07b128d0012209a28b9776d76a8793180eef9', - '6b84c6922397eba9b72cd2872281a68a5e683293a57a213b38cd8d7d3f4f2811' - ], - [ - 'da1d61d0ca721a11b1a5bf6b7d88e8421a288ab5d5bba5220e53d32b5f067ec2', - '8157f55a7c99306c79c0766161c91e2966a73899d279b48a655fba0f1ad836f1' - ], - [ - 'a8e282ff0c9706907215ff98e8fd416615311de0446f1e062a73b0610d064e13', - '7f97355b8db81c09abfb7f3c5b2515888b679a3e50dd6bd6cef7c73111f4cc0c' - ], - [ - '174a53b9c9a285872d39e56e6913cab15d59b1fa512508c022f382de8319497c', - 'ccc9dc37abfc9c1657b4155f2c47f9e6646b3a1d8cb9854383da13ac079afa73' - ], - [ - '959396981943785c3d3e57edf5018cdbe039e730e4918b3d884fdff09475b7ba', - '2e7e552888c331dd8ba0386a4b9cd6849c653f64c8709385e9b8abf87524f2fd' - ], - [ - 'd2a63a50ae401e56d645a1153b109a8fcca0a43d561fba2dbb51340c9d82b151', - 'e82d86fb6443fcb7565aee58b2948220a70f750af484ca52d4142174dcf89405' - ], - [ - '64587e2335471eb890ee7896d7cfdc866bacbdbd3839317b3436f9b45617e073', - 'd99fcdd5bf6902e2ae96dd6447c299a185b90a39133aeab358299e5e9faf6589' - ], - [ - '8481bde0e4e4d885b3a546d3e549de042f0aa6cea250e7fd358d6c86dd45e458', - '38ee7b8cba5404dd84a25bf39cecb2ca900a79c42b262e556d64b1b59779057e' - ], - [ - '13464a57a78102aa62b6979ae817f4637ffcfed3c4b1ce30bcd6303f6caf666b', - '69be159004614580ef7e433453ccb0ca48f300a81d0942e13f495a907f6ecc27' - ], - [ - 'bc4a9df5b713fe2e9aef430bcc1dc97a0cd9ccede2f28588cada3a0d2d83f366', - 'd3a81ca6e785c06383937adf4b798caa6e8a9fbfa547b16d758d666581f33c1' - ], - [ - '8c28a97bf8298bc0d23d8c749452a32e694b65e30a9472a3954ab30fe5324caa', - '40a30463a3305193378fedf31f7cc0eb7ae784f0451cb9459e71dc73cbef9482' - ], - [ - '8ea9666139527a8c1dd94ce4f071fd23c8b350c5a4bb33748c4ba111faccae0', - '620efabbc8ee2782e24e7c0cfb95c5d735b783be9cf0f8e955af34a30e62b945' - ], - [ - 'dd3625faef5ba06074669716bbd3788d89bdde815959968092f76cc4eb9a9787', - '7a188fa3520e30d461da2501045731ca941461982883395937f68d00c644a573' - ], - [ - 'f710d79d9eb962297e4f6232b40e8f7feb2bc63814614d692c12de752408221e', - 'ea98e67232d3b3295d3b535532115ccac8612c721851617526ae47a9c77bfc82' - ] - ] - }, - 'naf': { - 'wnd': 7, - 'points': [ - [ - 'f9308a019258c31049344f85f89d5229b531c845836f99b08601f113bce036f9', - '388f7b0f632de8140fe337e62a37f3566500a99934c2231b6cb9fd7584b8e672' - ], - [ - '2f8bde4d1a07209355b4a7250a5c5128e88b84bddc619ab7cba8d569b240efe4', - 'd8ac222636e5e3d6d4dba9dda6c9c426f788271bab0d6840dca87d3aa6ac62d6' - ], - [ - '5cbdf0646e5db4eaa398f365f2ea7a0e3d419b7e0330e39ce92bddedcac4f9bc', - '6aebca40ba255960a3178d6d861a54dba813d0b813fde7b5a5082628087264da' - ], - [ - 'acd484e2f0c7f65309ad178a9f559abde09796974c57e714c35f110dfc27ccbe', - 'cc338921b0a7d9fd64380971763b61e9add888a4375f8e0f05cc262ac64f9c37' - ], - [ - '774ae7f858a9411e5ef4246b70c65aac5649980be5c17891bbec17895da008cb', - 'd984a032eb6b5e190243dd56d7b7b365372db1e2dff9d6a8301d74c9c953c61b' - ], - [ - 'f28773c2d975288bc7d1d205c3748651b075fbc6610e58cddeeddf8f19405aa8', - 'ab0902e8d880a89758212eb65cdaf473a1a06da521fa91f29b5cb52db03ed81' - ], - [ - 'd7924d4f7d43ea965a465ae3095ff41131e5946f3c85f79e44adbcf8e27e080e', - '581e2872a86c72a683842ec228cc6defea40af2bd896d3a5c504dc9ff6a26b58' - ], - [ - 'defdea4cdb677750a420fee807eacf21eb9898ae79b9768766e4faa04a2d4a34', - '4211ab0694635168e997b0ead2a93daeced1f4a04a95c0f6cfb199f69e56eb77' - ], - [ - '2b4ea0a797a443d293ef5cff444f4979f06acfebd7e86d277475656138385b6c', - '85e89bc037945d93b343083b5a1c86131a01f60c50269763b570c854e5c09b7a' - ], - [ - '352bbf4a4cdd12564f93fa332ce333301d9ad40271f8107181340aef25be59d5', - '321eb4075348f534d59c18259dda3e1f4a1b3b2e71b1039c67bd3d8bcf81998c' - ], - [ - '2fa2104d6b38d11b0230010559879124e42ab8dfeff5ff29dc9cdadd4ecacc3f', - '2de1068295dd865b64569335bd5dd80181d70ecfc882648423ba76b532b7d67' - ], - [ - '9248279b09b4d68dab21a9b066edda83263c3d84e09572e269ca0cd7f5453714', - '73016f7bf234aade5d1aa71bdea2b1ff3fc0de2a887912ffe54a32ce97cb3402' - ], - [ - 'daed4f2be3a8bf278e70132fb0beb7522f570e144bf615c07e996d443dee8729', - 'a69dce4a7d6c98e8d4a1aca87ef8d7003f83c230f3afa726ab40e52290be1c55' - ], - [ - 'c44d12c7065d812e8acf28d7cbb19f9011ecd9e9fdf281b0e6a3b5e87d22e7db', - '2119a460ce326cdc76c45926c982fdac0e106e861edf61c5a039063f0e0e6482' - ], - [ - '6a245bf6dc698504c89a20cfded60853152b695336c28063b61c65cbd269e6b4', - 'e022cf42c2bd4a708b3f5126f16a24ad8b33ba48d0423b6efd5e6348100d8a82' - ], - [ - '1697ffa6fd9de627c077e3d2fe541084ce13300b0bec1146f95ae57f0d0bd6a5', - 'b9c398f186806f5d27561506e4557433a2cf15009e498ae7adee9d63d01b2396' - ], - [ - '605bdb019981718b986d0f07e834cb0d9deb8360ffb7f61df982345ef27a7479', - '2972d2de4f8d20681a78d93ec96fe23c26bfae84fb14db43b01e1e9056b8c49' - ], - [ - '62d14dab4150bf497402fdc45a215e10dcb01c354959b10cfe31c7e9d87ff33d', - '80fc06bd8cc5b01098088a1950eed0db01aa132967ab472235f5642483b25eaf' - ], - [ - '80c60ad0040f27dade5b4b06c408e56b2c50e9f56b9b8b425e555c2f86308b6f', - '1c38303f1cc5c30f26e66bad7fe72f70a65eed4cbe7024eb1aa01f56430bd57a' - ], - [ - '7a9375ad6167ad54aa74c6348cc54d344cc5dc9487d847049d5eabb0fa03c8fb', - 'd0e3fa9eca8726909559e0d79269046bdc59ea10c70ce2b02d499ec224dc7f7' - ], - [ - 'd528ecd9b696b54c907a9ed045447a79bb408ec39b68df504bb51f459bc3ffc9', - 'eecf41253136e5f99966f21881fd656ebc4345405c520dbc063465b521409933' - ], - [ - '49370a4b5f43412ea25f514e8ecdad05266115e4a7ecb1387231808f8b45963', - '758f3f41afd6ed428b3081b0512fd62a54c3f3afbb5b6764b653052a12949c9a' - ], - [ - '77f230936ee88cbbd73df930d64702ef881d811e0e1498e2f1c13eb1fc345d74', - '958ef42a7886b6400a08266e9ba1b37896c95330d97077cbbe8eb3c7671c60d6' - ], - [ - 'f2dac991cc4ce4b9ea44887e5c7c0bce58c80074ab9d4dbaeb28531b7739f530', - 'e0dedc9b3b2f8dad4da1f32dec2531df9eb5fbeb0598e4fd1a117dba703a3c37' - ], - [ - '463b3d9f662621fb1b4be8fbbe2520125a216cdfc9dae3debcba4850c690d45b', - '5ed430d78c296c3543114306dd8622d7c622e27c970a1de31cb377b01af7307e' - ], - [ - 'f16f804244e46e2a09232d4aff3b59976b98fac14328a2d1a32496b49998f247', - 'cedabd9b82203f7e13d206fcdf4e33d92a6c53c26e5cce26d6579962c4e31df6' - ], - [ - 'caf754272dc84563b0352b7a14311af55d245315ace27c65369e15f7151d41d1', - 'cb474660ef35f5f2a41b643fa5e460575f4fa9b7962232a5c32f908318a04476' - ], - [ - '2600ca4b282cb986f85d0f1709979d8b44a09c07cb86d7c124497bc86f082120', - '4119b88753c15bd6a693b03fcddbb45d5ac6be74ab5f0ef44b0be9475a7e4b40' - ], - [ - '7635ca72d7e8432c338ec53cd12220bc01c48685e24f7dc8c602a7746998e435', - '91b649609489d613d1d5e590f78e6d74ecfc061d57048bad9e76f302c5b9c61' - ], - [ - '754e3239f325570cdbbf4a87deee8a66b7f2b33479d468fbc1a50743bf56cc18', - '673fb86e5bda30fb3cd0ed304ea49a023ee33d0197a695d0c5d98093c536683' - ], - [ - 'e3e6bd1071a1e96aff57859c82d570f0330800661d1c952f9fe2694691d9b9e8', - '59c9e0bba394e76f40c0aa58379a3cb6a5a2283993e90c4167002af4920e37f5' - ], - [ - '186b483d056a033826ae73d88f732985c4ccb1f32ba35f4b4cc47fdcf04aa6eb', - '3b952d32c67cf77e2e17446e204180ab21fb8090895138b4a4a797f86e80888b' - ], - [ - 'df9d70a6b9876ce544c98561f4be4f725442e6d2b737d9c91a8321724ce0963f', - '55eb2dafd84d6ccd5f862b785dc39d4ab157222720ef9da217b8c45cf2ba2417' - ], - [ - '5edd5cc23c51e87a497ca815d5dce0f8ab52554f849ed8995de64c5f34ce7143', - 'efae9c8dbc14130661e8cec030c89ad0c13c66c0d17a2905cdc706ab7399a868' - ], - [ - '290798c2b6476830da12fe02287e9e777aa3fba1c355b17a722d362f84614fba', - 'e38da76dcd440621988d00bcf79af25d5b29c094db2a23146d003afd41943e7a' - ], - [ - 'af3c423a95d9f5b3054754efa150ac39cd29552fe360257362dfdecef4053b45', - 'f98a3fd831eb2b749a93b0e6f35cfb40c8cd5aa667a15581bc2feded498fd9c6' - ], - [ - '766dbb24d134e745cccaa28c99bf274906bb66b26dcf98df8d2fed50d884249a', - '744b1152eacbe5e38dcc887980da38b897584a65fa06cedd2c924f97cbac5996' - ], - [ - '59dbf46f8c94759ba21277c33784f41645f7b44f6c596a58ce92e666191abe3e', - 'c534ad44175fbc300f4ea6ce648309a042ce739a7919798cd85e216c4a307f6e' - ], - [ - 'f13ada95103c4537305e691e74e9a4a8dd647e711a95e73cb62dc6018cfd87b8', - 'e13817b44ee14de663bf4bc808341f326949e21a6a75c2570778419bdaf5733d' - ], - [ - '7754b4fa0e8aced06d4167a2c59cca4cda1869c06ebadfb6488550015a88522c', - '30e93e864e669d82224b967c3020b8fa8d1e4e350b6cbcc537a48b57841163a2' - ], - [ - '948dcadf5990e048aa3874d46abef9d701858f95de8041d2a6828c99e2262519', - 'e491a42537f6e597d5d28a3224b1bc25df9154efbd2ef1d2cbba2cae5347d57e' - ], - [ - '7962414450c76c1689c7b48f8202ec37fb224cf5ac0bfa1570328a8a3d7c77ab', - '100b610ec4ffb4760d5c1fc133ef6f6b12507a051f04ac5760afa5b29db83437' - ], - [ - '3514087834964b54b15b160644d915485a16977225b8847bb0dd085137ec47ca', - 'ef0afbb2056205448e1652c48e8127fc6039e77c15c2378b7e7d15a0de293311' - ], - [ - 'd3cc30ad6b483e4bc79ce2c9dd8bc54993e947eb8df787b442943d3f7b527eaf', - '8b378a22d827278d89c5e9be8f9508ae3c2ad46290358630afb34db04eede0a4' - ], - [ - '1624d84780732860ce1c78fcbfefe08b2b29823db913f6493975ba0ff4847610', - '68651cf9b6da903e0914448c6cd9d4ca896878f5282be4c8cc06e2a404078575' - ], - [ - '733ce80da955a8a26902c95633e62a985192474b5af207da6df7b4fd5fc61cd4', - 'f5435a2bd2badf7d485a4d8b8db9fcce3e1ef8e0201e4578c54673bc1dc5ea1d' - ], - [ - '15d9441254945064cf1a1c33bbd3b49f8966c5092171e699ef258dfab81c045c', - 'd56eb30b69463e7234f5137b73b84177434800bacebfc685fc37bbe9efe4070d' - ], - [ - 'a1d0fcf2ec9de675b612136e5ce70d271c21417c9d2b8aaaac138599d0717940', - 'edd77f50bcb5a3cab2e90737309667f2641462a54070f3d519212d39c197a629' - ], - [ - 'e22fbe15c0af8ccc5780c0735f84dbe9a790badee8245c06c7ca37331cb36980', - 'a855babad5cd60c88b430a69f53a1a7a38289154964799be43d06d77d31da06' - ], - [ - '311091dd9860e8e20ee13473c1155f5f69635e394704eaa74009452246cfa9b3', - '66db656f87d1f04fffd1f04788c06830871ec5a64feee685bd80f0b1286d8374' - ], - [ - '34c1fd04d301be89b31c0442d3e6ac24883928b45a9340781867d4232ec2dbdf', - '9414685e97b1b5954bd46f730174136d57f1ceeb487443dc5321857ba73abee' - ], - [ - 'f219ea5d6b54701c1c14de5b557eb42a8d13f3abbcd08affcc2a5e6b049b8d63', - '4cb95957e83d40b0f73af4544cccf6b1f4b08d3c07b27fb8d8c2962a400766d1' - ], - [ - 'd7b8740f74a8fbaab1f683db8f45de26543a5490bca627087236912469a0b448', - 'fa77968128d9c92ee1010f337ad4717eff15db5ed3c049b3411e0315eaa4593b' - ], - [ - '32d31c222f8f6f0ef86f7c98d3a3335ead5bcd32abdd94289fe4d3091aa824bf', - '5f3032f5892156e39ccd3d7915b9e1da2e6dac9e6f26e961118d14b8462e1661' - ], - [ - '7461f371914ab32671045a155d9831ea8793d77cd59592c4340f86cbc18347b5', - '8ec0ba238b96bec0cbdddcae0aa442542eee1ff50c986ea6b39847b3cc092ff6' - ], - [ - 'ee079adb1df1860074356a25aa38206a6d716b2c3e67453d287698bad7b2b2d6', - '8dc2412aafe3be5c4c5f37e0ecc5f9f6a446989af04c4e25ebaac479ec1c8c1e' - ], - [ - '16ec93e447ec83f0467b18302ee620f7e65de331874c9dc72bfd8616ba9da6b5', - '5e4631150e62fb40d0e8c2a7ca5804a39d58186a50e497139626778e25b0674d' - ], - [ - 'eaa5f980c245f6f038978290afa70b6bd8855897f98b6aa485b96065d537bd99', - 'f65f5d3e292c2e0819a528391c994624d784869d7e6ea67fb18041024edc07dc' - ], - [ - '78c9407544ac132692ee1910a02439958ae04877151342ea96c4b6b35a49f51', - 'f3e0319169eb9b85d5404795539a5e68fa1fbd583c064d2462b675f194a3ddb4' - ], - [ - '494f4be219a1a77016dcd838431aea0001cdc8ae7a6fc688726578d9702857a5', - '42242a969283a5f339ba7f075e36ba2af925ce30d767ed6e55f4b031880d562c' - ], - [ - 'a598a8030da6d86c6bc7f2f5144ea549d28211ea58faa70ebf4c1e665c1fe9b5', - '204b5d6f84822c307e4b4a7140737aec23fc63b65b35f86a10026dbd2d864e6b' - ], - [ - 'c41916365abb2b5d09192f5f2dbeafec208f020f12570a184dbadc3e58595997', - '4f14351d0087efa49d245b328984989d5caf9450f34bfc0ed16e96b58fa9913' - ], - [ - '841d6063a586fa475a724604da03bc5b92a2e0d2e0a36acfe4c73a5514742881', - '73867f59c0659e81904f9a1c7543698e62562d6744c169ce7a36de01a8d6154' - ], - [ - '5e95bb399a6971d376026947f89bde2f282b33810928be4ded112ac4d70e20d5', - '39f23f366809085beebfc71181313775a99c9aed7d8ba38b161384c746012865' - ], - [ - '36e4641a53948fd476c39f8a99fd974e5ec07564b5315d8bf99471bca0ef2f66', - 'd2424b1b1abe4eb8164227b085c9aa9456ea13493fd563e06fd51cf5694c78fc' - ], - [ - '336581ea7bfbbb290c191a2f507a41cf5643842170e914faeab27c2c579f726', - 'ead12168595fe1be99252129b6e56b3391f7ab1410cd1e0ef3dcdcabd2fda224' - ], - [ - '8ab89816dadfd6b6a1f2634fcf00ec8403781025ed6890c4849742706bd43ede', - '6fdcef09f2f6d0a044e654aef624136f503d459c3e89845858a47a9129cdd24e' - ], - [ - '1e33f1a746c9c5778133344d9299fcaa20b0938e8acff2544bb40284b8c5fb94', - '60660257dd11b3aa9c8ed618d24edff2306d320f1d03010e33a7d2057f3b3b6' - ], - [ - '85b7c1dcb3cec1b7ee7f30ded79dd20a0ed1f4cc18cbcfcfa410361fd8f08f31', - '3d98a9cdd026dd43f39048f25a8847f4fcafad1895d7a633c6fed3c35e999511' - ], - [ - '29df9fbd8d9e46509275f4b125d6d45d7fbe9a3b878a7af872a2800661ac5f51', - 'b4c4fe99c775a606e2d8862179139ffda61dc861c019e55cd2876eb2a27d84b' - ], - [ - 'a0b1cae06b0a847a3fea6e671aaf8adfdfe58ca2f768105c8082b2e449fce252', - 'ae434102edde0958ec4b19d917a6a28e6b72da1834aff0e650f049503a296cf2' - ], - [ - '4e8ceafb9b3e9a136dc7ff67e840295b499dfb3b2133e4ba113f2e4c0e121e5', - 'cf2174118c8b6d7a4b48f6d534ce5c79422c086a63460502b827ce62a326683c' - ], - [ - 'd24a44e047e19b6f5afb81c7ca2f69080a5076689a010919f42725c2b789a33b', - '6fb8d5591b466f8fc63db50f1c0f1c69013f996887b8244d2cdec417afea8fa3' - ], - [ - 'ea01606a7a6c9cdd249fdfcfacb99584001edd28abbab77b5104e98e8e3b35d4', - '322af4908c7312b0cfbfe369f7a7b3cdb7d4494bc2823700cfd652188a3ea98d' - ], - [ - 'af8addbf2b661c8a6c6328655eb96651252007d8c5ea31be4ad196de8ce2131f', - '6749e67c029b85f52a034eafd096836b2520818680e26ac8f3dfbcdb71749700' - ], - [ - 'e3ae1974566ca06cc516d47e0fb165a674a3dabcfca15e722f0e3450f45889', - '2aeabe7e4531510116217f07bf4d07300de97e4874f81f533420a72eeb0bd6a4' - ], - [ - '591ee355313d99721cf6993ffed1e3e301993ff3ed258802075ea8ced397e246', - 'b0ea558a113c30bea60fc4775460c7901ff0b053d25ca2bdeee98f1a4be5d196' - ], - [ - '11396d55fda54c49f19aa97318d8da61fa8584e47b084945077cf03255b52984', - '998c74a8cd45ac01289d5833a7beb4744ff536b01b257be4c5767bea93ea57a4' - ], - [ - '3c5d2a1ba39c5a1790000738c9e0c40b8dcdfd5468754b6405540157e017aa7a', - 'b2284279995a34e2f9d4de7396fc18b80f9b8b9fdd270f6661f79ca4c81bd257' - ], - [ - 'cc8704b8a60a0defa3a99a7299f2e9c3fbc395afb04ac078425ef8a1793cc030', - 'bdd46039feed17881d1e0862db347f8cf395b74fc4bcdc4e940b74e3ac1f1b13' - ], - [ - 'c533e4f7ea8555aacd9777ac5cad29b97dd4defccc53ee7ea204119b2889b197', - '6f0a256bc5efdf429a2fb6242f1a43a2d9b925bb4a4b3a26bb8e0f45eb596096' - ], - [ - 'c14f8f2ccb27d6f109f6d08d03cc96a69ba8c34eec07bbcf566d48e33da6593', - 'c359d6923bb398f7fd4473e16fe1c28475b740dd098075e6c0e8649113dc3a38' - ], - [ - 'a6cbc3046bc6a450bac24789fa17115a4c9739ed75f8f21ce441f72e0b90e6ef', - '21ae7f4680e889bb130619e2c0f95a360ceb573c70603139862afd617fa9b9f' - ], - [ - '347d6d9a02c48927ebfb86c1359b1caf130a3c0267d11ce6344b39f99d43cc38', - '60ea7f61a353524d1c987f6ecec92f086d565ab687870cb12689ff1e31c74448' - ], - [ - 'da6545d2181db8d983f7dcb375ef5866d47c67b1bf31c8cf855ef7437b72656a', - '49b96715ab6878a79e78f07ce5680c5d6673051b4935bd897fea824b77dc208a' - ], - [ - 'c40747cc9d012cb1a13b8148309c6de7ec25d6945d657146b9d5994b8feb1111', - '5ca560753be2a12fc6de6caf2cb489565db936156b9514e1bb5e83037e0fa2d4' - ], - [ - '4e42c8ec82c99798ccf3a610be870e78338c7f713348bd34c8203ef4037f3502', - '7571d74ee5e0fb92a7a8b33a07783341a5492144cc54bcc40a94473693606437' - ], - [ - '3775ab7089bc6af823aba2e1af70b236d251cadb0c86743287522a1b3b0dedea', - 'be52d107bcfa09d8bcb9736a828cfa7fac8db17bf7a76a2c42ad961409018cf7' - ], - [ - 'cee31cbf7e34ec379d94fb814d3d775ad954595d1314ba8846959e3e82f74e26', - '8fd64a14c06b589c26b947ae2bcf6bfa0149ef0be14ed4d80f448a01c43b1c6d' - ], - [ - 'b4f9eaea09b6917619f6ea6a4eb5464efddb58fd45b1ebefcdc1a01d08b47986', - '39e5c9925b5a54b07433a4f18c61726f8bb131c012ca542eb24a8ac07200682a' - ], - [ - 'd4263dfc3d2df923a0179a48966d30ce84e2515afc3dccc1b77907792ebcc60e', - '62dfaf07a0f78feb30e30d6295853ce189e127760ad6cf7fae164e122a208d54' - ], - [ - '48457524820fa65a4f8d35eb6930857c0032acc0a4a2de422233eeda897612c4', - '25a748ab367979d98733c38a1fa1c2e7dc6cc07db2d60a9ae7a76aaa49bd0f77' - ], - [ - 'dfeeef1881101f2cb11644f3a2afdfc2045e19919152923f367a1767c11cceda', - 'ecfb7056cf1de042f9420bab396793c0c390bde74b4bbdff16a83ae09a9a7517' - ], - [ - '6d7ef6b17543f8373c573f44e1f389835d89bcbc6062ced36c82df83b8fae859', - 'cd450ec335438986dfefa10c57fea9bcc521a0959b2d80bbf74b190dca712d10' - ], - [ - 'e75605d59102a5a2684500d3b991f2e3f3c88b93225547035af25af66e04541f', - 'f5c54754a8f71ee540b9b48728473e314f729ac5308b06938360990e2bfad125' - ], - [ - 'eb98660f4c4dfaa06a2be453d5020bc99a0c2e60abe388457dd43fefb1ed620c', - '6cb9a8876d9cb8520609af3add26cd20a0a7cd8a9411131ce85f44100099223e' - ], - [ - '13e87b027d8514d35939f2e6892b19922154596941888336dc3563e3b8dba942', - 'fef5a3c68059a6dec5d624114bf1e91aac2b9da568d6abeb2570d55646b8adf1' - ], - [ - 'ee163026e9fd6fe017c38f06a5be6fc125424b371ce2708e7bf4491691e5764a', - '1acb250f255dd61c43d94ccc670d0f58f49ae3fa15b96623e5430da0ad6c62b2' - ], - [ - 'b268f5ef9ad51e4d78de3a750c2dc89b1e626d43505867999932e5db33af3d80', - '5f310d4b3c99b9ebb19f77d41c1dee018cf0d34fd4191614003e945a1216e423' - ], - [ - 'ff07f3118a9df035e9fad85eb6c7bfe42b02f01ca99ceea3bf7ffdba93c4750d', - '438136d603e858a3a5c440c38eccbaddc1d2942114e2eddd4740d098ced1f0d8' - ], - [ - '8d8b9855c7c052a34146fd20ffb658bea4b9f69e0d825ebec16e8c3ce2b526a1', - 'cdb559eedc2d79f926baf44fb84ea4d44bcf50fee51d7ceb30e2e7f463036758' - ], - [ - '52db0b5384dfbf05bfa9d472d7ae26dfe4b851ceca91b1eba54263180da32b63', - 'c3b997d050ee5d423ebaf66a6db9f57b3180c902875679de924b69d84a7b375' - ], - [ - 'e62f9490d3d51da6395efd24e80919cc7d0f29c3f3fa48c6fff543becbd43352', - '6d89ad7ba4876b0b22c2ca280c682862f342c8591f1daf5170e07bfd9ccafa7d' - ], - [ - '7f30ea2476b399b4957509c88f77d0191afa2ff5cb7b14fd6d8e7d65aaab1193', - 'ca5ef7d4b231c94c3b15389a5f6311e9daff7bb67b103e9880ef4bff637acaec' - ], - [ - '5098ff1e1d9f14fb46a210fada6c903fef0fb7b4a1dd1d9ac60a0361800b7a00', - '9731141d81fc8f8084d37c6e7542006b3ee1b40d60dfe5362a5b132fd17ddc0' - ], - [ - '32b78c7de9ee512a72895be6b9cbefa6e2f3c4ccce445c96b9f2c81e2778ad58', - 'ee1849f513df71e32efc3896ee28260c73bb80547ae2275ba497237794c8753c' - ], - [ - 'e2cb74fddc8e9fbcd076eef2a7c72b0ce37d50f08269dfc074b581550547a4f7', - 'd3aa2ed71c9dd2247a62df062736eb0baddea9e36122d2be8641abcb005cc4a4' - ], - [ - '8438447566d4d7bedadc299496ab357426009a35f235cb141be0d99cd10ae3a8', - 'c4e1020916980a4da5d01ac5e6ad330734ef0d7906631c4f2390426b2edd791f' - ], - [ - '4162d488b89402039b584c6fc6c308870587d9c46f660b878ab65c82c711d67e', - '67163e903236289f776f22c25fb8a3afc1732f2b84b4e95dbda47ae5a0852649' - ], - [ - '3fad3fa84caf0f34f0f89bfd2dcf54fc175d767aec3e50684f3ba4a4bf5f683d', - 'cd1bc7cb6cc407bb2f0ca647c718a730cf71872e7d0d2a53fa20efcdfe61826' - ], - [ - '674f2600a3007a00568c1a7ce05d0816c1fb84bf1370798f1c69532faeb1a86b', - '299d21f9413f33b3edf43b257004580b70db57da0b182259e09eecc69e0d38a5' - ], - [ - 'd32f4da54ade74abb81b815ad1fb3b263d82d6c692714bcff87d29bd5ee9f08f', - 'f9429e738b8e53b968e99016c059707782e14f4535359d582fc416910b3eea87' - ], - [ - '30e4e670435385556e593657135845d36fbb6931f72b08cb1ed954f1e3ce3ff6', - '462f9bce619898638499350113bbc9b10a878d35da70740dc695a559eb88db7b' - ], - [ - 'be2062003c51cc3004682904330e4dee7f3dcd10b01e580bf1971b04d4cad297', - '62188bc49d61e5428573d48a74e1c655b1c61090905682a0d5558ed72dccb9bc' - ], - [ - '93144423ace3451ed29e0fb9ac2af211cb6e84a601df5993c419859fff5df04a', - '7c10dfb164c3425f5c71a3f9d7992038f1065224f72bb9d1d902a6d13037b47c' - ], - [ - 'b015f8044f5fcbdcf21ca26d6c34fb8197829205c7b7d2a7cb66418c157b112c', - 'ab8c1e086d04e813744a655b2df8d5f83b3cdc6faa3088c1d3aea1454e3a1d5f' - ], - [ - 'd5e9e1da649d97d89e4868117a465a3a4f8a18de57a140d36b3f2af341a21b52', - '4cb04437f391ed73111a13cc1d4dd0db1693465c2240480d8955e8592f27447a' - ], - [ - 'd3ae41047dd7ca065dbf8ed77b992439983005cd72e16d6f996a5316d36966bb', - 'bd1aeb21ad22ebb22a10f0303417c6d964f8cdd7df0aca614b10dc14d125ac46' - ], - [ - '463e2763d885f958fc66cdd22800f0a487197d0a82e377b49f80af87c897b065', - 'bfefacdb0e5d0fd7df3a311a94de062b26b80c61fbc97508b79992671ef7ca7f' - ], - [ - '7985fdfd127c0567c6f53ec1bb63ec3158e597c40bfe747c83cddfc910641917', - '603c12daf3d9862ef2b25fe1de289aed24ed291e0ec6708703a5bd567f32ed03' - ], - [ - '74a1ad6b5f76e39db2dd249410eac7f99e74c59cb83d2d0ed5ff1543da7703e9', - 'cc6157ef18c9c63cd6193d83631bbea0093e0968942e8c33d5737fd790e0db08' - ], - [ - '30682a50703375f602d416664ba19b7fc9bab42c72747463a71d0896b22f6da3', - '553e04f6b018b4fa6c8f39e7f311d3176290d0e0f19ca73f17714d9977a22ff8' - ], - [ - '9e2158f0d7c0d5f26c3791efefa79597654e7a2b2464f52b1ee6c1347769ef57', - '712fcdd1b9053f09003a3481fa7762e9ffd7c8ef35a38509e2fbf2629008373' - ], - [ - '176e26989a43c9cfeba4029c202538c28172e566e3c4fce7322857f3be327d66', - 'ed8cc9d04b29eb877d270b4878dc43c19aefd31f4eee09ee7b47834c1fa4b1c3' - ], - [ - '75d46efea3771e6e68abb89a13ad747ecf1892393dfc4f1b7004788c50374da8', - '9852390a99507679fd0b86fd2b39a868d7efc22151346e1a3ca4726586a6bed8' - ], - [ - '809a20c67d64900ffb698c4c825f6d5f2310fb0451c869345b7319f645605721', - '9e994980d9917e22b76b061927fa04143d096ccc54963e6a5ebfa5f3f8e286c1' - ], - [ - '1b38903a43f7f114ed4500b4eac7083fdefece1cf29c63528d563446f972c180', - '4036edc931a60ae889353f77fd53de4a2708b26b6f5da72ad3394119daf408f9' - ] - ] + /** + * Appends the elements of `values` to `array`. + * + * @private + * @param {Array} array The array to modify. + * @param {Array} values The values to append. + * @returns {Array} Returns `array`. + */ + function arrayPush(array, values) { + var index = -1, + length = values.length, + offset = array.length; + + while (++index < length) { + array[offset + index] = values[index]; } + return array; } - ] -}); -},{"../elliptic":209,"assert":41,"bn.js":207,"hash.js":223}],216:[function(require,module,exports){ -var assert = require('assert'); -var bn = require('bn.js'); -var elliptic = require('../../elliptic'); -var utils = elliptic.utils; + /** + * A specialized version of `_.reduce` for arrays without support for callback + * shorthands and `this` binding. + * + * @private + * @param {Array} array The array to iterate over. + * @param {Function} iteratee The function invoked per iteration. + * @param {*} [accumulator] The initial value. + * @param {boolean} [initFromArray] Specify using the first element of `array` + * as the initial value. + * @returns {*} Returns the accumulated value. + */ + function arrayReduce(array, iteratee, accumulator, initFromArray) { + var index = -1, + length = array.length; -var KeyPair = require('./key'); -var Signature = require('./signature'); + if (initFromArray && length) { + accumulator = array[++index]; + } + while (++index < length) { + accumulator = iteratee(accumulator, array[index], index, array); + } + return accumulator; + } -function EC(options) { - if (!(this instanceof EC)) - return new EC(options); + /** + * A specialized version of `_.reduceRight` for arrays without support for + * callback shorthands and `this` binding. + * + * @private + * @param {Array} array The array to iterate over. + * @param {Function} iteratee The function invoked per iteration. + * @param {*} [accumulator] The initial value. + * @param {boolean} [initFromArray] Specify using the last element of `array` + * as the initial value. + * @returns {*} Returns the accumulated value. + */ + function arrayReduceRight(array, iteratee, accumulator, initFromArray) { + var length = array.length; + if (initFromArray && length) { + accumulator = array[--length]; + } + while (length--) { + accumulator = iteratee(accumulator, array[length], length, array); + } + return accumulator; + } - // Shortcut `elliptic.ec(curve-name)` - if (typeof options === 'string') { - assert(elliptic.curves.hasOwnProperty(options), 'Unknown curve ' + options); + /** + * A specialized version of `_.some` for arrays without support for callback + * shorthands and `this` binding. + * + * @private + * @param {Array} array The array to iterate over. + * @param {Function} predicate The function invoked per iteration. + * @returns {boolean} Returns `true` if any element passes the predicate check, + * else `false`. + */ + function arraySome(array, predicate) { + var index = -1, + length = array.length; - options = elliptic.curves[options]; - } + while (++index < length) { + if (predicate(array[index], index, array)) { + return true; + } + } + return false; + } - // Shortcut for `elliptic.ec(elliptic.curves.curveName)` - if (options instanceof elliptic.curves.PresetCurve) - options = { curve: options }; + /** + * A specialized version of `_.sum` for arrays without support for callback + * shorthands and `this` binding.. + * + * @private + * @param {Array} array The array to iterate over. + * @param {Function} iteratee The function invoked per iteration. + * @returns {number} Returns the sum. + */ + function arraySum(array, iteratee) { + var length = array.length, + result = 0; - this.curve = options.curve.curve; - this.n = this.curve.n; - this.nh = this.n.shrn(1); - this.g = this.curve.g; + while (length--) { + result += +iteratee(array[length]) || 0; + } + return result; + } - // Point on curve - this.g = options.curve.g; - this.g.precompute(options.curve.n.bitLength() + 1); + /** + * Used by `_.defaults` to customize its `_.assign` use. + * + * @private + * @param {*} objectValue The destination object property value. + * @param {*} sourceValue The source object property value. + * @returns {*} Returns the value to assign to the destination object. + */ + function assignDefaults(objectValue, sourceValue) { + return objectValue === undefined ? sourceValue : objectValue; + } - // Hash for function for DRBG - this.hash = options.hash || options.curve.hash; -} -module.exports = EC; + /** + * Used by `_.template` to customize its `_.assign` use. + * + * **Note:** This function is like `assignDefaults` except that it ignores + * inherited property values when checking if a property is `undefined`. + * + * @private + * @param {*} objectValue The destination object property value. + * @param {*} sourceValue The source object property value. + * @param {string} key The key associated with the object and source values. + * @param {Object} object The destination object. + * @returns {*} Returns the value to assign to the destination object. + */ + function assignOwnDefaults(objectValue, sourceValue, key, object) { + return (objectValue === undefined || !hasOwnProperty.call(object, key)) + ? sourceValue + : objectValue; + } -EC.prototype.keyPair = function keyPair(priv, pub) { - return new KeyPair(this, priv, pub); -}; + /** + * A specialized version of `_.assign` for customizing assigned values without + * support for argument juggling, multiple sources, and `this` binding `customizer` + * functions. + * + * @private + * @param {Object} object The destination object. + * @param {Object} source The source object. + * @param {Function} customizer The function to customize assigned values. + * @returns {Object} Returns `object`. + */ + function assignWith(object, source, customizer) { + var index = -1, + props = keys(source), + length = props.length; -EC.prototype.genKeyPair = function genKeyPair(options) { - if (!options) - options = {}; + while (++index < length) { + var key = props[index], + value = object[key], + result = customizer(value, source[key], key, object, source); - // Instantiate Hmac_DRBG - var drbg = new elliptic.hmacDRBG({ - hash: this.hash, - pers: options.pers, - entropy: options.entropy || elliptic.rand(this.hash.hmacStrength), - nonce: this.n.toArray() - }); + if ((result === result ? (result !== value) : (value === value)) || + (value === undefined && !(key in object))) { + object[key] = result; + } + } + return object; + } - var bytes = this.n.byteLength(); - var ns2 = this.n.sub(new bn(2)); - do { - var priv = new bn(drbg.generate(bytes)); - if (priv.cmp(ns2) > 0) - continue; + /** + * The base implementation of `_.assign` without support for argument juggling, + * multiple sources, and `customizer` functions. + * + * @private + * @param {Object} object The destination object. + * @param {Object} source The source object. + * @returns {Object} Returns `object`. + */ + function baseAssign(object, source) { + return source == null + ? object + : baseCopy(source, keys(source), object); + } - priv.iaddn(1); - return this.keyPair(priv); - } while (true); -}; + /** + * The base implementation of `_.at` without support for string collections + * and individual key arguments. + * + * @private + * @param {Array|Object} collection The collection to iterate over. + * @param {number[]|string[]} props The property names or indexes of elements to pick. + * @returns {Array} Returns the new array of picked elements. + */ + function baseAt(collection, props) { + var index = -1, + isNil = collection == null, + isArr = !isNil && isArrayLike(collection), + length = isArr ? collection.length : 0, + propsLength = props.length, + result = Array(propsLength); -EC.prototype._truncateToN = function truncateToN(msg, truncOnly) { - var delta = msg.byteLength() * 8 - this.n.bitLength(); - if (delta > 0) - msg = msg.shrn(delta); - if (!truncOnly && msg.cmp(this.n) >= 0) - return msg.sub(this.n); - else - return msg; -}; + while(++index < propsLength) { + var key = props[index]; + if (isArr) { + result[index] = isIndex(key, length) ? collection[key] : undefined; + } else { + result[index] = isNil ? undefined : collection[key]; + } + } + return result; + } -EC.prototype.sign = function sign(msg, key, options) { - key = this.keyPair(key, 'hex'); - msg = this._truncateToN(new bn(msg, 16)); - if (!options) - options = {}; + /** + * Copies properties of `source` to `object`. + * + * @private + * @param {Object} source The object to copy properties from. + * @param {Array} props The property names to copy. + * @param {Object} [object={}] The object to copy properties to. + * @returns {Object} Returns `object`. + */ + function baseCopy(source, props, object) { + object || (object = {}); - // Zero-extend key to provide enough entropy - var bytes = this.n.byteLength(); - var bkey = key.getPrivate().toArray(); - for (var i = bkey.length; i < 21; i++) - bkey.unshift(0); + var index = -1, + length = props.length; - // Zero-extend nonce to have the same byte size as N - var nonce = msg.toArray(); - for (var i = nonce.length; i < bytes; i++) - nonce.unshift(0); + while (++index < length) { + var key = props[index]; + object[key] = source[key]; + } + return object; + } - // Instantiate Hmac_DRBG - var drbg = new elliptic.hmacDRBG({ - hash: this.hash, - entropy: bkey, - nonce: nonce - }); + /** + * The base implementation of `_.callback` which supports specifying the + * number of arguments to provide to `func`. + * + * @private + * @param {*} [func=_.identity] The value to convert to a callback. + * @param {*} [thisArg] The `this` binding of `func`. + * @param {number} [argCount] The number of arguments to provide to `func`. + * @returns {Function} Returns the callback. + */ + function baseCallback(func, thisArg, argCount) { + var type = typeof func; + if (type == 'function') { + return thisArg === undefined + ? func + : bindCallback(func, thisArg, argCount); + } + if (func == null) { + return identity; + } + if (type == 'object') { + return baseMatches(func); + } + return thisArg === undefined + ? property(func) + : baseMatchesProperty(func, thisArg); + } - // Number of bytes to generate - var ns1 = this.n.sub(new bn(1)); - do { - var k = new bn(drbg.generate(this.n.byteLength())); - k = this._truncateToN(k, true); - if (k.cmpn(1) <= 0 || k.cmp(ns1) >= 0) - continue; + /** + * The base implementation of `_.clone` without support for argument juggling + * and `this` binding `customizer` functions. + * + * @private + * @param {*} value The value to clone. + * @param {boolean} [isDeep] Specify a deep clone. + * @param {Function} [customizer] The function to customize cloning values. + * @param {string} [key] The key of `value`. + * @param {Object} [object] The object `value` belongs to. + * @param {Array} [stackA=[]] Tracks traversed source objects. + * @param {Array} [stackB=[]] Associates clones with source counterparts. + * @returns {*} Returns the cloned value. + */ + function baseClone(value, isDeep, customizer, key, object, stackA, stackB) { + var result; + if (customizer) { + result = object ? customizer(value, key, object) : customizer(value); + } + if (result !== undefined) { + return result; + } + if (!isObject(value)) { + return value; + } + var isArr = isArray(value); + if (isArr) { + result = initCloneArray(value); + if (!isDeep) { + return arrayCopy(value, result); + } + } else { + var tag = objToString.call(value), + isFunc = tag == funcTag; - var kp = this.g.mul(k); - if (kp.isInfinity()) - continue; + if (tag == objectTag || tag == argsTag || (isFunc && !object)) { + result = initCloneObject(isFunc ? {} : value); + if (!isDeep) { + return baseAssign(result, value); + } + } else { + return cloneableTags[tag] + ? initCloneByTag(value, tag, isDeep) + : (object ? value : {}); + } + } + // Check for circular references and return its corresponding clone. + stackA || (stackA = []); + stackB || (stackB = []); - var r = kp.getX().mod(this.n); - if (r.cmpn(0) === 0) - continue; + var length = stackA.length; + while (length--) { + if (stackA[length] == value) { + return stackB[length]; + } + } + // Add the source value to the stack of traversed objects and associate it with its clone. + stackA.push(value); + stackB.push(result); - var s = k.invm(this.n).mul(r.mul(key.getPrivate()).iadd(msg)).mod(this.n); - if (s.cmpn(0) === 0) - continue; + // Recursively populate clone (susceptible to call stack limits). + (isArr ? arrayEach : baseForOwn)(value, function(subValue, key) { + result[key] = baseClone(subValue, isDeep, customizer, key, value, stackA, stackB); + }); + return result; + } - // Use complement of `s`, if it is > `n / 2` - if (options.canonical && s.cmp(this.nh) > 0) - s = this.n.sub(s); + /** + * The base implementation of `_.create` without support for assigning + * properties to the created object. + * + * @private + * @param {Object} prototype The object to inherit from. + * @returns {Object} Returns the new object. + */ + var baseCreate = (function() { + function object() {} + return function(prototype) { + if (isObject(prototype)) { + object.prototype = prototype; + var result = new object; + object.prototype = undefined; + } + return result || {}; + }; + }()); - return new Signature(r, s); - } while (true); -}; + /** + * The base implementation of `_.delay` and `_.defer` which accepts an index + * of where to slice the arguments to provide to `func`. + * + * @private + * @param {Function} func The function to delay. + * @param {number} wait The number of milliseconds to delay invocation. + * @param {Object} args The arguments provide to `func`. + * @returns {number} Returns the timer id. + */ + function baseDelay(func, wait, args) { + if (typeof func != 'function') { + throw new TypeError(FUNC_ERROR_TEXT); + } + return setTimeout(function() { func.apply(undefined, args); }, wait); + } -EC.prototype.verify = function verify(msg, signature, key) { - msg = this._truncateToN(new bn(msg, 16)); - key = this.keyPair(key, 'hex'); - signature = new Signature(signature, 'hex'); + /** + * The base implementation of `_.difference` which accepts a single array + * of values to exclude. + * + * @private + * @param {Array} array The array to inspect. + * @param {Array} values The values to exclude. + * @returns {Array} Returns the new array of filtered values. + */ + function baseDifference(array, values) { + var length = array ? array.length : 0, + result = []; - // Perform primitive values validation - var r = signature.r; - var s = signature.s; - if (r.cmpn(1) < 0 || r.cmp(this.n) >= 0) - return false; - if (s.cmpn(1) < 0 || s.cmp(this.n) >= 0) - return false; + if (!length) { + return result; + } + var index = -1, + indexOf = getIndexOf(), + isCommon = indexOf == baseIndexOf, + cache = (isCommon && values.length >= LARGE_ARRAY_SIZE) ? createCache(values) : null, + valuesLength = values.length; - // Validate signature - var sinv = s.invm(this.n); - var u1 = sinv.mul(msg).mod(this.n); - var u2 = sinv.mul(r).mod(this.n); + if (cache) { + indexOf = cacheIndexOf; + isCommon = false; + values = cache; + } + outer: + while (++index < length) { + var value = array[index]; - var p = this.g.mulAdd(u1, key.getPublic(), u2); - if (p.isInfinity()) - return false; + if (isCommon && value === value) { + var valuesIndex = valuesLength; + while (valuesIndex--) { + if (values[valuesIndex] === value) { + continue outer; + } + } + result.push(value); + } + else if (indexOf(values, value, 0) < 0) { + result.push(value); + } + } + return result; + } - return p.getX().mod(this.n).cmp(r) === 0; -}; + /** + * The base implementation of `_.forEach` without support for callback + * shorthands and `this` binding. + * + * @private + * @param {Array|Object|string} collection The collection to iterate over. + * @param {Function} iteratee The function invoked per iteration. + * @returns {Array|Object|string} Returns `collection`. + */ + var baseEach = createBaseEach(baseForOwn); -},{"../../elliptic":209,"./key":217,"./signature":218,"assert":41,"bn.js":207}],217:[function(require,module,exports){ -var assert = require('assert'); -var bn = require('bn.js'); + /** + * The base implementation of `_.forEachRight` without support for callback + * shorthands and `this` binding. + * + * @private + * @param {Array|Object|string} collection The collection to iterate over. + * @param {Function} iteratee The function invoked per iteration. + * @returns {Array|Object|string} Returns `collection`. + */ + var baseEachRight = createBaseEach(baseForOwnRight, true); -var elliptic = require('../../elliptic'); -var utils = elliptic.utils; + /** + * The base implementation of `_.every` without support for callback + * shorthands and `this` binding. + * + * @private + * @param {Array|Object|string} collection The collection to iterate over. + * @param {Function} predicate The function invoked per iteration. + * @returns {boolean} Returns `true` if all elements pass the predicate check, + * else `false` + */ + function baseEvery(collection, predicate) { + var result = true; + baseEach(collection, function(value, index, collection) { + result = !!predicate(value, index, collection); + return result; + }); + return result; + } -function KeyPair(ec, priv, pub) { - if (priv instanceof KeyPair) - return priv; - if (pub instanceof KeyPair) - return pub; + /** + * Gets the extremum value of `collection` invoking `iteratee` for each value + * in `collection` to generate the criterion by which the value is ranked. + * The `iteratee` is invoked with three arguments: (value, index|key, collection). + * + * @private + * @param {Array|Object|string} collection The collection to iterate over. + * @param {Function} iteratee The function invoked per iteration. + * @param {Function} comparator The function used to compare values. + * @param {*} exValue The initial extremum value. + * @returns {*} Returns the extremum value. + */ + function baseExtremum(collection, iteratee, comparator, exValue) { + var computed = exValue, + result = computed; - if (!priv) { - priv = pub; - pub = null; - } - if (priv !== null && typeof priv === 'object') { - if (priv.x) { - // KeyPair(public) - pub = priv; - priv = null; - } else if (priv.priv || priv.pub) { - // KeyPair({ priv: ..., pub: ... }) - pub = priv.pub; - priv = priv.priv; + baseEach(collection, function(value, index, collection) { + var current = +iteratee(value, index, collection); + if (comparator(current, computed) || (current === exValue && current === result)) { + computed = current; + result = value; + } + }); + return result; } - } - this.ec = ec; - this.priv = null; - this.pub = null; + /** + * The base implementation of `_.fill` without an iteratee call guard. + * + * @private + * @param {Array} array The array to fill. + * @param {*} value The value to fill `array` with. + * @param {number} [start=0] The start position. + * @param {number} [end=array.length] The end position. + * @returns {Array} Returns `array`. + */ + function baseFill(array, value, start, end) { + var length = array.length; - // KeyPair(public, 'hex') - if (this._importPublicHex(priv, pub)) - return; + start = start == null ? 0 : (+start || 0); + if (start < 0) { + start = -start > length ? 0 : (length + start); + } + end = (end === undefined || end > length) ? length : (+end || 0); + if (end < 0) { + end += length; + } + length = start > end ? 0 : (end >>> 0); + start >>>= 0; - if (pub === 'hex') - pub = null; + while (start < length) { + array[start++] = value; + } + return array; + } - // KeyPair(priv, pub) - if (priv) - this._importPrivate(priv); - if (pub) - this._importPublic(pub); -} -module.exports = KeyPair; + /** + * The base implementation of `_.filter` without support for callback + * shorthands and `this` binding. + * + * @private + * @param {Array|Object|string} collection The collection to iterate over. + * @param {Function} predicate The function invoked per iteration. + * @returns {Array} Returns the new filtered array. + */ + function baseFilter(collection, predicate) { + var result = []; + baseEach(collection, function(value, index, collection) { + if (predicate(value, index, collection)) { + result.push(value); + } + }); + return result; + } -KeyPair.prototype.validate = function validate() { - var pub = this.getPublic(); + /** + * The base implementation of `_.find`, `_.findLast`, `_.findKey`, and `_.findLastKey`, + * without support for callback shorthands and `this` binding, which iterates + * over `collection` using the provided `eachFunc`. + * + * @private + * @param {Array|Object|string} collection The collection to search. + * @param {Function} predicate The function invoked per iteration. + * @param {Function} eachFunc The function to iterate over `collection`. + * @param {boolean} [retKey] Specify returning the key of the found element + * instead of the element itself. + * @returns {*} Returns the found element or its key, else `undefined`. + */ + function baseFind(collection, predicate, eachFunc, retKey) { + var result; + eachFunc(collection, function(value, key, collection) { + if (predicate(value, key, collection)) { + result = retKey ? key : value; + return false; + } + }); + return result; + } - if (pub.isInfinity()) - return { result: false, reason: 'Invalid public key' }; - if (!pub.validate()) - return { result: false, reason: 'Public key is not a point' }; - if (!pub.mul(this.ec.curve.n).isInfinity()) - return { result: false, reason: 'Public key * N != O' }; + /** + * The base implementation of `_.flatten` with added support for restricting + * flattening and specifying the start index. + * + * @private + * @param {Array} array The array to flatten. + * @param {boolean} [isDeep] Specify a deep flatten. + * @param {boolean} [isStrict] Restrict flattening to arrays-like objects. + * @param {Array} [result=[]] The initial result value. + * @returns {Array} Returns the new flattened array. + */ + function baseFlatten(array, isDeep, isStrict, result) { + result || (result = []); - return { result: true, reason: null }; -}; + var index = -1, + length = array.length; -KeyPair.prototype.getPublic = function getPublic(compact, enc) { - if (!this.pub) - this.pub = this.ec.g.mul(this.priv); + while (++index < length) { + var value = array[index]; + if (isObjectLike(value) && isArrayLike(value) && + (isStrict || isArray(value) || isArguments(value))) { + if (isDeep) { + // Recursively flatten arrays (susceptible to call stack limits). + baseFlatten(value, isDeep, isStrict, result); + } else { + arrayPush(result, value); + } + } else if (!isStrict) { + result[result.length] = value; + } + } + return result; + } - // compact is optional argument - if (typeof compact === 'string') { - enc = compact; - compact = null; - } + /** + * The base implementation of `baseForIn` and `baseForOwn` which iterates + * over `object` properties returned by `keysFunc` invoking `iteratee` for + * each property. Iteratee functions may exit iteration early by explicitly + * returning `false`. + * + * @private + * @param {Object} object The object to iterate over. + * @param {Function} iteratee The function invoked per iteration. + * @param {Function} keysFunc The function to get the keys of `object`. + * @returns {Object} Returns `object`. + */ + var baseFor = createBaseFor(); - if (!enc) - return this.pub; + /** + * This function is like `baseFor` except that it iterates over properties + * in the opposite order. + * + * @private + * @param {Object} object The object to iterate over. + * @param {Function} iteratee The function invoked per iteration. + * @param {Function} keysFunc The function to get the keys of `object`. + * @returns {Object} Returns `object`. + */ + var baseForRight = createBaseFor(true); - var len = this.ec.curve.p.byteLength(); - var x = this.pub.getX().toArray(); + /** + * The base implementation of `_.forIn` without support for callback + * shorthands and `this` binding. + * + * @private + * @param {Object} object The object to iterate over. + * @param {Function} iteratee The function invoked per iteration. + * @returns {Object} Returns `object`. + */ + function baseForIn(object, iteratee) { + return baseFor(object, iteratee, keysIn); + } - for (var i = x.length; i < len; i++) - x.unshift(0); + /** + * The base implementation of `_.forOwn` without support for callback + * shorthands and `this` binding. + * + * @private + * @param {Object} object The object to iterate over. + * @param {Function} iteratee The function invoked per iteration. + * @returns {Object} Returns `object`. + */ + function baseForOwn(object, iteratee) { + return baseFor(object, iteratee, keys); + } - if (compact) { - var res = [ this.pub.getY().isEven() ? 0x02 : 0x03 ].concat(x); - } else { - var y = this.pub.getY().toArray(); - for (var i = y.length; i < len; i++) - y.unshift(0); - var res = [ 0x04 ].concat(x, y); - } - return utils.encode(res, enc); -}; + /** + * The base implementation of `_.forOwnRight` without support for callback + * shorthands and `this` binding. + * + * @private + * @param {Object} object The object to iterate over. + * @param {Function} iteratee The function invoked per iteration. + * @returns {Object} Returns `object`. + */ + function baseForOwnRight(object, iteratee) { + return baseForRight(object, iteratee, keys); + } -KeyPair.prototype.getPrivate = function getPrivate(enc) { - if (enc === 'hex') - return this.priv.toString(16, 2); - else - return this.priv; -}; + /** + * The base implementation of `_.functions` which creates an array of + * `object` function property names filtered from those provided. + * + * @private + * @param {Object} object The object to inspect. + * @param {Array} props The property names to filter. + * @returns {Array} Returns the new array of filtered property names. + */ + function baseFunctions(object, props) { + var index = -1, + length = props.length, + resIndex = -1, + result = []; -KeyPair.prototype._importPrivate = function _importPrivate(key) { - this.priv = new bn(key, 16); + while (++index < length) { + var key = props[index]; + if (isFunction(object[key])) { + result[++resIndex] = key; + } + } + return result; + } - // Ensure that the priv won't be bigger than n, otherwise we may fail - // in fixed multiplication method - this.priv = this.priv.mod(this.ec.curve.n); -}; + /** + * The base implementation of `get` without support for string paths + * and default values. + * + * @private + * @param {Object} object The object to query. + * @param {Array} path The path of the property to get. + * @param {string} [pathKey] The key representation of path. + * @returns {*} Returns the resolved value. + */ + function baseGet(object, path, pathKey) { + if (object == null) { + return; + } + if (pathKey !== undefined && pathKey in toObject(object)) { + path = [pathKey]; + } + var index = 0, + length = path.length; -KeyPair.prototype._importPublic = function _importPublic(key) { - this.pub = this.ec.curve.point(key.x, key.y); -}; + while (object != null && index < length) { + object = object[path[index++]]; + } + return (index && index == length) ? object : undefined; + } -KeyPair.prototype._importPublicHex = function _importPublic(key, enc) { - key = utils.toArray(key, enc); - var len = this.ec.curve.p.byteLength(); - if (key[0] === 0x04 && key.length - 1 === 2 * len) { - this.pub = this.ec.curve.point( - key.slice(1, 1 + len), - key.slice(1 + len, 1 + 2 * len)); - } else if ((key[0] === 0x02 || key[0] === 0x03) && key.length - 1 === len) { - this.pub = this.ec.curve.pointFromX(key[0] === 0x03, - key.slice(1, 1 +len)); - } else { - return false; - } + /** + * The base implementation of `_.isEqual` without support for `this` binding + * `customizer` functions. + * + * @private + * @param {*} value The value to compare. + * @param {*} other The other value to compare. + * @param {Function} [customizer] The function to customize comparing values. + * @param {boolean} [isLoose] Specify performing partial comparisons. + * @param {Array} [stackA] Tracks traversed `value` objects. + * @param {Array} [stackB] Tracks traversed `other` objects. + * @returns {boolean} Returns `true` if the values are equivalent, else `false`. + */ + function baseIsEqual(value, other, customizer, isLoose, stackA, stackB) { + if (value === other) { + return true; + } + if (value == null || other == null || (!isObject(value) && !isObjectLike(other))) { + return value !== value && other !== other; + } + return baseIsEqualDeep(value, other, baseIsEqual, customizer, isLoose, stackA, stackB); + } - return true; -}; + /** + * A specialized version of `baseIsEqual` for arrays and objects which performs + * deep comparisons and tracks traversed objects enabling objects with circular + * references to be compared. + * + * @private + * @param {Object} object The object to compare. + * @param {Object} other The other object to compare. + * @param {Function} equalFunc The function to determine equivalents of values. + * @param {Function} [customizer] The function to customize comparing objects. + * @param {boolean} [isLoose] Specify performing partial comparisons. + * @param {Array} [stackA=[]] Tracks traversed `value` objects. + * @param {Array} [stackB=[]] Tracks traversed `other` objects. + * @returns {boolean} Returns `true` if the objects are equivalent, else `false`. + */ + function baseIsEqualDeep(object, other, equalFunc, customizer, isLoose, stackA, stackB) { + var objIsArr = isArray(object), + othIsArr = isArray(other), + objTag = arrayTag, + othTag = arrayTag; + + if (!objIsArr) { + objTag = objToString.call(object); + if (objTag == argsTag) { + objTag = objectTag; + } else if (objTag != objectTag) { + objIsArr = isTypedArray(object); + } + } + if (!othIsArr) { + othTag = objToString.call(other); + if (othTag == argsTag) { + othTag = objectTag; + } else if (othTag != objectTag) { + othIsArr = isTypedArray(other); + } + } + var objIsObj = objTag == objectTag, + othIsObj = othTag == objectTag, + isSameTag = objTag == othTag; -// ECDH -KeyPair.prototype.derive = function derive(pub) { - return pub.mul(this.priv).getX(); -}; + if (isSameTag && !(objIsArr || objIsObj)) { + return equalByTag(object, other, objTag); + } + if (!isLoose) { + var objIsWrapped = objIsObj && hasOwnProperty.call(object, '__wrapped__'), + othIsWrapped = othIsObj && hasOwnProperty.call(other, '__wrapped__'); -// ECDSA -KeyPair.prototype.sign = function sign(msg) { - return this.ec.sign(msg, this); -}; + if (objIsWrapped || othIsWrapped) { + return equalFunc(objIsWrapped ? object.value() : object, othIsWrapped ? other.value() : other, customizer, isLoose, stackA, stackB); + } + } + if (!isSameTag) { + return false; + } + // Assume cyclic values are equal. + // For more information on detecting circular references see https://es5.github.io/#JO. + stackA || (stackA = []); + stackB || (stackB = []); -KeyPair.prototype.verify = function verify(msg, signature) { - return this.ec.verify(msg, signature, this); -}; + var length = stackA.length; + while (length--) { + if (stackA[length] == object) { + return stackB[length] == other; + } + } + // Add `object` and `other` to the stack of traversed objects. + stackA.push(object); + stackB.push(other); -KeyPair.prototype.inspect = function inspect() { - return ''; -}; + var result = (objIsArr ? equalArrays : equalObjects)(object, other, equalFunc, customizer, isLoose, stackA, stackB); -},{"../../elliptic":209,"assert":41,"bn.js":207}],218:[function(require,module,exports){ -var assert = require('assert'); -var bn = require('bn.js'); + stackA.pop(); + stackB.pop(); -var elliptic = require('../../elliptic'); -var utils = elliptic.utils; + return result; + } -function Signature(r, s) { - if (r instanceof Signature) - return r; + /** + * The base implementation of `_.isMatch` without support for callback + * shorthands and `this` binding. + * + * @private + * @param {Object} object The object to inspect. + * @param {Array} matchData The propery names, values, and compare flags to match. + * @param {Function} [customizer] The function to customize comparing objects. + * @returns {boolean} Returns `true` if `object` is a match, else `false`. + */ + function baseIsMatch(object, matchData, customizer) { + var index = matchData.length, + length = index, + noCustomizer = !customizer; - if (this._importDER(r, s)) - return; + if (object == null) { + return !length; + } + object = toObject(object); + while (index--) { + var data = matchData[index]; + if ((noCustomizer && data[2]) + ? data[1] !== object[data[0]] + : !(data[0] in object) + ) { + return false; + } + } + while (++index < length) { + data = matchData[index]; + var key = data[0], + objValue = object[key], + srcValue = data[1]; - assert(r && s, 'Signature without r or s'); - this.r = new bn(r, 16); - this.s = new bn(s, 16); -} -module.exports = Signature; + if (noCustomizer && data[2]) { + if (objValue === undefined && !(key in object)) { + return false; + } + } else { + var result = customizer ? customizer(objValue, srcValue, key) : undefined; + if (!(result === undefined ? baseIsEqual(srcValue, objValue, customizer, true) : result)) { + return false; + } + } + } + return true; + } -Signature.prototype._importDER = function _importDER(data, enc) { - data = utils.toArray(data, enc); - if (data.length < 6 || data[0] !== 0x30 || data[2] !== 0x02) - return false; - var total = data[1]; - if (1 + total > data.length) - return false; - var rlen = data[3]; - // Short length notation - if (rlen >= 0x80) - return false; - if (4 + rlen + 2 >= data.length) - return false; - if (data[4 + rlen] !== 0x02) - return false; - var slen = data[5 + rlen]; - // Short length notation - if (slen >= 0x80) - return false; - if (4 + rlen + 2 + slen > data.length) - return false; + /** + * The base implementation of `_.map` without support for callback shorthands + * and `this` binding. + * + * @private + * @param {Array|Object|string} collection The collection to iterate over. + * @param {Function} iteratee The function invoked per iteration. + * @returns {Array} Returns the new mapped array. + */ + function baseMap(collection, iteratee) { + var index = -1, + result = isArrayLike(collection) ? Array(collection.length) : []; - this.r = new bn(data.slice(4, 4 + rlen)); - this.s = new bn(data.slice(4 + rlen + 2, 4 + rlen + 2 + slen)); + baseEach(collection, function(value, key, collection) { + result[++index] = iteratee(value, key, collection); + }); + return result; + } - return true; -}; + /** + * The base implementation of `_.matches` which does not clone `source`. + * + * @private + * @param {Object} source The object of property values to match. + * @returns {Function} Returns the new function. + */ + function baseMatches(source) { + var matchData = getMatchData(source); + if (matchData.length == 1 && matchData[0][2]) { + var key = matchData[0][0], + value = matchData[0][1]; -Signature.prototype.toDER = function toDER(enc) { - var r = this.r.toArray(); - var s = this.s.toArray(); + return function(object) { + if (object == null) { + return false; + } + return object[key] === value && (value !== undefined || (key in toObject(object))); + }; + } + return function(object) { + return baseIsMatch(object, matchData); + }; + } - // Pad values - if (r[0] & 0x80) - r = [ 0 ].concat(r); - // Pad values - if (s[0] & 0x80) - s = [ 0 ].concat(s); + /** + * The base implementation of `_.matchesProperty` which does not clone `srcValue`. + * + * @private + * @param {string} path The path of the property to get. + * @param {*} srcValue The value to compare. + * @returns {Function} Returns the new function. + */ + function baseMatchesProperty(path, srcValue) { + var isArr = isArray(path), + isCommon = isKey(path) && isStrictComparable(srcValue), + pathKey = (path + ''); - var total = r.length + s.length + 4; - var res = [ 0x30, total, 0x02, r.length ]; - res = res.concat(r, [ 0x02, s.length ], s); - return utils.encode(res, enc); -}; + path = toPath(path); + return function(object) { + if (object == null) { + return false; + } + var key = pathKey; + object = toObject(object); + if ((isArr || !isCommon) && !(key in object)) { + object = path.length == 1 ? object : baseGet(object, baseSlice(path, 0, -1)); + if (object == null) { + return false; + } + key = last(path); + object = toObject(object); + } + return object[key] === srcValue + ? (srcValue !== undefined || (key in object)) + : baseIsEqual(srcValue, object[key], undefined, true); + }; + } + + /** + * The base implementation of `_.merge` without support for argument juggling, + * multiple sources, and `this` binding `customizer` functions. + * + * @private + * @param {Object} object The destination object. + * @param {Object} source The source object. + * @param {Function} [customizer] The function to customize merged values. + * @param {Array} [stackA=[]] Tracks traversed source objects. + * @param {Array} [stackB=[]] Associates values with source counterparts. + * @returns {Object} Returns `object`. + */ + function baseMerge(object, source, customizer, stackA, stackB) { + if (!isObject(object)) { + return object; + } + var isSrcArr = isArrayLike(source) && (isArray(source) || isTypedArray(source)), + props = isSrcArr ? undefined : keys(source); + + arrayEach(props || source, function(srcValue, key) { + if (props) { + key = srcValue; + srcValue = source[key]; + } + if (isObjectLike(srcValue)) { + stackA || (stackA = []); + stackB || (stackB = []); + baseMergeDeep(object, source, key, baseMerge, customizer, stackA, stackB); + } + else { + var value = object[key], + result = customizer ? customizer(value, srcValue, key, object, source) : undefined, + isCommon = result === undefined; -},{"../../elliptic":209,"assert":41,"bn.js":207}],219:[function(require,module,exports){ -var assert = require('assert'); + if (isCommon) { + result = srcValue; + } + if ((result !== undefined || (isSrcArr && !(key in object))) && + (isCommon || (result === result ? (result !== value) : (value === value)))) { + object[key] = result; + } + } + }); + return object; + } -var hash = require('hash.js'); -var elliptic = require('../elliptic'); -var utils = elliptic.utils; + /** + * A specialized version of `baseMerge` for arrays and objects which performs + * deep merges and tracks traversed objects enabling objects with circular + * references to be merged. + * + * @private + * @param {Object} object The destination object. + * @param {Object} source The source object. + * @param {string} key The key of the value to merge. + * @param {Function} mergeFunc The function to merge values. + * @param {Function} [customizer] The function to customize merged values. + * @param {Array} [stackA=[]] Tracks traversed source objects. + * @param {Array} [stackB=[]] Associates values with source counterparts. + * @returns {boolean} Returns `true` if the objects are equivalent, else `false`. + */ + function baseMergeDeep(object, source, key, mergeFunc, customizer, stackA, stackB) { + var length = stackA.length, + srcValue = source[key]; -function HmacDRBG(options) { - if (!(this instanceof HmacDRBG)) - return new HmacDRBG(options); - this.hash = options.hash; - this.predResist = !!options.predResist; + while (length--) { + if (stackA[length] == srcValue) { + object[key] = stackB[length]; + return; + } + } + var value = object[key], + result = customizer ? customizer(value, srcValue, key, object, source) : undefined, + isCommon = result === undefined; + + if (isCommon) { + result = srcValue; + if (isArrayLike(srcValue) && (isArray(srcValue) || isTypedArray(srcValue))) { + result = isArray(value) + ? value + : (isArrayLike(value) ? arrayCopy(value) : []); + } + else if (isPlainObject(srcValue) || isArguments(srcValue)) { + result = isArguments(value) + ? toPlainObject(value) + : (isPlainObject(value) ? value : {}); + } + else { + isCommon = false; + } + } + // Add the source value to the stack of traversed objects and associate + // it with its merged value. + stackA.push(srcValue); + stackB.push(result); - this.outLen = this.hash.outSize; - this.minEntropy = options.minEntropy || this.hash.hmacStrength; + if (isCommon) { + // Recursively merge objects and arrays (susceptible to call stack limits). + object[key] = mergeFunc(result, srcValue, customizer, stackA, stackB); + } else if (result === result ? (result !== value) : (value === value)) { + object[key] = result; + } + } - this.reseed = null; - this.reseedInterval = null; - this.K = null; - this.V = null; + /** + * The base implementation of `_.property` without support for deep paths. + * + * @private + * @param {string} key The key of the property to get. + * @returns {Function} Returns the new function. + */ + function baseProperty(key) { + return function(object) { + return object == null ? undefined : object[key]; + }; + } - var entropy = utils.toArray(options.entropy, options.entropyEnc); - var nonce = utils.toArray(options.nonce, options.nonceEnc); - var pers = utils.toArray(options.pers, options.persEnc); - assert(entropy.length >= (this.minEntropy / 8), - 'Not enough entropy. Minimum is: ' + this.minEntropy + ' bits'); - this._init(entropy, nonce, pers); -} -module.exports = HmacDRBG; + /** + * A specialized version of `baseProperty` which supports deep paths. + * + * @private + * @param {Array|string} path The path of the property to get. + * @returns {Function} Returns the new function. + */ + function basePropertyDeep(path) { + var pathKey = (path + ''); + path = toPath(path); + return function(object) { + return baseGet(object, path, pathKey); + }; + } -HmacDRBG.prototype._init = function init(entropy, nonce, pers) { - var seed = entropy.concat(nonce).concat(pers); + /** + * The base implementation of `_.pullAt` without support for individual + * index arguments and capturing the removed elements. + * + * @private + * @param {Array} array The array to modify. + * @param {number[]} indexes The indexes of elements to remove. + * @returns {Array} Returns `array`. + */ + function basePullAt(array, indexes) { + var length = array ? indexes.length : 0; + while (length--) { + var index = indexes[length]; + if (index != previous && isIndex(index)) { + var previous = index; + splice.call(array, index, 1); + } + } + return array; + } - this.K = new Array(this.outLen / 8); - this.V = new Array(this.outLen / 8); - for (var i = 0; i < this.V.length; i++) { - this.K[i] = 0x00; - this.V[i] = 0x01; - } + /** + * The base implementation of `_.random` without support for argument juggling + * and returning floating-point numbers. + * + * @private + * @param {number} min The minimum possible value. + * @param {number} max The maximum possible value. + * @returns {number} Returns the random number. + */ + function baseRandom(min, max) { + return min + nativeFloor(nativeRandom() * (max - min + 1)); + } - this._update(seed); - this.reseed = 1; - this.reseedInterval = 0x1000000000000; // 2^48 -}; + /** + * The base implementation of `_.reduce` and `_.reduceRight` without support + * for callback shorthands and `this` binding, which iterates over `collection` + * using the provided `eachFunc`. + * + * @private + * @param {Array|Object|string} collection The collection to iterate over. + * @param {Function} iteratee The function invoked per iteration. + * @param {*} accumulator The initial value. + * @param {boolean} initFromCollection Specify using the first or last element + * of `collection` as the initial value. + * @param {Function} eachFunc The function to iterate over `collection`. + * @returns {*} Returns the accumulated value. + */ + function baseReduce(collection, iteratee, accumulator, initFromCollection, eachFunc) { + eachFunc(collection, function(value, index, collection) { + accumulator = initFromCollection + ? (initFromCollection = false, value) + : iteratee(accumulator, value, index, collection); + }); + return accumulator; + } -HmacDRBG.prototype._hmac = function hmac() { - return new hash.hmac(this.hash, this.K); -}; + /** + * The base implementation of `setData` without support for hot loop detection. + * + * @private + * @param {Function} func The function to associate metadata with. + * @param {*} data The metadata. + * @returns {Function} Returns `func`. + */ + var baseSetData = !metaMap ? identity : function(func, data) { + metaMap.set(func, data); + return func; + }; -HmacDRBG.prototype._update = function update(seed) { - var kmac = this._hmac() - .update(this.V) - .update([ 0x00 ]); - if (seed) - kmac = kmac.update(seed); - this.K = kmac.digest(); - this.V = this._hmac().update(this.V).digest(); - if (!seed) - return; + /** + * The base implementation of `_.slice` without an iteratee call guard. + * + * @private + * @param {Array} array The array to slice. + * @param {number} [start=0] The start position. + * @param {number} [end=array.length] The end position. + * @returns {Array} Returns the slice of `array`. + */ + function baseSlice(array, start, end) { + var index = -1, + length = array.length; - this.K = this._hmac() - .update(this.V) - .update([ 0x01 ]) - .update(seed) - .digest(); - this.V = this._hmac().update(this.V).digest(); -}; + start = start == null ? 0 : (+start || 0); + if (start < 0) { + start = -start > length ? 0 : (length + start); + } + end = (end === undefined || end > length) ? length : (+end || 0); + if (end < 0) { + end += length; + } + length = start > end ? 0 : ((end - start) >>> 0); + start >>>= 0; -HmacDRBG.prototype.reseed = function reseed(entropy, entropyEnc, add, addEnc) { - // Optional entropy enc - if (typeof entropyEnc !== 'string') { - addEnc = add; - add = entropyEnc; - entropyEnc = null; - } + var result = Array(length); + while (++index < length) { + result[index] = array[index + start]; + } + return result; + } - entropy = utils.toBuffer(entropy, entropyEnc); - add = utils.toBuffer(add, addEnc); + /** + * The base implementation of `_.some` without support for callback shorthands + * and `this` binding. + * + * @private + * @param {Array|Object|string} collection The collection to iterate over. + * @param {Function} predicate The function invoked per iteration. + * @returns {boolean} Returns `true` if any element passes the predicate check, + * else `false`. + */ + function baseSome(collection, predicate) { + var result; - assert(entropy.length >= (this.minEntropy / 8), - 'Not enough entropy. Minimum is: ' + this.minEntropy + ' bits'); + baseEach(collection, function(value, index, collection) { + result = predicate(value, index, collection); + return !result; + }); + return !!result; + } - this._update(entropy.concat(add || [])); - this.reseed = 1; -}; + /** + * The base implementation of `_.sortBy` which uses `comparer` to define + * the sort order of `array` and replaces criteria objects with their + * corresponding values. + * + * @private + * @param {Array} array The array to sort. + * @param {Function} comparer The function to define sort order. + * @returns {Array} Returns `array`. + */ + function baseSortBy(array, comparer) { + var length = array.length; -HmacDRBG.prototype.generate = function generate(len, enc, add, addEnc) { - if (this.reseed > this.reseedInterval) - throw new Error('Reseed is required'); + array.sort(comparer); + while (length--) { + array[length] = array[length].value; + } + return array; + } - // Optional encoding - if (typeof enc !== 'string') { - addEnc = add; - add = enc; - enc = null; - } + /** + * The base implementation of `_.sortByOrder` without param guards. + * + * @private + * @param {Array|Object|string} collection The collection to iterate over. + * @param {Function[]|Object[]|string[]} iteratees The iteratees to sort by. + * @param {boolean[]} orders The sort orders of `iteratees`. + * @returns {Array} Returns the new sorted array. + */ + function baseSortByOrder(collection, iteratees, orders) { + var callback = getCallback(), + index = -1; - // Optional additional data - if (add) { - add = utils.toArray(add, addEnc); - this._update(add); - } + iteratees = arrayMap(iteratees, function(iteratee) { return callback(iteratee); }); - var temp = []; - while (temp.length < len) { - this.V = this._hmac().update(this.V).digest(); - temp = temp.concat(this.V); - } + var result = baseMap(collection, function(value) { + var criteria = arrayMap(iteratees, function(iteratee) { return iteratee(value); }); + return { 'criteria': criteria, 'index': ++index, 'value': value }; + }); - var res = temp.slice(0, len); - this._update(add); - this.reseed++; - return utils.encode(res, enc); -}; + return baseSortBy(result, function(object, other) { + return compareMultiple(object, other, orders); + }); + } -},{"../elliptic":209,"assert":41,"hash.js":223}],220:[function(require,module,exports){ -var assert = require('assert'); -var bn = require('bn.js'); + /** + * The base implementation of `_.sum` without support for callback shorthands + * and `this` binding. + * + * @private + * @param {Array|Object|string} collection The collection to iterate over. + * @param {Function} iteratee The function invoked per iteration. + * @returns {number} Returns the sum. + */ + function baseSum(collection, iteratee) { + var result = 0; + baseEach(collection, function(value, index, collection) { + result += +iteratee(value, index, collection) || 0; + }); + return result; + } -var utils = exports; + /** + * The base implementation of `_.uniq` without support for callback shorthands + * and `this` binding. + * + * @private + * @param {Array} array The array to inspect. + * @param {Function} [iteratee] The function invoked per iteration. + * @returns {Array} Returns the new duplicate-value-free array. + */ + function baseUniq(array, iteratee) { + var index = -1, + indexOf = getIndexOf(), + length = array.length, + isCommon = indexOf == baseIndexOf, + isLarge = isCommon && length >= LARGE_ARRAY_SIZE, + seen = isLarge ? createCache() : null, + result = []; -function toArray(msg, enc) { - if (Array.isArray(msg)) - return msg.slice(); - if (!msg) - return []; - var res = []; - if (typeof msg === 'string') { - if (!enc) { - for (var i = 0; i < msg.length; i++) { - var c = msg.charCodeAt(i); - var hi = c >> 8; - var lo = c & 0xff; - if (hi) - res.push(hi, lo); - else - res.push(lo); + if (seen) { + indexOf = cacheIndexOf; + isCommon = false; + } else { + isLarge = false; + seen = iteratee ? [] : result; } - } else if (enc === 'hex') { - msg = msg.replace(/[^a-z0-9]+/ig, ''); - if (msg.length % 2 !== 0) - msg = '0' + msg; - for (var i = 0; i < msg.length; i += 2) - res.push(parseInt(msg[i] + msg[i + 1], 16)); + outer: + while (++index < length) { + var value = array[index], + computed = iteratee ? iteratee(value, index, array) : value; + + if (isCommon && value === value) { + var seenIndex = seen.length; + while (seenIndex--) { + if (seen[seenIndex] === computed) { + continue outer; + } + } + if (iteratee) { + seen.push(computed); + } + result.push(value); + } + else if (indexOf(seen, computed, 0) < 0) { + if (iteratee || isLarge) { + seen.push(computed); + } + result.push(value); + } + } + return result; } - } else { - for (var i = 0; i < msg.length; i++) - res[i] = msg[i] | 0; - } - return res; -} -utils.toArray = toArray; -function toHex(msg) { - var res = ''; - for (var i = 0; i < msg.length; i++) - res += zero2(msg[i].toString(16)); - return res; -} -utils.toHex = toHex; + /** + * The base implementation of `_.values` and `_.valuesIn` which creates an + * array of `object` property values corresponding to the property names + * of `props`. + * + * @private + * @param {Object} object The object to query. + * @param {Array} props The property names to get values for. + * @returns {Object} Returns the array of property values. + */ + function baseValues(object, props) { + var index = -1, + length = props.length, + result = Array(length); -utils.encode = function encode(arr, enc) { - if (enc === 'hex') - return toHex(arr); - else - return arr; -}; + while (++index < length) { + result[index] = object[props[index]]; + } + return result; + } -function zero2(word) { - if (word.length === 1) - return '0' + word; - else - return word; -} -utils.zero2 = zero2; + /** + * The base implementation of `_.dropRightWhile`, `_.dropWhile`, `_.takeRightWhile`, + * and `_.takeWhile` without support for callback shorthands and `this` binding. + * + * @private + * @param {Array} array The array to query. + * @param {Function} predicate The function invoked per iteration. + * @param {boolean} [isDrop] Specify dropping elements instead of taking them. + * @param {boolean} [fromRight] Specify iterating from right to left. + * @returns {Array} Returns the slice of `array`. + */ + function baseWhile(array, predicate, isDrop, fromRight) { + var length = array.length, + index = fromRight ? length : -1; -// Represent num in a w-NAF form -function getNAF(num, w) { - var naf = []; - var ws = 1 << (w + 1); - var k = num.clone(); - while (k.cmpn(1) >= 0) { - var z; - if (k.isOdd()) { - var mod = k.andln(ws - 1); - if (mod > (ws >> 1) - 1) - z = (ws >> 1) - mod; - else - z = mod; - k.isubn(z); - } else { - z = 0; + while ((fromRight ? index-- : ++index < length) && predicate(array[index], index, array)) {} + return isDrop + ? baseSlice(array, (fromRight ? 0 : index), (fromRight ? index + 1 : length)) + : baseSlice(array, (fromRight ? index + 1 : 0), (fromRight ? length : index)); } - naf.push(z); - // Optimization, shift by word if possible - var shift = (k.cmpn(0) !== 0 && k.andln(ws - 1) === 0) ? (w + 1) : 1; - for (var i = 1; i < shift; i++) - naf.push(0); - k.ishrn(shift); - } + /** + * The base implementation of `wrapperValue` which returns the result of + * performing a sequence of actions on the unwrapped `value`, where each + * successive action is supplied the return value of the previous. + * + * @private + * @param {*} value The unwrapped value. + * @param {Array} actions Actions to peform to resolve the unwrapped value. + * @returns {*} Returns the resolved value. + */ + function baseWrapperValue(value, actions) { + var result = value; + if (result instanceof LazyWrapper) { + result = result.value(); + } + var index = -1, + length = actions.length; - return naf; -} -utils.getNAF = getNAF; + while (++index < length) { + var action = actions[index]; + result = action.func.apply(action.thisArg, arrayPush([result], action.args)); + } + return result; + } -// Represent k1, k2 in a Joint Sparse Form -function getJSF(k1, k2) { - var jsf = [ - [], - [] - ]; + /** + * Performs a binary search of `array` to determine the index at which `value` + * should be inserted into `array` in order to maintain its sort order. + * + * @private + * @param {Array} array The sorted array to inspect. + * @param {*} value The value to evaluate. + * @param {boolean} [retHighest] Specify returning the highest qualified index. + * @returns {number} Returns the index at which `value` should be inserted + * into `array`. + */ + function binaryIndex(array, value, retHighest) { + var low = 0, + high = array ? array.length : low; - k1 = k1.clone(); - k2 = k2.clone(); - var d1 = 0; - var d2 = 0; - while (k1.cmpn(-d1) > 0 || k2.cmpn(-d2) > 0) { + if (typeof value == 'number' && value === value && high <= HALF_MAX_ARRAY_LENGTH) { + while (low < high) { + var mid = (low + high) >>> 1, + computed = array[mid]; - // First phase - var m14 = (k1.andln(3) + d1) & 3; - var m24 = (k2.andln(3) + d2) & 3; - if (m14 === 3) - m14 = -1; - if (m24 === 3) - m24 = -1; - var u1; - if ((m14 & 1) === 0) { - u1 = 0; - } else { - var m8 = (k1.andln(7) + d1) & 7; - if ((m8 === 3 || m8 === 5) && m24 === 2) - u1 = -m14; - else - u1 = m14; + if ((retHighest ? (computed <= value) : (computed < value)) && computed !== null) { + low = mid + 1; + } else { + high = mid; + } + } + return high; + } + return binaryIndexBy(array, value, identity, retHighest); } - jsf[0].push(u1); - var u2; - if ((m24 & 1) === 0) { - u2 = 0; - } else { - var m8 = (k2.andln(7) + d2) & 7; - if ((m8 === 3 || m8 === 5) && m14 === 2) - u2 = -m24; - else - u2 = m24; - } - jsf[1].push(u2); + /** + * This function is like `binaryIndex` except that it invokes `iteratee` for + * `value` and each element of `array` to compute their sort ranking. The + * iteratee is invoked with one argument; (value). + * + * @private + * @param {Array} array The sorted array to inspect. + * @param {*} value The value to evaluate. + * @param {Function} iteratee The function invoked per iteration. + * @param {boolean} [retHighest] Specify returning the highest qualified index. + * @returns {number} Returns the index at which `value` should be inserted + * into `array`. + */ + function binaryIndexBy(array, value, iteratee, retHighest) { + value = iteratee(value); - // Second phase - if (2 * d1 === u1 + 1) - d1 = 1 - d1; - if (2 * d2 === u2 + 1) - d2 = 1 - d2; - k1.ishrn(1); - k2.ishrn(1); - } + var low = 0, + high = array ? array.length : 0, + valIsNaN = value !== value, + valIsNull = value === null, + valIsUndef = value === undefined; - return jsf; -} -utils.getJSF = getJSF; + while (low < high) { + var mid = nativeFloor((low + high) / 2), + computed = iteratee(array[mid]), + isDef = computed !== undefined, + isReflexive = computed === computed; + + if (valIsNaN) { + var setLow = isReflexive || retHighest; + } else if (valIsNull) { + setLow = isReflexive && isDef && (retHighest || computed != null); + } else if (valIsUndef) { + setLow = isReflexive && (retHighest || isDef); + } else if (computed == null) { + setLow = false; + } else { + setLow = retHighest ? (computed <= value) : (computed < value); + } + if (setLow) { + low = mid + 1; + } else { + high = mid; + } + } + return nativeMin(high, MAX_ARRAY_INDEX); + } -},{"assert":41,"bn.js":207}],221:[function(require,module,exports){ -var r; + /** + * A specialized version of `baseCallback` which only supports `this` binding + * and specifying the number of arguments to provide to `func`. + * + * @private + * @param {Function} func The function to bind. + * @param {*} thisArg The `this` binding of `func`. + * @param {number} [argCount] The number of arguments to provide to `func`. + * @returns {Function} Returns the callback. + */ + function bindCallback(func, thisArg, argCount) { + if (typeof func != 'function') { + return identity; + } + if (thisArg === undefined) { + return func; + } + switch (argCount) { + case 1: return function(value) { + return func.call(thisArg, value); + }; + case 3: return function(value, index, collection) { + return func.call(thisArg, value, index, collection); + }; + case 4: return function(accumulator, value, index, collection) { + return func.call(thisArg, accumulator, value, index, collection); + }; + case 5: return function(value, other, key, object, source) { + return func.call(thisArg, value, other, key, object, source); + }; + } + return function() { + return func.apply(thisArg, arguments); + }; + } -module.exports = function rand(len) { - if (!r) - r = new Rand(); + /** + * Creates a clone of the given array buffer. + * + * @private + * @param {ArrayBuffer} buffer The array buffer to clone. + * @returns {ArrayBuffer} Returns the cloned array buffer. + */ + function bufferClone(buffer) { + var result = new ArrayBuffer(buffer.byteLength), + view = new Uint8Array(result); - return r.generate(len); -}; + view.set(new Uint8Array(buffer)); + return result; + } -function Rand() { -} + /** + * Creates an array that is the composition of partially applied arguments, + * placeholders, and provided arguments into a single array of arguments. + * + * @private + * @param {Array|Object} args The provided arguments. + * @param {Array} partials The arguments to prepend to those provided. + * @param {Array} holders The `partials` placeholder indexes. + * @returns {Array} Returns the new array of composed arguments. + */ + function composeArgs(args, partials, holders) { + var holdersLength = holders.length, + argsIndex = -1, + argsLength = nativeMax(args.length - holdersLength, 0), + leftIndex = -1, + leftLength = partials.length, + result = Array(leftLength + argsLength); -Rand.prototype.generate = function generate(len) { - return this._rand(len); -}; + while (++leftIndex < leftLength) { + result[leftIndex] = partials[leftIndex]; + } + while (++argsIndex < holdersLength) { + result[holders[argsIndex]] = args[argsIndex]; + } + while (argsLength--) { + result[leftIndex++] = args[argsIndex++]; + } + return result; + } -if (typeof window === 'object') { - if (window.crypto && window.crypto.getRandomValues) { - // Modern browsers - Rand.prototype._rand = function _rand(n) { - var arr = new Uint8Array(n); - window.crypto.getRandomValues(arr); - return arr; - }; - } else if (window.msCrypto && window.msCrypto.getRandomValues) { - // IE - Rand.prototype._rand = function _rand(n) { - var arr = new Uint8Array(n); - window.msCrypto.getRandomValues(arr); - return arr; - }; - } else { - // Old junk - Rand.prototype._rand = function() { - throw new Error('Not implemented yet'); - }; - } -} else { - // Node.js - var crypto; - Rand.prototype._rand = function _rand(n) { - if (!crypto) - crypto = require('cry' + 'pto'); - return crypto.randomBytes(n); - }; -} + /** + * This function is like `composeArgs` except that the arguments composition + * is tailored for `_.partialRight`. + * + * @private + * @param {Array|Object} args The provided arguments. + * @param {Array} partials The arguments to append to those provided. + * @param {Array} holders The `partials` placeholder indexes. + * @returns {Array} Returns the new array of composed arguments. + */ + function composeArgsRight(args, partials, holders) { + var holdersIndex = -1, + holdersLength = holders.length, + argsIndex = -1, + argsLength = nativeMax(args.length - holdersLength, 0), + rightIndex = -1, + rightLength = partials.length, + result = Array(argsLength + rightLength); + + while (++argsIndex < argsLength) { + result[argsIndex] = args[argsIndex]; + } + var offset = argsIndex; + while (++rightIndex < rightLength) { + result[offset + rightIndex] = partials[rightIndex]; + } + while (++holdersIndex < holdersLength) { + result[offset + holders[holdersIndex]] = args[argsIndex++]; + } + return result; + } -},{}],222:[function(require,module,exports){ -module.exports={ - "name": "elliptic", - "version": "0.16.0", - "description": "EC cryptography", - "main": "lib/elliptic.js", - "scripts": { - "test": "mocha --reporter=spec test/*-test.js" - }, - "repository": { - "type": "git", - "url": "git@github.com:indutny/elliptic" - }, - "keywords": [ - "EC", - "Elliptic", - "curve", - "Cryptography" - ], - "author": { - "name": "Fedor Indutny", - "email": "fedor@indutny.com" - }, - "license": "MIT", - "bugs": { - "url": "https://github.com/indutny/elliptic/issues" - }, - "homepage": "https://github.com/indutny/elliptic", - "devDependencies": { - "browserify": "^3.44.2", - "mocha": "^1.18.2", - "uglify-js": "^2.4.13" - }, - "dependencies": { - "bn.js": "^0.16.0", - "brorand": "^1.0.1", - "hash.js": "^0.3.2", - "inherits": "^2.0.1" - }, - "readme": "# Elliptic [![Build Status](https://secure.travis-ci.org/indutny/elliptic.png)](http://travis-ci.org/indutny/elliptic)\n\nFast elliptic-curve cryptography in a plain javascript implementation.\n\nNOTE: Please take a look at http://safecurves.cr.yp.to/ before choosing a curve\nfor your cryptography operations.\n\n## Incentive\n\nECC is much slower than regular RSA cryptography, the JS implementations are\neven more slower.\n\n## Benchmarks\n\n```bash\n$ node benchmarks/index.js\nBenchmarking: sign\nelliptic#sign x 262 ops/sec ±0.51% (177 runs sampled)\neccjs#sign x 55.91 ops/sec ±0.90% (144 runs sampled)\n------------------------\nFastest is elliptic#sign\n========================\nBenchmarking: verify\nelliptic#verify x 113 ops/sec ±0.50% (166 runs sampled)\neccjs#verify x 48.56 ops/sec ±0.36% (125 runs sampled)\n------------------------\nFastest is elliptic#verify\n========================\nBenchmarking: gen\nelliptic#gen x 294 ops/sec ±0.43% (176 runs sampled)\neccjs#gen x 62.25 ops/sec ±0.63% (129 runs sampled)\n------------------------\nFastest is elliptic#gen\n========================\nBenchmarking: ecdh\nelliptic#ecdh x 136 ops/sec ±0.85% (156 runs sampled)\n------------------------\nFastest is elliptic#ecdh\n========================\n```\n\n## API\n\n### ECDSA\n\n```javascript\nvar EC = require('elliptic').ec;\n\n// Create and initialize EC context\n// (better do it once and reuse it)\nvar ec = new EC('secp256k1');\n\n// Generate keys\nvar key = ec.genKeyPair();\n\n// Sign message (must be an array, or it'll be treated as a hex sequence)\nvar msg = [ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 ];\nvar signature = key.sign(msg);\n\n// Export DER encoded signature in Array\nvar derSign = signature.toDER();\n\n// Verify signature\nconsole.log(key.verify(msg, derSign));\n```\n\n### ECDH\n\n```javascript\n// Generate keys\nvar key1 = ec.genKeyPair();\nvar key2 = ec.genKeyPair();\n\nvar shared1 = key1.derive(key2.getPublic());\nvar shared2 = key2.derive(key1.getPublic());\n\nconsole.log('Both shared secrets are BN instances');\nconsole.log(shared1.toString(16));\nconsole.log(shared2.toString(16));\n```\n\nNOTE: `.derive()` returns a [BN][1] instance.\n\n## Supported curves\n\nElliptic.js support following curve types:\n\n* Short Weierstrass\n* Montgomery\n* Edwards\n* Twisted Edwards\n\nFollowing curve 'presets' are embedded into the library:\n\n* `secp256k1`\n* `p192`\n* `p224`\n* `p256`\n* `curve25519`\n* `ed25519`\n\nNOTE: That `curve25519` could not be used for ECDSA, use `ed25519` instead.\n\n### Implementation details\n\nECDSA is using deterministic `k` value generation as per [RFC6979][0]. Most of\nthe curve operations are performed on non-affine coordinates (either projective\nor extended), various windowing techniques are used for different cases.\n\nAll operations are performed in reduction context using [bn.js][1], hashing is\nprovided by [hash.js][2]\n\n#### LICENSE\n\nThis software is licensed under the MIT License.\n\nCopyright Fedor Indutny, 2014.\n\nPermission is hereby granted, free of charge, to any person obtaining a\ncopy of this software and associated documentation files (the\n\"Software\"), to deal in the Software without restriction, including\nwithout limitation the rights to use, copy, modify, merge, publish,\ndistribute, sublicense, and/or sell copies of the Software, and to permit\npersons to whom the Software is furnished to do so, subject to the\nfollowing conditions:\n\nThe above copyright notice and this permission notice shall be included\nin all copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS\nOR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\nMERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN\nNO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,\nDAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\nOTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE\nUSE OR OTHER DEALINGS IN THE SOFTWARE.\n\n[0]: http://tools.ietf.org/html/rfc6979\n[1]: https://github.com/indutny/bn.js\n[2]: https://github.com/indutny/hash.js\n", - "readmeFilename": "README.md", - "_id": "elliptic@0.16.0", - "_shasum": "9bc84e75ccd97e3e452c97371726c535314d1a57", - "_resolved": "https://registry.npmjs.org/elliptic/-/elliptic-0.16.0.tgz", - "_from": "https://registry.npmjs.org/elliptic/-/elliptic-0.16.0.tgz" -} + /** + * Creates a `_.countBy`, `_.groupBy`, `_.indexBy`, or `_.partition` function. + * + * @private + * @param {Function} setter The function to set keys and values of the accumulator object. + * @param {Function} [initializer] The function to initialize the accumulator object. + * @returns {Function} Returns the new aggregator function. + */ + function createAggregator(setter, initializer) { + return function(collection, iteratee, thisArg) { + var result = initializer ? initializer() : {}; + iteratee = getCallback(iteratee, thisArg, 3); -},{}],223:[function(require,module,exports){ -var hash = exports; + if (isArray(collection)) { + var index = -1, + length = collection.length; -hash.utils = require('./hash/utils'); -hash.common = require('./hash/common'); -hash.sha = require('./hash/sha'); -hash.ripemd = require('./hash/ripemd'); -hash.hmac = require('./hash/hmac'); + while (++index < length) { + var value = collection[index]; + setter(result, value, iteratee(value, index, collection), collection); + } + } else { + baseEach(collection, function(value, key, collection) { + setter(result, value, iteratee(value, key, collection), collection); + }); + } + return result; + }; + } -// Proxy hash functions to the main object -hash.sha1 = hash.sha.sha1; -hash.sha256 = hash.sha.sha256; -hash.sha224 = hash.sha.sha224; -hash.ripemd160 = hash.ripemd.ripemd160; + /** + * Creates a `_.assign`, `_.defaults`, or `_.merge` function. + * + * @private + * @param {Function} assigner The function to assign values. + * @returns {Function} Returns the new assigner function. + */ + function createAssigner(assigner) { + return restParam(function(object, sources) { + var index = -1, + length = object == null ? 0 : sources.length, + customizer = length > 2 ? sources[length - 2] : undefined, + guard = length > 2 ? sources[2] : undefined, + thisArg = length > 1 ? sources[length - 1] : undefined; + + if (typeof customizer == 'function') { + customizer = bindCallback(customizer, thisArg, 5); + length -= 2; + } else { + customizer = typeof thisArg == 'function' ? thisArg : undefined; + length -= (customizer ? 1 : 0); + } + if (guard && isIterateeCall(sources[0], sources[1], guard)) { + customizer = length < 3 ? undefined : customizer; + length = 1; + } + while (++index < length) { + var source = sources[index]; + if (source) { + assigner(object, source, customizer); + } + } + return object; + }); + } -},{"./hash/common":224,"./hash/hmac":225,"./hash/ripemd":226,"./hash/sha":227,"./hash/utils":228}],224:[function(require,module,exports){ -var hash = require('../hash'); -var utils = hash.utils; -var assert = utils.assert; + /** + * Creates a `baseEach` or `baseEachRight` function. + * + * @private + * @param {Function} eachFunc The function to iterate over a collection. + * @param {boolean} [fromRight] Specify iterating from right to left. + * @returns {Function} Returns the new base function. + */ + function createBaseEach(eachFunc, fromRight) { + return function(collection, iteratee) { + var length = collection ? getLength(collection) : 0; + if (!isLength(length)) { + return eachFunc(collection, iteratee); + } + var index = fromRight ? length : -1, + iterable = toObject(collection); -function BlockHash() { - this.pending = null; - this.pendingTotal = 0; - this.blockSize = this.constructor.blockSize; - this.outSize = this.constructor.outSize; - this.hmacStrength = this.constructor.hmacStrength; - this.endian = 'big'; + while ((fromRight ? index-- : ++index < length)) { + if (iteratee(iterable[index], index, iterable) === false) { + break; + } + } + return collection; + }; + } - this._delta8 = this.blockSize / 8; - this._delta32 = this.blockSize / 32; -} -exports.BlockHash = BlockHash; + /** + * Creates a base function for `_.forIn` or `_.forInRight`. + * + * @private + * @param {boolean} [fromRight] Specify iterating from right to left. + * @returns {Function} Returns the new base function. + */ + function createBaseFor(fromRight) { + return function(object, iteratee, keysFunc) { + var iterable = toObject(object), + props = keysFunc(object), + length = props.length, + index = fromRight ? length : -1; + + while ((fromRight ? index-- : ++index < length)) { + var key = props[index]; + if (iteratee(iterable[key], key, iterable) === false) { + break; + } + } + return object; + }; + } -BlockHash.prototype.update = function update(msg, enc) { - // Convert message to array, pad it, and join into 32bit blocks - msg = utils.toArray(msg, enc); - if (!this.pending) - this.pending = msg; - else - this.pending = this.pending.concat(msg); - this.pendingTotal += msg.length; + /** + * Creates a function that wraps `func` and invokes it with the `this` + * binding of `thisArg`. + * + * @private + * @param {Function} func The function to bind. + * @param {*} [thisArg] The `this` binding of `func`. + * @returns {Function} Returns the new bound function. + */ + function createBindWrapper(func, thisArg) { + var Ctor = createCtorWrapper(func); - // Enough data, try updating - if (this.pending.length >= this._delta8) { - msg = this.pending; + function wrapper() { + var fn = (this && this !== root && this instanceof wrapper) ? Ctor : func; + return fn.apply(thisArg, arguments); + } + return wrapper; + } - // Process pending data in blocks - var r = msg.length % this._delta8; - this.pending = msg.slice(msg.length - r, msg.length); - if (this.pending.length === 0) - this.pending = null; + /** + * Creates a `Set` cache object to optimize linear searches of large arrays. + * + * @private + * @param {Array} [values] The values to cache. + * @returns {null|Object} Returns the new cache object if `Set` is supported, else `null`. + */ + function createCache(values) { + return (nativeCreate && Set) ? new SetCache(values) : null; + } - msg = utils.join32(msg, 0, msg.length - r, this.endian); - for (var i = 0; i < msg.length; i += this._delta32) - this._update(msg, i, i + this._delta32); - } + /** + * Creates a function that produces compound words out of the words in a + * given string. + * + * @private + * @param {Function} callback The function to combine each word. + * @returns {Function} Returns the new compounder function. + */ + function createCompounder(callback) { + return function(string) { + var index = -1, + array = words(deburr(string)), + length = array.length, + result = ''; - return this; -}; + while (++index < length) { + result = callback(result, array[index], index); + } + return result; + }; + } -BlockHash.prototype.digest = function digest(enc) { - this.update(this._pad()); - assert(this.pending === null); + /** + * Creates a function that produces an instance of `Ctor` regardless of + * whether it was invoked as part of a `new` expression or by `call` or `apply`. + * + * @private + * @param {Function} Ctor The constructor to wrap. + * @returns {Function} Returns the new wrapped function. + */ + function createCtorWrapper(Ctor) { + return function() { + // Use a `switch` statement to work with class constructors. + // See http://ecma-international.org/ecma-262/6.0/#sec-ecmascript-function-objects-call-thisargument-argumentslist + // for more details. + var args = arguments; + switch (args.length) { + case 0: return new Ctor; + case 1: return new Ctor(args[0]); + case 2: return new Ctor(args[0], args[1]); + case 3: return new Ctor(args[0], args[1], args[2]); + case 4: return new Ctor(args[0], args[1], args[2], args[3]); + case 5: return new Ctor(args[0], args[1], args[2], args[3], args[4]); + case 6: return new Ctor(args[0], args[1], args[2], args[3], args[4], args[5]); + case 7: return new Ctor(args[0], args[1], args[2], args[3], args[4], args[5], args[6]); + } + var thisBinding = baseCreate(Ctor.prototype), + result = Ctor.apply(thisBinding, args); - return this._digest(enc); -}; + // Mimic the constructor's `return` behavior. + // See https://es5.github.io/#x13.2.2 for more details. + return isObject(result) ? result : thisBinding; + }; + } -BlockHash.prototype._pad = function pad() { - var len = this.pendingTotal; - var bytes = this._delta8; - var k = bytes - ((len + 8) % bytes); - var res = new Array(k + 8); - res[0] = 0x80; - for (var i = 1; i < k; i++) - res[i] = 0; + /** + * Creates a `_.curry` or `_.curryRight` function. + * + * @private + * @param {boolean} flag The curry bit flag. + * @returns {Function} Returns the new curry function. + */ + function createCurry(flag) { + function curryFunc(func, arity, guard) { + if (guard && isIterateeCall(func, arity, guard)) { + arity = undefined; + } + var result = createWrapper(func, flag, undefined, undefined, undefined, undefined, undefined, arity); + result.placeholder = curryFunc.placeholder; + return result; + } + return curryFunc; + } - // Append length - len <<= 3; - if (this.endian === 'big') { - res[i++] = 0; - res[i++] = 0; - res[i++] = 0; - res[i++] = 0; - res[i++] = (len >>> 24) & 0xff; - res[i++] = (len >>> 16) & 0xff; - res[i++] = (len >>> 8) & 0xff; - res[i++] = len & 0xff; - } else { - res[i++] = len & 0xff; - res[i++] = (len >>> 8) & 0xff; - res[i++] = (len >>> 16) & 0xff; - res[i++] = (len >>> 24) & 0xff; - res[i++] = 0; - res[i++] = 0; - res[i++] = 0; - res[i++] = 0; - } + /** + * Creates a `_.defaults` or `_.defaultsDeep` function. + * + * @private + * @param {Function} assigner The function to assign values. + * @param {Function} customizer The function to customize assigned values. + * @returns {Function} Returns the new defaults function. + */ + function createDefaults(assigner, customizer) { + return restParam(function(args) { + var object = args[0]; + if (object == null) { + return object; + } + args.push(customizer); + return assigner.apply(undefined, args); + }); + } - return res; -} + /** + * Creates a `_.max` or `_.min` function. + * + * @private + * @param {Function} comparator The function used to compare values. + * @param {*} exValue The initial extremum value. + * @returns {Function} Returns the new extremum function. + */ + function createExtremum(comparator, exValue) { + return function(collection, iteratee, thisArg) { + if (thisArg && isIterateeCall(collection, iteratee, thisArg)) { + iteratee = undefined; + } + iteratee = getCallback(iteratee, thisArg, 3); + if (iteratee.length == 1) { + collection = isArray(collection) ? collection : toIterable(collection); + var result = arrayExtremum(collection, iteratee, comparator, exValue); + if (!(collection.length && result === exValue)) { + return result; + } + } + return baseExtremum(collection, iteratee, comparator, exValue); + }; + } -},{"../hash":223}],225:[function(require,module,exports){ -arguments[4][84][0].apply(exports,arguments) -},{"../hash":223,"/Users/eordano/Code/bitcore/node_modules/bitcore-build/node_modules/browserify/node_modules/crypto-browserify/node_modules/browserify-sign/node_modules/elliptic/node_modules/hash.js/lib/hash/hmac.js":84}],226:[function(require,module,exports){ -var hash = require('../hash'); -var utils = hash.utils; + /** + * Creates a `_.find` or `_.findLast` function. + * + * @private + * @param {Function} eachFunc The function to iterate over a collection. + * @param {boolean} [fromRight] Specify iterating from right to left. + * @returns {Function} Returns the new find function. + */ + function createFind(eachFunc, fromRight) { + return function(collection, predicate, thisArg) { + predicate = getCallback(predicate, thisArg, 3); + if (isArray(collection)) { + var index = baseFindIndex(collection, predicate, fromRight); + return index > -1 ? collection[index] : undefined; + } + return baseFind(collection, predicate, eachFunc); + }; + } -var rotl32 = utils.rotl32; -var sum32 = utils.sum32; -var sum32_3 = utils.sum32_3; -var sum32_4 = utils.sum32_4; -var BlockHash = hash.common.BlockHash; + /** + * Creates a `_.findIndex` or `_.findLastIndex` function. + * + * @private + * @param {boolean} [fromRight] Specify iterating from right to left. + * @returns {Function} Returns the new find function. + */ + function createFindIndex(fromRight) { + return function(array, predicate, thisArg) { + if (!(array && array.length)) { + return -1; + } + predicate = getCallback(predicate, thisArg, 3); + return baseFindIndex(array, predicate, fromRight); + }; + } -function RIPEMD160() { - if (!(this instanceof RIPEMD160)) - return new RIPEMD160(); + /** + * Creates a `_.findKey` or `_.findLastKey` function. + * + * @private + * @param {Function} objectFunc The function to iterate over an object. + * @returns {Function} Returns the new find function. + */ + function createFindKey(objectFunc) { + return function(object, predicate, thisArg) { + predicate = getCallback(predicate, thisArg, 3); + return baseFind(object, predicate, objectFunc, true); + }; + } - BlockHash.call(this); + /** + * Creates a `_.flow` or `_.flowRight` function. + * + * @private + * @param {boolean} [fromRight] Specify iterating from right to left. + * @returns {Function} Returns the new flow function. + */ + function createFlow(fromRight) { + return function() { + var wrapper, + length = arguments.length, + index = fromRight ? length : -1, + leftIndex = 0, + funcs = Array(length); + + while ((fromRight ? index-- : ++index < length)) { + var func = funcs[leftIndex++] = arguments[index]; + if (typeof func != 'function') { + throw new TypeError(FUNC_ERROR_TEXT); + } + if (!wrapper && LodashWrapper.prototype.thru && getFuncName(func) == 'wrapper') { + wrapper = new LodashWrapper([], true); + } + } + index = wrapper ? -1 : length; + while (++index < length) { + func = funcs[index]; - this.h = [ 0x67452301, 0xefcdab89, 0x98badcfe, 0x10325476, 0xc3d2e1f0 ]; - this.endian = 'little'; -} -utils.inherits(RIPEMD160, BlockHash); -exports.ripemd160 = RIPEMD160; + var funcName = getFuncName(func), + data = funcName == 'wrapper' ? getData(func) : undefined; -RIPEMD160.blockSize = 512; -RIPEMD160.outSize = 160; -RIPEMD160.hmacStrength = 192; + if (data && isLaziable(data[0]) && data[1] == (ARY_FLAG | CURRY_FLAG | PARTIAL_FLAG | REARG_FLAG) && !data[4].length && data[9] == 1) { + wrapper = wrapper[getFuncName(data[0])].apply(wrapper, data[3]); + } else { + wrapper = (func.length == 1 && isLaziable(func)) ? wrapper[funcName]() : wrapper.thru(func); + } + } + return function() { + var args = arguments, + value = args[0]; -RIPEMD160.prototype._update = function update(msg, start) { - var A = this.h[0]; - var B = this.h[1]; - var C = this.h[2]; - var D = this.h[3]; - var E = this.h[4]; - var Ah = A; - var Bh = B; - var Ch = C; - var Dh = D; - var Eh = E; - for (var j = 0; j < 80; j++) { - var T = sum32( - rotl32( - sum32_4(A, f(j, B, C, D), msg[r[j] + start], K(j)), - s[j]), - E); - A = E; - E = D; - D = rotl32(C, 10); - C = B; - B = T; - T = sum32( - rotl32( - sum32_4(Ah, f(79 - j, Bh, Ch, Dh), msg[rh[j] + start], Kh(j)), - sh[j]), - Eh); - Ah = Eh; - Eh = Dh; - Dh = rotl32(Ch, 10); - Ch = Bh; - Bh = T; - } - T = sum32_3(this.h[1], C, Dh); - this.h[1] = sum32_3(this.h[2], D, Eh); - this.h[2] = sum32_3(this.h[3], E, Ah); - this.h[3] = sum32_3(this.h[4], A, Bh); - this.h[4] = sum32_3(this.h[0], B, Ch); - this.h[0] = T; -}; + if (wrapper && args.length == 1 && isArray(value) && value.length >= LARGE_ARRAY_SIZE) { + return wrapper.plant(value).value(); + } + var index = 0, + result = length ? funcs[index].apply(this, args) : value; -RIPEMD160.prototype._digest = function digest(enc) { - if (enc === 'hex') - return utils.toHex32(this.h, 'little'); - else - return utils.split32(this.h, 'little'); -}; + while (++index < length) { + result = funcs[index].call(this, result); + } + return result; + }; + }; + } -function f(j, x, y, z) { - if (j <= 15) - return x ^ y ^ z; - else if (j <= 31) - return (x & y) | ((~x) & z); - else if (j <= 47) - return (x | (~y)) ^ z; - else if (j <= 63) - return (x & z) | (y & (~z)); - else - return x ^ (y | (~z)); -} + /** + * Creates a function for `_.forEach` or `_.forEachRight`. + * + * @private + * @param {Function} arrayFunc The function to iterate over an array. + * @param {Function} eachFunc The function to iterate over a collection. + * @returns {Function} Returns the new each function. + */ + function createForEach(arrayFunc, eachFunc) { + return function(collection, iteratee, thisArg) { + return (typeof iteratee == 'function' && thisArg === undefined && isArray(collection)) + ? arrayFunc(collection, iteratee) + : eachFunc(collection, bindCallback(iteratee, thisArg, 3)); + }; + } -function K(j) { - if (j <= 15) - return 0x00000000; - else if (j <= 31) - return 0x5a827999; - else if (j <= 47) - return 0x6ed9eba1; - else if (j <= 63) - return 0x8f1bbcdc; - else - return 0xa953fd4e; -} + /** + * Creates a function for `_.forIn` or `_.forInRight`. + * + * @private + * @param {Function} objectFunc The function to iterate over an object. + * @returns {Function} Returns the new each function. + */ + function createForIn(objectFunc) { + return function(object, iteratee, thisArg) { + if (typeof iteratee != 'function' || thisArg !== undefined) { + iteratee = bindCallback(iteratee, thisArg, 3); + } + return objectFunc(object, iteratee, keysIn); + }; + } -function Kh(j) { - if (j <= 15) - return 0x50a28be6; - else if (j <= 31) - return 0x5c4dd124; - else if (j <= 47) - return 0x6d703ef3; - else if (j <= 63) - return 0x7a6d76e9; - else - return 0x00000000; -} + /** + * Creates a function for `_.forOwn` or `_.forOwnRight`. + * + * @private + * @param {Function} objectFunc The function to iterate over an object. + * @returns {Function} Returns the new each function. + */ + function createForOwn(objectFunc) { + return function(object, iteratee, thisArg) { + if (typeof iteratee != 'function' || thisArg !== undefined) { + iteratee = bindCallback(iteratee, thisArg, 3); + } + return objectFunc(object, iteratee); + }; + } -var r = [ - 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, - 7, 4, 13, 1, 10, 6, 15, 3, 12, 0, 9, 5, 2, 14, 11, 8, - 3, 10, 14, 4, 9, 15, 8, 1, 2, 7, 0, 6, 13, 11, 5, 12, - 1, 9, 11, 10, 0, 8, 12, 4, 13, 3, 7, 15, 14, 5, 6, 2, - 4, 0, 5, 9, 7, 12, 2, 10, 14, 1, 3, 8, 11, 6, 15, 13, -]; + /** + * Creates a function for `_.mapKeys` or `_.mapValues`. + * + * @private + * @param {boolean} [isMapKeys] Specify mapping keys instead of values. + * @returns {Function} Returns the new map function. + */ + function createObjectMapper(isMapKeys) { + return function(object, iteratee, thisArg) { + var result = {}; + iteratee = getCallback(iteratee, thisArg, 3); -var rh = [ - 5, 14, 7, 0, 9, 2, 11, 4, 13, 6, 15, 8, 1, 10, 3, 12, - 6, 11, 3, 7, 0, 13, 5, 10, 14, 15, 8, 12, 4, 9, 1, 2, - 15, 5, 1, 3, 7, 14, 6, 9, 11, 8, 12, 2, 10, 0, 4, 13, - 8, 6, 4, 1, 3, 11, 15, 0, 5, 12, 2, 13, 9, 7, 10, 14, - 12, 15, 10, 4, 1, 5, 8, 7, 6, 2, 13, 14, 0, 3, 9, 11 -]; + baseForOwn(object, function(value, key, object) { + var mapped = iteratee(value, key, object); + key = isMapKeys ? mapped : key; + value = isMapKeys ? value : mapped; + result[key] = value; + }); + return result; + }; + } -var s = [ - 11, 14, 15, 12, 5, 8, 7, 9, 11, 13, 14, 15, 6, 7, 9, 8, - 7, 6, 8, 13, 11, 9, 7, 15, 7, 12, 15, 9, 11, 7, 13, 12, - 11, 13, 6, 7, 14, 9, 13, 15, 14, 8, 13, 6, 5, 12, 7, 5, - 11, 12, 14, 15, 14, 15, 9, 8, 9, 14, 5, 6, 8, 6, 5, 12, - 9, 15, 5, 11, 6, 8, 13, 12, 5, 12, 13, 14, 11, 8, 5, 6, -]; + /** + * Creates a function for `_.padLeft` or `_.padRight`. + * + * @private + * @param {boolean} [fromRight] Specify padding from the right. + * @returns {Function} Returns the new pad function. + */ + function createPadDir(fromRight) { + return function(string, length, chars) { + string = baseToString(string); + return (fromRight ? string : '') + createPadding(string, length, chars) + (fromRight ? '' : string); + }; + } -var sh = [ - 8, 9, 9, 11, 13, 15, 15, 5, 7, 7, 8, 11, 14, 14, 12, 6, - 9, 13, 15, 7, 12, 8, 9, 11, 7, 7, 12, 7, 6, 15, 13, 11, - 9, 7, 15, 11, 8, 6, 6, 14, 12, 13, 5, 14, 13, 13, 7, 5, - 15, 5, 8, 11, 14, 14, 6, 14, 6, 9, 12, 9, 12, 5, 15, 8, - 8, 5, 12, 9, 12, 5, 14, 6, 8, 13, 6, 5, 15, 13, 11, 11 -]; + /** + * Creates a `_.partial` or `_.partialRight` function. + * + * @private + * @param {boolean} flag The partial bit flag. + * @returns {Function} Returns the new partial function. + */ + function createPartial(flag) { + var partialFunc = restParam(function(func, partials) { + var holders = replaceHolders(partials, partialFunc.placeholder); + return createWrapper(func, flag, undefined, partials, holders); + }); + return partialFunc; + } -},{"../hash":223}],227:[function(require,module,exports){ -var hash = require('../hash'); -var utils = hash.utils; -var assert = utils.assert; + /** + * Creates a function for `_.reduce` or `_.reduceRight`. + * + * @private + * @param {Function} arrayFunc The function to iterate over an array. + * @param {Function} eachFunc The function to iterate over a collection. + * @returns {Function} Returns the new each function. + */ + function createReduce(arrayFunc, eachFunc) { + return function(collection, iteratee, accumulator, thisArg) { + var initFromArray = arguments.length < 3; + return (typeof iteratee == 'function' && thisArg === undefined && isArray(collection)) + ? arrayFunc(collection, iteratee, accumulator, initFromArray) + : baseReduce(collection, getCallback(iteratee, thisArg, 4), accumulator, initFromArray, eachFunc); + }; + } -var rotr32 = utils.rotr32; -var rotl32 = utils.rotl32; -var sum32 = utils.sum32; -var sum32_4 = utils.sum32_4; -var sum32_5 = utils.sum32_5; -var BlockHash = hash.common.BlockHash; + /** + * Creates a function that wraps `func` and invokes it with optional `this` + * binding of, partial application, and currying. + * + * @private + * @param {Function|string} func The function or method name to reference. + * @param {number} bitmask The bitmask of flags. See `createWrapper` for more details. + * @param {*} [thisArg] The `this` binding of `func`. + * @param {Array} [partials] The arguments to prepend to those provided to the new function. + * @param {Array} [holders] The `partials` placeholder indexes. + * @param {Array} [partialsRight] The arguments to append to those provided to the new function. + * @param {Array} [holdersRight] The `partialsRight` placeholder indexes. + * @param {Array} [argPos] The argument positions of the new function. + * @param {number} [ary] The arity cap of `func`. + * @param {number} [arity] The arity of `func`. + * @returns {Function} Returns the new wrapped function. + */ + function createHybridWrapper(func, bitmask, thisArg, partials, holders, partialsRight, holdersRight, argPos, ary, arity) { + var isAry = bitmask & ARY_FLAG, + isBind = bitmask & BIND_FLAG, + isBindKey = bitmask & BIND_KEY_FLAG, + isCurry = bitmask & CURRY_FLAG, + isCurryBound = bitmask & CURRY_BOUND_FLAG, + isCurryRight = bitmask & CURRY_RIGHT_FLAG, + Ctor = isBindKey ? undefined : createCtorWrapper(func); + + function wrapper() { + // Avoid `arguments` object use disqualifying optimizations by + // converting it to an array before providing it to other functions. + var length = arguments.length, + index = length, + args = Array(length); + + while (index--) { + args[index] = arguments[index]; + } + if (partials) { + args = composeArgs(args, partials, holders); + } + if (partialsRight) { + args = composeArgsRight(args, partialsRight, holdersRight); + } + if (isCurry || isCurryRight) { + var placeholder = wrapper.placeholder, + argsHolders = replaceHolders(args, placeholder); + + length -= argsHolders.length; + if (length < arity) { + var newArgPos = argPos ? arrayCopy(argPos) : undefined, + newArity = nativeMax(arity - length, 0), + newsHolders = isCurry ? argsHolders : undefined, + newHoldersRight = isCurry ? undefined : argsHolders, + newPartials = isCurry ? args : undefined, + newPartialsRight = isCurry ? undefined : args; + + bitmask |= (isCurry ? PARTIAL_FLAG : PARTIAL_RIGHT_FLAG); + bitmask &= ~(isCurry ? PARTIAL_RIGHT_FLAG : PARTIAL_FLAG); + + if (!isCurryBound) { + bitmask &= ~(BIND_FLAG | BIND_KEY_FLAG); + } + var newData = [func, bitmask, thisArg, newPartials, newsHolders, newPartialsRight, newHoldersRight, newArgPos, ary, newArity], + result = createHybridWrapper.apply(undefined, newData); -var sha256_K = [ - 0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, - 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5, - 0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3, - 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174, - 0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc, - 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da, - 0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7, - 0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967, - 0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13, - 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85, - 0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3, - 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070, - 0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5, - 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3, - 0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208, - 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2 -]; + if (isLaziable(func)) { + setData(result, newData); + } + result.placeholder = placeholder; + return result; + } + } + var thisBinding = isBind ? thisArg : this, + fn = isBindKey ? thisBinding[func] : func; -var sha1_K = [ - 0x5A827999, 0x6ED9EBA1, - 0x8F1BBCDC, 0xCA62C1D6 -]; + if (argPos) { + args = reorder(args, argPos); + } + if (isAry && ary < args.length) { + args.length = ary; + } + if (this && this !== root && this instanceof wrapper) { + fn = Ctor || createCtorWrapper(func); + } + return fn.apply(thisBinding, args); + } + return wrapper; + } -function SHA256() { - if (!(this instanceof SHA256)) - return new SHA256(); + /** + * Creates the padding required for `string` based on the given `length`. + * The `chars` string is truncated if the number of characters exceeds `length`. + * + * @private + * @param {string} string The string to create padding for. + * @param {number} [length=0] The padding length. + * @param {string} [chars=' '] The string used as padding. + * @returns {string} Returns the pad for `string`. + */ + function createPadding(string, length, chars) { + var strLength = string.length; + length = +length; + + if (strLength >= length || !nativeIsFinite(length)) { + return ''; + } + var padLength = length - strLength; + chars = chars == null ? ' ' : (chars + ''); + return repeat(chars, nativeCeil(padLength / chars.length)).slice(0, padLength); + } + + /** + * Creates a function that wraps `func` and invokes it with the optional `this` + * binding of `thisArg` and the `partials` prepended to those provided to + * the wrapper. + * + * @private + * @param {Function} func The function to partially apply arguments to. + * @param {number} bitmask The bitmask of flags. See `createWrapper` for more details. + * @param {*} thisArg The `this` binding of `func`. + * @param {Array} partials The arguments to prepend to those provided to the new function. + * @returns {Function} Returns the new bound function. + */ + function createPartialWrapper(func, bitmask, thisArg, partials) { + var isBind = bitmask & BIND_FLAG, + Ctor = createCtorWrapper(func); + + function wrapper() { + // Avoid `arguments` object use disqualifying optimizations by + // converting it to an array before providing it `func`. + var argsIndex = -1, + argsLength = arguments.length, + leftIndex = -1, + leftLength = partials.length, + args = Array(leftLength + argsLength); + + while (++leftIndex < leftLength) { + args[leftIndex] = partials[leftIndex]; + } + while (argsLength--) { + args[leftIndex++] = arguments[++argsIndex]; + } + var fn = (this && this !== root && this instanceof wrapper) ? Ctor : func; + return fn.apply(isBind ? thisArg : this, args); + } + return wrapper; + } - BlockHash.call(this); - this.h = [ 0x6a09e667, 0xbb67ae85, 0x3c6ef372, 0xa54ff53a, - 0x510e527f, 0x9b05688c, 0x1f83d9ab, 0x5be0cd19 ]; - this.k = sha256_K; - this.W = new Array(64); -} -utils.inherits(SHA256, BlockHash); -exports.sha256 = SHA256; + /** + * Creates a `_.ceil`, `_.floor`, or `_.round` function. + * + * @private + * @param {string} methodName The name of the `Math` method to use when rounding. + * @returns {Function} Returns the new round function. + */ + function createRound(methodName) { + var func = Math[methodName]; + return function(number, precision) { + precision = precision === undefined ? 0 : (+precision || 0); + if (precision) { + precision = pow(10, precision); + return func(number * precision) / precision; + } + return func(number); + }; + } -SHA256.blockSize = 512; -SHA256.outSize = 256; -SHA256.hmacStrength = 192; + /** + * Creates a `_.sortedIndex` or `_.sortedLastIndex` function. + * + * @private + * @param {boolean} [retHighest] Specify returning the highest qualified index. + * @returns {Function} Returns the new index function. + */ + function createSortedIndex(retHighest) { + return function(array, value, iteratee, thisArg) { + var callback = getCallback(iteratee); + return (iteratee == null && callback === baseCallback) + ? binaryIndex(array, value, retHighest) + : binaryIndexBy(array, value, callback(iteratee, thisArg, 1), retHighest); + }; + } -SHA256.prototype._update = function _update(msg, start) { - var W = this.W; + /** + * Creates a function that either curries or invokes `func` with optional + * `this` binding and partially applied arguments. + * + * @private + * @param {Function|string} func The function or method name to reference. + * @param {number} bitmask The bitmask of flags. + * The bitmask may be composed of the following flags: + * 1 - `_.bind` + * 2 - `_.bindKey` + * 4 - `_.curry` or `_.curryRight` of a bound function + * 8 - `_.curry` + * 16 - `_.curryRight` + * 32 - `_.partial` + * 64 - `_.partialRight` + * 128 - `_.rearg` + * 256 - `_.ary` + * @param {*} [thisArg] The `this` binding of `func`. + * @param {Array} [partials] The arguments to be partially applied. + * @param {Array} [holders] The `partials` placeholder indexes. + * @param {Array} [argPos] The argument positions of the new function. + * @param {number} [ary] The arity cap of `func`. + * @param {number} [arity] The arity of `func`. + * @returns {Function} Returns the new wrapped function. + */ + function createWrapper(func, bitmask, thisArg, partials, holders, argPos, ary, arity) { + var isBindKey = bitmask & BIND_KEY_FLAG; + if (!isBindKey && typeof func != 'function') { + throw new TypeError(FUNC_ERROR_TEXT); + } + var length = partials ? partials.length : 0; + if (!length) { + bitmask &= ~(PARTIAL_FLAG | PARTIAL_RIGHT_FLAG); + partials = holders = undefined; + } + length -= (holders ? holders.length : 0); + if (bitmask & PARTIAL_RIGHT_FLAG) { + var partialsRight = partials, + holdersRight = holders; - for (var i = 0; i < 16; i++) - W[i] = msg[start + i]; - for (; i < W.length; i++) - W[i] = sum32_4(g1_256(W[i - 2]), W[i - 7], g0_256(W[i - 15]), W[i - 16]); + partials = holders = undefined; + } + var data = isBindKey ? undefined : getData(func), + newData = [func, bitmask, thisArg, partials, holders, partialsRight, holdersRight, argPos, ary, arity]; - var a = this.h[0]; - var b = this.h[1]; - var c = this.h[2]; - var d = this.h[3]; - var e = this.h[4]; - var f = this.h[5]; - var g = this.h[6]; - var h = this.h[7]; + if (data) { + mergeData(newData, data); + bitmask = newData[1]; + arity = newData[9]; + } + newData[9] = arity == null + ? (isBindKey ? 0 : func.length) + : (nativeMax(arity - length, 0) || 0); + + if (bitmask == BIND_FLAG) { + var result = createBindWrapper(newData[0], newData[2]); + } else if ((bitmask == PARTIAL_FLAG || bitmask == (BIND_FLAG | PARTIAL_FLAG)) && !newData[4].length) { + result = createPartialWrapper.apply(undefined, newData); + } else { + result = createHybridWrapper.apply(undefined, newData); + } + var setter = data ? baseSetData : setData; + return setter(result, newData); + } - assert(this.k.length === W.length); - for (var i = 0; i < W.length; i++) { - var T1 = sum32_5(h, s1_256(e), ch32(e, f, g), this.k[i], W[i]); - var T2 = sum32(s0_256(a), maj32(a, b, c)); - h = g; - g = f; - f = e; - e = sum32(d, T1); - d = c; - c = b; - b = a; - a = sum32(T1, T2); - } + /** + * A specialized version of `baseIsEqualDeep` for arrays with support for + * partial deep comparisons. + * + * @private + * @param {Array} array The array to compare. + * @param {Array} other The other array to compare. + * @param {Function} equalFunc The function to determine equivalents of values. + * @param {Function} [customizer] The function to customize comparing arrays. + * @param {boolean} [isLoose] Specify performing partial comparisons. + * @param {Array} [stackA] Tracks traversed `value` objects. + * @param {Array} [stackB] Tracks traversed `other` objects. + * @returns {boolean} Returns `true` if the arrays are equivalent, else `false`. + */ + function equalArrays(array, other, equalFunc, customizer, isLoose, stackA, stackB) { + var index = -1, + arrLength = array.length, + othLength = other.length; - this.h[0] = sum32(this.h[0], a); - this.h[1] = sum32(this.h[1], b); - this.h[2] = sum32(this.h[2], c); - this.h[3] = sum32(this.h[3], d); - this.h[4] = sum32(this.h[4], e); - this.h[5] = sum32(this.h[5], f); - this.h[6] = sum32(this.h[6], g); - this.h[7] = sum32(this.h[7], h); -}; + if (arrLength != othLength && !(isLoose && othLength > arrLength)) { + return false; + } + // Ignore non-index properties. + while (++index < arrLength) { + var arrValue = array[index], + othValue = other[index], + result = customizer ? customizer(isLoose ? othValue : arrValue, isLoose ? arrValue : othValue, index) : undefined; + + if (result !== undefined) { + if (result) { + continue; + } + return false; + } + // Recursively compare arrays (susceptible to call stack limits). + if (isLoose) { + if (!arraySome(other, function(othValue) { + return arrValue === othValue || equalFunc(arrValue, othValue, customizer, isLoose, stackA, stackB); + })) { + return false; + } + } else if (!(arrValue === othValue || equalFunc(arrValue, othValue, customizer, isLoose, stackA, stackB))) { + return false; + } + } + return true; + } -SHA256.prototype._digest = function digest(enc) { - if (enc === 'hex') - return utils.toHex32(this.h, 'big'); - else - return utils.split32(this.h, 'big'); -}; + /** + * A specialized version of `baseIsEqualDeep` for comparing objects of + * the same `toStringTag`. + * + * **Note:** This function only supports comparing values with tags of + * `Boolean`, `Date`, `Error`, `Number`, `RegExp`, or `String`. + * + * @private + * @param {Object} object The object to compare. + * @param {Object} other The other object to compare. + * @param {string} tag The `toStringTag` of the objects to compare. + * @returns {boolean} Returns `true` if the objects are equivalent, else `false`. + */ + function equalByTag(object, other, tag) { + switch (tag) { + case boolTag: + case dateTag: + // Coerce dates and booleans to numbers, dates to milliseconds and booleans + // to `1` or `0` treating invalid dates coerced to `NaN` as not equal. + return +object == +other; + + case errorTag: + return object.name == other.name && object.message == other.message; + + case numberTag: + // Treat `NaN` vs. `NaN` as equal. + return (object != +object) + ? other != +other + : object == +other; + + case regexpTag: + case stringTag: + // Coerce regexes to strings and treat strings primitives and string + // objects as equal. See https://es5.github.io/#x15.10.6.4 for more details. + return object == (other + ''); + } + return false; + } -function SHA224() { - if (!(this instanceof SHA224)) - return new SHA224(); + /** + * A specialized version of `baseIsEqualDeep` for objects with support for + * partial deep comparisons. + * + * @private + * @param {Object} object The object to compare. + * @param {Object} other The other object to compare. + * @param {Function} equalFunc The function to determine equivalents of values. + * @param {Function} [customizer] The function to customize comparing values. + * @param {boolean} [isLoose] Specify performing partial comparisons. + * @param {Array} [stackA] Tracks traversed `value` objects. + * @param {Array} [stackB] Tracks traversed `other` objects. + * @returns {boolean} Returns `true` if the objects are equivalent, else `false`. + */ + function equalObjects(object, other, equalFunc, customizer, isLoose, stackA, stackB) { + var objProps = keys(object), + objLength = objProps.length, + othProps = keys(other), + othLength = othProps.length; - SHA256.call(this); - this.h = [ 0xc1059ed8, 0x367cd507, 0x3070dd17, 0xf70e5939, - 0xffc00b31, 0x68581511, 0x64f98fa7, 0xbefa4fa4 ]; -} -utils.inherits(SHA224, SHA256); -exports.sha224 = SHA224; + if (objLength != othLength && !isLoose) { + return false; + } + var index = objLength; + while (index--) { + var key = objProps[index]; + if (!(isLoose ? key in other : hasOwnProperty.call(other, key))) { + return false; + } + } + var skipCtor = isLoose; + while (++index < objLength) { + key = objProps[index]; + var objValue = object[key], + othValue = other[key], + result = customizer ? customizer(isLoose ? othValue : objValue, isLoose? objValue : othValue, key) : undefined; + + // Recursively compare objects (susceptible to call stack limits). + if (!(result === undefined ? equalFunc(objValue, othValue, customizer, isLoose, stackA, stackB) : result)) { + return false; + } + skipCtor || (skipCtor = key == 'constructor'); + } + if (!skipCtor) { + var objCtor = object.constructor, + othCtor = other.constructor; + + // Non `Object` object instances with different constructors are not equal. + if (objCtor != othCtor && + ('constructor' in object && 'constructor' in other) && + !(typeof objCtor == 'function' && objCtor instanceof objCtor && + typeof othCtor == 'function' && othCtor instanceof othCtor)) { + return false; + } + } + return true; + } -SHA224.blockSize = 512; -SHA224.outSize = 224; -SHA224.hmacStrength = 192; + /** + * Gets the appropriate "callback" function. If the `_.callback` method is + * customized this function returns the custom method, otherwise it returns + * the `baseCallback` function. If arguments are provided the chosen function + * is invoked with them and its result is returned. + * + * @private + * @returns {Function} Returns the chosen function or its result. + */ + function getCallback(func, thisArg, argCount) { + var result = lodash.callback || callback; + result = result === callback ? baseCallback : result; + return argCount ? result(func, thisArg, argCount) : result; + } -SHA224.prototype._digest = function digest(enc) { - // Just truncate output - if (enc === 'hex') - return utils.toHex32(this.h.slice(0, 7), 'big'); - else - return utils.split32(this.h.slice(0, 7), 'big'); -}; + /** + * Gets metadata for `func`. + * + * @private + * @param {Function} func The function to query. + * @returns {*} Returns the metadata for `func`. + */ + var getData = !metaMap ? noop : function(func) { + return metaMap.get(func); + }; -function SHA1() { - if (!(this instanceof SHA1)) - return new SHA1(); + /** + * Gets the name of `func`. + * + * @private + * @param {Function} func The function to query. + * @returns {string} Returns the function name. + */ + function getFuncName(func) { + var result = func.name, + array = realNames[result], + length = array ? array.length : 0; - BlockHash.call(this); - this.h = [ 0x67452301, 0xefcdab89, 0x98badcfe, - 0x10325476, 0xc3d2e1f0 ]; - this.W = new Array(80); -} + while (length--) { + var data = array[length], + otherFunc = data.func; + if (otherFunc == null || otherFunc == func) { + return data.name; + } + } + return result; + } -utils.inherits(SHA1, BlockHash); -exports.sha1 = SHA1; + /** + * Gets the appropriate "indexOf" function. If the `_.indexOf` method is + * customized this function returns the custom method, otherwise it returns + * the `baseIndexOf` function. If arguments are provided the chosen function + * is invoked with them and its result is returned. + * + * @private + * @returns {Function|number} Returns the chosen function or its result. + */ + function getIndexOf(collection, target, fromIndex) { + var result = lodash.indexOf || indexOf; + result = result === indexOf ? baseIndexOf : result; + return collection ? result(collection, target, fromIndex) : result; + } -SHA1.blockSize = 512; -SHA1.outSize = 160; -SHA1.hmacStrength = 80; + /** + * Gets the "length" property value of `object`. + * + * **Note:** This function is used to avoid a [JIT bug](https://bugs.webkit.org/show_bug.cgi?id=142792) + * that affects Safari on at least iOS 8.1-8.3 ARM64. + * + * @private + * @param {Object} object The object to query. + * @returns {*} Returns the "length" value. + */ + var getLength = baseProperty('length'); -SHA1.prototype._update = function _update(msg, start) { - var W = this.W; + /** + * Gets the propery names, values, and compare flags of `object`. + * + * @private + * @param {Object} object The object to query. + * @returns {Array} Returns the match data of `object`. + */ + function getMatchData(object) { + var result = pairs(object), + length = result.length; - for (var i = 0; i < 16; i++) - W[i] = msg[start + i]; + while (length--) { + result[length][2] = isStrictComparable(result[length][1]); + } + return result; + } - for(; i < W.length; i++) - W[i] = rotl32(W[i - 3] ^ W[i - 8] ^ W[i - 14] ^ W[i - 16], 1); + /** + * Gets the native function at `key` of `object`. + * + * @private + * @param {Object} object The object to query. + * @param {string} key The key of the method to get. + * @returns {*} Returns the function if it's native, else `undefined`. + */ + function getNative(object, key) { + var value = object == null ? undefined : object[key]; + return isNative(value) ? value : undefined; + } - var a = this.h[0]; - var b = this.h[1]; - var c = this.h[2]; - var d = this.h[3]; - var e = this.h[4]; + /** + * Gets the view, applying any `transforms` to the `start` and `end` positions. + * + * @private + * @param {number} start The start of the view. + * @param {number} end The end of the view. + * @param {Array} transforms The transformations to apply to the view. + * @returns {Object} Returns an object containing the `start` and `end` + * positions of the view. + */ + function getView(start, end, transforms) { + var index = -1, + length = transforms.length; - for (var i = 0; i < W.length; i++) { - var s = ~~(i / 20); - var t = sum32_5(rotl32(a, 5), ft_1(s, b, c, d), e, W[i], sha1_K[s]); - e = d; - d = c; - c = rotl32(b, 30); - b = a; - a = t; - } + while (++index < length) { + var data = transforms[index], + size = data.size; + + switch (data.type) { + case 'drop': start += size; break; + case 'dropRight': end -= size; break; + case 'take': end = nativeMin(end, start + size); break; + case 'takeRight': start = nativeMax(start, end - size); break; + } + } + return { 'start': start, 'end': end }; + } - this.h[0] = sum32(this.h[0], a); - this.h[1] = sum32(this.h[1], b); - this.h[2] = sum32(this.h[2], c); - this.h[3] = sum32(this.h[3], d); - this.h[4] = sum32(this.h[4], e); -}; + /** + * Initializes an array clone. + * + * @private + * @param {Array} array The array to clone. + * @returns {Array} Returns the initialized clone. + */ + function initCloneArray(array) { + var length = array.length, + result = new array.constructor(length); + + // Add array properties assigned by `RegExp#exec`. + if (length && typeof array[0] == 'string' && hasOwnProperty.call(array, 'index')) { + result.index = array.index; + result.input = array.input; + } + return result; + } -SHA1.prototype._digest = function digest(enc) { - if (enc === 'hex') - return utils.toHex32(this.h, 'big'); - else - return utils.split32(this.h, 'big'); -}; + /** + * Initializes an object clone. + * + * @private + * @param {Object} object The object to clone. + * @returns {Object} Returns the initialized clone. + */ + function initCloneObject(object) { + var Ctor = object.constructor; + if (!(typeof Ctor == 'function' && Ctor instanceof Ctor)) { + Ctor = Object; + } + return new Ctor; + } -function ch32(x, y, z) { - return (x & y) ^ ((~x) & z); -} + /** + * Initializes an object clone based on its `toStringTag`. + * + * **Note:** This function only supports cloning values with tags of + * `Boolean`, `Date`, `Error`, `Number`, `RegExp`, or `String`. + * + * @private + * @param {Object} object The object to clone. + * @param {string} tag The `toStringTag` of the object to clone. + * @param {boolean} [isDeep] Specify a deep clone. + * @returns {Object} Returns the initialized clone. + */ + function initCloneByTag(object, tag, isDeep) { + var Ctor = object.constructor; + switch (tag) { + case arrayBufferTag: + return bufferClone(object); + + case boolTag: + case dateTag: + return new Ctor(+object); + + case float32Tag: case float64Tag: + case int8Tag: case int16Tag: case int32Tag: + case uint8Tag: case uint8ClampedTag: case uint16Tag: case uint32Tag: + var buffer = object.buffer; + return new Ctor(isDeep ? bufferClone(buffer) : buffer, object.byteOffset, object.length); + + case numberTag: + case stringTag: + return new Ctor(object); + + case regexpTag: + var result = new Ctor(object.source, reFlags.exec(object)); + result.lastIndex = object.lastIndex; + } + return result; + } -function maj32(x, y, z) { - return (x & y) ^ (x & z) ^ (y & z); -} + /** + * Invokes the method at `path` on `object`. + * + * @private + * @param {Object} object The object to query. + * @param {Array|string} path The path of the method to invoke. + * @param {Array} args The arguments to invoke the method with. + * @returns {*} Returns the result of the invoked method. + */ + function invokePath(object, path, args) { + if (object != null && !isKey(path, object)) { + path = toPath(path); + object = path.length == 1 ? object : baseGet(object, baseSlice(path, 0, -1)); + path = last(path); + } + var func = object == null ? object : object[path]; + return func == null ? undefined : func.apply(object, args); + } -function p32(x, y, z) { - return x ^ y ^ z; -} + /** + * Checks if `value` is array-like. + * + * @private + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is array-like, else `false`. + */ + function isArrayLike(value) { + return value != null && isLength(getLength(value)); + } -function s0_256(x) { - return rotr32(x, 2) ^ rotr32(x, 13) ^ rotr32(x, 22); -} + /** + * Checks if `value` is a valid array-like index. + * + * @private + * @param {*} value The value to check. + * @param {number} [length=MAX_SAFE_INTEGER] The upper bounds of a valid index. + * @returns {boolean} Returns `true` if `value` is a valid index, else `false`. + */ + function isIndex(value, length) { + value = (typeof value == 'number' || reIsUint.test(value)) ? +value : -1; + length = length == null ? MAX_SAFE_INTEGER : length; + return value > -1 && value % 1 == 0 && value < length; + } -function s1_256(x) { - return rotr32(x, 6) ^ rotr32(x, 11) ^ rotr32(x, 25); -} + /** + * Checks if the provided arguments are from an iteratee call. + * + * @private + * @param {*} value The potential iteratee value argument. + * @param {*} index The potential iteratee index or key argument. + * @param {*} object The potential iteratee object argument. + * @returns {boolean} Returns `true` if the arguments are from an iteratee call, else `false`. + */ + function isIterateeCall(value, index, object) { + if (!isObject(object)) { + return false; + } + var type = typeof index; + if (type == 'number' + ? (isArrayLike(object) && isIndex(index, object.length)) + : (type == 'string' && index in object)) { + var other = object[index]; + return value === value ? (value === other) : (other !== other); + } + return false; + } -function g0_256(x) { - return rotr32(x, 7) ^ rotr32(x, 18) ^ (x >>> 3); -} + /** + * Checks if `value` is a property name and not a property path. + * + * @private + * @param {*} value The value to check. + * @param {Object} [object] The object to query keys on. + * @returns {boolean} Returns `true` if `value` is a property name, else `false`. + */ + function isKey(value, object) { + var type = typeof value; + if ((type == 'string' && reIsPlainProp.test(value)) || type == 'number') { + return true; + } + if (isArray(value)) { + return false; + } + var result = !reIsDeepProp.test(value); + return result || (object != null && value in toObject(object)); + } -function g1_256(x) { - return rotr32(x, 17) ^ rotr32(x, 19) ^ (x >>> 10); -} + /** + * Checks if `func` has a lazy counterpart. + * + * @private + * @param {Function} func The function to check. + * @returns {boolean} Returns `true` if `func` has a lazy counterpart, else `false`. + */ + function isLaziable(func) { + var funcName = getFuncName(func); + if (!(funcName in LazyWrapper.prototype)) { + return false; + } + var other = lodash[funcName]; + if (func === other) { + return true; + } + var data = getData(other); + return !!data && func === data[0]; + } -function ft_1(s, x, y, z) { - if (s === 0) - return ch32(x, y, z); - if (s === 1 || s === 3) - return p32(x, y, z) - if (s === 2) - return maj32(x, y, z) -} + /** + * Checks if `value` is a valid array-like length. + * + * **Note:** This function is based on [`ToLength`](http://ecma-international.org/ecma-262/6.0/#sec-tolength). + * + * @private + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a valid length, else `false`. + */ + function isLength(value) { + return typeof value == 'number' && value > -1 && value % 1 == 0 && value <= MAX_SAFE_INTEGER; + } -},{"../hash":223}],228:[function(require,module,exports){ -var utils = exports; -var inherits = require('inherits'); + /** + * Checks if `value` is suitable for strict equality comparisons, i.e. `===`. + * + * @private + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` if suitable for strict + * equality comparisons, else `false`. + */ + function isStrictComparable(value) { + return value === value && !isObject(value); + } -function toArray(msg, enc) { - if (Array.isArray(msg)) - return msg.slice(); - if (!msg) - return []; - var res = []; - if (typeof msg === 'string') { - if (!enc) { - for (var i = 0; i < msg.length; i++) { - var c = msg.charCodeAt(i); - var hi = c >> 8; - var lo = c & 0xff; - if (hi) - res.push(hi, lo); - else - res.push(lo); + /** + * Merges the function metadata of `source` into `data`. + * + * Merging metadata reduces the number of wrappers required to invoke a function. + * This is possible because methods like `_.bind`, `_.curry`, and `_.partial` + * may be applied regardless of execution order. Methods like `_.ary` and `_.rearg` + * augment function arguments, making the order in which they are executed important, + * preventing the merging of metadata. However, we make an exception for a safe + * common case where curried functions have `_.ary` and or `_.rearg` applied. + * + * @private + * @param {Array} data The destination metadata. + * @param {Array} source The source metadata. + * @returns {Array} Returns `data`. + */ + function mergeData(data, source) { + var bitmask = data[1], + srcBitmask = source[1], + newBitmask = bitmask | srcBitmask, + isCommon = newBitmask < ARY_FLAG; + + var isCombo = + (srcBitmask == ARY_FLAG && bitmask == CURRY_FLAG) || + (srcBitmask == ARY_FLAG && bitmask == REARG_FLAG && data[7].length <= source[8]) || + (srcBitmask == (ARY_FLAG | REARG_FLAG) && bitmask == CURRY_FLAG); + + // Exit early if metadata can't be merged. + if (!(isCommon || isCombo)) { + return data; } - } else if (enc === 'hex') { - msg = msg.replace(/[^a-z0-9]+/ig, ''); - if (msg.length % 2 != 0) - msg = '0' + msg; - for (var i = 0; i < msg.length; i += 2) - res.push(parseInt(msg[i] + msg[i + 1], 16)); - } - } else { - for (var i = 0; i < msg.length; i++) - res[i] = msg[i] | 0; - } - return res; -} -utils.toArray = toArray; + // Use source `thisArg` if available. + if (srcBitmask & BIND_FLAG) { + data[2] = source[2]; + // Set when currying a bound function. + newBitmask |= (bitmask & BIND_FLAG) ? 0 : CURRY_BOUND_FLAG; + } + // Compose partial arguments. + var value = source[3]; + if (value) { + var partials = data[3]; + data[3] = partials ? composeArgs(partials, value, source[4]) : arrayCopy(value); + data[4] = partials ? replaceHolders(data[3], PLACEHOLDER) : arrayCopy(source[4]); + } + // Compose partial right arguments. + value = source[5]; + if (value) { + partials = data[5]; + data[5] = partials ? composeArgsRight(partials, value, source[6]) : arrayCopy(value); + data[6] = partials ? replaceHolders(data[5], PLACEHOLDER) : arrayCopy(source[6]); + } + // Use source `argPos` if available. + value = source[7]; + if (value) { + data[7] = arrayCopy(value); + } + // Use source `ary` if it's smaller. + if (srcBitmask & ARY_FLAG) { + data[8] = data[8] == null ? source[8] : nativeMin(data[8], source[8]); + } + // Use source `arity` if one is not provided. + if (data[9] == null) { + data[9] = source[9]; + } + // Use source `func` and merge bitmasks. + data[0] = source[0]; + data[1] = newBitmask; -function toHex(msg) { - var res = ''; - for (var i = 0; i < msg.length; i++) - res += zero2(msg[i].toString(16)); - return res; -} -utils.toHex = toHex; + return data; + } -function toHex32(msg, endian) { - var res = ''; - for (var i = 0; i < msg.length; i++) { - var w = msg[i]; - if (endian === 'little') { - w = (w >>> 24) | - ((w >>> 8) & 0xff00) | - ((w << 8) & 0xff0000) | - ((w & 0xff) << 24); - if (w < 0) - w += 0x100000000; + /** + * Used by `_.defaultsDeep` to customize its `_.merge` use. + * + * @private + * @param {*} objectValue The destination object property value. + * @param {*} sourceValue The source object property value. + * @returns {*} Returns the value to assign to the destination object. + */ + function mergeDefaults(objectValue, sourceValue) { + return objectValue === undefined ? sourceValue : merge(objectValue, sourceValue, mergeDefaults); } - res += zero8(w.toString(16)); - } - return res; -} -utils.toHex32 = toHex32; -function zero2(word) { - if (word.length === 1) - return '0' + word; - else - return word; -} -utils.zero2 = zero2; + /** + * A specialized version of `_.pick` which picks `object` properties specified + * by `props`. + * + * @private + * @param {Object} object The source object. + * @param {string[]} props The property names to pick. + * @returns {Object} Returns the new object. + */ + function pickByArray(object, props) { + object = toObject(object); -function zero8(word) { - if (word.length === 7) - return '0' + word; - else if (word.length === 6) - return '00' + word; - else if (word.length === 5) - return '000' + word; - else if (word.length === 4) - return '0000' + word; - else if (word.length === 3) - return '00000' + word; - else if (word.length === 2) - return '000000' + word; - else if (word.length === 1) - return '0000000' + word; - else - return word; -} -utils.zero8 = zero8; + var index = -1, + length = props.length, + result = {}; -function join32(msg, start, end, endian) { - var len = end - start; - assert(len % 4 === 0); - var res = new Array(len / 4); - for (var i = 0, k = start; i < res.length; i++, k += 4) { - var w; - if (endian === 'big') - w = (msg[k] << 24) | (msg[k + 1] << 16) | (msg[k + 2] << 8) | msg[k + 3]; - else - w = (msg[k + 3] << 24) | (msg[k + 2] << 16) | (msg[k + 1] << 8) | msg[k]; - if (w < 0) - w += 0x100000000; - res[i] = w; - } - return res; -} -utils.join32 = join32; + while (++index < length) { + var key = props[index]; + if (key in object) { + result[key] = object[key]; + } + } + return result; + } -function split32(msg, endian) { - var res = new Array(msg.length * 4); - for (var i = 0, k = 0; i < msg.length; i++, k += 4) { - var m = msg[i]; - if (endian === 'big') { - res[k] = m >>> 24; - res[k + 1] = (m >>> 16) & 0xff; - res[k + 2] = (m >>> 8) & 0xff; - res[k + 3] = m & 0xff; - } else { - res[k + 3] = m >>> 24; - res[k + 2] = (m >>> 16) & 0xff; - res[k + 1] = (m >>> 8) & 0xff; - res[k] = m & 0xff; + /** + * A specialized version of `_.pick` which picks `object` properties `predicate` + * returns truthy for. + * + * @private + * @param {Object} object The source object. + * @param {Function} predicate The function invoked per iteration. + * @returns {Object} Returns the new object. + */ + function pickByCallback(object, predicate) { + var result = {}; + baseForIn(object, function(value, key, object) { + if (predicate(value, key, object)) { + result[key] = value; + } + }); + return result; } - } - return res; -} -utils.split32 = split32; -function rotr32(w, b) { - return (w >>> b) | (w << (32 - b)); -} -utils.rotr32 = rotr32; + /** + * Reorder `array` according to the specified indexes where the element at + * the first index is assigned as the first element, the element at + * the second index is assigned as the second element, and so on. + * + * @private + * @param {Array} array The array to reorder. + * @param {Array} indexes The arranged array indexes. + * @returns {Array} Returns `array`. + */ + function reorder(array, indexes) { + var arrLength = array.length, + length = nativeMin(indexes.length, arrLength), + oldArray = arrayCopy(array); + + while (length--) { + var index = indexes[length]; + array[length] = isIndex(index, arrLength) ? oldArray[index] : undefined; + } + return array; + } + + /** + * Sets metadata for `func`. + * + * **Note:** If this function becomes hot, i.e. is invoked a lot in a short + * period of time, it will trip its breaker and transition to an identity function + * to avoid garbage collection pauses in V8. See [V8 issue 2070](https://code.google.com/p/v8/issues/detail?id=2070) + * for more details. + * + * @private + * @param {Function} func The function to associate metadata with. + * @param {*} data The metadata. + * @returns {Function} Returns `func`. + */ + var setData = (function() { + var count = 0, + lastCalled = 0; + + return function(key, value) { + var stamp = now(), + remaining = HOT_SPAN - (stamp - lastCalled); + + lastCalled = stamp; + if (remaining > 0) { + if (++count >= HOT_COUNT) { + return key; + } + } else { + count = 0; + } + return baseSetData(key, value); + }; + }()); + + /** + * A fallback implementation of `Object.keys` which creates an array of the + * own enumerable property names of `object`. + * + * @private + * @param {Object} object The object to query. + * @returns {Array} Returns the array of property names. + */ + function shimKeys(object) { + var props = keysIn(object), + propsLength = props.length, + length = propsLength && object.length; -function rotl32(w, b) { - return (w << b) | (w >>> (32 - b)); -} -utils.rotl32 = rotl32; + var allowIndexes = !!length && isLength(length) && + (isArray(object) || isArguments(object)); -function sum32(a, b) { - var r = (a + b) & 0xffffffff; - if (r < 0) - r += 0x100000000; - return r; -} -utils.sum32 = sum32; + var index = -1, + result = []; -function sum32_3(a, b, c) { - var r = (a + b + c) & 0xffffffff; - if (r < 0) - r += 0x100000000; - return r; -} -utils.sum32_3 = sum32_3; + while (++index < propsLength) { + var key = props[index]; + if ((allowIndexes && isIndex(key, length)) || hasOwnProperty.call(object, key)) { + result.push(key); + } + } + return result; + } -function sum32_4(a, b, c, d) { - var r = (a + b + c + d) & 0xffffffff; - if (r < 0) - r += 0x100000000; - return r; -} -utils.sum32_4 = sum32_4; + /** + * Converts `value` to an array-like object if it's not one. + * + * @private + * @param {*} value The value to process. + * @returns {Array|Object} Returns the array-like object. + */ + function toIterable(value) { + if (value == null) { + return []; + } + if (!isArrayLike(value)) { + return values(value); + } + return isObject(value) ? value : Object(value); + } -function sum32_5(a, b, c, d, e) { - var r = (a + b + c + d + e) & 0xffffffff; - if (r < 0) - r += 0x100000000; - return r; -} -utils.sum32_5 = sum32_5; + /** + * Converts `value` to an object if it's not one. + * + * @private + * @param {*} value The value to process. + * @returns {Object} Returns the object. + */ + function toObject(value) { + return isObject(value) ? value : Object(value); + } -function assert(cond, msg) { - if (!cond) - throw new Error(msg || 'Assertion failed'); -} -utils.assert = assert; + /** + * Converts `value` to property path array if it's not one. + * + * @private + * @param {*} value The value to process. + * @returns {Array} Returns the property path array. + */ + function toPath(value) { + if (isArray(value)) { + return value; + } + var result = []; + baseToString(value).replace(rePropName, function(match, number, quote, string) { + result.push(quote ? string.replace(reEscapeChar, '$1') : (number || match)); + }); + return result; + } -utils.inherits = inherits; + /** + * Creates a clone of `wrapper`. + * + * @private + * @param {Object} wrapper The wrapper to clone. + * @returns {Object} Returns the cloned wrapper. + */ + function wrapperClone(wrapper) { + return wrapper instanceof LazyWrapper + ? wrapper.clone() + : new LodashWrapper(wrapper.__wrapped__, wrapper.__chain__, arrayCopy(wrapper.__actions__)); + } -},{"inherits":229}],229:[function(require,module,exports){ -if (typeof Object.create === 'function') { - // implementation from standard node.js 'util' module - module.exports = function inherits(ctor, superCtor) { - ctor.super_ = superCtor - ctor.prototype = Object.create(superCtor.prototype, { - constructor: { - value: ctor, - enumerable: false, - writable: true, - configurable: true + /*------------------------------------------------------------------------*/ + + /** + * Creates an array of elements split into groups the length of `size`. + * If `collection` can't be split evenly, the final chunk will be the remaining + * elements. + * + * @static + * @memberOf _ + * @category Array + * @param {Array} array The array to process. + * @param {number} [size=1] The length of each chunk. + * @param- {Object} [guard] Enables use as a callback for functions like `_.map`. + * @returns {Array} Returns the new array containing chunks. + * @example + * + * _.chunk(['a', 'b', 'c', 'd'], 2); + * // => [['a', 'b'], ['c', 'd']] + * + * _.chunk(['a', 'b', 'c', 'd'], 3); + * // => [['a', 'b', 'c'], ['d']] + */ + function chunk(array, size, guard) { + if (guard ? isIterateeCall(array, size, guard) : size == null) { + size = 1; + } else { + size = nativeMax(nativeFloor(size) || 1, 1); } - }); - }; -} else { - // old school shim for old browsers - module.exports = function inherits(ctor, superCtor) { - ctor.super_ = superCtor - var TempCtor = function () {} - TempCtor.prototype = superCtor.prototype - ctor.prototype = new TempCtor() - ctor.prototype.constructor = ctor - } -} + var index = 0, + length = array ? array.length : 0, + resIndex = -1, + result = Array(nativeCeil(length / size)); -},{}],230:[function(require,module,exports){ -(function (global){ -/** - * @license - * Lo-Dash 2.4.1 (Custom Build) - * Build: `lodash modern -o ./dist/lodash.js` - * Copyright 2012-2013 The Dojo Foundation - * Based on Underscore.js 1.5.2 - * Copyright 2009-2013 Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors - * Available under MIT license - */ -;(function() { + while (index < length) { + result[++resIndex] = baseSlice(array, index, (index += size)); + } + return result; + } - /** Used as a safe reference for `undefined` in pre ES5 environments */ - var undefined; + /** + * Creates an array with all falsey values removed. The values `false`, `null`, + * `0`, `""`, `undefined`, and `NaN` are falsey. + * + * @static + * @memberOf _ + * @category Array + * @param {Array} array The array to compact. + * @returns {Array} Returns the new array of filtered values. + * @example + * + * _.compact([0, 1, false, 2, '', 3]); + * // => [1, 2, 3] + */ + function compact(array) { + var index = -1, + length = array ? array.length : 0, + resIndex = -1, + result = []; + + while (++index < length) { + var value = array[index]; + if (value) { + result[++resIndex] = value; + } + } + return result; + } + + /** + * Creates an array of unique `array` values not included in the other + * provided arrays using [`SameValueZero`](http://ecma-international.org/ecma-262/6.0/#sec-samevaluezero) + * for equality comparisons. + * + * @static + * @memberOf _ + * @category Array + * @param {Array} array The array to inspect. + * @param {...Array} [values] The arrays of values to exclude. + * @returns {Array} Returns the new array of filtered values. + * @example + * + * _.difference([1, 2, 3], [4, 2]); + * // => [1, 3] + */ + var difference = restParam(function(array, values) { + return (isObjectLike(array) && isArrayLike(array)) + ? baseDifference(array, baseFlatten(values, false, true)) + : []; + }); - /** Used to pool arrays and objects used internally */ - var arrayPool = [], - objectPool = []; + /** + * Creates a slice of `array` with `n` elements dropped from the beginning. + * + * @static + * @memberOf _ + * @category Array + * @param {Array} array The array to query. + * @param {number} [n=1] The number of elements to drop. + * @param- {Object} [guard] Enables use as a callback for functions like `_.map`. + * @returns {Array} Returns the slice of `array`. + * @example + * + * _.drop([1, 2, 3]); + * // => [2, 3] + * + * _.drop([1, 2, 3], 2); + * // => [3] + * + * _.drop([1, 2, 3], 5); + * // => [] + * + * _.drop([1, 2, 3], 0); + * // => [1, 2, 3] + */ + function drop(array, n, guard) { + var length = array ? array.length : 0; + if (!length) { + return []; + } + if (guard ? isIterateeCall(array, n, guard) : n == null) { + n = 1; + } + return baseSlice(array, n < 0 ? 0 : n); + } - /** Used to generate unique IDs */ - var idCounter = 0; + /** + * Creates a slice of `array` with `n` elements dropped from the end. + * + * @static + * @memberOf _ + * @category Array + * @param {Array} array The array to query. + * @param {number} [n=1] The number of elements to drop. + * @param- {Object} [guard] Enables use as a callback for functions like `_.map`. + * @returns {Array} Returns the slice of `array`. + * @example + * + * _.dropRight([1, 2, 3]); + * // => [1, 2] + * + * _.dropRight([1, 2, 3], 2); + * // => [1] + * + * _.dropRight([1, 2, 3], 5); + * // => [] + * + * _.dropRight([1, 2, 3], 0); + * // => [1, 2, 3] + */ + function dropRight(array, n, guard) { + var length = array ? array.length : 0; + if (!length) { + return []; + } + if (guard ? isIterateeCall(array, n, guard) : n == null) { + n = 1; + } + n = length - (+n || 0); + return baseSlice(array, 0, n < 0 ? 0 : n); + } - /** Used to prefix keys to avoid issues with `__proto__` and properties on `Object.prototype` */ - var keyPrefix = +new Date + ''; + /** + * Creates a slice of `array` excluding elements dropped from the end. + * Elements are dropped until `predicate` returns falsey. The predicate is + * bound to `thisArg` and invoked with three arguments: (value, index, array). + * + * If a property name is provided for `predicate` the created `_.property` + * style callback returns the property value of the given element. + * + * If a value is also provided for `thisArg` the created `_.matchesProperty` + * style callback returns `true` for elements that have a matching property + * value, else `false`. + * + * If an object is provided for `predicate` the created `_.matches` style + * callback returns `true` for elements that match the properties of the given + * object, else `false`. + * + * @static + * @memberOf _ + * @category Array + * @param {Array} array The array to query. + * @param {Function|Object|string} [predicate=_.identity] The function invoked + * per iteration. + * @param {*} [thisArg] The `this` binding of `predicate`. + * @returns {Array} Returns the slice of `array`. + * @example + * + * _.dropRightWhile([1, 2, 3], function(n) { + * return n > 1; + * }); + * // => [1] + * + * var users = [ + * { 'user': 'barney', 'active': true }, + * { 'user': 'fred', 'active': false }, + * { 'user': 'pebbles', 'active': false } + * ]; + * + * // using the `_.matches` callback shorthand + * _.pluck(_.dropRightWhile(users, { 'user': 'pebbles', 'active': false }), 'user'); + * // => ['barney', 'fred'] + * + * // using the `_.matchesProperty` callback shorthand + * _.pluck(_.dropRightWhile(users, 'active', false), 'user'); + * // => ['barney'] + * + * // using the `_.property` callback shorthand + * _.pluck(_.dropRightWhile(users, 'active'), 'user'); + * // => ['barney', 'fred', 'pebbles'] + */ + function dropRightWhile(array, predicate, thisArg) { + return (array && array.length) + ? baseWhile(array, getCallback(predicate, thisArg, 3), true, true) + : []; + } - /** Used as the size when optimizations are enabled for large arrays */ - var largeArraySize = 75; + /** + * Creates a slice of `array` excluding elements dropped from the beginning. + * Elements are dropped until `predicate` returns falsey. The predicate is + * bound to `thisArg` and invoked with three arguments: (value, index, array). + * + * If a property name is provided for `predicate` the created `_.property` + * style callback returns the property value of the given element. + * + * If a value is also provided for `thisArg` the created `_.matchesProperty` + * style callback returns `true` for elements that have a matching property + * value, else `false`. + * + * If an object is provided for `predicate` the created `_.matches` style + * callback returns `true` for elements that have the properties of the given + * object, else `false`. + * + * @static + * @memberOf _ + * @category Array + * @param {Array} array The array to query. + * @param {Function|Object|string} [predicate=_.identity] The function invoked + * per iteration. + * @param {*} [thisArg] The `this` binding of `predicate`. + * @returns {Array} Returns the slice of `array`. + * @example + * + * _.dropWhile([1, 2, 3], function(n) { + * return n < 3; + * }); + * // => [3] + * + * var users = [ + * { 'user': 'barney', 'active': false }, + * { 'user': 'fred', 'active': false }, + * { 'user': 'pebbles', 'active': true } + * ]; + * + * // using the `_.matches` callback shorthand + * _.pluck(_.dropWhile(users, { 'user': 'barney', 'active': false }), 'user'); + * // => ['fred', 'pebbles'] + * + * // using the `_.matchesProperty` callback shorthand + * _.pluck(_.dropWhile(users, 'active', false), 'user'); + * // => ['pebbles'] + * + * // using the `_.property` callback shorthand + * _.pluck(_.dropWhile(users, 'active'), 'user'); + * // => ['barney', 'fred', 'pebbles'] + */ + function dropWhile(array, predicate, thisArg) { + return (array && array.length) + ? baseWhile(array, getCallback(predicate, thisArg, 3), true) + : []; + } - /** Used as the max size of the `arrayPool` and `objectPool` */ - var maxPoolSize = 40; + /** + * Fills elements of `array` with `value` from `start` up to, but not + * including, `end`. + * + * **Note:** This method mutates `array`. + * + * @static + * @memberOf _ + * @category Array + * @param {Array} array The array to fill. + * @param {*} value The value to fill `array` with. + * @param {number} [start=0] The start position. + * @param {number} [end=array.length] The end position. + * @returns {Array} Returns `array`. + * @example + * + * var array = [1, 2, 3]; + * + * _.fill(array, 'a'); + * console.log(array); + * // => ['a', 'a', 'a'] + * + * _.fill(Array(3), 2); + * // => [2, 2, 2] + * + * _.fill([4, 6, 8], '*', 1, 2); + * // => [4, '*', 8] + */ + function fill(array, value, start, end) { + var length = array ? array.length : 0; + if (!length) { + return []; + } + if (start && typeof start != 'number' && isIterateeCall(array, value, start)) { + start = 0; + end = length; + } + return baseFill(array, value, start, end); + } - /** Used to detect and test whitespace */ - var whitespace = ( - // whitespace - ' \t\x0B\f\xA0\ufeff' + + /** + * This method is like `_.find` except that it returns the index of the first + * element `predicate` returns truthy for instead of the element itself. + * + * If a property name is provided for `predicate` the created `_.property` + * style callback returns the property value of the given element. + * + * If a value is also provided for `thisArg` the created `_.matchesProperty` + * style callback returns `true` for elements that have a matching property + * value, else `false`. + * + * If an object is provided for `predicate` the created `_.matches` style + * callback returns `true` for elements that have the properties of the given + * object, else `false`. + * + * @static + * @memberOf _ + * @category Array + * @param {Array} array The array to search. + * @param {Function|Object|string} [predicate=_.identity] The function invoked + * per iteration. + * @param {*} [thisArg] The `this` binding of `predicate`. + * @returns {number} Returns the index of the found element, else `-1`. + * @example + * + * var users = [ + * { 'user': 'barney', 'active': false }, + * { 'user': 'fred', 'active': false }, + * { 'user': 'pebbles', 'active': true } + * ]; + * + * _.findIndex(users, function(chr) { + * return chr.user == 'barney'; + * }); + * // => 0 + * + * // using the `_.matches` callback shorthand + * _.findIndex(users, { 'user': 'fred', 'active': false }); + * // => 1 + * + * // using the `_.matchesProperty` callback shorthand + * _.findIndex(users, 'active', false); + * // => 0 + * + * // using the `_.property` callback shorthand + * _.findIndex(users, 'active'); + * // => 2 + */ + var findIndex = createFindIndex(); - // line terminators - '\n\r\u2028\u2029' + + /** + * This method is like `_.findIndex` except that it iterates over elements + * of `collection` from right to left. + * + * If a property name is provided for `predicate` the created `_.property` + * style callback returns the property value of the given element. + * + * If a value is also provided for `thisArg` the created `_.matchesProperty` + * style callback returns `true` for elements that have a matching property + * value, else `false`. + * + * If an object is provided for `predicate` the created `_.matches` style + * callback returns `true` for elements that have the properties of the given + * object, else `false`. + * + * @static + * @memberOf _ + * @category Array + * @param {Array} array The array to search. + * @param {Function|Object|string} [predicate=_.identity] The function invoked + * per iteration. + * @param {*} [thisArg] The `this` binding of `predicate`. + * @returns {number} Returns the index of the found element, else `-1`. + * @example + * + * var users = [ + * { 'user': 'barney', 'active': true }, + * { 'user': 'fred', 'active': false }, + * { 'user': 'pebbles', 'active': false } + * ]; + * + * _.findLastIndex(users, function(chr) { + * return chr.user == 'pebbles'; + * }); + * // => 2 + * + * // using the `_.matches` callback shorthand + * _.findLastIndex(users, { 'user': 'barney', 'active': true }); + * // => 0 + * + * // using the `_.matchesProperty` callback shorthand + * _.findLastIndex(users, 'active', false); + * // => 2 + * + * // using the `_.property` callback shorthand + * _.findLastIndex(users, 'active'); + * // => 0 + */ + var findLastIndex = createFindIndex(true); - // unicode category "Zs" space separators - '\u1680\u180e\u2000\u2001\u2002\u2003\u2004\u2005\u2006\u2007\u2008\u2009\u200a\u202f\u205f\u3000' - ); + /** + * Gets the first element of `array`. + * + * @static + * @memberOf _ + * @alias head + * @category Array + * @param {Array} array The array to query. + * @returns {*} Returns the first element of `array`. + * @example + * + * _.first([1, 2, 3]); + * // => 1 + * + * _.first([]); + * // => undefined + */ + function first(array) { + return array ? array[0] : undefined; + } - /** Used to match empty string literals in compiled template source */ - var reEmptyStringLeading = /\b__p \+= '';/g, - reEmptyStringMiddle = /\b(__p \+=) '' \+/g, - reEmptyStringTrailing = /(__e\(.*?\)|\b__t\)) \+\n'';/g; + /** + * Flattens a nested array. If `isDeep` is `true` the array is recursively + * flattened, otherwise it is only flattened a single level. + * + * @static + * @memberOf _ + * @category Array + * @param {Array} array The array to flatten. + * @param {boolean} [isDeep] Specify a deep flatten. + * @param- {Object} [guard] Enables use as a callback for functions like `_.map`. + * @returns {Array} Returns the new flattened array. + * @example + * + * _.flatten([1, [2, 3, [4]]]); + * // => [1, 2, 3, [4]] + * + * // using `isDeep` + * _.flatten([1, [2, 3, [4]]], true); + * // => [1, 2, 3, 4] + */ + function flatten(array, isDeep, guard) { + var length = array ? array.length : 0; + if (guard && isIterateeCall(array, isDeep, guard)) { + isDeep = false; + } + return length ? baseFlatten(array, isDeep) : []; + } - /** - * Used to match ES6 template delimiters - * http://people.mozilla.org/~jorendorff/es6-draft.html#sec-literals-string-literals - */ - var reEsTemplate = /\$\{([^\\}]*(?:\\.[^\\}]*)*)\}/g; + /** + * Recursively flattens a nested array. + * + * @static + * @memberOf _ + * @category Array + * @param {Array} array The array to recursively flatten. + * @returns {Array} Returns the new flattened array. + * @example + * + * _.flattenDeep([1, [2, 3, [4]]]); + * // => [1, 2, 3, 4] + */ + function flattenDeep(array) { + var length = array ? array.length : 0; + return length ? baseFlatten(array, true) : []; + } - /** Used to match regexp flags from their coerced string values */ - var reFlags = /\w*$/; + /** + * Gets the index at which the first occurrence of `value` is found in `array` + * using [`SameValueZero`](http://ecma-international.org/ecma-262/6.0/#sec-samevaluezero) + * for equality comparisons. If `fromIndex` is negative, it is used as the offset + * from the end of `array`. If `array` is sorted providing `true` for `fromIndex` + * performs a faster binary search. + * + * @static + * @memberOf _ + * @category Array + * @param {Array} array The array to search. + * @param {*} value The value to search for. + * @param {boolean|number} [fromIndex=0] The index to search from or `true` + * to perform a binary search on a sorted array. + * @returns {number} Returns the index of the matched value, else `-1`. + * @example + * + * _.indexOf([1, 2, 1, 2], 2); + * // => 1 + * + * // using `fromIndex` + * _.indexOf([1, 2, 1, 2], 2, 2); + * // => 3 + * + * // performing a binary search + * _.indexOf([1, 1, 2, 2], 2, true); + * // => 2 + */ + function indexOf(array, value, fromIndex) { + var length = array ? array.length : 0; + if (!length) { + return -1; + } + if (typeof fromIndex == 'number') { + fromIndex = fromIndex < 0 ? nativeMax(length + fromIndex, 0) : fromIndex; + } else if (fromIndex) { + var index = binaryIndex(array, value); + if (index < length && + (value === value ? (value === array[index]) : (array[index] !== array[index]))) { + return index; + } + return -1; + } + return baseIndexOf(array, value, fromIndex || 0); + } - /** Used to detected named functions */ - var reFuncName = /^\s*function[ \n\r\t]+\w/; + /** + * Gets all but the last element of `array`. + * + * @static + * @memberOf _ + * @category Array + * @param {Array} array The array to query. + * @returns {Array} Returns the slice of `array`. + * @example + * + * _.initial([1, 2, 3]); + * // => [1, 2] + */ + function initial(array) { + return dropRight(array, 1); + } - /** Used to match "interpolate" template delimiters */ - var reInterpolate = /<%=([\s\S]+?)%>/g; + /** + * Creates an array of unique values that are included in all of the provided + * arrays using [`SameValueZero`](http://ecma-international.org/ecma-262/6.0/#sec-samevaluezero) + * for equality comparisons. + * + * @static + * @memberOf _ + * @category Array + * @param {...Array} [arrays] The arrays to inspect. + * @returns {Array} Returns the new array of shared values. + * @example + * _.intersection([1, 2], [4, 2], [2, 1]); + * // => [2] + */ + var intersection = restParam(function(arrays) { + var othLength = arrays.length, + othIndex = othLength, + caches = Array(length), + indexOf = getIndexOf(), + isCommon = indexOf == baseIndexOf, + result = []; - /** Used to match leading whitespace and zeros to be removed */ - var reLeadingSpacesAndZeros = RegExp('^[' + whitespace + ']*0+(?=.$)'); + while (othIndex--) { + var value = arrays[othIndex] = isArrayLike(value = arrays[othIndex]) ? value : []; + caches[othIndex] = (isCommon && value.length >= 120) ? createCache(othIndex && value) : null; + } + var array = arrays[0], + index = -1, + length = array ? array.length : 0, + seen = caches[0]; - /** Used to ensure capturing order of template delimiters */ - var reNoMatch = /($^)/; + outer: + while (++index < length) { + value = array[index]; + if ((seen ? cacheIndexOf(seen, value) : indexOf(result, value, 0)) < 0) { + var othIndex = othLength; + while (--othIndex) { + var cache = caches[othIndex]; + if ((cache ? cacheIndexOf(cache, value) : indexOf(arrays[othIndex], value, 0)) < 0) { + continue outer; + } + } + if (seen) { + seen.push(value); + } + result.push(value); + } + } + return result; + }); - /** Used to detect functions containing a `this` reference */ - var reThis = /\bthis\b/; + /** + * Gets the last element of `array`. + * + * @static + * @memberOf _ + * @category Array + * @param {Array} array The array to query. + * @returns {*} Returns the last element of `array`. + * @example + * + * _.last([1, 2, 3]); + * // => 3 + */ + function last(array) { + var length = array ? array.length : 0; + return length ? array[length - 1] : undefined; + } - /** Used to match unescaped characters in compiled string literals */ - var reUnescapedString = /['\n\r\t\u2028\u2029\\]/g; + /** + * This method is like `_.indexOf` except that it iterates over elements of + * `array` from right to left. + * + * @static + * @memberOf _ + * @category Array + * @param {Array} array The array to search. + * @param {*} value The value to search for. + * @param {boolean|number} [fromIndex=array.length-1] The index to search from + * or `true` to perform a binary search on a sorted array. + * @returns {number} Returns the index of the matched value, else `-1`. + * @example + * + * _.lastIndexOf([1, 2, 1, 2], 2); + * // => 3 + * + * // using `fromIndex` + * _.lastIndexOf([1, 2, 1, 2], 2, 2); + * // => 1 + * + * // performing a binary search + * _.lastIndexOf([1, 1, 2, 2], 2, true); + * // => 3 + */ + function lastIndexOf(array, value, fromIndex) { + var length = array ? array.length : 0; + if (!length) { + return -1; + } + var index = length; + if (typeof fromIndex == 'number') { + index = (fromIndex < 0 ? nativeMax(length + fromIndex, 0) : nativeMin(fromIndex || 0, length - 1)) + 1; + } else if (fromIndex) { + index = binaryIndex(array, value, true) - 1; + var other = array[index]; + if (value === value ? (value === other) : (other !== other)) { + return index; + } + return -1; + } + if (value !== value) { + return indexOfNaN(array, index, true); + } + while (index--) { + if (array[index] === value) { + return index; + } + } + return -1; + } - /** Used to assign default `context` object properties */ - var contextProps = [ - 'Array', 'Boolean', 'Date', 'Function', 'Math', 'Number', 'Object', - 'RegExp', 'String', '_', 'attachEvent', 'clearTimeout', 'isFinite', 'isNaN', - 'parseInt', 'setTimeout' - ]; + /** + * Removes all provided values from `array` using + * [`SameValueZero`](http://ecma-international.org/ecma-262/6.0/#sec-samevaluezero) + * for equality comparisons. + * + * **Note:** Unlike `_.without`, this method mutates `array`. + * + * @static + * @memberOf _ + * @category Array + * @param {Array} array The array to modify. + * @param {...*} [values] The values to remove. + * @returns {Array} Returns `array`. + * @example + * + * var array = [1, 2, 3, 1, 2, 3]; + * + * _.pull(array, 2, 3); + * console.log(array); + * // => [1, 1] + */ + function pull() { + var args = arguments, + array = args[0]; - /** Used to make template sourceURLs easier to identify */ - var templateCounter = 0; - - /** `Object#toString` result shortcuts */ - var argsClass = '[object Arguments]', - arrayClass = '[object Array]', - boolClass = '[object Boolean]', - dateClass = '[object Date]', - funcClass = '[object Function]', - numberClass = '[object Number]', - objectClass = '[object Object]', - regexpClass = '[object RegExp]', - stringClass = '[object String]'; - - /** Used to identify object classifications that `_.clone` supports */ - var cloneableClasses = {}; - cloneableClasses[funcClass] = false; - cloneableClasses[argsClass] = cloneableClasses[arrayClass] = - cloneableClasses[boolClass] = cloneableClasses[dateClass] = - cloneableClasses[numberClass] = cloneableClasses[objectClass] = - cloneableClasses[regexpClass] = cloneableClasses[stringClass] = true; - - /** Used as an internal `_.debounce` options object */ - var debounceOptions = { - 'leading': false, - 'maxWait': 0, - 'trailing': false - }; + if (!(array && array.length)) { + return array; + } + var index = 0, + indexOf = getIndexOf(), + length = args.length; - /** Used as the property descriptor for `__bindData__` */ - var descriptor = { - 'configurable': false, - 'enumerable': false, - 'value': null, - 'writable': false - }; + while (++index < length) { + var fromIndex = 0, + value = args[index]; - /** Used to determine if values are of the language type Object */ - var objectTypes = { - 'boolean': false, - 'function': true, - 'object': true, - 'number': false, - 'string': false, - 'undefined': false - }; + while ((fromIndex = indexOf(array, value, fromIndex)) > -1) { + splice.call(array, fromIndex, 1); + } + } + return array; + } - /** Used to escape characters for inclusion in compiled string literals */ - var stringEscapes = { - '\\': '\\', - "'": "'", - '\n': 'n', - '\r': 'r', - '\t': 't', - '\u2028': 'u2028', - '\u2029': 'u2029' - }; + /** + * Removes elements from `array` corresponding to the given indexes and returns + * an array of the removed elements. Indexes may be specified as an array of + * indexes or as individual arguments. + * + * **Note:** Unlike `_.at`, this method mutates `array`. + * + * @static + * @memberOf _ + * @category Array + * @param {Array} array The array to modify. + * @param {...(number|number[])} [indexes] The indexes of elements to remove, + * specified as individual indexes or arrays of indexes. + * @returns {Array} Returns the new array of removed elements. + * @example + * + * var array = [5, 10, 15, 20]; + * var evens = _.pullAt(array, 1, 3); + * + * console.log(array); + * // => [5, 15] + * + * console.log(evens); + * // => [10, 20] + */ + var pullAt = restParam(function(array, indexes) { + indexes = baseFlatten(indexes); - /** Used as a reference to the global object */ - var root = (objectTypes[typeof window] && window) || this; + var result = baseAt(array, indexes); + basePullAt(array, indexes.sort(baseCompareAscending)); + return result; + }); - /** Detect free variable `exports` */ - var freeExports = objectTypes[typeof exports] && exports && !exports.nodeType && exports; + /** + * Removes all elements from `array` that `predicate` returns truthy for + * and returns an array of the removed elements. The predicate is bound to + * `thisArg` and invoked with three arguments: (value, index, array). + * + * If a property name is provided for `predicate` the created `_.property` + * style callback returns the property value of the given element. + * + * If a value is also provided for `thisArg` the created `_.matchesProperty` + * style callback returns `true` for elements that have a matching property + * value, else `false`. + * + * If an object is provided for `predicate` the created `_.matches` style + * callback returns `true` for elements that have the properties of the given + * object, else `false`. + * + * **Note:** Unlike `_.filter`, this method mutates `array`. + * + * @static + * @memberOf _ + * @category Array + * @param {Array} array The array to modify. + * @param {Function|Object|string} [predicate=_.identity] The function invoked + * per iteration. + * @param {*} [thisArg] The `this` binding of `predicate`. + * @returns {Array} Returns the new array of removed elements. + * @example + * + * var array = [1, 2, 3, 4]; + * var evens = _.remove(array, function(n) { + * return n % 2 == 0; + * }); + * + * console.log(array); + * // => [1, 3] + * + * console.log(evens); + * // => [2, 4] + */ + function remove(array, predicate, thisArg) { + var result = []; + if (!(array && array.length)) { + return result; + } + var index = -1, + indexes = [], + length = array.length; - /** Detect free variable `module` */ - var freeModule = objectTypes[typeof module] && module && !module.nodeType && module; + predicate = getCallback(predicate, thisArg, 3); + while (++index < length) { + var value = array[index]; + if (predicate(value, index, array)) { + result.push(value); + indexes.push(index); + } + } + basePullAt(array, indexes); + return result; + } - /** Detect the popular CommonJS extension `module.exports` */ - var moduleExports = freeModule && freeModule.exports === freeExports && freeExports; + /** + * Gets all but the first element of `array`. + * + * @static + * @memberOf _ + * @alias tail + * @category Array + * @param {Array} array The array to query. + * @returns {Array} Returns the slice of `array`. + * @example + * + * _.rest([1, 2, 3]); + * // => [2, 3] + */ + function rest(array) { + return drop(array, 1); + } - /** Detect free variable `global` from Node.js or Browserified code and use it as `root` */ - var freeGlobal = objectTypes[typeof global] && global; - if (freeGlobal && (freeGlobal.global === freeGlobal || freeGlobal.window === freeGlobal)) { - root = freeGlobal; - } + /** + * Creates a slice of `array` from `start` up to, but not including, `end`. + * + * **Note:** This method is used instead of `Array#slice` to support node + * lists in IE < 9 and to ensure dense arrays are returned. + * + * @static + * @memberOf _ + * @category Array + * @param {Array} array The array to slice. + * @param {number} [start=0] The start position. + * @param {number} [end=array.length] The end position. + * @returns {Array} Returns the slice of `array`. + */ + function slice(array, start, end) { + var length = array ? array.length : 0; + if (!length) { + return []; + } + if (end && typeof end != 'number' && isIterateeCall(array, start, end)) { + start = 0; + end = length; + } + return baseSlice(array, start, end); + } - /*--------------------------------------------------------------------------*/ + /** + * Uses a binary search to determine the lowest index at which `value` should + * be inserted into `array` in order to maintain its sort order. If an iteratee + * function is provided it is invoked for `value` and each element of `array` + * to compute their sort ranking. The iteratee is bound to `thisArg` and + * invoked with one argument; (value). + * + * If a property name is provided for `iteratee` the created `_.property` + * style callback returns the property value of the given element. + * + * If a value is also provided for `thisArg` the created `_.matchesProperty` + * style callback returns `true` for elements that have a matching property + * value, else `false`. + * + * If an object is provided for `iteratee` the created `_.matches` style + * callback returns `true` for elements that have the properties of the given + * object, else `false`. + * + * @static + * @memberOf _ + * @category Array + * @param {Array} array The sorted array to inspect. + * @param {*} value The value to evaluate. + * @param {Function|Object|string} [iteratee=_.identity] The function invoked + * per iteration. + * @param {*} [thisArg] The `this` binding of `iteratee`. + * @returns {number} Returns the index at which `value` should be inserted + * into `array`. + * @example + * + * _.sortedIndex([30, 50], 40); + * // => 1 + * + * _.sortedIndex([4, 4, 5, 5], 5); + * // => 2 + * + * var dict = { 'data': { 'thirty': 30, 'forty': 40, 'fifty': 50 } }; + * + * // using an iteratee function + * _.sortedIndex(['thirty', 'fifty'], 'forty', function(word) { + * return this.data[word]; + * }, dict); + * // => 1 + * + * // using the `_.property` callback shorthand + * _.sortedIndex([{ 'x': 30 }, { 'x': 50 }], { 'x': 40 }, 'x'); + * // => 1 + */ + var sortedIndex = createSortedIndex(); - /** - * The base implementation of `_.indexOf` without support for binary searches - * or `fromIndex` constraints. - * - * @private - * @param {Array} array The array to search. - * @param {*} value The value to search for. - * @param {number} [fromIndex=0] The index to search from. - * @returns {number} Returns the index of the matched value or `-1`. - */ - function baseIndexOf(array, value, fromIndex) { - var index = (fromIndex || 0) - 1, - length = array ? array.length : 0; + /** + * This method is like `_.sortedIndex` except that it returns the highest + * index at which `value` should be inserted into `array` in order to + * maintain its sort order. + * + * @static + * @memberOf _ + * @category Array + * @param {Array} array The sorted array to inspect. + * @param {*} value The value to evaluate. + * @param {Function|Object|string} [iteratee=_.identity] The function invoked + * per iteration. + * @param {*} [thisArg] The `this` binding of `iteratee`. + * @returns {number} Returns the index at which `value` should be inserted + * into `array`. + * @example + * + * _.sortedLastIndex([4, 4, 5, 5], 5); + * // => 4 + */ + var sortedLastIndex = createSortedIndex(true); - while (++index < length) { - if (array[index] === value) { - return index; + /** + * Creates a slice of `array` with `n` elements taken from the beginning. + * + * @static + * @memberOf _ + * @category Array + * @param {Array} array The array to query. + * @param {number} [n=1] The number of elements to take. + * @param- {Object} [guard] Enables use as a callback for functions like `_.map`. + * @returns {Array} Returns the slice of `array`. + * @example + * + * _.take([1, 2, 3]); + * // => [1] + * + * _.take([1, 2, 3], 2); + * // => [1, 2] + * + * _.take([1, 2, 3], 5); + * // => [1, 2, 3] + * + * _.take([1, 2, 3], 0); + * // => [] + */ + function take(array, n, guard) { + var length = array ? array.length : 0; + if (!length) { + return []; + } + if (guard ? isIterateeCall(array, n, guard) : n == null) { + n = 1; } + return baseSlice(array, 0, n < 0 ? 0 : n); } - return -1; - } - /** - * An implementation of `_.contains` for cache objects that mimics the return - * signature of `_.indexOf` by returning `0` if the value is found, else `-1`. - * - * @private - * @param {Object} cache The cache object to inspect. - * @param {*} value The value to search for. - * @returns {number} Returns `0` if `value` is found, else `-1`. - */ - function cacheIndexOf(cache, value) { - var type = typeof value; - cache = cache.cache; + /** + * Creates a slice of `array` with `n` elements taken from the end. + * + * @static + * @memberOf _ + * @category Array + * @param {Array} array The array to query. + * @param {number} [n=1] The number of elements to take. + * @param- {Object} [guard] Enables use as a callback for functions like `_.map`. + * @returns {Array} Returns the slice of `array`. + * @example + * + * _.takeRight([1, 2, 3]); + * // => [3] + * + * _.takeRight([1, 2, 3], 2); + * // => [2, 3] + * + * _.takeRight([1, 2, 3], 5); + * // => [1, 2, 3] + * + * _.takeRight([1, 2, 3], 0); + * // => [] + */ + function takeRight(array, n, guard) { + var length = array ? array.length : 0; + if (!length) { + return []; + } + if (guard ? isIterateeCall(array, n, guard) : n == null) { + n = 1; + } + n = length - (+n || 0); + return baseSlice(array, n < 0 ? 0 : n); + } - if (type == 'boolean' || value == null) { - return cache[value] ? 0 : -1; + /** + * Creates a slice of `array` with elements taken from the end. Elements are + * taken until `predicate` returns falsey. The predicate is bound to `thisArg` + * and invoked with three arguments: (value, index, array). + * + * If a property name is provided for `predicate` the created `_.property` + * style callback returns the property value of the given element. + * + * If a value is also provided for `thisArg` the created `_.matchesProperty` + * style callback returns `true` for elements that have a matching property + * value, else `false`. + * + * If an object is provided for `predicate` the created `_.matches` style + * callback returns `true` for elements that have the properties of the given + * object, else `false`. + * + * @static + * @memberOf _ + * @category Array + * @param {Array} array The array to query. + * @param {Function|Object|string} [predicate=_.identity] The function invoked + * per iteration. + * @param {*} [thisArg] The `this` binding of `predicate`. + * @returns {Array} Returns the slice of `array`. + * @example + * + * _.takeRightWhile([1, 2, 3], function(n) { + * return n > 1; + * }); + * // => [2, 3] + * + * var users = [ + * { 'user': 'barney', 'active': true }, + * { 'user': 'fred', 'active': false }, + * { 'user': 'pebbles', 'active': false } + * ]; + * + * // using the `_.matches` callback shorthand + * _.pluck(_.takeRightWhile(users, { 'user': 'pebbles', 'active': false }), 'user'); + * // => ['pebbles'] + * + * // using the `_.matchesProperty` callback shorthand + * _.pluck(_.takeRightWhile(users, 'active', false), 'user'); + * // => ['fred', 'pebbles'] + * + * // using the `_.property` callback shorthand + * _.pluck(_.takeRightWhile(users, 'active'), 'user'); + * // => [] + */ + function takeRightWhile(array, predicate, thisArg) { + return (array && array.length) + ? baseWhile(array, getCallback(predicate, thisArg, 3), false, true) + : []; } - if (type != 'number' && type != 'string') { - type = 'object'; + + /** + * Creates a slice of `array` with elements taken from the beginning. Elements + * are taken until `predicate` returns falsey. The predicate is bound to + * `thisArg` and invoked with three arguments: (value, index, array). + * + * If a property name is provided for `predicate` the created `_.property` + * style callback returns the property value of the given element. + * + * If a value is also provided for `thisArg` the created `_.matchesProperty` + * style callback returns `true` for elements that have a matching property + * value, else `false`. + * + * If an object is provided for `predicate` the created `_.matches` style + * callback returns `true` for elements that have the properties of the given + * object, else `false`. + * + * @static + * @memberOf _ + * @category Array + * @param {Array} array The array to query. + * @param {Function|Object|string} [predicate=_.identity] The function invoked + * per iteration. + * @param {*} [thisArg] The `this` binding of `predicate`. + * @returns {Array} Returns the slice of `array`. + * @example + * + * _.takeWhile([1, 2, 3], function(n) { + * return n < 3; + * }); + * // => [1, 2] + * + * var users = [ + * { 'user': 'barney', 'active': false }, + * { 'user': 'fred', 'active': false}, + * { 'user': 'pebbles', 'active': true } + * ]; + * + * // using the `_.matches` callback shorthand + * _.pluck(_.takeWhile(users, { 'user': 'barney', 'active': false }), 'user'); + * // => ['barney'] + * + * // using the `_.matchesProperty` callback shorthand + * _.pluck(_.takeWhile(users, 'active', false), 'user'); + * // => ['barney', 'fred'] + * + * // using the `_.property` callback shorthand + * _.pluck(_.takeWhile(users, 'active'), 'user'); + * // => [] + */ + function takeWhile(array, predicate, thisArg) { + return (array && array.length) + ? baseWhile(array, getCallback(predicate, thisArg, 3)) + : []; } - var key = type == 'number' ? value : keyPrefix + value; - cache = (cache = cache[type]) && cache[key]; - return type == 'object' - ? (cache && baseIndexOf(cache, value) > -1 ? 0 : -1) - : (cache ? 0 : -1); - } + /** + * Creates an array of unique values, in order, from all of the provided arrays + * using [`SameValueZero`](http://ecma-international.org/ecma-262/6.0/#sec-samevaluezero) + * for equality comparisons. + * + * @static + * @memberOf _ + * @category Array + * @param {...Array} [arrays] The arrays to inspect. + * @returns {Array} Returns the new array of combined values. + * @example + * + * _.union([1, 2], [4, 2], [2, 1]); + * // => [1, 2, 4] + */ + var union = restParam(function(arrays) { + return baseUniq(baseFlatten(arrays, false, true)); + }); - /** - * Adds a given value to the corresponding cache object. - * - * @private - * @param {*} value The value to add to the cache. - */ - function cachePush(value) { - var cache = this.cache, - type = typeof value; + /** + * Creates a duplicate-free version of an array, using + * [`SameValueZero`](http://ecma-international.org/ecma-262/6.0/#sec-samevaluezero) + * for equality comparisons, in which only the first occurence of each element + * is kept. Providing `true` for `isSorted` performs a faster search algorithm + * for sorted arrays. If an iteratee function is provided it is invoked for + * each element in the array to generate the criterion by which uniqueness + * is computed. The `iteratee` is bound to `thisArg` and invoked with three + * arguments: (value, index, array). + * + * If a property name is provided for `iteratee` the created `_.property` + * style callback returns the property value of the given element. + * + * If a value is also provided for `thisArg` the created `_.matchesProperty` + * style callback returns `true` for elements that have a matching property + * value, else `false`. + * + * If an object is provided for `iteratee` the created `_.matches` style + * callback returns `true` for elements that have the properties of the given + * object, else `false`. + * + * @static + * @memberOf _ + * @alias unique + * @category Array + * @param {Array} array The array to inspect. + * @param {boolean} [isSorted] Specify the array is sorted. + * @param {Function|Object|string} [iteratee] The function invoked per iteration. + * @param {*} [thisArg] The `this` binding of `iteratee`. + * @returns {Array} Returns the new duplicate-value-free array. + * @example + * + * _.uniq([2, 1, 2]); + * // => [2, 1] + * + * // using `isSorted` + * _.uniq([1, 1, 2], true); + * // => [1, 2] + * + * // using an iteratee function + * _.uniq([1, 2.5, 1.5, 2], function(n) { + * return this.floor(n); + * }, Math); + * // => [1, 2.5] + * + * // using the `_.property` callback shorthand + * _.uniq([{ 'x': 1 }, { 'x': 2 }, { 'x': 1 }], 'x'); + * // => [{ 'x': 1 }, { 'x': 2 }] + */ + function uniq(array, isSorted, iteratee, thisArg) { + var length = array ? array.length : 0; + if (!length) { + return []; + } + if (isSorted != null && typeof isSorted != 'boolean') { + thisArg = iteratee; + iteratee = isIterateeCall(array, isSorted, thisArg) ? undefined : isSorted; + isSorted = false; + } + var callback = getCallback(); + if (!(iteratee == null && callback === baseCallback)) { + iteratee = callback(iteratee, thisArg, 3); + } + return (isSorted && getIndexOf() == baseIndexOf) + ? sortedUniq(array, iteratee) + : baseUniq(array, iteratee); + } - if (type == 'boolean' || value == null) { - cache[value] = true; - } else { - if (type != 'number' && type != 'string') { - type = 'object'; + /** + * This method is like `_.zip` except that it accepts an array of grouped + * elements and creates an array regrouping the elements to their pre-zip + * configuration. + * + * @static + * @memberOf _ + * @category Array + * @param {Array} array The array of grouped elements to process. + * @returns {Array} Returns the new array of regrouped elements. + * @example + * + * var zipped = _.zip(['fred', 'barney'], [30, 40], [true, false]); + * // => [['fred', 30, true], ['barney', 40, false]] + * + * _.unzip(zipped); + * // => [['fred', 'barney'], [30, 40], [true, false]] + */ + function unzip(array) { + if (!(array && array.length)) { + return []; } - var key = type == 'number' ? value : keyPrefix + value, - typeCache = cache[type] || (cache[type] = {}); + var index = -1, + length = 0; - if (type == 'object') { - (typeCache[key] || (typeCache[key] = [])).push(value); - } else { - typeCache[key] = true; + array = arrayFilter(array, function(group) { + if (isArrayLike(group)) { + length = nativeMax(group.length, length); + return true; + } + }); + var result = Array(length); + while (++index < length) { + result[index] = arrayMap(array, baseProperty(index)); } + return result; } - } - /** - * Used by `_.max` and `_.min` as the default callback when a given - * collection is a string value. - * - * @private - * @param {string} value The character to inspect. - * @returns {number} Returns the code unit of given character. - */ - function charAtCallback(value) { - return value.charCodeAt(0); - } + /** + * This method is like `_.unzip` except that it accepts an iteratee to specify + * how regrouped values should be combined. The `iteratee` is bound to `thisArg` + * and invoked with four arguments: (accumulator, value, index, group). + * + * @static + * @memberOf _ + * @category Array + * @param {Array} array The array of grouped elements to process. + * @param {Function} [iteratee] The function to combine regrouped values. + * @param {*} [thisArg] The `this` binding of `iteratee`. + * @returns {Array} Returns the new array of regrouped elements. + * @example + * + * var zipped = _.zip([1, 2], [10, 20], [100, 200]); + * // => [[1, 10, 100], [2, 20, 200]] + * + * _.unzipWith(zipped, _.add); + * // => [3, 30, 300] + */ + function unzipWith(array, iteratee, thisArg) { + var length = array ? array.length : 0; + if (!length) { + return []; + } + var result = unzip(array); + if (iteratee == null) { + return result; + } + iteratee = bindCallback(iteratee, thisArg, 4); + return arrayMap(result, function(group) { + return arrayReduce(group, iteratee, undefined, true); + }); + } - /** - * Used by `sortBy` to compare transformed `collection` elements, stable sorting - * them in ascending order. - * - * @private - * @param {Object} a The object to compare to `b`. - * @param {Object} b The object to compare to `a`. - * @returns {number} Returns the sort order indicator of `1` or `-1`. - */ - function compareAscending(a, b) { - var ac = a.criteria, - bc = b.criteria, - index = -1, - length = ac.length; + /** + * Creates an array excluding all provided values using + * [`SameValueZero`](http://ecma-international.org/ecma-262/6.0/#sec-samevaluezero) + * for equality comparisons. + * + * @static + * @memberOf _ + * @category Array + * @param {Array} array The array to filter. + * @param {...*} [values] The values to exclude. + * @returns {Array} Returns the new array of filtered values. + * @example + * + * _.without([1, 2, 1, 3], 1, 2); + * // => [3] + */ + var without = restParam(function(array, values) { + return isArrayLike(array) + ? baseDifference(array, values) + : []; + }); - while (++index < length) { - var value = ac[index], - other = bc[index]; + /** + * Creates an array of unique values that is the [symmetric difference](https://en.wikipedia.org/wiki/Symmetric_difference) + * of the provided arrays. + * + * @static + * @memberOf _ + * @category Array + * @param {...Array} [arrays] The arrays to inspect. + * @returns {Array} Returns the new array of values. + * @example + * + * _.xor([1, 2], [4, 2]); + * // => [1, 4] + */ + function xor() { + var index = -1, + length = arguments.length; - if (value !== other) { - if (value > other || typeof value == 'undefined') { - return 1; - } - if (value < other || typeof other == 'undefined') { - return -1; + while (++index < length) { + var array = arguments[index]; + if (isArrayLike(array)) { + var result = result + ? arrayPush(baseDifference(result, array), baseDifference(array, result)) + : array; } } + return result ? baseUniq(result) : []; } - // Fixes an `Array#sort` bug in the JS engine embedded in Adobe applications - // that causes it, under certain circumstances, to return the same value for - // `a` and `b`. See https://github.com/jashkenas/underscore/pull/1247 - // - // This also ensures a stable sort in V8 and other engines. - // See http://code.google.com/p/v8/issues/detail?id=90 - return a.index - b.index; - } - - /** - * Creates a cache object to optimize linear searches of large arrays. - * - * @private - * @param {Array} [array=[]] The array to search. - * @returns {null|Object} Returns the cache object or `null` if caching should not be used. - */ - function createCache(array) { - var index = -1, - length = array.length, - first = array[0], - mid = array[(length / 2) | 0], - last = array[length - 1]; - if (first && typeof first == 'object' && - mid && typeof mid == 'object' && last && typeof last == 'object') { - return false; - } - var cache = getObject(); - cache['false'] = cache['null'] = cache['true'] = cache['undefined'] = false; + /** + * Creates an array of grouped elements, the first of which contains the first + * elements of the given arrays, the second of which contains the second elements + * of the given arrays, and so on. + * + * @static + * @memberOf _ + * @category Array + * @param {...Array} [arrays] The arrays to process. + * @returns {Array} Returns the new array of grouped elements. + * @example + * + * _.zip(['fred', 'barney'], [30, 40], [true, false]); + * // => [['fred', 30, true], ['barney', 40, false]] + */ + var zip = restParam(unzip); - var result = getObject(); - result.array = array; - result.cache = cache; - result.push = cachePush; + /** + * The inverse of `_.pairs`; this method returns an object composed from arrays + * of property names and values. Provide either a single two dimensional array, + * e.g. `[[key1, value1], [key2, value2]]` or two arrays, one of property names + * and one of corresponding values. + * + * @static + * @memberOf _ + * @alias object + * @category Array + * @param {Array} props The property names. + * @param {Array} [values=[]] The property values. + * @returns {Object} Returns the new object. + * @example + * + * _.zipObject([['fred', 30], ['barney', 40]]); + * // => { 'fred': 30, 'barney': 40 } + * + * _.zipObject(['fred', 'barney'], [30, 40]); + * // => { 'fred': 30, 'barney': 40 } + */ + function zipObject(props, values) { + var index = -1, + length = props ? props.length : 0, + result = {}; - while (++index < length) { - result.push(array[index]); + if (length && !values && !isArray(props[0])) { + values = []; + } + while (++index < length) { + var key = props[index]; + if (values) { + result[key] = values[index]; + } else if (key) { + result[key[0]] = key[1]; + } + } + return result; } - return result; - } - /** - * Used by `template` to escape characters for inclusion in compiled - * string literals. - * - * @private - * @param {string} match The matched character to escape. - * @returns {string} Returns the escaped character. - */ - function escapeStringChar(match) { - return '\\' + stringEscapes[match]; - } + /** + * This method is like `_.zip` except that it accepts an iteratee to specify + * how grouped values should be combined. The `iteratee` is bound to `thisArg` + * and invoked with four arguments: (accumulator, value, index, group). + * + * @static + * @memberOf _ + * @category Array + * @param {...Array} [arrays] The arrays to process. + * @param {Function} [iteratee] The function to combine grouped values. + * @param {*} [thisArg] The `this` binding of `iteratee`. + * @returns {Array} Returns the new array of grouped elements. + * @example + * + * _.zipWith([1, 2], [10, 20], [100, 200], _.add); + * // => [111, 222] + */ + var zipWith = restParam(function(arrays) { + var length = arrays.length, + iteratee = length > 2 ? arrays[length - 2] : undefined, + thisArg = length > 1 ? arrays[length - 1] : undefined; - /** - * Gets an array from the array pool or creates a new one if the pool is empty. - * - * @private - * @returns {Array} The array from the pool. - */ - function getArray() { - return arrayPool.pop() || []; - } + if (length > 2 && typeof iteratee == 'function') { + length -= 2; + } else { + iteratee = (length > 1 && typeof thisArg == 'function') ? (--length, thisArg) : undefined; + thisArg = undefined; + } + arrays.length = length; + return unzipWith(arrays, iteratee, thisArg); + }); - /** - * Gets an object from the object pool or creates a new one if the pool is empty. - * - * @private - * @returns {Object} The object from the pool. - */ - function getObject() { - return objectPool.pop() || { - 'array': null, - 'cache': null, - 'criteria': null, - 'false': false, - 'index': 0, - 'null': false, - 'number': null, - 'object': null, - 'push': null, - 'string': null, - 'true': false, - 'undefined': false, - 'value': null - }; - } + /*------------------------------------------------------------------------*/ - /** - * Releases the given array back to the array pool. - * - * @private - * @param {Array} [array] The array to release. - */ - function releaseArray(array) { - array.length = 0; - if (arrayPool.length < maxPoolSize) { - arrayPool.push(array); + /** + * Creates a `lodash` object that wraps `value` with explicit method + * chaining enabled. + * + * @static + * @memberOf _ + * @category Chain + * @param {*} value The value to wrap. + * @returns {Object} Returns the new `lodash` wrapper instance. + * @example + * + * var users = [ + * { 'user': 'barney', 'age': 36 }, + * { 'user': 'fred', 'age': 40 }, + * { 'user': 'pebbles', 'age': 1 } + * ]; + * + * var youngest = _.chain(users) + * .sortBy('age') + * .map(function(chr) { + * return chr.user + ' is ' + chr.age; + * }) + * .first() + * .value(); + * // => 'pebbles is 1' + */ + function chain(value) { + var result = lodash(value); + result.__chain__ = true; + return result; } - } - /** - * Releases the given object back to the object pool. - * - * @private - * @param {Object} [object] The object to release. - */ - function releaseObject(object) { - var cache = object.cache; - if (cache) { - releaseObject(cache); + /** + * This method invokes `interceptor` and returns `value`. The interceptor is + * bound to `thisArg` and invoked with one argument; (value). The purpose of + * this method is to "tap into" a method chain in order to perform operations + * on intermediate results within the chain. + * + * @static + * @memberOf _ + * @category Chain + * @param {*} value The value to provide to `interceptor`. + * @param {Function} interceptor The function to invoke. + * @param {*} [thisArg] The `this` binding of `interceptor`. + * @returns {*} Returns `value`. + * @example + * + * _([1, 2, 3]) + * .tap(function(array) { + * array.pop(); + * }) + * .reverse() + * .value(); + * // => [2, 1] + */ + function tap(value, interceptor, thisArg) { + interceptor.call(thisArg, value); + return value; } - object.array = object.cache = object.criteria = object.object = object.number = object.string = object.value = null; - if (objectPool.length < maxPoolSize) { - objectPool.push(object); + + /** + * This method is like `_.tap` except that it returns the result of `interceptor`. + * + * @static + * @memberOf _ + * @category Chain + * @param {*} value The value to provide to `interceptor`. + * @param {Function} interceptor The function to invoke. + * @param {*} [thisArg] The `this` binding of `interceptor`. + * @returns {*} Returns the result of `interceptor`. + * @example + * + * _(' abc ') + * .chain() + * .trim() + * .thru(function(value) { + * return [value]; + * }) + * .value(); + * // => ['abc'] + */ + function thru(value, interceptor, thisArg) { + return interceptor.call(thisArg, value); } - } - /** - * Slices the `collection` from the `start` index up to, but not including, - * the `end` index. - * - * Note: This function is used instead of `Array#slice` to support node lists - * in IE < 9 and to ensure dense arrays are returned. - * - * @private - * @param {Array|Object|string} collection The collection to slice. - * @param {number} start The start index. - * @param {number} end The end index. - * @returns {Array} Returns the new array. - */ - function slice(array, start, end) { - start || (start = 0); - if (typeof end == 'undefined') { - end = array ? array.length : 0; + /** + * Enables explicit method chaining on the wrapper object. + * + * @name chain + * @memberOf _ + * @category Chain + * @returns {Object} Returns the new `lodash` wrapper instance. + * @example + * + * var users = [ + * { 'user': 'barney', 'age': 36 }, + * { 'user': 'fred', 'age': 40 } + * ]; + * + * // without explicit chaining + * _(users).first(); + * // => { 'user': 'barney', 'age': 36 } + * + * // with explicit chaining + * _(users).chain() + * .first() + * .pick('user') + * .value(); + * // => { 'user': 'barney' } + */ + function wrapperChain() { + return chain(this); } - var index = -1, - length = end - start || 0, - result = Array(length < 0 ? 0 : length); - while (++index < length) { - result[index] = array[start + index]; + /** + * Executes the chained sequence and returns the wrapped result. + * + * @name commit + * @memberOf _ + * @category Chain + * @returns {Object} Returns the new `lodash` wrapper instance. + * @example + * + * var array = [1, 2]; + * var wrapped = _(array).push(3); + * + * console.log(array); + * // => [1, 2] + * + * wrapped = wrapped.commit(); + * console.log(array); + * // => [1, 2, 3] + * + * wrapped.last(); + * // => 3 + * + * console.log(array); + * // => [1, 2, 3] + */ + function wrapperCommit() { + return new LodashWrapper(this.value(), this.__chain__); } - return result; - } - /*--------------------------------------------------------------------------*/ + /** + * Creates a new array joining a wrapped array with any additional arrays + * and/or values. + * + * @name concat + * @memberOf _ + * @category Chain + * @param {...*} [values] The values to concatenate. + * @returns {Array} Returns the new concatenated array. + * @example + * + * var array = [1]; + * var wrapped = _(array).concat(2, [3], [[4]]); + * + * console.log(wrapped.value()); + * // => [1, 2, 3, [4]] + * + * console.log(array); + * // => [1] + */ + var wrapperConcat = restParam(function(values) { + values = baseFlatten(values); + return this.thru(function(array) { + return arrayConcat(isArray(array) ? array : [toObject(array)], values); + }); + }); - /** - * Create a new `lodash` function using the given context object. - * - * @static - * @memberOf _ - * @category Utilities - * @param {Object} [context=root] The context object. - * @returns {Function} Returns the `lodash` function. - */ - function runInContext(context) { - // Avoid issues with some ES3 environments that attempt to use values, named - // after built-in constructors like `Object`, for the creation of literals. - // ES5 clears this up by stating that literals must use built-in constructors. - // See http://es5.github.io/#x11.1.5. - context = context ? _.defaults(root.Object(), context, _.pick(root, contextProps)) : root; + /** + * Creates a clone of the chained sequence planting `value` as the wrapped value. + * + * @name plant + * @memberOf _ + * @category Chain + * @returns {Object} Returns the new `lodash` wrapper instance. + * @example + * + * var array = [1, 2]; + * var wrapped = _(array).map(function(value) { + * return Math.pow(value, 2); + * }); + * + * var other = [3, 4]; + * var otherWrapped = wrapped.plant(other); + * + * otherWrapped.value(); + * // => [9, 16] + * + * wrapped.value(); + * // => [1, 4] + */ + function wrapperPlant(value) { + var result, + parent = this; + + while (parent instanceof baseLodash) { + var clone = wrapperClone(parent); + if (result) { + previous.__wrapped__ = clone; + } else { + result = clone; + } + var previous = clone; + parent = parent.__wrapped__; + } + previous.__wrapped__ = value; + return result; + } - /** Native constructor references */ - var Array = context.Array, - Boolean = context.Boolean, - Date = context.Date, - Function = context.Function, - Math = context.Math, - Number = context.Number, - Object = context.Object, - RegExp = context.RegExp, - String = context.String, - TypeError = context.TypeError; + /** + * Reverses the wrapped array so the first element becomes the last, the + * second element becomes the second to last, and so on. + * + * **Note:** This method mutates the wrapped array. + * + * @name reverse + * @memberOf _ + * @category Chain + * @returns {Object} Returns the new reversed `lodash` wrapper instance. + * @example + * + * var array = [1, 2, 3]; + * + * _(array).reverse().value() + * // => [3, 2, 1] + * + * console.log(array); + * // => [3, 2, 1] + */ + function wrapperReverse() { + var value = this.__wrapped__; + + var interceptor = function(value) { + return (wrapped && wrapped.__dir__ < 0) ? value : value.reverse(); + }; + if (value instanceof LazyWrapper) { + var wrapped = value; + if (this.__actions__.length) { + wrapped = new LazyWrapper(this); + } + wrapped = wrapped.reverse(); + wrapped.__actions__.push({ 'func': thru, 'args': [interceptor], 'thisArg': undefined }); + return new LodashWrapper(wrapped, this.__chain__); + } + return this.thru(interceptor); + } /** - * Used for `Array` method references. + * Produces the result of coercing the unwrapped value to a string. + * + * @name toString + * @memberOf _ + * @category Chain + * @returns {string} Returns the coerced string value. + * @example * - * Normally `Array.prototype` would suffice, however, using an array literal - * avoids issues in Narwhal. + * _([1, 2, 3]).toString(); + * // => '1,2,3' */ - var arrayRef = []; - - /** Used for native method references */ - var objectProto = Object.prototype; + function wrapperToString() { + return (this.value() + ''); + } - /** Used to restore the original `_` reference in `noConflict` */ - var oldDash = context._; + /** + * Executes the chained sequence to extract the unwrapped value. + * + * @name value + * @memberOf _ + * @alias run, toJSON, valueOf + * @category Chain + * @returns {*} Returns the resolved unwrapped value. + * @example + * + * _([1, 2, 3]).value(); + * // => [1, 2, 3] + */ + function wrapperValue() { + return baseWrapperValue(this.__wrapped__, this.__actions__); + } - /** Used to resolve the internal [[Class]] of values */ - var toString = objectProto.toString; + /*------------------------------------------------------------------------*/ - /** Used to detect if a method is native */ - var reNative = RegExp('^' + - String(toString) - .replace(/[.*+?^${}()|[\]\\]/g, '\\$&') - .replace(/toString| for [^\]]+/g, '.*?') + '$' - ); + /** + * Creates an array of elements corresponding to the given keys, or indexes, + * of `collection`. Keys may be specified as individual arguments or as arrays + * of keys. + * + * @static + * @memberOf _ + * @category Collection + * @param {Array|Object|string} collection The collection to iterate over. + * @param {...(number|number[]|string|string[])} [props] The property names + * or indexes of elements to pick, specified individually or in arrays. + * @returns {Array} Returns the new array of picked elements. + * @example + * + * _.at(['a', 'b', 'c'], [0, 2]); + * // => ['a', 'c'] + * + * _.at(['barney', 'fred', 'pebbles'], 0, 2); + * // => ['barney', 'pebbles'] + */ + var at = restParam(function(collection, props) { + return baseAt(collection, baseFlatten(props)); + }); - /** Native method shortcuts */ - var ceil = Math.ceil, - clearTimeout = context.clearTimeout, - floor = Math.floor, - fnToString = Function.prototype.toString, - getPrototypeOf = isNative(getPrototypeOf = Object.getPrototypeOf) && getPrototypeOf, - hasOwnProperty = objectProto.hasOwnProperty, - push = arrayRef.push, - setTimeout = context.setTimeout, - splice = arrayRef.splice, - unshift = arrayRef.unshift; + /** + * Creates an object composed of keys generated from the results of running + * each element of `collection` through `iteratee`. The corresponding value + * of each key is the number of times the key was returned by `iteratee`. + * The `iteratee` is bound to `thisArg` and invoked with three arguments: + * (value, index|key, collection). + * + * If a property name is provided for `iteratee` the created `_.property` + * style callback returns the property value of the given element. + * + * If a value is also provided for `thisArg` the created `_.matchesProperty` + * style callback returns `true` for elements that have a matching property + * value, else `false`. + * + * If an object is provided for `iteratee` the created `_.matches` style + * callback returns `true` for elements that have the properties of the given + * object, else `false`. + * + * @static + * @memberOf _ + * @category Collection + * @param {Array|Object|string} collection The collection to iterate over. + * @param {Function|Object|string} [iteratee=_.identity] The function invoked + * per iteration. + * @param {*} [thisArg] The `this` binding of `iteratee`. + * @returns {Object} Returns the composed aggregate object. + * @example + * + * _.countBy([4.3, 6.1, 6.4], function(n) { + * return Math.floor(n); + * }); + * // => { '4': 1, '6': 2 } + * + * _.countBy([4.3, 6.1, 6.4], function(n) { + * return this.floor(n); + * }, Math); + * // => { '4': 1, '6': 2 } + * + * _.countBy(['one', 'two', 'three'], 'length'); + * // => { '3': 2, '5': 1 } + */ + var countBy = createAggregator(function(result, value, key) { + hasOwnProperty.call(result, key) ? ++result[key] : (result[key] = 1); + }); - /** Used to set meta data on functions */ - var defineProperty = (function() { - // IE 8 only accepts DOM elements - try { - var o = {}, - func = isNative(func = Object.defineProperty) && func, - result = func(o, o, o) && func; - } catch(e) { } - return result; - }()); + /** + * Checks if `predicate` returns truthy for **all** elements of `collection`. + * The predicate is bound to `thisArg` and invoked with three arguments: + * (value, index|key, collection). + * + * If a property name is provided for `predicate` the created `_.property` + * style callback returns the property value of the given element. + * + * If a value is also provided for `thisArg` the created `_.matchesProperty` + * style callback returns `true` for elements that have a matching property + * value, else `false`. + * + * If an object is provided for `predicate` the created `_.matches` style + * callback returns `true` for elements that have the properties of the given + * object, else `false`. + * + * @static + * @memberOf _ + * @alias all + * @category Collection + * @param {Array|Object|string} collection The collection to iterate over. + * @param {Function|Object|string} [predicate=_.identity] The function invoked + * per iteration. + * @param {*} [thisArg] The `this` binding of `predicate`. + * @returns {boolean} Returns `true` if all elements pass the predicate check, + * else `false`. + * @example + * + * _.every([true, 1, null, 'yes'], Boolean); + * // => false + * + * var users = [ + * { 'user': 'barney', 'active': false }, + * { 'user': 'fred', 'active': false } + * ]; + * + * // using the `_.matches` callback shorthand + * _.every(users, { 'user': 'barney', 'active': false }); + * // => false + * + * // using the `_.matchesProperty` callback shorthand + * _.every(users, 'active', false); + * // => true + * + * // using the `_.property` callback shorthand + * _.every(users, 'active'); + * // => false + */ + function every(collection, predicate, thisArg) { + var func = isArray(collection) ? arrayEvery : baseEvery; + if (thisArg && isIterateeCall(collection, predicate, thisArg)) { + predicate = undefined; + } + if (typeof predicate != 'function' || thisArg !== undefined) { + predicate = getCallback(predicate, thisArg, 3); + } + return func(collection, predicate); + } - /* Native method shortcuts for methods with the same name as other `lodash` methods */ - var nativeCreate = isNative(nativeCreate = Object.create) && nativeCreate, - nativeIsArray = isNative(nativeIsArray = Array.isArray) && nativeIsArray, - nativeIsFinite = context.isFinite, - nativeIsNaN = context.isNaN, - nativeKeys = isNative(nativeKeys = Object.keys) && nativeKeys, - nativeMax = Math.max, - nativeMin = Math.min, - nativeParseInt = context.parseInt, - nativeRandom = Math.random; + /** + * Iterates over elements of `collection`, returning an array of all elements + * `predicate` returns truthy for. The predicate is bound to `thisArg` and + * invoked with three arguments: (value, index|key, collection). + * + * If a property name is provided for `predicate` the created `_.property` + * style callback returns the property value of the given element. + * + * If a value is also provided for `thisArg` the created `_.matchesProperty` + * style callback returns `true` for elements that have a matching property + * value, else `false`. + * + * If an object is provided for `predicate` the created `_.matches` style + * callback returns `true` for elements that have the properties of the given + * object, else `false`. + * + * @static + * @memberOf _ + * @alias select + * @category Collection + * @param {Array|Object|string} collection The collection to iterate over. + * @param {Function|Object|string} [predicate=_.identity] The function invoked + * per iteration. + * @param {*} [thisArg] The `this` binding of `predicate`. + * @returns {Array} Returns the new filtered array. + * @example + * + * _.filter([4, 5, 6], function(n) { + * return n % 2 == 0; + * }); + * // => [4, 6] + * + * var users = [ + * { 'user': 'barney', 'age': 36, 'active': true }, + * { 'user': 'fred', 'age': 40, 'active': false } + * ]; + * + * // using the `_.matches` callback shorthand + * _.pluck(_.filter(users, { 'age': 36, 'active': true }), 'user'); + * // => ['barney'] + * + * // using the `_.matchesProperty` callback shorthand + * _.pluck(_.filter(users, 'active', false), 'user'); + * // => ['fred'] + * + * // using the `_.property` callback shorthand + * _.pluck(_.filter(users, 'active'), 'user'); + * // => ['barney'] + */ + function filter(collection, predicate, thisArg) { + var func = isArray(collection) ? arrayFilter : baseFilter; + predicate = getCallback(predicate, thisArg, 3); + return func(collection, predicate); + } - /** Used to lookup a built-in constructor by [[Class]] */ - var ctorByClass = {}; - ctorByClass[arrayClass] = Array; - ctorByClass[boolClass] = Boolean; - ctorByClass[dateClass] = Date; - ctorByClass[funcClass] = Function; - ctorByClass[objectClass] = Object; - ctorByClass[numberClass] = Number; - ctorByClass[regexpClass] = RegExp; - ctorByClass[stringClass] = String; + /** + * Iterates over elements of `collection`, returning the first element + * `predicate` returns truthy for. The predicate is bound to `thisArg` and + * invoked with three arguments: (value, index|key, collection). + * + * If a property name is provided for `predicate` the created `_.property` + * style callback returns the property value of the given element. + * + * If a value is also provided for `thisArg` the created `_.matchesProperty` + * style callback returns `true` for elements that have a matching property + * value, else `false`. + * + * If an object is provided for `predicate` the created `_.matches` style + * callback returns `true` for elements that have the properties of the given + * object, else `false`. + * + * @static + * @memberOf _ + * @alias detect + * @category Collection + * @param {Array|Object|string} collection The collection to search. + * @param {Function|Object|string} [predicate=_.identity] The function invoked + * per iteration. + * @param {*} [thisArg] The `this` binding of `predicate`. + * @returns {*} Returns the matched element, else `undefined`. + * @example + * + * var users = [ + * { 'user': 'barney', 'age': 36, 'active': true }, + * { 'user': 'fred', 'age': 40, 'active': false }, + * { 'user': 'pebbles', 'age': 1, 'active': true } + * ]; + * + * _.result(_.find(users, function(chr) { + * return chr.age < 40; + * }), 'user'); + * // => 'barney' + * + * // using the `_.matches` callback shorthand + * _.result(_.find(users, { 'age': 1, 'active': true }), 'user'); + * // => 'pebbles' + * + * // using the `_.matchesProperty` callback shorthand + * _.result(_.find(users, 'active', false), 'user'); + * // => 'fred' + * + * // using the `_.property` callback shorthand + * _.result(_.find(users, 'active'), 'user'); + * // => 'barney' + */ + var find = createFind(baseEach); - /*--------------------------------------------------------------------------*/ + /** + * This method is like `_.find` except that it iterates over elements of + * `collection` from right to left. + * + * @static + * @memberOf _ + * @category Collection + * @param {Array|Object|string} collection The collection to search. + * @param {Function|Object|string} [predicate=_.identity] The function invoked + * per iteration. + * @param {*} [thisArg] The `this` binding of `predicate`. + * @returns {*} Returns the matched element, else `undefined`. + * @example + * + * _.findLast([1, 2, 3, 4], function(n) { + * return n % 2 == 1; + * }); + * // => 3 + */ + var findLast = createFind(baseEachRight, true); /** - * Creates a `lodash` object which wraps the given value to enable intuitive - * method chaining. + * Performs a deep comparison between each element in `collection` and the + * source object, returning the first element that has equivalent property + * values. + * + * **Note:** This method supports comparing arrays, booleans, `Date` objects, + * numbers, `Object` objects, regexes, and strings. Objects are compared by + * their own, not inherited, enumerable properties. For comparing a single + * own or inherited property value see `_.matchesProperty`. * - * In addition to Lo-Dash methods, wrappers also have the following `Array` methods: - * `concat`, `join`, `pop`, `push`, `reverse`, `shift`, `slice`, `sort`, `splice`, - * and `unshift` + * @static + * @memberOf _ + * @category Collection + * @param {Array|Object|string} collection The collection to search. + * @param {Object} source The object of property values to match. + * @returns {*} Returns the matched element, else `undefined`. + * @example * - * Chaining is supported in custom builds as long as the `value` method is - * implicitly or explicitly included in the build. + * var users = [ + * { 'user': 'barney', 'age': 36, 'active': true }, + * { 'user': 'fred', 'age': 40, 'active': false } + * ]; * - * The chainable wrapper functions are: - * `after`, `assign`, `bind`, `bindAll`, `bindKey`, `chain`, `compact`, - * `compose`, `concat`, `countBy`, `create`, `createCallback`, `curry`, - * `debounce`, `defaults`, `defer`, `delay`, `difference`, `filter`, `flatten`, - * `forEach`, `forEachRight`, `forIn`, `forInRight`, `forOwn`, `forOwnRight`, - * `functions`, `groupBy`, `indexBy`, `initial`, `intersection`, `invert`, - * `invoke`, `keys`, `map`, `max`, `memoize`, `merge`, `min`, `object`, `omit`, - * `once`, `pairs`, `partial`, `partialRight`, `pick`, `pluck`, `pull`, `push`, - * `range`, `reject`, `remove`, `rest`, `reverse`, `shuffle`, `slice`, `sort`, - * `sortBy`, `splice`, `tap`, `throttle`, `times`, `toArray`, `transform`, - * `union`, `uniq`, `unshift`, `unzip`, `values`, `where`, `without`, `wrap`, - * and `zip` - * - * The non-chainable wrapper functions are: - * `clone`, `cloneDeep`, `contains`, `escape`, `every`, `find`, `findIndex`, - * `findKey`, `findLast`, `findLastIndex`, `findLastKey`, `has`, `identity`, - * `indexOf`, `isArguments`, `isArray`, `isBoolean`, `isDate`, `isElement`, - * `isEmpty`, `isEqual`, `isFinite`, `isFunction`, `isNaN`, `isNull`, `isNumber`, - * `isObject`, `isPlainObject`, `isRegExp`, `isString`, `isUndefined`, `join`, - * `lastIndexOf`, `mixin`, `noConflict`, `parseInt`, `pop`, `random`, `reduce`, - * `reduceRight`, `result`, `shift`, `size`, `some`, `sortedIndex`, `runInContext`, - * `template`, `unescape`, `uniqueId`, and `value` - * - * The wrapper functions `first` and `last` return wrapped values when `n` is - * provided, otherwise they return unwrapped values. - * - * Explicit chaining can be enabled by using the `_.chain` method. + * _.result(_.findWhere(users, { 'age': 36, 'active': true }), 'user'); + * // => 'barney' * - * @name _ - * @constructor - * @category Chaining - * @param {*} value The value to wrap in a `lodash` instance. - * @returns {Object} Returns a `lodash` instance. + * _.result(_.findWhere(users, { 'age': 40, 'active': false }), 'user'); + * // => 'fred' + */ + function findWhere(collection, source) { + return find(collection, baseMatches(source)); + } + + /** + * Iterates over elements of `collection` invoking `iteratee` for each element. + * The `iteratee` is bound to `thisArg` and invoked with three arguments: + * (value, index|key, collection). Iteratee functions may exit iteration early + * by explicitly returning `false`. + * + * **Note:** As with other "Collections" methods, objects with a "length" property + * are iterated like arrays. To avoid this behavior `_.forIn` or `_.forOwn` + * may be used for object iteration. + * + * @static + * @memberOf _ + * @alias each + * @category Collection + * @param {Array|Object|string} collection The collection to iterate over. + * @param {Function} [iteratee=_.identity] The function invoked per iteration. + * @param {*} [thisArg] The `this` binding of `iteratee`. + * @returns {Array|Object|string} Returns `collection`. * @example * - * var wrapped = _([1, 2, 3]); + * _([1, 2]).forEach(function(n) { + * console.log(n); + * }).value(); + * // => logs each value from left to right and returns the array * - * // returns an unwrapped value - * wrapped.reduce(function(sum, num) { - * return sum + num; + * _.forEach({ 'a': 1, 'b': 2 }, function(n, key) { + * console.log(n, key); * }); - * // => 6 + * // => logs each value-key pair and returns the object (iteration order is not guaranteed) + */ + var forEach = createForEach(arrayEach, baseEach); + + /** + * This method is like `_.forEach` except that it iterates over elements of + * `collection` from right to left. * - * // returns a wrapped value - * var squares = wrapped.map(function(num) { - * return num * num; + * @static + * @memberOf _ + * @alias eachRight + * @category Collection + * @param {Array|Object|string} collection The collection to iterate over. + * @param {Function} [iteratee=_.identity] The function invoked per iteration. + * @param {*} [thisArg] The `this` binding of `iteratee`. + * @returns {Array|Object|string} Returns `collection`. + * @example + * + * _([1, 2]).forEachRight(function(n) { + * console.log(n); + * }).value(); + * // => logs each value from right to left and returns the array + */ + var forEachRight = createForEach(arrayEachRight, baseEachRight); + + /** + * Creates an object composed of keys generated from the results of running + * each element of `collection` through `iteratee`. The corresponding value + * of each key is an array of the elements responsible for generating the key. + * The `iteratee` is bound to `thisArg` and invoked with three arguments: + * (value, index|key, collection). + * + * If a property name is provided for `iteratee` the created `_.property` + * style callback returns the property value of the given element. + * + * If a value is also provided for `thisArg` the created `_.matchesProperty` + * style callback returns `true` for elements that have a matching property + * value, else `false`. + * + * If an object is provided for `iteratee` the created `_.matches` style + * callback returns `true` for elements that have the properties of the given + * object, else `false`. + * + * @static + * @memberOf _ + * @category Collection + * @param {Array|Object|string} collection The collection to iterate over. + * @param {Function|Object|string} [iteratee=_.identity] The function invoked + * per iteration. + * @param {*} [thisArg] The `this` binding of `iteratee`. + * @returns {Object} Returns the composed aggregate object. + * @example + * + * _.groupBy([4.2, 6.1, 6.4], function(n) { + * return Math.floor(n); * }); + * // => { '4': [4.2], '6': [6.1, 6.4] } * - * _.isArray(squares); + * _.groupBy([4.2, 6.1, 6.4], function(n) { + * return this.floor(n); + * }, Math); + * // => { '4': [4.2], '6': [6.1, 6.4] } + * + * // using the `_.property` callback shorthand + * _.groupBy(['one', 'two', 'three'], 'length'); + * // => { '3': ['one', 'two'], '5': ['three'] } + */ + var groupBy = createAggregator(function(result, value, key) { + if (hasOwnProperty.call(result, key)) { + result[key].push(value); + } else { + result[key] = [value]; + } + }); + + /** + * Checks if `value` is in `collection` using + * [`SameValueZero`](http://ecma-international.org/ecma-262/6.0/#sec-samevaluezero) + * for equality comparisons. If `fromIndex` is negative, it is used as the offset + * from the end of `collection`. + * + * @static + * @memberOf _ + * @alias contains, include + * @category Collection + * @param {Array|Object|string} collection The collection to search. + * @param {*} target The value to search for. + * @param {number} [fromIndex=0] The index to search from. + * @param- {Object} [guard] Enables use as a callback for functions like `_.reduce`. + * @returns {boolean} Returns `true` if a matching element is found, else `false`. + * @example + * + * _.includes([1, 2, 3], 1); + * // => true + * + * _.includes([1, 2, 3], 1, 2); * // => false * - * _.isArray(squares.value()); + * _.includes({ 'user': 'fred', 'age': 40 }, 'fred'); + * // => true + * + * _.includes('pebbles', 'eb'); * // => true */ - function lodash(value) { - // don't wrap if already wrapped, even if wrapped by a different `lodash` constructor - return (value && typeof value == 'object' && !isArray(value) && hasOwnProperty.call(value, '__wrapped__')) - ? value - : new lodashWrapper(value); + function includes(collection, target, fromIndex, guard) { + var length = collection ? getLength(collection) : 0; + if (!isLength(length)) { + collection = values(collection); + length = collection.length; + } + if (typeof fromIndex != 'number' || (guard && isIterateeCall(target, fromIndex, guard))) { + fromIndex = 0; + } else { + fromIndex = fromIndex < 0 ? nativeMax(length + fromIndex, 0) : (fromIndex || 0); + } + return (typeof collection == 'string' || !isArray(collection) && isString(collection)) + ? (fromIndex <= length && collection.indexOf(target, fromIndex) > -1) + : (!!length && getIndexOf(collection, target, fromIndex) > -1); } /** - * A fast path for creating `lodash` wrapper objects. + * Creates an object composed of keys generated from the results of running + * each element of `collection` through `iteratee`. The corresponding value + * of each key is the last element responsible for generating the key. The + * iteratee function is bound to `thisArg` and invoked with three arguments: + * (value, index|key, collection). * - * @private - * @param {*} value The value to wrap in a `lodash` instance. - * @param {boolean} chainAll A flag to enable chaining for all methods - * @returns {Object} Returns a `lodash` instance. + * If a property name is provided for `iteratee` the created `_.property` + * style callback returns the property value of the given element. + * + * If a value is also provided for `thisArg` the created `_.matchesProperty` + * style callback returns `true` for elements that have a matching property + * value, else `false`. + * + * If an object is provided for `iteratee` the created `_.matches` style + * callback returns `true` for elements that have the properties of the given + * object, else `false`. + * + * @static + * @memberOf _ + * @category Collection + * @param {Array|Object|string} collection The collection to iterate over. + * @param {Function|Object|string} [iteratee=_.identity] The function invoked + * per iteration. + * @param {*} [thisArg] The `this` binding of `iteratee`. + * @returns {Object} Returns the composed aggregate object. + * @example + * + * var keyData = [ + * { 'dir': 'left', 'code': 97 }, + * { 'dir': 'right', 'code': 100 } + * ]; + * + * _.indexBy(keyData, 'dir'); + * // => { 'left': { 'dir': 'left', 'code': 97 }, 'right': { 'dir': 'right', 'code': 100 } } + * + * _.indexBy(keyData, function(object) { + * return String.fromCharCode(object.code); + * }); + * // => { 'a': { 'dir': 'left', 'code': 97 }, 'd': { 'dir': 'right', 'code': 100 } } + * + * _.indexBy(keyData, function(object) { + * return this.fromCharCode(object.code); + * }, String); + * // => { 'a': { 'dir': 'left', 'code': 97 }, 'd': { 'dir': 'right', 'code': 100 } } */ - function lodashWrapper(value, chainAll) { - this.__chain__ = !!chainAll; - this.__wrapped__ = value; - } - // ensure `new lodashWrapper` is an instance of `lodash` - lodashWrapper.prototype = lodash.prototype; + var indexBy = createAggregator(function(result, value, key) { + result[key] = value; + }); /** - * An object used to flag environments features. + * Invokes the method at `path` of each element in `collection`, returning + * an array of the results of each invoked method. Any additional arguments + * are provided to each invoked method. If `methodName` is a function it is + * invoked for, and `this` bound to, each element in `collection`. * * @static * @memberOf _ - * @type Object + * @category Collection + * @param {Array|Object|string} collection The collection to iterate over. + * @param {Array|Function|string} path The path of the method to invoke or + * the function invoked per iteration. + * @param {...*} [args] The arguments to invoke the method with. + * @returns {Array} Returns the array of results. + * @example + * + * _.invoke([[5, 1, 7], [3, 2, 1]], 'sort'); + * // => [[1, 5, 7], [1, 2, 3]] + * + * _.invoke([123, 456], String.prototype.split, ''); + * // => [['1', '2', '3'], ['4', '5', '6']] */ - var support = lodash.support = {}; + var invoke = restParam(function(collection, path, args) { + var index = -1, + isFunc = typeof path == 'function', + isProp = isKey(path), + result = isArrayLike(collection) ? Array(collection.length) : []; + + baseEach(collection, function(value) { + var func = isFunc ? path : ((isProp && value != null) ? value[path] : undefined); + result[++index] = func ? func.apply(value, args) : invokePath(value, path, args); + }); + return result; + }); /** - * Detect if functions can be decompiled by `Function#toString` - * (all but PS3 and older Opera mobile browsers & avoided in Windows 8 apps). + * Creates an array of values by running each element in `collection` through + * `iteratee`. The `iteratee` is bound to `thisArg` and invoked with three + * arguments: (value, index|key, collection). + * + * If a property name is provided for `iteratee` the created `_.property` + * style callback returns the property value of the given element. + * + * If a value is also provided for `thisArg` the created `_.matchesProperty` + * style callback returns `true` for elements that have a matching property + * value, else `false`. + * + * If an object is provided for `iteratee` the created `_.matches` style + * callback returns `true` for elements that have the properties of the given + * object, else `false`. + * + * Many lodash methods are guarded to work as iteratees for methods like + * `_.every`, `_.filter`, `_.map`, `_.mapValues`, `_.reject`, and `_.some`. + * + * The guarded methods are: + * `ary`, `callback`, `chunk`, `clone`, `create`, `curry`, `curryRight`, + * `drop`, `dropRight`, `every`, `fill`, `flatten`, `invert`, `max`, `min`, + * `parseInt`, `slice`, `sortBy`, `take`, `takeRight`, `template`, `trim`, + * `trimLeft`, `trimRight`, `trunc`, `random`, `range`, `sample`, `some`, + * `sum`, `uniq`, and `words` + * + * @static + * @memberOf _ + * @alias collect + * @category Collection + * @param {Array|Object|string} collection The collection to iterate over. + * @param {Function|Object|string} [iteratee=_.identity] The function invoked + * per iteration. + * @param {*} [thisArg] The `this` binding of `iteratee`. + * @returns {Array} Returns the new mapped array. + * @example + * + * function timesThree(n) { + * return n * 3; + * } + * + * _.map([1, 2], timesThree); + * // => [3, 6] + * + * _.map({ 'a': 1, 'b': 2 }, timesThree); + * // => [3, 6] (iteration order is not guaranteed) + * + * var users = [ + * { 'user': 'barney' }, + * { 'user': 'fred' } + * ]; * - * @memberOf _.support - * @type boolean + * // using the `_.property` callback shorthand + * _.map(users, 'user'); + * // => ['barney', 'fred'] */ - support.funcDecomp = !isNative(context.WinRTError) && reThis.test(runInContext); + function map(collection, iteratee, thisArg) { + var func = isArray(collection) ? arrayMap : baseMap; + iteratee = getCallback(iteratee, thisArg, 3); + return func(collection, iteratee); + } /** - * Detect if `Function#name` is supported (all but IE). + * Creates an array of elements split into two groups, the first of which + * contains elements `predicate` returns truthy for, while the second of which + * contains elements `predicate` returns falsey for. The predicate is bound + * to `thisArg` and invoked with three arguments: (value, index|key, collection). + * + * If a property name is provided for `predicate` the created `_.property` + * style callback returns the property value of the given element. + * + * If a value is also provided for `thisArg` the created `_.matchesProperty` + * style callback returns `true` for elements that have a matching property + * value, else `false`. + * + * If an object is provided for `predicate` the created `_.matches` style + * callback returns `true` for elements that have the properties of the given + * object, else `false`. + * + * @static + * @memberOf _ + * @category Collection + * @param {Array|Object|string} collection The collection to iterate over. + * @param {Function|Object|string} [predicate=_.identity] The function invoked + * per iteration. + * @param {*} [thisArg] The `this` binding of `predicate`. + * @returns {Array} Returns the array of grouped elements. + * @example + * + * _.partition([1, 2, 3], function(n) { + * return n % 2; + * }); + * // => [[1, 3], [2]] + * + * _.partition([1.2, 2.3, 3.4], function(n) { + * return this.floor(n) % 2; + * }, Math); + * // => [[1.2, 3.4], [2.3]] + * + * var users = [ + * { 'user': 'barney', 'age': 36, 'active': false }, + * { 'user': 'fred', 'age': 40, 'active': true }, + * { 'user': 'pebbles', 'age': 1, 'active': false } + * ]; + * + * var mapper = function(array) { + * return _.pluck(array, 'user'); + * }; + * + * // using the `_.matches` callback shorthand + * _.map(_.partition(users, { 'age': 1, 'active': false }), mapper); + * // => [['pebbles'], ['barney', 'fred']] * - * @memberOf _.support - * @type boolean + * // using the `_.matchesProperty` callback shorthand + * _.map(_.partition(users, 'active', false), mapper); + * // => [['barney', 'pebbles'], ['fred']] + * + * // using the `_.property` callback shorthand + * _.map(_.partition(users, 'active'), mapper); + * // => [['fred'], ['barney', 'pebbles']] */ - support.funcNames = typeof Function.name == 'string'; + var partition = createAggregator(function(result, value, key) { + result[key ? 0 : 1].push(value); + }, function() { return [[], []]; }); /** - * By default, the template delimiters used by Lo-Dash are similar to those in - * embedded Ruby (ERB). Change the following template settings to use alternative - * delimiters. + * Gets the property value of `path` from all elements in `collection`. * * @static * @memberOf _ - * @type Object + * @category Collection + * @param {Array|Object|string} collection The collection to iterate over. + * @param {Array|string} path The path of the property to pluck. + * @returns {Array} Returns the property values. + * @example + * + * var users = [ + * { 'user': 'barney', 'age': 36 }, + * { 'user': 'fred', 'age': 40 } + * ]; + * + * _.pluck(users, 'user'); + * // => ['barney', 'fred'] + * + * var userIndex = _.indexBy(users, 'user'); + * _.pluck(userIndex, 'age'); + * // => [36, 40] (iteration order is not guaranteed) */ - lodash.templateSettings = { + function pluck(collection, path) { + return map(collection, property(path)); + } - /** - * Used to detect `data` property values to be HTML-escaped. - * - * @memberOf _.templateSettings - * @type RegExp - */ - 'escape': /<%-([\s\S]+?)%>/g, + /** + * Reduces `collection` to a value which is the accumulated result of running + * each element in `collection` through `iteratee`, where each successive + * invocation is supplied the return value of the previous. If `accumulator` + * is not provided the first element of `collection` is used as the initial + * value. The `iteratee` is bound to `thisArg` and invoked with four arguments: + * (accumulator, value, index|key, collection). + * + * Many lodash methods are guarded to work as iteratees for methods like + * `_.reduce`, `_.reduceRight`, and `_.transform`. + * + * The guarded methods are: + * `assign`, `defaults`, `defaultsDeep`, `includes`, `merge`, `sortByAll`, + * and `sortByOrder` + * + * @static + * @memberOf _ + * @alias foldl, inject + * @category Collection + * @param {Array|Object|string} collection The collection to iterate over. + * @param {Function} [iteratee=_.identity] The function invoked per iteration. + * @param {*} [accumulator] The initial value. + * @param {*} [thisArg] The `this` binding of `iteratee`. + * @returns {*} Returns the accumulated value. + * @example + * + * _.reduce([1, 2], function(total, n) { + * return total + n; + * }); + * // => 3 + * + * _.reduce({ 'a': 1, 'b': 2 }, function(result, n, key) { + * result[key] = n * 3; + * return result; + * }, {}); + * // => { 'a': 3, 'b': 6 } (iteration order is not guaranteed) + */ + var reduce = createReduce(arrayReduce, baseEach); - /** - * Used to detect code to be evaluated. - * - * @memberOf _.templateSettings - * @type RegExp - */ - 'evaluate': /<%([\s\S]+?)%>/g, + /** + * This method is like `_.reduce` except that it iterates over elements of + * `collection` from right to left. + * + * @static + * @memberOf _ + * @alias foldr + * @category Collection + * @param {Array|Object|string} collection The collection to iterate over. + * @param {Function} [iteratee=_.identity] The function invoked per iteration. + * @param {*} [accumulator] The initial value. + * @param {*} [thisArg] The `this` binding of `iteratee`. + * @returns {*} Returns the accumulated value. + * @example + * + * var array = [[0, 1], [2, 3], [4, 5]]; + * + * _.reduceRight(array, function(flattened, other) { + * return flattened.concat(other); + * }, []); + * // => [4, 5, 2, 3, 0, 1] + */ + var reduceRight = createReduce(arrayReduceRight, baseEachRight); - /** - * Used to detect `data` property values to inject. - * - * @memberOf _.templateSettings - * @type RegExp - */ - 'interpolate': reInterpolate, + /** + * The opposite of `_.filter`; this method returns the elements of `collection` + * that `predicate` does **not** return truthy for. + * + * @static + * @memberOf _ + * @category Collection + * @param {Array|Object|string} collection The collection to iterate over. + * @param {Function|Object|string} [predicate=_.identity] The function invoked + * per iteration. + * @param {*} [thisArg] The `this` binding of `predicate`. + * @returns {Array} Returns the new filtered array. + * @example + * + * _.reject([1, 2, 3, 4], function(n) { + * return n % 2 == 0; + * }); + * // => [1, 3] + * + * var users = [ + * { 'user': 'barney', 'age': 36, 'active': false }, + * { 'user': 'fred', 'age': 40, 'active': true } + * ]; + * + * // using the `_.matches` callback shorthand + * _.pluck(_.reject(users, { 'age': 40, 'active': true }), 'user'); + * // => ['barney'] + * + * // using the `_.matchesProperty` callback shorthand + * _.pluck(_.reject(users, 'active', false), 'user'); + * // => ['fred'] + * + * // using the `_.property` callback shorthand + * _.pluck(_.reject(users, 'active'), 'user'); + * // => ['barney'] + */ + function reject(collection, predicate, thisArg) { + var func = isArray(collection) ? arrayFilter : baseFilter; + predicate = getCallback(predicate, thisArg, 3); + return func(collection, function(value, index, collection) { + return !predicate(value, index, collection); + }); + } - /** - * Used to reference the data object in the template text. - * - * @memberOf _.templateSettings - * @type string - */ - 'variable': '', + /** + * Gets a random element or `n` random elements from a collection. + * + * @static + * @memberOf _ + * @category Collection + * @param {Array|Object|string} collection The collection to sample. + * @param {number} [n] The number of elements to sample. + * @param- {Object} [guard] Enables use as a callback for functions like `_.map`. + * @returns {*} Returns the random sample(s). + * @example + * + * _.sample([1, 2, 3, 4]); + * // => 2 + * + * _.sample([1, 2, 3, 4], 2); + * // => [3, 1] + */ + function sample(collection, n, guard) { + if (guard ? isIterateeCall(collection, n, guard) : n == null) { + collection = toIterable(collection); + var length = collection.length; + return length > 0 ? collection[baseRandom(0, length - 1)] : undefined; + } + var index = -1, + result = toArray(collection), + length = result.length, + lastIndex = length - 1; - /** - * Used to import variables into the compiled template. - * - * @memberOf _.templateSettings - * @type Object - */ - 'imports': { + n = nativeMin(n < 0 ? 0 : (+n || 0), length); + while (++index < n) { + var rand = baseRandom(index, lastIndex), + value = result[rand]; - /** - * A reference to the `lodash` function. - * - * @memberOf _.templateSettings.imports - * @type Function - */ - '_': lodash + result[rand] = result[index]; + result[index] = value; } - }; + result.length = n; + return result; + } - /*--------------------------------------------------------------------------*/ + /** + * Creates an array of shuffled values, using a version of the + * [Fisher-Yates shuffle](https://en.wikipedia.org/wiki/Fisher-Yates_shuffle). + * + * @static + * @memberOf _ + * @category Collection + * @param {Array|Object|string} collection The collection to shuffle. + * @returns {Array} Returns the new shuffled array. + * @example + * + * _.shuffle([1, 2, 3, 4]); + * // => [4, 1, 3, 2] + */ + function shuffle(collection) { + return sample(collection, POSITIVE_INFINITY); + } /** - * The base implementation of `_.bind` that creates the bound function and - * sets its meta data. + * Gets the size of `collection` by returning its length for array-like + * values or the number of own enumerable properties for objects. * - * @private - * @param {Array} bindData The bind data array. - * @returns {Function} Returns the new bound function. + * @static + * @memberOf _ + * @category Collection + * @param {Array|Object|string} collection The collection to inspect. + * @returns {number} Returns the size of `collection`. + * @example + * + * _.size([1, 2, 3]); + * // => 3 + * + * _.size({ 'a': 1, 'b': 2 }); + * // => 2 + * + * _.size('pebbles'); + * // => 7 */ - function baseBind(bindData) { - var func = bindData[0], - partialArgs = bindData[2], - thisArg = bindData[4]; - - function bound() { - // `Function#bind` spec - // http://es5.github.io/#x15.3.4.5 - if (partialArgs) { - // avoid `arguments` object deoptimizations by using `slice` instead - // of `Array.prototype.slice.call` and not assigning `arguments` to a - // variable as a ternary expression - var args = slice(partialArgs); - push.apply(args, arguments); - } - // mimic the constructor's `return` behavior - // http://es5.github.io/#x13.2.2 - if (this instanceof bound) { - // ensure `new bound` is an instance of `func` - var thisBinding = baseCreate(func.prototype), - result = func.apply(thisBinding, args || arguments); - return isObject(result) ? result : thisBinding; - } - return func.apply(thisArg, args || arguments); - } - setBindData(bound, bindData); - return bound; + function size(collection) { + var length = collection ? getLength(collection) : 0; + return isLength(length) ? length : keys(collection).length; } /** - * The base implementation of `_.clone` without argument juggling or support - * for `thisArg` binding. + * Checks if `predicate` returns truthy for **any** element of `collection`. + * The function returns as soon as it finds a passing value and does not iterate + * over the entire collection. The predicate is bound to `thisArg` and invoked + * with three arguments: (value, index|key, collection). * - * @private - * @param {*} value The value to clone. - * @param {boolean} [isDeep=false] Specify a deep clone. - * @param {Function} [callback] The function to customize cloning values. - * @param {Array} [stackA=[]] Tracks traversed source objects. - * @param {Array} [stackB=[]] Associates clones with source counterparts. - * @returns {*} Returns the cloned value. + * If a property name is provided for `predicate` the created `_.property` + * style callback returns the property value of the given element. + * + * If a value is also provided for `thisArg` the created `_.matchesProperty` + * style callback returns `true` for elements that have a matching property + * value, else `false`. + * + * If an object is provided for `predicate` the created `_.matches` style + * callback returns `true` for elements that have the properties of the given + * object, else `false`. + * + * @static + * @memberOf _ + * @alias any + * @category Collection + * @param {Array|Object|string} collection The collection to iterate over. + * @param {Function|Object|string} [predicate=_.identity] The function invoked + * per iteration. + * @param {*} [thisArg] The `this` binding of `predicate`. + * @returns {boolean} Returns `true` if any element passes the predicate check, + * else `false`. + * @example + * + * _.some([null, 0, 'yes', false], Boolean); + * // => true + * + * var users = [ + * { 'user': 'barney', 'active': true }, + * { 'user': 'fred', 'active': false } + * ]; + * + * // using the `_.matches` callback shorthand + * _.some(users, { 'user': 'barney', 'active': false }); + * // => false + * + * // using the `_.matchesProperty` callback shorthand + * _.some(users, 'active', false); + * // => true + * + * // using the `_.property` callback shorthand + * _.some(users, 'active'); + * // => true */ - function baseClone(value, isDeep, callback, stackA, stackB) { - if (callback) { - var result = callback(value); - if (typeof result != 'undefined') { - return result; - } - } - // inspect [[Class]] - var isObj = isObject(value); - if (isObj) { - var className = toString.call(value); - if (!cloneableClasses[className]) { - return value; - } - var ctor = ctorByClass[className]; - switch (className) { - case boolClass: - case dateClass: - return new ctor(+value); - - case numberClass: - case stringClass: - return new ctor(value); - - case regexpClass: - result = ctor(value.source, reFlags.exec(value)); - result.lastIndex = value.lastIndex; - return result; - } - } else { - return value; - } - var isArr = isArray(value); - if (isDeep) { - // check for circular references and return corresponding clone - var initedStack = !stackA; - stackA || (stackA = getArray()); - stackB || (stackB = getArray()); - - var length = stackA.length; - while (length--) { - if (stackA[length] == value) { - return stackB[length]; - } - } - result = isArr ? ctor(value.length) : {}; + function some(collection, predicate, thisArg) { + var func = isArray(collection) ? arraySome : baseSome; + if (thisArg && isIterateeCall(collection, predicate, thisArg)) { + predicate = undefined; } - else { - result = isArr ? slice(value) : assign({}, value); + if (typeof predicate != 'function' || thisArg !== undefined) { + predicate = getCallback(predicate, thisArg, 3); } - // add array properties assigned by `RegExp#exec` - if (isArr) { - if (hasOwnProperty.call(value, 'index')) { - result.index = value.index; - } - if (hasOwnProperty.call(value, 'input')) { - result.input = value.input; - } + return func(collection, predicate); + } + + /** + * Creates an array of elements, sorted in ascending order by the results of + * running each element in a collection through `iteratee`. This method performs + * a stable sort, that is, it preserves the original sort order of equal elements. + * The `iteratee` is bound to `thisArg` and invoked with three arguments: + * (value, index|key, collection). + * + * If a property name is provided for `iteratee` the created `_.property` + * style callback returns the property value of the given element. + * + * If a value is also provided for `thisArg` the created `_.matchesProperty` + * style callback returns `true` for elements that have a matching property + * value, else `false`. + * + * If an object is provided for `iteratee` the created `_.matches` style + * callback returns `true` for elements that have the properties of the given + * object, else `false`. + * + * @static + * @memberOf _ + * @category Collection + * @param {Array|Object|string} collection The collection to iterate over. + * @param {Function|Object|string} [iteratee=_.identity] The function invoked + * per iteration. + * @param {*} [thisArg] The `this` binding of `iteratee`. + * @returns {Array} Returns the new sorted array. + * @example + * + * _.sortBy([1, 2, 3], function(n) { + * return Math.sin(n); + * }); + * // => [3, 1, 2] + * + * _.sortBy([1, 2, 3], function(n) { + * return this.sin(n); + * }, Math); + * // => [3, 1, 2] + * + * var users = [ + * { 'user': 'fred' }, + * { 'user': 'pebbles' }, + * { 'user': 'barney' } + * ]; + * + * // using the `_.property` callback shorthand + * _.pluck(_.sortBy(users, 'user'), 'user'); + * // => ['barney', 'fred', 'pebbles'] + */ + function sortBy(collection, iteratee, thisArg) { + if (collection == null) { + return []; } - // exit for shallow clone - if (!isDeep) { - return result; + if (thisArg && isIterateeCall(collection, iteratee, thisArg)) { + iteratee = undefined; } - // add the source value to the stack of traversed objects - // and associate it with its clone - stackA.push(value); - stackB.push(result); + var index = -1; + iteratee = getCallback(iteratee, thisArg, 3); - // recursively populate clone (susceptible to call stack limits) - (isArr ? forEach : forOwn)(value, function(objValue, key) { - result[key] = baseClone(objValue, isDeep, callback, stackA, stackB); + var result = baseMap(collection, function(value, key, collection) { + return { 'criteria': iteratee(value, key, collection), 'index': ++index, 'value': value }; }); - - if (initedStack) { - releaseArray(stackA); - releaseArray(stackB); - } - return result; + return baseSortBy(result, compareAscending); } /** - * The base implementation of `_.create` without support for assigning - * properties to the created object. + * This method is like `_.sortBy` except that it can sort by multiple iteratees + * or property names. * - * @private - * @param {Object} prototype The object to inherit from. - * @returns {Object} Returns the new object. + * If a property name is provided for an iteratee the created `_.property` + * style callback returns the property value of the given element. + * + * If an object is provided for an iteratee the created `_.matches` style + * callback returns `true` for elements that have the properties of the given + * object, else `false`. + * + * @static + * @memberOf _ + * @category Collection + * @param {Array|Object|string} collection The collection to iterate over. + * @param {...(Function|Function[]|Object|Object[]|string|string[])} iteratees + * The iteratees to sort by, specified as individual values or arrays of values. + * @returns {Array} Returns the new sorted array. + * @example + * + * var users = [ + * { 'user': 'fred', 'age': 48 }, + * { 'user': 'barney', 'age': 36 }, + * { 'user': 'fred', 'age': 42 }, + * { 'user': 'barney', 'age': 34 } + * ]; + * + * _.map(_.sortByAll(users, ['user', 'age']), _.values); + * // => [['barney', 34], ['barney', 36], ['fred', 42], ['fred', 48]] + * + * _.map(_.sortByAll(users, 'user', function(chr) { + * return Math.floor(chr.age / 10); + * }), _.values); + * // => [['barney', 36], ['barney', 34], ['fred', 48], ['fred', 42]] */ - function baseCreate(prototype, properties) { - return isObject(prototype) ? nativeCreate(prototype) : {}; - } - // fallback for browsers without `Object.create` - if (!nativeCreate) { - baseCreate = (function() { - function Object() {} - return function(prototype) { - if (isObject(prototype)) { - Object.prototype = prototype; - var result = new Object; - Object.prototype = null; - } - return result || context.Object(); - }; - }()); - } + var sortByAll = restParam(function(collection, iteratees) { + if (collection == null) { + return []; + } + var guard = iteratees[2]; + if (guard && isIterateeCall(iteratees[0], iteratees[1], guard)) { + iteratees.length = 1; + } + return baseSortByOrder(collection, baseFlatten(iteratees), []); + }); /** - * The base implementation of `_.createCallback` without support for creating - * "_.pluck" or "_.where" style callbacks. + * This method is like `_.sortByAll` except that it allows specifying the + * sort orders of the iteratees to sort by. If `orders` is unspecified, all + * values are sorted in ascending order. Otherwise, a value is sorted in + * ascending order if its corresponding order is "asc", and descending if "desc". * - * @private - * @param {*} [func=identity] The value to convert to a callback. - * @param {*} [thisArg] The `this` binding of the created callback. - * @param {number} [argCount] The number of arguments the callback accepts. - * @returns {Function} Returns a callback function. + * If a property name is provided for an iteratee the created `_.property` + * style callback returns the property value of the given element. + * + * If an object is provided for an iteratee the created `_.matches` style + * callback returns `true` for elements that have the properties of the given + * object, else `false`. + * + * @static + * @memberOf _ + * @category Collection + * @param {Array|Object|string} collection The collection to iterate over. + * @param {Function[]|Object[]|string[]} iteratees The iteratees to sort by. + * @param {boolean[]} [orders] The sort orders of `iteratees`. + * @param- {Object} [guard] Enables use as a callback for functions like `_.reduce`. + * @returns {Array} Returns the new sorted array. + * @example + * + * var users = [ + * { 'user': 'fred', 'age': 48 }, + * { 'user': 'barney', 'age': 34 }, + * { 'user': 'fred', 'age': 42 }, + * { 'user': 'barney', 'age': 36 } + * ]; + * + * // sort by `user` in ascending order and by `age` in descending order + * _.map(_.sortByOrder(users, ['user', 'age'], ['asc', 'desc']), _.values); + * // => [['barney', 36], ['barney', 34], ['fred', 48], ['fred', 42]] */ - function baseCreateCallback(func, thisArg, argCount) { - if (typeof func != 'function') { - return identity; - } - // exit early for no `thisArg` or already bound by `Function#bind` - if (typeof thisArg == 'undefined' || !('prototype' in func)) { - return func; + function sortByOrder(collection, iteratees, orders, guard) { + if (collection == null) { + return []; } - var bindData = func.__bindData__; - if (typeof bindData == 'undefined') { - if (support.funcNames) { - bindData = !func.name; - } - bindData = bindData || !support.funcDecomp; - if (!bindData) { - var source = fnToString.call(func); - if (!support.funcNames) { - bindData = !reFuncName.test(source); - } - if (!bindData) { - // checks if `func` references the `this` keyword and stores the result - bindData = reThis.test(source); - setBindData(func, bindData); - } - } + if (guard && isIterateeCall(iteratees, orders, guard)) { + orders = undefined; } - // exit early if there are no `this` references or `func` is bound - if (bindData === false || (bindData !== true && bindData[1] & 1)) { - return func; + if (!isArray(iteratees)) { + iteratees = iteratees == null ? [] : [iteratees]; } - switch (argCount) { - case 1: return function(value) { - return func.call(thisArg, value); - }; - case 2: return function(a, b) { - return func.call(thisArg, a, b); - }; - case 3: return function(value, index, collection) { - return func.call(thisArg, value, index, collection); - }; - case 4: return function(accumulator, value, index, collection) { - return func.call(thisArg, accumulator, value, index, collection); - }; + if (!isArray(orders)) { + orders = orders == null ? [] : [orders]; } - return bind(func, thisArg); + return baseSortByOrder(collection, iteratees, orders); } /** - * The base implementation of `createWrapper` that creates the wrapper and - * sets its meta data. + * Performs a deep comparison between each element in `collection` and the + * source object, returning an array of all elements that have equivalent + * property values. * - * @private - * @param {Array} bindData The bind data array. - * @returns {Function} Returns the new function. + * **Note:** This method supports comparing arrays, booleans, `Date` objects, + * numbers, `Object` objects, regexes, and strings. Objects are compared by + * their own, not inherited, enumerable properties. For comparing a single + * own or inherited property value see `_.matchesProperty`. + * + * @static + * @memberOf _ + * @category Collection + * @param {Array|Object|string} collection The collection to search. + * @param {Object} source The object of property values to match. + * @returns {Array} Returns the new filtered array. + * @example + * + * var users = [ + * { 'user': 'barney', 'age': 36, 'active': false, 'pets': ['hoppy'] }, + * { 'user': 'fred', 'age': 40, 'active': true, 'pets': ['baby puss', 'dino'] } + * ]; + * + * _.pluck(_.where(users, { 'age': 36, 'active': false }), 'user'); + * // => ['barney'] + * + * _.pluck(_.where(users, { 'pets': ['dino'] }), 'user'); + * // => ['fred'] */ - function baseCreateWrapper(bindData) { - var func = bindData[0], - bitmask = bindData[1], - partialArgs = bindData[2], - partialRightArgs = bindData[3], - thisArg = bindData[4], - arity = bindData[5]; - - var isBind = bitmask & 1, - isBindKey = bitmask & 2, - isCurry = bitmask & 4, - isCurryBound = bitmask & 8, - key = func; - - function bound() { - var thisBinding = isBind ? thisArg : this; - if (partialArgs) { - var args = slice(partialArgs); - push.apply(args, arguments); - } - if (partialRightArgs || isCurry) { - args || (args = slice(arguments)); - if (partialRightArgs) { - push.apply(args, partialRightArgs); - } - if (isCurry && args.length < arity) { - bitmask |= 16 & ~32; - return baseCreateWrapper([func, (isCurryBound ? bitmask : bitmask & ~3), args, null, thisArg, arity]); - } - } - args || (args = arguments); - if (isBindKey) { - func = thisBinding[key]; - } - if (this instanceof bound) { - thisBinding = baseCreate(func.prototype); - var result = func.apply(thisBinding, args); - return isObject(result) ? result : thisBinding; - } - return func.apply(thisBinding, args); - } - setBindData(bound, bindData); - return bound; + function where(collection, source) { + return filter(collection, baseMatches(source)); } + /*------------------------------------------------------------------------*/ + /** - * The base implementation of `_.difference` that accepts a single array - * of values to exclude. + * Gets the number of milliseconds that have elapsed since the Unix epoch + * (1 January 1970 00:00:00 UTC). * - * @private - * @param {Array} array The array to process. - * @param {Array} [values] The array of values to exclude. - * @returns {Array} Returns a new array of filtered values. + * @static + * @memberOf _ + * @category Date + * @example + * + * _.defer(function(stamp) { + * console.log(_.now() - stamp); + * }, _.now()); + * // => logs the number of milliseconds it took for the deferred function to be invoked */ - function baseDifference(array, values) { - var index = -1, - indexOf = getIndexOf(), - length = array ? array.length : 0, - isLarge = length >= largeArraySize && indexOf === baseIndexOf, - result = []; + var now = nativeNow || function() { + return new Date().getTime(); + }; - if (isLarge) { - var cache = createCache(values); - if (cache) { - indexOf = cacheIndexOf; - values = cache; + /*------------------------------------------------------------------------*/ + + /** + * The opposite of `_.before`; this method creates a function that invokes + * `func` once it is called `n` or more times. + * + * @static + * @memberOf _ + * @category Function + * @param {number} n The number of calls before `func` is invoked. + * @param {Function} func The function to restrict. + * @returns {Function} Returns the new restricted function. + * @example + * + * var saves = ['profile', 'settings']; + * + * var done = _.after(saves.length, function() { + * console.log('done saving!'); + * }); + * + * _.forEach(saves, function(type) { + * asyncSave({ 'type': type, 'complete': done }); + * }); + * // => logs 'done saving!' after the two async saves have completed + */ + function after(n, func) { + if (typeof func != 'function') { + if (typeof n == 'function') { + var temp = n; + n = func; + func = temp; } else { - isLarge = false; + throw new TypeError(FUNC_ERROR_TEXT); } } - while (++index < length) { - var value = array[index]; - if (indexOf(values, value) < 0) { - result.push(value); + n = nativeIsFinite(n = +n) ? n : 0; + return function() { + if (--n < 1) { + return func.apply(this, arguments); } - } - if (isLarge) { - releaseObject(values); - } - return result; + }; } /** - * The base implementation of `_.flatten` without support for callback - * shorthands or `thisArg` binding. + * Creates a function that accepts up to `n` arguments ignoring any + * additional arguments. * - * @private - * @param {Array} array The array to flatten. - * @param {boolean} [isShallow=false] A flag to restrict flattening to a single level. - * @param {boolean} [isStrict=false] A flag to restrict flattening to arrays and `arguments` objects. - * @param {number} [fromIndex=0] The index to start from. - * @returns {Array} Returns a new flattened array. + * @static + * @memberOf _ + * @category Function + * @param {Function} func The function to cap arguments for. + * @param {number} [n=func.length] The arity cap. + * @param- {Object} [guard] Enables use as a callback for functions like `_.map`. + * @returns {Function} Returns the new function. + * @example + * + * _.map(['6', '8', '10'], _.ary(parseInt, 1)); + * // => [6, 8, 10] */ - function baseFlatten(array, isShallow, isStrict, fromIndex) { - var index = (fromIndex || 0) - 1, - length = array ? array.length : 0, - result = []; - - while (++index < length) { - var value = array[index]; - - if (value && typeof value == 'object' && typeof value.length == 'number' - && (isArray(value) || isArguments(value))) { - // recursively flatten arrays (susceptible to call stack limits) - if (!isShallow) { - value = baseFlatten(value, isShallow, isStrict); - } - var valIndex = -1, - valLength = value.length, - resIndex = result.length; - - result.length += valLength; - while (++valIndex < valLength) { - result[resIndex++] = value[valIndex]; - } - } else if (!isStrict) { - result.push(value); - } + function ary(func, n, guard) { + if (guard && isIterateeCall(func, n, guard)) { + n = undefined; } - return result; + n = (func && n == null) ? func.length : nativeMax(+n || 0, 0); + return createWrapper(func, ARY_FLAG, undefined, undefined, undefined, undefined, n); } /** - * The base implementation of `_.isEqual`, without support for `thisArg` binding, - * that allows partial "_.where" style comparisons. + * Creates a function that invokes `func`, with the `this` binding and arguments + * of the created function, while it is called less than `n` times. Subsequent + * calls to the created function return the result of the last `func` invocation. * - * @private - * @param {*} a The value to compare. - * @param {*} b The other value to compare. - * @param {Function} [callback] The function to customize comparing values. - * @param {Function} [isWhere=false] A flag to indicate performing partial comparisons. - * @param {Array} [stackA=[]] Tracks traversed `a` objects. - * @param {Array} [stackB=[]] Tracks traversed `b` objects. - * @returns {boolean} Returns `true` if the values are equivalent, else `false`. + * @static + * @memberOf _ + * @category Function + * @param {number} n The number of calls at which `func` is no longer invoked. + * @param {Function} func The function to restrict. + * @returns {Function} Returns the new restricted function. + * @example + * + * jQuery('#add').on('click', _.before(5, addContactToList)); + * // => allows adding up to 4 contacts to the list */ - function baseIsEqual(a, b, callback, isWhere, stackA, stackB) { - // used to indicate that when comparing objects, `a` has at least the properties of `b` - if (callback) { - var result = callback(a, b); - if (typeof result != 'undefined') { - return !!result; + function before(n, func) { + var result; + if (typeof func != 'function') { + if (typeof n == 'function') { + var temp = n; + n = func; + func = temp; + } else { + throw new TypeError(FUNC_ERROR_TEXT); } } - // exit early for identical values - if (a === b) { - // treat `+0` vs. `-0` as not equal - return a !== 0 || (1 / a == 1 / b); - } - var type = typeof a, - otherType = typeof b; - - // exit early for unlike primitive values - if (a === a && - !(a && objectTypes[type]) && - !(b && objectTypes[otherType])) { - return false; - } - // exit early for `null` and `undefined` avoiding ES3's Function#call behavior - // http://es5.github.io/#x15.3.4.4 - if (a == null || b == null) { - return a === b; - } - // compare [[Class]] names - var className = toString.call(a), - otherClass = toString.call(b); - - if (className == argsClass) { - className = objectClass; - } - if (otherClass == argsClass) { - otherClass = objectClass; - } - if (className != otherClass) { - return false; - } - switch (className) { - case boolClass: - case dateClass: - // coerce dates and booleans to numbers, dates to milliseconds and booleans - // to `1` or `0` treating invalid dates coerced to `NaN` as not equal - return +a == +b; - - case numberClass: - // treat `NaN` vs. `NaN` as equal - return (a != +a) - ? b != +b - // but treat `+0` vs. `-0` as not equal - : (a == 0 ? (1 / a == 1 / b) : a == +b); - - case regexpClass: - case stringClass: - // coerce regexes to strings (http://es5.github.io/#x15.10.6.4) - // treat string primitives and their corresponding object instances as equal - return a == String(b); - } - var isArr = className == arrayClass; - if (!isArr) { - // unwrap any `lodash` wrapped values - var aWrapped = hasOwnProperty.call(a, '__wrapped__'), - bWrapped = hasOwnProperty.call(b, '__wrapped__'); - - if (aWrapped || bWrapped) { - return baseIsEqual(aWrapped ? a.__wrapped__ : a, bWrapped ? b.__wrapped__ : b, callback, isWhere, stackA, stackB); - } - // exit for functions and DOM nodes - if (className != objectClass) { - return false; + return function() { + if (--n > 0) { + result = func.apply(this, arguments); } - // in older versions of Opera, `arguments` objects have `Array` constructors - var ctorA = a.constructor, - ctorB = b.constructor; - - // non `Object` object instances with different constructors are not equal - if (ctorA != ctorB && - !(isFunction(ctorA) && ctorA instanceof ctorA && isFunction(ctorB) && ctorB instanceof ctorB) && - ('constructor' in a && 'constructor' in b) - ) { - return false; + if (n <= 1) { + func = undefined; } - } - // assume cyclic structures are equal - // the algorithm for detecting cyclic structures is adapted from ES 5.1 - // section 15.12.3, abstract operation `JO` (http://es5.github.io/#x15.12.3) - var initedStack = !stackA; - stackA || (stackA = getArray()); - stackB || (stackB = getArray()); + return result; + }; + } - var length = stackA.length; - while (length--) { - if (stackA[length] == a) { - return stackB[length] == b; - } + /** + * Creates a function that invokes `func` with the `this` binding of `thisArg` + * and prepends any additional `_.bind` arguments to those provided to the + * bound function. + * + * The `_.bind.placeholder` value, which defaults to `_` in monolithic builds, + * may be used as a placeholder for partially applied arguments. + * + * **Note:** Unlike native `Function#bind` this method does not set the "length" + * property of bound functions. + * + * @static + * @memberOf _ + * @category Function + * @param {Function} func The function to bind. + * @param {*} thisArg The `this` binding of `func`. + * @param {...*} [partials] The arguments to be partially applied. + * @returns {Function} Returns the new bound function. + * @example + * + * var greet = function(greeting, punctuation) { + * return greeting + ' ' + this.user + punctuation; + * }; + * + * var object = { 'user': 'fred' }; + * + * var bound = _.bind(greet, object, 'hi'); + * bound('!'); + * // => 'hi fred!' + * + * // using placeholders + * var bound = _.bind(greet, object, _, '!'); + * bound('hi'); + * // => 'hi fred!' + */ + var bind = restParam(function(func, thisArg, partials) { + var bitmask = BIND_FLAG; + if (partials.length) { + var holders = replaceHolders(partials, bind.placeholder); + bitmask |= PARTIAL_FLAG; } - var size = 0; - result = true; + return createWrapper(func, bitmask, thisArg, partials, holders); + }); - // add `a` and `b` to the stack of traversed objects - stackA.push(a); - stackB.push(b); + /** + * Binds methods of an object to the object itself, overwriting the existing + * method. Method names may be specified as individual arguments or as arrays + * of method names. If no method names are provided all enumerable function + * properties, own and inherited, of `object` are bound. + * + * **Note:** This method does not set the "length" property of bound functions. + * + * @static + * @memberOf _ + * @category Function + * @param {Object} object The object to bind and assign the bound methods to. + * @param {...(string|string[])} [methodNames] The object method names to bind, + * specified as individual method names or arrays of method names. + * @returns {Object} Returns `object`. + * @example + * + * var view = { + * 'label': 'docs', + * 'onClick': function() { + * console.log('clicked ' + this.label); + * } + * }; + * + * _.bindAll(view); + * jQuery('#docs').on('click', view.onClick); + * // => logs 'clicked docs' when the element is clicked + */ + var bindAll = restParam(function(object, methodNames) { + methodNames = methodNames.length ? baseFlatten(methodNames) : functions(object); - // recursively compare objects and arrays (susceptible to call stack limits) - if (isArr) { - // compare lengths to determine if a deep comparison is necessary - length = a.length; - size = b.length; - result = size == length; - - if (result || isWhere) { - // deep compare the contents, ignoring non-numeric properties - while (size--) { - var index = length, - value = b[size]; - - if (isWhere) { - while (index--) { - if ((result = baseIsEqual(a[index], value, callback, isWhere, stackA, stackB))) { - break; - } - } - } else if (!(result = baseIsEqual(a[size], value, callback, isWhere, stackA, stackB))) { - break; - } - } - } - } - else { - // deep compare objects using `forIn`, instead of `forOwn`, to avoid `Object.keys` - // which, in this case, is more costly - forIn(b, function(value, key, b) { - if (hasOwnProperty.call(b, key)) { - // count the number of properties. - size++; - // deep compare each property value. - return (result = hasOwnProperty.call(a, key) && baseIsEqual(a[key], value, callback, isWhere, stackA, stackB)); - } - }); + var index = -1, + length = methodNames.length; - if (result && !isWhere) { - // ensure both objects have the same number of properties - forIn(a, function(value, key, a) { - if (hasOwnProperty.call(a, key)) { - // `size` will be `-1` if `a` has more properties than `b` - return (result = --size > -1); - } - }); - } + while (++index < length) { + var key = methodNames[index]; + object[key] = createWrapper(object[key], BIND_FLAG, object); } - stackA.pop(); - stackB.pop(); + return object; + }); - if (initedStack) { - releaseArray(stackA); - releaseArray(stackB); + /** + * Creates a function that invokes the method at `object[key]` and prepends + * any additional `_.bindKey` arguments to those provided to the bound function. + * + * This method differs from `_.bind` by allowing bound functions to reference + * methods that may be redefined or don't yet exist. + * See [Peter Michaux's article](http://peter.michaux.ca/articles/lazy-function-definition-pattern) + * for more details. + * + * The `_.bindKey.placeholder` value, which defaults to `_` in monolithic + * builds, may be used as a placeholder for partially applied arguments. + * + * @static + * @memberOf _ + * @category Function + * @param {Object} object The object the method belongs to. + * @param {string} key The key of the method. + * @param {...*} [partials] The arguments to be partially applied. + * @returns {Function} Returns the new bound function. + * @example + * + * var object = { + * 'user': 'fred', + * 'greet': function(greeting, punctuation) { + * return greeting + ' ' + this.user + punctuation; + * } + * }; + * + * var bound = _.bindKey(object, 'greet', 'hi'); + * bound('!'); + * // => 'hi fred!' + * + * object.greet = function(greeting, punctuation) { + * return greeting + 'ya ' + this.user + punctuation; + * }; + * + * bound('!'); + * // => 'hiya fred!' + * + * // using placeholders + * var bound = _.bindKey(object, 'greet', _, '!'); + * bound('hi'); + * // => 'hiya fred!' + */ + var bindKey = restParam(function(object, key, partials) { + var bitmask = BIND_FLAG | BIND_KEY_FLAG; + if (partials.length) { + var holders = replaceHolders(partials, bindKey.placeholder); + bitmask |= PARTIAL_FLAG; } - return result; - } + return createWrapper(key, bitmask, object, partials, holders); + }); /** - * The base implementation of `_.merge` without argument juggling or support - * for `thisArg` binding. + * Creates a function that accepts one or more arguments of `func` that when + * called either invokes `func` returning its result, if all `func` arguments + * have been provided, or returns a function that accepts one or more of the + * remaining `func` arguments, and so on. The arity of `func` may be specified + * if `func.length` is not sufficient. * - * @private - * @param {Object} object The destination object. - * @param {Object} source The source object. - * @param {Function} [callback] The function to customize merging properties. - * @param {Array} [stackA=[]] Tracks traversed source objects. - * @param {Array} [stackB=[]] Associates values with source counterparts. + * The `_.curry.placeholder` value, which defaults to `_` in monolithic builds, + * may be used as a placeholder for provided arguments. + * + * **Note:** This method does not set the "length" property of curried functions. + * + * @static + * @memberOf _ + * @category Function + * @param {Function} func The function to curry. + * @param {number} [arity=func.length] The arity of `func`. + * @param- {Object} [guard] Enables use as a callback for functions like `_.map`. + * @returns {Function} Returns the new curried function. + * @example + * + * var abc = function(a, b, c) { + * return [a, b, c]; + * }; + * + * var curried = _.curry(abc); + * + * curried(1)(2)(3); + * // => [1, 2, 3] + * + * curried(1, 2)(3); + * // => [1, 2, 3] + * + * curried(1, 2, 3); + * // => [1, 2, 3] + * + * // using placeholders + * curried(1)(_, 3)(2); + * // => [1, 2, 3] */ - function baseMerge(object, source, callback, stackA, stackB) { - (isArray(source) ? forEach : forOwn)(source, function(source, key) { - var found, - isArr, - result = source, - value = object[key]; - - if (source && ((isArr = isArray(source)) || isPlainObject(source))) { - // avoid merging previously merged cyclic sources - var stackLength = stackA.length; - while (stackLength--) { - if ((found = stackA[stackLength] == source)) { - value = stackB[stackLength]; - break; - } - } - if (!found) { - var isShallow; - if (callback) { - result = callback(value, source); - if ((isShallow = typeof result != 'undefined')) { - value = result; - } - } - if (!isShallow) { - value = isArr - ? (isArray(value) ? value : []) - : (isPlainObject(value) ? value : {}); - } - // add `source` and associated `value` to the stack of traversed objects - stackA.push(source); - stackB.push(value); - - // recursively merge objects and arrays (susceptible to call stack limits) - if (!isShallow) { - baseMerge(value, source, callback, stackA, stackB); - } - } - } - else { - if (callback) { - result = callback(value, source); - if (typeof result == 'undefined') { - result = source; - } - } - if (typeof result != 'undefined') { - value = result; - } - } - object[key] = value; - }); - } + var curry = createCurry(CURRY_FLAG); /** - * The base implementation of `_.random` without argument juggling or support - * for returning floating-point numbers. + * This method is like `_.curry` except that arguments are applied to `func` + * in the manner of `_.partialRight` instead of `_.partial`. * - * @private - * @param {number} min The minimum possible value. - * @param {number} max The maximum possible value. - * @returns {number} Returns a random number. + * The `_.curryRight.placeholder` value, which defaults to `_` in monolithic + * builds, may be used as a placeholder for provided arguments. + * + * **Note:** This method does not set the "length" property of curried functions. + * + * @static + * @memberOf _ + * @category Function + * @param {Function} func The function to curry. + * @param {number} [arity=func.length] The arity of `func`. + * @param- {Object} [guard] Enables use as a callback for functions like `_.map`. + * @returns {Function} Returns the new curried function. + * @example + * + * var abc = function(a, b, c) { + * return [a, b, c]; + * }; + * + * var curried = _.curryRight(abc); + * + * curried(3)(2)(1); + * // => [1, 2, 3] + * + * curried(2, 3)(1); + * // => [1, 2, 3] + * + * curried(1, 2, 3); + * // => [1, 2, 3] + * + * // using placeholders + * curried(3)(1, _)(2); + * // => [1, 2, 3] */ - function baseRandom(min, max) { - return min + floor(nativeRandom() * (max - min + 1)); - } + var curryRight = createCurry(CURRY_RIGHT_FLAG); /** - * The base implementation of `_.uniq` without support for callback shorthands - * or `thisArg` binding. + * Creates a debounced function that delays invoking `func` until after `wait` + * milliseconds have elapsed since the last time the debounced function was + * invoked. The debounced function comes with a `cancel` method to cancel + * delayed invocations. Provide an options object to indicate that `func` + * should be invoked on the leading and/or trailing edge of the `wait` timeout. + * Subsequent calls to the debounced function return the result of the last + * `func` invocation. + * + * **Note:** If `leading` and `trailing` options are `true`, `func` is invoked + * on the trailing edge of the timeout only if the the debounced function is + * invoked more than once during the `wait` timeout. * - * @private - * @param {Array} array The array to process. - * @param {boolean} [isSorted=false] A flag to indicate that `array` is sorted. - * @param {Function} [callback] The function called per iteration. - * @returns {Array} Returns a duplicate-value-free array. + * See [David Corbacho's article](http://drupalmotion.com/article/debounce-and-throttle-visual-explanation) + * for details over the differences between `_.debounce` and `_.throttle`. + * + * @static + * @memberOf _ + * @category Function + * @param {Function} func The function to debounce. + * @param {number} [wait=0] The number of milliseconds to delay. + * @param {Object} [options] The options object. + * @param {boolean} [options.leading=false] Specify invoking on the leading + * edge of the timeout. + * @param {number} [options.maxWait] The maximum time `func` is allowed to be + * delayed before it is invoked. + * @param {boolean} [options.trailing=true] Specify invoking on the trailing + * edge of the timeout. + * @returns {Function} Returns the new debounced function. + * @example + * + * // avoid costly calculations while the window size is in flux + * jQuery(window).on('resize', _.debounce(calculateLayout, 150)); + * + * // invoke `sendMail` when the click event is fired, debouncing subsequent calls + * jQuery('#postbox').on('click', _.debounce(sendMail, 300, { + * 'leading': true, + * 'trailing': false + * })); + * + * // ensure `batchLog` is invoked once after 1 second of debounced calls + * var source = new EventSource('/stream'); + * jQuery(source).on('message', _.debounce(batchLog, 250, { + * 'maxWait': 1000 + * })); + * + * // cancel a debounced call + * var todoChanges = _.debounce(batchLog, 1000); + * Object.observe(models.todo, todoChanges); + * + * Object.observe(models, function(changes) { + * if (_.find(changes, { 'user': 'todo', 'type': 'delete'})) { + * todoChanges.cancel(); + * } + * }, ['delete']); + * + * // ...at some point `models.todo` is changed + * models.todo.completed = true; + * + * // ...before 1 second has passed `models.todo` is deleted + * // which cancels the debounced `todoChanges` call + * delete models.todo; */ - function baseUniq(array, isSorted, callback) { - var index = -1, - indexOf = getIndexOf(), - length = array ? array.length : 0, - result = []; + function debounce(func, wait, options) { + var args, + maxTimeoutId, + result, + stamp, + thisArg, + timeoutId, + trailingCall, + lastCalled = 0, + maxWait = false, + trailing = true; - var isLarge = !isSorted && length >= largeArraySize && indexOf === baseIndexOf, - seen = (callback || isLarge) ? getArray() : result; + if (typeof func != 'function') { + throw new TypeError(FUNC_ERROR_TEXT); + } + wait = wait < 0 ? 0 : (+wait || 0); + if (options === true) { + var leading = true; + trailing = false; + } else if (isObject(options)) { + leading = !!options.leading; + maxWait = 'maxWait' in options && nativeMax(+options.maxWait || 0, wait); + trailing = 'trailing' in options ? !!options.trailing : trailing; + } - if (isLarge) { - var cache = createCache(seen); - indexOf = cacheIndexOf; - seen = cache; + function cancel() { + if (timeoutId) { + clearTimeout(timeoutId); + } + if (maxTimeoutId) { + clearTimeout(maxTimeoutId); + } + lastCalled = 0; + maxTimeoutId = timeoutId = trailingCall = undefined; } - while (++index < length) { - var value = array[index], - computed = callback ? callback(value, index, array) : value; - if (isSorted - ? !index || seen[seen.length - 1] !== computed - : indexOf(seen, computed) < 0 - ) { - if (callback || isLarge) { - seen.push(computed); + function complete(isCalled, id) { + if (id) { + clearTimeout(id); + } + maxTimeoutId = timeoutId = trailingCall = undefined; + if (isCalled) { + lastCalled = now(); + result = func.apply(thisArg, args); + if (!timeoutId && !maxTimeoutId) { + args = thisArg = undefined; } - result.push(value); } } - if (isLarge) { - releaseArray(seen.array); - releaseObject(seen); - } else if (callback) { - releaseArray(seen); + + function delayed() { + var remaining = wait - (now() - stamp); + if (remaining <= 0 || remaining > wait) { + complete(trailingCall, maxTimeoutId); + } else { + timeoutId = setTimeout(delayed, remaining); + } } - return result; - } - /** - * Creates a function that aggregates a collection, creating an object composed - * of keys generated from the results of running each element of the collection - * through a callback. The given `setter` function sets the keys and values - * of the composed object. - * - * @private - * @param {Function} setter The setter function. - * @returns {Function} Returns the new aggregator function. - */ - function createAggregator(setter) { - return function(collection, callback, thisArg) { - var result = {}; - callback = lodash.createCallback(callback, thisArg, 3); + function maxDelayed() { + complete(trailing, timeoutId); + } - var index = -1, - length = collection ? collection.length : 0; + function debounced() { + args = arguments; + stamp = now(); + thisArg = this; + trailingCall = trailing && (timeoutId || !leading); - if (typeof length == 'number') { - while (++index < length) { - var value = collection[index]; - setter(result, value, callback(value, index, collection), collection); - } + if (maxWait === false) { + var leadingCall = leading && !timeoutId; } else { - forOwn(collection, function(value, key, collection) { - setter(result, value, callback(value, key, collection), collection); - }); - } - return result; - }; - } + if (!maxTimeoutId && !leading) { + lastCalled = stamp; + } + var remaining = maxWait - (stamp - lastCalled), + isCalled = remaining <= 0 || remaining > maxWait; - /** - * Creates a function that, when called, either curries or invokes `func` - * with an optional `this` binding and partially applied arguments. - * - * @private - * @param {Function|string} func The function or method name to reference. - * @param {number} bitmask The bitmask of method flags to compose. - * The bitmask may be composed of the following flags: - * 1 - `_.bind` - * 2 - `_.bindKey` - * 4 - `_.curry` - * 8 - `_.curry` (bound) - * 16 - `_.partial` - * 32 - `_.partialRight` - * @param {Array} [partialArgs] An array of arguments to prepend to those - * provided to the new function. - * @param {Array} [partialRightArgs] An array of arguments to append to those - * provided to the new function. - * @param {*} [thisArg] The `this` binding of `func`. - * @param {number} [arity] The arity of `func`. - * @returns {Function} Returns the new function. - */ - function createWrapper(func, bitmask, partialArgs, partialRightArgs, thisArg, arity) { - var isBind = bitmask & 1, - isBindKey = bitmask & 2, - isCurry = bitmask & 4, - isCurryBound = bitmask & 8, - isPartial = bitmask & 16, - isPartialRight = bitmask & 32; - - if (!isBindKey && !isFunction(func)) { - throw new TypeError; - } - if (isPartial && !partialArgs.length) { - bitmask &= ~16; - isPartial = partialArgs = false; - } - if (isPartialRight && !partialRightArgs.length) { - bitmask &= ~32; - isPartialRight = partialRightArgs = false; - } - var bindData = func && func.__bindData__; - if (bindData && bindData !== true) { - // clone `bindData` - bindData = slice(bindData); - if (bindData[2]) { - bindData[2] = slice(bindData[2]); - } - if (bindData[3]) { - bindData[3] = slice(bindData[3]); - } - // set `thisBinding` is not previously bound - if (isBind && !(bindData[1] & 1)) { - bindData[4] = thisArg; + if (isCalled) { + if (maxTimeoutId) { + maxTimeoutId = clearTimeout(maxTimeoutId); + } + lastCalled = stamp; + result = func.apply(thisArg, args); + } + else if (!maxTimeoutId) { + maxTimeoutId = setTimeout(maxDelayed, remaining); + } } - // set if previously bound but not currently (subsequent curried functions) - if (!isBind && bindData[1] & 1) { - bitmask |= 8; + if (isCalled && timeoutId) { + timeoutId = clearTimeout(timeoutId); } - // set curried arity if not yet set - if (isCurry && !(bindData[1] & 4)) { - bindData[5] = arity; + else if (!timeoutId && wait !== maxWait) { + timeoutId = setTimeout(delayed, wait); } - // append partial left arguments - if (isPartial) { - push.apply(bindData[2] || (bindData[2] = []), partialArgs); + if (leadingCall) { + isCalled = true; + result = func.apply(thisArg, args); } - // append partial right arguments - if (isPartialRight) { - unshift.apply(bindData[3] || (bindData[3] = []), partialRightArgs); + if (isCalled && !timeoutId && !maxTimeoutId) { + args = thisArg = undefined; } - // merge flags - bindData[1] |= bitmask; - return createWrapper.apply(null, bindData); - } - // fast path for `_.bind` - var creater = (bitmask == 1 || bitmask === 17) ? baseBind : baseCreateWrapper; - return creater([func, bitmask, partialArgs, partialRightArgs, thisArg, arity]); - } - - /** - * Used by `escape` to convert characters to HTML entities. - * - * @private - * @param {string} match The matched character to escape. - * @returns {string} Returns the escaped character. - */ - function escapeHtmlChar(match) { - return htmlEscapes[match]; - } - - /** - * Gets the appropriate "indexOf" function. If the `_.indexOf` method is - * customized, this method returns the custom method, otherwise it returns - * the `baseIndexOf` function. - * - * @private - * @returns {Function} Returns the "indexOf" function. - */ - function getIndexOf() { - var result = (result = lodash.indexOf) === indexOf ? baseIndexOf : result; - return result; - } - - /** - * Checks if `value` is a native function. - * - * @private - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if the `value` is a native function, else `false`. - */ - function isNative(value) { - return typeof value == 'function' && reNative.test(value); - } - - /** - * Sets `this` binding data on a given function. - * - * @private - * @param {Function} func The function to set data on. - * @param {Array} value The data array to set. - */ - var setBindData = !defineProperty ? noop : function(func, value) { - descriptor.value = value; - defineProperty(func, '__bindData__', descriptor); - }; - - /** - * A fallback implementation of `isPlainObject` which checks if a given value - * is an object created by the `Object` constructor, assuming objects created - * by the `Object` constructor have no inherited enumerable properties and that - * there are no `Object.prototype` extensions. - * - * @private - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is a plain object, else `false`. - */ - function shimIsPlainObject(value) { - var ctor, - result; - - // avoid non Object objects, `arguments` objects, and DOM elements - if (!(value && toString.call(value) == objectClass) || - (ctor = value.constructor, isFunction(ctor) && !(ctor instanceof ctor))) { - return false; - } - // In most environments an object's own properties are iterated before - // its inherited properties. If the last iterated property is an object's - // own property then there are no inherited enumerable properties. - forIn(value, function(value, key) { - result = key; - }); - return typeof result == 'undefined' || hasOwnProperty.call(value, result); - } - - /** - * Used by `unescape` to convert HTML entities to characters. - * - * @private - * @param {string} match The matched character to unescape. - * @returns {string} Returns the unescaped character. - */ - function unescapeHtmlChar(match) { - return htmlUnescapes[match]; + return result; + } + debounced.cancel = cancel; + return debounced; } - /*--------------------------------------------------------------------------*/ - /** - * Checks if `value` is an `arguments` object. + * Defers invoking the `func` until the current call stack has cleared. Any + * additional arguments are provided to `func` when it is invoked. * * @static * @memberOf _ - * @category Objects - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if the `value` is an `arguments` object, else `false`. + * @category Function + * @param {Function} func The function to defer. + * @param {...*} [args] The arguments to invoke the function with. + * @returns {number} Returns the timer id. * @example * - * (function() { return _.isArguments(arguments); })(1, 2, 3); - * // => true - * - * _.isArguments([1, 2, 3]); - * // => false + * _.defer(function(text) { + * console.log(text); + * }, 'deferred'); + * // logs 'deferred' after one or more milliseconds */ - function isArguments(value) { - return value && typeof value == 'object' && typeof value.length == 'number' && - toString.call(value) == argsClass || false; - } + var defer = restParam(function(func, args) { + return baseDelay(func, 1, args); + }); /** - * Checks if `value` is an array. + * Invokes `func` after `wait` milliseconds. Any additional arguments are + * provided to `func` when it is invoked. * * @static * @memberOf _ - * @type Function - * @category Objects - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if the `value` is an array, else `false`. + * @category Function + * @param {Function} func The function to delay. + * @param {number} wait The number of milliseconds to delay invocation. + * @param {...*} [args] The arguments to invoke the function with. + * @returns {number} Returns the timer id. * @example * - * (function() { return _.isArray(arguments); })(); - * // => false - * - * _.isArray([1, 2, 3]); - * // => true + * _.delay(function(text) { + * console.log(text); + * }, 1000, 'later'); + * // => logs 'later' after one second */ - var isArray = nativeIsArray || function(value) { - return value && typeof value == 'object' && typeof value.length == 'number' && - toString.call(value) == arrayClass || false; - }; - - /** - * A fallback implementation of `Object.keys` which produces an array of the - * given object's own enumerable property names. - * - * @private - * @type Function - * @param {Object} object The object to inspect. - * @returns {Array} Returns an array of property names. - */ - var shimKeys = function(object) { - var index, iterable = object, result = []; - if (!iterable) return result; - if (!(objectTypes[typeof object])) return result; - for (index in iterable) { - if (hasOwnProperty.call(iterable, index)) { - result.push(index); - } - } - return result - }; + var delay = restParam(function(func, wait, args) { + return baseDelay(func, wait, args); + }); /** - * Creates an array composed of the own enumerable property names of an object. + * Creates a function that returns the result of invoking the provided + * functions with the `this` binding of the created function, where each + * successive invocation is supplied the return value of the previous. * * @static * @memberOf _ - * @category Objects - * @param {Object} object The object to inspect. - * @returns {Array} Returns an array of property names. + * @category Function + * @param {...Function} [funcs] Functions to invoke. + * @returns {Function} Returns the new function. * @example * - * _.keys({ 'one': 1, 'two': 2, 'three': 3 }); - * // => ['one', 'two', 'three'] (property order is not guaranteed across environments) - */ - var keys = !nativeKeys ? shimKeys : function(object) { - if (!isObject(object)) { - return []; - } - return nativeKeys(object); - }; - - /** - * Used to convert characters to HTML entities: + * function square(n) { + * return n * n; + * } * - * Though the `>` character is escaped for symmetry, characters like `>` and `/` - * don't require escaping in HTML and have no special meaning unless they're part - * of a tag or an unquoted attribute value. - * http://mathiasbynens.be/notes/ambiguous-ampersands (under "semi-related fun fact") + * var addSquare = _.flow(_.add, square); + * addSquare(1, 2); + * // => 9 */ - var htmlEscapes = { - '&': '&', - '<': '<', - '>': '>', - '"': '"', - "'": ''' - }; - - /** Used to convert HTML entities to characters */ - var htmlUnescapes = invert(htmlEscapes); - - /** Used to match HTML entities and HTML characters */ - var reEscapedHtml = RegExp('(' + keys(htmlUnescapes).join('|') + ')', 'g'), - reUnescapedHtml = RegExp('[' + keys(htmlEscapes).join('') + ']', 'g'); - - /*--------------------------------------------------------------------------*/ + var flow = createFlow(); /** - * Assigns own enumerable properties of source object(s) to the destination - * object. Subsequent sources will overwrite property assignments of previous - * sources. If a callback is provided it will be executed to produce the - * assigned values. The callback is bound to `thisArg` and invoked with two - * arguments; (objectValue, sourceValue). + * This method is like `_.flow` except that it creates a function that + * invokes the provided functions from right to left. * * @static * @memberOf _ - * @type Function - * @alias extend - * @category Objects - * @param {Object} object The destination object. - * @param {...Object} [source] The source objects. - * @param {Function} [callback] The function to customize assigning values. - * @param {*} [thisArg] The `this` binding of `callback`. - * @returns {Object} Returns the destination object. + * @alias backflow, compose + * @category Function + * @param {...Function} [funcs] Functions to invoke. + * @returns {Function} Returns the new function. * @example * - * _.assign({ 'name': 'fred' }, { 'employer': 'slate' }); - * // => { 'name': 'fred', 'employer': 'slate' } - * - * var defaults = _.partialRight(_.assign, function(a, b) { - * return typeof a == 'undefined' ? b : a; - * }); + * function square(n) { + * return n * n; + * } * - * var object = { 'name': 'barney' }; - * defaults(object, { 'name': 'fred', 'employer': 'slate' }); - * // => { 'name': 'barney', 'employer': 'slate' } + * var addSquare = _.flowRight(square, _.add); + * addSquare(1, 2); + * // => 9 */ - var assign = function(object, source, guard) { - var index, iterable = object, result = iterable; - if (!iterable) return result; - var args = arguments, - argsIndex = 0, - argsLength = typeof guard == 'number' ? 2 : args.length; - if (argsLength > 3 && typeof args[argsLength - 2] == 'function') { - var callback = baseCreateCallback(args[--argsLength - 1], args[argsLength--], 2); - } else if (argsLength > 2 && typeof args[argsLength - 1] == 'function') { - callback = args[--argsLength]; - } - while (++argsIndex < argsLength) { - iterable = args[argsIndex]; - if (iterable && objectTypes[typeof iterable]) { - var ownIndex = -1, - ownProps = objectTypes[typeof iterable] && keys(iterable), - length = ownProps ? ownProps.length : 0; - - while (++ownIndex < length) { - index = ownProps[ownIndex]; - result[index] = callback ? callback(result[index], iterable[index]) : iterable[index]; - } - } - } - return result - }; + var flowRight = createFlow(true); /** - * Creates a clone of `value`. If `isDeep` is `true` nested objects will also - * be cloned, otherwise they will be assigned by reference. If a callback - * is provided it will be executed to produce the cloned values. If the - * callback returns `undefined` cloning will be handled by the method instead. - * The callback is bound to `thisArg` and invoked with one argument; (value). + * Creates a function that memoizes the result of `func`. If `resolver` is + * provided it determines the cache key for storing the result based on the + * arguments provided to the memoized function. By default, the first argument + * provided to the memoized function is coerced to a string and used as the + * cache key. The `func` is invoked with the `this` binding of the memoized + * function. + * + * **Note:** The cache is exposed as the `cache` property on the memoized + * function. Its creation may be customized by replacing the `_.memoize.Cache` + * constructor with one whose instances implement the [`Map`](http://ecma-international.org/ecma-262/6.0/#sec-properties-of-the-map-prototype-object) + * method interface of `get`, `has`, and `set`. * * @static * @memberOf _ - * @category Objects - * @param {*} value The value to clone. - * @param {boolean} [isDeep=false] Specify a deep clone. - * @param {Function} [callback] The function to customize cloning values. - * @param {*} [thisArg] The `this` binding of `callback`. - * @returns {*} Returns the cloned value. + * @category Function + * @param {Function} func The function to have its output memoized. + * @param {Function} [resolver] The function to resolve the cache key. + * @returns {Function} Returns the new memoizing function. * @example * - * var characters = [ - * { 'name': 'barney', 'age': 36 }, - * { 'name': 'fred', 'age': 40 } - * ]; - * - * var shallow = _.clone(characters); - * shallow[0] === characters[0]; - * // => true - * - * var deep = _.clone(characters, true); - * deep[0] === characters[0]; - * // => false - * - * _.mixin({ - * 'clone': _.partialRight(_.clone, function(value) { - * return _.isElement(value) ? value.cloneNode(false) : undefined; - * }) + * var upperCase = _.memoize(function(string) { + * return string.toUpperCase(); * }); * - * var clone = _.clone(document.body); - * clone.childNodes.length; - * // => 0 + * upperCase('fred'); + * // => 'FRED' + * + * // modifying the result cache + * upperCase.cache.set('fred', 'BARNEY'); + * upperCase('fred'); + * // => 'BARNEY' + * + * // replacing `_.memoize.Cache` + * var object = { 'user': 'fred' }; + * var other = { 'user': 'barney' }; + * var identity = _.memoize(_.identity); + * + * identity(object); + * // => { 'user': 'fred' } + * identity(other); + * // => { 'user': 'fred' } + * + * _.memoize.Cache = WeakMap; + * var identity = _.memoize(_.identity); + * + * identity(object); + * // => { 'user': 'fred' } + * identity(other); + * // => { 'user': 'barney' } */ - function clone(value, isDeep, callback, thisArg) { - // allows working with "Collections" methods without using their `index` - // and `collection` arguments for `isDeep` and `callback` - if (typeof isDeep != 'boolean' && isDeep != null) { - thisArg = callback; - callback = isDeep; - isDeep = false; + function memoize(func, resolver) { + if (typeof func != 'function' || (resolver && typeof resolver != 'function')) { + throw new TypeError(FUNC_ERROR_TEXT); } - return baseClone(value, isDeep, typeof callback == 'function' && baseCreateCallback(callback, thisArg, 1)); + var memoized = function() { + var args = arguments, + key = resolver ? resolver.apply(this, args) : args[0], + cache = memoized.cache; + + if (cache.has(key)) { + return cache.get(key); + } + var result = func.apply(this, args); + memoized.cache = cache.set(key, result); + return result; + }; + memoized.cache = new memoize.Cache; + return memoized; } /** - * Creates a deep clone of `value`. If a callback is provided it will be - * executed to produce the cloned values. If the callback returns `undefined` - * cloning will be handled by the method instead. The callback is bound to - * `thisArg` and invoked with one argument; (value). - * - * Note: This method is loosely based on the structured clone algorithm. Functions - * and DOM nodes are **not** cloned. The enumerable properties of `arguments` objects and - * objects created by constructors other than `Object` are cloned to plain `Object` objects. - * See http://www.w3.org/TR/html5/infrastructure.html#internal-structured-cloning-algorithm. + * Creates a function that runs each argument through a corresponding + * transform function. * * @static * @memberOf _ - * @category Objects - * @param {*} value The value to deep clone. - * @param {Function} [callback] The function to customize cloning values. - * @param {*} [thisArg] The `this` binding of `callback`. - * @returns {*} Returns the deep cloned value. + * @category Function + * @param {Function} func The function to wrap. + * @param {...(Function|Function[])} [transforms] The functions to transform + * arguments, specified as individual functions or arrays of functions. + * @returns {Function} Returns the new function. * @example * - * var characters = [ - * { 'name': 'barney', 'age': 36 }, - * { 'name': 'fred', 'age': 40 } - * ]; + * function doubled(n) { + * return n * 2; + * } * - * var deep = _.cloneDeep(characters); - * deep[0] === characters[0]; - * // => false + * function square(n) { + * return n * n; + * } * - * var view = { - * 'label': 'docs', - * 'node': element - * }; + * var modded = _.modArgs(function(x, y) { + * return [x, y]; + * }, square, doubled); * - * var clone = _.cloneDeep(view, function(value) { - * return _.isElement(value) ? value.cloneNode(true) : undefined; - * }); + * modded(1, 2); + * // => [1, 4] * - * clone.node == view.node; - * // => false + * modded(5, 10); + * // => [25, 20] */ - function cloneDeep(value, callback, thisArg) { - return baseClone(value, true, typeof callback == 'function' && baseCreateCallback(callback, thisArg, 1)); - } + var modArgs = restParam(function(func, transforms) { + transforms = baseFlatten(transforms); + if (typeof func != 'function' || !arrayEvery(transforms, baseIsFunction)) { + throw new TypeError(FUNC_ERROR_TEXT); + } + var length = transforms.length; + return restParam(function(args) { + var index = nativeMin(args.length, length); + while (index--) { + args[index] = transforms[index](args[index]); + } + return func.apply(this, args); + }); + }); /** - * Creates an object that inherits from the given `prototype` object. If a - * `properties` object is provided its own enumerable properties are assigned - * to the created object. + * Creates a function that negates the result of the predicate `func`. The + * `func` predicate is invoked with the `this` binding and arguments of the + * created function. * * @static * @memberOf _ - * @category Objects - * @param {Object} prototype The object to inherit from. - * @param {Object} [properties] The properties to assign to the object. - * @returns {Object} Returns the new object. + * @category Function + * @param {Function} predicate The predicate to negate. + * @returns {Function} Returns the new function. * @example * - * function Shape() { - * this.x = 0; - * this.y = 0; - * } - * - * function Circle() { - * Shape.call(this); + * function isEven(n) { + * return n % 2 == 0; * } * - * Circle.prototype = _.create(Shape.prototype, { 'constructor': Circle }); - * - * var circle = new Circle; - * circle instanceof Circle; - * // => true - * - * circle instanceof Shape; - * // => true + * _.filter([1, 2, 3, 4, 5, 6], _.negate(isEven)); + * // => [1, 3, 5] */ - function create(prototype, properties) { - var result = baseCreate(prototype); - return properties ? assign(result, properties) : result; + function negate(predicate) { + if (typeof predicate != 'function') { + throw new TypeError(FUNC_ERROR_TEXT); + } + return function() { + return !predicate.apply(this, arguments); + }; } /** - * Assigns own enumerable properties of source object(s) to the destination - * object for all destination properties that resolve to `undefined`. Once a - * property is set, additional defaults of the same property will be ignored. + * Creates a function that is restricted to invoking `func` once. Repeat calls + * to the function return the value of the first call. The `func` is invoked + * with the `this` binding and arguments of the created function. * * @static * @memberOf _ - * @type Function - * @category Objects - * @param {Object} object The destination object. - * @param {...Object} [source] The source objects. - * @param- {Object} [guard] Allows working with `_.reduce` without using its - * `key` and `object` arguments as sources. - * @returns {Object} Returns the destination object. + * @category Function + * @param {Function} func The function to restrict. + * @returns {Function} Returns the new restricted function. * @example * - * var object = { 'name': 'barney' }; - * _.defaults(object, { 'name': 'fred', 'employer': 'slate' }); - * // => { 'name': 'barney', 'employer': 'slate' } + * var initialize = _.once(createApplication); + * initialize(); + * initialize(); + * // `initialize` invokes `createApplication` once */ - var defaults = function(object, source, guard) { - var index, iterable = object, result = iterable; - if (!iterable) return result; - var args = arguments, - argsIndex = 0, - argsLength = typeof guard == 'number' ? 2 : args.length; - while (++argsIndex < argsLength) { - iterable = args[argsIndex]; - if (iterable && objectTypes[typeof iterable]) { - var ownIndex = -1, - ownProps = objectTypes[typeof iterable] && keys(iterable), - length = ownProps ? ownProps.length : 0; - - while (++ownIndex < length) { - index = ownProps[ownIndex]; - if (typeof result[index] == 'undefined') result[index] = iterable[index]; - } - } - } - return result - }; + function once(func) { + return before(2, func); + } /** - * This method is like `_.findIndex` except that it returns the key of the - * first element that passes the callback check, instead of the element itself. + * Creates a function that invokes `func` with `partial` arguments prepended + * to those provided to the new function. This method is like `_.bind` except + * it does **not** alter the `this` binding. * - * If a property name is provided for `callback` the created "_.pluck" style - * callback will return the property value of the given element. + * The `_.partial.placeholder` value, which defaults to `_` in monolithic + * builds, may be used as a placeholder for partially applied arguments. * - * If an object is provided for `callback` the created "_.where" style callback - * will return `true` for elements that have the properties of the given object, - * else `false`. + * **Note:** This method does not set the "length" property of partially + * applied functions. * * @static * @memberOf _ - * @category Objects - * @param {Object} object The object to search. - * @param {Function|Object|string} [callback=identity] The function called per - * iteration. If a property name or object is provided it will be used to - * create a "_.pluck" or "_.where" style callback, respectively. - * @param {*} [thisArg] The `this` binding of `callback`. - * @returns {string|undefined} Returns the key of the found element, else `undefined`. + * @category Function + * @param {Function} func The function to partially apply arguments to. + * @param {...*} [partials] The arguments to be partially applied. + * @returns {Function} Returns the new partially applied function. * @example * - * var characters = { - * 'barney': { 'age': 36, 'blocked': false }, - * 'fred': { 'age': 40, 'blocked': true }, - * 'pebbles': { 'age': 1, 'blocked': false } + * var greet = function(greeting, name) { + * return greeting + ' ' + name; * }; * - * _.findKey(characters, function(chr) { - * return chr.age < 40; - * }); - * // => 'barney' (property order is not guaranteed across environments) - * - * // using "_.where" callback shorthand - * _.findKey(characters, { 'age': 1 }); - * // => 'pebbles' + * var sayHelloTo = _.partial(greet, 'hello'); + * sayHelloTo('fred'); + * // => 'hello fred' * - * // using "_.pluck" callback shorthand - * _.findKey(characters, 'blocked'); - * // => 'fred' + * // using placeholders + * var greetFred = _.partial(greet, _, 'fred'); + * greetFred('hi'); + * // => 'hi fred' */ - function findKey(object, callback, thisArg) { - var result; - callback = lodash.createCallback(callback, thisArg, 3); - forOwn(object, function(value, key, object) { - if (callback(value, key, object)) { - result = key; - return false; - } - }); - return result; - } + var partial = createPartial(PARTIAL_FLAG); /** - * This method is like `_.findKey` except that it iterates over elements - * of a `collection` in the opposite order. + * This method is like `_.partial` except that partially applied arguments + * are appended to those provided to the new function. * - * If a property name is provided for `callback` the created "_.pluck" style - * callback will return the property value of the given element. + * The `_.partialRight.placeholder` value, which defaults to `_` in monolithic + * builds, may be used as a placeholder for partially applied arguments. * - * If an object is provided for `callback` the created "_.where" style callback - * will return `true` for elements that have the properties of the given object, - * else `false`. + * **Note:** This method does not set the "length" property of partially + * applied functions. * * @static * @memberOf _ - * @category Objects - * @param {Object} object The object to search. - * @param {Function|Object|string} [callback=identity] The function called per - * iteration. If a property name or object is provided it will be used to - * create a "_.pluck" or "_.where" style callback, respectively. - * @param {*} [thisArg] The `this` binding of `callback`. - * @returns {string|undefined} Returns the key of the found element, else `undefined`. + * @category Function + * @param {Function} func The function to partially apply arguments to. + * @param {...*} [partials] The arguments to be partially applied. + * @returns {Function} Returns the new partially applied function. * @example * - * var characters = { - * 'barney': { 'age': 36, 'blocked': true }, - * 'fred': { 'age': 40, 'blocked': false }, - * 'pebbles': { 'age': 1, 'blocked': true } + * var greet = function(greeting, name) { + * return greeting + ' ' + name; * }; * - * _.findLastKey(characters, function(chr) { - * return chr.age < 40; - * }); - * // => returns `pebbles`, assuming `_.findKey` returns `barney` - * - * // using "_.where" callback shorthand - * _.findLastKey(characters, { 'age': 40 }); - * // => 'fred' + * var greetFred = _.partialRight(greet, 'fred'); + * greetFred('hi'); + * // => 'hi fred' * - * // using "_.pluck" callback shorthand - * _.findLastKey(characters, 'blocked'); - * // => 'pebbles' + * // using placeholders + * var sayHelloTo = _.partialRight(greet, 'hello', _); + * sayHelloTo('fred'); + * // => 'hello fred' */ - function findLastKey(object, callback, thisArg) { - var result; - callback = lodash.createCallback(callback, thisArg, 3); - forOwnRight(object, function(value, key, object) { - if (callback(value, key, object)) { - result = key; - return false; - } - }); - return result; - } + var partialRight = createPartial(PARTIAL_RIGHT_FLAG); /** - * Iterates over own and inherited enumerable properties of an object, - * executing the callback for each property. The callback is bound to `thisArg` - * and invoked with three arguments; (value, key, object). Callbacks may exit - * iteration early by explicitly returning `false`. + * Creates a function that invokes `func` with arguments arranged according + * to the specified indexes where the argument value at the first index is + * provided as the first argument, the argument value at the second index is + * provided as the second argument, and so on. * * @static * @memberOf _ - * @type Function - * @category Objects - * @param {Object} object The object to iterate over. - * @param {Function} [callback=identity] The function called per iteration. - * @param {*} [thisArg] The `this` binding of `callback`. - * @returns {Object} Returns `object`. + * @category Function + * @param {Function} func The function to rearrange arguments for. + * @param {...(number|number[])} indexes The arranged argument indexes, + * specified as individual indexes or arrays of indexes. + * @returns {Function} Returns the new function. * @example * - * function Shape() { - * this.x = 0; - * this.y = 0; - * } + * var rearged = _.rearg(function(a, b, c) { + * return [a, b, c]; + * }, 2, 0, 1); * - * Shape.prototype.move = function(x, y) { - * this.x += x; - * this.y += y; - * }; + * rearged('b', 'c', 'a') + * // => ['a', 'b', 'c'] * - * _.forIn(new Shape, function(value, key) { - * console.log(key); - * }); - * // => logs 'x', 'y', and 'move' (property order is not guaranteed across environments) - */ - var forIn = function(collection, callback, thisArg) { - var index, iterable = collection, result = iterable; - if (!iterable) return result; - if (!objectTypes[typeof iterable]) return result; - callback = callback && typeof thisArg == 'undefined' ? callback : baseCreateCallback(callback, thisArg, 3); - for (index in iterable) { - if (callback(iterable[index], index, collection) === false) return result; - } - return result - }; + * var map = _.rearg(_.map, [1, 0]); + * map(function(n) { + * return n * 3; + * }, [1, 2, 3]); + * // => [3, 6, 9] + */ + var rearg = restParam(function(func, indexes) { + return createWrapper(func, REARG_FLAG, undefined, undefined, undefined, baseFlatten(indexes)); + }); /** - * This method is like `_.forIn` except that it iterates over elements - * of a `collection` in the opposite order. + * Creates a function that invokes `func` with the `this` binding of the + * created function and arguments from `start` and beyond provided as an array. + * + * **Note:** This method is based on the [rest parameter](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/rest_parameters). * * @static * @memberOf _ - * @category Objects - * @param {Object} object The object to iterate over. - * @param {Function} [callback=identity] The function called per iteration. - * @param {*} [thisArg] The `this` binding of `callback`. - * @returns {Object} Returns `object`. + * @category Function + * @param {Function} func The function to apply a rest parameter to. + * @param {number} [start=func.length-1] The start position of the rest parameter. + * @returns {Function} Returns the new function. * @example * - * function Shape() { - * this.x = 0; - * this.y = 0; - * } - * - * Shape.prototype.move = function(x, y) { - * this.x += x; - * this.y += y; - * }; - * - * _.forInRight(new Shape, function(value, key) { - * console.log(key); + * var say = _.restParam(function(what, names) { + * return what + ' ' + _.initial(names).join(', ') + + * (_.size(names) > 1 ? ', & ' : '') + _.last(names); * }); - * // => logs 'move', 'y', and 'x' assuming `_.forIn ` logs 'x', 'y', and 'move' + * + * say('hello', 'fred', 'barney', 'pebbles'); + * // => 'hello fred, barney, & pebbles' */ - function forInRight(object, callback, thisArg) { - var pairs = []; - - forIn(object, function(value, key) { - pairs.push(key, value); - }); + function restParam(func, start) { + if (typeof func != 'function') { + throw new TypeError(FUNC_ERROR_TEXT); + } + start = nativeMax(start === undefined ? (func.length - 1) : (+start || 0), 0); + return function() { + var args = arguments, + index = -1, + length = nativeMax(args.length - start, 0), + rest = Array(length); - var length = pairs.length; - callback = baseCreateCallback(callback, thisArg, 3); - while (length--) { - if (callback(pairs[length--], pairs[length], object) === false) { - break; + while (++index < length) { + rest[index] = args[start + index]; } - } - return object; + switch (start) { + case 0: return func.call(this, rest); + case 1: return func.call(this, args[0], rest); + case 2: return func.call(this, args[0], args[1], rest); + } + var otherArgs = Array(start + 1); + index = -1; + while (++index < start) { + otherArgs[index] = args[index]; + } + otherArgs[start] = rest; + return func.apply(this, otherArgs); + }; } /** - * Iterates over own enumerable properties of an object, executing the callback - * for each property. The callback is bound to `thisArg` and invoked with three - * arguments; (value, key, object). Callbacks may exit iteration early by - * explicitly returning `false`. + * Creates a function that invokes `func` with the `this` binding of the created + * function and an array of arguments much like [`Function#apply`](https://es5.github.io/#x15.3.4.3). + * + * **Note:** This method is based on the [spread operator](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Spread_operator). * * @static * @memberOf _ - * @type Function - * @category Objects - * @param {Object} object The object to iterate over. - * @param {Function} [callback=identity] The function called per iteration. - * @param {*} [thisArg] The `this` binding of `callback`. - * @returns {Object} Returns `object`. + * @category Function + * @param {Function} func The function to spread arguments over. + * @returns {Function} Returns the new function. * @example * - * _.forOwn({ '0': 'zero', '1': 'one', 'length': 2 }, function(num, key) { - * console.log(key); + * var say = _.spread(function(who, what) { + * return who + ' says ' + what; * }); - * // => logs '0', '1', and 'length' (property order is not guaranteed across environments) - */ - var forOwn = function(collection, callback, thisArg) { - var index, iterable = collection, result = iterable; - if (!iterable) return result; - if (!objectTypes[typeof iterable]) return result; - callback = callback && typeof thisArg == 'undefined' ? callback : baseCreateCallback(callback, thisArg, 3); - var ownIndex = -1, - ownProps = objectTypes[typeof iterable] && keys(iterable), - length = ownProps ? ownProps.length : 0; - - while (++ownIndex < length) { - index = ownProps[ownIndex]; - if (callback(iterable[index], index, collection) === false) return result; - } - return result - }; - - /** - * This method is like `_.forOwn` except that it iterates over elements - * of a `collection` in the opposite order. * - * @static - * @memberOf _ - * @category Objects - * @param {Object} object The object to iterate over. - * @param {Function} [callback=identity] The function called per iteration. - * @param {*} [thisArg] The `this` binding of `callback`. - * @returns {Object} Returns `object`. - * @example + * say(['fred', 'hello']); + * // => 'fred says hello' * - * _.forOwnRight({ '0': 'zero', '1': 'one', 'length': 2 }, function(num, key) { - * console.log(key); - * }); - * // => logs 'length', '1', and '0' assuming `_.forOwn` logs '0', '1', and 'length' + * // with a Promise + * var numbers = Promise.all([ + * Promise.resolve(40), + * Promise.resolve(36) + * ]); + * + * numbers.then(_.spread(function(x, y) { + * return x + y; + * })); + * // => a Promise of 76 */ - function forOwnRight(object, callback, thisArg) { - var props = keys(object), - length = props.length; - - callback = baseCreateCallback(callback, thisArg, 3); - while (length--) { - var key = props[length]; - if (callback(object[key], key, object) === false) { - break; - } + function spread(func) { + if (typeof func != 'function') { + throw new TypeError(FUNC_ERROR_TEXT); } - return object; + return function(array) { + return func.apply(this, array); + }; } /** - * Creates a sorted array of property names of all enumerable properties, - * own and inherited, of `object` that have function values. - * - * @static - * @memberOf _ - * @alias methods - * @category Objects - * @param {Object} object The object to inspect. - * @returns {Array} Returns an array of property names that have function values. - * @example + * Creates a throttled function that only invokes `func` at most once per + * every `wait` milliseconds. The throttled function comes with a `cancel` + * method to cancel delayed invocations. Provide an options object to indicate + * that `func` should be invoked on the leading and/or trailing edge of the + * `wait` timeout. Subsequent calls to the throttled function return the + * result of the last `func` call. + * + * **Note:** If `leading` and `trailing` options are `true`, `func` is invoked + * on the trailing edge of the timeout only if the the throttled function is + * invoked more than once during the `wait` timeout. * - * _.functions(_); - * // => ['all', 'any', 'bind', 'bindAll', 'clone', 'compact', 'compose', ...] - */ - function functions(object) { - var result = []; - forIn(object, function(value, key) { - if (isFunction(value)) { - result.push(key); - } - }); - return result.sort(); - } - - /** - * Checks if the specified property name exists as a direct property of `object`, - * instead of an inherited property. + * See [David Corbacho's article](http://drupalmotion.com/article/debounce-and-throttle-visual-explanation) + * for details over the differences between `_.throttle` and `_.debounce`. * * @static * @memberOf _ - * @category Objects - * @param {Object} object The object to inspect. - * @param {string} key The name of the property to check. - * @returns {boolean} Returns `true` if key is a direct property, else `false`. + * @category Function + * @param {Function} func The function to throttle. + * @param {number} [wait=0] The number of milliseconds to throttle invocations to. + * @param {Object} [options] The options object. + * @param {boolean} [options.leading=true] Specify invoking on the leading + * edge of the timeout. + * @param {boolean} [options.trailing=true] Specify invoking on the trailing + * edge of the timeout. + * @returns {Function} Returns the new throttled function. * @example * - * _.has({ 'a': 1, 'b': 2, 'c': 3 }, 'b'); - * // => true - */ - function has(object, key) { - return object ? hasOwnProperty.call(object, key) : false; - } - - /** - * Creates an object composed of the inverted keys and values of the given object. + * // avoid excessively updating the position while scrolling + * jQuery(window).on('scroll', _.throttle(updatePosition, 100)); * - * @static - * @memberOf _ - * @category Objects - * @param {Object} object The object to invert. - * @returns {Object} Returns the created inverted object. - * @example + * // invoke `renewToken` when the click event is fired, but not more than once every 5 minutes + * jQuery('.interactive').on('click', _.throttle(renewToken, 300000, { + * 'trailing': false + * })); * - * _.invert({ 'first': 'fred', 'second': 'barney' }); - * // => { 'fred': 'first', 'barney': 'second' } + * // cancel a trailing throttled call + * jQuery(window).on('popstate', throttled.cancel); */ - function invert(object) { - var index = -1, - props = keys(object), - length = props.length, - result = {}; + function throttle(func, wait, options) { + var leading = true, + trailing = true; - while (++index < length) { - var key = props[index]; - result[object[key]] = key; + if (typeof func != 'function') { + throw new TypeError(FUNC_ERROR_TEXT); } - return result; + if (options === false) { + leading = false; + } else if (isObject(options)) { + leading = 'leading' in options ? !!options.leading : leading; + trailing = 'trailing' in options ? !!options.trailing : trailing; + } + return debounce(func, wait, { 'leading': leading, 'maxWait': +wait, 'trailing': trailing }); } /** - * Checks if `value` is a boolean value. + * Creates a function that provides `value` to the wrapper function as its + * first argument. Any additional arguments provided to the function are + * appended to those provided to the wrapper function. The wrapper is invoked + * with the `this` binding of the created function. * * @static * @memberOf _ - * @category Objects - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if the `value` is a boolean value, else `false`. + * @category Function + * @param {*} value The value to wrap. + * @param {Function} wrapper The wrapper function. + * @returns {Function} Returns the new function. * @example * - * _.isBoolean(null); - * // => false + * var p = _.wrap(_.escape, function(func, text) { + * return '

' + func(text) + '

'; + * }); + * + * p('fred, barney, & pebbles'); + * // => '

fred, barney, & pebbles

' */ - function isBoolean(value) { - return value === true || value === false || - value && typeof value == 'object' && toString.call(value) == boolClass || false; + function wrap(value, wrapper) { + wrapper = wrapper == null ? identity : wrapper; + return createWrapper(wrapper, PARTIAL_FLAG, undefined, [value], []); } + /*------------------------------------------------------------------------*/ + /** - * Checks if `value` is a date. + * Creates a clone of `value`. If `isDeep` is `true` nested objects are cloned, + * otherwise they are assigned by reference. If `customizer` is provided it is + * invoked to produce the cloned values. If `customizer` returns `undefined` + * cloning is handled by the method instead. The `customizer` is bound to + * `thisArg` and invoked with two argument; (value [, index|key, object]). + * + * **Note:** This method is loosely based on the + * [structured clone algorithm](http://www.w3.org/TR/html5/infrastructure.html#internal-structured-cloning-algorithm). + * The enumerable properties of `arguments` objects and objects created by + * constructors other than `Object` are cloned to plain `Object` objects. An + * empty object is returned for uncloneable values such as functions, DOM nodes, + * Maps, Sets, and WeakMaps. * * @static * @memberOf _ - * @category Objects - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if the `value` is a date, else `false`. + * @category Lang + * @param {*} value The value to clone. + * @param {boolean} [isDeep] Specify a deep clone. + * @param {Function} [customizer] The function to customize cloning values. + * @param {*} [thisArg] The `this` binding of `customizer`. + * @returns {*} Returns the cloned value. * @example * - * _.isDate(new Date); + * var users = [ + * { 'user': 'barney' }, + * { 'user': 'fred' } + * ]; + * + * var shallow = _.clone(users); + * shallow[0] === users[0]; * // => true - */ - function isDate(value) { - return value && typeof value == 'object' && toString.call(value) == dateClass || false; - } - - /** - * Checks if `value` is a DOM element. * - * @static - * @memberOf _ - * @category Objects - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if the `value` is a DOM element, else `false`. - * @example + * var deep = _.clone(users, true); + * deep[0] === users[0]; + * // => false * - * _.isElement(document.body); - * // => true + * // using a customizer callback + * var el = _.clone(document.body, function(value) { + * if (_.isElement(value)) { + * return value.cloneNode(false); + * } + * }); + * + * el === document.body + * // => false + * el.nodeName + * // => BODY + * el.childNodes.length; + * // => 0 */ - function isElement(value) { - return value && value.nodeType === 1 || false; + function clone(value, isDeep, customizer, thisArg) { + if (isDeep && typeof isDeep != 'boolean' && isIterateeCall(value, isDeep, customizer)) { + isDeep = false; + } + else if (typeof isDeep == 'function') { + thisArg = customizer; + customizer = isDeep; + isDeep = false; + } + return typeof customizer == 'function' + ? baseClone(value, isDeep, bindCallback(customizer, thisArg, 1)) + : baseClone(value, isDeep); } /** - * Checks if `value` is empty. Arrays, strings, or `arguments` objects with a - * length of `0` and objects with no own enumerable properties are considered - * "empty". + * Creates a deep clone of `value`. If `customizer` is provided it is invoked + * to produce the cloned values. If `customizer` returns `undefined` cloning + * is handled by the method instead. The `customizer` is bound to `thisArg` + * and invoked with two argument; (value [, index|key, object]). + * + * **Note:** This method is loosely based on the + * [structured clone algorithm](http://www.w3.org/TR/html5/infrastructure.html#internal-structured-cloning-algorithm). + * The enumerable properties of `arguments` objects and objects created by + * constructors other than `Object` are cloned to plain `Object` objects. An + * empty object is returned for uncloneable values such as functions, DOM nodes, + * Maps, Sets, and WeakMaps. * * @static * @memberOf _ - * @category Objects - * @param {Array|Object|string} value The value to inspect. - * @returns {boolean} Returns `true` if the `value` is empty, else `false`. + * @category Lang + * @param {*} value The value to deep clone. + * @param {Function} [customizer] The function to customize cloning values. + * @param {*} [thisArg] The `this` binding of `customizer`. + * @returns {*} Returns the deep cloned value. * @example * - * _.isEmpty([1, 2, 3]); + * var users = [ + * { 'user': 'barney' }, + * { 'user': 'fred' } + * ]; + * + * var deep = _.cloneDeep(users); + * deep[0] === users[0]; * // => false * - * _.isEmpty({}); - * // => true + * // using a customizer callback + * var el = _.cloneDeep(document.body, function(value) { + * if (_.isElement(value)) { + * return value.cloneNode(true); + * } + * }); * - * _.isEmpty(''); - * // => true + * el === document.body + * // => false + * el.nodeName + * // => BODY + * el.childNodes.length; + * // => 20 */ - function isEmpty(value) { - var result = true; - if (!value) { - return result; - } - var className = toString.call(value), - length = value.length; - - if ((className == arrayClass || className == stringClass || className == argsClass ) || - (className == objectClass && typeof length == 'number' && isFunction(value.splice))) { - return !length; - } - forOwn(value, function() { - return (result = false); - }); - return result; + function cloneDeep(value, customizer, thisArg) { + return typeof customizer == 'function' + ? baseClone(value, true, bindCallback(customizer, thisArg, 1)) + : baseClone(value, true); } /** - * Performs a deep comparison between two values to determine if they are - * equivalent to each other. If a callback is provided it will be executed - * to compare values. If the callback returns `undefined` comparisons will - * be handled by the method instead. The callback is bound to `thisArg` and - * invoked with two arguments; (a, b). + * Checks if `value` is greater than `other`. * * @static * @memberOf _ - * @category Objects - * @param {*} a The value to compare. - * @param {*} b The other value to compare. - * @param {Function} [callback] The function to customize comparing values. - * @param {*} [thisArg] The `this` binding of `callback`. - * @returns {boolean} Returns `true` if the values are equivalent, else `false`. + * @category Lang + * @param {*} value The value to compare. + * @param {*} other The other value to compare. + * @returns {boolean} Returns `true` if `value` is greater than `other`, else `false`. * @example * - * var object = { 'name': 'fred' }; - * var copy = { 'name': 'fred' }; - * - * object == copy; - * // => false - * - * _.isEqual(object, copy); + * _.gt(3, 1); * // => true * - * var words = ['hello', 'goodbye']; - * var otherWords = ['hi', 'goodbye']; - * - * _.isEqual(words, otherWords, function(a, b) { - * var reGreet = /^(?:hello|hi)$/i, - * aGreet = _.isString(a) && reGreet.test(a), - * bGreet = _.isString(b) && reGreet.test(b); + * _.gt(3, 3); + * // => false * - * return (aGreet || bGreet) ? (aGreet == bGreet) : undefined; - * }); - * // => true + * _.gt(1, 3); + * // => false */ - function isEqual(a, b, callback, thisArg) { - return baseIsEqual(a, b, typeof callback == 'function' && baseCreateCallback(callback, thisArg, 2)); + function gt(value, other) { + return value > other; } /** - * Checks if `value` is, or can be coerced to, a finite number. - * - * Note: This is not the same as native `isFinite` which will return true for - * booleans and empty strings. See http://es5.github.io/#x15.1.2.5. + * Checks if `value` is greater than or equal to `other`. * * @static * @memberOf _ - * @category Objects - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if the `value` is finite, else `false`. + * @category Lang + * @param {*} value The value to compare. + * @param {*} other The other value to compare. + * @returns {boolean} Returns `true` if `value` is greater than or equal to `other`, else `false`. * @example * - * _.isFinite(-101); + * _.gte(3, 1); * // => true * - * _.isFinite('10'); + * _.gte(3, 3); * // => true * - * _.isFinite(true); - * // => false - * - * _.isFinite(''); - * // => false - * - * _.isFinite(Infinity); + * _.gte(1, 3); * // => false */ - function isFinite(value) { - return nativeIsFinite(value) && !nativeIsNaN(parseFloat(value)); + function gte(value, other) { + return value >= other; } /** - * Checks if `value` is a function. + * Checks if `value` is classified as an `arguments` object. * * @static * @memberOf _ - * @category Objects + * @category Lang * @param {*} value The value to check. - * @returns {boolean} Returns `true` if the `value` is a function, else `false`. + * @returns {boolean} Returns `true` if `value` is correctly classified, else `false`. * @example * - * _.isFunction(_); + * _.isArguments(function() { return arguments; }()); * // => true + * + * _.isArguments([1, 2, 3]); + * // => false */ - function isFunction(value) { - return typeof value == 'function'; + function isArguments(value) { + return isObjectLike(value) && isArrayLike(value) && + hasOwnProperty.call(value, 'callee') && !propertyIsEnumerable.call(value, 'callee'); } /** - * Checks if `value` is the language type of Object. - * (e.g. arrays, functions, objects, regexes, `new Number(0)`, and `new String('')`) + * Checks if `value` is classified as an `Array` object. * * @static * @memberOf _ - * @category Objects + * @category Lang * @param {*} value The value to check. - * @returns {boolean} Returns `true` if the `value` is an object, else `false`. + * @returns {boolean} Returns `true` if `value` is correctly classified, else `false`. * @example * - * _.isObject({}); - * // => true - * - * _.isObject([1, 2, 3]); + * _.isArray([1, 2, 3]); * // => true * - * _.isObject(1); + * _.isArray(function() { return arguments; }()); * // => false */ - function isObject(value) { - // check if the value is the ECMAScript language type of Object - // http://es5.github.io/#x8 - // and avoid a V8 bug - // http://code.google.com/p/v8/issues/detail?id=2291 - return !!(value && objectTypes[typeof value]); - } + var isArray = nativeIsArray || function(value) { + return isObjectLike(value) && isLength(value.length) && objToString.call(value) == arrayTag; + }; /** - * Checks if `value` is `NaN`. - * - * Note: This is not the same as native `isNaN` which will return `true` for - * `undefined` and other non-numeric values. See http://es5.github.io/#x15.1.2.4. + * Checks if `value` is classified as a boolean primitive or object. * * @static * @memberOf _ - * @category Objects + * @category Lang * @param {*} value The value to check. - * @returns {boolean} Returns `true` if the `value` is `NaN`, else `false`. + * @returns {boolean} Returns `true` if `value` is correctly classified, else `false`. * @example * - * _.isNaN(NaN); - * // => true - * - * _.isNaN(new Number(NaN)); - * // => true - * - * isNaN(undefined); + * _.isBoolean(false); * // => true * - * _.isNaN(undefined); + * _.isBoolean(null); * // => false */ - function isNaN(value) { - // `NaN` as a primitive is the only value that is not equal to itself - // (perform the [[Class]] check first to avoid errors with some host objects in IE) - return isNumber(value) && value != +value; + function isBoolean(value) { + return value === true || value === false || (isObjectLike(value) && objToString.call(value) == boolTag); } /** - * Checks if `value` is `null`. + * Checks if `value` is classified as a `Date` object. * * @static * @memberOf _ - * @category Objects + * @category Lang * @param {*} value The value to check. - * @returns {boolean} Returns `true` if the `value` is `null`, else `false`. + * @returns {boolean} Returns `true` if `value` is correctly classified, else `false`. * @example * - * _.isNull(null); + * _.isDate(new Date); * // => true * - * _.isNull(undefined); + * _.isDate('Mon April 23 2012'); * // => false */ - function isNull(value) { - return value === null; + function isDate(value) { + return isObjectLike(value) && objToString.call(value) == dateTag; } /** - * Checks if `value` is a number. - * - * Note: `NaN` is considered a number. See http://es5.github.io/#x8.5. + * Checks if `value` is a DOM element. * * @static * @memberOf _ - * @category Objects + * @category Lang * @param {*} value The value to check. - * @returns {boolean} Returns `true` if the `value` is a number, else `false`. + * @returns {boolean} Returns `true` if `value` is a DOM element, else `false`. * @example * - * _.isNumber(8.4 * 5); + * _.isElement(document.body); * // => true + * + * _.isElement(''); + * // => false */ - function isNumber(value) { - return typeof value == 'number' || - value && typeof value == 'object' && toString.call(value) == numberClass || false; + function isElement(value) { + return !!value && value.nodeType === 1 && isObjectLike(value) && !isPlainObject(value); } /** - * Checks if `value` is an object created by the `Object` constructor. + * Checks if `value` is empty. A value is considered empty unless it is an + * `arguments` object, array, string, or jQuery-like collection with a length + * greater than `0` or an object with own enumerable properties. * * @static * @memberOf _ - * @category Objects - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is a plain object, else `false`. + * @category Lang + * @param {Array|Object|string} value The value to inspect. + * @returns {boolean} Returns `true` if `value` is empty, else `false`. * @example * - * function Shape() { - * this.x = 0; - * this.y = 0; - * } + * _.isEmpty(null); + * // => true * - * _.isPlainObject(new Shape); - * // => false + * _.isEmpty(true); + * // => true * - * _.isPlainObject([1, 2, 3]); + * _.isEmpty(1); + * // => true + * + * _.isEmpty([1, 2, 3]); * // => false * - * _.isPlainObject({ 'x': 0, 'y': 0 }); - * // => true + * _.isEmpty({ 'a': 1 }); + * // => false */ - var isPlainObject = !getPrototypeOf ? shimIsPlainObject : function(value) { - if (!(value && toString.call(value) == objectClass)) { - return false; + function isEmpty(value) { + if (value == null) { + return true; } - var valueOf = value.valueOf, - objProto = isNative(valueOf) && (objProto = getPrototypeOf(valueOf)) && getPrototypeOf(objProto); - - return objProto - ? (value == objProto || getPrototypeOf(value) == objProto) - : shimIsPlainObject(value); - }; + if (isArrayLike(value) && (isArray(value) || isString(value) || isArguments(value) || + (isObjectLike(value) && isFunction(value.splice)))) { + return !value.length; + } + return !keys(value).length; + } /** - * Checks if `value` is a regular expression. + * Performs a deep comparison between two values to determine if they are + * equivalent. If `customizer` is provided it is invoked to compare values. + * If `customizer` returns `undefined` comparisons are handled by the method + * instead. The `customizer` is bound to `thisArg` and invoked with three + * arguments: (value, other [, index|key]). + * + * **Note:** This method supports comparing arrays, booleans, `Date` objects, + * numbers, `Object` objects, regexes, and strings. Objects are compared by + * their own, not inherited, enumerable properties. Functions and DOM nodes + * are **not** supported. Provide a customizer function to extend support + * for comparing other values. * * @static * @memberOf _ - * @category Objects - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if the `value` is a regular expression, else `false`. + * @alias eq + * @category Lang + * @param {*} value The value to compare. + * @param {*} other The other value to compare. + * @param {Function} [customizer] The function to customize value comparisons. + * @param {*} [thisArg] The `this` binding of `customizer`. + * @returns {boolean} Returns `true` if the values are equivalent, else `false`. * @example * - * _.isRegExp(/fred/); + * var object = { 'user': 'fred' }; + * var other = { 'user': 'fred' }; + * + * object == other; + * // => false + * + * _.isEqual(object, other); * // => true - */ - function isRegExp(value) { - return value && typeof value == 'object' && toString.call(value) == regexpClass || false; - } - - /** - * Checks if `value` is a string. * - * @static - * @memberOf _ - * @category Objects - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if the `value` is a string, else `false`. - * @example + * // using a customizer callback + * var array = ['hello', 'goodbye']; + * var other = ['hi', 'goodbye']; * - * _.isString('fred'); + * _.isEqual(array, other, function(value, other) { + * if (_.every([value, other], RegExp.prototype.test, /^h(?:i|ello)$/)) { + * return true; + * } + * }); * // => true */ - function isString(value) { - return typeof value == 'string' || - value && typeof value == 'object' && toString.call(value) == stringClass || false; + function isEqual(value, other, customizer, thisArg) { + customizer = typeof customizer == 'function' ? bindCallback(customizer, thisArg, 3) : undefined; + var result = customizer ? customizer(value, other) : undefined; + return result === undefined ? baseIsEqual(value, other, customizer) : !!result; } /** - * Checks if `value` is `undefined`. + * Checks if `value` is an `Error`, `EvalError`, `RangeError`, `ReferenceError`, + * `SyntaxError`, `TypeError`, or `URIError` object. * * @static * @memberOf _ - * @category Objects + * @category Lang * @param {*} value The value to check. - * @returns {boolean} Returns `true` if the `value` is `undefined`, else `false`. + * @returns {boolean} Returns `true` if `value` is an error object, else `false`. * @example * - * _.isUndefined(void 0); + * _.isError(new Error); * // => true + * + * _.isError(Error); + * // => false */ - function isUndefined(value) { - return typeof value == 'undefined'; + function isError(value) { + return isObjectLike(value) && typeof value.message == 'string' && objToString.call(value) == errorTag; } /** - * Creates an object with the same keys as `object` and values generated by - * running each own enumerable property of `object` through the callback. - * The callback is bound to `thisArg` and invoked with three arguments; - * (value, key, object). + * Checks if `value` is a finite primitive number. * - * If a property name is provided for `callback` the created "_.pluck" style - * callback will return the property value of the given element. - * - * If an object is provided for `callback` the created "_.where" style callback - * will return `true` for elements that have the properties of the given object, - * else `false`. + * **Note:** This method is based on [`Number.isFinite`](http://ecma-international.org/ecma-262/6.0/#sec-number.isfinite). * * @static * @memberOf _ - * @category Objects - * @param {Object} object The object to iterate over. - * @param {Function|Object|string} [callback=identity] The function called - * per iteration. If a property name or object is provided it will be used - * to create a "_.pluck" or "_.where" style callback, respectively. - * @param {*} [thisArg] The `this` binding of `callback`. - * @returns {Array} Returns a new object with values of the results of each `callback` execution. + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a finite number, else `false`. * @example * - * _.mapValues({ 'a': 1, 'b': 2, 'c': 3} , function(num) { return num * 3; }); - * // => { 'a': 3, 'b': 6, 'c': 9 } + * _.isFinite(10); + * // => true + * + * _.isFinite('10'); + * // => false * - * var characters = { - * 'fred': { 'name': 'fred', 'age': 40 }, - * 'pebbles': { 'name': 'pebbles', 'age': 1 } - * }; + * _.isFinite(true); + * // => false + * + * _.isFinite(Object(10)); + * // => false * - * // using "_.pluck" callback shorthand - * _.mapValues(characters, 'age'); - * // => { 'fred': 40, 'pebbles': 1 } + * _.isFinite(Infinity); + * // => false */ - function mapValues(object, callback, thisArg) { - var result = {}; - callback = lodash.createCallback(callback, thisArg, 3); - - forOwn(object, function(value, key, object) { - result[key] = callback(value, key, object); - }); - return result; + function isFinite(value) { + return typeof value == 'number' && nativeIsFinite(value); } /** - * Recursively merges own enumerable properties of the source object(s), that - * don't resolve to `undefined` into the destination object. Subsequent sources - * will overwrite property assignments of previous sources. If a callback is - * provided it will be executed to produce the merged values of the destination - * and source properties. If the callback returns `undefined` merging will - * be handled by the method instead. The callback is bound to `thisArg` and - * invoked with two arguments; (objectValue, sourceValue). + * Checks if `value` is classified as a `Function` object. * * @static * @memberOf _ - * @category Objects - * @param {Object} object The destination object. - * @param {...Object} [source] The source objects. - * @param {Function} [callback] The function to customize merging properties. - * @param {*} [thisArg] The `this` binding of `callback`. - * @returns {Object} Returns the destination object. + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is correctly classified, else `false`. * @example * - * var names = { - * 'characters': [ - * { 'name': 'barney' }, - * { 'name': 'fred' } - * ] - * }; - * - * var ages = { - * 'characters': [ - * { 'age': 36 }, - * { 'age': 40 } - * ] - * }; - * - * _.merge(names, ages); - * // => { 'characters': [{ 'name': 'barney', 'age': 36 }, { 'name': 'fred', 'age': 40 }] } - * - * var food = { - * 'fruits': ['apple'], - * 'vegetables': ['beet'] - * }; - * - * var otherFood = { - * 'fruits': ['banana'], - * 'vegetables': ['carrot'] - * }; + * _.isFunction(_); + * // => true * - * _.merge(food, otherFood, function(a, b) { - * return _.isArray(a) ? a.concat(b) : undefined; - * }); - * // => { 'fruits': ['apple', 'banana'], 'vegetables': ['beet', 'carrot] } + * _.isFunction(/abc/); + * // => false */ - function merge(object) { - var args = arguments, - length = 2; - - if (!isObject(object)) { - return object; - } - // allows working with `_.reduce` and `_.reduceRight` without using - // their `index` and `collection` arguments - if (typeof args[2] != 'number') { - length = args.length; - } - if (length > 3 && typeof args[length - 2] == 'function') { - var callback = baseCreateCallback(args[--length - 1], args[length--], 2); - } else if (length > 2 && typeof args[length - 1] == 'function') { - callback = args[--length]; - } - var sources = slice(arguments, 1, length), - index = -1, - stackA = getArray(), - stackB = getArray(); - - while (++index < length) { - baseMerge(object, sources[index], callback, stackA, stackB); - } - releaseArray(stackA); - releaseArray(stackB); - return object; + function isFunction(value) { + // The use of `Object#toString` avoids issues with the `typeof` operator + // in older versions of Chrome and Safari which return 'function' for regexes + // and Safari 8 equivalents which return 'object' for typed array constructors. + return isObject(value) && objToString.call(value) == funcTag; } /** - * Creates a shallow clone of `object` excluding the specified properties. - * Property names may be specified as individual arguments or as arrays of - * property names. If a callback is provided it will be executed for each - * property of `object` omitting the properties the callback returns truey - * for. The callback is bound to `thisArg` and invoked with three arguments; - * (value, key, object). + * Checks if `value` is the [language type](https://es5.github.io/#x8) of `Object`. + * (e.g. arrays, functions, objects, regexes, `new Number(0)`, and `new String('')`) * * @static * @memberOf _ - * @category Objects - * @param {Object} object The source object. - * @param {Function|...string|string[]} [callback] The properties to omit or the - * function called per iteration. - * @param {*} [thisArg] The `this` binding of `callback`. - * @returns {Object} Returns an object without the omitted properties. + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is an object, else `false`. * @example * - * _.omit({ 'name': 'fred', 'age': 40 }, 'age'); - * // => { 'name': 'fred' } + * _.isObject({}); + * // => true * - * _.omit({ 'name': 'fred', 'age': 40 }, function(value) { - * return typeof value == 'number'; - * }); - * // => { 'name': 'fred' } + * _.isObject([1, 2, 3]); + * // => true + * + * _.isObject(1); + * // => false */ - function omit(object, callback, thisArg) { - var result = {}; - if (typeof callback != 'function') { - var props = []; - forIn(object, function(value, key) { - props.push(key); - }); - props = baseDifference(props, baseFlatten(arguments, true, false, 1)); - - var index = -1, - length = props.length; - - while (++index < length) { - var key = props[index]; - result[key] = object[key]; - } - } else { - callback = lodash.createCallback(callback, thisArg, 3); - forIn(object, function(value, key, object) { - if (!callback(value, key, object)) { - result[key] = value; - } - }); - } - return result; + function isObject(value) { + // Avoid a V8 JIT bug in Chrome 19-20. + // See https://code.google.com/p/v8/issues/detail?id=2291 for more details. + var type = typeof value; + return !!value && (type == 'object' || type == 'function'); } /** - * Creates a two dimensional array of an object's key-value pairs, - * i.e. `[[key1, value1], [key2, value2]]`. + * Performs a deep comparison between `object` and `source` to determine if + * `object` contains equivalent property values. If `customizer` is provided + * it is invoked to compare values. If `customizer` returns `undefined` + * comparisons are handled by the method instead. The `customizer` is bound + * to `thisArg` and invoked with three arguments: (value, other, index|key). + * + * **Note:** This method supports comparing properties of arrays, booleans, + * `Date` objects, numbers, `Object` objects, regexes, and strings. Functions + * and DOM nodes are **not** supported. Provide a customizer function to extend + * support for comparing other values. * * @static * @memberOf _ - * @category Objects + * @category Lang * @param {Object} object The object to inspect. - * @returns {Array} Returns new array of key-value pairs. + * @param {Object} source The object of property values to match. + * @param {Function} [customizer] The function to customize value comparisons. + * @param {*} [thisArg] The `this` binding of `customizer`. + * @returns {boolean} Returns `true` if `object` is a match, else `false`. * @example * - * _.pairs({ 'barney': 36, 'fred': 40 }); - * // => [['barney', 36], ['fred', 40]] (property order is not guaranteed across environments) + * var object = { 'user': 'fred', 'age': 40 }; + * + * _.isMatch(object, { 'age': 40 }); + * // => true + * + * _.isMatch(object, { 'age': 36 }); + * // => false + * + * // using a customizer callback + * var object = { 'greeting': 'hello' }; + * var source = { 'greeting': 'hi' }; + * + * _.isMatch(object, source, function(value, other) { + * return _.every([value, other], RegExp.prototype.test, /^h(?:i|ello)$/) || undefined; + * }); + * // => true */ - function pairs(object) { - var index = -1, - props = keys(object), - length = props.length, - result = Array(length); - - while (++index < length) { - var key = props[index]; - result[index] = [key, object[key]]; - } - return result; + function isMatch(object, source, customizer, thisArg) { + customizer = typeof customizer == 'function' ? bindCallback(customizer, thisArg, 3) : undefined; + return baseIsMatch(object, getMatchData(source), customizer); } /** - * Creates a shallow clone of `object` composed of the specified properties. - * Property names may be specified as individual arguments or as arrays of - * property names. If a callback is provided it will be executed for each - * property of `object` picking the properties the callback returns truey - * for. The callback is bound to `thisArg` and invoked with three arguments; - * (value, key, object). + * Checks if `value` is `NaN`. + * + * **Note:** This method is not the same as [`isNaN`](https://es5.github.io/#x15.1.2.4) + * which returns `true` for `undefined` and other non-numeric values. * * @static * @memberOf _ - * @category Objects - * @param {Object} object The source object. - * @param {Function|...string|string[]} [callback] The function called per - * iteration or property names to pick, specified as individual property - * names or arrays of property names. - * @param {*} [thisArg] The `this` binding of `callback`. - * @returns {Object} Returns an object composed of the picked properties. + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is `NaN`, else `false`. * @example * - * _.pick({ 'name': 'fred', '_userid': 'fred1' }, 'name'); - * // => { 'name': 'fred' } + * _.isNaN(NaN); + * // => true * - * _.pick({ 'name': 'fred', '_userid': 'fred1' }, function(value, key) { - * return key.charAt(0) != '_'; - * }); - * // => { 'name': 'fred' } + * _.isNaN(new Number(NaN)); + * // => true + * + * isNaN(undefined); + * // => true + * + * _.isNaN(undefined); + * // => false */ - function pick(object, callback, thisArg) { - var result = {}; - if (typeof callback != 'function') { - var index = -1, - props = baseFlatten(arguments, true, false, 1), - length = isObject(object) ? props.length : 0; - - while (++index < length) { - var key = props[index]; - if (key in object) { - result[key] = object[key]; - } - } - } else { - callback = lodash.createCallback(callback, thisArg, 3); - forIn(object, function(value, key, object) { - if (callback(value, key, object)) { - result[key] = value; - } - }); - } - return result; + function isNaN(value) { + // An `NaN` primitive is the only value that is not equal to itself. + // Perform the `toStringTag` check first to avoid errors with some host objects in IE. + return isNumber(value) && value != +value; } /** - * An alternative to `_.reduce` this method transforms `object` to a new - * `accumulator` object which is the result of running each of its own - * enumerable properties through a callback, with each callback execution - * potentially mutating the `accumulator` object. The callback is bound to - * `thisArg` and invoked with four arguments; (accumulator, value, key, object). - * Callbacks may exit iteration early by explicitly returning `false`. + * Checks if `value` is a native function. * * @static * @memberOf _ - * @category Objects - * @param {Array|Object} object The object to iterate over. - * @param {Function} [callback=identity] The function called per iteration. - * @param {*} [accumulator] The custom accumulator value. - * @param {*} [thisArg] The `this` binding of `callback`. - * @returns {*} Returns the accumulated value. + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a native function, else `false`. * @example * - * var squares = _.transform([1, 2, 3, 4, 5, 6, 7, 8, 9, 10], function(result, num) { - * num *= num; - * if (num % 2) { - * return result.push(num) < 3; - * } - * }); - * // => [1, 9, 25] + * _.isNative(Array.prototype.push); + * // => true * - * var mapped = _.transform({ 'a': 1, 'b': 2, 'c': 3 }, function(result, num, key) { - * result[key] = num * 3; - * }); - * // => { 'a': 3, 'b': 6, 'c': 9 } + * _.isNative(_); + * // => false */ - function transform(object, callback, accumulator, thisArg) { - var isArr = isArray(object); - if (accumulator == null) { - if (isArr) { - accumulator = []; - } else { - var ctor = object && object.constructor, - proto = ctor && ctor.prototype; - - accumulator = baseCreate(proto); - } + function isNative(value) { + if (value == null) { + return false; } - if (callback) { - callback = lodash.createCallback(callback, thisArg, 4); - (isArr ? forEach : forOwn)(object, function(value, index, object) { - return callback(accumulator, value, index, object); - }); + if (isFunction(value)) { + return reIsNative.test(fnToString.call(value)); } - return accumulator; + return isObjectLike(value) && reIsHostCtor.test(value); } /** - * Creates an array composed of the own enumerable property values of `object`. + * Checks if `value` is `null`. * * @static * @memberOf _ - * @category Objects - * @param {Object} object The object to inspect. - * @returns {Array} Returns an array of property values. + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is `null`, else `false`. * @example * - * _.values({ 'one': 1, 'two': 2, 'three': 3 }); - * // => [1, 2, 3] (property order is not guaranteed across environments) + * _.isNull(null); + * // => true + * + * _.isNull(void 0); + * // => false */ - function values(object) { - var index = -1, - props = keys(object), - length = props.length, - result = Array(length); - - while (++index < length) { - result[index] = object[props[index]]; - } - return result; + function isNull(value) { + return value === null; } - /*--------------------------------------------------------------------------*/ - /** - * Creates an array of elements from the specified indexes, or keys, of the - * `collection`. Indexes may be specified as individual arguments or as arrays - * of indexes. + * Checks if `value` is classified as a `Number` primitive or object. + * + * **Note:** To exclude `Infinity`, `-Infinity`, and `NaN`, which are classified + * as numbers, use the `_.isFinite` method. * * @static * @memberOf _ - * @category Collections - * @param {Array|Object|string} collection The collection to iterate over. - * @param {...(number|number[]|string|string[])} [index] The indexes of `collection` - * to retrieve, specified as individual indexes or arrays of indexes. - * @returns {Array} Returns a new array of elements corresponding to the - * provided indexes. + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is correctly classified, else `false`. * @example * - * _.at(['a', 'b', 'c', 'd', 'e'], [0, 2, 4]); - * // => ['a', 'c', 'e'] + * _.isNumber(8.4); + * // => true + * + * _.isNumber(NaN); + * // => true * - * _.at(['fred', 'barney', 'pebbles'], 0, 2); - * // => ['fred', 'pebbles'] + * _.isNumber('8.4'); + * // => false */ - function at(collection) { - var args = arguments, - index = -1, - props = baseFlatten(args, true, false, 1), - length = (args[2] && args[2][args[1]] === collection) ? 1 : props.length, - result = Array(length); - - while(++index < length) { - result[index] = collection[props[index]]; - } - return result; + function isNumber(value) { + return typeof value == 'number' || (isObjectLike(value) && objToString.call(value) == numberTag); } /** - * Checks if a given value is present in a collection using strict equality - * for comparisons, i.e. `===`. If `fromIndex` is negative, it is used as the - * offset from the end of the collection. + * Checks if `value` is a plain object, that is, an object created by the + * `Object` constructor or one with a `[[Prototype]]` of `null`. + * + * **Note:** This method assumes objects created by the `Object` constructor + * have no inherited enumerable properties. * * @static * @memberOf _ - * @alias include - * @category Collections - * @param {Array|Object|string} collection The collection to iterate over. - * @param {*} target The value to check for. - * @param {number} [fromIndex=0] The index to search from. - * @returns {boolean} Returns `true` if the `target` element is found, else `false`. + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a plain object, else `false`. * @example * - * _.contains([1, 2, 3], 1); - * // => true + * function Foo() { + * this.a = 1; + * } + * + * _.isPlainObject(new Foo); + * // => false * - * _.contains([1, 2, 3], 1, 2); + * _.isPlainObject([1, 2, 3]); * // => false * - * _.contains({ 'name': 'fred', 'age': 40 }, 'fred'); + * _.isPlainObject({ 'x': 0, 'y': 0 }); * // => true * - * _.contains('pebbles', 'eb'); + * _.isPlainObject(Object.create(null)); * // => true */ - function contains(collection, target, fromIndex) { - var index = -1, - indexOf = getIndexOf(), - length = collection ? collection.length : 0, - result = false; - - fromIndex = (fromIndex < 0 ? nativeMax(0, length + fromIndex) : fromIndex) || 0; - if (isArray(collection)) { - result = indexOf(collection, target, fromIndex) > -1; - } else if (typeof length == 'number') { - result = (isString(collection) ? collection.indexOf(target, fromIndex) : indexOf(collection, target, fromIndex)) > -1; - } else { - forOwn(collection, function(value) { - if (++index >= fromIndex) { - return !(result = value === target); - } - }); + function isPlainObject(value) { + var Ctor; + + // Exit early for non `Object` objects. + if (!(isObjectLike(value) && objToString.call(value) == objectTag && !isArguments(value)) || + (!hasOwnProperty.call(value, 'constructor') && (Ctor = value.constructor, typeof Ctor == 'function' && !(Ctor instanceof Ctor)))) { + return false; } - return result; + // IE < 9 iterates inherited properties before own properties. If the first + // iterated property is an object's own property then there are no inherited + // enumerable properties. + var result; + // In most environments an object's own properties are iterated before + // its inherited properties. If the last iterated property is an object's + // own property then there are no inherited enumerable properties. + baseForIn(value, function(subValue, key) { + result = key; + }); + return result === undefined || hasOwnProperty.call(value, result); } /** - * Creates an object composed of keys generated from the results of running - * each element of `collection` through the callback. The corresponding value - * of each key is the number of times the key was returned by the callback. - * The callback is bound to `thisArg` and invoked with three arguments; - * (value, index|key, collection). - * - * If a property name is provided for `callback` the created "_.pluck" style - * callback will return the property value of the given element. - * - * If an object is provided for `callback` the created "_.where" style callback - * will return `true` for elements that have the properties of the given object, - * else `false`. + * Checks if `value` is classified as a `RegExp` object. * * @static * @memberOf _ - * @category Collections - * @param {Array|Object|string} collection The collection to iterate over. - * @param {Function|Object|string} [callback=identity] The function called - * per iteration. If a property name or object is provided it will be used - * to create a "_.pluck" or "_.where" style callback, respectively. - * @param {*} [thisArg] The `this` binding of `callback`. - * @returns {Object} Returns the composed aggregate object. + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is correctly classified, else `false`. * @example * - * _.countBy([4.3, 6.1, 6.4], function(num) { return Math.floor(num); }); - * // => { '4': 1, '6': 2 } - * - * _.countBy([4.3, 6.1, 6.4], function(num) { return this.floor(num); }, Math); - * // => { '4': 1, '6': 2 } + * _.isRegExp(/abc/); + * // => true * - * _.countBy(['one', 'two', 'three'], 'length'); - * // => { '3': 2, '5': 1 } + * _.isRegExp('/abc/'); + * // => false */ - var countBy = createAggregator(function(result, value, key) { - (hasOwnProperty.call(result, key) ? result[key]++ : result[key] = 1); - }); + function isRegExp(value) { + return isObject(value) && objToString.call(value) == regexpTag; + } /** - * Checks if the given callback returns truey value for **all** elements of - * a collection. The callback is bound to `thisArg` and invoked with three - * arguments; (value, index|key, collection). - * - * If a property name is provided for `callback` the created "_.pluck" style - * callback will return the property value of the given element. - * - * If an object is provided for `callback` the created "_.where" style callback - * will return `true` for elements that have the properties of the given object, - * else `false`. + * Checks if `value` is classified as a `String` primitive or object. * * @static * @memberOf _ - * @alias all - * @category Collections - * @param {Array|Object|string} collection The collection to iterate over. - * @param {Function|Object|string} [callback=identity] The function called - * per iteration. If a property name or object is provided it will be used - * to create a "_.pluck" or "_.where" style callback, respectively. - * @param {*} [thisArg] The `this` binding of `callback`. - * @returns {boolean} Returns `true` if all elements passed the callback check, - * else `false`. + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is correctly classified, else `false`. * @example * - * _.every([true, 1, null, 'yes']); - * // => false - * - * var characters = [ - * { 'name': 'barney', 'age': 36 }, - * { 'name': 'fred', 'age': 40 } - * ]; - * - * // using "_.pluck" callback shorthand - * _.every(characters, 'age'); + * _.isString('abc'); * // => true * - * // using "_.where" callback shorthand - * _.every(characters, { 'age': 36 }); + * _.isString(1); * // => false */ - function every(collection, callback, thisArg) { - var result = true; - callback = lodash.createCallback(callback, thisArg, 3); - - var index = -1, - length = collection ? collection.length : 0; - - if (typeof length == 'number') { - while (++index < length) { - if (!(result = !!callback(collection[index], index, collection))) { - break; - } - } - } else { - forOwn(collection, function(value, index, collection) { - return (result = !!callback(value, index, collection)); - }); - } - return result; + function isString(value) { + return typeof value == 'string' || (isObjectLike(value) && objToString.call(value) == stringTag); } /** - * Iterates over elements of a collection, returning an array of all elements - * the callback returns truey for. The callback is bound to `thisArg` and - * invoked with three arguments; (value, index|key, collection). - * - * If a property name is provided for `callback` the created "_.pluck" style - * callback will return the property value of the given element. - * - * If an object is provided for `callback` the created "_.where" style callback - * will return `true` for elements that have the properties of the given object, - * else `false`. + * Checks if `value` is classified as a typed array. * * @static * @memberOf _ - * @alias select - * @category Collections - * @param {Array|Object|string} collection The collection to iterate over. - * @param {Function|Object|string} [callback=identity] The function called - * per iteration. If a property name or object is provided it will be used - * to create a "_.pluck" or "_.where" style callback, respectively. - * @param {*} [thisArg] The `this` binding of `callback`. - * @returns {Array} Returns a new array of elements that passed the callback check. + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is correctly classified, else `false`. * @example * - * var evens = _.filter([1, 2, 3, 4, 5, 6], function(num) { return num % 2 == 0; }); - * // => [2, 4, 6] - * - * var characters = [ - * { 'name': 'barney', 'age': 36, 'blocked': false }, - * { 'name': 'fred', 'age': 40, 'blocked': true } - * ]; - * - * // using "_.pluck" callback shorthand - * _.filter(characters, 'blocked'); - * // => [{ 'name': 'fred', 'age': 40, 'blocked': true }] + * _.isTypedArray(new Uint8Array); + * // => true * - * // using "_.where" callback shorthand - * _.filter(characters, { 'age': 36 }); - * // => [{ 'name': 'barney', 'age': 36, 'blocked': false }] + * _.isTypedArray([]); + * // => false */ - function filter(collection, callback, thisArg) { - var result = []; - callback = lodash.createCallback(callback, thisArg, 3); - - var index = -1, - length = collection ? collection.length : 0; - - if (typeof length == 'number') { - while (++index < length) { - var value = collection[index]; - if (callback(value, index, collection)) { - result.push(value); - } - } - } else { - forOwn(collection, function(value, index, collection) { - if (callback(value, index, collection)) { - result.push(value); - } - }); - } - return result; + function isTypedArray(value) { + return isObjectLike(value) && isLength(value.length) && !!typedArrayTags[objToString.call(value)]; } /** - * Iterates over elements of a collection, returning the first element that - * the callback returns truey for. The callback is bound to `thisArg` and - * invoked with three arguments; (value, index|key, collection). - * - * If a property name is provided for `callback` the created "_.pluck" style - * callback will return the property value of the given element. - * - * If an object is provided for `callback` the created "_.where" style callback - * will return `true` for elements that have the properties of the given object, - * else `false`. + * Checks if `value` is `undefined`. * * @static * @memberOf _ - * @alias detect, findWhere - * @category Collections - * @param {Array|Object|string} collection The collection to iterate over. - * @param {Function|Object|string} [callback=identity] The function called - * per iteration. If a property name or object is provided it will be used - * to create a "_.pluck" or "_.where" style callback, respectively. - * @param {*} [thisArg] The `this` binding of `callback`. - * @returns {*} Returns the found element, else `undefined`. + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is `undefined`, else `false`. * @example * - * var characters = [ - * { 'name': 'barney', 'age': 36, 'blocked': false }, - * { 'name': 'fred', 'age': 40, 'blocked': true }, - * { 'name': 'pebbles', 'age': 1, 'blocked': false } - * ]; - * - * _.find(characters, function(chr) { - * return chr.age < 40; - * }); - * // => { 'name': 'barney', 'age': 36, 'blocked': false } - * - * // using "_.where" callback shorthand - * _.find(characters, { 'age': 1 }); - * // => { 'name': 'pebbles', 'age': 1, 'blocked': false } + * _.isUndefined(void 0); + * // => true * - * // using "_.pluck" callback shorthand - * _.find(characters, 'blocked'); - * // => { 'name': 'fred', 'age': 40, 'blocked': true } + * _.isUndefined(null); + * // => false */ - function find(collection, callback, thisArg) { - callback = lodash.createCallback(callback, thisArg, 3); - - var index = -1, - length = collection ? collection.length : 0; - - if (typeof length == 'number') { - while (++index < length) { - var value = collection[index]; - if (callback(value, index, collection)) { - return value; - } - } - } else { - var result; - forOwn(collection, function(value, index, collection) { - if (callback(value, index, collection)) { - result = value; - return false; - } - }); - return result; - } + function isUndefined(value) { + return value === undefined; } /** - * This method is like `_.find` except that it iterates over elements - * of a `collection` from right to left. + * Checks if `value` is less than `other`. * * @static * @memberOf _ - * @category Collections - * @param {Array|Object|string} collection The collection to iterate over. - * @param {Function|Object|string} [callback=identity] The function called - * per iteration. If a property name or object is provided it will be used - * to create a "_.pluck" or "_.where" style callback, respectively. - * @param {*} [thisArg] The `this` binding of `callback`. - * @returns {*} Returns the found element, else `undefined`. + * @category Lang + * @param {*} value The value to compare. + * @param {*} other The other value to compare. + * @returns {boolean} Returns `true` if `value` is less than `other`, else `false`. * @example * - * _.findLast([1, 2, 3, 4], function(num) { - * return num % 2 == 1; - * }); - * // => 3 + * _.lt(1, 3); + * // => true + * + * _.lt(3, 3); + * // => false + * + * _.lt(3, 1); + * // => false */ - function findLast(collection, callback, thisArg) { - var result; - callback = lodash.createCallback(callback, thisArg, 3); - forEachRight(collection, function(value, index, collection) { - if (callback(value, index, collection)) { - result = value; - return false; - } - }); - return result; + function lt(value, other) { + return value < other; } /** - * Iterates over elements of a collection, executing the callback for each - * element. The callback is bound to `thisArg` and invoked with three arguments; - * (value, index|key, collection). Callbacks may exit iteration early by - * explicitly returning `false`. - * - * Note: As with other "Collections" methods, objects with a `length` property - * are iterated like arrays. To avoid this behavior `_.forIn` or `_.forOwn` - * may be used for object iteration. + * Checks if `value` is less than or equal to `other`. * * @static * @memberOf _ - * @alias each - * @category Collections - * @param {Array|Object|string} collection The collection to iterate over. - * @param {Function} [callback=identity] The function called per iteration. - * @param {*} [thisArg] The `this` binding of `callback`. - * @returns {Array|Object|string} Returns `collection`. + * @category Lang + * @param {*} value The value to compare. + * @param {*} other The other value to compare. + * @returns {boolean} Returns `true` if `value` is less than or equal to `other`, else `false`. * @example * - * _([1, 2, 3]).forEach(function(num) { console.log(num); }).join(','); - * // => logs each number and returns '1,2,3' + * _.lte(1, 3); + * // => true + * + * _.lte(3, 3); + * // => true * - * _.forEach({ 'one': 1, 'two': 2, 'three': 3 }, function(num) { console.log(num); }); - * // => logs each number and returns the object (property order is not guaranteed across environments) + * _.lte(3, 1); + * // => false */ - function forEach(collection, callback, thisArg) { - var index = -1, - length = collection ? collection.length : 0; - - callback = callback && typeof thisArg == 'undefined' ? callback : baseCreateCallback(callback, thisArg, 3); - if (typeof length == 'number') { - while (++index < length) { - if (callback(collection[index], index, collection) === false) { - break; - } - } - } else { - forOwn(collection, callback); - } - return collection; + function lte(value, other) { + return value <= other; } /** - * This method is like `_.forEach` except that it iterates over elements - * of a `collection` from right to left. + * Converts `value` to an array. * * @static * @memberOf _ - * @alias eachRight - * @category Collections - * @param {Array|Object|string} collection The collection to iterate over. - * @param {Function} [callback=identity] The function called per iteration. - * @param {*} [thisArg] The `this` binding of `callback`. - * @returns {Array|Object|string} Returns `collection`. + * @category Lang + * @param {*} value The value to convert. + * @returns {Array} Returns the converted array. * @example * - * _([1, 2, 3]).forEachRight(function(num) { console.log(num); }).join(','); - * // => logs each number from right to left and returns '3,2,1' + * (function() { + * return _.toArray(arguments).slice(1); + * }(1, 2, 3)); + * // => [2, 3] */ - function forEachRight(collection, callback, thisArg) { - var length = collection ? collection.length : 0; - callback = callback && typeof thisArg == 'undefined' ? callback : baseCreateCallback(callback, thisArg, 3); - if (typeof length == 'number') { - while (length--) { - if (callback(collection[length], length, collection) === false) { - break; - } - } - } else { - var props = keys(collection); - length = props.length; - forOwn(collection, function(value, key, collection) { - key = props ? props[--length] : --length; - return callback(collection[key], key, collection); - }); + function toArray(value) { + var length = value ? getLength(value) : 0; + if (!isLength(length)) { + return values(value); + } + if (!length) { + return []; } - return collection; + return arrayCopy(value); } /** - * Creates an object composed of keys generated from the results of running - * each element of a collection through the callback. The corresponding value - * of each key is an array of the elements responsible for generating the key. - * The callback is bound to `thisArg` and invoked with three arguments; - * (value, index|key, collection). - * - * If a property name is provided for `callback` the created "_.pluck" style - * callback will return the property value of the given element. - * - * If an object is provided for `callback` the created "_.where" style callback - * will return `true` for elements that have the properties of the given object, - * else `false` + * Converts `value` to a plain object flattening inherited enumerable + * properties of `value` to own properties of the plain object. * * @static * @memberOf _ - * @category Collections - * @param {Array|Object|string} collection The collection to iterate over. - * @param {Function|Object|string} [callback=identity] The function called - * per iteration. If a property name or object is provided it will be used - * to create a "_.pluck" or "_.where" style callback, respectively. - * @param {*} [thisArg] The `this` binding of `callback`. - * @returns {Object} Returns the composed aggregate object. + * @category Lang + * @param {*} value The value to convert. + * @returns {Object} Returns the converted plain object. * @example * - * _.groupBy([4.2, 6.1, 6.4], function(num) { return Math.floor(num); }); - * // => { '4': [4.2], '6': [6.1, 6.4] } + * function Foo() { + * this.b = 2; + * } * - * _.groupBy([4.2, 6.1, 6.4], function(num) { return this.floor(num); }, Math); - * // => { '4': [4.2], '6': [6.1, 6.4] } + * Foo.prototype.c = 3; * - * // using "_.pluck" callback shorthand - * _.groupBy(['one', 'two', 'three'], 'length'); - * // => { '3': ['one', 'two'], '5': ['three'] } + * _.assign({ 'a': 1 }, new Foo); + * // => { 'a': 1, 'b': 2 } + * + * _.assign({ 'a': 1 }, _.toPlainObject(new Foo)); + * // => { 'a': 1, 'b': 2, 'c': 3 } */ - var groupBy = createAggregator(function(result, value, key) { - (hasOwnProperty.call(result, key) ? result[key] : result[key] = []).push(value); - }); + function toPlainObject(value) { + return baseCopy(value, keysIn(value)); + } + + /*------------------------------------------------------------------------*/ /** - * Creates an object composed of keys generated from the results of running - * each element of the collection through the given callback. The corresponding - * value of each key is the last element responsible for generating the key. - * The callback is bound to `thisArg` and invoked with three arguments; - * (value, index|key, collection). - * - * If a property name is provided for `callback` the created "_.pluck" style - * callback will return the property value of the given element. - * - * If an object is provided for `callback` the created "_.where" style callback - * will return `true` for elements that have the properties of the given object, - * else `false`. + * Recursively merges own enumerable properties of the source object(s), that + * don't resolve to `undefined` into the destination object. Subsequent sources + * overwrite property assignments of previous sources. If `customizer` is + * provided it is invoked to produce the merged values of the destination and + * source properties. If `customizer` returns `undefined` merging is handled + * by the method instead. The `customizer` is bound to `thisArg` and invoked + * with five arguments: (objectValue, sourceValue, key, object, source). * * @static * @memberOf _ - * @category Collections - * @param {Array|Object|string} collection The collection to iterate over. - * @param {Function|Object|string} [callback=identity] The function called - * per iteration. If a property name or object is provided it will be used - * to create a "_.pluck" or "_.where" style callback, respectively. - * @param {*} [thisArg] The `this` binding of `callback`. - * @returns {Object} Returns the composed aggregate object. + * @category Object + * @param {Object} object The destination object. + * @param {...Object} [sources] The source objects. + * @param {Function} [customizer] The function to customize assigned values. + * @param {*} [thisArg] The `this` binding of `customizer`. + * @returns {Object} Returns `object`. * @example * - * var keys = [ - * { 'dir': 'left', 'code': 97 }, - * { 'dir': 'right', 'code': 100 } - * ]; + * var users = { + * 'data': [{ 'user': 'barney' }, { 'user': 'fred' }] + * }; * - * _.indexBy(keys, 'dir'); - * // => { 'left': { 'dir': 'left', 'code': 97 }, 'right': { 'dir': 'right', 'code': 100 } } + * var ages = { + * 'data': [{ 'age': 36 }, { 'age': 40 }] + * }; * - * _.indexBy(keys, function(key) { return String.fromCharCode(key.code); }); - * // => { 'a': { 'dir': 'left', 'code': 97 }, 'd': { 'dir': 'right', 'code': 100 } } + * _.merge(users, ages); + * // => { 'data': [{ 'user': 'barney', 'age': 36 }, { 'user': 'fred', 'age': 40 }] } * - * _.indexBy(characters, function(key) { this.fromCharCode(key.code); }, String); - * // => { 'a': { 'dir': 'left', 'code': 97 }, 'd': { 'dir': 'right', 'code': 100 } } + * // using a customizer callback + * var object = { + * 'fruits': ['apple'], + * 'vegetables': ['beet'] + * }; + * + * var other = { + * 'fruits': ['banana'], + * 'vegetables': ['carrot'] + * }; + * + * _.merge(object, other, function(a, b) { + * if (_.isArray(a)) { + * return a.concat(b); + * } + * }); + * // => { 'fruits': ['apple', 'banana'], 'vegetables': ['beet', 'carrot'] } */ - var indexBy = createAggregator(function(result, value, key) { - result[key] = value; - }); + var merge = createAssigner(baseMerge); /** - * Invokes the method named by `methodName` on each element in the `collection` - * returning an array of the results of each invoked method. Additional arguments - * will be provided to each invoked method. If `methodName` is a function it - * will be invoked for, and `this` bound to, each element in the `collection`. + * Assigns own enumerable properties of source object(s) to the destination + * object. Subsequent sources overwrite property assignments of previous sources. + * If `customizer` is provided it is invoked to produce the assigned values. + * The `customizer` is bound to `thisArg` and invoked with five arguments: + * (objectValue, sourceValue, key, object, source). + * + * **Note:** This method mutates `object` and is based on + * [`Object.assign`](http://ecma-international.org/ecma-262/6.0/#sec-object.assign). * * @static * @memberOf _ - * @category Collections - * @param {Array|Object|string} collection The collection to iterate over. - * @param {Function|string} methodName The name of the method to invoke or - * the function invoked per iteration. - * @param {...*} [arg] Arguments to invoke the method with. - * @returns {Array} Returns a new array of the results of each invoked method. + * @alias extend + * @category Object + * @param {Object} object The destination object. + * @param {...Object} [sources] The source objects. + * @param {Function} [customizer] The function to customize assigned values. + * @param {*} [thisArg] The `this` binding of `customizer`. + * @returns {Object} Returns `object`. * @example * - * _.invoke([[5, 1, 7], [3, 2, 1]], 'sort'); - * // => [[1, 5, 7], [1, 2, 3]] + * _.assign({ 'user': 'barney' }, { 'age': 40 }, { 'user': 'fred' }); + * // => { 'user': 'fred', 'age': 40 } * - * _.invoke([123, 456], String.prototype.split, ''); - * // => [['1', '2', '3'], ['4', '5', '6']] + * // using a customizer callback + * var defaults = _.partialRight(_.assign, function(value, other) { + * return _.isUndefined(value) ? other : value; + * }); + * + * defaults({ 'user': 'barney' }, { 'age': 36 }, { 'user': 'fred' }); + * // => { 'user': 'barney', 'age': 36 } */ - function invoke(collection, methodName) { - var args = slice(arguments, 2), - index = -1, - isFunc = typeof methodName == 'function', - length = collection ? collection.length : 0, - result = Array(typeof length == 'number' ? length : 0); - - forEach(collection, function(value) { - result[++index] = (isFunc ? methodName : value[methodName]).apply(value, args); - }); - return result; - } + var assign = createAssigner(function(object, source, customizer) { + return customizer + ? assignWith(object, source, customizer) + : baseAssign(object, source); + }); /** - * Creates an array of values by running each element in the collection - * through the callback. The callback is bound to `thisArg` and invoked with - * three arguments; (value, index|key, collection). - * - * If a property name is provided for `callback` the created "_.pluck" style - * callback will return the property value of the given element. - * - * If an object is provided for `callback` the created "_.where" style callback - * will return `true` for elements that have the properties of the given object, - * else `false`. + * Creates an object that inherits from the given `prototype` object. If a + * `properties` object is provided its own enumerable properties are assigned + * to the created object. * * @static * @memberOf _ - * @alias collect - * @category Collections - * @param {Array|Object|string} collection The collection to iterate over. - * @param {Function|Object|string} [callback=identity] The function called - * per iteration. If a property name or object is provided it will be used - * to create a "_.pluck" or "_.where" style callback, respectively. - * @param {*} [thisArg] The `this` binding of `callback`. - * @returns {Array} Returns a new array of the results of each `callback` execution. + * @category Object + * @param {Object} prototype The object to inherit from. + * @param {Object} [properties] The properties to assign to the object. + * @param- {Object} [guard] Enables use as a callback for functions like `_.map`. + * @returns {Object} Returns the new object. * @example * - * _.map([1, 2, 3], function(num) { return num * 3; }); - * // => [3, 6, 9] + * function Shape() { + * this.x = 0; + * this.y = 0; + * } * - * _.map({ 'one': 1, 'two': 2, 'three': 3 }, function(num) { return num * 3; }); - * // => [3, 6, 9] (property order is not guaranteed across environments) + * function Circle() { + * Shape.call(this); + * } * - * var characters = [ - * { 'name': 'barney', 'age': 36 }, - * { 'name': 'fred', 'age': 40 } - * ]; + * Circle.prototype = _.create(Shape.prototype, { + * 'constructor': Circle + * }); * - * // using "_.pluck" callback shorthand - * _.map(characters, 'name'); - * // => ['barney', 'fred'] + * var circle = new Circle; + * circle instanceof Circle; + * // => true + * + * circle instanceof Shape; + * // => true */ - function map(collection, callback, thisArg) { - var index = -1, - length = collection ? collection.length : 0; - - callback = lodash.createCallback(callback, thisArg, 3); - if (typeof length == 'number') { - var result = Array(length); - while (++index < length) { - result[index] = callback(collection[index], index, collection); - } - } else { - result = []; - forOwn(collection, function(value, key, collection) { - result[++index] = callback(value, key, collection); - }); + function create(prototype, properties, guard) { + var result = baseCreate(prototype); + if (guard && isIterateeCall(prototype, properties, guard)) { + properties = undefined; } - return result; + return properties ? baseAssign(result, properties) : result; } /** - * Retrieves the maximum value of a collection. If the collection is empty or - * falsey `-Infinity` is returned. If a callback is provided it will be executed - * for each value in the collection to generate the criterion by which the value - * is ranked. The callback is bound to `thisArg` and invoked with three - * arguments; (value, index, collection). - * - * If a property name is provided for `callback` the created "_.pluck" style - * callback will return the property value of the given element. + * Assigns own enumerable properties of source object(s) to the destination + * object for all destination properties that resolve to `undefined`. Once a + * property is set, additional values of the same property are ignored. * - * If an object is provided for `callback` the created "_.where" style callback - * will return `true` for elements that have the properties of the given object, - * else `false`. + * **Note:** This method mutates `object`. * * @static * @memberOf _ - * @category Collections - * @param {Array|Object|string} collection The collection to iterate over. - * @param {Function|Object|string} [callback=identity] The function called - * per iteration. If a property name or object is provided it will be used - * to create a "_.pluck" or "_.where" style callback, respectively. - * @param {*} [thisArg] The `this` binding of `callback`. - * @returns {*} Returns the maximum value. + * @category Object + * @param {Object} object The destination object. + * @param {...Object} [sources] The source objects. + * @returns {Object} Returns `object`. * @example * - * _.max([4, 2, 8, 6]); - * // => 8 + * _.defaults({ 'user': 'barney' }, { 'age': 36 }, { 'user': 'fred' }); + * // => { 'user': 'barney', 'age': 36 } + */ + var defaults = createDefaults(assign, assignDefaults); + + /** + * This method is like `_.defaults` except that it recursively assigns + * default properties. * - * var characters = [ - * { 'name': 'barney', 'age': 36 }, - * { 'name': 'fred', 'age': 40 } - * ]; + * **Note:** This method mutates `object`. + * + * @static + * @memberOf _ + * @category Object + * @param {Object} object The destination object. + * @param {...Object} [sources] The source objects. + * @returns {Object} Returns `object`. + * @example * - * _.max(characters, function(chr) { return chr.age; }); - * // => { 'name': 'fred', 'age': 40 }; + * _.defaultsDeep({ 'user': { 'name': 'barney' } }, { 'user': { 'name': 'fred', 'age': 36 } }); + * // => { 'user': { 'name': 'barney', 'age': 36 } } * - * // using "_.pluck" callback shorthand - * _.max(characters, 'age'); - * // => { 'name': 'fred', 'age': 40 }; */ - function max(collection, callback, thisArg) { - var computed = -Infinity, - result = computed; - - // allows working with functions like `_.map` without using - // their `index` argument as a callback - if (typeof callback != 'function' && thisArg && thisArg[callback] === collection) { - callback = null; - } - if (callback == null && isArray(collection)) { - var index = -1, - length = collection.length; - - while (++index < length) { - var value = collection[index]; - if (value > result) { - result = value; - } - } - } else { - callback = (callback == null && isString(collection)) - ? charAtCallback - : lodash.createCallback(callback, thisArg, 3); - - forEach(collection, function(value, index, collection) { - var current = callback(value, index, collection); - if (current > computed) { - computed = current; - result = value; - } - }); - } - return result; - } + var defaultsDeep = createDefaults(merge, mergeDefaults); /** - * Retrieves the minimum value of a collection. If the collection is empty or - * falsey `Infinity` is returned. If a callback is provided it will be executed - * for each value in the collection to generate the criterion by which the value - * is ranked. The callback is bound to `thisArg` and invoked with three - * arguments; (value, index, collection). + * This method is like `_.find` except that it returns the key of the first + * element `predicate` returns truthy for instead of the element itself. * - * If a property name is provided for `callback` the created "_.pluck" style - * callback will return the property value of the given element. + * If a property name is provided for `predicate` the created `_.property` + * style callback returns the property value of the given element. * - * If an object is provided for `callback` the created "_.where" style callback - * will return `true` for elements that have the properties of the given object, - * else `false`. + * If a value is also provided for `thisArg` the created `_.matchesProperty` + * style callback returns `true` for elements that have a matching property + * value, else `false`. + * + * If an object is provided for `predicate` the created `_.matches` style + * callback returns `true` for elements that have the properties of the given + * object, else `false`. * * @static * @memberOf _ - * @category Collections - * @param {Array|Object|string} collection The collection to iterate over. - * @param {Function|Object|string} [callback=identity] The function called - * per iteration. If a property name or object is provided it will be used - * to create a "_.pluck" or "_.where" style callback, respectively. - * @param {*} [thisArg] The `this` binding of `callback`. - * @returns {*} Returns the minimum value. + * @category Object + * @param {Object} object The object to search. + * @param {Function|Object|string} [predicate=_.identity] The function invoked + * per iteration. + * @param {*} [thisArg] The `this` binding of `predicate`. + * @returns {string|undefined} Returns the key of the matched element, else `undefined`. * @example * - * _.min([4, 2, 8, 6]); - * // => 2 + * var users = { + * 'barney': { 'age': 36, 'active': true }, + * 'fred': { 'age': 40, 'active': false }, + * 'pebbles': { 'age': 1, 'active': true } + * }; * - * var characters = [ - * { 'name': 'barney', 'age': 36 }, - * { 'name': 'fred', 'age': 40 } - * ]; + * _.findKey(users, function(chr) { + * return chr.age < 40; + * }); + * // => 'barney' (iteration order is not guaranteed) * - * _.min(characters, function(chr) { return chr.age; }); - * // => { 'name': 'barney', 'age': 36 }; + * // using the `_.matches` callback shorthand + * _.findKey(users, { 'age': 1, 'active': true }); + * // => 'pebbles' + * + * // using the `_.matchesProperty` callback shorthand + * _.findKey(users, 'active', false); + * // => 'fred' * - * // using "_.pluck" callback shorthand - * _.min(characters, 'age'); - * // => { 'name': 'barney', 'age': 36 }; + * // using the `_.property` callback shorthand + * _.findKey(users, 'active'); + * // => 'barney' */ - function min(collection, callback, thisArg) { - var computed = Infinity, - result = computed; - - // allows working with functions like `_.map` without using - // their `index` argument as a callback - if (typeof callback != 'function' && thisArg && thisArg[callback] === collection) { - callback = null; - } - if (callback == null && isArray(collection)) { - var index = -1, - length = collection.length; - - while (++index < length) { - var value = collection[index]; - if (value < result) { - result = value; - } - } - } else { - callback = (callback == null && isString(collection)) - ? charAtCallback - : lodash.createCallback(callback, thisArg, 3); - - forEach(collection, function(value, index, collection) { - var current = callback(value, index, collection); - if (current < computed) { - computed = current; - result = value; - } - }); - } - return result; - } + var findKey = createFindKey(baseForOwn); /** - * Retrieves the value of a specified property from all elements in the collection. + * This method is like `_.findKey` except that it iterates over elements of + * a collection in the opposite order. + * + * If a property name is provided for `predicate` the created `_.property` + * style callback returns the property value of the given element. + * + * If a value is also provided for `thisArg` the created `_.matchesProperty` + * style callback returns `true` for elements that have a matching property + * value, else `false`. + * + * If an object is provided for `predicate` the created `_.matches` style + * callback returns `true` for elements that have the properties of the given + * object, else `false`. * * @static * @memberOf _ - * @type Function - * @category Collections - * @param {Array|Object|string} collection The collection to iterate over. - * @param {string} property The name of the property to pluck. - * @returns {Array} Returns a new array of property values. + * @category Object + * @param {Object} object The object to search. + * @param {Function|Object|string} [predicate=_.identity] The function invoked + * per iteration. + * @param {*} [thisArg] The `this` binding of `predicate`. + * @returns {string|undefined} Returns the key of the matched element, else `undefined`. * @example * - * var characters = [ - * { 'name': 'barney', 'age': 36 }, - * { 'name': 'fred', 'age': 40 } - * ]; + * var users = { + * 'barney': { 'age': 36, 'active': true }, + * 'fred': { 'age': 40, 'active': false }, + * 'pebbles': { 'age': 1, 'active': true } + * }; * - * _.pluck(characters, 'name'); - * // => ['barney', 'fred'] + * _.findLastKey(users, function(chr) { + * return chr.age < 40; + * }); + * // => returns `pebbles` assuming `_.findKey` returns `barney` + * + * // using the `_.matches` callback shorthand + * _.findLastKey(users, { 'age': 36, 'active': true }); + * // => 'barney' + * + * // using the `_.matchesProperty` callback shorthand + * _.findLastKey(users, 'active', false); + * // => 'fred' + * + * // using the `_.property` callback shorthand + * _.findLastKey(users, 'active'); + * // => 'pebbles' */ - var pluck = map; + var findLastKey = createFindKey(baseForOwnRight); /** - * Reduces a collection to a value which is the accumulated result of running - * each element in the collection through the callback, where each successive - * callback execution consumes the return value of the previous execution. If - * `accumulator` is not provided the first element of the collection will be - * used as the initial `accumulator` value. The callback is bound to `thisArg` - * and invoked with four arguments; (accumulator, value, index|key, collection). + * Iterates over own and inherited enumerable properties of an object invoking + * `iteratee` for each property. The `iteratee` is bound to `thisArg` and invoked + * with three arguments: (value, key, object). Iteratee functions may exit + * iteration early by explicitly returning `false`. * * @static * @memberOf _ - * @alias foldl, inject - * @category Collections - * @param {Array|Object|string} collection The collection to iterate over. - * @param {Function} [callback=identity] The function called per iteration. - * @param {*} [accumulator] Initial value of the accumulator. - * @param {*} [thisArg] The `this` binding of `callback`. - * @returns {*} Returns the accumulated value. + * @category Object + * @param {Object} object The object to iterate over. + * @param {Function} [iteratee=_.identity] The function invoked per iteration. + * @param {*} [thisArg] The `this` binding of `iteratee`. + * @returns {Object} Returns `object`. * @example * - * var sum = _.reduce([1, 2, 3], function(sum, num) { - * return sum + num; - * }); - * // => 6 - * - * var mapped = _.reduce({ 'a': 1, 'b': 2, 'c': 3 }, function(result, num, key) { - * result[key] = num * 3; - * return result; - * }, {}); - * // => { 'a': 3, 'b': 6, 'c': 9 } - */ - function reduce(collection, callback, accumulator, thisArg) { - if (!collection) return accumulator; - var noaccum = arguments.length < 3; - callback = lodash.createCallback(callback, thisArg, 4); - - var index = -1, - length = collection.length; - - if (typeof length == 'number') { - if (noaccum) { - accumulator = collection[++index]; - } - while (++index < length) { - accumulator = callback(accumulator, collection[index], index, collection); - } - } else { - forOwn(collection, function(value, index, collection) { - accumulator = noaccum - ? (noaccum = false, value) - : callback(accumulator, value, index, collection) - }); - } - return accumulator; - } + * function Foo() { + * this.a = 1; + * this.b = 2; + * } + * + * Foo.prototype.c = 3; + * + * _.forIn(new Foo, function(value, key) { + * console.log(key); + * }); + * // => logs 'a', 'b', and 'c' (iteration order is not guaranteed) + */ + var forIn = createForIn(baseFor); /** - * This method is like `_.reduce` except that it iterates over elements - * of a `collection` from right to left. + * This method is like `_.forIn` except that it iterates over properties of + * `object` in the opposite order. * * @static * @memberOf _ - * @alias foldr - * @category Collections - * @param {Array|Object|string} collection The collection to iterate over. - * @param {Function} [callback=identity] The function called per iteration. - * @param {*} [accumulator] Initial value of the accumulator. - * @param {*} [thisArg] The `this` binding of `callback`. - * @returns {*} Returns the accumulated value. + * @category Object + * @param {Object} object The object to iterate over. + * @param {Function} [iteratee=_.identity] The function invoked per iteration. + * @param {*} [thisArg] The `this` binding of `iteratee`. + * @returns {Object} Returns `object`. * @example * - * var list = [[0, 1], [2, 3], [4, 5]]; - * var flat = _.reduceRight(list, function(a, b) { return a.concat(b); }, []); - * // => [4, 5, 2, 3, 0, 1] + * function Foo() { + * this.a = 1; + * this.b = 2; + * } + * + * Foo.prototype.c = 3; + * + * _.forInRight(new Foo, function(value, key) { + * console.log(key); + * }); + * // => logs 'c', 'b', and 'a' assuming `_.forIn ` logs 'a', 'b', and 'c' */ - function reduceRight(collection, callback, accumulator, thisArg) { - var noaccum = arguments.length < 3; - callback = lodash.createCallback(callback, thisArg, 4); - forEachRight(collection, function(value, index, collection) { - accumulator = noaccum - ? (noaccum = false, value) - : callback(accumulator, value, index, collection); - }); - return accumulator; - } + var forInRight = createForIn(baseForRight); /** - * The opposite of `_.filter` this method returns the elements of a - * collection that the callback does **not** return truey for. - * - * If a property name is provided for `callback` the created "_.pluck" style - * callback will return the property value of the given element. - * - * If an object is provided for `callback` the created "_.where" style callback - * will return `true` for elements that have the properties of the given object, - * else `false`. + * Iterates over own enumerable properties of an object invoking `iteratee` + * for each property. The `iteratee` is bound to `thisArg` and invoked with + * three arguments: (value, key, object). Iteratee functions may exit iteration + * early by explicitly returning `false`. * * @static * @memberOf _ - * @category Collections - * @param {Array|Object|string} collection The collection to iterate over. - * @param {Function|Object|string} [callback=identity] The function called - * per iteration. If a property name or object is provided it will be used - * to create a "_.pluck" or "_.where" style callback, respectively. - * @param {*} [thisArg] The `this` binding of `callback`. - * @returns {Array} Returns a new array of elements that failed the callback check. + * @category Object + * @param {Object} object The object to iterate over. + * @param {Function} [iteratee=_.identity] The function invoked per iteration. + * @param {*} [thisArg] The `this` binding of `iteratee`. + * @returns {Object} Returns `object`. * @example * - * var odds = _.reject([1, 2, 3, 4, 5, 6], function(num) { return num % 2 == 0; }); - * // => [1, 3, 5] - * - * var characters = [ - * { 'name': 'barney', 'age': 36, 'blocked': false }, - * { 'name': 'fred', 'age': 40, 'blocked': true } - * ]; + * function Foo() { + * this.a = 1; + * this.b = 2; + * } * - * // using "_.pluck" callback shorthand - * _.reject(characters, 'blocked'); - * // => [{ 'name': 'barney', 'age': 36, 'blocked': false }] + * Foo.prototype.c = 3; * - * // using "_.where" callback shorthand - * _.reject(characters, { 'age': 36 }); - * // => [{ 'name': 'fred', 'age': 40, 'blocked': true }] + * _.forOwn(new Foo, function(value, key) { + * console.log(key); + * }); + * // => logs 'a' and 'b' (iteration order is not guaranteed) */ - function reject(collection, callback, thisArg) { - callback = lodash.createCallback(callback, thisArg, 3); - return filter(collection, function(value, index, collection) { - return !callback(value, index, collection); - }); - } + var forOwn = createForOwn(baseForOwn); /** - * Retrieves a random element or `n` random elements from a collection. + * This method is like `_.forOwn` except that it iterates over properties of + * `object` in the opposite order. * * @static * @memberOf _ - * @category Collections - * @param {Array|Object|string} collection The collection to sample. - * @param {number} [n] The number of elements to sample. - * @param- {Object} [guard] Allows working with functions like `_.map` - * without using their `index` arguments as `n`. - * @returns {Array} Returns the random sample(s) of `collection`. + * @category Object + * @param {Object} object The object to iterate over. + * @param {Function} [iteratee=_.identity] The function invoked per iteration. + * @param {*} [thisArg] The `this` binding of `iteratee`. + * @returns {Object} Returns `object`. * @example * - * _.sample([1, 2, 3, 4]); - * // => 2 + * function Foo() { + * this.a = 1; + * this.b = 2; + * } * - * _.sample([1, 2, 3, 4], 2); - * // => [3, 1] + * Foo.prototype.c = 3; + * + * _.forOwnRight(new Foo, function(value, key) { + * console.log(key); + * }); + * // => logs 'b' and 'a' assuming `_.forOwn` logs 'a' and 'b' */ - function sample(collection, n, guard) { - if (collection && typeof collection.length != 'number') { - collection = values(collection); - } - if (n == null || guard) { - return collection ? collection[baseRandom(0, collection.length - 1)] : undefined; - } - var result = shuffle(collection); - result.length = nativeMin(nativeMax(0, n), result.length); - return result; - } + var forOwnRight = createForOwn(baseForOwnRight); /** - * Creates an array of shuffled values, using a version of the Fisher-Yates - * shuffle. See http://en.wikipedia.org/wiki/Fisher-Yates_shuffle. + * Creates an array of function property names from all enumerable properties, + * own and inherited, of `object`. * * @static * @memberOf _ - * @category Collections - * @param {Array|Object|string} collection The collection to shuffle. - * @returns {Array} Returns a new shuffled collection. + * @alias methods + * @category Object + * @param {Object} object The object to inspect. + * @returns {Array} Returns the new array of property names. * @example * - * _.shuffle([1, 2, 3, 4, 5, 6]); - * // => [4, 1, 6, 3, 5, 2] + * _.functions(_); + * // => ['after', 'ary', 'assign', ...] */ - function shuffle(collection) { - var index = -1, - length = collection ? collection.length : 0, - result = Array(typeof length == 'number' ? length : 0); - - forEach(collection, function(value) { - var rand = baseRandom(0, ++index); - result[index] = result[rand]; - result[rand] = value; - }); - return result; + function functions(object) { + return baseFunctions(object, keysIn(object)); } /** - * Gets the size of the `collection` by returning `collection.length` for arrays - * and array-like objects or the number of own enumerable properties for objects. + * Gets the property value at `path` of `object`. If the resolved value is + * `undefined` the `defaultValue` is used in its place. * * @static * @memberOf _ - * @category Collections - * @param {Array|Object|string} collection The collection to inspect. - * @returns {number} Returns `collection.length` or number of own enumerable properties. + * @category Object + * @param {Object} object The object to query. + * @param {Array|string} path The path of the property to get. + * @param {*} [defaultValue] The value returned if the resolved value is `undefined`. + * @returns {*} Returns the resolved value. * @example * - * _.size([1, 2]); - * // => 2 + * var object = { 'a': [{ 'b': { 'c': 3 } }] }; * - * _.size({ 'one': 1, 'two': 2, 'three': 3 }); + * _.get(object, 'a[0].b.c'); * // => 3 * - * _.size('pebbles'); - * // => 7 + * _.get(object, ['a', '0', 'b', 'c']); + * // => 3 + * + * _.get(object, 'a.b.c', 'default'); + * // => 'default' */ - function size(collection) { - var length = collection ? collection.length : 0; - return typeof length == 'number' ? length : keys(collection).length; + function get(object, path, defaultValue) { + var result = object == null ? undefined : baseGet(object, toPath(path), path + ''); + return result === undefined ? defaultValue : result; } /** - * Checks if the callback returns a truey value for **any** element of a - * collection. The function returns as soon as it finds a passing value and - * does not iterate over the entire collection. The callback is bound to - * `thisArg` and invoked with three arguments; (value, index|key, collection). - * - * If a property name is provided for `callback` the created "_.pluck" style - * callback will return the property value of the given element. - * - * If an object is provided for `callback` the created "_.where" style callback - * will return `true` for elements that have the properties of the given object, - * else `false`. + * Checks if `path` is a direct property. * * @static * @memberOf _ - * @alias any - * @category Collections - * @param {Array|Object|string} collection The collection to iterate over. - * @param {Function|Object|string} [callback=identity] The function called - * per iteration. If a property name or object is provided it will be used - * to create a "_.pluck" or "_.where" style callback, respectively. - * @param {*} [thisArg] The `this` binding of `callback`. - * @returns {boolean} Returns `true` if any element passed the callback check, - * else `false`. + * @category Object + * @param {Object} object The object to query. + * @param {Array|string} path The path to check. + * @returns {boolean} Returns `true` if `path` is a direct property, else `false`. * @example * - * _.some([null, 0, 'yes', false], Boolean); - * // => true + * var object = { 'a': { 'b': { 'c': 3 } } }; * - * var characters = [ - * { 'name': 'barney', 'age': 36, 'blocked': false }, - * { 'name': 'fred', 'age': 40, 'blocked': true } - * ]; + * _.has(object, 'a'); + * // => true * - * // using "_.pluck" callback shorthand - * _.some(characters, 'blocked'); + * _.has(object, 'a.b.c'); * // => true * - * // using "_.where" callback shorthand - * _.some(characters, { 'age': 1 }); - * // => false + * _.has(object, ['a', 'b', 'c']); + * // => true */ - function some(collection, callback, thisArg) { - var result; - callback = lodash.createCallback(callback, thisArg, 3); - - var index = -1, - length = collection ? collection.length : 0; - - if (typeof length == 'number') { - while (++index < length) { - if ((result = callback(collection[index], index, collection))) { - break; - } + function has(object, path) { + if (object == null) { + return false; + } + var result = hasOwnProperty.call(object, path); + if (!result && !isKey(path)) { + path = toPath(path); + object = path.length == 1 ? object : baseGet(object, baseSlice(path, 0, -1)); + if (object == null) { + return false; } - } else { - forOwn(collection, function(value, index, collection) { - return !(result = callback(value, index, collection)); - }); + path = last(path); + result = hasOwnProperty.call(object, path); } - return !!result; + return result || (isLength(object.length) && isIndex(path, object.length) && + (isArray(object) || isArguments(object))); } /** - * Creates an array of elements, sorted in ascending order by the results of - * running each element in a collection through the callback. This method - * performs a stable sort, that is, it will preserve the original sort order - * of equal elements. The callback is bound to `thisArg` and invoked with - * three arguments; (value, index|key, collection). - * - * If a property name is provided for `callback` the created "_.pluck" style - * callback will return the property value of the given element. - * - * If an array of property names is provided for `callback` the collection - * will be sorted by each property value. - * - * If an object is provided for `callback` the created "_.where" style callback - * will return `true` for elements that have the properties of the given object, - * else `false`. + * Creates an object composed of the inverted keys and values of `object`. + * If `object` contains duplicate values, subsequent values overwrite property + * assignments of previous values unless `multiValue` is `true`. * * @static * @memberOf _ - * @category Collections - * @param {Array|Object|string} collection The collection to iterate over. - * @param {Array|Function|Object|string} [callback=identity] The function called - * per iteration. If a property name or object is provided it will be used - * to create a "_.pluck" or "_.where" style callback, respectively. - * @param {*} [thisArg] The `this` binding of `callback`. - * @returns {Array} Returns a new array of sorted elements. + * @category Object + * @param {Object} object The object to invert. + * @param {boolean} [multiValue] Allow multiple values per key. + * @param- {Object} [guard] Enables use as a callback for functions like `_.map`. + * @returns {Object} Returns the new inverted object. * @example * - * _.sortBy([1, 2, 3], function(num) { return Math.sin(num); }); - * // => [3, 1, 2] - * - * _.sortBy([1, 2, 3], function(num) { return this.sin(num); }, Math); - * // => [3, 1, 2] - * - * var characters = [ - * { 'name': 'barney', 'age': 36 }, - * { 'name': 'fred', 'age': 40 }, - * { 'name': 'barney', 'age': 26 }, - * { 'name': 'fred', 'age': 30 } - * ]; + * var object = { 'a': 1, 'b': 2, 'c': 1 }; * - * // using "_.pluck" callback shorthand - * _.map(_.sortBy(characters, 'age'), _.values); - * // => [['barney', 26], ['fred', 30], ['barney', 36], ['fred', 40]] + * _.invert(object); + * // => { '1': 'c', '2': 'b' } * - * // sorting by multiple properties - * _.map(_.sortBy(characters, ['name', 'age']), _.values); - * // = > [['barney', 26], ['barney', 36], ['fred', 30], ['fred', 40]] + * // with `multiValue` + * _.invert(object, true); + * // => { '1': ['a', 'c'], '2': ['b'] } */ - function sortBy(collection, callback, thisArg) { + function invert(object, multiValue, guard) { + if (guard && isIterateeCall(object, multiValue, guard)) { + multiValue = undefined; + } var index = -1, - isArr = isArray(callback), - length = collection ? collection.length : 0, - result = Array(typeof length == 'number' ? length : 0); + props = keys(object), + length = props.length, + result = {}; - if (!isArr) { - callback = lodash.createCallback(callback, thisArg, 3); - } - forEach(collection, function(value, key, collection) { - var object = result[++index] = getObject(); - if (isArr) { - object.criteria = map(callback, function(key) { return value[key]; }); - } else { - (object.criteria = getArray())[0] = callback(value, key, collection); - } - object.index = index; - object.value = value; - }); + while (++index < length) { + var key = props[index], + value = object[key]; - length = result.length; - result.sort(compareAscending); - while (length--) { - var object = result[length]; - result[length] = object.value; - if (!isArr) { - releaseArray(object.criteria); + if (multiValue) { + if (hasOwnProperty.call(result, value)) { + result[value].push(key); + } else { + result[value] = [key]; + } + } + else { + result[value] = key; } - releaseObject(object); } return result; } /** - * Converts the `collection` to an array. + * Creates an array of the own enumerable property names of `object`. + * + * **Note:** Non-object values are coerced to objects. See the + * [ES spec](http://ecma-international.org/ecma-262/6.0/#sec-object.keys) + * for more details. * * @static * @memberOf _ - * @category Collections - * @param {Array|Object|string} collection The collection to convert. - * @returns {Array} Returns the new converted array. + * @category Object + * @param {Object} object The object to query. + * @returns {Array} Returns the array of property names. * @example * - * (function() { return _.toArray(arguments).slice(1); })(1, 2, 3, 4); - * // => [2, 3, 4] + * function Foo() { + * this.a = 1; + * this.b = 2; + * } + * + * Foo.prototype.c = 3; + * + * _.keys(new Foo); + * // => ['a', 'b'] (iteration order is not guaranteed) + * + * _.keys('hi'); + * // => ['0', '1'] */ - function toArray(collection) { - if (collection && typeof collection.length == 'number') { - return slice(collection); + var keys = !nativeKeys ? shimKeys : function(object) { + var Ctor = object == null ? undefined : object.constructor; + if ((typeof Ctor == 'function' && Ctor.prototype === object) || + (typeof object != 'function' && isArrayLike(object))) { + return shimKeys(object); } - return values(collection); - } + return isObject(object) ? nativeKeys(object) : []; + }; /** - * Performs a deep comparison of each element in a `collection` to the given - * `properties` object, returning an array of all elements that have equivalent - * property values. + * Creates an array of the own and inherited enumerable property names of `object`. + * + * **Note:** Non-object values are coerced to objects. * * @static * @memberOf _ - * @type Function - * @category Collections - * @param {Array|Object|string} collection The collection to iterate over. - * @param {Object} props The object of property values to filter by. - * @returns {Array} Returns a new array of elements that have the given properties. + * @category Object + * @param {Object} object The object to query. + * @returns {Array} Returns the array of property names. * @example * - * var characters = [ - * { 'name': 'barney', 'age': 36, 'pets': ['hoppy'] }, - * { 'name': 'fred', 'age': 40, 'pets': ['baby puss', 'dino'] } - * ]; + * function Foo() { + * this.a = 1; + * this.b = 2; + * } * - * _.where(characters, { 'age': 36 }); - * // => [{ 'name': 'barney', 'age': 36, 'pets': ['hoppy'] }] + * Foo.prototype.c = 3; * - * _.where(characters, { 'pets': ['dino'] }); - * // => [{ 'name': 'fred', 'age': 40, 'pets': ['baby puss', 'dino'] }] + * _.keysIn(new Foo); + * // => ['a', 'b', 'c'] (iteration order is not guaranteed) */ - var where = filter; - - /*--------------------------------------------------------------------------*/ + function keysIn(object) { + if (object == null) { + return []; + } + if (!isObject(object)) { + object = Object(object); + } + var length = object.length; + length = (length && isLength(length) && + (isArray(object) || isArguments(object)) && length) || 0; - /** - * Creates an array with all falsey values removed. The values `false`, `null`, - * `0`, `""`, `undefined`, and `NaN` are all falsey. - * - * @static - * @memberOf _ - * @category Arrays - * @param {Array} array The array to compact. - * @returns {Array} Returns a new array of filtered values. - * @example - * - * _.compact([0, 1, false, 2, '', 3]); - * // => [1, 2, 3] - */ - function compact(array) { - var index = -1, - length = array ? array.length : 0, - result = []; + var Ctor = object.constructor, + index = -1, + isProto = typeof Ctor == 'function' && Ctor.prototype === object, + result = Array(length), + skipIndexes = length > 0; while (++index < length) { - var value = array[index]; - if (value) { - result.push(value); + result[index] = (index + ''); + } + for (var key in object) { + if (!(skipIndexes && isIndex(key, length)) && + !(key == 'constructor' && (isProto || !hasOwnProperty.call(object, key)))) { + result.push(key); } } return result; } /** - * Creates an array excluding all values of the provided arrays using strict - * equality for comparisons, i.e. `===`. + * The opposite of `_.mapValues`; this method creates an object with the + * same values as `object` and keys generated by running each own enumerable + * property of `object` through `iteratee`. * * @static * @memberOf _ - * @category Arrays - * @param {Array} array The array to process. - * @param {...Array} [values] The arrays of values to exclude. - * @returns {Array} Returns a new array of filtered values. + * @category Object + * @param {Object} object The object to iterate over. + * @param {Function|Object|string} [iteratee=_.identity] The function invoked + * per iteration. + * @param {*} [thisArg] The `this` binding of `iteratee`. + * @returns {Object} Returns the new mapped object. * @example * - * _.difference([1, 2, 3, 4, 5], [5, 2, 10]); - * // => [1, 3, 4] + * _.mapKeys({ 'a': 1, 'b': 2 }, function(value, key) { + * return key + value; + * }); + * // => { 'a1': 1, 'b2': 2 } */ - function difference(array) { - return baseDifference(array, baseFlatten(arguments, true, true, 1)); - } + var mapKeys = createObjectMapper(true); /** - * This method is like `_.find` except that it returns the index of the first - * element that passes the callback check, instead of the element itself. + * Creates an object with the same keys as `object` and values generated by + * running each own enumerable property of `object` through `iteratee`. The + * iteratee function is bound to `thisArg` and invoked with three arguments: + * (value, key, object). * - * If a property name is provided for `callback` the created "_.pluck" style - * callback will return the property value of the given element. + * If a property name is provided for `iteratee` the created `_.property` + * style callback returns the property value of the given element. * - * If an object is provided for `callback` the created "_.where" style callback - * will return `true` for elements that have the properties of the given object, - * else `false`. + * If a value is also provided for `thisArg` the created `_.matchesProperty` + * style callback returns `true` for elements that have a matching property + * value, else `false`. + * + * If an object is provided for `iteratee` the created `_.matches` style + * callback returns `true` for elements that have the properties of the given + * object, else `false`. * * @static * @memberOf _ - * @category Arrays - * @param {Array} array The array to search. - * @param {Function|Object|string} [callback=identity] The function called - * per iteration. If a property name or object is provided it will be used - * to create a "_.pluck" or "_.where" style callback, respectively. - * @param {*} [thisArg] The `this` binding of `callback`. - * @returns {number} Returns the index of the found element, else `-1`. + * @category Object + * @param {Object} object The object to iterate over. + * @param {Function|Object|string} [iteratee=_.identity] The function invoked + * per iteration. + * @param {*} [thisArg] The `this` binding of `iteratee`. + * @returns {Object} Returns the new mapped object. * @example * - * var characters = [ - * { 'name': 'barney', 'age': 36, 'blocked': false }, - * { 'name': 'fred', 'age': 40, 'blocked': true }, - * { 'name': 'pebbles', 'age': 1, 'blocked': false } - * ]; - * - * _.findIndex(characters, function(chr) { - * return chr.age < 20; + * _.mapValues({ 'a': 1, 'b': 2 }, function(n) { + * return n * 3; * }); - * // => 2 + * // => { 'a': 3, 'b': 6 } * - * // using "_.where" callback shorthand - * _.findIndex(characters, { 'age': 36 }); - * // => 0 + * var users = { + * 'fred': { 'user': 'fred', 'age': 40 }, + * 'pebbles': { 'user': 'pebbles', 'age': 1 } + * }; * - * // using "_.pluck" callback shorthand - * _.findIndex(characters, 'blocked'); - * // => 1 + * // using the `_.property` callback shorthand + * _.mapValues(users, 'age'); + * // => { 'fred': 40, 'pebbles': 1 } (iteration order is not guaranteed) */ - function findIndex(array, callback, thisArg) { - var index = -1, - length = array ? array.length : 0; - - callback = lodash.createCallback(callback, thisArg, 3); - while (++index < length) { - if (callback(array[index], index, array)) { - return index; - } - } - return -1; - } + var mapValues = createObjectMapper(); /** - * This method is like `_.findIndex` except that it iterates over elements - * of a `collection` from right to left. - * - * If a property name is provided for `callback` the created "_.pluck" style - * callback will return the property value of the given element. - * - * If an object is provided for `callback` the created "_.where" style callback - * will return `true` for elements that have the properties of the given object, - * else `false`. + * The opposite of `_.pick`; this method creates an object composed of the + * own and inherited enumerable properties of `object` that are not omitted. * * @static * @memberOf _ - * @category Arrays - * @param {Array} array The array to search. - * @param {Function|Object|string} [callback=identity] The function called - * per iteration. If a property name or object is provided it will be used - * to create a "_.pluck" or "_.where" style callback, respectively. - * @param {*} [thisArg] The `this` binding of `callback`. - * @returns {number} Returns the index of the found element, else `-1`. + * @category Object + * @param {Object} object The source object. + * @param {Function|...(string|string[])} [predicate] The function invoked per + * iteration or property names to omit, specified as individual property + * names or arrays of property names. + * @param {*} [thisArg] The `this` binding of `predicate`. + * @returns {Object} Returns the new object. * @example * - * var characters = [ - * { 'name': 'barney', 'age': 36, 'blocked': true }, - * { 'name': 'fred', 'age': 40, 'blocked': false }, - * { 'name': 'pebbles', 'age': 1, 'blocked': true } - * ]; - * - * _.findLastIndex(characters, function(chr) { - * return chr.age > 30; - * }); - * // => 1 + * var object = { 'user': 'fred', 'age': 40 }; * - * // using "_.where" callback shorthand - * _.findLastIndex(characters, { 'age': 36 }); - * // => 0 + * _.omit(object, 'age'); + * // => { 'user': 'fred' } * - * // using "_.pluck" callback shorthand - * _.findLastIndex(characters, 'blocked'); - * // => 2 + * _.omit(object, _.isNumber); + * // => { 'user': 'fred' } */ - function findLastIndex(array, callback, thisArg) { - var length = array ? array.length : 0; - callback = lodash.createCallback(callback, thisArg, 3); - while (length--) { - if (callback(array[length], length, array)) { - return length; - } + var omit = restParam(function(object, props) { + if (object == null) { + return {}; } - return -1; - } + if (typeof props[0] != 'function') { + var props = arrayMap(baseFlatten(props), String); + return pickByArray(object, baseDifference(keysIn(object), props)); + } + var predicate = bindCallback(props[0], props[1], 3); + return pickByCallback(object, function(value, key, object) { + return !predicate(value, key, object); + }); + }); /** - * Gets the first element or first `n` elements of an array. If a callback - * is provided elements at the beginning of the array are returned as long - * as the callback returns truey. The callback is bound to `thisArg` and - * invoked with three arguments; (value, index, array). - * - * If a property name is provided for `callback` the created "_.pluck" style - * callback will return the property value of the given element. - * - * If an object is provided for `callback` the created "_.where" style callback - * will return `true` for elements that have the properties of the given object, - * else `false`. + * Creates a two dimensional array of the key-value pairs for `object`, + * e.g. `[[key1, value1], [key2, value2]]`. * * @static * @memberOf _ - * @alias head, take - * @category Arrays - * @param {Array} array The array to query. - * @param {Function|Object|number|string} [callback] The function called - * per element or the number of elements to return. If a property name or - * object is provided it will be used to create a "_.pluck" or "_.where" - * style callback, respectively. - * @param {*} [thisArg] The `this` binding of `callback`. - * @returns {*} Returns the first element(s) of `array`. + * @category Object + * @param {Object} object The object to query. + * @returns {Array} Returns the new array of key-value pairs. * @example * - * _.first([1, 2, 3]); - * // => 1 - * - * _.first([1, 2, 3], 2); - * // => [1, 2] - * - * _.first([1, 2, 3], function(num) { - * return num < 3; - * }); - * // => [1, 2] - * - * var characters = [ - * { 'name': 'barney', 'blocked': true, 'employer': 'slate' }, - * { 'name': 'fred', 'blocked': false, 'employer': 'slate' }, - * { 'name': 'pebbles', 'blocked': true, 'employer': 'na' } - * ]; - * - * // using "_.pluck" callback shorthand - * _.first(characters, 'blocked'); - * // => [{ 'name': 'barney', 'blocked': true, 'employer': 'slate' }] - * - * // using "_.where" callback shorthand - * _.pluck(_.first(characters, { 'employer': 'slate' }), 'name'); - * // => ['barney', 'fred'] + * _.pairs({ 'barney': 36, 'fred': 40 }); + * // => [['barney', 36], ['fred', 40]] (iteration order is not guaranteed) */ - function first(array, callback, thisArg) { - var n = 0, - length = array ? array.length : 0; + function pairs(object) { + object = toObject(object); - if (typeof callback != 'number' && callback != null) { - var index = -1; - callback = lodash.createCallback(callback, thisArg, 3); - while (++index < length && callback(array[index], index, array)) { - n++; - } - } else { - n = callback; - if (n == null || thisArg) { - return array ? array[0] : undefined; - } + var index = -1, + props = keys(object), + length = props.length, + result = Array(length); + + while (++index < length) { + var key = props[index]; + result[index] = [key, object[key]]; } - return slice(array, 0, nativeMin(nativeMax(0, n), length)); + return result; } /** - * Flattens a nested array (the nesting can be to any depth). If `isShallow` - * is truey, the array will only be flattened a single level. If a callback - * is provided each element of the array is passed through the callback before - * flattening. The callback is bound to `thisArg` and invoked with three - * arguments; (value, index, array). - * - * If a property name is provided for `callback` the created "_.pluck" style - * callback will return the property value of the given element. - * - * If an object is provided for `callback` the created "_.where" style callback - * will return `true` for elements that have the properties of the given object, - * else `false`. + * Creates an object composed of the picked `object` properties. Property + * names may be specified as individual arguments or as arrays of property + * names. If `predicate` is provided it is invoked for each property of `object` + * picking the properties `predicate` returns truthy for. The predicate is + * bound to `thisArg` and invoked with three arguments: (value, key, object). * * @static * @memberOf _ - * @category Arrays - * @param {Array} array The array to flatten. - * @param {boolean} [isShallow=false] A flag to restrict flattening to a single level. - * @param {Function|Object|string} [callback=identity] The function called - * per iteration. If a property name or object is provided it will be used - * to create a "_.pluck" or "_.where" style callback, respectively. - * @param {*} [thisArg] The `this` binding of `callback`. - * @returns {Array} Returns a new flattened array. + * @category Object + * @param {Object} object The source object. + * @param {Function|...(string|string[])} [predicate] The function invoked per + * iteration or property names to pick, specified as individual property + * names or arrays of property names. + * @param {*} [thisArg] The `this` binding of `predicate`. + * @returns {Object} Returns the new object. * @example * - * _.flatten([1, [2], [3, [[4]]]]); - * // => [1, 2, 3, 4]; + * var object = { 'user': 'fred', 'age': 40 }; * - * _.flatten([1, [2], [3, [[4]]]], true); - * // => [1, 2, 3, [[4]]]; + * _.pick(object, 'user'); + * // => { 'user': 'fred' } * - * var characters = [ - * { 'name': 'barney', 'age': 30, 'pets': ['hoppy'] }, - * { 'name': 'fred', 'age': 40, 'pets': ['baby puss', 'dino'] } - * ]; - * - * // using "_.pluck" callback shorthand - * _.flatten(characters, 'pets'); - * // => ['hoppy', 'baby puss', 'dino'] + * _.pick(object, _.isString); + * // => { 'user': 'fred' } */ - function flatten(array, isShallow, callback, thisArg) { - // juggle arguments - if (typeof isShallow != 'boolean' && isShallow != null) { - thisArg = callback; - callback = (typeof isShallow != 'function' && thisArg && thisArg[isShallow] === array) ? null : isShallow; - isShallow = false; + var pick = restParam(function(object, props) { + if (object == null) { + return {}; } - if (callback != null) { - array = map(array, callback, thisArg); - } - return baseFlatten(array, isShallow); - } + return typeof props[0] == 'function' + ? pickByCallback(object, bindCallback(props[0], props[1], 3)) + : pickByArray(object, baseFlatten(props)); + }); /** - * Gets the index at which the first occurrence of `value` is found using - * strict equality for comparisons, i.e. `===`. If the array is already sorted - * providing `true` for `fromIndex` will run a faster binary search. + * This method is like `_.get` except that if the resolved value is a function + * it is invoked with the `this` binding of its parent object and its result + * is returned. * * @static * @memberOf _ - * @category Arrays - * @param {Array} array The array to search. - * @param {*} value The value to search for. - * @param {boolean|number} [fromIndex=0] The index to search from or `true` - * to perform a binary search on a sorted array. - * @returns {number} Returns the index of the matched value or `-1`. + * @category Object + * @param {Object} object The object to query. + * @param {Array|string} path The path of the property to resolve. + * @param {*} [defaultValue] The value returned if the resolved value is `undefined`. + * @returns {*} Returns the resolved value. * @example * - * _.indexOf([1, 2, 3, 1, 2, 3], 2); - * // => 1 + * var object = { 'a': [{ 'b': { 'c1': 3, 'c2': _.constant(4) } }] }; * - * _.indexOf([1, 2, 3, 1, 2, 3], 2, 3); + * _.result(object, 'a[0].b.c1'); + * // => 3 + * + * _.result(object, 'a[0].b.c2'); * // => 4 * - * _.indexOf([1, 1, 2, 2, 3, 3], 2, true); - * // => 2 + * _.result(object, 'a.b.c', 'default'); + * // => 'default' + * + * _.result(object, 'a.b.c', _.constant('default')); + * // => 'default' */ - function indexOf(array, value, fromIndex) { - if (typeof fromIndex == 'number') { - var length = array ? array.length : 0; - fromIndex = (fromIndex < 0 ? nativeMax(0, length + fromIndex) : fromIndex || 0); - } else if (fromIndex) { - var index = sortedIndex(array, value); - return array[index] === value ? index : -1; + function result(object, path, defaultValue) { + var result = object == null ? undefined : object[path]; + if (result === undefined) { + if (object != null && !isKey(path, object)) { + path = toPath(path); + object = path.length == 1 ? object : baseGet(object, baseSlice(path, 0, -1)); + result = object == null ? undefined : object[last(path)]; + } + result = result === undefined ? defaultValue : result; } - return baseIndexOf(array, value, fromIndex); + return isFunction(result) ? result.call(object) : result; } /** - * Gets all but the last element or last `n` elements of an array. If a - * callback is provided elements at the end of the array are excluded from - * the result as long as the callback returns truey. The callback is bound - * to `thisArg` and invoked with three arguments; (value, index, array). - * - * If a property name is provided for `callback` the created "_.pluck" style - * callback will return the property value of the given element. - * - * If an object is provided for `callback` the created "_.where" style callback - * will return `true` for elements that have the properties of the given object, - * else `false`. + * Sets the property value of `path` on `object`. If a portion of `path` + * does not exist it is created. * * @static * @memberOf _ - * @category Arrays - * @param {Array} array The array to query. - * @param {Function|Object|number|string} [callback=1] The function called - * per element or the number of elements to exclude. If a property name or - * object is provided it will be used to create a "_.pluck" or "_.where" - * style callback, respectively. - * @param {*} [thisArg] The `this` binding of `callback`. - * @returns {Array} Returns a slice of `array`. + * @category Object + * @param {Object} object The object to augment. + * @param {Array|string} path The path of the property to set. + * @param {*} value The value to set. + * @returns {Object} Returns `object`. * @example * - * _.initial([1, 2, 3]); - * // => [1, 2] - * - * _.initial([1, 2, 3], 2); - * // => [1] - * - * _.initial([1, 2, 3], function(num) { - * return num > 1; - * }); - * // => [1] - * - * var characters = [ - * { 'name': 'barney', 'blocked': false, 'employer': 'slate' }, - * { 'name': 'fred', 'blocked': true, 'employer': 'slate' }, - * { 'name': 'pebbles', 'blocked': true, 'employer': 'na' } - * ]; + * var object = { 'a': [{ 'b': { 'c': 3 } }] }; * - * // using "_.pluck" callback shorthand - * _.initial(characters, 'blocked'); - * // => [{ 'name': 'barney', 'blocked': false, 'employer': 'slate' }] + * _.set(object, 'a[0].b.c', 4); + * console.log(object.a[0].b.c); + * // => 4 * - * // using "_.where" callback shorthand - * _.pluck(_.initial(characters, { 'employer': 'na' }), 'name'); - * // => ['barney', 'fred'] + * _.set(object, 'x[0].y.z', 5); + * console.log(object.x[0].y.z); + * // => 5 */ - function initial(array, callback, thisArg) { - var n = 0, - length = array ? array.length : 0; + function set(object, path, value) { + if (object == null) { + return object; + } + var pathKey = (path + ''); + path = (object[pathKey] != null || isKey(path, object)) ? [pathKey] : toPath(path); - if (typeof callback != 'number' && callback != null) { - var index = length; - callback = lodash.createCallback(callback, thisArg, 3); - while (index-- && callback(array[index], index, array)) { - n++; + var index = -1, + length = path.length, + lastIndex = length - 1, + nested = object; + + while (nested != null && ++index < length) { + var key = path[index]; + if (isObject(nested)) { + if (index == lastIndex) { + nested[key] = value; + } else if (nested[key] == null) { + nested[key] = isIndex(path[index + 1]) ? [] : {}; + } } - } else { - n = (callback == null || thisArg) ? 1 : callback || n; + nested = nested[key]; } - return slice(array, 0, nativeMin(nativeMax(0, length - n), length)); + return object; } /** - * Creates an array of unique values present in all provided arrays using - * strict equality for comparisons, i.e. `===`. + * An alternative to `_.reduce`; this method transforms `object` to a new + * `accumulator` object which is the result of running each of its own enumerable + * properties through `iteratee`, with each invocation potentially mutating + * the `accumulator` object. The `iteratee` is bound to `thisArg` and invoked + * with four arguments: (accumulator, value, key, object). Iteratee functions + * may exit iteration early by explicitly returning `false`. * * @static * @memberOf _ - * @category Arrays - * @param {...Array} [array] The arrays to inspect. - * @returns {Array} Returns an array of shared values. + * @category Object + * @param {Array|Object} object The object to iterate over. + * @param {Function} [iteratee=_.identity] The function invoked per iteration. + * @param {*} [accumulator] The custom accumulator value. + * @param {*} [thisArg] The `this` binding of `iteratee`. + * @returns {*} Returns the accumulated value. * @example * - * _.intersection([1, 2, 3], [5, 2, 1, 4], [2, 1]); - * // => [1, 2] + * _.transform([2, 3, 4], function(result, n) { + * result.push(n *= n); + * return n % 2 == 0; + * }); + * // => [4, 9] + * + * _.transform({ 'a': 1, 'b': 2 }, function(result, n, key) { + * result[key] = n * 3; + * }); + * // => { 'a': 3, 'b': 6 } */ - function intersection() { - var args = [], - argsIndex = -1, - argsLength = arguments.length, - caches = getArray(), - indexOf = getIndexOf(), - trustIndexOf = indexOf === baseIndexOf, - seen = getArray(); - - while (++argsIndex < argsLength) { - var value = arguments[argsIndex]; - if (isArray(value) || isArguments(value)) { - args.push(value); - caches.push(trustIndexOf && value.length >= largeArraySize && - createCache(argsIndex ? args[argsIndex] : seen)); - } - } - var array = args[0], - index = -1, - length = array ? array.length : 0, - result = []; - - outer: - while (++index < length) { - var cache = caches[0]; - value = array[index]; + function transform(object, iteratee, accumulator, thisArg) { + var isArr = isArray(object) || isTypedArray(object); + iteratee = getCallback(iteratee, thisArg, 4); - if ((cache ? cacheIndexOf(cache, value) : indexOf(seen, value)) < 0) { - argsIndex = argsLength; - (cache || seen).push(value); - while (--argsIndex) { - cache = caches[argsIndex]; - if ((cache ? cacheIndexOf(cache, value) : indexOf(args[argsIndex], value)) < 0) { - continue outer; - } + if (accumulator == null) { + if (isArr || isObject(object)) { + var Ctor = object.constructor; + if (isArr) { + accumulator = isArray(object) ? new Ctor : []; + } else { + accumulator = baseCreate(isFunction(Ctor) ? Ctor.prototype : undefined); } - result.push(value); - } - } - while (argsLength--) { - cache = caches[argsLength]; - if (cache) { - releaseObject(cache); + } else { + accumulator = {}; } } - releaseArray(caches); - releaseArray(seen); - return result; + (isArr ? arrayEach : baseForOwn)(object, function(value, index, object) { + return iteratee(accumulator, value, index, object); + }); + return accumulator; } /** - * Gets the last element or last `n` elements of an array. If a callback is - * provided elements at the end of the array are returned as long as the - * callback returns truey. The callback is bound to `thisArg` and invoked - * with three arguments; (value, index, array). + * Creates an array of the own enumerable property values of `object`. * - * If a property name is provided for `callback` the created "_.pluck" style - * callback will return the property value of the given element. - * - * If an object is provided for `callback` the created "_.where" style callback - * will return `true` for elements that have the properties of the given object, - * else `false`. + * **Note:** Non-object values are coerced to objects. * * @static * @memberOf _ - * @category Arrays - * @param {Array} array The array to query. - * @param {Function|Object|number|string} [callback] The function called - * per element or the number of elements to return. If a property name or - * object is provided it will be used to create a "_.pluck" or "_.where" - * style callback, respectively. - * @param {*} [thisArg] The `this` binding of `callback`. - * @returns {*} Returns the last element(s) of `array`. + * @category Object + * @param {Object} object The object to query. + * @returns {Array} Returns the array of property values. * @example * - * _.last([1, 2, 3]); - * // => 3 - * - * _.last([1, 2, 3], 2); - * // => [2, 3] - * - * _.last([1, 2, 3], function(num) { - * return num > 1; - * }); - * // => [2, 3] + * function Foo() { + * this.a = 1; + * this.b = 2; + * } * - * var characters = [ - * { 'name': 'barney', 'blocked': false, 'employer': 'slate' }, - * { 'name': 'fred', 'blocked': true, 'employer': 'slate' }, - * { 'name': 'pebbles', 'blocked': true, 'employer': 'na' } - * ]; + * Foo.prototype.c = 3; * - * // using "_.pluck" callback shorthand - * _.pluck(_.last(characters, 'blocked'), 'name'); - * // => ['fred', 'pebbles'] + * _.values(new Foo); + * // => [1, 2] (iteration order is not guaranteed) * - * // using "_.where" callback shorthand - * _.last(characters, { 'employer': 'na' }); - * // => [{ 'name': 'pebbles', 'blocked': true, 'employer': 'na' }] + * _.values('hi'); + * // => ['h', 'i'] */ - function last(array, callback, thisArg) { - var n = 0, - length = array ? array.length : 0; - - if (typeof callback != 'number' && callback != null) { - var index = length; - callback = lodash.createCallback(callback, thisArg, 3); - while (index-- && callback(array[index], index, array)) { - n++; - } - } else { - n = callback; - if (n == null || thisArg) { - return array ? array[length - 1] : undefined; - } - } - return slice(array, nativeMax(0, length - n)); + function values(object) { + return baseValues(object, keys(object)); } /** - * Gets the index at which the last occurrence of `value` is found using strict - * equality for comparisons, i.e. `===`. If `fromIndex` is negative, it is used - * as the offset from the end of the collection. - * - * If a property name is provided for `callback` the created "_.pluck" style - * callback will return the property value of the given element. + * Creates an array of the own and inherited enumerable property values + * of `object`. * - * If an object is provided for `callback` the created "_.where" style callback - * will return `true` for elements that have the properties of the given object, - * else `false`. + * **Note:** Non-object values are coerced to objects. * * @static * @memberOf _ - * @category Arrays - * @param {Array} array The array to search. - * @param {*} value The value to search for. - * @param {number} [fromIndex=array.length-1] The index to search from. - * @returns {number} Returns the index of the matched value or `-1`. + * @category Object + * @param {Object} object The object to query. + * @returns {Array} Returns the array of property values. * @example * - * _.lastIndexOf([1, 2, 3, 1, 2, 3], 2); - * // => 4 - * - * _.lastIndexOf([1, 2, 3, 1, 2, 3], 2, 3); - * // => 1 - */ - function lastIndexOf(array, value, fromIndex) { - var index = array ? array.length : 0; - if (typeof fromIndex == 'number') { - index = (fromIndex < 0 ? nativeMax(0, index + fromIndex) : nativeMin(fromIndex, index - 1)) + 1; - } - while (index--) { - if (array[index] === value) { - return index; - } - } - return -1; - } - - /** - * Removes all provided values from the given array using strict equality for - * comparisons, i.e. `===`. + * function Foo() { + * this.a = 1; + * this.b = 2; + * } * - * @static - * @memberOf _ - * @category Arrays - * @param {Array} array The array to modify. - * @param {...*} [value] The values to remove. - * @returns {Array} Returns `array`. - * @example + * Foo.prototype.c = 3; * - * var array = [1, 2, 3, 1, 2, 3]; - * _.pull(array, 2, 3); - * console.log(array); - * // => [1, 1] + * _.valuesIn(new Foo); + * // => [1, 2, 3] (iteration order is not guaranteed) */ - function pull(array) { - var args = arguments, - argsIndex = 0, - argsLength = args.length, - length = array ? array.length : 0; - - while (++argsIndex < argsLength) { - var index = -1, - value = args[argsIndex]; - while (++index < length) { - if (array[index] === value) { - splice.call(array, index--, 1); - length--; - } - } - } - return array; + function valuesIn(object) { + return baseValues(object, keysIn(object)); } + /*------------------------------------------------------------------------*/ + /** - * Creates an array of numbers (positive and/or negative) progressing from - * `start` up to but not including `end`. If `start` is less than `stop` a - * zero-length range is created unless a negative `step` is specified. + * Checks if `n` is between `start` and up to but not including, `end`. If + * `end` is not specified it is set to `start` with `start` then set to `0`. * * @static * @memberOf _ - * @category Arrays + * @category Number + * @param {number} n The number to check. * @param {number} [start=0] The start of the range. * @param {number} end The end of the range. - * @param {number} [step=1] The value to increment or decrement by. - * @returns {Array} Returns a new range array. + * @returns {boolean} Returns `true` if `n` is in the range, else `false`. * @example * - * _.range(4); - * // => [0, 1, 2, 3] + * _.inRange(3, 2, 4); + * // => true * - * _.range(1, 5); - * // => [1, 2, 3, 4] + * _.inRange(4, 8); + * // => true * - * _.range(0, 20, 5); - * // => [0, 5, 10, 15] + * _.inRange(4, 2); + * // => false * - * _.range(0, -4, -1); - * // => [0, -1, -2, -3] + * _.inRange(2, 2); + * // => false * - * _.range(1, 4, 0); - * // => [1, 1, 1] + * _.inRange(1.2, 2); + * // => true * - * _.range(0); - * // => [] + * _.inRange(5.2, 4); + * // => false */ - function range(start, end, step) { + function inRange(value, start, end) { start = +start || 0; - step = typeof step == 'number' ? step : (+step || 1); - - if (end == null) { + if (end === undefined) { end = start; start = 0; + } else { + end = +end || 0; } - // use `Array(length)` so engines like Chakra and V8 avoid slower modes - // http://youtu.be/XAqIpGU8ZZk#t=17m25s - var index = -1, - length = nativeMax(0, ceil((end - start) / (step || 1))), - result = Array(length); - - while (++index < length) { - result[index] = start; - start += step; - } - return result; + return value >= nativeMin(start, end) && value < nativeMax(start, end); } /** - * Removes all elements from an array that the callback returns truey for - * and returns an array of removed elements. The callback is bound to `thisArg` - * and invoked with three arguments; (value, index, array). - * - * If a property name is provided for `callback` the created "_.pluck" style - * callback will return the property value of the given element. - * - * If an object is provided for `callback` the created "_.where" style callback - * will return `true` for elements that have the properties of the given object, - * else `false`. + * Produces a random number between `min` and `max` (inclusive). If only one + * argument is provided a number between `0` and the given number is returned. + * If `floating` is `true`, or either `min` or `max` are floats, a floating-point + * number is returned instead of an integer. * * @static * @memberOf _ - * @category Arrays - * @param {Array} array The array to modify. - * @param {Function|Object|string} [callback=identity] The function called - * per iteration. If a property name or object is provided it will be used - * to create a "_.pluck" or "_.where" style callback, respectively. - * @param {*} [thisArg] The `this` binding of `callback`. - * @returns {Array} Returns a new array of removed elements. + * @category Number + * @param {number} [min=0] The minimum possible value. + * @param {number} [max=1] The maximum possible value. + * @param {boolean} [floating] Specify returning a floating-point number. + * @returns {number} Returns the random number. * @example * - * var array = [1, 2, 3, 4, 5, 6]; - * var evens = _.remove(array, function(num) { return num % 2 == 0; }); + * _.random(0, 5); + * // => an integer between 0 and 5 + * + * _.random(5); + * // => also an integer between 0 and 5 * - * console.log(array); - * // => [1, 3, 5] + * _.random(5, true); + * // => a floating-point number between 0 and 5 * - * console.log(evens); - * // => [2, 4, 6] + * _.random(1.2, 5.2); + * // => a floating-point number between 1.2 and 5.2 */ - function remove(array, callback, thisArg) { - var index = -1, - length = array ? array.length : 0, - result = []; + function random(min, max, floating) { + if (floating && isIterateeCall(min, max, floating)) { + max = floating = undefined; + } + var noMin = min == null, + noMax = max == null; - callback = lodash.createCallback(callback, thisArg, 3); - while (++index < length) { - var value = array[index]; - if (callback(value, index, array)) { - result.push(value); - splice.call(array, index--, 1); - length--; + if (floating == null) { + if (noMax && typeof min == 'boolean') { + floating = min; + min = 1; + } + else if (typeof max == 'boolean') { + floating = max; + noMax = true; } } - return result; + if (noMin && noMax) { + max = 1; + noMax = false; + } + min = +min || 0; + if (noMax) { + max = min; + min = 0; + } else { + max = +max || 0; + } + if (floating || min % 1 || max % 1) { + var rand = nativeRandom(); + return nativeMin(min + (rand * (max - min + parseFloat('1e-' + ((rand + '').length - 1)))), max); + } + return baseRandom(min, max); } + /*------------------------------------------------------------------------*/ + /** - * The opposite of `_.initial` this method gets all but the first element or - * first `n` elements of an array. If a callback function is provided elements - * at the beginning of the array are excluded from the result as long as the - * callback returns truey. The callback is bound to `thisArg` and invoked - * with three arguments; (value, index, array). - * - * If a property name is provided for `callback` the created "_.pluck" style - * callback will return the property value of the given element. - * - * If an object is provided for `callback` the created "_.where" style callback - * will return `true` for elements that have the properties of the given object, - * else `false`. + * Converts `string` to [camel case](https://en.wikipedia.org/wiki/CamelCase). * * @static * @memberOf _ - * @alias drop, tail - * @category Arrays - * @param {Array} array The array to query. - * @param {Function|Object|number|string} [callback=1] The function called - * per element or the number of elements to exclude. If a property name or - * object is provided it will be used to create a "_.pluck" or "_.where" - * style callback, respectively. - * @param {*} [thisArg] The `this` binding of `callback`. - * @returns {Array} Returns a slice of `array`. + * @category String + * @param {string} [string=''] The string to convert. + * @returns {string} Returns the camel cased string. * @example * - * _.rest([1, 2, 3]); - * // => [2, 3] - * - * _.rest([1, 2, 3], 2); - * // => [3] + * _.camelCase('Foo Bar'); + * // => 'fooBar' * - * _.rest([1, 2, 3], function(num) { - * return num < 3; - * }); - * // => [3] + * _.camelCase('--foo-bar'); + * // => 'fooBar' * - * var characters = [ - * { 'name': 'barney', 'blocked': true, 'employer': 'slate' }, - * { 'name': 'fred', 'blocked': false, 'employer': 'slate' }, - * { 'name': 'pebbles', 'blocked': true, 'employer': 'na' } - * ]; + * _.camelCase('__foo_bar__'); + * // => 'fooBar' + */ + var camelCase = createCompounder(function(result, word, index) { + word = word.toLowerCase(); + return result + (index ? (word.charAt(0).toUpperCase() + word.slice(1)) : word); + }); + + /** + * Capitalizes the first character of `string`. * - * // using "_.pluck" callback shorthand - * _.pluck(_.rest(characters, 'blocked'), 'name'); - * // => ['fred', 'pebbles'] + * @static + * @memberOf _ + * @category String + * @param {string} [string=''] The string to capitalize. + * @returns {string} Returns the capitalized string. + * @example * - * // using "_.where" callback shorthand - * _.rest(characters, { 'employer': 'slate' }); - * // => [{ 'name': 'pebbles', 'blocked': true, 'employer': 'na' }] + * _.capitalize('fred'); + * // => 'Fred' */ - function rest(array, callback, thisArg) { - if (typeof callback != 'number' && callback != null) { - var n = 0, - index = -1, - length = array ? array.length : 0; - - callback = lodash.createCallback(callback, thisArg, 3); - while (++index < length && callback(array[index], index, array)) { - n++; - } - } else { - n = (callback == null || thisArg) ? 1 : nativeMax(0, callback); - } - return slice(array, n); + function capitalize(string) { + string = baseToString(string); + return string && (string.charAt(0).toUpperCase() + string.slice(1)); } /** - * Uses a binary search to determine the smallest index at which a value - * should be inserted into a given sorted array in order to maintain the sort - * order of the array. If a callback is provided it will be executed for - * `value` and each element of `array` to compute their sort ranking. The - * callback is bound to `thisArg` and invoked with one argument; (value). - * - * If a property name is provided for `callback` the created "_.pluck" style - * callback will return the property value of the given element. - * - * If an object is provided for `callback` the created "_.where" style callback - * will return `true` for elements that have the properties of the given object, - * else `false`. + * Deburrs `string` by converting [latin-1 supplementary letters](https://en.wikipedia.org/wiki/Latin-1_Supplement_(Unicode_block)#Character_table) + * to basic latin letters and removing [combining diacritical marks](https://en.wikipedia.org/wiki/Combining_Diacritical_Marks). * * @static * @memberOf _ - * @category Arrays - * @param {Array} array The array to inspect. - * @param {*} value The value to evaluate. - * @param {Function|Object|string} [callback=identity] The function called - * per iteration. If a property name or object is provided it will be used - * to create a "_.pluck" or "_.where" style callback, respectively. - * @param {*} [thisArg] The `this` binding of `callback`. - * @returns {number} Returns the index at which `value` should be inserted - * into `array`. + * @category String + * @param {string} [string=''] The string to deburr. + * @returns {string} Returns the deburred string. * @example * - * _.sortedIndex([20, 30, 50], 40); - * // => 2 - * - * // using "_.pluck" callback shorthand - * _.sortedIndex([{ 'x': 20 }, { 'x': 30 }, { 'x': 50 }], { 'x': 40 }, 'x'); - * // => 2 - * - * var dict = { - * 'wordToNumber': { 'twenty': 20, 'thirty': 30, 'fourty': 40, 'fifty': 50 } - * }; - * - * _.sortedIndex(['twenty', 'thirty', 'fifty'], 'fourty', function(word) { - * return dict.wordToNumber[word]; - * }); - * // => 2 - * - * _.sortedIndex(['twenty', 'thirty', 'fifty'], 'fourty', function(word) { - * return this.wordToNumber[word]; - * }, dict); - * // => 2 + * _.deburr('déjà vu'); + * // => 'deja vu' */ - function sortedIndex(array, value, callback, thisArg) { - var low = 0, - high = array ? array.length : low; - - // explicitly reference `identity` for better inlining in Firefox - callback = callback ? lodash.createCallback(callback, thisArg, 1) : identity; - value = callback(value); - - while (low < high) { - var mid = (low + high) >>> 1; - (callback(array[mid]) < value) - ? low = mid + 1 - : high = mid; - } - return low; + function deburr(string) { + string = baseToString(string); + return string && string.replace(reLatin1, deburrLetter).replace(reComboMark, ''); } /** - * Creates an array of unique values, in order, of the provided arrays using - * strict equality for comparisons, i.e. `===`. + * Checks if `string` ends with the given target string. * * @static * @memberOf _ - * @category Arrays - * @param {...Array} [array] The arrays to inspect. - * @returns {Array} Returns an array of combined values. + * @category String + * @param {string} [string=''] The string to search. + * @param {string} [target] The string to search for. + * @param {number} [position=string.length] The position to search from. + * @returns {boolean} Returns `true` if `string` ends with `target`, else `false`. * @example * - * _.union([1, 2, 3], [5, 2, 1, 4], [2, 1]); - * // => [1, 2, 3, 5, 4] + * _.endsWith('abc', 'c'); + * // => true + * + * _.endsWith('abc', 'b'); + * // => false + * + * _.endsWith('abc', 'b', 2); + * // => true */ - function union() { - return baseUniq(baseFlatten(arguments, true, true)); + function endsWith(string, target, position) { + string = baseToString(string); + target = (target + ''); + + var length = string.length; + position = position === undefined + ? length + : nativeMin(position < 0 ? 0 : (+position || 0), length); + + position -= target.length; + return position >= 0 && string.indexOf(target, position) == position; } /** - * Creates a duplicate-value-free version of an array using strict equality - * for comparisons, i.e. `===`. If the array is sorted, providing - * `true` for `isSorted` will use a faster algorithm. If a callback is provided - * each element of `array` is passed through the callback before uniqueness - * is computed. The callback is bound to `thisArg` and invoked with three - * arguments; (value, index, array). + * Converts the characters "&", "<", ">", '"', "'", and "\`", in `string` to + * their corresponding HTML entities. + * + * **Note:** No other characters are escaped. To escape additional characters + * use a third-party library like [_he_](https://mths.be/he). * - * If a property name is provided for `callback` the created "_.pluck" style - * callback will return the property value of the given element. + * Though the ">" character is escaped for symmetry, characters like + * ">" and "/" don't need escaping in HTML and have no special meaning + * unless they're part of a tag or unquoted attribute value. + * See [Mathias Bynens's article](https://mathiasbynens.be/notes/ambiguous-ampersands) + * (under "semi-related fun fact") for more details. * - * If an object is provided for `callback` the created "_.where" style callback - * will return `true` for elements that have the properties of the given object, - * else `false`. + * Backticks are escaped because in Internet Explorer < 9, they can break out + * of attribute values or HTML comments. See [#59](https://html5sec.org/#59), + * [#102](https://html5sec.org/#102), [#108](https://html5sec.org/#108), and + * [#133](https://html5sec.org/#133) of the [HTML5 Security Cheatsheet](https://html5sec.org/) + * for more details. + * + * When working with HTML you should always [quote attribute values](http://wonko.com/post/html-escaping) + * to reduce XSS vectors. * * @static * @memberOf _ - * @alias unique - * @category Arrays - * @param {Array} array The array to process. - * @param {boolean} [isSorted=false] A flag to indicate that `array` is sorted. - * @param {Function|Object|string} [callback=identity] The function called - * per iteration. If a property name or object is provided it will be used - * to create a "_.pluck" or "_.where" style callback, respectively. - * @param {*} [thisArg] The `this` binding of `callback`. - * @returns {Array} Returns a duplicate-value-free array. + * @category String + * @param {string} [string=''] The string to escape. + * @returns {string} Returns the escaped string. * @example * - * _.uniq([1, 2, 1, 3, 1]); - * // => [1, 2, 3] - * - * _.uniq([1, 1, 2, 2, 3], true); - * // => [1, 2, 3] - * - * _.uniq(['A', 'b', 'C', 'a', 'B', 'c'], function(letter) { return letter.toLowerCase(); }); - * // => ['A', 'b', 'C'] - * - * _.uniq([1, 2.5, 3, 1.5, 2, 3.5], function(num) { return this.floor(num); }, Math); - * // => [1, 2.5, 3] - * - * // using "_.pluck" callback shorthand - * _.uniq([{ 'x': 1 }, { 'x': 2 }, { 'x': 1 }], 'x'); - * // => [{ 'x': 1 }, { 'x': 2 }] + * _.escape('fred, barney, & pebbles'); + * // => 'fred, barney, & pebbles' */ - function uniq(array, isSorted, callback, thisArg) { - // juggle arguments - if (typeof isSorted != 'boolean' && isSorted != null) { - thisArg = callback; - callback = (typeof isSorted != 'function' && thisArg && thisArg[isSorted] === array) ? null : isSorted; - isSorted = false; - } - if (callback != null) { - callback = lodash.createCallback(callback, thisArg, 3); - } - return baseUniq(array, isSorted, callback); + function escape(string) { + // Reset `lastIndex` because in IE < 9 `String#replace` does not. + string = baseToString(string); + return (string && reHasUnescapedHtml.test(string)) + ? string.replace(reUnescapedHtml, escapeHtmlChar) + : string; } /** - * Creates an array excluding all provided values using strict equality for - * comparisons, i.e. `===`. + * Escapes the `RegExp` special characters "\", "/", "^", "$", ".", "|", "?", + * "*", "+", "(", ")", "[", "]", "{" and "}" in `string`. * * @static * @memberOf _ - * @category Arrays - * @param {Array} array The array to filter. - * @param {...*} [value] The values to exclude. - * @returns {Array} Returns a new array of filtered values. + * @category String + * @param {string} [string=''] The string to escape. + * @returns {string} Returns the escaped string. * @example * - * _.without([1, 2, 1, 0, 3, 1, 4], 0, 1); - * // => [2, 3, 4] + * _.escapeRegExp('[lodash](https://lodash.com/)'); + * // => '\[lodash\]\(https:\/\/lodash\.com\/\)' */ - function without(array) { - return baseDifference(array, slice(arguments, 1)); + function escapeRegExp(string) { + string = baseToString(string); + return (string && reHasRegExpChars.test(string)) + ? string.replace(reRegExpChars, escapeRegExpChar) + : (string || '(?:)'); } /** - * Creates an array that is the symmetric difference of the provided arrays. - * See http://en.wikipedia.org/wiki/Symmetric_difference. + * Converts `string` to [kebab case](https://en.wikipedia.org/wiki/Letter_case#Special_case_styles). * * @static * @memberOf _ - * @category Arrays - * @param {...Array} [array] The arrays to inspect. - * @returns {Array} Returns an array of values. + * @category String + * @param {string} [string=''] The string to convert. + * @returns {string} Returns the kebab cased string. * @example * - * _.xor([1, 2, 3], [5, 2, 1, 4]); - * // => [3, 5, 4] + * _.kebabCase('Foo Bar'); + * // => 'foo-bar' * - * _.xor([1, 2, 5], [2, 3, 5], [3, 4, 5]); - * // => [1, 4, 5] + * _.kebabCase('fooBar'); + * // => 'foo-bar' + * + * _.kebabCase('__foo_bar__'); + * // => 'foo-bar' */ - function xor() { - var index = -1, - length = arguments.length; - - while (++index < length) { - var array = arguments[index]; - if (isArray(array) || isArguments(array)) { - var result = result - ? baseUniq(baseDifference(result, array).concat(baseDifference(array, result))) - : array; - } - } - return result || []; - } + var kebabCase = createCompounder(function(result, word, index) { + return result + (index ? '-' : '') + word.toLowerCase(); + }); /** - * Creates an array of grouped elements, the first of which contains the first - * elements of the given arrays, the second of which contains the second - * elements of the given arrays, and so on. + * Pads `string` on the left and right sides if it's shorter than `length`. + * Padding characters are truncated if they can't be evenly divided by `length`. * * @static * @memberOf _ - * @alias unzip - * @category Arrays - * @param {...Array} [array] Arrays to process. - * @returns {Array} Returns a new array of grouped elements. + * @category String + * @param {string} [string=''] The string to pad. + * @param {number} [length=0] The padding length. + * @param {string} [chars=' '] The string used as padding. + * @returns {string} Returns the padded string. * @example * - * _.zip(['fred', 'barney'], [30, 40], [true, false]); - * // => [['fred', 30, true], ['barney', 40, false]] + * _.pad('abc', 8); + * // => ' abc ' + * + * _.pad('abc', 8, '_-'); + * // => '_-abc_-_' + * + * _.pad('abc', 3); + * // => 'abc' */ - function zip() { - var array = arguments.length > 1 ? arguments : arguments[0], - index = -1, - length = array ? max(pluck(array, 'length')) : 0, - result = Array(length < 0 ? 0 : length); + function pad(string, length, chars) { + string = baseToString(string); + length = +length; - while (++index < length) { - result[index] = pluck(array, index); + var strLength = string.length; + if (strLength >= length || !nativeIsFinite(length)) { + return string; } - return result; + var mid = (length - strLength) / 2, + leftLength = nativeFloor(mid), + rightLength = nativeCeil(mid); + + chars = createPadding('', rightLength, chars); + return chars.slice(0, leftLength) + string + chars; } /** - * Creates an object composed from arrays of `keys` and `values`. Provide - * either a single two dimensional array, i.e. `[[key1, value1], [key2, value2]]` - * or two arrays, one of `keys` and one of corresponding `values`. + * Pads `string` on the left side if it's shorter than `length`. Padding + * characters are truncated if they exceed `length`. * * @static * @memberOf _ - * @alias object - * @category Arrays - * @param {Array} keys The array of keys. - * @param {Array} [values=[]] The array of values. - * @returns {Object} Returns an object composed of the given keys and - * corresponding values. + * @category String + * @param {string} [string=''] The string to pad. + * @param {number} [length=0] The padding length. + * @param {string} [chars=' '] The string used as padding. + * @returns {string} Returns the padded string. * @example * - * _.zipObject(['fred', 'barney'], [30, 40]); - * // => { 'fred': 30, 'barney': 40 } + * _.padLeft('abc', 6); + * // => ' abc' + * + * _.padLeft('abc', 6, '_-'); + * // => '_-_abc' + * + * _.padLeft('abc', 3); + * // => 'abc' */ - function zipObject(keys, values) { - var index = -1, - length = keys ? keys.length : 0, - result = {}; - - if (!values && length && !isArray(keys[0])) { - values = []; - } - while (++index < length) { - var key = keys[index]; - if (values) { - result[key] = values[index]; - } else if (key) { - result[key[0]] = key[1]; - } - } - return result; - } - - /*--------------------------------------------------------------------------*/ + var padLeft = createPadDir(); /** - * Creates a function that executes `func`, with the `this` binding and - * arguments of the created function, only after being called `n` times. + * Pads `string` on the right side if it's shorter than `length`. Padding + * characters are truncated if they exceed `length`. * * @static * @memberOf _ - * @category Functions - * @param {number} n The number of times the function must be called before - * `func` is executed. - * @param {Function} func The function to restrict. - * @returns {Function} Returns the new restricted function. + * @category String + * @param {string} [string=''] The string to pad. + * @param {number} [length=0] The padding length. + * @param {string} [chars=' '] The string used as padding. + * @returns {string} Returns the padded string. * @example * - * var saves = ['profile', 'settings']; + * _.padRight('abc', 6); + * // => 'abc ' * - * var done = _.after(saves.length, function() { - * console.log('Done saving!'); - * }); + * _.padRight('abc', 6, '_-'); + * // => 'abc_-_' * - * _.forEach(saves, function(type) { - * asyncSave({ 'type': type, 'complete': done }); - * }); - * // => logs 'Done saving!', after all saves have completed + * _.padRight('abc', 3); + * // => 'abc' */ - function after(n, func) { - if (!isFunction(func)) { - throw new TypeError; - } - return function() { - if (--n < 1) { - return func.apply(this, arguments); - } - }; - } + var padRight = createPadDir(true); /** - * Creates a function that, when called, invokes `func` with the `this` - * binding of `thisArg` and prepends any additional `bind` arguments to those - * provided to the bound function. + * Converts `string` to an integer of the specified radix. If `radix` is + * `undefined` or `0`, a `radix` of `10` is used unless `value` is a hexadecimal, + * in which case a `radix` of `16` is used. + * + * **Note:** This method aligns with the [ES5 implementation](https://es5.github.io/#E) + * of `parseInt`. * * @static * @memberOf _ - * @category Functions - * @param {Function} func The function to bind. - * @param {*} [thisArg] The `this` binding of `func`. - * @param {...*} [arg] Arguments to be partially applied. - * @returns {Function} Returns the new bound function. + * @category String + * @param {string} string The string to convert. + * @param {number} [radix] The radix to interpret `value` by. + * @param- {Object} [guard] Enables use as a callback for functions like `_.map`. + * @returns {number} Returns the converted integer. * @example * - * var func = function(greeting) { - * return greeting + ' ' + this.name; - * }; + * _.parseInt('08'); + * // => 8 * - * func = _.bind(func, { 'name': 'fred' }, 'hi'); - * func(); - * // => 'hi fred' + * _.map(['6', '08', '10'], _.parseInt); + * // => [6, 8, 10] */ - function bind(func, thisArg) { - return arguments.length > 2 - ? createWrapper(func, 17, slice(arguments, 2), null, thisArg) - : createWrapper(func, 1, null, null, thisArg); + function parseInt(string, radix, guard) { + // Firefox < 21 and Opera < 15 follow ES3 for `parseInt`. + // Chrome fails to trim leading whitespace characters. + // See https://code.google.com/p/v8/issues/detail?id=3109 for more details. + if (guard ? isIterateeCall(string, radix, guard) : radix == null) { + radix = 0; + } else if (radix) { + radix = +radix; + } + string = trim(string); + return nativeParseInt(string, radix || (reHasHexPrefix.test(string) ? 16 : 10)); } /** - * Binds methods of an object to the object itself, overwriting the existing - * method. Method names may be specified as individual arguments or as arrays - * of method names. If no method names are provided all the function properties - * of `object` will be bound. + * Repeats the given string `n` times. * * @static * @memberOf _ - * @category Functions - * @param {Object} object The object to bind and assign the bound methods to. - * @param {...string} [methodName] The object method names to - * bind, specified as individual method names or arrays of method names. - * @returns {Object} Returns `object`. + * @category String + * @param {string} [string=''] The string to repeat. + * @param {number} [n=0] The number of times to repeat the string. + * @returns {string} Returns the repeated string. * @example * - * var view = { - * 'label': 'docs', - * 'onClick': function() { console.log('clicked ' + this.label); } - * }; + * _.repeat('*', 3); + * // => '***' * - * _.bindAll(view); - * jQuery('#docs').on('click', view.onClick); - * // => logs 'clicked docs', when the button is clicked + * _.repeat('abc', 2); + * // => 'abcabc' + * + * _.repeat('abc', 0); + * // => '' */ - function bindAll(object) { - var funcs = arguments.length > 1 ? baseFlatten(arguments, true, false, 1) : functions(object), - index = -1, - length = funcs.length; - - while (++index < length) { - var key = funcs[index]; - object[key] = createWrapper(object[key], 1, null, null, object); + function repeat(string, n) { + var result = ''; + string = baseToString(string); + n = +n; + if (n < 1 || !string || !nativeIsFinite(n)) { + return result; } - return object; + // Leverage the exponentiation by squaring algorithm for a faster repeat. + // See https://en.wikipedia.org/wiki/Exponentiation_by_squaring for more details. + do { + if (n % 2) { + result += string; + } + n = nativeFloor(n / 2); + string += string; + } while (n); + + return result; } /** - * Creates a function that, when called, invokes the method at `object[key]` - * and prepends any additional `bindKey` arguments to those provided to the bound - * function. This method differs from `_.bind` by allowing bound functions to - * reference methods that will be redefined or don't yet exist. - * See http://michaux.ca/articles/lazy-function-definition-pattern. + * Converts `string` to [snake case](https://en.wikipedia.org/wiki/Snake_case). * * @static * @memberOf _ - * @category Functions - * @param {Object} object The object the method belongs to. - * @param {string} key The key of the method. - * @param {...*} [arg] Arguments to be partially applied. - * @returns {Function} Returns the new bound function. + * @category String + * @param {string} [string=''] The string to convert. + * @returns {string} Returns the snake cased string. * @example * - * var object = { - * 'name': 'fred', - * 'greet': function(greeting) { - * return greeting + ' ' + this.name; - * } - * }; - * - * var func = _.bindKey(object, 'greet', 'hi'); - * func(); - * // => 'hi fred' + * _.snakeCase('Foo Bar'); + * // => 'foo_bar' * - * object.greet = function(greeting) { - * return greeting + 'ya ' + this.name + '!'; - * }; + * _.snakeCase('fooBar'); + * // => 'foo_bar' * - * func(); - * // => 'hiya fred!' + * _.snakeCase('--foo-bar'); + * // => 'foo_bar' */ - function bindKey(object, key) { - return arguments.length > 2 - ? createWrapper(key, 19, slice(arguments, 2), null, object) - : createWrapper(key, 3, null, null, object); - } + var snakeCase = createCompounder(function(result, word, index) { + return result + (index ? '_' : '') + word.toLowerCase(); + }); /** - * Creates a function that is the composition of the provided functions, - * where each function consumes the return value of the function that follows. - * For example, composing the functions `f()`, `g()`, and `h()` produces `f(g(h()))`. - * Each function is executed with the `this` binding of the composed function. + * Converts `string` to [start case](https://en.wikipedia.org/wiki/Letter_case#Stylistic_or_specialised_usage). * * @static * @memberOf _ - * @category Functions - * @param {...Function} [func] Functions to compose. - * @returns {Function} Returns the new composed function. + * @category String + * @param {string} [string=''] The string to convert. + * @returns {string} Returns the start cased string. * @example * - * var realNameMap = { - * 'pebbles': 'penelope' - * }; - * - * var format = function(name) { - * name = realNameMap[name.toLowerCase()] || name; - * return name.charAt(0).toUpperCase() + name.slice(1).toLowerCase(); - * }; + * _.startCase('--foo-bar'); + * // => 'Foo Bar' * - * var greet = function(formatted) { - * return 'Hiya ' + formatted + '!'; - * }; + * _.startCase('fooBar'); + * // => 'Foo Bar' * - * var welcome = _.compose(greet, format); - * welcome('pebbles'); - * // => 'Hiya Penelope!' + * _.startCase('__foo_bar__'); + * // => 'Foo Bar' */ - function compose() { - var funcs = arguments, - length = funcs.length; - - while (length--) { - if (!isFunction(funcs[length])) { - throw new TypeError; - } - } - return function() { - var args = arguments, - length = funcs.length; - - while (length--) { - args = [funcs[length].apply(this, args)]; - } - return args[0]; - }; - } + var startCase = createCompounder(function(result, word, index) { + return result + (index ? ' ' : '') + (word.charAt(0).toUpperCase() + word.slice(1)); + }); /** - * Creates a function which accepts one or more arguments of `func` that when - * invoked either executes `func` returning its result, if all `func` arguments - * have been provided, or returns a function that accepts one or more of the - * remaining `func` arguments, and so on. The arity of `func` can be specified - * if `func.length` is not sufficient. + * Checks if `string` starts with the given target string. * * @static * @memberOf _ - * @category Functions - * @param {Function} func The function to curry. - * @param {number} [arity=func.length] The arity of `func`. - * @returns {Function} Returns the new curried function. + * @category String + * @param {string} [string=''] The string to search. + * @param {string} [target] The string to search for. + * @param {number} [position=0] The position to search from. + * @returns {boolean} Returns `true` if `string` starts with `target`, else `false`. * @example * - * var curried = _.curry(function(a, b, c) { - * console.log(a + b + c); - * }); - * - * curried(1)(2)(3); - * // => 6 + * _.startsWith('abc', 'a'); + * // => true * - * curried(1, 2)(3); - * // => 6 + * _.startsWith('abc', 'b'); + * // => false * - * curried(1, 2, 3); - * // => 6 + * _.startsWith('abc', 'b', 1); + * // => true */ - function curry(func, arity) { - arity = typeof arity == 'number' ? arity : (+arity || func.length); - return createWrapper(func, 4, null, null, null, arity); + function startsWith(string, target, position) { + string = baseToString(string); + position = position == null + ? 0 + : nativeMin(position < 0 ? 0 : (+position || 0), string.length); + + return string.lastIndexOf(target, position) == position; } /** - * Creates a function that will delay the execution of `func` until after - * `wait` milliseconds have elapsed since the last time it was invoked. - * Provide an options object to indicate that `func` should be invoked on - * the leading and/or trailing edge of the `wait` timeout. Subsequent calls - * to the debounced function will return the result of the last `func` call. + * Creates a compiled template function that can interpolate data properties + * in "interpolate" delimiters, HTML-escape interpolated data properties in + * "escape" delimiters, and execute JavaScript in "evaluate" delimiters. Data + * properties may be accessed as free variables in the template. If a setting + * object is provided it takes precedence over `_.templateSettings` values. * - * Note: If `leading` and `trailing` options are `true` `func` will be called - * on the trailing edge of the timeout only if the the debounced function is - * invoked more than once during the `wait` timeout. + * **Note:** In the development build `_.template` utilizes + * [sourceURLs](http://www.html5rocks.com/en/tutorials/developertools/sourcemaps/#toc-sourceurl) + * for easier debugging. + * + * For more information on precompiling templates see + * [lodash's custom builds documentation](https://lodash.com/custom-builds). + * + * For more information on Chrome extension sandboxes see + * [Chrome's extensions documentation](https://developer.chrome.com/extensions/sandboxingEval). * * @static * @memberOf _ - * @category Functions - * @param {Function} func The function to debounce. - * @param {number} wait The number of milliseconds to delay. + * @category String + * @param {string} [string=''] The template string. * @param {Object} [options] The options object. - * @param {boolean} [options.leading=false] Specify execution on the leading edge of the timeout. - * @param {number} [options.maxWait] The maximum time `func` is allowed to be delayed before it's called. - * @param {boolean} [options.trailing=true] Specify execution on the trailing edge of the timeout. - * @returns {Function} Returns the new debounced function. + * @param {RegExp} [options.escape] The HTML "escape" delimiter. + * @param {RegExp} [options.evaluate] The "evaluate" delimiter. + * @param {Object} [options.imports] An object to import into the template as free variables. + * @param {RegExp} [options.interpolate] The "interpolate" delimiter. + * @param {string} [options.sourceURL] The sourceURL of the template's compiled source. + * @param {string} [options.variable] The data object variable name. + * @param- {Object} [otherOptions] Enables the legacy `options` param signature. + * @returns {Function} Returns the compiled template function. * @example * - * // avoid costly calculations while the window size is in flux - * var lazyLayout = _.debounce(calculateLayout, 150); - * jQuery(window).on('resize', lazyLayout); + * // using the "interpolate" delimiter to create a compiled template + * var compiled = _.template('hello <%= user %>!'); + * compiled({ 'user': 'fred' }); + * // => 'hello fred!' * - * // execute `sendMail` when the click event is fired, debouncing subsequent calls - * jQuery('#postbox').on('click', _.debounce(sendMail, 300, { - * 'leading': true, - * 'trailing': false - * }); + * // using the HTML "escape" delimiter to escape data property values + * var compiled = _.template('<%- value %>'); + * compiled({ 'value': '