Show More
Commit Description:
merge
Commit Description:
merge
References:
File last commit:
Show/Diff file:
Action:
node_modules/crypto-js/sha3.js
| 322 lines
| 10.4 KiB
| application/javascript
| JavascriptLexer
|
r789 | ;(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++) { | |||
// 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)); | |||
return CryptoJS.SHA3; | |||
})); |