Subversion Repositories cryptochat

Rev

View as "text/javascript" | Blame | Last modification | View Log | RSS feed

  1. /*
  2. CryptoJS v3.1.2
  3. code.google.com/p/crypto-js
  4. (c) 2009-2013 by Jeff Mott. All rights reserved.
  5. code.google.com/p/crypto-js/wiki/License
  6. */
  7. (function (Math) {
  8.     // Shortcuts
  9.     var C = CryptoJS;
  10.     var C_lib = C.lib;
  11.     var WordArray = C_lib.WordArray;
  12.     var Hasher = C_lib.Hasher;
  13.     var C_x64 = C.x64;
  14.     var X64Word = C_x64.Word;
  15.     var C_algo = C.algo;
  16.  
  17.     // Constants tables
  18.     var RHO_OFFSETS = [];
  19.     var PI_INDEXES  = [];
  20.     var ROUND_CONSTANTS = [];
  21.  
  22.     // Compute Constants
  23.     (function () {
  24.         // Compute rho offset constants
  25.         var x = 1, y = 0;
  26.         for (var t = 0; t < 24; t++) {
  27.             RHO_OFFSETS[x + 5 * y] = ((t + 1) * (t + 2) / 2) % 64;
  28.  
  29.             var newX = y % 5;
  30.             var newY = (2 * x + 3 * y) % 5;
  31.             x = newX;
  32.             y = newY;
  33.         }
  34.  
  35.         // Compute pi index constants
  36.         for (var x = 0; x < 5; x++) {
  37.             for (var y = 0; y < 5; y++) {
  38.                 PI_INDEXES[x + 5 * y] = y + ((2 * x + 3 * y) % 5) * 5;
  39.             }
  40.         }
  41.  
  42.         // Compute round constants
  43.         var LFSR = 0x01;
  44.         for (var i = 0; i < 24; i++) {
  45.             var roundConstantMsw = 0;
  46.             var roundConstantLsw = 0;
  47.  
  48.             for (var j = 0; j < 7; j++) {
  49.                 if (LFSR & 0x01) {
  50.                     var bitPosition = (1 << j) - 1;
  51.                     if (bitPosition < 32) {
  52.                         roundConstantLsw ^= 1 << bitPosition;
  53.                     } else /* if (bitPosition >= 32) */ {
  54.                         roundConstantMsw ^= 1 << (bitPosition - 32);
  55.                     }
  56.                 }
  57.  
  58.                 // Compute next LFSR
  59.                 if (LFSR & 0x80) {
  60.                     // Primitive polynomial over GF(2): x^8 + x^6 + x^5 + x^4 + 1
  61.                     LFSR = (LFSR << 1) ^ 0x71;
  62.                 } else {
  63.                     LFSR <<= 1;
  64.                 }
  65.             }
  66.  
  67.             ROUND_CONSTANTS[i] = X64Word.create(roundConstantMsw, roundConstantLsw);
  68.         }
  69.     }());
  70.  
  71.     // Reusable objects for temporary values
  72.     var T = [];
  73.     (function () {
  74.         for (var i = 0; i < 25; i++) {
  75.             T[i] = X64Word.create();
  76.         }
  77.     }());
  78.  
  79.     /**
  80.      * SHA-3 hash algorithm.
  81.      */
  82.     var SHA3 = C_algo.SHA3 = Hasher.extend({
  83.         /**
  84.          * Configuration options.
  85.          *
  86.          * @property {number} outputLength
  87.          *   The desired number of bits in the output hash.
  88.          *   Only values permitted are: 224, 256, 384, 512.
  89.          *   Default: 512
  90.          */
  91.         cfg: Hasher.cfg.extend({
  92.             outputLength: 512
  93.         }),
  94.  
  95.         _doReset: function () {
  96.             var state = this._state = []
  97.             for (var i = 0; i < 25; i++) {
  98.                 state[i] = new X64Word.init();
  99.             }
  100.  
  101.             this.blockSize = (1600 - 2 * this.cfg.outputLength) / 32;
  102.         },
  103.  
  104.         _doProcessBlock: function (M, offset) {
  105.             // Shortcuts
  106.             var state = this._state;
  107.             var nBlockSizeLanes = this.blockSize / 2;
  108.  
  109.             // Absorb
  110.             for (var i = 0; i < nBlockSizeLanes; i++) {
  111.                 // Shortcuts
  112.                 var M2i  = M[offset + 2 * i];
  113.                 var M2i1 = M[offset + 2 * i + 1];
  114.  
  115.                 // Swap endian
  116.                 M2i = (
  117.                     (((M2i << 8)  | (M2i >>> 24)) & 0x00ff00ff) |
  118.                     (((M2i << 24) | (M2i >>> 8))  & 0xff00ff00)
  119.                 );
  120.                 M2i1 = (
  121.                     (((M2i1 << 8)  | (M2i1 >>> 24)) & 0x00ff00ff) |
  122.                     (((M2i1 << 24) | (M2i1 >>> 8))  & 0xff00ff00)
  123.                 );
  124.  
  125.                 // Absorb message into state
  126.                 var lane = state[i];
  127.                 lane.high ^= M2i1;
  128.                 lane.low  ^= M2i;
  129.             }
  130.  
  131.             // Rounds
  132.             for (var round = 0; round < 24; round++) {
  133.                 // Theta
  134.                 for (var x = 0; x < 5; x++) {
  135.                     // Mix column lanes
  136.                     var tMsw = 0, tLsw = 0;
  137.                     for (var y = 0; y < 5; y++) {
  138.                         var lane = state[x + 5 * y];
  139.                         tMsw ^= lane.high;
  140.                         tLsw ^= lane.low;
  141.                     }
  142.  
  143.                     // Temporary values
  144.                     var Tx = T[x];
  145.                     Tx.high = tMsw;
  146.                     Tx.low  = tLsw;
  147.                 }
  148.                 for (var x = 0; x < 5; x++) {
  149.                     // Shortcuts
  150.                     var Tx4 = T[(x + 4) % 5];
  151.                     var Tx1 = T[(x + 1) % 5];
  152.                     var Tx1Msw = Tx1.high;
  153.                     var Tx1Lsw = Tx1.low;
  154.  
  155.                     // Mix surrounding columns
  156.                     var tMsw = Tx4.high ^ ((Tx1Msw << 1) | (Tx1Lsw >>> 31));
  157.                     var tLsw = Tx4.low  ^ ((Tx1Lsw << 1) | (Tx1Msw >>> 31));
  158.                     for (var y = 0; y < 5; y++) {
  159.                         var lane = state[x + 5 * y];
  160.                         lane.high ^= tMsw;
  161.                         lane.low  ^= tLsw;
  162.                     }
  163.                 }
  164.  
  165.                 // Rho Pi
  166.                 for (var laneIndex = 1; laneIndex < 25; laneIndex++) {
  167.                     // Shortcuts
  168.                     var lane = state[laneIndex];
  169.                     var laneMsw = lane.high;
  170.                     var laneLsw = lane.low;
  171.                     var rhoOffset = RHO_OFFSETS[laneIndex];
  172.  
  173.                     // Rotate lanes
  174.                     if (rhoOffset < 32) {
  175.                         var tMsw = (laneMsw << rhoOffset) | (laneLsw >>> (32 - rhoOffset));
  176.                         var tLsw = (laneLsw << rhoOffset) | (laneMsw >>> (32 - rhoOffset));
  177.                     } else /* if (rhoOffset >= 32) */ {
  178.                         var tMsw = (laneLsw << (rhoOffset - 32)) | (laneMsw >>> (64 - rhoOffset));
  179.                         var tLsw = (laneMsw << (rhoOffset - 32)) | (laneLsw >>> (64 - rhoOffset));
  180.                     }
  181.  
  182.                     // Transpose lanes
  183.                     var TPiLane = T[PI_INDEXES[laneIndex]];
  184.                     TPiLane.high = tMsw;
  185.                     TPiLane.low  = tLsw;
  186.                 }
  187.  
  188.                 // Rho pi at x = y = 0
  189.                 var T0 = T[0];
  190.                 var state0 = state[0];
  191.                 T0.high = state0.high;
  192.                 T0.low  = state0.low;
  193.  
  194.                 // Chi
  195.                 for (var x = 0; x < 5; x++) {
  196.                     for (var y = 0; y < 5; y++) {
  197.                         // Shortcuts
  198.                         var laneIndex = x + 5 * y;
  199.                         var lane = state[laneIndex];
  200.                         var TLane = T[laneIndex];
  201.                         var Tx1Lane = T[((x + 1) % 5) + 5 * y];
  202.                         var Tx2Lane = T[((x + 2) % 5) + 5 * y];
  203.  
  204.                         // Mix rows
  205.                         lane.high = TLane.high ^ (~Tx1Lane.high & Tx2Lane.high);
  206.                         lane.low  = TLane.low  ^ (~Tx1Lane.low  & Tx2Lane.low);
  207.                     }
  208.                 }
  209.  
  210.                 // Iota
  211.                 var lane = state[0];
  212.                 var roundConstant = ROUND_CONSTANTS[round];
  213.                 lane.high ^= roundConstant.high;
  214.                 lane.low  ^= roundConstant.low;;
  215.             }
  216.         },
  217.  
  218.         _doFinalize: function () {
  219.             // Shortcuts
  220.             var data = this._data;
  221.             var dataWords = data.words;
  222.             var nBitsTotal = this._nDataBytes * 8;
  223.             var nBitsLeft = data.sigBytes * 8;
  224.             var blockSizeBits = this.blockSize * 32;
  225.  
  226.             // Add padding
  227.             dataWords[nBitsLeft >>> 5] |= 0x1 << (24 - nBitsLeft % 32);
  228.             dataWords[((Math.ceil((nBitsLeft + 1) / blockSizeBits) * blockSizeBits) >>> 5) - 1] |= 0x80;
  229.             data.sigBytes = dataWords.length * 4;
  230.  
  231.             // Hash final blocks
  232.             this._process();
  233.  
  234.             // Shortcuts
  235.             var state = this._state;
  236.             var outputLengthBytes = this.cfg.outputLength / 8;
  237.             var outputLengthLanes = outputLengthBytes / 8;
  238.  
  239.             // Squeeze
  240.             var hashWords = [];
  241.             for (var i = 0; i < outputLengthLanes; i++) {
  242.                 // Shortcuts
  243.                 var lane = state[i];
  244.                 var laneMsw = lane.high;
  245.                 var laneLsw = lane.low;
  246.  
  247.                 // Swap endian
  248.                 laneMsw = (
  249.                     (((laneMsw << 8)  | (laneMsw >>> 24)) & 0x00ff00ff) |
  250.                     (((laneMsw << 24) | (laneMsw >>> 8))  & 0xff00ff00)
  251.                 );
  252.                 laneLsw = (
  253.                     (((laneLsw << 8)  | (laneLsw >>> 24)) & 0x00ff00ff) |
  254.                     (((laneLsw << 24) | (laneLsw >>> 8))  & 0xff00ff00)
  255.                 );
  256.  
  257.                 // Squeeze state to retrieve hash
  258.                 hashWords.push(laneLsw);
  259.                 hashWords.push(laneMsw);
  260.             }
  261.  
  262.             // Return final computed hash
  263.             return new WordArray.init(hashWords, outputLengthBytes);
  264.         },
  265.  
  266.         clone: function () {
  267.             var clone = Hasher.clone.call(this);
  268.  
  269.             var state = clone._state = this._state.slice(0);
  270.             for (var i = 0; i < 25; i++) {
  271.                 state[i] = state[i].clone();
  272.             }
  273.  
  274.             return clone;
  275.         }
  276.     });
  277.  
  278.     /**
  279.      * Shortcut function to the hasher's object interface.
  280.      *
  281.      * @param {WordArray|string} message The message to hash.
  282.      *
  283.      * @return {WordArray} The hash.
  284.      *
  285.      * @static
  286.      *
  287.      * @example
  288.      *
  289.      *     var hash = CryptoJS.SHA3('message');
  290.      *     var hash = CryptoJS.SHA3(wordArray);
  291.      */
  292.     C.SHA3 = Hasher._createHelper(SHA3);
  293.  
  294.     /**
  295.      * Shortcut function to the HMAC's object interface.
  296.      *
  297.      * @param {WordArray|string} message The message to hash.
  298.      * @param {WordArray|string} key The secret key.
  299.      *
  300.      * @return {WordArray} The HMAC.
  301.      *
  302.      * @static
  303.      *
  304.      * @example
  305.      *
  306.      *     var hmac = CryptoJS.HmacSHA3(message, key);
  307.      */
  308.     C.HmacSHA3 = Hasher._createHmacHelper(SHA3);
  309. }(Math));
  310.