diff options
Diffstat (limited to 'src/sha1_nice.js')
-rw-r--r-- | src/sha1_nice.js | 440 |
1 files changed, 248 insertions, 192 deletions
diff --git a/src/sha1_nice.js b/src/sha1_nice.js index aa03dfe..9ea56fe 100644 --- a/src/sha1_nice.js +++ b/src/sha1_nice.js @@ -1,184 +1,195 @@ -/* A JavaScript implementation of the SHA family of hashes, as defined in FIPS PUB 180-2 - * as well as the corresponding HMAC implementation as defined in FIPS PUB 198a - * Version 1.2 Copyright Brian Turek 2009 +/* A JavaScript implementation of the SHA family of hashes, as defined in FIPS + * PUB 180-2 as well as the corresponding HMAC implementation as defined in + * FIPS PUB 198a + * + * Version 1.3 Copyright Brian Turek 2008-2010 * Distributed under the BSD License * See http://jssha.sourceforge.net/ for more information * * Several functions taken from Paul Johnson */ - -function jsSHA(srcString, inputFormat) { - - jsSHA.charSize = 8; - jsSHA.b64pad = ""; - jsSHA.hexCase = 0; - - var sha1 = null; - - var str2binb = function (str) { - var bin = []; - var mask = (1 << jsSHA.charSize) - 1; - var length = str.length * jsSHA.charSize; - - for (var i = 0; i < length; i += jsSHA.charSize) { - bin[i >> 5] |= (str.charCodeAt(i / jsSHA.charSize) & mask) << (32 - jsSHA.charSize - i % 32); +(function () +{ + var charSize = 8, + b64pad = "", + hexCase = 0, + + str2binb = function (str) + { + var bin = [], mask = (1 << charSize) - 1, + length = str.length * charSize, i; + + for (i = 0; i < length; i += charSize) + { + bin[i >> 5] |= (str.charCodeAt(i / charSize) & mask) << + (32 - charSize - (i % 32)); } return bin; - }; - - var hex2binb = function (str) { - var bin = []; - var length = str.length; - - for (var i = 0; i < length; i += 2) { - var num = parseInt(str.substr(i, 2), 16); - if (!isNaN(num)) { + }, + + hex2binb = function (str) + { + var bin = [], length = str.length, i, num; + + for (i = 0; i < length; i += 2) + { + num = parseInt(str.substr(i, 2), 16); + if (!isNaN(num)) + { bin[i >> 3] |= num << (24 - (4 * (i % 8))); - } else { + } + else + { return "INVALID HEX STRING"; } } return bin; - }; + }, - var strBinLen = null; - var strToHash = null; + binb2hex = function (binarray) + { + var hex_tab = (hexCase) ? "0123456789ABCDEF" : "0123456789abcdef", + str = "", length = binarray.length * 4, i, srcByte; - if ("HEX" === inputFormat) { - if (0 !== (srcString.length % 2)) { - return "TEXT MUST BE IN BYTE INCREMENTS"; - } - strBinLen = srcString.length * 4; - strToHash = hex2binb(srcString); - } else if (("ASCII" === inputFormat) || - ('undefined' === typeof(inputFormat))) { - strBinLen = srcString.length * jsSHA.charSize; - strToHash = str2binb(srcString); - } else { - return "UNKNOWN TEXT INPUT TYPE"; - } - - var binb2hex = function (binarray) { - var hex_tab = jsSHA.hexCase ? "0123456789ABCDEF" : "0123456789abcdef"; - var str = ""; - var length = binarray.length * 4; - - for (var i = 0; i < length; i++) { - str += hex_tab.charAt((binarray[i >> 2] >> ((3 - i % 4) * 8 + 4)) & 0xF) + hex_tab.charAt((binarray[i >> 2] >> ((3 - i % 4) * 8)) & 0xF); + for (i = 0; i < length; i += 1) + { + srcByte = binarray[i >> 2] >> ((3 - (i % 4)) * 8); + str += hex_tab.charAt((srcByte >> 4) & 0xF) + + hex_tab.charAt(srcByte & 0xF); } return str; - }; + }, + + binb2b64 = function (binarray) + { + var tab = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz" + + "0123456789+/", str = "", length = binarray.length * 4, i, j, + triplet; - var binb2b64 = function (binarray) { - var tab = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; - var str = ""; - var length = binarray.length * 4; - for (var i = 0; i < length; i += 3) + for (i = 0; i < length; i += 3) { - var triplet = (((binarray[i >> 2] >> 8 * (3 - i % 4)) & 0xFF) << 16) | (((binarray[i + 1 >> 2] >> 8 * (3 - (i + 1) % 4)) & 0xFF) << 8) | ((binarray[i + 2 >> 2] >> 8 * (3 - (i + 2) % 4)) & 0xFF); - for (var j = 0; j < 4; j++) { - if (i * 8 + j * 6 > binarray.length * 32) { - str += jsSHA.b64pad; - } else { + triplet = (((binarray[i >> 2] >> 8 * (3 - i % 4)) & 0xFF) << 16) | + (((binarray[i + 1 >> 2] >> 8 * (3 - (i + 1) % 4)) & 0xFF) << 8) | + ((binarray[i + 2 >> 2] >> 8 * (3 - (i + 2) % 4)) & 0xFF); + for (j = 0; j < 4; j += 1) + { + if (i * 8 + j * 6 <= binarray.length * 32) + { str += tab.charAt((triplet >> 6 * (3 - j)) & 0x3F); } + else + { + str += b64pad; + } } } return str; - }; + }, - var rotl = function (x, n) { - if (n < 32) { - return (x << n) | (x >>> (32 - n)); - } else { - return x; - } - }; + rotl = function (x, n) + { + return (x << n) | (x >>> (32 - n)); + }, - var parity = function (x, y, z) { + parity = function (x, y, z) + { return x ^ y ^ z; - }; + }, - var ch = function (x, y, z) { + ch = function (x, y, z) + { return (x & y) ^ (~x & z); - }; + }, - var maj = function (x, y, z) { + maj = function (x, y, z) + { return (x & y) ^ (x & z) ^ (y & z); - }; + }, - var safeAdd_2 = function (x, y) { - var lsw = (x & 0xFFFF) + (y & 0xFFFF); - var msw = (x >>> 16) + (y >>> 16) + (lsw >>> 16); + safeAdd_2 = function (x, y) + { + var lsw = (x & 0xFFFF) + (y & 0xFFFF), + msw = (x >>> 16) + (y >>> 16) + (lsw >>> 16); return ((msw & 0xFFFF) << 16) | (lsw & 0xFFFF); - }; - - var safeAdd_5 = function (a, b, c, d, e) { + }, + + safeAdd_5 = function (a, b, c, d, e) + { var lsw = (a & 0xFFFF) + (b & 0xFFFF) + (c & 0xFFFF) + (d & 0xFFFF) + - (e & 0xFFFF); - var msw = (a >>> 16) + (b >>> 16) + (c >>> 16) + (d >>> 16) + - (e >>> 16) + (lsw >>> 16); + (e & 0xFFFF), + msw = (a >>> 16) + (b >>> 16) + (c >>> 16) + (d >>> 16) + + (e >>> 16) + (lsw >>> 16); return ((msw & 0xFFFF) << 16) | (lsw & 0xFFFF); - }; - - var coreSHA1 = function (message, messageLen) { - var W = []; - var a, b, c, d, e; - var T; - var H = [ - 0x67452301, 0xefcdab89, 0x98badcfe, 0x10325476, 0xc3d2e1f0 - ]; - var K = [ - 0x5a827999, 0x5a827999, 0x5a827999, 0x5a827999, - 0x5a827999, 0x5a827999, 0x5a827999, 0x5a827999, - 0x5a827999, 0x5a827999, 0x5a827999, 0x5a827999, - 0x5a827999, 0x5a827999, 0x5a827999, 0x5a827999, - 0x5a827999, 0x5a827999, 0x5a827999, 0x5a827999, - 0x6ed9eba1, 0x6ed9eba1, 0x6ed9eba1, 0x6ed9eba1, - 0x6ed9eba1, 0x6ed9eba1, 0x6ed9eba1, 0x6ed9eba1, - 0x6ed9eba1, 0x6ed9eba1, 0x6ed9eba1, 0x6ed9eba1, - 0x6ed9eba1, 0x6ed9eba1, 0x6ed9eba1, 0x6ed9eba1, - 0x6ed9eba1, 0x6ed9eba1, 0x6ed9eba1, 0x6ed9eba1, - 0x8f1bbcdc, 0x8f1bbcdc, 0x8f1bbcdc, 0x8f1bbcdc, - 0x8f1bbcdc, 0x8f1bbcdc, 0x8f1bbcdc, 0x8f1bbcdc, - 0x8f1bbcdc, 0x8f1bbcdc, 0x8f1bbcdc, 0x8f1bbcdc, - 0x8f1bbcdc, 0x8f1bbcdc, 0x8f1bbcdc, 0x8f1bbcdc, - 0x8f1bbcdc, 0x8f1bbcdc, 0x8f1bbcdc, 0x8f1bbcdc, - 0xca62c1d6, 0xca62c1d6, 0xca62c1d6, 0xca62c1d6, - 0xca62c1d6, 0xca62c1d6, 0xca62c1d6, 0xca62c1d6, - 0xca62c1d6, 0xca62c1d6, 0xca62c1d6, 0xca62c1d6, - 0xca62c1d6, 0xca62c1d6, 0xca62c1d6, 0xca62c1d6, - 0xca62c1d6, 0xca62c1d6, 0xca62c1d6, 0xca62c1d6 - ]; - - message[messageLen >> 5] |= 0x80 << (24 - messageLen % 32); - message[((messageLen + 1 + 64 >> 9) << 4) + 15] = messageLen; - var appendedMessageLength = message.length; - - for (var i = 0; i < appendedMessageLength; i += 16) { + }, + + coreSHA1 = function (message, messageLen) + { + var W = [], a, b, c, d, e, T, i, t, appendedMessageLength, + H = [ + 0x67452301, 0xefcdab89, 0x98badcfe, 0x10325476, 0xc3d2e1f0 + ], + K = [ + 0x5a827999, 0x5a827999, 0x5a827999, 0x5a827999, + 0x5a827999, 0x5a827999, 0x5a827999, 0x5a827999, + 0x5a827999, 0x5a827999, 0x5a827999, 0x5a827999, + 0x5a827999, 0x5a827999, 0x5a827999, 0x5a827999, + 0x5a827999, 0x5a827999, 0x5a827999, 0x5a827999, + 0x6ed9eba1, 0x6ed9eba1, 0x6ed9eba1, 0x6ed9eba1, + 0x6ed9eba1, 0x6ed9eba1, 0x6ed9eba1, 0x6ed9eba1, + 0x6ed9eba1, 0x6ed9eba1, 0x6ed9eba1, 0x6ed9eba1, + 0x6ed9eba1, 0x6ed9eba1, 0x6ed9eba1, 0x6ed9eba1, + 0x6ed9eba1, 0x6ed9eba1, 0x6ed9eba1, 0x6ed9eba1, + 0x8f1bbcdc, 0x8f1bbcdc, 0x8f1bbcdc, 0x8f1bbcdc, + 0x8f1bbcdc, 0x8f1bbcdc, 0x8f1bbcdc, 0x8f1bbcdc, + 0x8f1bbcdc, 0x8f1bbcdc, 0x8f1bbcdc, 0x8f1bbcdc, + 0x8f1bbcdc, 0x8f1bbcdc, 0x8f1bbcdc, 0x8f1bbcdc, + 0x8f1bbcdc, 0x8f1bbcdc, 0x8f1bbcdc, 0x8f1bbcdc, + 0xca62c1d6, 0xca62c1d6, 0xca62c1d6, 0xca62c1d6, + 0xca62c1d6, 0xca62c1d6, 0xca62c1d6, 0xca62c1d6, + 0xca62c1d6, 0xca62c1d6, 0xca62c1d6, 0xca62c1d6, + 0xca62c1d6, 0xca62c1d6, 0xca62c1d6, 0xca62c1d6, + 0xca62c1d6, 0xca62c1d6, 0xca62c1d6, 0xca62c1d6 + ]; + + message[messageLen >> 5] |= 0x80 << (24 - (messageLen % 32)); + message[(((messageLen + 65) >> 9) << 4) + 15] = messageLen; + + appendedMessageLength = message.length; + + for (i = 0; i < appendedMessageLength; i += 16) + { a = H[0]; b = H[1]; c = H[2]; d = H[3]; e = H[4]; - for (var t = 0; t < 80; t++) { - if (t < 16) { + for (t = 0; t < 80; t += 1) + { + if (t < 16) + { W[t] = message[t + i]; - } else { + } + else + { W[t] = rotl(W[t - 3] ^ W[t - 8] ^ W[t - 14] ^ W[t - 16], 1); } - if (t < 20) { + if (t < 20) + { T = safeAdd_5(rotl(a, 5), ch(b, c, d), e, K[t], W[t]); - } else if (t < 40) { + } + else if (t < 40) + { T = safeAdd_5(rotl(a, 5), parity(b, c, d), e, K[t], W[t]); - } else if (t < 60) { + } + else if (t < 60) + { T = safeAdd_5(rotl(a, 5), maj(b, c, d), e, K[t], W[t]); } else { T = safeAdd_5(rotl(a, 5), parity(b, c, d), e, K[t], W[t]); @@ -199,77 +210,122 @@ function jsSHA(srcString, inputFormat) { } return H; - }; + }, - this.getHash = function (format) { - var formatFunc = null; - var message = strToHash.slice(); + jsSHA = function (srcString, inputFormat) + { - if (sha1 === null) { - sha1 = sha1 = coreSHA1(message, strBinLen); - } + this.sha1 = null; - switch (format) { - case "HEX": - formatFunc = binb2hex; - break; - case "B64": - formatFunc = binb2b64; - break; - default: - return "FORMAT NOT RECOGNIZED"; - } + this.strBinLen = null; + this.strToHash = null; - return formatFunc(sha1); - }; - - this.getHMAC = function (key, inputFormat, outputFormat) { - var formatFunc = null; - var keyToUse = null; - var keyWithIPad = []; - var keyWithOPad = []; - var retVal = null; - var keyBinLen = null; - - switch (outputFormat) { - case "HEX": - formatFunc = binb2hex; - break; - case "B64": - formatFunc = binb2b64; - break; - default: - return "FORMAT NOT RECOGNIZED"; + if ("HEX" === inputFormat) + { + if (0 !== (srcString.length % 2)) + { + return "TEXT MUST BE IN BYTE INCREMENTS"; + } + this.strBinLen = srcString.length * 4; + this.strToHash = hex2binb(srcString); + } + else if (("ASCII" === inputFormat) || + ('undefined' === typeof(inputFormat))) + { + this.strBinLen = srcString.length * charSize; + this.strToHash = str2binb(srcString); + } + else + { + return "UNKNOWN TEXT INPUT TYPE"; } + }; - if ("HEX" === inputFormat) { - if (0 !== (key.length % 2)) { - return "KEY MUST BE IN BYTE INCREMENTS"; + jsSHA.prototype = { + getHash : function (format) + { + var formatFunc = null, message = this.strToHash.slice(); + + switch (format) + { + case "HEX": + formatFunc = binb2hex; + break; + case "B64": + formatFunc = binb2b64; + break; + default: + return "FORMAT NOT RECOGNIZED"; } - keyToUse = hex2binb(key); - keyBinLen = key.length * 4; - } else if ("ASCII" === inputFormat) { - keyToUse = str2binb(key); - keyBinLen = key.length * jsSHA.charSize; - } else { - return "UNKNOWN KEY INPUT TYPE"; - } - if (512 < keyBinLen) { - keyToUse = coreSHA1(keyToUse, keyBinLen); - keyToUse[15] &= 0xFFFFFF00; - } else if (512 > keyBinLen) { - keyToUse[15] &= 0xFFFFFF00; - } + if (null === this.sha1) + { + this.sha1 = coreSHA1(message, this.strBinLen); + } + return formatFunc(this.sha1); + }, - for (var i = 0; i <= 15; i++) { - keyWithIPad[i] = keyToUse[i] ^ 0x36363636; - keyWithOPad[i] = keyToUse[i] ^ 0x5C5C5C5C; - } + getHMAC : function (key, inputFormat, outputFormat) + { + var formatFunc, keyToUse, i, retVal, keyBinLen, + keyWithIPad = [], keyWithOPad = []; + + switch (outputFormat) + { + case "HEX": + formatFunc = binb2hex; + break; + case "B64": + formatFunc = binb2b64; + break; + default: + return "FORMAT NOT RECOGNIZED"; + } + + if ("HEX" === inputFormat) + { + if (0 !== (key.length % 2)) + { + return "KEY MUST BE IN BYTE INCREMENTS"; + } + keyToUse = hex2binb(key); + keyBinLen = key.length * 4; + } + else if ("ASCII" === inputFormat) + { + keyToUse = str2binb(key); + keyBinLen = key.length * charSize; + } + else + { + return "UNKNOWN KEY INPUT TYPE"; + } - retVal = coreSHA1(keyWithIPad.concat(strToHash), 512 + strBinLen); - retVal = coreSHA1(keyWithOPad.concat(retVal), 672); + if (64 < (keyBinLen / 8)) + { + keyToUse = coreSHA1(keyToUse, keyBinLen); + keyToUse[15] &= 0xFFFFFF00; + } + else if (64 > (keyBinLen / 8)) + { + keyToUse[15] &= 0xFFFFFF00; + } + + for (i = 0; i <= 15; i += 1) + { + keyWithIPad[i] = keyToUse[i] ^ 0x36363636; + keyWithOPad[i] = keyToUse[i] ^ 0x5C5C5C5C; + } - return (formatFunc(retVal)); + retVal = coreSHA1( + keyWithIPad.concat(this.strToHash), + 512 + this.strBinLen); + retVal = coreSHA1(keyWithOPad.concat(retVal), 672); + + return (formatFunc(retVal)); + } }; -} + + window.jsSHA = jsSHA; +}()); + |