| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309 | /*CryptoJS v3.1.2code.google.com/p/crypto-js(c) 2009-2013 by Jeff Mott. All rights reserved.code.google.com/p/crypto-js/wiki/License*/(function (Math) {    // Shortcuts    var C = CryptoJS;    var C_lib = C.lib;    var WordArray = C_lib.WordArray;    var Hasher = C_lib.Hasher;    var C_x64 = C.x64;    var X64Word = C_x64.Word;    var C_algo = C.algo;    // Constants tables    var RHO_OFFSETS = [];    var PI_INDEXES  = [];    var ROUND_CONSTANTS = [];    // Compute Constants    (function () {        // Compute rho offset constants        var x = 1, y = 0;        for (var t = 0; t < 24; t++) {            RHO_OFFSETS[x + 5 * y] = ((t + 1) * (t + 2) / 2) % 64;            var newX = y % 5;            var newY = (2 * x + 3 * y) % 5;            x = newX;            y = newY;        }        // Compute pi index constants        for (var x = 0; x < 5; x++) {            for (var y = 0; y < 5; y++) {                PI_INDEXES[x + 5 * y] = y + ((2 * x + 3 * y) % 5) * 5;            }        }        // Compute round constants        var LFSR = 0x01;        for (var i = 0; i < 24; i++) {            var roundConstantMsw = 0;            var roundConstantLsw = 0;            for (var j = 0; j < 7; j++) {                if (LFSR & 0x01) {                    var bitPosition = (1 << j) - 1;                    if (bitPosition < 32) {                        roundConstantLsw ^= 1 << bitPosition;                    } else /* if (bitPosition >= 32) */ {                        roundConstantMsw ^= 1 << (bitPosition - 32);                    }                }                // Compute next LFSR                if (LFSR & 0x80) {                    // Primitive polynomial over GF(2): x^8 + x^6 + x^5 + x^4 + 1                    LFSR = (LFSR << 1) ^ 0x71;                } else {                    LFSR <<= 1;                }            }            ROUND_CONSTANTS[i] = X64Word.create(roundConstantMsw, roundConstantLsw);        }    }());    // Reusable objects for temporary values    var T = [];    (function () {        for (var i = 0; i < 25; i++) {            T[i] = X64Word.create();        }    }());    /**     * SHA-3 hash algorithm.     */    var SHA3 = C_algo.SHA3 = Hasher.extend({        /**         * Configuration options.         *         * @property {number} outputLength         *   The desired number of bits in the output hash.         *   Only values permitted are: 224, 256, 384, 512.         *   Default: 512         */        cfg: Hasher.cfg.extend({            outputLength: 512        }),        _doReset: function () {            var state = this._state = []            for (var i = 0; i < 25; i++) {                state[i] = new X64Word.init();            }            this.blockSize = (1600 - 2 * this.cfg.outputLength) / 32;        },        _doProcessBlock: function (M, offset) {            // Shortcuts            var state = this._state;            var nBlockSizeLanes = this.blockSize / 2;            // Absorb            for (var i = 0; i < nBlockSizeLanes; i++) {                // Shortcuts                var M2i  = M[offset + 2 * i];                var M2i1 = M[offset + 2 * i + 1];                // Swap endian                M2i = (                    (((M2i << 8)  | (M2i >>> 24)) & 0x00ff00ff) |                    (((M2i << 24) | (M2i >>> 8))  & 0xff00ff00)                );                M2i1 = (                    (((M2i1 << 8)  | (M2i1 >>> 24)) & 0x00ff00ff) |                    (((M2i1 << 24) | (M2i1 >>> 8))  & 0xff00ff00)                );                // Absorb message into state                var lane = state[i];                lane.high ^= M2i1;                lane.low  ^= M2i;            }            // Rounds            for (var round = 0; round < 24; round++) {                // Theta                for (var x = 0; x < 5; x++) {                    // Mix column lanes                    var tMsw = 0, tLsw = 0;                    for (var y = 0; y < 5; y++) {                        var lane = state[x + 5 * y];                        tMsw ^= lane.high;                        tLsw ^= lane.low;                    }                    // Temporary values                    var Tx = T[x];                    Tx.high = tMsw;                    Tx.low  = tLsw;                }                for (var x = 0; x < 5; x++) {                    // Shortcuts                    var Tx4 = T[(x + 4) % 5];                    var Tx1 = T[(x + 1) % 5];                    var Tx1Msw = Tx1.high;                    var Tx1Lsw = Tx1.low;                    // Mix surrounding columns                    var tMsw = Tx4.high ^ ((Tx1Msw << 1) | (Tx1Lsw >>> 31));                    var tLsw = Tx4.low  ^ ((Tx1Lsw << 1) | (Tx1Msw >>> 31));                    for (var y = 0; y < 5; y++) {                        var lane = state[x + 5 * y];                        lane.high ^= tMsw;                        lane.low  ^= tLsw;                    }                }                // Rho Pi                for (var laneIndex = 1; laneIndex < 25; laneIndex++) {                    // Shortcuts                    var lane = state[laneIndex];                    var laneMsw = lane.high;                    var laneLsw = lane.low;                    var rhoOffset = RHO_OFFSETS[laneIndex];                    // Rotate lanes                    if (rhoOffset < 32) {                        var tMsw = (laneMsw << rhoOffset) | (laneLsw >>> (32 - rhoOffset));                        var tLsw = (laneLsw << rhoOffset) | (laneMsw >>> (32 - rhoOffset));                    } else /* if (rhoOffset >= 32) */ {                        var tMsw = (laneLsw << (rhoOffset - 32)) | (laneMsw >>> (64 - rhoOffset));                        var tLsw = (laneMsw << (rhoOffset - 32)) | (laneLsw >>> (64 - rhoOffset));                    }                    // Transpose lanes                    var TPiLane = T[PI_INDEXES[laneIndex]];                    TPiLane.high = tMsw;                    TPiLane.low  = tLsw;                }                // Rho pi at x = y = 0                var T0 = T[0];                var state0 = state[0];                T0.high = state0.high;                T0.low  = state0.low;                // Chi                for (var x = 0; x < 5; x++) {                    for (var y = 0; y < 5; y++) {                        // Shortcuts                        var laneIndex = x + 5 * y;                        var lane = state[laneIndex];                        var TLane = T[laneIndex];                        var Tx1Lane = T[((x + 1) % 5) + 5 * y];                        var Tx2Lane = T[((x + 2) % 5) + 5 * y];                        // Mix rows                        lane.high = TLane.high ^ (~Tx1Lane.high & Tx2Lane.high);                        lane.low  = TLane.low  ^ (~Tx1Lane.low  & Tx2Lane.low);                    }                }                // Iota                var lane = state[0];                var roundConstant = ROUND_CONSTANTS[round];                lane.high ^= roundConstant.high;                lane.low  ^= roundConstant.low;;            }        },        _doFinalize: function () {            // Shortcuts            var data = this._data;            var dataWords = data.words;            var nBitsTotal = this._nDataBytes * 8;            var nBitsLeft = data.sigBytes * 8;            var blockSizeBits = this.blockSize * 32;            // Add padding            dataWords[nBitsLeft >>> 5] |= 0x1 << (24 - nBitsLeft % 32);            dataWords[((Math.ceil((nBitsLeft + 1) / blockSizeBits) * blockSizeBits) >>> 5) - 1] |= 0x80;            data.sigBytes = dataWords.length * 4;            // Hash final blocks            this._process();            // Shortcuts            var state = this._state;            var outputLengthBytes = this.cfg.outputLength / 8;            var outputLengthLanes = outputLengthBytes / 8;            // Squeeze            var hashWords = [];            for (var i = 0; i < outputLengthLanes; i++) {                // Shortcuts                var lane = state[i];                var laneMsw = lane.high;                var laneLsw = lane.low;                // Swap endian                laneMsw = (                    (((laneMsw << 8)  | (laneMsw >>> 24)) & 0x00ff00ff) |                    (((laneMsw << 24) | (laneMsw >>> 8))  & 0xff00ff00)                );                laneLsw = (                    (((laneLsw << 8)  | (laneLsw >>> 24)) & 0x00ff00ff) |                    (((laneLsw << 24) | (laneLsw >>> 8))  & 0xff00ff00)                );                // Squeeze state to retrieve hash                hashWords.push(laneLsw);                hashWords.push(laneMsw);            }            // Return final computed hash            return new WordArray.init(hashWords, outputLengthBytes);        },        clone: function () {            var clone = Hasher.clone.call(this);            var state = clone._state = this._state.slice(0);            for (var i = 0; i < 25; i++) {                state[i] = state[i].clone();            }            return clone;        }    });    /**     * Shortcut function to the hasher's object interface.     *     * @param {WordArray|string} message The message to hash.     *     * @return {WordArray} The hash.     *     * @static     *     * @example     *     *     var hash = CryptoJS.SHA3('message');     *     var hash = CryptoJS.SHA3(wordArray);     */    C.SHA3 = Hasher._createHelper(SHA3);    /**     * Shortcut function to the HMAC's object interface.     *     * @param {WordArray|string} message The message to hash.     * @param {WordArray|string} key The secret key.     *     * @return {WordArray} The HMAC.     *     * @static     *     * @example     *     *     var hmac = CryptoJS.HmacSHA3(message, key);     */    C.HmacSHA3 = Hasher._createHmacHelper(SHA3);}(Math));
 |