/* 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
 * Distributed under the BSD License
 * See http://jssha.sourceforge.net/ for more information
 *
 * Several functions taken from Paul Johnson
 */

function jsSHA(k,l){jsSHA.charSize=8;jsSHA.b64pad="";jsSHA.hexCase=0;var m=null;var o=function(a){var b=[];var c=(1<<jsSHA.charSize)-1;var d=a.length*jsSHA.charSize;for(var i=0;i<d;i+=jsSHA.charSize){b[i>>5]|=(a.charCodeAt(i/jsSHA.charSize)&c)<<(32-jsSHA.charSize-i%32)}return b};var p=function(a){var b=[];var c=a.length;for(var i=0;i<c;i+=2){var d=parseInt(a.substr(i,2),16);if(!isNaN(d)){b[i>>3]|=d<<(24-(4*(i%8)))}else{return"INVALID HEX STRING"}}return b};var q=null;var r=null;if("HEX"===l){if(0!==(k.length%2)){return"TEXT MUST BE IN BYTE INCREMENTS"}q=k.length*4;r=p(k)}else if(("ASCII"===l)||('undefined'===typeof(l))){q=k.length*jsSHA.charSize;r=o(k)}else{return"UNKNOWN TEXT INPUT TYPE"}var s=function(a){var b=jsSHA.hexCase?"0123456789ABCDEF":"0123456789abcdef";var c="";var d=a.length*4;for(var i=0;i<d;i++){c+=b.charAt((a[i>>2]>>((3-i%4)*8+4))&0xF)+b.charAt((a[i>>2]>>((3-i%4)*8))&0xF)}return c};var u=function(a){var b="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";var c="";var d=a.length*4;for(var i=0;i<d;i+=3){var e=(((a[i>>2]>>8*(3-i%4))&0xFF)<<16)|(((a[i+1>>2]>>8*(3-(i+1)%4))&0xFF)<<8)|((a[i+2>>2]>>8*(3-(i+2)%4))&0xFF);for(var j=0;j<4;j++){if(i*8+j*6>a.length*32){c+=jsSHA.b64pad}else{c+=b.charAt((e>>6*(3-j))&0x3F)}}}return c};var v=function(x,n){if(n<32){return(x<<n)|(x>>>(32-n))}else{return x}};var w=function(x,y,z){return x^y^z};var A=function(x,y,z){return(x&y)^(~x&z)};var B=function(x,y,z){return(x&y)^(x&z)^(y&z)};var C=function(x,y){var a=(x&0xFFFF)+(y&0xFFFF);var b=(x>>>16)+(y>>>16)+(a>>>16);return((b&0xFFFF)<<16)|(a&0xFFFF)};var D=function(a,b,c,d,e){var f=(a&0xFFFF)+(b&0xFFFF)+(c&0xFFFF)+(d&0xFFFF)+(e&0xFFFF);var g=(a>>>16)+(b>>>16)+(c>>>16)+(d>>>16)+(e>>>16)+(f>>>16);return((g&0xFFFF)<<16)|(f&0xFFFF)};var E=function(f,g){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];f[g>>5]|=0x80<<(24-g%32);f[((g+1+64>>9)<<4)+15]=g;var h=f.length;for(var i=0;i<h;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){W[t]=f[t+i]}else{W[t]=v(W[t-3]^W[t-8]^W[t-14]^W[t-16],1)}if(t<20){T=D(v(a,5),A(b,c,d),e,K[t],W[t])}else if(t<40){T=D(v(a,5),w(b,c,d),e,K[t],W[t])}else if(t<60){T=D(v(a,5),B(b,c,d),e,K[t],W[t])}else{T=D(v(a,5),w(b,c,d),e,K[t],W[t])}e=d;d=c;c=v(b,30);b=a;a=T}H[0]=C(a,H[0]);H[1]=C(b,H[1]);H[2]=C(c,H[2]);H[3]=C(d,H[3]);H[4]=C(e,H[4])}return H};this.getHash=function(a){var b=null;var c=r.slice();if(m===null){m=m=E(c,q)}switch(a){case"HEX":b=s;break;case"B64":b=u;break;default:return"FORMAT NOT RECOGNIZED"}return b(m)};this.getHMAC=function(a,b,c){var d=null;var e=null;var f=[];var g=[];var h=null;var j=null;switch(c){case"HEX":d=s;break;case"B64":d=u;break;default:return"FORMAT NOT RECOGNIZED"}if("HEX"===b){if(0!==(a.length%2)){return"KEY MUST BE IN BYTE INCREMENTS"}e=p(a);j=a.length*4}else if("ASCII"===b){e=o(a);j=a.length*jsSHA.charSize}else{return"UNKNOWN KEY INPUT TYPE"}if(512<j){e=E(e,j);e[15]&=0xFFFFFF00}else if(512>j){e[15]&=0xFFFFFF00}for(var i=0;i<=15;i++){f[i]=e[i]^0x36363636;g[i]=e[i]^0x5C5C5C5C}h=E(f.concat(r),512+q);h=E(g.concat(h),672);return(d(h))}}
