Created
November 4, 2013 10:04
-
-
Save ondrek/7300557 to your computer and use it in GitHub Desktop.
Javascript SHA512 implementation
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
(function () { | |
// Shortcuts | |
var C = CryptoJS; | |
var C_lib = C.lib; | |
var Hasher = C_lib.Hasher; | |
var C_x64 = C.x64; | |
var X64Word = C_x64.Word; | |
var X64WordArray = C_x64.WordArray; | |
var C_algo = C.algo; | |
function X64Word_create() { | |
return X64Word.create.apply(X64Word, arguments); | |
} | |
// Constants | |
var K = [ | |
X64Word_create(0x428a2f98, 0xd728ae22), X64Word_create(0x71374491, 0x23ef65cd), | |
X64Word_create(0xb5c0fbcf, 0xec4d3b2f), X64Word_create(0xe9b5dba5, 0x8189dbbc), | |
X64Word_create(0x3956c25b, 0xf348b538), X64Word_create(0x59f111f1, 0xb605d019), | |
X64Word_create(0x923f82a4, 0xaf194f9b), X64Word_create(0xab1c5ed5, 0xda6d8118), | |
X64Word_create(0xd807aa98, 0xa3030242), X64Word_create(0x12835b01, 0x45706fbe), | |
X64Word_create(0x243185be, 0x4ee4b28c), X64Word_create(0x550c7dc3, 0xd5ffb4e2), | |
X64Word_create(0x72be5d74, 0xf27b896f), X64Word_create(0x80deb1fe, 0x3b1696b1), | |
X64Word_create(0x9bdc06a7, 0x25c71235), X64Word_create(0xc19bf174, 0xcf692694), | |
X64Word_create(0xe49b69c1, 0x9ef14ad2), X64Word_create(0xefbe4786, 0x384f25e3), | |
X64Word_create(0x0fc19dc6, 0x8b8cd5b5), X64Word_create(0x240ca1cc, 0x77ac9c65), | |
X64Word_create(0x2de92c6f, 0x592b0275), X64Word_create(0x4a7484aa, 0x6ea6e483), | |
X64Word_create(0x5cb0a9dc, 0xbd41fbd4), X64Word_create(0x76f988da, 0x831153b5), | |
X64Word_create(0x983e5152, 0xee66dfab), X64Word_create(0xa831c66d, 0x2db43210), | |
X64Word_create(0xb00327c8, 0x98fb213f), X64Word_create(0xbf597fc7, 0xbeef0ee4), | |
X64Word_create(0xc6e00bf3, 0x3da88fc2), X64Word_create(0xd5a79147, 0x930aa725), | |
X64Word_create(0x06ca6351, 0xe003826f), X64Word_create(0x14292967, 0x0a0e6e70), | |
X64Word_create(0x27b70a85, 0x46d22ffc), X64Word_create(0x2e1b2138, 0x5c26c926), | |
X64Word_create(0x4d2c6dfc, 0x5ac42aed), X64Word_create(0x53380d13, 0x9d95b3df), | |
X64Word_create(0x650a7354, 0x8baf63de), X64Word_create(0x766a0abb, 0x3c77b2a8), | |
X64Word_create(0x81c2c92e, 0x47edaee6), X64Word_create(0x92722c85, 0x1482353b), | |
X64Word_create(0xa2bfe8a1, 0x4cf10364), X64Word_create(0xa81a664b, 0xbc423001), | |
X64Word_create(0xc24b8b70, 0xd0f89791), X64Word_create(0xc76c51a3, 0x0654be30), | |
X64Word_create(0xd192e819, 0xd6ef5218), X64Word_create(0xd6990624, 0x5565a910), | |
X64Word_create(0xf40e3585, 0x5771202a), X64Word_create(0x106aa070, 0x32bbd1b8), | |
X64Word_create(0x19a4c116, 0xb8d2d0c8), X64Word_create(0x1e376c08, 0x5141ab53), | |
X64Word_create(0x2748774c, 0xdf8eeb99), X64Word_create(0x34b0bcb5, 0xe19b48a8), | |
X64Word_create(0x391c0cb3, 0xc5c95a63), X64Word_create(0x4ed8aa4a, 0xe3418acb), | |
X64Word_create(0x5b9cca4f, 0x7763e373), X64Word_create(0x682e6ff3, 0xd6b2b8a3), | |
X64Word_create(0x748f82ee, 0x5defb2fc), X64Word_create(0x78a5636f, 0x43172f60), | |
X64Word_create(0x84c87814, 0xa1f0ab72), X64Word_create(0x8cc70208, 0x1a6439ec), | |
X64Word_create(0x90befffa, 0x23631e28), X64Word_create(0xa4506ceb, 0xde82bde9), | |
X64Word_create(0xbef9a3f7, 0xb2c67915), X64Word_create(0xc67178f2, 0xe372532b), | |
X64Word_create(0xca273ece, 0xea26619c), X64Word_create(0xd186b8c7, 0x21c0c207), | |
X64Word_create(0xeada7dd6, 0xcde0eb1e), X64Word_create(0xf57d4f7f, 0xee6ed178), | |
X64Word_create(0x06f067aa, 0x72176fba), X64Word_create(0x0a637dc5, 0xa2c898a6), | |
X64Word_create(0x113f9804, 0xbef90dae), X64Word_create(0x1b710b35, 0x131c471b), | |
X64Word_create(0x28db77f5, 0x23047d84), X64Word_create(0x32caab7b, 0x40c72493), | |
X64Word_create(0x3c9ebe0a, 0x15c9bebc), X64Word_create(0x431d67c4, 0x9c100d4c), | |
X64Word_create(0x4cc5d4be, 0xcb3e42b6), X64Word_create(0x597f299c, 0xfc657e2a), | |
X64Word_create(0x5fcb6fab, 0x3ad6faec), X64Word_create(0x6c44198c, 0x4a475817) | |
]; | |
// Reusable objects | |
var W = []; | |
(function () { | |
for (var i = 0; i < 80; i++) { | |
W[i] = X64Word_create(); | |
} | |
}()); | |
/** | |
* SHA-512 hash algorithm. | |
*/ | |
var SHA512 = C_algo.SHA512 = Hasher.extend({ | |
_doReset: function () { | |
this._hash = X64WordArray.create([ | |
X64Word_create(0x6a09e667, 0xf3bcc908), X64Word_create(0xbb67ae85, 0x84caa73b), | |
X64Word_create(0x3c6ef372, 0xfe94f82b), X64Word_create(0xa54ff53a, 0x5f1d36f1), | |
X64Word_create(0x510e527f, 0xade682d1), X64Word_create(0x9b05688c, 0x2b3e6c1f), | |
X64Word_create(0x1f83d9ab, 0xfb41bd6b), X64Word_create(0x5be0cd19, 0x137e2179) | |
]); | |
}, | |
_doProcessBlock: function (M, offset) { | |
// Shortcuts | |
var H = this._hash.words; | |
var H0 = H[0]; | |
var H1 = H[1]; | |
var H2 = H[2]; | |
var H3 = H[3]; | |
var H4 = H[4]; | |
var H5 = H[5]; | |
var H6 = H[6]; | |
var H7 = H[7]; | |
var H0h = H0.high; | |
var H0l = H0.low; | |
var H1h = H1.high; | |
var H1l = H1.low; | |
var H2h = H2.high; | |
var H2l = H2.low; | |
var H3h = H3.high; | |
var H3l = H3.low; | |
var H4h = H4.high; | |
var H4l = H4.low; | |
var H5h = H5.high; | |
var H5l = H5.low; | |
var H6h = H6.high; | |
var H6l = H6.low; | |
var H7h = H7.high; | |
var H7l = H7.low; | |
// Working variables | |
var ah = H0h; | |
var al = H0l; | |
var bh = H1h; | |
var bl = H1l; | |
var ch = H2h; | |
var cl = H2l; | |
var dh = H3h; | |
var dl = H3l; | |
var eh = H4h; | |
var el = H4l; | |
var fh = H5h; | |
var fl = H5l; | |
var gh = H6h; | |
var gl = H6l; | |
var hh = H7h; | |
var hl = H7l; | |
// Rounds | |
for (var i = 0; i < 80; i++) { | |
// Shortcut | |
var Wi = W[i]; | |
// Extend message | |
if (i < 16) { | |
var Wih = Wi.high = M[offset + i * 2] | 0; | |
var Wil = Wi.low = M[offset + i * 2 + 1] | 0; | |
} else { | |
// Gamma0 | |
var gamma0x = W[i - 15]; | |
var gamma0xh = gamma0x.high; | |
var gamma0xl = gamma0x.low; | |
var gamma0h = ((gamma0xh >>> 1) | (gamma0xl << 31)) ^ ((gamma0xh >>> 8) | (gamma0xl << 24)) ^ (gamma0xh >>> 7); | |
var gamma0l = ((gamma0xl >>> 1) | (gamma0xh << 31)) ^ ((gamma0xl >>> 8) | (gamma0xh << 24)) ^ ((gamma0xl >>> 7) | (gamma0xh << 25)); | |
// Gamma1 | |
var gamma1x = W[i - 2]; | |
var gamma1xh = gamma1x.high; | |
var gamma1xl = gamma1x.low; | |
var gamma1h = ((gamma1xh >>> 19) | (gamma1xl << 13)) ^ ((gamma1xh << 3) | (gamma1xl >>> 29)) ^ (gamma1xh >>> 6); | |
var gamma1l = ((gamma1xl >>> 19) | (gamma1xh << 13)) ^ ((gamma1xl << 3) | (gamma1xh >>> 29)) ^ ((gamma1xl >>> 6) | (gamma1xh << 26)); | |
// W[i] = gamma0 + W[i - 7] + gamma1 + W[i - 16] | |
var Wi7 = W[i - 7]; | |
var Wi7h = Wi7.high; | |
var Wi7l = Wi7.low; | |
var Wi16 = W[i - 16]; | |
var Wi16h = Wi16.high; | |
var Wi16l = Wi16.low; | |
var Wil = gamma0l + Wi7l; | |
var Wih = gamma0h + Wi7h + ((Wil >>> 0) < (gamma0l >>> 0) ? 1 : 0); | |
var Wil = Wil + gamma1l; | |
var Wih = Wih + gamma1h + ((Wil >>> 0) < (gamma1l >>> 0) ? 1 : 0); | |
var Wil = Wil + Wi16l; | |
var Wih = Wih + Wi16h + ((Wil >>> 0) < (Wi16l >>> 0) ? 1 : 0); | |
Wi.high = Wih; | |
Wi.low = Wil; | |
} | |
var chh = (eh & fh) ^ (~eh & gh); | |
var chl = (el & fl) ^ (~el & gl); | |
var majh = (ah & bh) ^ (ah & ch) ^ (bh & ch); | |
var majl = (al & bl) ^ (al & cl) ^ (bl & cl); | |
var sigma0h = ((ah >>> 28) | (al << 4)) ^ ((ah << 30) | (al >>> 2)) ^ ((ah << 25) | (al >>> 7)); | |
var sigma0l = ((al >>> 28) | (ah << 4)) ^ ((al << 30) | (ah >>> 2)) ^ ((al << 25) | (ah >>> 7)); | |
var sigma1h = ((eh >>> 14) | (el << 18)) ^ ((eh >>> 18) | (el << 14)) ^ ((eh << 23) | (el >>> 9)); | |
var sigma1l = ((el >>> 14) | (eh << 18)) ^ ((el >>> 18) | (eh << 14)) ^ ((el << 23) | (eh >>> 9)); | |
// t1 = h + sigma1 + ch + K[i] + W[i] | |
var Ki = K[i]; | |
var Kih = Ki.high; | |
var Kil = Ki.low; | |
var t1l = hl + sigma1l; | |
var t1h = hh + sigma1h + ((t1l >>> 0) < (hl >>> 0) ? 1 : 0); | |
var t1l = t1l + chl; | |
var t1h = t1h + chh + ((t1l >>> 0) < (chl >>> 0) ? 1 : 0); | |
var t1l = t1l + Kil; | |
var t1h = t1h + Kih + ((t1l >>> 0) < (Kil >>> 0) ? 1 : 0); | |
var t1l = t1l + Wil; | |
var t1h = t1h + Wih + ((t1l >>> 0) < (Wil >>> 0) ? 1 : 0); | |
var t2l = sigma0l + majl; | |
var t2h = sigma0h + majh + ((t2l >>> 0) < (sigma0l >>> 0) ? 1 : 0); | |
// Update working variables | |
hh = gh; | |
hl = gl; | |
gh = fh; | |
gl = fl; | |
fh = eh; | |
fl = el; | |
el = (dl + t1l) | 0; | |
eh = (dh + t1h + ((el >>> 0) < (dl >>> 0) ? 1 : 0)) | 0; | |
dh = ch; | |
dl = cl; | |
ch = bh; | |
cl = bl; | |
bh = ah; | |
bl = al; | |
al = (t1l + t2l) | 0; | |
ah = (t1h + t2h + ((al >>> 0) < (t1l >>> 0) ? 1 : 0)) | 0; | |
} | |
// Intermediate hash value | |
H0l = H0.low = (H0l + al); | |
H0.high = (H0h + ah + ((H0l >>> 0) < (al >>> 0) ? 1 : 0)); | |
H1l = H1.low = (H1l + bl); | |
H1.high = (H1h + bh + ((H1l >>> 0) < (bl >>> 0) ? 1 : 0)); | |
H2l = H2.low = (H2l + cl); | |
H2.high = (H2h + ch + ((H2l >>> 0) < (cl >>> 0) ? 1 : 0)); | |
H3l = H3.low = (H3l + dl); | |
H3.high = (H3h + dh + ((H3l >>> 0) < (dl >>> 0) ? 1 : 0)); | |
H4l = H4.low = (H4l + el); | |
H4.high = (H4h + eh + ((H4l >>> 0) < (el >>> 0) ? 1 : 0)); | |
H5l = H5.low = (H5l + fl); | |
H5.high = (H5h + fh + ((H5l >>> 0) < (fl >>> 0) ? 1 : 0)); | |
H6l = H6.low = (H6l + gl); | |
H6.high = (H6h + gh + ((H6l >>> 0) < (gl >>> 0) ? 1 : 0)); | |
H7l = H7.low = (H7l + hl); | |
H7.high = (H7h + hh + ((H7l >>> 0) < (hl >>> 0) ? 1 : 0)); | |
}, | |
_doFinalize: function () { | |
// Shortcuts | |
var data = this._data; | |
var dataWords = data.words; | |
var nBitsTotal = this._nDataBytes * 8; | |
var nBitsLeft = data.sigBytes * 8; | |
// Add padding | |
dataWords[nBitsLeft >>> 5] |= 0x80 << (24 - nBitsLeft % 32); | |
dataWords[(((nBitsLeft + 128) >>> 10) << 5) + 31] = nBitsTotal; | |
data.sigBytes = dataWords.length * 4; | |
// Hash final blocks | |
this._process(); | |
// Convert hash to 32-bit word array before returning | |
this._hash = this._hash.toX32(); | |
}, | |
blockSize: 1024/32 | |
}); | |
/** | |
* 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.SHA512('message'); | |
* var hash = CryptoJS.SHA512(wordArray); | |
*/ | |
C.SHA512 = Hasher._createHelper(SHA512); | |
/** | |
* 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.HmacSHA512(message, key); | |
*/ | |
C.HmacSHA512 = Hasher._createHmacHelper(SHA512); | |
}()); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment