partkeepr

fork of partkeepr
git clone https://git.e1e0.net/partkeepr.git
Log | Files | Refs | Submodules | README | LICENSE

core.js (20621B)


      1 /**
      2  * CryptoJS core components.
      3  */
      4 var CryptoJS = CryptoJS || (function (Math, undefined) {
      5     /**
      6      * CryptoJS namespace.
      7      */
      8     var C = {};
      9 
     10     /**
     11      * Library namespace.
     12      */
     13     var C_lib = C.lib = {};
     14 
     15     /**
     16      * Base object for prototypal inheritance.
     17      */
     18     var Base = C_lib.Base = (function () {
     19         function F() {}
     20 
     21         return {
     22             /**
     23              * Creates a new object that inherits from this object.
     24              *
     25              * @param {Object} overrides Properties to copy into the new object.
     26              *
     27              * @return {Object} The new object.
     28              *
     29              * @static
     30              *
     31              * @example
     32              *
     33              *     var MyType = CryptoJS.lib.Base.extend({
     34              *         field: 'value',
     35              *
     36              *         method: function () {
     37              *         }
     38              *     });
     39              */
     40             extend: function (overrides) {
     41                 // Spawn
     42                 F.prototype = this;
     43                 var subtype = new F();
     44 
     45                 // Augment
     46                 if (overrides) {
     47                     subtype.mixIn(overrides);
     48                 }
     49 
     50                 // Create default initializer
     51                 if (!subtype.hasOwnProperty('init')) {
     52                     subtype.init = function () {
     53                         subtype.$super.init.apply(this, arguments);
     54                     };
     55                 }
     56 
     57                 // Initializer's prototype is the subtype object
     58                 subtype.init.prototype = subtype;
     59 
     60                 // Reference supertype
     61                 subtype.$super = this;
     62 
     63                 return subtype;
     64             },
     65 
     66             /**
     67              * Extends this object and runs the init method.
     68              * Arguments to create() will be passed to init().
     69              *
     70              * @return {Object} The new object.
     71              *
     72              * @static
     73              *
     74              * @example
     75              *
     76              *     var instance = MyType.create();
     77              */
     78             create: function () {
     79                 var instance = this.extend();
     80                 instance.init.apply(instance, arguments);
     81 
     82                 return instance;
     83             },
     84 
     85             /**
     86              * Initializes a newly created object.
     87              * Override this method to add some logic when your objects are created.
     88              *
     89              * @example
     90              *
     91              *     var MyType = CryptoJS.lib.Base.extend({
     92              *         init: function () {
     93              *             // ...
     94              *         }
     95              *     });
     96              */
     97             init: function () {
     98             },
     99 
    100             /**
    101              * Copies properties into this object.
    102              *
    103              * @param {Object} properties The properties to mix in.
    104              *
    105              * @example
    106              *
    107              *     MyType.mixIn({
    108              *         field: 'value'
    109              *     });
    110              */
    111             mixIn: function (properties) {
    112                 for (var propertyName in properties) {
    113                     if (properties.hasOwnProperty(propertyName)) {
    114                         this[propertyName] = properties[propertyName];
    115                     }
    116                 }
    117 
    118                 // IE won't copy toString using the loop above
    119                 if (properties.hasOwnProperty('toString')) {
    120                     this.toString = properties.toString;
    121                 }
    122             },
    123 
    124             /**
    125              * Creates a copy of this object.
    126              *
    127              * @return {Object} The clone.
    128              *
    129              * @example
    130              *
    131              *     var clone = instance.clone();
    132              */
    133             clone: function () {
    134                 return this.init.prototype.extend(this);
    135             }
    136         };
    137     }());
    138 
    139     /**
    140      * An array of 32-bit words.
    141      *
    142      * @property {Array} words The array of 32-bit words.
    143      * @property {number} sigBytes The number of significant bytes in this word array.
    144      */
    145     var WordArray = C_lib.WordArray = Base.extend({
    146         /**
    147          * Initializes a newly created word array.
    148          *
    149          * @param {Array} words (Optional) An array of 32-bit words.
    150          * @param {number} sigBytes (Optional) The number of significant bytes in the words.
    151          *
    152          * @example
    153          *
    154          *     var wordArray = CryptoJS.lib.WordArray.create();
    155          *     var wordArray = CryptoJS.lib.WordArray.create([0x00010203, 0x04050607]);
    156          *     var wordArray = CryptoJS.lib.WordArray.create([0x00010203, 0x04050607], 6);
    157          */
    158         init: function (words, sigBytes) {
    159             words = this.words = words || [];
    160 
    161             if (sigBytes != undefined) {
    162                 this.sigBytes = sigBytes;
    163             } else {
    164                 this.sigBytes = words.length * 4;
    165             }
    166         },
    167 
    168         /**
    169          * Converts this word array to a string.
    170          *
    171          * @param {Encoder} encoder (Optional) The encoding strategy to use. Default: CryptoJS.enc.Hex
    172          *
    173          * @return {string} The stringified word array.
    174          *
    175          * @example
    176          *
    177          *     var string = wordArray + '';
    178          *     var string = wordArray.toString();
    179          *     var string = wordArray.toString(CryptoJS.enc.Utf8);
    180          */
    181         toString: function (encoder) {
    182             return (encoder || Hex).stringify(this);
    183         },
    184 
    185         /**
    186          * Concatenates a word array to this word array.
    187          *
    188          * @param {WordArray} wordArray The word array to append.
    189          *
    190          * @return {WordArray} This word array.
    191          *
    192          * @example
    193          *
    194          *     wordArray1.concat(wordArray2);
    195          */
    196         concat: function (wordArray) {
    197             // Shortcuts
    198             var thisWords = this.words;
    199             var thatWords = wordArray.words;
    200             var thisSigBytes = this.sigBytes;
    201             var thatSigBytes = wordArray.sigBytes;
    202 
    203             // Clamp excess bits
    204             this.clamp();
    205 
    206             // Concat
    207             if (thisSigBytes % 4) {
    208                 // Copy one byte at a time
    209                 for (var i = 0; i < thatSigBytes; i++) {
    210                     var thatByte = (thatWords[i >>> 2] >>> (24 - (i % 4) * 8)) & 0xff;
    211                     thisWords[(thisSigBytes + i) >>> 2] |= thatByte << (24 - ((thisSigBytes + i) % 4) * 8);
    212                 }
    213             } else if (thatWords.length > 0xffff) {
    214                 // Copy one word at a time
    215                 for (var i = 0; i < thatSigBytes; i += 4) {
    216                     thisWords[(thisSigBytes + i) >>> 2] = thatWords[i >>> 2];
    217                 }
    218             } else {
    219                 // Copy all words at once
    220                 thisWords.push.apply(thisWords, thatWords);
    221             }
    222             this.sigBytes += thatSigBytes;
    223 
    224             // Chainable
    225             return this;
    226         },
    227 
    228         /**
    229          * Removes insignificant bits.
    230          *
    231          * @example
    232          *
    233          *     wordArray.clamp();
    234          */
    235         clamp: function () {
    236             // Shortcuts
    237             var words = this.words;
    238             var sigBytes = this.sigBytes;
    239 
    240             // Clamp
    241             words[sigBytes >>> 2] &= 0xffffffff << (32 - (sigBytes % 4) * 8);
    242             words.length = Math.ceil(sigBytes / 4);
    243         },
    244 
    245         /**
    246          * Creates a copy of this word array.
    247          *
    248          * @return {WordArray} The clone.
    249          *
    250          * @example
    251          *
    252          *     var clone = wordArray.clone();
    253          */
    254         clone: function () {
    255             var clone = Base.clone.call(this);
    256             clone.words = this.words.slice(0);
    257 
    258             return clone;
    259         },
    260 
    261         /**
    262          * Creates a word array filled with random bytes.
    263          *
    264          * @param {number} nBytes The number of random bytes to generate.
    265          *
    266          * @return {WordArray} The random word array.
    267          *
    268          * @static
    269          *
    270          * @example
    271          *
    272          *     var wordArray = CryptoJS.lib.WordArray.random(16);
    273          */
    274         random: function (nBytes) {
    275             var words = [];
    276             for (var i = 0; i < nBytes; i += 4) {
    277                 words.push((Math.random() * 0x100000000) | 0);
    278             }
    279 
    280             return new WordArray.init(words, nBytes);
    281         }
    282     });
    283 
    284     /**
    285      * Encoder namespace.
    286      */
    287     var C_enc = C.enc = {};
    288 
    289     /**
    290      * Hex encoding strategy.
    291      */
    292     var Hex = C_enc.Hex = {
    293         /**
    294          * Converts a word array to a hex string.
    295          *
    296          * @param {WordArray} wordArray The word array.
    297          *
    298          * @return {string} The hex string.
    299          *
    300          * @static
    301          *
    302          * @example
    303          *
    304          *     var hexString = CryptoJS.enc.Hex.stringify(wordArray);
    305          */
    306         stringify: function (wordArray) {
    307             // Shortcuts
    308             var words = wordArray.words;
    309             var sigBytes = wordArray.sigBytes;
    310 
    311             // Convert
    312             var hexChars = [];
    313             for (var i = 0; i < sigBytes; i++) {
    314                 var bite = (words[i >>> 2] >>> (24 - (i % 4) * 8)) & 0xff;
    315                 hexChars.push((bite >>> 4).toString(16));
    316                 hexChars.push((bite & 0x0f).toString(16));
    317             }
    318 
    319             return hexChars.join('');
    320         },
    321 
    322         /**
    323          * Converts a hex string to a word array.
    324          *
    325          * @param {string} hexStr The hex string.
    326          *
    327          * @return {WordArray} The word array.
    328          *
    329          * @static
    330          *
    331          * @example
    332          *
    333          *     var wordArray = CryptoJS.enc.Hex.parse(hexString);
    334          */
    335         parse: function (hexStr) {
    336             // Shortcut
    337             var hexStrLength = hexStr.length;
    338 
    339             // Convert
    340             var words = [];
    341             for (var i = 0; i < hexStrLength; i += 2) {
    342                 words[i >>> 3] |= parseInt(hexStr.substr(i, 2), 16) << (24 - (i % 8) * 4);
    343             }
    344 
    345             return new WordArray.init(words, hexStrLength / 2);
    346         }
    347     };
    348 
    349     /**
    350      * Latin1 encoding strategy.
    351      */
    352     var Latin1 = C_enc.Latin1 = {
    353         /**
    354          * Converts a word array to a Latin1 string.
    355          *
    356          * @param {WordArray} wordArray The word array.
    357          *
    358          * @return {string} The Latin1 string.
    359          *
    360          * @static
    361          *
    362          * @example
    363          *
    364          *     var latin1String = CryptoJS.enc.Latin1.stringify(wordArray);
    365          */
    366         stringify: function (wordArray) {
    367             // Shortcuts
    368             var words = wordArray.words;
    369             var sigBytes = wordArray.sigBytes;
    370 
    371             // Convert
    372             var latin1Chars = [];
    373             for (var i = 0; i < sigBytes; i++) {
    374                 var bite = (words[i >>> 2] >>> (24 - (i % 4) * 8)) & 0xff;
    375                 latin1Chars.push(String.fromCharCode(bite));
    376             }
    377 
    378             return latin1Chars.join('');
    379         },
    380 
    381         /**
    382          * Converts a Latin1 string to a word array.
    383          *
    384          * @param {string} latin1Str The Latin1 string.
    385          *
    386          * @return {WordArray} The word array.
    387          *
    388          * @static
    389          *
    390          * @example
    391          *
    392          *     var wordArray = CryptoJS.enc.Latin1.parse(latin1String);
    393          */
    394         parse: function (latin1Str) {
    395             // Shortcut
    396             var latin1StrLength = latin1Str.length;
    397 
    398             // Convert
    399             var words = [];
    400             for (var i = 0; i < latin1StrLength; i++) {
    401                 words[i >>> 2] |= (latin1Str.charCodeAt(i) & 0xff) << (24 - (i % 4) * 8);
    402             }
    403 
    404             return new WordArray.init(words, latin1StrLength);
    405         }
    406     };
    407 
    408     /**
    409      * UTF-8 encoding strategy.
    410      */
    411     var Utf8 = C_enc.Utf8 = {
    412         /**
    413          * Converts a word array to a UTF-8 string.
    414          *
    415          * @param {WordArray} wordArray The word array.
    416          *
    417          * @return {string} The UTF-8 string.
    418          *
    419          * @static
    420          *
    421          * @example
    422          *
    423          *     var utf8String = CryptoJS.enc.Utf8.stringify(wordArray);
    424          */
    425         stringify: function (wordArray) {
    426             try {
    427                 return decodeURIComponent(escape(Latin1.stringify(wordArray)));
    428             } catch (e) {
    429                 throw new Error('Malformed UTF-8 data');
    430             }
    431         },
    432 
    433         /**
    434          * Converts a UTF-8 string to a word array.
    435          *
    436          * @param {string} utf8Str The UTF-8 string.
    437          *
    438          * @return {WordArray} The word array.
    439          *
    440          * @static
    441          *
    442          * @example
    443          *
    444          *     var wordArray = CryptoJS.enc.Utf8.parse(utf8String);
    445          */
    446         parse: function (utf8Str) {
    447             return Latin1.parse(unescape(encodeURIComponent(utf8Str)));
    448         }
    449     };
    450 
    451     /**
    452      * Abstract buffered block algorithm template.
    453      *
    454      * The property blockSize must be implemented in a concrete subtype.
    455      *
    456      * @property {number} _minBufferSize The number of blocks that should be kept unprocessed in the buffer. Default: 0
    457      */
    458     var BufferedBlockAlgorithm = C_lib.BufferedBlockAlgorithm = Base.extend({
    459         /**
    460          * Resets this block algorithm's data buffer to its initial state.
    461          *
    462          * @example
    463          *
    464          *     bufferedBlockAlgorithm.reset();
    465          */
    466         reset: function () {
    467             // Initial values
    468             this._data = new WordArray.init();
    469             this._nDataBytes = 0;
    470         },
    471 
    472         /**
    473          * Adds new data to this block algorithm's buffer.
    474          *
    475          * @param {WordArray|string} data The data to append. Strings are converted to a WordArray using UTF-8.
    476          *
    477          * @example
    478          *
    479          *     bufferedBlockAlgorithm._append('data');
    480          *     bufferedBlockAlgorithm._append(wordArray);
    481          */
    482         _append: function (data) {
    483             // Convert string to WordArray, else assume WordArray already
    484             if (typeof data == 'string') {
    485                 data = Utf8.parse(data);
    486             }
    487 
    488             // Append
    489             this._data.concat(data);
    490             this._nDataBytes += data.sigBytes;
    491         },
    492 
    493         /**
    494          * Processes available data blocks.
    495          *
    496          * This method invokes _doProcessBlock(offset), which must be implemented by a concrete subtype.
    497          *
    498          * @param {boolean} doFlush Whether all blocks and partial blocks should be processed.
    499          *
    500          * @return {WordArray} The processed data.
    501          *
    502          * @example
    503          *
    504          *     var processedData = bufferedBlockAlgorithm._process();
    505          *     var processedData = bufferedBlockAlgorithm._process(!!'flush');
    506          */
    507         _process: function (doFlush) {
    508             // Shortcuts
    509             var data = this._data;
    510             var dataWords = data.words;
    511             var dataSigBytes = data.sigBytes;
    512             var blockSize = this.blockSize;
    513             var blockSizeBytes = blockSize * 4;
    514 
    515             // Count blocks ready
    516             var nBlocksReady = dataSigBytes / blockSizeBytes;
    517             if (doFlush) {
    518                 // Round up to include partial blocks
    519                 nBlocksReady = Math.ceil(nBlocksReady);
    520             } else {
    521                 // Round down to include only full blocks,
    522                 // less the number of blocks that must remain in the buffer
    523                 nBlocksReady = Math.max((nBlocksReady | 0) - this._minBufferSize, 0);
    524             }
    525 
    526             // Count words ready
    527             var nWordsReady = nBlocksReady * blockSize;
    528 
    529             // Count bytes ready
    530             var nBytesReady = Math.min(nWordsReady * 4, dataSigBytes);
    531 
    532             // Process blocks
    533             if (nWordsReady) {
    534                 for (var offset = 0; offset < nWordsReady; offset += blockSize) {
    535                     // Perform concrete-algorithm logic
    536                     this._doProcessBlock(dataWords, offset);
    537                 }
    538 
    539                 // Remove processed words
    540                 var processedWords = dataWords.splice(0, nWordsReady);
    541                 data.sigBytes -= nBytesReady;
    542             }
    543 
    544             // Return processed words
    545             return new WordArray.init(processedWords, nBytesReady);
    546         },
    547 
    548         /**
    549          * Creates a copy of this object.
    550          *
    551          * @return {Object} The clone.
    552          *
    553          * @example
    554          *
    555          *     var clone = bufferedBlockAlgorithm.clone();
    556          */
    557         clone: function () {
    558             var clone = Base.clone.call(this);
    559             clone._data = this._data.clone();
    560 
    561             return clone;
    562         },
    563 
    564         _minBufferSize: 0
    565     });
    566 
    567     /**
    568      * Abstract hasher template.
    569      *
    570      * @property {number} blockSize The number of 32-bit words this hasher operates on. Default: 16 (512 bits)
    571      */
    572     var Hasher = C_lib.Hasher = BufferedBlockAlgorithm.extend({
    573         /**
    574          * Configuration options.
    575          */
    576         cfg: Base.extend(),
    577 
    578         /**
    579          * Initializes a newly created hasher.
    580          *
    581          * @param {Object} cfg (Optional) The configuration options to use for this hash computation.
    582          *
    583          * @example
    584          *
    585          *     var hasher = CryptoJS.algo.SHA256.create();
    586          */
    587         init: function (cfg) {
    588             // Apply config defaults
    589             this.cfg = this.cfg.extend(cfg);
    590 
    591             // Set initial values
    592             this.reset();
    593         },
    594 
    595         /**
    596          * Resets this hasher to its initial state.
    597          *
    598          * @example
    599          *
    600          *     hasher.reset();
    601          */
    602         reset: function () {
    603             // Reset data buffer
    604             BufferedBlockAlgorithm.reset.call(this);
    605 
    606             // Perform concrete-hasher logic
    607             this._doReset();
    608         },
    609 
    610         /**
    611          * Updates this hasher with a message.
    612          *
    613          * @param {WordArray|string} messageUpdate The message to append.
    614          *
    615          * @return {Hasher} This hasher.
    616          *
    617          * @example
    618          *
    619          *     hasher.update('message');
    620          *     hasher.update(wordArray);
    621          */
    622         update: function (messageUpdate) {
    623             // Append
    624             this._append(messageUpdate);
    625 
    626             // Update the hash
    627             this._process();
    628 
    629             // Chainable
    630             return this;
    631         },
    632 
    633         /**
    634          * Finalizes the hash computation.
    635          * Note that the finalize operation is effectively a destructive, read-once operation.
    636          *
    637          * @param {WordArray|string} messageUpdate (Optional) A final message update.
    638          *
    639          * @return {WordArray} The hash.
    640          *
    641          * @example
    642          *
    643          *     var hash = hasher.finalize();
    644          *     var hash = hasher.finalize('message');
    645          *     var hash = hasher.finalize(wordArray);
    646          */
    647         finalize: function (messageUpdate) {
    648             // Final message update
    649             if (messageUpdate) {
    650                 this._append(messageUpdate);
    651             }
    652 
    653             // Perform concrete-hasher logic
    654             var hash = this._doFinalize();
    655 
    656             return hash;
    657         },
    658 
    659         blockSize: 512/32,
    660 
    661         /**
    662          * Creates a shortcut function to a hasher's object interface.
    663          *
    664          * @param {Hasher} hasher The hasher to create a helper for.
    665          *
    666          * @return {Function} The shortcut function.
    667          *
    668          * @static
    669          *
    670          * @example
    671          *
    672          *     var SHA256 = CryptoJS.lib.Hasher._createHelper(CryptoJS.algo.SHA256);
    673          */
    674         _createHelper: function (hasher) {
    675             return function (message, cfg) {
    676                 return new hasher.init(cfg).finalize(message);
    677             };
    678         },
    679 
    680         /**
    681          * Creates a shortcut function to the HMAC's object interface.
    682          *
    683          * @param {Hasher} hasher The hasher to use in this HMAC helper.
    684          *
    685          * @return {Function} The shortcut function.
    686          *
    687          * @static
    688          *
    689          * @example
    690          *
    691          *     var HmacSHA256 = CryptoJS.lib.Hasher._createHmacHelper(CryptoJS.algo.SHA256);
    692          */
    693         _createHmacHelper: function (hasher) {
    694             return function (message, key) {
    695                 return new C_algo.HMAC.init(hasher, key).finalize(message);
    696             };
    697         }
    698     });
    699 
    700     /**
    701      * Algorithm namespace.
    702      */
    703     var C_algo = C.algo = {};
    704 
    705     return C;
    706 }(Math));