Spaces:
Runtime error
Runtime error
;(function (root, factory, undef) { | |
if (typeof exports === "object") { | |
// CommonJS | |
module.exports = exports = factory(require("./core"), require("./x64-core")); | |
} | |
else if (typeof define === "function" && define.amd) { | |
// AMD | |
define(["./core", "./x64-core"], factory); | |
} | |
else { | |
// Global (browser) | |
factory(root.CryptoJS); | |
} | |
}(this, function (CryptoJS) { | |
(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++) { | |
var tMsw; | |
var tLsw; | |
// Shortcuts | |
var lane = state[laneIndex]; | |
var laneMsw = lane.high; | |
var laneLsw = lane.low; | |
var rhoOffset = RHO_OFFSETS[laneIndex]; | |
// Rotate lanes | |
if (rhoOffset < 32) { | |
tMsw = (laneMsw << rhoOffset) | (laneLsw >>> (32 - rhoOffset)); | |
tLsw = (laneLsw << rhoOffset) | (laneMsw >>> (32 - rhoOffset)); | |
} else /* if (rhoOffset >= 32) */ { | |
tMsw = (laneLsw << (rhoOffset - 32)) | (laneMsw >>> (64 - rhoOffset)); | |
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)); | |
return CryptoJS.SHA3; | |
})); |