diff options
author | Brian Turek <brian.turek@gmail.com> | 2015-06-13 07:29:52 -0400 |
---|---|---|
committer | Brian Turek <brian.turek@gmail.com> | 2015-06-13 07:29:52 -0400 |
commit | 386bac08228cfd470e46d4668d1dd8bb4f4053c3 (patch) | |
tree | 2a1be7d6c28edcf9c90592622caa3a8a21552c4c | |
parent | 3c1d4f2e65d19577a647732811cc6a875b29fcb9 (diff) | |
parent | b202bf60dcf42973ade5f5421849ee83712f5dcd (diff) | |
download | jsSHA-386bac08228cfd470e46d4668d1dd8bb4f4053c3.zip jsSHA-386bac08228cfd470e46d4668d1dd8bb4f4053c3.tar.gz jsSHA-386bac08228cfd470e46d4668d1dd8bb4f4053c3.tar.bz2 |
Merge streaming
-rw-r--r-- | CHANGELOG | 5 | ||||
-rw-r--r-- | README.md | 69 | ||||
-rw-r--r-- | src/sha.js | 51 | ||||
-rw-r--r-- | src/sha1.js | 23 | ||||
-rw-r--r-- | src/sha256.js | 30 | ||||
-rw-r--r-- | src/sha512.js | 44 | ||||
-rw-r--r-- | src/sha_dev.js | 1211 | ||||
-rw-r--r-- | test/test.html | 105 |
8 files changed, 877 insertions, 661 deletions
@@ -1,6 +1,11 @@ ------------------------- jsSHA - ChangeLog ------------------------- +2.0.0 (2015-XX-XX) +========================= +- Completely reworked API to support streaming inputs +- Exceptions now throw Errors instead of strings (thanks jclem!) + 1.6.0 (2015-03-08) ========================= This marks the last v1.X new feature release. The API is changing @@ -69,32 +69,45 @@ in your header (sha.js used below): <script type="text/javascript" src="/path/to/sha.js"></script> -Instantiate a new jsSHA object with your string to be hashed and its format -(HEX or TEXT) as the parameters. Then, call getHash with the desired hash -variant (SHA-1, SHA-224, SHA-256, SHA-384, or SHA-512) and output type -(HEX or B64). - -In the example below, "This is a Test" and "SHA-512" were used -as the string to be hashed and variant respectively. Also, the HMAC using TEXT -key "SecretKey" and hashing algorithm SHA-512 was calculated. - - var shaObj = new jsSHA("This is a Test", "TEXT"); - var hash = shaObj.getHash("SHA-512", "HEX"); - var hmac = shaObj.getHMAC("SecretKey", "TEXT", "SHA-512", "HEX"); - -The constructor takes an optional parameter, encoding, that specifies the -encoding used to encode TEXT-type inputs. Valid options are "UTF8", "UTF16BE", -and "UTF16LE", it defaults to "UTF8" - -getHash takes two optional parameters, a numRounds integer and an outputFormatOpts -hashlist. numRounds controls the number of hashing iterations/rounds performed -and defaults to a value of "1" if not specified. outputFormatOpts dictates -some formatting options for the output. By default, -`outputFormatOpts = {"outputUpper" : false, "b64Pad" : "="}`. These -options are intelligently interpreted based upon the chosen output format. - -getHMAC also takes an optional outputFormatOpts hashlist which operates the exact -same way as above. +#### Hashing +Instantiate a new jsSHA object with the desired hash type, input type, and +options as parameters. The hash type can be one of SHA-1, SHA-224, SHA-256, +SHA-384, or SHA-512. The input type can be one of HEX, TEXT, B64, or BYTES. +You can then stream in input using the "update" object function. Finally, +simply call "getHash" with the output type as a parameter (B64, HEX, or BYTES). +Example to calculate the SHA-512 of "This is a test": + + var shaObj = new jsSHA("SHA-512", "TEXT"); + shaObj.update("This is a test"); + var hash = shaObj.getHash("HEX"); + +The constructor takes a hashmap as a optional third argument with possible +properties of "numRounds" and "encoding". numRounds controls the number of +hashing iterations/rounds performed and defaults to a value of "1" if not +specified. encoding specifies the encoding used to encode TEXT-type inputs. +Valid options are "UTF8", "UTF16BE", and "UTF16LE", it defaults to "UTF8". + +getHash also takes a hashmap as an optional second argument. By default the +hashmap is `{"outputUpper" : false, "b64Pad" : "="}`. These options are +intelligently interpreted based upon the chosen output format. + +#### HMAC +Instantiate a new jsSHA object the same way as for hashing. Then set the HMAC +key to be used by calling "setHMACKey" with the key and its input type (this +MUST be done before calling update). You can stream in the input using the +"update" object function just like hashing. Finally, get the HMAC by calling +the "getHMAC" function with the output type as its argument. Example to +calculate the SHA-512 HMAC of the string "This is a test" with the key "abc": + + var shaObj = new jsSHA(hashType, "TEXT"); + shaObj.setHMACKey("abc", "TEXT"); + shaObj.update("This is a test"); + var hmac = shaObj.getHMAC("HEX"); + +setHMACKey takes the same input types as the constructor and getHMAC takes the +same inputs as "getHash" as described above. + +Note: You cannot calculate both the hash and HMAC using the same object. ### Node.js jsSHA is available through NPM and be installed by simply doing @@ -116,12 +129,12 @@ a command like the following: --externs /path/to/build/externs.js --warning_level VERBOSE \ --compilation_level ADVANCED_OPTIMIZATIONS \ --js /path/to/sha_dev.js --js_output_file /path/to/sha.js - + where FLAG is a bitwise OR of the following values: * 4 for SHA-384/SHA-512 * 2 for SHA-224/256 * 1 for SHA-1 -##Contact Info +## Contact Info The project's website is located at [http://caligatio.github.com/jsSHA/](http://caligatio.github.com/jsSHA/) @@ -9,28 +9,29 @@ Several functions taken from Paul Johnston */ -'use strict';(function(U){function z(a,b,c){var e=0,f=[0],k="",h=null,k=c||"UTF8";if("UTF8"!==k&&"UTF16BE"!==k&&"UTF16LE"!==k)throw"encoding must be UTF8, UTF16BE, or UTF16LE";if("HEX"===b){if(0!==a.length%2)throw"srcString of HEX type must be in byte increments";h=D(a);e=h.binLen;f=h.value}else if("TEXT"===b||"ASCII"===b)h=L(a,k),e=h.binLen,f=h.value;else if("B64"===b)h=M(a),e=h.binLen,f=h.value;else if("BYTES"===b)h=N(a),e=h.binLen,f=h.value;else throw"inputFormat must be HEX, TEXT, ASCII, B64, or BYTES"; -this.getHash=function(a,b,c,k){var h=null,d=f.slice(),n=e,m;3===arguments.length?"number"!==typeof c&&(k=c,c=1):2===arguments.length&&(c=1);if(c!==parseInt(c,10)||1>c)throw"numRounds must a integer >= 1";switch(b){case "HEX":h=O;break;case "B64":h=P;break;case "BYTES":h=Q;break;default:throw"format must be HEX, B64, or BYTES";}if("SHA-1"===a)for(m=0;m<c;m+=1)d=A(d,n),n=160;else if("SHA-224"===a)for(m=0;m<c;m+=1)d=w(d,n,a),n=224;else if("SHA-256"===a)for(m=0;m<c;m+=1)d=w(d,n,a),n=256;else if("SHA-384"=== -a)for(m=0;m<c;m+=1)d=w(d,n,a),n=384;else if("SHA-512"===a)for(m=0;m<c;m+=1)d=w(d,n,a),n=512;else throw"Chosen SHA variant is not supported";return h(d,R(k))};this.getHMAC=function(a,b,c,h,q){var d,n,m,t,r=[],u=[];d=null;switch(h){case "HEX":h=O;break;case "B64":h=P;break;case "BYTES":h=Q;break;default:throw"outputFormat must be HEX, B64, or BYTES";}if("SHA-1"===c)n=64,t=160;else if("SHA-224"===c)n=64,t=224;else if("SHA-256"===c)n=64,t=256;else if("SHA-384"===c)n=128,t=384;else if("SHA-512"===c)n= -128,t=512;else throw"Chosen SHA variant is not supported";if("HEX"===b)d=D(a),m=d.binLen,d=d.value;else if("TEXT"===b||"ASCII"===b)d=L(a,k),m=d.binLen,d=d.value;else if("B64"===b)d=M(a),m=d.binLen,d=d.value;else if("BYTES"===b)d=N(a),m=d.binLen,d=d.value;else throw"inputFormat must be HEX, TEXT, ASCII, B64, or BYTES";a=8*n;b=n/4-1;if(n<m/8){for(d="SHA-1"===c?A(d,m):w(d,m,c);d.length<=b;)d.push(0);d[b]&=4294967040}else if(n>m/8){for(;d.length<=b;)d.push(0);d[b]&=4294967040}for(n=0;n<=b;n+=1)r[n]=d[n]^ -909522486,u[n]=d[n]^1549556828;c="SHA-1"===c?A(u.concat(A(r.concat(f),a+e)),a+t):w(u.concat(w(r.concat(f),a+e,c)),a+t,c);return h(c,R(q))}}function q(a,b){this.a=a;this.b=b}function L(a,b){var c=[],e,f=[],k=0,h,p,q;if("UTF8"===b)for(h=0;h<a.length;h+=1)for(e=a.charCodeAt(h),f=[],128>e?f.push(e):2048>e?(f.push(192|e>>>6),f.push(128|e&63)):55296>e||57344<=e?f.push(224|e>>>12,128|e>>>6&63,128|e&63):(h+=1,e=65536+((e&1023)<<10|a.charCodeAt(h)&1023),f.push(240|e>>>18,128|e>>>12&63,128|e>>>6&63,128|e&63)), -p=0;p<f.length;p+=1){for(q=k>>>2;c.length<=q;)c.push(0);c[q]|=f[p]<<24-k%4*8;k+=1}else if("UTF16BE"===b||"UTF16LE"===b)for(h=0;h<a.length;h+=1){e=a.charCodeAt(h);"UTF16LE"===b&&(p=e&255,e=p<<8|e>>8);for(q=k>>>2;c.length<=q;)c.push(0);c[q]|=e<<16-k%4*8;k+=2}return{value:c,binLen:8*k}}function D(a){var b=[],c=a.length,e,f,k;if(0!==c%2)throw"String of HEX type must be in byte increments";for(e=0;e<c;e+=2){f=parseInt(a.substr(e,2),16);if(isNaN(f))throw"String of HEX type contains invalid characters"; -for(k=e>>>3;b.length<=k;)b.push(0);b[e>>>3]|=f<<24-e%8*4}return{value:b,binLen:4*c}}function N(a){var b=[],c,e,f;for(e=0;e<a.length;e+=1)c=a.charCodeAt(e),f=e>>>2,b.length<=f&&b.push(0),b[f]|=c<<24-e%4*8;return{value:b,binLen:8*a.length}}function M(a){var b=[],c=0,e,f,k,h,p;if(-1===a.search(/^[a-zA-Z0-9=+\/]+$/))throw"Invalid character in base-64 string";f=a.indexOf("=");a=a.replace(/\=/g,"");if(-1!==f&&f<a.length)throw"Invalid '=' found in base-64 string";for(f=0;f<a.length;f+=4){p=a.substr(f,4); -for(k=h=0;k<p.length;k+=1)e="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/".indexOf(p[k]),h|=e<<18-6*k;for(k=0;k<p.length-1;k+=1){for(e=c>>>2;b.length<=e;)b.push(0);b[e]|=(h>>>16-8*k&255)<<24-c%4*8;c+=1}}return{value:b,binLen:8*c}}function O(a,b){var c="",e=4*a.length,f,k;for(f=0;f<e;f+=1)k=a[f>>>2]>>>8*(3-f%4),c+="0123456789abcdef".charAt(k>>>4&15)+"0123456789abcdef".charAt(k&15);return b.outputUpper?c.toUpperCase():c}function P(a,b){var c="",e=4*a.length,f,k,h;for(f=0;f<e;f+= -3)for(h=f+1>>>2,k=a.length<=h?0:a[h],h=f+2>>>2,h=a.length<=h?0:a[h],h=(a[f>>>2]>>>8*(3-f%4)&255)<<16|(k>>>8*(3-(f+1)%4)&255)<<8|h>>>8*(3-(f+2)%4)&255,k=0;4>k;k+=1)c=8*f+6*k<=32*a.length?c+"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/".charAt(h>>>6*(3-k)&63):c+b.b64Pad;return c}function Q(a){var b="",c=4*a.length,e,f;for(e=0;e<c;e+=1)f=a[e>>>2]>>>8*(3-e%4)&255,b+=String.fromCharCode(f);return b}function R(a){var b={outputUpper:!1,b64Pad:"="};try{a.hasOwnProperty("outputUpper")&& -(b.outputUpper=a.outputUpper),a.hasOwnProperty("b64Pad")&&(b.b64Pad=a.b64Pad)}catch(c){}if("boolean"!==typeof b.outputUpper)throw"Invalid outputUpper formatting option";if("string"!==typeof b.b64Pad)throw"Invalid b64Pad formatting option";return b}function x(a,b){return a<<b|a>>>32-b}function r(a,b){return a>>>b|a<<32-b}function u(a,b){var c=null,c=new q(a.a,a.b);return c=32>=b?new q(c.a>>>b|c.b<<32-b&4294967295,c.b>>>b|c.a<<32-b&4294967295):new q(c.b>>>b-32|c.a<<64-b&4294967295,c.a>>>b-32|c.b<<64- -b&4294967295)}function S(a,b){var c=null;return c=32>=b?new q(a.a>>>b,a.b>>>b|a.a<<32-b&4294967295):new q(0,a.a>>>b-32)}function V(a,b,c){return a&b^~a&c}function W(a,b,c){return new q(a.a&b.a^~a.a&c.a,a.b&b.b^~a.b&c.b)}function T(a,b,c){return a&b^a&c^b&c}function X(a,b,c){return new q(a.a&b.a^a.a&c.a^b.a&c.a,a.b&b.b^a.b&c.b^b.b&c.b)}function Y(a){return r(a,2)^r(a,13)^r(a,22)}function Z(a){var b=u(a,28),c=u(a,34);a=u(a,39);return new q(b.a^c.a^a.a,b.b^c.b^a.b)}function $(a){return r(a,6)^r(a,11)^ -r(a,25)}function aa(a){var b=u(a,14),c=u(a,18);a=u(a,41);return new q(b.a^c.a^a.a,b.b^c.b^a.b)}function ba(a){return r(a,7)^r(a,18)^a>>>3}function ca(a){var b=u(a,1),c=u(a,8);a=S(a,7);return new q(b.a^c.a^a.a,b.b^c.b^a.b)}function da(a){return r(a,17)^r(a,19)^a>>>10}function ea(a){var b=u(a,19),c=u(a,61);a=S(a,6);return new q(b.a^c.a^a.a,b.b^c.b^a.b)}function C(a,b){var c=(a&65535)+(b&65535);return((a>>>16)+(b>>>16)+(c>>>16)&65535)<<16|c&65535}function fa(a,b,c,e){var f=(a&65535)+(b&65535)+(c&65535)+ -(e&65535);return((a>>>16)+(b>>>16)+(c>>>16)+(e>>>16)+(f>>>16)&65535)<<16|f&65535}function E(a,b,c,e,f){var k=(a&65535)+(b&65535)+(c&65535)+(e&65535)+(f&65535);return((a>>>16)+(b>>>16)+(c>>>16)+(e>>>16)+(f>>>16)+(k>>>16)&65535)<<16|k&65535}function ga(a,b){var c,e,f;c=(a.b&65535)+(b.b&65535);e=(a.b>>>16)+(b.b>>>16)+(c>>>16);f=(e&65535)<<16|c&65535;c=(a.a&65535)+(b.a&65535)+(e>>>16);e=(a.a>>>16)+(b.a>>>16)+(c>>>16);return new q((e&65535)<<16|c&65535,f)}function ha(a,b,c,e){var f,k,h;f=(a.b&65535)+(b.b& -65535)+(c.b&65535)+(e.b&65535);k=(a.b>>>16)+(b.b>>>16)+(c.b>>>16)+(e.b>>>16)+(f>>>16);h=(k&65535)<<16|f&65535;f=(a.a&65535)+(b.a&65535)+(c.a&65535)+(e.a&65535)+(k>>>16);k=(a.a>>>16)+(b.a>>>16)+(c.a>>>16)+(e.a>>>16)+(f>>>16);return new q((k&65535)<<16|f&65535,h)}function ia(a,b,c,e,f){var k,h,p;k=(a.b&65535)+(b.b&65535)+(c.b&65535)+(e.b&65535)+(f.b&65535);h=(a.b>>>16)+(b.b>>>16)+(c.b>>>16)+(e.b>>>16)+(f.b>>>16)+(k>>>16);p=(h&65535)<<16|k&65535;k=(a.a&65535)+(b.a&65535)+(c.a&65535)+(e.a&65535)+(f.a& -65535)+(h>>>16);h=(a.a>>>16)+(b.a>>>16)+(c.a>>>16)+(e.a>>>16)+(f.a>>>16)+(k>>>16);return new q((h&65535)<<16|k&65535,p)}function A(a,b){var c=[],e,f,k,h,p,q,r,s,u,d=[1732584193,4023233417,2562383102,271733878,3285377520];for(e=(b+65>>>9<<4)+15;a.length<=e;)a.push(0);a[b>>>5]|=128<<24-b%32;a[e]=b;u=a.length;for(r=0;r<u;r+=16){e=d[0];f=d[1];k=d[2];h=d[3];p=d[4];for(s=0;80>s;s+=1)c[s]=16>s?a[s+r]:x(c[s-3]^c[s-8]^c[s-14]^c[s-16],1),q=20>s?E(x(e,5),f&k^~f&h,p,1518500249,c[s]):40>s?E(x(e,5),f^k^h,p,1859775393, -c[s]):60>s?E(x(e,5),T(f,k,h),p,2400959708,c[s]):E(x(e,5),f^k^h,p,3395469782,c[s]),p=h,h=k,k=x(f,30),f=e,e=q;d[0]=C(e,d[0]);d[1]=C(f,d[1]);d[2]=C(k,d[2]);d[3]=C(h,d[3]);d[4]=C(p,d[4])}return d}function w(a,b,c){var e,f,k,h,p,r,u,s,y,d,n,m,t,w,x,v,z,A,F,G,H,I,J,K,g,B=[],D,l=[1116352408,1899447441,3049323471,3921009573,961987163,1508970993,2453635748,2870763221,3624381080,310598401,607225278,1426881987,1925078388,2162078206,2614888103,3248222580,3835390401,4022224774,264347078,604807628,770255983,1249150122, -1555081692,1996064986,2554220882,2821834349,2952996808,3210313671,3336571891,3584528711,113926993,338241895,666307205,773529912,1294757372,1396182291,1695183700,1986661051,2177026350,2456956037,2730485921,2820302411,3259730800,3345764771,3516065817,3600352804,4094571909,275423344,430227734,506948616,659060556,883997877,958139571,1322822218,1537002063,1747873779,1955562222,2024104815,2227730452,2361852424,2428436474,2756734187,3204031479,3329325298];d=[3238371032,914150663,812702999,4144912697,4290775857, -1750603025,1694076839,3204075428];f=[1779033703,3144134277,1013904242,2773480762,1359893119,2600822924,528734635,1541459225];if("SHA-224"===c||"SHA-256"===c)n=64,e=(b+65>>>9<<4)+15,w=16,x=1,g=Number,v=C,z=fa,A=E,F=ba,G=da,H=Y,I=$,K=T,J=V,d="SHA-224"===c?d:f;else if("SHA-384"===c||"SHA-512"===c)n=80,e=(b+128>>>10<<5)+31,w=32,x=2,g=q,v=ga,z=ha,A=ia,F=ca,G=ea,H=Z,I=aa,K=X,J=W,l=[new g(l[0],3609767458),new g(l[1],602891725),new g(l[2],3964484399),new g(l[3],2173295548),new g(l[4],4081628472),new g(l[5], -3053834265),new g(l[6],2937671579),new g(l[7],3664609560),new g(l[8],2734883394),new g(l[9],1164996542),new g(l[10],1323610764),new g(l[11],3590304994),new g(l[12],4068182383),new g(l[13],991336113),new g(l[14],633803317),new g(l[15],3479774868),new g(l[16],2666613458),new g(l[17],944711139),new g(l[18],2341262773),new g(l[19],2007800933),new g(l[20],1495990901),new g(l[21],1856431235),new g(l[22],3175218132),new g(l[23],2198950837),new g(l[24],3999719339),new g(l[25],766784016),new g(l[26],2566594879), -new g(l[27],3203337956),new g(l[28],1034457026),new g(l[29],2466948901),new g(l[30],3758326383),new g(l[31],168717936),new g(l[32],1188179964),new g(l[33],1546045734),new g(l[34],1522805485),new g(l[35],2643833823),new g(l[36],2343527390),new g(l[37],1014477480),new g(l[38],1206759142),new g(l[39],344077627),new g(l[40],1290863460),new g(l[41],3158454273),new g(l[42],3505952657),new g(l[43],106217008),new g(l[44],3606008344),new g(l[45],1432725776),new g(l[46],1467031594),new g(l[47],851169720),new g(l[48], -3100823752),new g(l[49],1363258195),new g(l[50],3750685593),new g(l[51],3785050280),new g(l[52],3318307427),new g(l[53],3812723403),new g(l[54],2003034995),new g(l[55],3602036899),new g(l[56],1575990012),new g(l[57],1125592928),new g(l[58],2716904306),new g(l[59],442776044),new g(l[60],593698344),new g(l[61],3733110249),new g(l[62],2999351573),new g(l[63],3815920427),new g(3391569614,3928383900),new g(3515267271,566280711),new g(3940187606,3454069534),new g(4118630271,4000239992),new g(116418474, -1914138554),new g(174292421,2731055270),new g(289380356,3203993006),new g(460393269,320620315),new g(685471733,587496836),new g(852142971,1086792851),new g(1017036298,365543100),new g(1126000580,2618297676),new g(1288033470,3409855158),new g(1501505948,4234509866),new g(1607167915,987167468),new g(1816402316,1246189591)],d="SHA-384"===c?[new g(3418070365,d[0]),new g(1654270250,d[1]),new g(2438529370,d[2]),new g(355462360,d[3]),new g(1731405415,d[4]),new g(41048885895,d[5]),new g(3675008525,d[6]), -new g(1203062813,d[7])]:[new g(f[0],4089235720),new g(f[1],2227873595),new g(f[2],4271175723),new g(f[3],1595750129),new g(f[4],2917565137),new g(f[5],725511199),new g(f[6],4215389547),new g(f[7],327033209)];else throw"Unexpected error in SHA-2 implementation";for(;a.length<=e;)a.push(0);a[b>>>5]|=128<<24-b%32;a[e]=b;D=a.length;for(m=0;m<D;m+=w){b=d[0];e=d[1];f=d[2];k=d[3];h=d[4];p=d[5];r=d[6];u=d[7];for(t=0;t<n;t+=1)16>t?(y=t*x+m,s=a.length<=y?0:a[y],y=a.length<=y+1?0:a[y+1],B[t]=new g(s,y)):B[t]= -z(G(B[t-2]),B[t-7],F(B[t-15]),B[t-16]),s=A(u,I(h),J(h,p,r),l[t],B[t]),y=v(H(b),K(b,e,f)),u=r,r=p,p=h,h=v(k,s),k=f,f=e,e=b,b=v(s,y);d[0]=v(b,d[0]);d[1]=v(e,d[1]);d[2]=v(f,d[2]);d[3]=v(k,d[3]);d[4]=v(h,d[4]);d[5]=v(p,d[5]);d[6]=v(r,d[6]);d[7]=v(u,d[7])}if("SHA-224"===c)a=[d[0],d[1],d[2],d[3],d[4],d[5],d[6]];else if("SHA-256"===c)a=d;else if("SHA-384"===c)a=[d[0].a,d[0].b,d[1].a,d[1].b,d[2].a,d[2].b,d[3].a,d[3].b,d[4].a,d[4].b,d[5].a,d[5].b];else if("SHA-512"===c)a=[d[0].a,d[0].b,d[1].a,d[1].b,d[2].a, -d[2].b,d[3].a,d[3].b,d[4].a,d[4].b,d[5].a,d[5].b,d[6].a,d[6].b,d[7].a,d[7].b];else throw"Unexpected error in SHA-2 implementation";return a}"function"===typeof define&&define.amd?define(function(){return z}):"undefined"!==typeof exports?"undefined"!==typeof module&&module.exports?module.exports=exports=z:exports=z:U.jsSHA=z})(this); +'use strict';(function(T){function y(c,a,d){var b=0,f=[],k=0,g,e,n,h,m,u,r,p=!1,q=!1,t=[],v=[],x,w=!1;d=d||{};g=d.encoding||"UTF8";x=d.numRounds||1;n=J(a,g);if(x!==parseInt(x,10)||1>x)throw Error("numRounds must a integer >= 1");if("SHA-1"===c)m=512,u=K,r=U,h=160;else if(u=function(a,d){return L(a,d,c)},r=function(a,d,b,f){var k,e;if("SHA-224"===c||"SHA-256"===c)k=(d+72>>>9<<4)+15,e=16;else if("SHA-384"===c||"SHA-512"===c)k=(d+136>>>10<<5)+31,e=32;else throw Error("Unexpected error in SHA-2 implementation"); +for(;a.length<=k;)a.push(0);a[d>>>5]|=128<<24-d%32;a[k]=d+b;b=a.length;for(d=0;d<b;d+=e)f=L(a.slice(d,d+e),f,c);if("SHA-224"===c)a=[f[0],f[1],f[2],f[3],f[4],f[5],f[6]];else if("SHA-256"===c)a=f;else if("SHA-384"===c)a=[f[0].a,f[0].b,f[1].a,f[1].b,f[2].a,f[2].b,f[3].a,f[3].b,f[4].a,f[4].b,f[5].a,f[5].b];else if("SHA-512"===c)a=[f[0].a,f[0].b,f[1].a,f[1].b,f[2].a,f[2].b,f[3].a,f[3].b,f[4].a,f[4].b,f[5].a,f[5].b,f[6].a,f[6].b,f[7].a,f[7].b];else throw Error("Unexpected error in SHA-2 implementation"); +return a},"SHA-224"===c)m=512,h=224;else if("SHA-256"===c)m=512,h=256;else if("SHA-384"===c)m=1024,h=384;else if("SHA-512"===c)m=1024,h=512;else throw Error("Chosen SHA variant is not supported");e=z(c);this.setHMACKey=function(a,d,f){var k;if(!0===q)throw Error("HMAC key already set");if(!0===p)throw Error("Cannot set HMAC key after finalizing hash");if(!0===w)throw Error("Cannot set HMAC key after calling update");g=(f||{}).encoding||"UTF8";d=J(d,g)(a);a=d.binLen;d=d.value;k=m>>>3;f=k/4-1;if(k< +a/8){for(d=r(d,a,0,z(c));d.length<=f;)d.push(0);d[f]&=4294967040}else if(k>a/8){for(;d.length<=f;)d.push(0);d[f]&=4294967040}for(a=0;a<=f;a+=1)t[a]=d[a]^909522486,v[a]=d[a]^1549556828;e=u(t,e);b=m;q=!0};this.update=function(a){var c,d,g,h=0,p=m>>>5;c=n(a,f,k);a=c.binLen;d=c.value;c=a>>>5;for(g=0;g<c;g+=p)h+m<=a&&(e=u(d.slice(g,g+p),e),h+=m);b+=h;f=d.slice(h>>>5);k=a%m;w=!0};this.getHash=function(a,d){var g,m,n;if(!0===q)throw Error("Cannot call getHash after setting HMAC key");n=M(d);switch(a){case "HEX":g= +function(a){return N(a,n)};break;case "B64":g=function(a){return O(a,n)};break;case "BYTES":g=P;break;default:throw Error("format must be HEX, B64, or BYTES");}if(!1===p)for(e=r(f,k,b,e),m=1;m<x;m+=1)e=r(e,h,0,z(c));p=!0;return g(e)};this.getHMAC=function(a,d){var g,n,t;if(!1===q)throw Error("Cannot call getHMAC without first setting HMAC key");t=M(d);switch(a){case "HEX":g=function(a){return N(a,t)};break;case "B64":g=function(a){return O(a,t)};break;case "BYTES":g=P;break;default:throw Error("outputFormat must be HEX, B64, or BYTES"); +}!1===p&&(n=r(f,k,b,e),e=u(v,z(c)),e=r(n,h,m,e));p=!0;return g(e)}}function b(c,a){this.a=c;this.b=a}function V(c,a,d){var b=c.length,f,k,e,l,n;a=a||[0];d=d||0;n=d>>>3;if(0!==b%2)throw Error("String of HEX type must be in byte increments");for(f=0;f<b;f+=2){k=parseInt(c.substr(f,2),16);if(isNaN(k))throw Error("String of HEX type contains invalid characters");l=(f>>>1)+n;for(e=l>>>2;a.length<=e;)a.push(0);a[e]|=k<<8*(3-l%4)}return{value:a,binLen:4*b+d}}function W(c,a,d){var b=[],f,k,e,l,b=a||[0];d= +d||0;k=d>>>3;for(f=0;f<c.length;f+=1)a=c.charCodeAt(f),l=f+k,e=l>>>2,b.length<=e&&b.push(0),b[e]|=a<<8*(3-l%4);return{value:b,binLen:8*c.length+d}}function X(c,a,d){var b=[],f=0,e,g,l,n,h,m,b=a||[0];d=d||0;a=d>>>3;if(-1===c.search(/^[a-zA-Z0-9=+\/]+$/))throw Error("Invalid character in base-64 string");g=c.indexOf("=");c=c.replace(/\=/g,"");if(-1!==g&&g<c.length)throw Error("Invalid '=' found in base-64 string");for(g=0;g<c.length;g+=4){h=c.substr(g,4);for(l=n=0;l<h.length;l+=1)e="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/".indexOf(h[l]), +n|=e<<18-6*l;for(l=0;l<h.length-1;l+=1){m=f+a;for(e=m>>>2;b.length<=e;)b.push(0);b[e]|=(n>>>16-8*l&255)<<8*(3-m%4);f+=1}}return{value:b,binLen:8*f+d}}function N(c,a){var d="",b=4*c.length,f,e;for(f=0;f<b;f+=1)e=c[f>>>2]>>>8*(3-f%4),d+="0123456789abcdef".charAt(e>>>4&15)+"0123456789abcdef".charAt(e&15);return a.outputUpper?d.toUpperCase():d}function O(c,a){var d="",b=4*c.length,f,e,g;for(f=0;f<b;f+=3)for(g=f+1>>>2,e=c.length<=g?0:c[g],g=f+2>>>2,g=c.length<=g?0:c[g],g=(c[f>>>2]>>>8*(3-f%4)&255)<<16| +(e>>>8*(3-(f+1)%4)&255)<<8|g>>>8*(3-(f+2)%4)&255,e=0;4>e;e+=1)8*f+6*e<=32*c.length?d+="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/".charAt(g>>>6*(3-e)&63):d+=a.b64Pad;return d}function P(c){var a="",d=4*c.length,b,f;for(b=0;b<d;b+=1)f=c[b>>>2]>>>8*(3-b%4)&255,a+=String.fromCharCode(f);return a}function M(c){var a={outputUpper:!1,b64Pad:"="};c=c||{};a.outputUpper=c.outputUpper||!1;a.b64Pad=c.b64Pad||"=";if("boolean"!==typeof a.outputUpper)throw Error("Invalid outputUpper formatting option"); +if("string"!==typeof a.b64Pad)throw Error("Invalid b64Pad formatting option");return a}function J(c,a){var d;switch(a){case "UTF8":case "UTF16BE":case "UTF16LE":break;default:throw Error("encoding must be UTF8, UTF16BE, or UTF16LE");}switch(c){case "HEX":d=V;break;case "TEXT":d=function(c,d,b){var e=[],l=[],n=0,h,m,u,r,p,e=d||[0];d=b||0;u=d>>>3;if("UTF8"===a)for(h=0;h<c.length;h+=1)for(b=c.charCodeAt(h),l=[],128>b?l.push(b):2048>b?(l.push(192|b>>>6),l.push(128|b&63)):55296>b||57344<=b?l.push(224| +b>>>12,128|b>>>6&63,128|b&63):(h+=1,b=65536+((b&1023)<<10|c.charCodeAt(h)&1023),l.push(240|b>>>18,128|b>>>12&63,128|b>>>6&63,128|b&63)),m=0;m<l.length;m+=1){p=n+u;for(r=p>>>2;e.length<=r;)e.push(0);e[r]|=l[m]<<8*(3-p%4);n+=1}else if("UTF16BE"===a||"UTF16LE"===a)for(h=0;h<c.length;h+=1){b=c.charCodeAt(h);"UTF16LE"===a&&(m=b&255,b=m<<8|b>>>8);p=n+u;for(r=p>>>2;e.length<=r;)e.push(0);e[r]|=b<<8*(2-p%4);n+=2}return{value:e,binLen:8*n+d}};break;case "B64":d=X;break;case "BYTES":d=W;break;default:throw Error("format must be HEX, TEXT, B64, or BYTES"); +}return d}function w(c,a){return c<<a|c>>>32-a}function q(c,a){return c>>>a|c<<32-a}function v(c,a){var d=null,d=new b(c.a,c.b);return d=32>=a?new b(d.a>>>a|d.b<<32-a&4294967295,d.b>>>a|d.a<<32-a&4294967295):new b(d.b>>>a-32|d.a<<64-a&4294967295,d.a>>>a-32|d.b<<64-a&4294967295)}function Q(c,a){var d=null;return d=32>=a?new b(c.a>>>a,c.b>>>a|c.a<<32-a&4294967295):new b(0,c.a>>>a-32)}function Y(c,a,d){return c&a^~c&d}function Z(c,a,d){return new b(c.a&a.a^~c.a&d.a,c.b&a.b^~c.b&d.b)}function R(c,a,d){return c& +a^c&d^a&d}function aa(c,a,d){return new b(c.a&a.a^c.a&d.a^a.a&d.a,c.b&a.b^c.b&d.b^a.b&d.b)}function ba(c){return q(c,2)^q(c,13)^q(c,22)}function ca(c){var a=v(c,28),d=v(c,34);c=v(c,39);return new b(a.a^d.a^c.a,a.b^d.b^c.b)}function da(c){return q(c,6)^q(c,11)^q(c,25)}function ea(c){var a=v(c,14),d=v(c,18);c=v(c,41);return new b(a.a^d.a^c.a,a.b^d.b^c.b)}function fa(c){return q(c,7)^q(c,18)^c>>>3}function ga(c){var a=v(c,1),d=v(c,8);c=Q(c,7);return new b(a.a^d.a^c.a,a.b^d.b^c.b)}function ha(c){return q(c, +17)^q(c,19)^c>>>10}function ia(c){var a=v(c,19),d=v(c,61);c=Q(c,6);return new b(a.a^d.a^c.a,a.b^d.b^c.b)}function B(c,a){var d=(c&65535)+(a&65535);return((c>>>16)+(a>>>16)+(d>>>16)&65535)<<16|d&65535}function ja(c,a,d,b){var f=(c&65535)+(a&65535)+(d&65535)+(b&65535);return((c>>>16)+(a>>>16)+(d>>>16)+(b>>>16)+(f>>>16)&65535)<<16|f&65535}function C(c,a,d,b,f){var e=(c&65535)+(a&65535)+(d&65535)+(b&65535)+(f&65535);return((c>>>16)+(a>>>16)+(d>>>16)+(b>>>16)+(f>>>16)+(e>>>16)&65535)<<16|e&65535}function ka(c, +a){var d,e,f;d=(c.b&65535)+(a.b&65535);e=(c.b>>>16)+(a.b>>>16)+(d>>>16);f=(e&65535)<<16|d&65535;d=(c.a&65535)+(a.a&65535)+(e>>>16);e=(c.a>>>16)+(a.a>>>16)+(d>>>16);return new b((e&65535)<<16|d&65535,f)}function la(c,a,d,e){var f,k,g;f=(c.b&65535)+(a.b&65535)+(d.b&65535)+(e.b&65535);k=(c.b>>>16)+(a.b>>>16)+(d.b>>>16)+(e.b>>>16)+(f>>>16);g=(k&65535)<<16|f&65535;f=(c.a&65535)+(a.a&65535)+(d.a&65535)+(e.a&65535)+(k>>>16);k=(c.a>>>16)+(a.a>>>16)+(d.a>>>16)+(e.a>>>16)+(f>>>16);return new b((k&65535)<<16| +f&65535,g)}function ma(c,a,d,e,f){var k,g,l;k=(c.b&65535)+(a.b&65535)+(d.b&65535)+(e.b&65535)+(f.b&65535);g=(c.b>>>16)+(a.b>>>16)+(d.b>>>16)+(e.b>>>16)+(f.b>>>16)+(k>>>16);l=(g&65535)<<16|k&65535;k=(c.a&65535)+(a.a&65535)+(d.a&65535)+(e.a&65535)+(f.a&65535)+(g>>>16);g=(c.a>>>16)+(a.a>>>16)+(d.a>>>16)+(e.a>>>16)+(f.a>>>16)+(k>>>16);return new b((g&65535)<<16|k&65535,l)}function z(c){var a,d;if("SHA-1"===c)c=[1732584193,4023233417,2562383102,271733878,3285377520];else switch(a=[3238371032,914150663, +812702999,4144912697,4290775857,1750603025,1694076839,3204075428],d=[1779033703,3144134277,1013904242,2773480762,1359893119,2600822924,528734635,1541459225],c){case "SHA-224":c=a;break;case "SHA-256":c=d;break;case "SHA-384":c=[new b(3418070365,a[0]),new b(1654270250,a[1]),new b(2438529370,a[2]),new b(355462360,a[3]),new b(1731405415,a[4]),new b(41048885895,a[5]),new b(3675008525,a[6]),new b(1203062813,a[7])];break;case "SHA-512":c=[new b(d[0],4089235720),new b(d[1],2227873595),new b(d[2],4271175723), +new b(d[3],1595750129),new b(d[4],2917565137),new b(d[5],725511199),new b(d[6],4215389547),new b(d[7],327033209)];break;default:throw Error("Unknown SHA variant");}return c}function K(c,a){var d=[],b,e,k,g,l,n,h;b=a[0];e=a[1];k=a[2];g=a[3];l=a[4];for(h=0;80>h;h+=1)d[h]=16>h?c[h]:w(d[h-3]^d[h-8]^d[h-14]^d[h-16],1),n=20>h?C(w(b,5),e&k^~e&g,l,1518500249,d[h]):40>h?C(w(b,5),e^k^g,l,1859775393,d[h]):60>h?C(w(b,5),R(e,k,g),l,2400959708,d[h]):C(w(b,5),e^k^g,l,3395469782,d[h]),l=g,g=k,k=w(e,30),e=b,b=n;a[0]= +B(b,a[0]);a[1]=B(e,a[1]);a[2]=B(k,a[2]);a[3]=B(g,a[3]);a[4]=B(l,a[4]);return a}function U(c,a,b,e){var f;for(f=(a+72>>>9<<4)+15;c.length<=f;)c.push(0);c[a>>>5]|=128<<24-a%32;c[f]=a+b;b=c.length;for(a=0;a<b;a+=16)e=K(c.slice(a,a+16),e);return e}function L(c,a,d){var q,f,k,g,l,n,h,m,u,r,p,v,t,w,x,y,z,D,E,F,G,H,A=[],I;if("SHA-224"===d||"SHA-256"===d)r=64,v=1,H=Number,t=B,w=ja,x=C,y=fa,z=ha,D=ba,E=da,G=R,F=Y,I=e;else if("SHA-384"===d||"SHA-512"===d)r=80,v=2,H=b,t=ka,w=la,x=ma,y=ga,z=ia,D=ca,E=ea,G=aa, +F=Z,I=S;else throw Error("Unexpected error in SHA-2 implementation");d=a[0];q=a[1];f=a[2];k=a[3];g=a[4];l=a[5];n=a[6];h=a[7];for(p=0;p<r;p+=1)16>p?(u=p*v,m=c.length<=u?0:c[u],u=c.length<=u+1?0:c[u+1],A[p]=new H(m,u)):A[p]=w(z(A[p-2]),A[p-7],y(A[p-15]),A[p-16]),m=x(h,E(g),F(g,l,n),I[p],A[p]),u=t(D(d),G(d,q,f)),h=n,n=l,l=g,g=t(k,m),k=f,f=q,q=d,d=t(m,u);a[0]=t(d,a[0]);a[1]=t(q,a[1]);a[2]=t(f,a[2]);a[3]=t(k,a[3]);a[4]=t(g,a[4]);a[5]=t(l,a[5]);a[6]=t(n,a[6]);a[7]=t(h,a[7]);return a}var e,S;e=[1116352408, +1899447441,3049323471,3921009573,961987163,1508970993,2453635748,2870763221,3624381080,310598401,607225278,1426881987,1925078388,2162078206,2614888103,3248222580,3835390401,4022224774,264347078,604807628,770255983,1249150122,1555081692,1996064986,2554220882,2821834349,2952996808,3210313671,3336571891,3584528711,113926993,338241895,666307205,773529912,1294757372,1396182291,1695183700,1986661051,2177026350,2456956037,2730485921,2820302411,3259730800,3345764771,3516065817,3600352804,4094571909,275423344, +430227734,506948616,659060556,883997877,958139571,1322822218,1537002063,1747873779,1955562222,2024104815,2227730452,2361852424,2428436474,2756734187,3204031479,3329325298];S=[new b(e[0],3609767458),new b(e[1],602891725),new b(e[2],3964484399),new b(e[3],2173295548),new b(e[4],4081628472),new b(e[5],3053834265),new b(e[6],2937671579),new b(e[7],3664609560),new b(e[8],2734883394),new b(e[9],1164996542),new b(e[10],1323610764),new b(e[11],3590304994),new b(e[12],4068182383),new b(e[13],991336113),new b(e[14], +633803317),new b(e[15],3479774868),new b(e[16],2666613458),new b(e[17],944711139),new b(e[18],2341262773),new b(e[19],2007800933),new b(e[20],1495990901),new b(e[21],1856431235),new b(e[22],3175218132),new b(e[23],2198950837),new b(e[24],3999719339),new b(e[25],766784016),new b(e[26],2566594879),new b(e[27],3203337956),new b(e[28],1034457026),new b(e[29],2466948901),new b(e[30],3758326383),new b(e[31],168717936),new b(e[32],1188179964),new b(e[33],1546045734),new b(e[34],1522805485),new b(e[35],2643833823), +new b(e[36],2343527390),new b(e[37],1014477480),new b(e[38],1206759142),new b(e[39],344077627),new b(e[40],1290863460),new b(e[41],3158454273),new b(e[42],3505952657),new b(e[43],106217008),new b(e[44],3606008344),new b(e[45],1432725776),new b(e[46],1467031594),new b(e[47],851169720),new b(e[48],3100823752),new b(e[49],1363258195),new b(e[50],3750685593),new b(e[51],3785050280),new b(e[52],3318307427),new b(e[53],3812723403),new b(e[54],2003034995),new b(e[55],3602036899),new b(e[56],1575990012), +new b(e[57],1125592928),new b(e[58],2716904306),new b(e[59],442776044),new b(e[60],593698344),new b(e[61],3733110249),new b(e[62],2999351573),new b(e[63],3815920427),new b(3391569614,3928383900),new b(3515267271,566280711),new b(3940187606,3454069534),new b(4118630271,4000239992),new b(116418474,1914138554),new b(174292421,2731055270),new b(289380356,3203993006),new b(460393269,320620315),new b(685471733,587496836),new b(852142971,1086792851),new b(1017036298,365543100),new b(1126000580,2618297676), +new b(1288033470,3409855158),new b(1501505948,4234509866),new b(1607167915,987167468),new b(1816402316,1246189591)];"function"===typeof define&&define.amd?define(function(){return y}):"undefined"!==typeof exports?"undefined"!==typeof module&&module.exports?module.exports=exports=y:exports=y:T.jsSHA=y})(this); diff --git a/src/sha1.js b/src/sha1.js index 95c5753..ee9110e 100644 --- a/src/sha1.js +++ b/src/sha1.js @@ -9,14 +9,15 @@ Several functions taken from Paul Johnston */ -'use strict';(function(D){function n(c,b,g){var a=0,d=[0],e="",f=null,e=g||"UTF8";if("UTF8"!==e&&"UTF16BE"!==e&&"UTF16LE"!==e)throw"encoding must be UTF8, UTF16BE, or UTF16LE";if("HEX"===b){if(0!==c.length%2)throw"srcString of HEX type must be in byte increments";f=v(c);a=f.binLen;d=f.value}else if("TEXT"===b||"ASCII"===b)f=w(c,e),a=f.binLen,d=f.value;else if("B64"===b)f=x(c),a=f.binLen,d=f.value;else if("BYTES"===b)f=y(c),a=f.binLen,d=f.value;else throw"inputFormat must be HEX, TEXT, ASCII, B64, or BYTES"; -this.getHash=function(c,b,e,g){var f=null,h=d.slice(),m=a,p;3===arguments.length?"number"!==typeof e&&(g=e,e=1):2===arguments.length&&(e=1);if(e!==parseInt(e,10)||1>e)throw"numRounds must a integer >= 1";switch(b){case "HEX":f=z;break;case "B64":f=A;break;case "BYTES":f=B;break;default:throw"format must be HEX, B64, or BYTES";}if("SHA-1"===c)for(p=0;p<e;p+=1)h=t(h,m),m=160;else throw"Chosen SHA variant is not supported";return f(h,C(g))};this.getHMAC=function(c,b,f,g,r){var h,m,p,s,n=[],u=[];h=null; -switch(g){case "HEX":g=z;break;case "B64":g=A;break;case "BYTES":g=B;break;default:throw"outputFormat must be HEX, B64, or BYTES";}if("SHA-1"===f)m=64,s=160;else throw"Chosen SHA variant is not supported";if("HEX"===b)h=v(c),p=h.binLen,h=h.value;else if("TEXT"===b||"ASCII"===b)h=w(c,e),p=h.binLen,h=h.value;else if("B64"===b)h=x(c),p=h.binLen,h=h.value;else if("BYTES"===b)h=y(c),p=h.binLen,h=h.value;else throw"inputFormat must be HEX, TEXT, ASCII, B64, or BYTES";c=8*m;b=m/4-1;if(m<p/8){if("SHA-1"=== -f)h=t(h,p);else throw"Unexpected error in HMAC implementation";for(;h.length<=b;)h.push(0);h[b]&=4294967040}else if(m>p/8){for(;h.length<=b;)h.push(0);h[b]&=4294967040}for(m=0;m<=b;m+=1)n[m]=h[m]^909522486,u[m]=h[m]^1549556828;if("SHA-1"===f)f=t(u.concat(t(n.concat(d),c+a)),c+s);else throw"Unexpected error in HMAC implementation";return g(f,C(r))}}function w(c,b){var g=[],a,d=[],e=0,f,k,q;if("UTF8"===b)for(f=0;f<c.length;f+=1)for(a=c.charCodeAt(f),d=[],128>a?d.push(a):2048>a?(d.push(192|a>>>6),d.push(128| -a&63)):55296>a||57344<=a?d.push(224|a>>>12,128|a>>>6&63,128|a&63):(f+=1,a=65536+((a&1023)<<10|c.charCodeAt(f)&1023),d.push(240|a>>>18,128|a>>>12&63,128|a>>>6&63,128|a&63)),k=0;k<d.length;k+=1){for(q=e>>>2;g.length<=q;)g.push(0);g[q]|=d[k]<<24-e%4*8;e+=1}else if("UTF16BE"===b||"UTF16LE"===b)for(f=0;f<c.length;f+=1){a=c.charCodeAt(f);"UTF16LE"===b&&(k=a&255,a=k<<8|a>>8);for(q=e>>>2;g.length<=q;)g.push(0);g[q]|=a<<16-e%4*8;e+=2}return{value:g,binLen:8*e}}function v(c){var b=[],g=c.length,a,d,e;if(0!== -g%2)throw"String of HEX type must be in byte increments";for(a=0;a<g;a+=2){d=parseInt(c.substr(a,2),16);if(isNaN(d))throw"String of HEX type contains invalid characters";for(e=a>>>3;b.length<=e;)b.push(0);b[a>>>3]|=d<<24-a%8*4}return{value:b,binLen:4*g}}function y(c){var b=[],g,a,d;for(a=0;a<c.length;a+=1)g=c.charCodeAt(a),d=a>>>2,b.length<=d&&b.push(0),b[d]|=g<<24-a%4*8;return{value:b,binLen:8*c.length}}function x(c){var b=[],g=0,a,d,e,f,k;if(-1===c.search(/^[a-zA-Z0-9=+\/]+$/))throw"Invalid character in base-64 string"; -d=c.indexOf("=");c=c.replace(/\=/g,"");if(-1!==d&&d<c.length)throw"Invalid '=' found in base-64 string";for(d=0;d<c.length;d+=4){k=c.substr(d,4);for(e=f=0;e<k.length;e+=1)a="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/".indexOf(k[e]),f|=a<<18-6*e;for(e=0;e<k.length-1;e+=1){for(a=g>>>2;b.length<=a;)b.push(0);b[a]|=(f>>>16-8*e&255)<<24-g%4*8;g+=1}}return{value:b,binLen:8*g}}function z(c,b){var g="",a=4*c.length,d,e;for(d=0;d<a;d+=1)e=c[d>>>2]>>>8*(3-d%4),g+="0123456789abcdef".charAt(e>>> -4&15)+"0123456789abcdef".charAt(e&15);return b.outputUpper?g.toUpperCase():g}function A(c,b){var g="",a=4*c.length,d,e,f;for(d=0;d<a;d+=3)for(f=d+1>>>2,e=c.length<=f?0:c[f],f=d+2>>>2,f=c.length<=f?0:c[f],f=(c[d>>>2]>>>8*(3-d%4)&255)<<16|(e>>>8*(3-(d+1)%4)&255)<<8|f>>>8*(3-(d+2)%4)&255,e=0;4>e;e+=1)g=8*d+6*e<=32*c.length?g+"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/".charAt(f>>>6*(3-e)&63):g+b.b64Pad;return g}function B(c){var b="",g=4*c.length,a,d;for(a=0;a<g;a+=1)d=c[a>>>2]>>> -8*(3-a%4)&255,b+=String.fromCharCode(d);return b}function C(c){var b={outputUpper:!1,b64Pad:"="};try{c.hasOwnProperty("outputUpper")&&(b.outputUpper=c.outputUpper),c.hasOwnProperty("b64Pad")&&(b.b64Pad=c.b64Pad)}catch(g){}if("boolean"!==typeof b.outputUpper)throw"Invalid outputUpper formatting option";if("string"!==typeof b.b64Pad)throw"Invalid b64Pad formatting option";return b}function r(c,b){return c<<b|c>>>32-b}function s(c,b){var g=(c&65535)+(b&65535);return((c>>>16)+(b>>>16)+(g>>>16)&65535)<< -16|g&65535}function u(c,b,g,a,d){var e=(c&65535)+(b&65535)+(g&65535)+(a&65535)+(d&65535);return((c>>>16)+(b>>>16)+(g>>>16)+(a>>>16)+(d>>>16)+(e>>>16)&65535)<<16|e&65535}function t(c,b){var g=[],a,d,e,f,k,q,n,l,t,h=[1732584193,4023233417,2562383102,271733878,3285377520];for(a=(b+65>>>9<<4)+15;c.length<=a;)c.push(0);c[b>>>5]|=128<<24-b%32;c[a]=b;t=c.length;for(n=0;n<t;n+=16){a=h[0];d=h[1];e=h[2];f=h[3];k=h[4];for(l=0;80>l;l+=1)g[l]=16>l?c[l+n]:r(g[l-3]^g[l-8]^g[l-14]^g[l-16],1),q=20>l?u(r(a,5),d&e^ -~d&f,k,1518500249,g[l]):40>l?u(r(a,5),d^e^f,k,1859775393,g[l]):60>l?u(r(a,5),d&e^d&f^e&f,k,2400959708,g[l]):u(r(a,5),d^e^f,k,3395469782,g[l]),k=f,f=e,e=r(d,30),d=a,a=q;h[0]=s(a,h[0]);h[1]=s(d,h[1]);h[2]=s(e,h[2]);h[3]=s(f,h[3]);h[4]=s(k,h[4])}return h}"function"===typeof define&&define.amd?define(function(){return n}):"undefined"!==typeof exports?"undefined"!==typeof module&&module.exports?module.exports=exports=n:exports=n:D.jsSHA=n})(this); +'use strict';(function(E){function t(c,a,e){var g=0,b=[],d=0,f,k,l,h,m,w,n,q=!1,r=!1,p=[],t=[],v,u=!1;e=e||{};f=e.encoding||"UTF8";v=e.numRounds||1;l=y(a,f);if(v!==parseInt(v,10)||1>v)throw Error("numRounds must a integer >= 1");if("SHA-1"===c)m=512,w=z,n=F,h=160;else throw Error("Chosen SHA variant is not supported");k=x(c);this.setHMACKey=function(a,b,d){var e;if(!0===r)throw Error("HMAC key already set");if(!0===q)throw Error("Cannot set HMAC key after finalizing hash");if(!0===u)throw Error("Cannot set HMAC key after calling update"); +f=(d||{}).encoding||"UTF8";b=y(b,f)(a);a=b.binLen;b=b.value;e=m>>>3;d=e/4-1;if(e<a/8){for(b=n(b,a,0,x(c));b.length<=d;)b.push(0);b[d]&=4294967040}else if(e>a/8){for(;b.length<=d;)b.push(0);b[d]&=4294967040}for(a=0;a<=d;a+=1)p[a]=b[a]^909522486,t[a]=b[a]^1549556828;k=w(p,k);g=m;r=!0};this.update=function(a){var c,e,f,h=0,n=m>>>5;c=l(a,b,d);a=c.binLen;e=c.value;c=a>>>5;for(f=0;f<c;f+=n)h+m<=a&&(k=w(e.slice(f,f+n),k),h+=m);g+=h;b=e.slice(h>>>5);d=a%m;u=!0};this.getHash=function(a,e){var f,l,m;if(!0=== +r)throw Error("Cannot call getHash after setting HMAC key");m=A(e);switch(a){case "HEX":f=function(a){return B(a,m)};break;case "B64":f=function(a){return C(a,m)};break;case "BYTES":f=D;break;default:throw Error("format must be HEX, B64, or BYTES");}if(!1===q)for(k=n(b,d,g,k),l=1;l<v;l+=1)k=n(k,h,0,x(c));q=!0;return f(k)};this.getHMAC=function(a,e){var f,l,p;if(!1===r)throw Error("Cannot call getHMAC without first setting HMAC key");p=A(e);switch(a){case "HEX":f=function(a){return B(a,p)};break;case "B64":f= +function(a){return C(a,p)};break;case "BYTES":f=D;break;default:throw Error("outputFormat must be HEX, B64, or BYTES");}!1===q&&(l=n(b,d,g,k),k=w(t,x(c)),k=n(l,h,m,k));q=!0;return f(k)}}function G(c,a,e){var g=c.length,b,d,f,k,l;a=a||[0];e=e||0;l=e>>>3;if(0!==g%2)throw Error("String of HEX type must be in byte increments");for(b=0;b<g;b+=2){d=parseInt(c.substr(b,2),16);if(isNaN(d))throw Error("String of HEX type contains invalid characters");k=(b>>>1)+l;for(f=k>>>2;a.length<=f;)a.push(0);a[f]|=d<< +8*(3-k%4)}return{value:a,binLen:4*g+e}}function H(c,a,e){var g=[],b,d,f,k,g=a||[0];e=e||0;d=e>>>3;for(b=0;b<c.length;b+=1)a=c.charCodeAt(b),k=b+d,f=k>>>2,g.length<=f&&g.push(0),g[f]|=a<<8*(3-k%4);return{value:g,binLen:8*c.length+e}}function I(c,a,e){var g=[],b=0,d,f,k,l,h,m,g=a||[0];e=e||0;a=e>>>3;if(-1===c.search(/^[a-zA-Z0-9=+\/]+$/))throw Error("Invalid character in base-64 string");f=c.indexOf("=");c=c.replace(/\=/g,"");if(-1!==f&&f<c.length)throw Error("Invalid '=' found in base-64 string"); +for(f=0;f<c.length;f+=4){h=c.substr(f,4);for(k=l=0;k<h.length;k+=1)d="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/".indexOf(h[k]),l|=d<<18-6*k;for(k=0;k<h.length-1;k+=1){m=b+a;for(d=m>>>2;g.length<=d;)g.push(0);g[d]|=(l>>>16-8*k&255)<<8*(3-m%4);b+=1}}return{value:g,binLen:8*b+e}}function B(c,a){var e="",g=4*c.length,b,d;for(b=0;b<g;b+=1)d=c[b>>>2]>>>8*(3-b%4),e+="0123456789abcdef".charAt(d>>>4&15)+"0123456789abcdef".charAt(d&15);return a.outputUpper?e.toUpperCase():e}function C(c, +a){var e="",g=4*c.length,b,d,f;for(b=0;b<g;b+=3)for(f=b+1>>>2,d=c.length<=f?0:c[f],f=b+2>>>2,f=c.length<=f?0:c[f],f=(c[b>>>2]>>>8*(3-b%4)&255)<<16|(d>>>8*(3-(b+1)%4)&255)<<8|f>>>8*(3-(b+2)%4)&255,d=0;4>d;d+=1)8*b+6*d<=32*c.length?e+="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/".charAt(f>>>6*(3-d)&63):e+=a.b64Pad;return e}function D(c){var a="",e=4*c.length,g,b;for(g=0;g<e;g+=1)b=c[g>>>2]>>>8*(3-g%4)&255,a+=String.fromCharCode(b);return a}function A(c){var a={outputUpper:!1,b64Pad:"="}; +c=c||{};a.outputUpper=c.outputUpper||!1;a.b64Pad=c.b64Pad||"=";if("boolean"!==typeof a.outputUpper)throw Error("Invalid outputUpper formatting option");if("string"!==typeof a.b64Pad)throw Error("Invalid b64Pad formatting option");return a}function y(c,a){var e;switch(a){case "UTF8":case "UTF16BE":case "UTF16LE":break;default:throw Error("encoding must be UTF8, UTF16BE, or UTF16LE");}switch(c){case "HEX":e=G;break;case "TEXT":e=function(e,b,d){var f=[],c=[],l=0,h,m,p,n,q,f=b||[0];b=d||0;p=b>>>3;if("UTF8"=== +a)for(h=0;h<e.length;h+=1)for(d=e.charCodeAt(h),c=[],128>d?c.push(d):2048>d?(c.push(192|d>>>6),c.push(128|d&63)):55296>d||57344<=d?c.push(224|d>>>12,128|d>>>6&63,128|d&63):(h+=1,d=65536+((d&1023)<<10|e.charCodeAt(h)&1023),c.push(240|d>>>18,128|d>>>12&63,128|d>>>6&63,128|d&63)),m=0;m<c.length;m+=1){q=l+p;for(n=q>>>2;f.length<=n;)f.push(0);f[n]|=c[m]<<8*(3-q%4);l+=1}else if("UTF16BE"===a||"UTF16LE"===a)for(h=0;h<e.length;h+=1){d=e.charCodeAt(h);"UTF16LE"===a&&(m=d&255,d=m<<8|d>>>8);q=l+p;for(n=q>>> +2;f.length<=n;)f.push(0);f[n]|=d<<8*(2-q%4);l+=2}return{value:f,binLen:8*l+b}};break;case "B64":e=I;break;case "BYTES":e=H;break;default:throw Error("format must be HEX, TEXT, B64, or BYTES");}return e}function r(c,a){return c<<a|c>>>32-a}function p(c,a){var e=(c&65535)+(a&65535);return((c>>>16)+(a>>>16)+(e>>>16)&65535)<<16|e&65535}function u(c,a,e,g,b){var d=(c&65535)+(a&65535)+(e&65535)+(g&65535)+(b&65535);return((c>>>16)+(a>>>16)+(e>>>16)+(g>>>16)+(b>>>16)+(d>>>16)&65535)<<16|d&65535}function x(c){if("SHA-1"=== +c)c=[1732584193,4023233417,2562383102,271733878,3285377520];else throw Error("No SHA variants supported");return c}function z(c,a){var e=[],g,b,d,f,k,l,h;g=a[0];b=a[1];d=a[2];f=a[3];k=a[4];for(h=0;80>h;h+=1)e[h]=16>h?c[h]:r(e[h-3]^e[h-8]^e[h-14]^e[h-16],1),l=20>h?u(r(g,5),b&d^~b&f,k,1518500249,e[h]):40>h?u(r(g,5),b^d^f,k,1859775393,e[h]):60>h?u(r(g,5),b&d^b&f^d&f,k,2400959708,e[h]):u(r(g,5),b^d^f,k,3395469782,e[h]),k=f,f=d,d=r(b,30),b=g,g=l;a[0]=p(g,a[0]);a[1]=p(b,a[1]);a[2]=p(d,a[2]);a[3]=p(f,a[3]); +a[4]=p(k,a[4]);return a}function F(c,a,e,g){var b;for(b=(a+72>>>9<<4)+15;c.length<=b;)c.push(0);c[a>>>5]|=128<<24-a%32;c[b]=a+e;e=c.length;for(a=0;a<e;a+=16)g=z(c.slice(a,a+16),g);return g}"function"===typeof define&&define.amd?define(function(){return t}):"undefined"!==typeof exports?"undefined"!==typeof module&&module.exports?module.exports=exports=t:exports=t:E.jsSHA=t})(this); diff --git a/src/sha256.js b/src/sha256.js index e94f291..97e0f9f 100644 --- a/src/sha256.js +++ b/src/sha256.js @@ -9,17 +9,19 @@ Several functions taken from Paul Johnston */ -'use strict';(function(F){function u(a,b,d){var c=0,f=[0],h="",g=null,h=d||"UTF8";if("UTF8"!==h&&"UTF16BE"!==h&&"UTF16LE"!==h)throw"encoding must be UTF8, UTF16BE, or UTF16LE";if("HEX"===b){if(0!==a.length%2)throw"srcString of HEX type must be in byte increments";g=w(a);c=g.binLen;f=g.value}else if("TEXT"===b||"ASCII"===b)g=x(a,h),c=g.binLen,f=g.value;else if("B64"===b)g=y(a),c=g.binLen,f=g.value;else if("BYTES"===b)g=z(a),c=g.binLen,f=g.value;else throw"inputFormat must be HEX, TEXT, ASCII, B64, or BYTES"; -this.getHash=function(a,b,d,h){var g=null,e=f.slice(),k=c,l;3===arguments.length?"number"!==typeof d&&(h=d,d=1):2===arguments.length&&(d=1);if(d!==parseInt(d,10)||1>d)throw"numRounds must a integer >= 1";switch(b){case "HEX":g=A;break;case "B64":g=B;break;case "BYTES":g=C;break;default:throw"format must be HEX, B64, or BYTES";}if("SHA-224"===a)for(l=0;l<d;l+=1)e=t(e,k,a),k=224;else if("SHA-256"===a)for(l=0;l<d;l+=1)e=t(e,k,a),k=256;else throw"Chosen SHA variant is not supported";return g(e,D(h))}; -this.getHMAC=function(a,b,d,g,s){var e,k,l,n,p=[],E=[];e=null;switch(g){case "HEX":g=A;break;case "B64":g=B;break;case "BYTES":g=C;break;default:throw"outputFormat must be HEX, B64, or BYTES";}if("SHA-224"===d)k=64,n=224;else if("SHA-256"===d)k=64,n=256;else throw"Chosen SHA variant is not supported";if("HEX"===b)e=w(a),l=e.binLen,e=e.value;else if("TEXT"===b||"ASCII"===b)e=x(a,h),l=e.binLen,e=e.value;else if("B64"===b)e=y(a),l=e.binLen,e=e.value;else if("BYTES"===b)e=z(a),l=e.binLen,e=e.value;else throw"inputFormat must be HEX, TEXT, ASCII, B64, or BYTES"; -a=8*k;b=k/4-1;if(k<l/8){for(e=t(e,l,d);e.length<=b;)e.push(0);e[b]&=4294967040}else if(k>l/8){for(;e.length<=b;)e.push(0);e[b]&=4294967040}for(k=0;k<=b;k+=1)p[k]=e[k]^909522486,E[k]=e[k]^1549556828;d=t(E.concat(t(p.concat(f),a+c,d)),a+n,d);return g(d,D(s))}}function x(a,b){var d=[],c,f=[],h=0,g,m,q;if("UTF8"===b)for(g=0;g<a.length;g+=1)for(c=a.charCodeAt(g),f=[],128>c?f.push(c):2048>c?(f.push(192|c>>>6),f.push(128|c&63)):55296>c||57344<=c?f.push(224|c>>>12,128|c>>>6&63,128|c&63):(g+=1,c=65536+((c& -1023)<<10|a.charCodeAt(g)&1023),f.push(240|c>>>18,128|c>>>12&63,128|c>>>6&63,128|c&63)),m=0;m<f.length;m+=1){for(q=h>>>2;d.length<=q;)d.push(0);d[q]|=f[m]<<24-h%4*8;h+=1}else if("UTF16BE"===b||"UTF16LE"===b)for(g=0;g<a.length;g+=1){c=a.charCodeAt(g);"UTF16LE"===b&&(m=c&255,c=m<<8|c>>8);for(q=h>>>2;d.length<=q;)d.push(0);d[q]|=c<<16-h%4*8;h+=2}return{value:d,binLen:8*h}}function w(a){var b=[],d=a.length,c,f,h;if(0!==d%2)throw"String of HEX type must be in byte increments";for(c=0;c<d;c+=2){f=parseInt(a.substr(c, -2),16);if(isNaN(f))throw"String of HEX type contains invalid characters";for(h=c>>>3;b.length<=h;)b.push(0);b[c>>>3]|=f<<24-c%8*4}return{value:b,binLen:4*d}}function z(a){var b=[],d,c,f;for(c=0;c<a.length;c+=1)d=a.charCodeAt(c),f=c>>>2,b.length<=f&&b.push(0),b[f]|=d<<24-c%4*8;return{value:b,binLen:8*a.length}}function y(a){var b=[],d=0,c,f,h,g,m;if(-1===a.search(/^[a-zA-Z0-9=+\/]+$/))throw"Invalid character in base-64 string";f=a.indexOf("=");a=a.replace(/\=/g,"");if(-1!==f&&f<a.length)throw"Invalid '=' found in base-64 string"; -for(f=0;f<a.length;f+=4){m=a.substr(f,4);for(h=g=0;h<m.length;h+=1)c="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/".indexOf(m[h]),g|=c<<18-6*h;for(h=0;h<m.length-1;h+=1){for(c=d>>>2;b.length<=c;)b.push(0);b[c]|=(g>>>16-8*h&255)<<24-d%4*8;d+=1}}return{value:b,binLen:8*d}}function A(a,b){var d="",c=4*a.length,f,h;for(f=0;f<c;f+=1)h=a[f>>>2]>>>8*(3-f%4),d+="0123456789abcdef".charAt(h>>>4&15)+"0123456789abcdef".charAt(h&15);return b.outputUpper?d.toUpperCase():d}function B(a,b){var d= -"",c=4*a.length,f,h,g;for(f=0;f<c;f+=3)for(g=f+1>>>2,h=a.length<=g?0:a[g],g=f+2>>>2,g=a.length<=g?0:a[g],g=(a[f>>>2]>>>8*(3-f%4)&255)<<16|(h>>>8*(3-(f+1)%4)&255)<<8|g>>>8*(3-(f+2)%4)&255,h=0;4>h;h+=1)d=8*f+6*h<=32*a.length?d+"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/".charAt(g>>>6*(3-h)&63):d+b.b64Pad;return d}function C(a){var b="",d=4*a.length,c,f;for(c=0;c<d;c+=1)f=a[c>>>2]>>>8*(3-c%4)&255,b+=String.fromCharCode(f);return b}function D(a){var b={outputUpper:!1,b64Pad:"="}; -try{a.hasOwnProperty("outputUpper")&&(b.outputUpper=a.outputUpper),a.hasOwnProperty("b64Pad")&&(b.b64Pad=a.b64Pad)}catch(d){}if("boolean"!==typeof b.outputUpper)throw"Invalid outputUpper formatting option";if("string"!==typeof b.b64Pad)throw"Invalid b64Pad formatting option";return b}function p(a,b){return a>>>b|a<<32-b}function I(a,b,d){return a&b^~a&d}function J(a,b,d){return a&b^a&d^b&d}function K(a){return p(a,2)^p(a,13)^p(a,22)}function L(a){return p(a,6)^p(a,11)^p(a,25)}function M(a){return p(a, -7)^p(a,18)^a>>>3}function N(a){return p(a,17)^p(a,19)^a>>>10}function O(a,b){var d=(a&65535)+(b&65535);return((a>>>16)+(b>>>16)+(d>>>16)&65535)<<16|d&65535}function P(a,b,d,c){var f=(a&65535)+(b&65535)+(d&65535)+(c&65535);return((a>>>16)+(b>>>16)+(d>>>16)+(c>>>16)+(f>>>16)&65535)<<16|f&65535}function Q(a,b,d,c,f){var h=(a&65535)+(b&65535)+(d&65535)+(c&65535)+(f&65535);return((a>>>16)+(b>>>16)+(d>>>16)+(c>>>16)+(f>>>16)+(h>>>16)&65535)<<16|h&65535}function t(a,b,d){var c,f,h,g,m,q,p,t,s,e,k,l,n,u, -E,r,w,x,y,z,A,B,C,D,G,v=[],H,F=[1116352408,1899447441,3049323471,3921009573,961987163,1508970993,2453635748,2870763221,3624381080,310598401,607225278,1426881987,1925078388,2162078206,2614888103,3248222580,3835390401,4022224774,264347078,604807628,770255983,1249150122,1555081692,1996064986,2554220882,2821834349,2952996808,3210313671,3336571891,3584528711,113926993,338241895,666307205,773529912,1294757372,1396182291,1695183700,1986661051,2177026350,2456956037,2730485921,2820302411,3259730800,3345764771, -3516065817,3600352804,4094571909,275423344,430227734,506948616,659060556,883997877,958139571,1322822218,1537002063,1747873779,1955562222,2024104815,2227730452,2361852424,2428436474,2756734187,3204031479,3329325298];e=[3238371032,914150663,812702999,4144912697,4290775857,1750603025,1694076839,3204075428];f=[1779033703,3144134277,1013904242,2773480762,1359893119,2600822924,528734635,1541459225];if("SHA-224"===d||"SHA-256"===d)k=64,c=(b+65>>>9<<4)+15,u=16,E=1,G=Number,r=O,w=P,x=Q,y=M,z=N,A=K,B=L,D=J, -C=I,e="SHA-224"===d?e:f;else throw"Unexpected error in SHA-2 implementation";for(;a.length<=c;)a.push(0);a[b>>>5]|=128<<24-b%32;a[c]=b;H=a.length;for(l=0;l<H;l+=u){b=e[0];c=e[1];f=e[2];h=e[3];g=e[4];m=e[5];q=e[6];p=e[7];for(n=0;n<k;n+=1)16>n?(s=n*E+l,t=a.length<=s?0:a[s],s=a.length<=s+1?0:a[s+1],v[n]=new G(t,s)):v[n]=w(z(v[n-2]),v[n-7],y(v[n-15]),v[n-16]),t=x(p,B(g),C(g,m,q),F[n],v[n]),s=r(A(b),D(b,c,f)),p=q,q=m,m=g,g=r(h,t),h=f,f=c,c=b,b=r(t,s);e[0]=r(b,e[0]);e[1]=r(c,e[1]);e[2]=r(f,e[2]);e[3]=r(h, -e[3]);e[4]=r(g,e[4]);e[5]=r(m,e[5]);e[6]=r(q,e[6]);e[7]=r(p,e[7])}if("SHA-224"===d)a=[e[0],e[1],e[2],e[3],e[4],e[5],e[6]];else if("SHA-256"===d)a=e;else throw"Unexpected error in SHA-2 implementation";return a}"function"===typeof define&&define.amd?define(function(){return u}):"undefined"!==typeof exports?"undefined"!==typeof module&&module.exports?module.exports=exports=u:exports=u:F.jsSHA=u})(this); +'use strict';(function(H){function v(c,a,b){var g=0,d=[],f=0,e,h,n,l,m,F,r,p=!1,k=!1,q=[],t=[],u,y=!1;b=b||{};e=b.encoding||"UTF8";u=b.numRounds||1;n=z(a,e);if(u!==parseInt(u,10)||1>u)throw Error("numRounds must a integer >= 1");F=function(a,b){return A(a,b,c)};r=function(a,b,f,d){var g,e;if("SHA-224"===c||"SHA-256"===c)g=(b+72>>>9<<4)+15,e=16;else throw Error("Unexpected error in SHA-2 implementation");for(;a.length<=g;)a.push(0);a[b>>>5]|=128<<24-b%32;a[g]=b+f;f=a.length;for(b=0;b<f;b+=e)d=A(a.slice(b, +b+e),d,c);if("SHA-224"===c)a=[d[0],d[1],d[2],d[3],d[4],d[5],d[6]];else if("SHA-256"===c)a=d;else throw Error("Unexpected error in SHA-2 implementation");return a};if("SHA-224"===c)m=512,l=224;else if("SHA-256"===c)m=512,l=256;else throw Error("Chosen SHA variant is not supported");h=w(c);this.setHMACKey=function(a,b,d){var f;if(!0===k)throw Error("HMAC key already set");if(!0===p)throw Error("Cannot set HMAC key after finalizing hash");if(!0===y)throw Error("Cannot set HMAC key after calling update"); +e=(d||{}).encoding||"UTF8";b=z(b,e)(a);a=b.binLen;b=b.value;f=m>>>3;d=f/4-1;if(f<a/8){for(b=r(b,a,0,w(c));b.length<=d;)b.push(0);b[d]&=4294967040}else if(f>a/8){for(;b.length<=d;)b.push(0);b[d]&=4294967040}for(a=0;a<=d;a+=1)q[a]=b[a]^909522486,t[a]=b[a]^1549556828;h=F(q,h);g=m;k=!0};this.update=function(a){var b,c,e,l=0,p=m>>>5;b=n(a,d,f);a=b.binLen;c=b.value;b=a>>>5;for(e=0;e<b;e+=p)l+m<=a&&(h=F(c.slice(e,e+p),h),l+=m);g+=l;d=c.slice(l>>>5);f=a%m;y=!0};this.getHash=function(a,b){var e,m,n;if(!0=== +k)throw Error("Cannot call getHash after setting HMAC key");n=B(b);switch(a){case "HEX":e=function(a){return C(a,n)};break;case "B64":e=function(a){return D(a,n)};break;case "BYTES":e=E;break;default:throw Error("format must be HEX, B64, or BYTES");}if(!1===p)for(h=r(d,f,g,h),m=1;m<u;m+=1)h=r(h,l,0,w(c));p=!0;return e(h)};this.getHMAC=function(a,b){var e,n,q;if(!1===k)throw Error("Cannot call getHMAC without first setting HMAC key");q=B(b);switch(a){case "HEX":e=function(a){return C(a,q)};break;case "B64":e= +function(a){return D(a,q)};break;case "BYTES":e=E;break;default:throw Error("outputFormat must be HEX, B64, or BYTES");}!1===p&&(n=r(d,f,g,h),h=F(t,w(c)),h=r(n,l,m,h));p=!0;return e(h)}}function k(){}function I(c,a,b){var g=c.length,d,f,e,h,n;a=a||[0];b=b||0;n=b>>>3;if(0!==g%2)throw Error("String of HEX type must be in byte increments");for(d=0;d<g;d+=2){f=parseInt(c.substr(d,2),16);if(isNaN(f))throw Error("String of HEX type contains invalid characters");h=(d>>>1)+n;for(e=h>>>2;a.length<=e;)a.push(0); +a[e]|=f<<8*(3-h%4)}return{value:a,binLen:4*g+b}}function J(c,a,b){var g=[],d,f,e,h,g=a||[0];b=b||0;f=b>>>3;for(d=0;d<c.length;d+=1)a=c.charCodeAt(d),h=d+f,e=h>>>2,g.length<=e&&g.push(0),g[e]|=a<<8*(3-h%4);return{value:g,binLen:8*c.length+b}}function K(c,a,b){var g=[],d=0,f,e,h,n,l,m,g=a||[0];b=b||0;a=b>>>3;if(-1===c.search(/^[a-zA-Z0-9=+\/]+$/))throw Error("Invalid character in base-64 string");e=c.indexOf("=");c=c.replace(/\=/g,"");if(-1!==e&&e<c.length)throw Error("Invalid '=' found in base-64 string"); +for(e=0;e<c.length;e+=4){l=c.substr(e,4);for(h=n=0;h<l.length;h+=1)f="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/".indexOf(l[h]),n|=f<<18-6*h;for(h=0;h<l.length-1;h+=1){m=d+a;for(f=m>>>2;g.length<=f;)g.push(0);g[f]|=(n>>>16-8*h&255)<<8*(3-m%4);d+=1}}return{value:g,binLen:8*d+b}}function C(c,a){var b="",g=4*c.length,d,f;for(d=0;d<g;d+=1)f=c[d>>>2]>>>8*(3-d%4),b+="0123456789abcdef".charAt(f>>>4&15)+"0123456789abcdef".charAt(f&15);return a.outputUpper?b.toUpperCase():b}function D(c, +a){var b="",g=4*c.length,d,f,e;for(d=0;d<g;d+=3)for(e=d+1>>>2,f=c.length<=e?0:c[e],e=d+2>>>2,e=c.length<=e?0:c[e],e=(c[d>>>2]>>>8*(3-d%4)&255)<<16|(f>>>8*(3-(d+1)%4)&255)<<8|e>>>8*(3-(d+2)%4)&255,f=0;4>f;f+=1)8*d+6*f<=32*c.length?b+="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/".charAt(e>>>6*(3-f)&63):b+=a.b64Pad;return b}function E(c){var a="",b=4*c.length,g,d;for(g=0;g<b;g+=1)d=c[g>>>2]>>>8*(3-g%4)&255,a+=String.fromCharCode(d);return a}function B(c){var a={outputUpper:!1,b64Pad:"="}; +c=c||{};a.outputUpper=c.outputUpper||!1;a.b64Pad=c.b64Pad||"=";if("boolean"!==typeof a.outputUpper)throw Error("Invalid outputUpper formatting option");if("string"!==typeof a.b64Pad)throw Error("Invalid b64Pad formatting option");return a}function z(c,a){var b;switch(a){case "UTF8":case "UTF16BE":case "UTF16LE":break;default:throw Error("encoding must be UTF8, UTF16BE, or UTF16LE");}switch(c){case "HEX":b=I;break;case "TEXT":b=function(b,c,f){var e=[],h=[],n=0,l,m,k,r,p,e=c||[0];c=f||0;k=c>>>3;if("UTF8"=== +a)for(l=0;l<b.length;l+=1)for(f=b.charCodeAt(l),h=[],128>f?h.push(f):2048>f?(h.push(192|f>>>6),h.push(128|f&63)):55296>f||57344<=f?h.push(224|f>>>12,128|f>>>6&63,128|f&63):(l+=1,f=65536+((f&1023)<<10|b.charCodeAt(l)&1023),h.push(240|f>>>18,128|f>>>12&63,128|f>>>6&63,128|f&63)),m=0;m<h.length;m+=1){p=n+k;for(r=p>>>2;e.length<=r;)e.push(0);e[r]|=h[m]<<8*(3-p%4);n+=1}else if("UTF16BE"===a||"UTF16LE"===a)for(l=0;l<b.length;l+=1){f=b.charCodeAt(l);"UTF16LE"===a&&(m=f&255,f=m<<8|f>>>8);p=n+k;for(r=p>>> +2;e.length<=r;)e.push(0);e[r]|=f<<8*(2-p%4);n+=2}return{value:e,binLen:8*n+c}};break;case "B64":b=K;break;case "BYTES":b=J;break;default:throw Error("format must be HEX, TEXT, B64, or BYTES");}return b}function t(c,a){return c>>>a|c<<32-a}function L(c,a,b){return c&a^~c&b}function M(c,a,b){return c&a^c&b^a&b}function N(c){return t(c,2)^t(c,13)^t(c,22)}function O(c){return t(c,6)^t(c,11)^t(c,25)}function P(c){return t(c,7)^t(c,18)^c>>>3}function Q(c){return t(c,17)^t(c,19)^c>>>10}function R(c,a){var b= +(c&65535)+(a&65535);return((c>>>16)+(a>>>16)+(b>>>16)&65535)<<16|b&65535}function S(c,a,b,g){var d=(c&65535)+(a&65535)+(b&65535)+(g&65535);return((c>>>16)+(a>>>16)+(b>>>16)+(g>>>16)+(d>>>16)&65535)<<16|d&65535}function T(c,a,b,g,d){var f=(c&65535)+(a&65535)+(b&65535)+(g&65535)+(d&65535);return((c>>>16)+(a>>>16)+(b>>>16)+(g>>>16)+(d>>>16)+(f>>>16)&65535)<<16|f&65535}function w(c){var a,b;a=[3238371032,914150663,812702999,4144912697,4290775857,1750603025,1694076839,3204075428];b=[1779033703,3144134277, +1013904242,2773480762,1359893119,2600822924,528734635,1541459225];switch(c){case "SHA-224":c=a;break;case "SHA-256":c=b;break;case "SHA-384":c=[new k,new k,new k,new k,new k,new k,new k,new k];break;case "SHA-512":c=[new k,new k,new k,new k,new k,new k,new k,new k];break;default:throw Error("Unknown SHA variant");}return c}function A(c,a,b){var g,d,f,e,h,n,l,m,k,r,p,t,q,v,u,y,w,z,A,B,C,D,x=[],E;if("SHA-224"===b||"SHA-256"===b)r=64,t=1,D=Number,q=R,v=S,u=T,y=P,w=Q,z=N,A=O,C=M,B=L,E=G;else throw Error("Unexpected error in SHA-2 implementation"); +b=a[0];g=a[1];d=a[2];f=a[3];e=a[4];h=a[5];n=a[6];l=a[7];for(p=0;p<r;p+=1)16>p?(k=p*t,m=c.length<=k?0:c[k],k=c.length<=k+1?0:c[k+1],x[p]=new D(m,k)):x[p]=v(w(x[p-2]),x[p-7],y(x[p-15]),x[p-16]),m=u(l,A(e),B(e,h,n),E[p],x[p]),k=q(z(b),C(b,g,d)),l=n,n=h,h=e,e=q(f,m),f=d,d=g,g=b,b=q(m,k);a[0]=q(b,a[0]);a[1]=q(g,a[1]);a[2]=q(d,a[2]);a[3]=q(f,a[3]);a[4]=q(e,a[4]);a[5]=q(h,a[5]);a[6]=q(n,a[6]);a[7]=q(l,a[7]);return a}var G;G=[1116352408,1899447441,3049323471,3921009573,961987163,1508970993,2453635748,2870763221, +3624381080,310598401,607225278,1426881987,1925078388,2162078206,2614888103,3248222580,3835390401,4022224774,264347078,604807628,770255983,1249150122,1555081692,1996064986,2554220882,2821834349,2952996808,3210313671,3336571891,3584528711,113926993,338241895,666307205,773529912,1294757372,1396182291,1695183700,1986661051,2177026350,2456956037,2730485921,2820302411,3259730800,3345764771,3516065817,3600352804,4094571909,275423344,430227734,506948616,659060556,883997877,958139571,1322822218,1537002063, +1747873779,1955562222,2024104815,2227730452,2361852424,2428436474,2756734187,3204031479,3329325298];"function"===typeof define&&define.amd?define(function(){return v}):"undefined"!==typeof exports?"undefined"!==typeof module&&module.exports?module.exports=exports=v:exports=v:H.jsSHA=v})(this); diff --git a/src/sha512.js b/src/sha512.js index 7835b10..5ad9fd4 100644 --- a/src/sha512.js +++ b/src/sha512.js @@ -9,24 +9,26 @@ Several functions taken from Paul Johnston */ -'use strict';(function(J){function w(a,b,c){var f=0,g=[0],l="",h=null,l=c||"UTF8";if("UTF8"!==l&&"UTF16BE"!==l&&"UTF16LE"!==l)throw"encoding must be UTF8, UTF16BE, or UTF16LE";if("HEX"===b){if(0!==a.length%2)throw"srcString of HEX type must be in byte increments";h=y(a);f=h.binLen;g=h.value}else if("TEXT"===b||"ASCII"===b)h=z(a,l),f=h.binLen,g=h.value;else if("B64"===b)h=A(a),f=h.binLen,g=h.value;else if("BYTES"===b)h=B(a),f=h.binLen,g=h.value;else throw"inputFormat must be HEX, TEXT, ASCII, B64, or BYTES"; -this.getHash=function(a,b,c,l){var h=null,d=g.slice(),n=f,p;3===arguments.length?"number"!==typeof c&&(l=c,c=1):2===arguments.length&&(c=1);if(c!==parseInt(c,10)||1>c)throw"numRounds must a integer >= 1";switch(b){case "HEX":h=D;break;case "B64":h=E;break;case "BYTES":h=F;break;default:throw"format must be HEX, B64, or BYTES";}if("SHA-384"===a)for(p=0;p<c;p+=1)d=u(d,n,a),n=384;else if("SHA-512"===a)for(p=0;p<c;p+=1)d=u(d,n,a),n=512;else throw"Chosen SHA variant is not supported";return h(d,G(l))}; -this.getHMAC=function(a,b,c,h,m){var d,n,p,r,q=[],H=[];d=null;switch(h){case "HEX":h=D;break;case "B64":h=E;break;case "BYTES":h=F;break;default:throw"outputFormat must be HEX, B64, or BYTES";}if("SHA-384"===c)n=128,r=384;else if("SHA-512"===c)n=128,r=512;else throw"Chosen SHA variant is not supported";if("HEX"===b)d=y(a),p=d.binLen,d=d.value;else if("TEXT"===b||"ASCII"===b)d=z(a,l),p=d.binLen,d=d.value;else if("B64"===b)d=A(a),p=d.binLen,d=d.value;else if("BYTES"===b)d=B(a),p=d.binLen,d=d.value; -else throw"inputFormat must be HEX, TEXT, ASCII, B64, or BYTES";a=8*n;b=n/4-1;if(n<p/8){for(d=u(d,p,c);d.length<=b;)d.push(0);d[b]&=4294967040}else if(n>p/8){for(;d.length<=b;)d.push(0);d[b]&=4294967040}for(n=0;n<=b;n+=1)q[n]=d[n]^909522486,H[n]=d[n]^1549556828;c=u(H.concat(u(q.concat(g),a+f,c)),a+r,c);return h(c,G(m))}}function m(a,b){this.a=a;this.b=b}function z(a,b){var c=[],f,g=[],l=0,h,s,m;if("UTF8"===b)for(h=0;h<a.length;h+=1)for(f=a.charCodeAt(h),g=[],128>f?g.push(f):2048>f?(g.push(192|f>>> -6),g.push(128|f&63)):55296>f||57344<=f?g.push(224|f>>>12,128|f>>>6&63,128|f&63):(h+=1,f=65536+((f&1023)<<10|a.charCodeAt(h)&1023),g.push(240|f>>>18,128|f>>>12&63,128|f>>>6&63,128|f&63)),s=0;s<g.length;s+=1){for(m=l>>>2;c.length<=m;)c.push(0);c[m]|=g[s]<<24-l%4*8;l+=1}else if("UTF16BE"===b||"UTF16LE"===b)for(h=0;h<a.length;h+=1){f=a.charCodeAt(h);"UTF16LE"===b&&(s=f&255,f=s<<8|f>>8);for(m=l>>>2;c.length<=m;)c.push(0);c[m]|=f<<16-l%4*8;l+=2}return{value:c,binLen:8*l}}function y(a){var b=[],c=a.length, -f,g,l;if(0!==c%2)throw"String of HEX type must be in byte increments";for(f=0;f<c;f+=2){g=parseInt(a.substr(f,2),16);if(isNaN(g))throw"String of HEX type contains invalid characters";for(l=f>>>3;b.length<=l;)b.push(0);b[f>>>3]|=g<<24-f%8*4}return{value:b,binLen:4*c}}function B(a){var b=[],c,f,g;for(f=0;f<a.length;f+=1)c=a.charCodeAt(f),g=f>>>2,b.length<=g&&b.push(0),b[g]|=c<<24-f%4*8;return{value:b,binLen:8*a.length}}function A(a){var b=[],c=0,f,g,l,h,m;if(-1===a.search(/^[a-zA-Z0-9=+\/]+$/))throw"Invalid character in base-64 string"; -g=a.indexOf("=");a=a.replace(/\=/g,"");if(-1!==g&&g<a.length)throw"Invalid '=' found in base-64 string";for(g=0;g<a.length;g+=4){m=a.substr(g,4);for(l=h=0;l<m.length;l+=1)f="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/".indexOf(m[l]),h|=f<<18-6*l;for(l=0;l<m.length-1;l+=1){for(f=c>>>2;b.length<=f;)b.push(0);b[f]|=(h>>>16-8*l&255)<<24-c%4*8;c+=1}}return{value:b,binLen:8*c}}function D(a,b){var c="",f=4*a.length,g,l;for(g=0;g<f;g+=1)l=a[g>>>2]>>>8*(3-g%4),c+="0123456789abcdef".charAt(l>>> -4&15)+"0123456789abcdef".charAt(l&15);return b.outputUpper?c.toUpperCase():c}function E(a,b){var c="",f=4*a.length,g,l,h;for(g=0;g<f;g+=3)for(h=g+1>>>2,l=a.length<=h?0:a[h],h=g+2>>>2,h=a.length<=h?0:a[h],h=(a[g>>>2]>>>8*(3-g%4)&255)<<16|(l>>>8*(3-(g+1)%4)&255)<<8|h>>>8*(3-(g+2)%4)&255,l=0;4>l;l+=1)c=8*g+6*l<=32*a.length?c+"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/".charAt(h>>>6*(3-l)&63):c+b.b64Pad;return c}function F(a){var b="",c=4*a.length,f,g;for(f=0;f<c;f+=1)g=a[f>>>2]>>> -8*(3-f%4)&255,b+=String.fromCharCode(g);return b}function G(a){var b={outputUpper:!1,b64Pad:"="};try{a.hasOwnProperty("outputUpper")&&(b.outputUpper=a.outputUpper),a.hasOwnProperty("b64Pad")&&(b.b64Pad=a.b64Pad)}catch(c){}if("boolean"!==typeof b.outputUpper)throw"Invalid outputUpper formatting option";if("string"!==typeof b.b64Pad)throw"Invalid b64Pad formatting option";return b}function q(a,b){var c=null,c=new m(a.a,a.b);return c=32>=b?new m(c.a>>>b|c.b<<32-b&4294967295,c.b>>>b|c.a<<32-b&4294967295): -new m(c.b>>>b-32|c.a<<64-b&4294967295,c.a>>>b-32|c.b<<64-b&4294967295)}function I(a,b){var c=null;return c=32>=b?new m(a.a>>>b,a.b>>>b|a.a<<32-b&4294967295):new m(0,a.a>>>b-32)}function K(a,b,c){return new m(a.a&b.a^~a.a&c.a,a.b&b.b^~a.b&c.b)}function L(a,b,c){return new m(a.a&b.a^a.a&c.a^b.a&c.a,a.b&b.b^a.b&c.b^b.b&c.b)}function M(a){var b=q(a,28),c=q(a,34);a=q(a,39);return new m(b.a^c.a^a.a,b.b^c.b^a.b)}function N(a){var b=q(a,14),c=q(a,18);a=q(a,41);return new m(b.a^c.a^a.a,b.b^c.b^a.b)}function O(a){var b= -q(a,1),c=q(a,8);a=I(a,7);return new m(b.a^c.a^a.a,b.b^c.b^a.b)}function P(a){var b=q(a,19),c=q(a,61);a=I(a,6);return new m(b.a^c.a^a.a,b.b^c.b^a.b)}function Q(a,b){var c,f,g;c=(a.b&65535)+(b.b&65535);f=(a.b>>>16)+(b.b>>>16)+(c>>>16);g=(f&65535)<<16|c&65535;c=(a.a&65535)+(b.a&65535)+(f>>>16);f=(a.a>>>16)+(b.a>>>16)+(c>>>16);return new m((f&65535)<<16|c&65535,g)}function R(a,b,c,f){var g,l,h;g=(a.b&65535)+(b.b&65535)+(c.b&65535)+(f.b&65535);l=(a.b>>>16)+(b.b>>>16)+(c.b>>>16)+(f.b>>>16)+(g>>>16);h=(l& -65535)<<16|g&65535;g=(a.a&65535)+(b.a&65535)+(c.a&65535)+(f.a&65535)+(l>>>16);l=(a.a>>>16)+(b.a>>>16)+(c.a>>>16)+(f.a>>>16)+(g>>>16);return new m((l&65535)<<16|g&65535,h)}function S(a,b,c,f,g){var l,h,s;l=(a.b&65535)+(b.b&65535)+(c.b&65535)+(f.b&65535)+(g.b&65535);h=(a.b>>>16)+(b.b>>>16)+(c.b>>>16)+(f.b>>>16)+(g.b>>>16)+(l>>>16);s=(h&65535)<<16|l&65535;l=(a.a&65535)+(b.a&65535)+(c.a&65535)+(f.a&65535)+(g.a&65535)+(h>>>16);h=(a.a>>>16)+(b.a>>>16)+(c.a>>>16)+(f.a>>>16)+(g.a>>>16)+(l>>>16);return new m((h& -65535)<<16|l&65535,s)}function u(a,b,c){var f,g,l,h,s,q,u,C,v,d,n,p,r,w,H,t,y,z,A,B,D,E,F,G,e,x=[],I,k=[1116352408,1899447441,3049323471,3921009573,961987163,1508970993,2453635748,2870763221,3624381080,310598401,607225278,1426881987,1925078388,2162078206,2614888103,3248222580,3835390401,4022224774,264347078,604807628,770255983,1249150122,1555081692,1996064986,2554220882,2821834349,2952996808,3210313671,3336571891,3584528711,113926993,338241895,666307205,773529912,1294757372,1396182291,1695183700, -1986661051,2177026350,2456956037,2730485921,2820302411,3259730800,3345764771,3516065817,3600352804,4094571909,275423344,430227734,506948616,659060556,883997877,958139571,1322822218,1537002063,1747873779,1955562222,2024104815,2227730452,2361852424,2428436474,2756734187,3204031479,3329325298];d=[3238371032,914150663,812702999,4144912697,4290775857,1750603025,1694076839,3204075428];g=[1779033703,3144134277,1013904242,2773480762,1359893119,2600822924,528734635,1541459225];if("SHA-384"===c||"SHA-512"=== -c)n=80,f=(b+128>>>10<<5)+31,w=32,H=2,e=m,t=Q,y=R,z=S,A=O,B=P,D=M,E=N,G=L,F=K,k=[new e(k[0],3609767458),new e(k[1],602891725),new e(k[2],3964484399),new e(k[3],2173295548),new e(k[4],4081628472),new e(k[5],3053834265),new e(k[6],2937671579),new e(k[7],3664609560),new e(k[8],2734883394),new e(k[9],1164996542),new e(k[10],1323610764),new e(k[11],3590304994),new e(k[12],4068182383),new e(k[13],991336113),new e(k[14],633803317),new e(k[15],3479774868),new e(k[16],2666613458),new e(k[17],944711139),new e(k[18], -2341262773),new e(k[19],2007800933),new e(k[20],1495990901),new e(k[21],1856431235),new e(k[22],3175218132),new e(k[23],2198950837),new e(k[24],3999719339),new e(k[25],766784016),new e(k[26],2566594879),new e(k[27],3203337956),new e(k[28],1034457026),new e(k[29],2466948901),new e(k[30],3758326383),new e(k[31],168717936),new e(k[32],1188179964),new e(k[33],1546045734),new e(k[34],1522805485),new e(k[35],2643833823),new e(k[36],2343527390),new e(k[37],1014477480),new e(k[38],1206759142),new e(k[39], -344077627),new e(k[40],1290863460),new e(k[41],3158454273),new e(k[42],3505952657),new e(k[43],106217008),new e(k[44],3606008344),new e(k[45],1432725776),new e(k[46],1467031594),new e(k[47],851169720),new e(k[48],3100823752),new e(k[49],1363258195),new e(k[50],3750685593),new e(k[51],3785050280),new e(k[52],3318307427),new e(k[53],3812723403),new e(k[54],2003034995),new e(k[55],3602036899),new e(k[56],1575990012),new e(k[57],1125592928),new e(k[58],2716904306),new e(k[59],442776044),new e(k[60],593698344), -new e(k[61],3733110249),new e(k[62],2999351573),new e(k[63],3815920427),new e(3391569614,3928383900),new e(3515267271,566280711),new e(3940187606,3454069534),new e(4118630271,4000239992),new e(116418474,1914138554),new e(174292421,2731055270),new e(289380356,3203993006),new e(460393269,320620315),new e(685471733,587496836),new e(852142971,1086792851),new e(1017036298,365543100),new e(1126000580,2618297676),new e(1288033470,3409855158),new e(1501505948,4234509866),new e(1607167915,987167468),new e(1816402316, -1246189591)],d="SHA-384"===c?[new e(3418070365,d[0]),new e(1654270250,d[1]),new e(2438529370,d[2]),new e(355462360,d[3]),new e(1731405415,d[4]),new e(41048885895,d[5]),new e(3675008525,d[6]),new e(1203062813,d[7])]:[new e(g[0],4089235720),new e(g[1],2227873595),new e(g[2],4271175723),new e(g[3],1595750129),new e(g[4],2917565137),new e(g[5],725511199),new e(g[6],4215389547),new e(g[7],327033209)];else throw"Unexpected error in SHA-2 implementation";for(;a.length<=f;)a.push(0);a[b>>>5]|=128<<24-b%32; -a[f]=b;I=a.length;for(p=0;p<I;p+=w){b=d[0];f=d[1];g=d[2];l=d[3];h=d[4];s=d[5];q=d[6];u=d[7];for(r=0;r<n;r+=1)16>r?(v=r*H+p,C=a.length<=v?0:a[v],v=a.length<=v+1?0:a[v+1],x[r]=new e(C,v)):x[r]=y(B(x[r-2]),x[r-7],A(x[r-15]),x[r-16]),C=z(u,E(h),F(h,s,q),k[r],x[r]),v=t(D(b),G(b,f,g)),u=q,q=s,s=h,h=t(l,C),l=g,g=f,f=b,b=t(C,v);d[0]=t(b,d[0]);d[1]=t(f,d[1]);d[2]=t(g,d[2]);d[3]=t(l,d[3]);d[4]=t(h,d[4]);d[5]=t(s,d[5]);d[6]=t(q,d[6]);d[7]=t(u,d[7])}if("SHA-384"===c)a=[d[0].a,d[0].b,d[1].a,d[1].b,d[2].a,d[2].b, -d[3].a,d[3].b,d[4].a,d[4].b,d[5].a,d[5].b];else if("SHA-512"===c)a=[d[0].a,d[0].b,d[1].a,d[1].b,d[2].a,d[2].b,d[3].a,d[3].b,d[4].a,d[4].b,d[5].a,d[5].b,d[6].a,d[6].b,d[7].a,d[7].b];else throw"Unexpected error in SHA-2 implementation";return a}"function"===typeof define&&define.amd?define(function(){return w}):"undefined"!==typeof exports?"undefined"!==typeof module&&module.exports?module.exports=exports=w:exports=w:J.jsSHA=w})(this); +'use strict';(function(K){function x(p,c,a){var b=0,f=[],e=0,g,h,m,k,l,r,t,n=!1,u=!1,v=[],A=[],w,B=!1;a=a||{};g=a.encoding||"UTF8";w=a.numRounds||1;m=C(c,g);if(w!==parseInt(w,10)||1>w)throw Error("numRounds must a integer >= 1");r=function(c,a){return D(c,a,p)};t=function(c,a,d,e){var f,b;if("SHA-384"===p||"SHA-512"===p)f=(a+136>>>10<<5)+31,b=32;else throw Error("Unexpected error in SHA-2 implementation");for(;c.length<=f;)c.push(0);c[a>>>5]|=128<<24-a%32;c[f]=a+d;d=c.length;for(a=0;a<d;a+=b)e=D(c.slice(a, +a+b),e,p);if("SHA-384"===p)c=[e[0].a,e[0].b,e[1].a,e[1].b,e[2].a,e[2].b,e[3].a,e[3].b,e[4].a,e[4].b,e[5].a,e[5].b];else if("SHA-512"===p)c=[e[0].a,e[0].b,e[1].a,e[1].b,e[2].a,e[2].b,e[3].a,e[3].b,e[4].a,e[4].b,e[5].a,e[5].b,e[6].a,e[6].b,e[7].a,e[7].b];else throw Error("Unexpected error in SHA-2 implementation");return c};if("SHA-384"===p)l=1024,k=384;else if("SHA-512"===p)l=1024,k=512;else throw Error("Chosen SHA variant is not supported");h=y(p);this.setHMACKey=function(c,a,d){var e;if(!0===u)throw Error("HMAC key already set"); +if(!0===n)throw Error("Cannot set HMAC key after finalizing hash");if(!0===B)throw Error("Cannot set HMAC key after calling update");g=(d||{}).encoding||"UTF8";a=C(a,g)(c);c=a.binLen;a=a.value;e=l>>>3;d=e/4-1;if(e<c/8){for(a=t(a,c,0,y(p));a.length<=d;)a.push(0);a[d]&=4294967040}else if(e>c/8){for(;a.length<=d;)a.push(0);a[d]&=4294967040}for(c=0;c<=d;c+=1)v[c]=a[c]^909522486,A[c]=a[c]^1549556828;h=r(v,h);b=l;u=!0};this.update=function(c){var a,p,d,g=0,k=l>>>5;a=m(c,f,e);c=a.binLen;p=a.value;a=c>>> +5;for(d=0;d<a;d+=k)g+l<=c&&(h=r(p.slice(d,d+k),h),g+=l);b+=g;f=p.slice(g>>>5);e=c%l;B=!0};this.getHash=function(c,a){var d,g,l;if(!0===u)throw Error("Cannot call getHash after setting HMAC key");l=E(a);switch(c){case "HEX":d=function(c){return F(c,l)};break;case "B64":d=function(c){return G(c,l)};break;case "BYTES":d=H;break;default:throw Error("format must be HEX, B64, or BYTES");}if(!1===n)for(h=t(f,e,b,h),g=1;g<w;g+=1)h=t(h,k,0,y(p));n=!0;return d(h)};this.getHMAC=function(c,a){var d,g,m;if(!1=== +u)throw Error("Cannot call getHMAC without first setting HMAC key");m=E(a);switch(c){case "HEX":d=function(c){return F(c,m)};break;case "B64":d=function(c){return G(c,m)};break;case "BYTES":d=H;break;default:throw Error("outputFormat must be HEX, B64, or BYTES");}!1===n&&(g=t(f,e,b,h),h=r(A,y(p)),h=t(g,k,l,h));n=!0;return d(h)}}function a(a,c){this.a=a;this.b=c}function L(a,c,d){var b=a.length,f,e,g,h,m;c=c||[0];d=d||0;m=d>>>3;if(0!==b%2)throw Error("String of HEX type must be in byte increments"); +for(f=0;f<b;f+=2){e=parseInt(a.substr(f,2),16);if(isNaN(e))throw Error("String of HEX type contains invalid characters");h=(f>>>1)+m;for(g=h>>>2;c.length<=g;)c.push(0);c[g]|=e<<8*(3-h%4)}return{value:c,binLen:4*b+d}}function M(a,c,d){var b=[],f,e,g,h,b=c||[0];d=d||0;e=d>>>3;for(f=0;f<a.length;f+=1)c=a.charCodeAt(f),h=f+e,g=h>>>2,b.length<=g&&b.push(0),b[g]|=c<<8*(3-h%4);return{value:b,binLen:8*a.length+d}}function N(a,c,d){var b=[],f=0,e,g,h,m,k,l,b=c||[0];d=d||0;c=d>>>3;if(-1===a.search(/^[a-zA-Z0-9=+\/]+$/))throw Error("Invalid character in base-64 string"); +g=a.indexOf("=");a=a.replace(/\=/g,"");if(-1!==g&&g<a.length)throw Error("Invalid '=' found in base-64 string");for(g=0;g<a.length;g+=4){k=a.substr(g,4);for(h=m=0;h<k.length;h+=1)e="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/".indexOf(k[h]),m|=e<<18-6*h;for(h=0;h<k.length-1;h+=1){l=f+c;for(e=l>>>2;b.length<=e;)b.push(0);b[e]|=(m>>>16-8*h&255)<<8*(3-l%4);f+=1}}return{value:b,binLen:8*f+d}}function F(a,c){var d="",b=4*a.length,f,e;for(f=0;f<b;f+=1)e=a[f>>>2]>>>8*(3-f%4),d+="0123456789abcdef".charAt(e>>> +4&15)+"0123456789abcdef".charAt(e&15);return c.outputUpper?d.toUpperCase():d}function G(a,c){var d="",b=4*a.length,f,e,g;for(f=0;f<b;f+=3)for(g=f+1>>>2,e=a.length<=g?0:a[g],g=f+2>>>2,g=a.length<=g?0:a[g],g=(a[f>>>2]>>>8*(3-f%4)&255)<<16|(e>>>8*(3-(f+1)%4)&255)<<8|g>>>8*(3-(f+2)%4)&255,e=0;4>e;e+=1)8*f+6*e<=32*a.length?d+="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/".charAt(g>>>6*(3-e)&63):d+=c.b64Pad;return d}function H(a){var c="",d=4*a.length,b,f;for(b=0;b<d;b+=1)f=a[b>>>2]>>> +8*(3-b%4)&255,c+=String.fromCharCode(f);return c}function E(a){var c={outputUpper:!1,b64Pad:"="};a=a||{};c.outputUpper=a.outputUpper||!1;c.b64Pad=a.b64Pad||"=";if("boolean"!==typeof c.outputUpper)throw Error("Invalid outputUpper formatting option");if("string"!==typeof c.b64Pad)throw Error("Invalid b64Pad formatting option");return c}function C(a,c){var d;switch(c){case "UTF8":case "UTF16BE":case "UTF16LE":break;default:throw Error("encoding must be UTF8, UTF16BE, or UTF16LE");}switch(a){case "HEX":d= +L;break;case "TEXT":d=function(a,d,e){var b=[],p=[],m=0,k,l,r,t,n,b=d||[0];d=e||0;r=d>>>3;if("UTF8"===c)for(k=0;k<a.length;k+=1)for(e=a.charCodeAt(k),p=[],128>e?p.push(e):2048>e?(p.push(192|e>>>6),p.push(128|e&63)):55296>e||57344<=e?p.push(224|e>>>12,128|e>>>6&63,128|e&63):(k+=1,e=65536+((e&1023)<<10|a.charCodeAt(k)&1023),p.push(240|e>>>18,128|e>>>12&63,128|e>>>6&63,128|e&63)),l=0;l<p.length;l+=1){n=m+r;for(t=n>>>2;b.length<=t;)b.push(0);b[t]|=p[l]<<8*(3-n%4);m+=1}else if("UTF16BE"===c||"UTF16LE"=== +c)for(k=0;k<a.length;k+=1){e=a.charCodeAt(k);"UTF16LE"===c&&(l=e&255,e=l<<8|e>>>8);n=m+r;for(t=n>>>2;b.length<=t;)b.push(0);b[t]|=e<<8*(2-n%4);m+=2}return{value:b,binLen:8*m+d}};break;case "B64":d=N;break;case "BYTES":d=M;break;default:throw Error("format must be HEX, TEXT, B64, or BYTES");}return d}function u(b,c){var d=null,d=new a(b.a,b.b);return d=32>=c?new a(d.a>>>c|d.b<<32-c&4294967295,d.b>>>c|d.a<<32-c&4294967295):new a(d.b>>>c-32|d.a<<64-c&4294967295,d.a>>>c-32|d.b<<64-c&4294967295)}function I(b, +c){var d=null;return d=32>=c?new a(b.a>>>c,b.b>>>c|b.a<<32-c&4294967295):new a(0,b.a>>>c-32)}function O(b,c,d){return new a(b.a&c.a^~b.a&d.a,b.b&c.b^~b.b&d.b)}function P(b,c,d){return new a(b.a&c.a^b.a&d.a^c.a&d.a,b.b&c.b^b.b&d.b^c.b&d.b)}function Q(b){var c=u(b,28),d=u(b,34);b=u(b,39);return new a(c.a^d.a^b.a,c.b^d.b^b.b)}function R(b){var c=u(b,14),d=u(b,18);b=u(b,41);return new a(c.a^d.a^b.a,c.b^d.b^b.b)}function S(b){var c=u(b,1),d=u(b,8);b=I(b,7);return new a(c.a^d.a^b.a,c.b^d.b^b.b)}function T(b){var c= +u(b,19),d=u(b,61);b=I(b,6);return new a(c.a^d.a^b.a,c.b^d.b^b.b)}function U(b,c){var d,q,f;d=(b.b&65535)+(c.b&65535);q=(b.b>>>16)+(c.b>>>16)+(d>>>16);f=(q&65535)<<16|d&65535;d=(b.a&65535)+(c.a&65535)+(q>>>16);q=(b.a>>>16)+(c.a>>>16)+(d>>>16);return new a((q&65535)<<16|d&65535,f)}function V(b,c,d,q){var f,e,g;f=(b.b&65535)+(c.b&65535)+(d.b&65535)+(q.b&65535);e=(b.b>>>16)+(c.b>>>16)+(d.b>>>16)+(q.b>>>16)+(f>>>16);g=(e&65535)<<16|f&65535;f=(b.a&65535)+(c.a&65535)+(d.a&65535)+(q.a&65535)+(e>>>16);e=(b.a>>> +16)+(c.a>>>16)+(d.a>>>16)+(q.a>>>16)+(f>>>16);return new a((e&65535)<<16|f&65535,g)}function W(b,c,d,q,f){var e,g,h;e=(b.b&65535)+(c.b&65535)+(d.b&65535)+(q.b&65535)+(f.b&65535);g=(b.b>>>16)+(c.b>>>16)+(d.b>>>16)+(q.b>>>16)+(f.b>>>16)+(e>>>16);h=(g&65535)<<16|e&65535;e=(b.a&65535)+(c.a&65535)+(d.a&65535)+(q.a&65535)+(f.a&65535)+(g>>>16);g=(b.a>>>16)+(c.a>>>16)+(d.a>>>16)+(q.a>>>16)+(f.a>>>16)+(e>>>16);return new a((g&65535)<<16|e&65535,h)}function y(b){var c,d;c=[3238371032,914150663,812702999,4144912697, +4290775857,1750603025,1694076839,3204075428];d=[1779033703,3144134277,1013904242,2773480762,1359893119,2600822924,528734635,1541459225];switch(b){case "SHA-224":b=c;break;case "SHA-256":b=d;break;case "SHA-384":b=[new a(3418070365,c[0]),new a(1654270250,c[1]),new a(2438529370,c[2]),new a(355462360,c[3]),new a(1731405415,c[4]),new a(41048885895,c[5]),new a(3675008525,c[6]),new a(1203062813,c[7])];break;case "SHA-512":b=[new a(d[0],4089235720),new a(d[1],2227873595),new a(d[2],4271175723),new a(d[3], +1595750129),new a(d[4],2917565137),new a(d[5],725511199),new a(d[6],4215389547),new a(d[7],327033209)];break;default:throw Error("Unknown SHA variant");}return b}function D(b,c,d){var q,f,e,g,h,m,k,l,r,t,n,u,v,A,w,B,x,y,C,D,E,F,z=[],G;if("SHA-384"===d||"SHA-512"===d)t=80,u=2,F=a,v=U,A=V,w=W,B=S,x=T,y=Q,C=R,E=P,D=O,G=J;else throw Error("Unexpected error in SHA-2 implementation");d=c[0];q=c[1];f=c[2];e=c[3];g=c[4];h=c[5];m=c[6];k=c[7];for(n=0;n<t;n+=1)16>n?(r=n*u,l=b.length<=r?0:b[r],r=b.length<=r+ +1?0:b[r+1],z[n]=new F(l,r)):z[n]=A(x(z[n-2]),z[n-7],B(z[n-15]),z[n-16]),l=w(k,C(g),D(g,h,m),G[n],z[n]),r=v(y(d),E(d,q,f)),k=m,m=h,h=g,g=v(e,l),e=f,f=q,q=d,d=v(l,r);c[0]=v(d,c[0]);c[1]=v(q,c[1]);c[2]=v(f,c[2]);c[3]=v(e,c[3]);c[4]=v(g,c[4]);c[5]=v(h,c[5]);c[6]=v(m,c[6]);c[7]=v(k,c[7]);return c}var b,J;b=[1116352408,1899447441,3049323471,3921009573,961987163,1508970993,2453635748,2870763221,3624381080,310598401,607225278,1426881987,1925078388,2162078206,2614888103,3248222580,3835390401,4022224774,264347078, +604807628,770255983,1249150122,1555081692,1996064986,2554220882,2821834349,2952996808,3210313671,3336571891,3584528711,113926993,338241895,666307205,773529912,1294757372,1396182291,1695183700,1986661051,2177026350,2456956037,2730485921,2820302411,3259730800,3345764771,3516065817,3600352804,4094571909,275423344,430227734,506948616,659060556,883997877,958139571,1322822218,1537002063,1747873779,1955562222,2024104815,2227730452,2361852424,2428436474,2756734187,3204031479,3329325298];J=[new a(b[0],3609767458), +new a(b[1],602891725),new a(b[2],3964484399),new a(b[3],2173295548),new a(b[4],4081628472),new a(b[5],3053834265),new a(b[6],2937671579),new a(b[7],3664609560),new a(b[8],2734883394),new a(b[9],1164996542),new a(b[10],1323610764),new a(b[11],3590304994),new a(b[12],4068182383),new a(b[13],991336113),new a(b[14],633803317),new a(b[15],3479774868),new a(b[16],2666613458),new a(b[17],944711139),new a(b[18],2341262773),new a(b[19],2007800933),new a(b[20],1495990901),new a(b[21],1856431235),new a(b[22], +3175218132),new a(b[23],2198950837),new a(b[24],3999719339),new a(b[25],766784016),new a(b[26],2566594879),new a(b[27],3203337956),new a(b[28],1034457026),new a(b[29],2466948901),new a(b[30],3758326383),new a(b[31],168717936),new a(b[32],1188179964),new a(b[33],1546045734),new a(b[34],1522805485),new a(b[35],2643833823),new a(b[36],2343527390),new a(b[37],1014477480),new a(b[38],1206759142),new a(b[39],344077627),new a(b[40],1290863460),new a(b[41],3158454273),new a(b[42],3505952657),new a(b[43], +106217008),new a(b[44],3606008344),new a(b[45],1432725776),new a(b[46],1467031594),new a(b[47],851169720),new a(b[48],3100823752),new a(b[49],1363258195),new a(b[50],3750685593),new a(b[51],3785050280),new a(b[52],3318307427),new a(b[53],3812723403),new a(b[54],2003034995),new a(b[55],3602036899),new a(b[56],1575990012),new a(b[57],1125592928),new a(b[58],2716904306),new a(b[59],442776044),new a(b[60],593698344),new a(b[61],3733110249),new a(b[62],2999351573),new a(b[63],3815920427),new a(3391569614, +3928383900),new a(3515267271,566280711),new a(3940187606,3454069534),new a(4118630271,4000239992),new a(116418474,1914138554),new a(174292421,2731055270),new a(289380356,3203993006),new a(460393269,320620315),new a(685471733,587496836),new a(852142971,1086792851),new a(1017036298,365543100),new a(1126000580,2618297676),new a(1288033470,3409855158),new a(1501505948,4234509866),new a(1607167915,987167468),new a(1816402316,1246189591)];"function"===typeof define&&define.amd?define(function(){return x}): +"undefined"!==typeof exports?"undefined"!==typeof module&&module.exports?module.exports=exports=x:exports=x:K.jsSHA=x})(this); diff --git a/src/sha_dev.js b/src/sha_dev.js index 34ab870..58e4fd8 100644 --- a/src/sha_dev.js +++ b/src/sha_dev.js @@ -41,17 +41,31 @@ var SUPPORTED_ALGS = 4 | 2 | 1; /** * Convert a string to an array of big-endian words * + * There is a known bug with an odd number of existing bytes and using a + * UTF-16 encoding. However, this function is used such that the existing + * bytes are always a result of a previous UTF-16 str2binb call and + * therefore there should never be an odd number of existing bytes + * * @private * @param {string} str String to be converted to binary representation * @param {string} utfType The Unicode type, UTF8 or UTF16BE, UTF16LE, to * use to encode the source string + * @param {Array.<number>} existingBin A packed int array of bytes to + * append the results to + * @param {number} existingBinLen The number of bits in the existingBin + * array * @return {{value : Array.<number>, binLen : number}} Hash list where * "value" contains the output number array and "binLen" is the binary * length of "value" */ - function str2binb(str, utfType) + function str2binb(str, utfType, existingBin, existingBinLen) { - var bin = [], codePnt, binArr = [], byteCnt = 0, i, j, offset; + var bin = [], codePnt, binArr = [], byteCnt = 0, i, j, existingByteLen, + intOffset, byteOffset; + + bin = existingBin || [0]; + existingBinLen = existingBinLen || 0; + existingByteLen = existingBinLen >>> 3; if ("UTF8" === utfType) { @@ -90,12 +104,14 @@ var SUPPORTED_ALGS = 4 | 2 | 1; for (j = 0; j < binArr.length; j += 1) { - offset = byteCnt >>> 2; - while (bin.length <= offset) + byteOffset = byteCnt + existingByteLen; + intOffset = byteOffset >>> 2; + while (bin.length <= intOffset) { bin.push(0); } - bin[offset] |= binArr[j] << (24 - (8 * (byteCnt % 4))); + /* Known bug kicks in here */ + bin[intOffset] |= binArr[j] << (8 * (3 - (byteOffset % 4))); byteCnt += 1; } } @@ -109,19 +125,20 @@ var SUPPORTED_ALGS = 4 | 2 | 1; if ("UTF16LE" === utfType) { j = codePnt & 0xFF; - codePnt = (j << 8) | (codePnt >> 8); + codePnt = (j << 8) | (codePnt >>> 8); } - offset = byteCnt >>> 2; - while (bin.length <= offset) + byteOffset = byteCnt + existingByteLen; + intOffset = byteOffset >>> 2; + while (bin.length <= intOffset) { bin.push(0); } - bin[offset] |= codePnt << (16 - (8 * (byteCnt % 4))); + bin[intOffset] |= codePnt << (8 * (2 - (byteOffset % 4))); byteCnt += 2; } } - return {"value" : bin, "binLen" : byteCnt * 8}; + return {"value" : bin, "binLen" : byteCnt * 8 + existingBinLen}; } /** @@ -129,17 +146,26 @@ var SUPPORTED_ALGS = 4 | 2 | 1; * * @private * @param {string} str String to be converted to binary representation + * @param {Array.<number>} existingBin A packed int array of bytes to + * append the results to + * @param {number} existingBinLen The number of bits in the existingBin + * array * @return {{value : Array.<number>, binLen : number}} Hash list where * "value" contains the output number array and "binLen" is the binary * length of "value" */ - function hex2binb(str) + function hex2binb(str, existingBin, existingBinLen) { - var bin = [], length = str.length, i, num, offset; + var bin, length = str.length, i, num, intOffset, byteOffset, + existingByteLen; + + bin = existingBin || [0]; + existingBinLen = existingBinLen || 0; + existingByteLen = existingBinLen >>> 3; if (0 !== (length % 2)) { - throw "String of HEX type must be in byte increments"; + throw new Error("String of HEX type must be in byte increments"); } for (i = 0; i < length; i += 2) @@ -147,48 +173,59 @@ var SUPPORTED_ALGS = 4 | 2 | 1; num = parseInt(str.substr(i, 2), 16); if (!isNaN(num)) { - offset = i >>> 3; - while (bin.length <= offset) + byteOffset = (i >>> 1) + existingByteLen; + intOffset = byteOffset >>> 2; + while (bin.length <= intOffset) { bin.push(0); } - bin[i >>> 3] |= num << (24 - (4 * (i % 8))); + bin[intOffset] |= num << 8 * (3 - (byteOffset % 4)); } else { - throw "String of HEX type contains invalid characters"; + throw new Error("String of HEX type contains invalid characters"); } } - return {"value" : bin, "binLen" : length * 4}; + return {"value" : bin, "binLen" : length * 4 + existingBinLen}; } - /** + /** * Convert a string of raw bytes to an array of big-endian words * * @private * @param {string} str String of raw bytes to be converted to binary representation + * @param {Array.<number>} existingBin A packed int array of bytes to + * append the results to + * @param {number} existingBinLen The number of bits in the existingBin + * array * @return {{value : Array.<number>, binLen : number}} Hash list where * "value" contains the output number array and "binLen" is the binary * length of "value" */ - function bytes2binb(str) + function bytes2binb(str, existingBin, existingBinLen) { - var bin = [], codePnt, i, offset; + var bin = [], codePnt, i, existingByteLen, intOffset, + byteOffset; + + bin = existingBin || [0]; + existingBinLen = existingBinLen || 0; + existingByteLen = existingBinLen >>> 3; for (i = 0; i < str.length; i += 1) { codePnt = str.charCodeAt(i); - offset = i >>> 2; - if (bin.length <= offset) + byteOffset = i + existingByteLen; + intOffset = byteOffset >>> 2; + if (bin.length <= intOffset) { bin.push(0); } - bin[offset] |= codePnt << (24 - (8 * (i % 4))); + bin[intOffset] |= codePnt << 8 * (3 - (byteOffset % 4)); } - return {"value" : bin, "binLen" : str.length * 8}; + return {"value" : bin, "binLen" : str.length * 8 + existingBinLen}; } /** @@ -196,24 +233,33 @@ var SUPPORTED_ALGS = 4 | 2 | 1; * * @private * @param {string} str String to be converted to binary representation + * @param {Array.<number>} existingBin A packed int array of bytes to + * append the results to + * @param {number} existingBinLen The number of bits in the existingBin + * array * @return {{value : Array.<number>, binLen : number}} Hash list where * "value" contains the output number array and "binLen" is the binary * length of "value" */ - function b642binb(str) + function b642binb(str, existingBin, existingBinLen) { - var retVal = [], byteCnt = 0, index, i, j, tmpInt, strPart, firstEqual, offset, - b64Tab = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; + var bin = [], byteCnt = 0, index, i, j, tmpInt, strPart, firstEqual, + b64Tab = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/", + existingByteLen, intOffset, byteOffset; + + bin = existingBin || [0]; + existingBinLen = existingBinLen || 0; + existingByteLen = existingBinLen >>> 3; if (-1 === str.search(/^[a-zA-Z0-9=+\/]+$/)) { - throw "Invalid character in base-64 string"; + throw new Error("Invalid character in base-64 string"); } firstEqual = str.indexOf('='); str = str.replace(/\=/g, ''); if ((-1 !== firstEqual) && (firstEqual < str.length)) { - throw "Invalid '=' found in base-64 string"; + throw new Error("Invalid '=' found in base-64 string"); } for (i = 0; i < str.length; i += 4) @@ -229,18 +275,19 @@ var SUPPORTED_ALGS = 4 | 2 | 1; for (j = 0; j < strPart.length - 1; j += 1) { - offset = byteCnt >>> 2; - while (retVal.length <= offset) + byteOffset = byteCnt + existingByteLen; + intOffset = byteOffset >>> 2; + while (bin.length <= intOffset) { - retVal.push(0); + bin.push(0); } - retVal[offset] |= ((tmpInt >>> (16 - (j * 8))) & 0xFF) << - (24 - (8 * (byteCnt % 4))); + bin[intOffset] |= ((tmpInt >>> (16 - (j * 8))) & 0xFF) << + 8 * (3 - (byteOffset % 4)); byteCnt += 1; } } - return {"value" : retVal, "binLen" : byteCnt * 8}; + return {"value" : bin, "binLen" : byteCnt * 8 + existingBinLen}; } /** @@ -316,11 +363,10 @@ var SUPPORTED_ALGS = 4 | 2 | 1; * @private * @param {Array.<number>} binarray Array of integers to be converted to * a raw bytes string representation - * @param {!Object} formatOpts Unused Hash list * @return {string} Raw bytes representation of the parameter in string * form */ - function binb2bytes(binarray, formatOpts) + function binb2bytes(binarray) { var str = "", length = binarray.length * 4, i, srcByte; @@ -338,38 +384,82 @@ var SUPPORTED_ALGS = 4 | 2 | 1; * presence of every option or adding the default value * * @private - * @param {{outputUpper : boolean, b64Pad : string}|undefined} outputOpts - * Hash list of output formatting options + * @param {{outputUpper : (boolean|undefined), b64Pad : (string|undefined)}=} + * options Hash list of output formatting options * @return {{outputUpper : boolean, b64Pad : string}} Validated hash list * containing output formatting options */ - function getOutputOpts(outputOpts) + function getOutputOpts(options) { - var retVal = {"outputUpper" : false, "b64Pad" : "="}; + var retVal = {"outputUpper" : false, "b64Pad" : "="}, outputOptions; + outputOptions = options || {}; - try + retVal["outputUpper"] = outputOptions["outputUpper"] || false; + retVal["b64Pad"] = outputOptions["b64Pad"] || "="; + + if ("boolean" !== typeof(retVal["outputUpper"])) { - if (outputOpts.hasOwnProperty("outputUpper")) - { - retVal["outputUpper"] = outputOpts["outputUpper"]; - } + throw new Error("Invalid outputUpper formatting option"); + } - if (outputOpts.hasOwnProperty("b64Pad")) - { - retVal["b64Pad"] = outputOpts["b64Pad"]; - } + if ("string" !== typeof(retVal["b64Pad"])) + { + throw new Error("Invalid b64Pad formatting option"); } - catch(ignore) - {} - if ("boolean" !== typeof(retVal["outputUpper"])) + return retVal; + } + + /** + * Function that takes an input format and UTF encoding and returns the + * appropriate function used to convert the input. + * + * @private + * @param {string} format The format of the string to be converted + * @param {string} utfType The string encoding to use (UTF8, UTF16BE, + * UTF16LE) + * @return {function(string, Array.<number>=, number=): {value : + * Array.<number>, binLen : number}} Function that will convert an input + * string to a packed int array + */ + function getStrConverter(format, utfType) + { + var retVal; + + /* Validate encoding */ + switch (utfType) { - throw "Invalid outputUpper formatting option"; + case "UTF8": + /* Fallthrough */ + case "UTF16BE": + /* Fallthrough */ + case "UTF16LE": + /* Fallthrough */ + break; + default: + throw new Error("encoding must be UTF8, UTF16BE, or UTF16LE"); } - if ("string" !== typeof(retVal["b64Pad"])) + /* Map inputFormat to the appropriate converter */ + switch (format) { - throw "Invalid b64Pad formatting option"; + case "HEX": + retVal = hex2binb; + break; + case "TEXT": + retVal = function(str, existingBin, existingBinLen) + { + return str2binb(str, utfType, existingBin, existingBinLen); + }; + break; + case "B64": + retVal = b642binb; + break; + case "BYTES": + retVal = bytes2binb; + break; + default: + throw new Error("format must be HEX, TEXT, B64, or BYTES"); } return retVal; @@ -820,132 +910,269 @@ var SUPPORTED_ALGS = 4 | 2 | 1; } /** - * Calculates the SHA-1 hash of the string set at instantiation + * Gets the H values for the specified SHA variant + * + * @param {string} variant The SHA variant + * @return {Array.<number|Int_64>} The initial H values + */ + function getH(variant) + { + var retVal, H_trunc, H_full; + + if (("SHA-1" === variant) && (1 & SUPPORTED_ALGS)) + { + retVal = [ + 0x67452301, 0xefcdab89, 0x98badcfe, 0x10325476, 0xc3d2e1f0 + ]; + } + else if (6 & SUPPORTED_ALGS) + { + H_trunc = [ + 0xc1059ed8, 0x367cd507, 0x3070dd17, 0xf70e5939, + 0xffc00b31, 0x68581511, 0x64f98fa7, 0xbefa4fa4 + ]; + H_full = [ + 0x6A09E667, 0xBB67AE85, 0x3C6EF372, 0xA54FF53A, + 0x510E527F, 0x9B05688C, 0x1F83D9AB, 0x5BE0CD19 + ]; + + switch (variant) + { + case "SHA-224": + retVal = H_trunc; + break; + case "SHA-256": + retVal = H_full; + break; + case "SHA-384": + retVal = [ + new Int_64(0xcbbb9d5d, H_trunc[0]), + new Int_64(0x0629a292a, H_trunc[1]), + new Int_64(0x9159015a, H_trunc[2]), + new Int_64(0x0152fecd8, H_trunc[3]), + new Int_64(0x67332667, H_trunc[4]), + new Int_64(0x98eb44a87, H_trunc[5]), + new Int_64(0xdb0c2e0d, H_trunc[6]), + new Int_64(0x047b5481d, H_trunc[7]) + ]; + break; + case "SHA-512": + retVal = [ + new Int_64(H_full[0], 0xf3bcc908), + new Int_64(H_full[1], 0x84caa73b), + new Int_64(H_full[2], 0xfe94f82b), + new Int_64(H_full[3], 0x5f1d36f1), + new Int_64(H_full[4], 0xade682d1), + new Int_64(H_full[5], 0x2b3e6c1f), + new Int_64(H_full[6], 0xfb41bd6b), + new Int_64(H_full[7], 0x137e2179) + ]; + break; + default: + throw new Error("Unknown SHA variant"); + } + } + else + { + throw new Error("No SHA variants supported"); + } + + return retVal; + } + + /** + * Performs a round of SHA-1 hashing over a 512-byte block * * @private - * @param {Array.<number>} message The binary array representation of the - * string to hash - * @param {number} messageLen The number of bits in the message + * @param {Array.<number>} block The binary array representation of the + * block to hash + * @param {Array.<number>} H The intermediate H values from a previous + * round + * @return {Array.<number>} The resulting H values + */ + function roundSHA1(block, H) + { + var W = [], a, b, c, d, e, T, ch = ch_32, parity = parity_32, + maj = maj_32, rotl = rotl_32, safeAdd_2 = safeAdd_32_2, t, + safeAdd_5 = safeAdd_32_5; + + a = H[0]; + b = H[1]; + c = H[2]; + d = H[3]; + e = H[4]; + + for (t = 0; t < 80; t += 1) + { + if (t < 16) + { + W[t] = block[t]; + } + else + { + W[t] = rotl(W[t - 3] ^ W[t - 8] ^ W[t - 14] ^ W[t - 16], 1); + } + + if (t < 20) + { + T = safeAdd_5(rotl(a, 5), ch(b, c, d), e, 0x5a827999, W[t]); + } + else if (t < 40) + { + T = safeAdd_5(rotl(a, 5), parity(b, c, d), e, 0x6ed9eba1, W[t]); + } + else if (t < 60) + { + T = safeAdd_5(rotl(a, 5), maj(b, c, d), e, 0x8f1bbcdc, W[t]); + } else { + T = safeAdd_5(rotl(a, 5), parity(b, c, d), e, 0xca62c1d6, W[t]); + } + + e = d; + d = c; + c = rotl(b, 30); + b = a; + a = T; + } + + H[0] = safeAdd_2(a, H[0]); + H[1] = safeAdd_2(b, H[1]); + H[2] = safeAdd_2(c, H[2]); + H[3] = safeAdd_2(d, H[3]); + H[4] = safeAdd_2(e, H[4]); + + return H; + } + + /** + * Finalizes the SHA-1 hash + * + * @private + * @param {Array.<number>} remainder Any leftover unprocessed packed ints + * that still need to be processed + * @param {number} remainderBinLen The number of bits in remainder + * @param {number} processedBinLen The number of bits already + * processed + * @param {Array.<number>} H The intermediate H values from a previous + * round * @return {Array.<number>} The array of integers representing the SHA-1 * hash of message */ - function coreSHA1(message, messageLen) + function finalizeSHA1(remainder, remainderBinLen, processedBinLen, H) { - var W = [], a, b, c, d, e, T, ch = ch_32, parity = parity_32, - maj = maj_32, rotl = rotl_32, safeAdd_2 = safeAdd_32_2, i, t, - safeAdd_5 = safeAdd_32_5, appendedMessageLength, offset, - H = [ - 0x67452301, 0xefcdab89, 0x98badcfe, 0x10325476, 0xc3d2e1f0 - ]; + var i, appendedMessageLength, offset; - offset = (((messageLen + 65) >>> 9) << 4) + 15; - while (message.length <= offset) + /* Add 72 because of the 64-bit length and the extra byte because + of the bit (actually a byte) append */ + offset = (((remainderBinLen + 72) >>> 9) << 4) + 15; + while (remainder.length <= offset) { - message.push(0); + remainder.push(0); } /* Append '1' at the end of the binary string */ - message[messageLen >>> 5] |= 0x80 << (24 - (messageLen % 32)); + remainder[remainderBinLen >>> 5] |= 0x80 << (24 - (remainderBinLen % 32)); /* Append length of binary string in the position such that the new length is a multiple of 512. Logic does not work for even multiples of 512 but there can never be even multiples of 512 */ - message[offset] = messageLen; + remainder[offset] = remainderBinLen + processedBinLen; - appendedMessageLength = message.length; + appendedMessageLength = remainder.length; + /* This will always be at least 1 full chunk */ for (i = 0; i < appendedMessageLength; i += 16) { - a = H[0]; - b = H[1]; - c = H[2]; - d = H[3]; - e = H[4]; - - for (t = 0; t < 80; t += 1) - { - if (t < 16) - { - W[t] = message[t + i]; - } - else - { - W[t] = rotl(W[t - 3] ^ W[t - 8] ^ W[t - 14] ^ W[t - 16], 1); - } - - if (t < 20) - { - T = safeAdd_5(rotl(a, 5), ch(b, c, d), e, 0x5a827999, W[t]); - } - else if (t < 40) - { - T = safeAdd_5(rotl(a, 5), parity(b, c, d), e, 0x6ed9eba1, W[t]); - } - else if (t < 60) - { - T = safeAdd_5(rotl(a, 5), maj(b, c, d), e, 0x8f1bbcdc, W[t]); - } else { - T = safeAdd_5(rotl(a, 5), parity(b, c, d), e, 0xca62c1d6, W[t]); - } - - e = d; - d = c; - c = rotl(b, 30); - b = a; - a = T; - } - - H[0] = safeAdd_2(a, H[0]); - H[1] = safeAdd_2(b, H[1]); - H[2] = safeAdd_2(c, H[2]); - H[3] = safeAdd_2(d, H[3]); - H[4] = safeAdd_2(e, H[4]); + H = roundSHA1(remainder.slice(i, i + 16), H); } return H; } + /* Put this here so the K arrays aren't put on the stack for every block */ + var K_sha2, K_sha512; + if (6 & SUPPORTED_ALGS) + { + K_sha2 = [ + 0x428A2F98, 0x71374491, 0xB5C0FBCF, 0xE9B5DBA5, + 0x3956C25B, 0x59F111F1, 0x923F82A4, 0xAB1C5ED5, + 0xD807AA98, 0x12835B01, 0x243185BE, 0x550C7DC3, + 0x72BE5D74, 0x80DEB1FE, 0x9BDC06A7, 0xC19BF174, + 0xE49B69C1, 0xEFBE4786, 0x0FC19DC6, 0x240CA1CC, + 0x2DE92C6F, 0x4A7484AA, 0x5CB0A9DC, 0x76F988DA, + 0x983E5152, 0xA831C66D, 0xB00327C8, 0xBF597FC7, + 0xC6E00BF3, 0xD5A79147, 0x06CA6351, 0x14292967, + 0x27B70A85, 0x2E1B2138, 0x4D2C6DFC, 0x53380D13, + 0x650A7354, 0x766A0ABB, 0x81C2C92E, 0x92722C85, + 0xA2BFE8A1, 0xA81A664B, 0xC24B8B70, 0xC76C51A3, + 0xD192E819, 0xD6990624, 0xF40E3585, 0x106AA070, + 0x19A4C116, 0x1E376C08, 0x2748774C, 0x34B0BCB5, + 0x391C0CB3, 0x4ED8AA4A, 0x5B9CCA4F, 0x682E6FF3, + 0x748F82EE, 0x78A5636F, 0x84C87814, 0x8CC70208, + 0x90BEFFFA, 0xA4506CEB, 0xBEF9A3F7, 0xC67178F2 + ]; + + if (4 & SUPPORTED_ALGS) + { + K_sha512 = [ + new Int_64(K_sha2[ 0], 0xd728ae22), new Int_64(K_sha2[ 1], 0x23ef65cd), + new Int_64(K_sha2[ 2], 0xec4d3b2f), new Int_64(K_sha2[ 3], 0x8189dbbc), + new Int_64(K_sha2[ 4], 0xf348b538), new Int_64(K_sha2[ 5], 0xb605d019), + new Int_64(K_sha2[ 6], 0xaf194f9b), new Int_64(K_sha2[ 7], 0xda6d8118), + new Int_64(K_sha2[ 8], 0xa3030242), new Int_64(K_sha2[ 9], 0x45706fbe), + new Int_64(K_sha2[10], 0x4ee4b28c), new Int_64(K_sha2[11], 0xd5ffb4e2), + new Int_64(K_sha2[12], 0xf27b896f), new Int_64(K_sha2[13], 0x3b1696b1), + new Int_64(K_sha2[14], 0x25c71235), new Int_64(K_sha2[15], 0xcf692694), + new Int_64(K_sha2[16], 0x9ef14ad2), new Int_64(K_sha2[17], 0x384f25e3), + new Int_64(K_sha2[18], 0x8b8cd5b5), new Int_64(K_sha2[19], 0x77ac9c65), + new Int_64(K_sha2[20], 0x592b0275), new Int_64(K_sha2[21], 0x6ea6e483), + new Int_64(K_sha2[22], 0xbd41fbd4), new Int_64(K_sha2[23], 0x831153b5), + new Int_64(K_sha2[24], 0xee66dfab), new Int_64(K_sha2[25], 0x2db43210), + new Int_64(K_sha2[26], 0x98fb213f), new Int_64(K_sha2[27], 0xbeef0ee4), + new Int_64(K_sha2[28], 0x3da88fc2), new Int_64(K_sha2[29], 0x930aa725), + new Int_64(K_sha2[30], 0xe003826f), new Int_64(K_sha2[31], 0x0a0e6e70), + new Int_64(K_sha2[32], 0x46d22ffc), new Int_64(K_sha2[33], 0x5c26c926), + new Int_64(K_sha2[34], 0x5ac42aed), new Int_64(K_sha2[35], 0x9d95b3df), + new Int_64(K_sha2[36], 0x8baf63de), new Int_64(K_sha2[37], 0x3c77b2a8), + new Int_64(K_sha2[38], 0x47edaee6), new Int_64(K_sha2[39], 0x1482353b), + new Int_64(K_sha2[40], 0x4cf10364), new Int_64(K_sha2[41], 0xbc423001), + new Int_64(K_sha2[42], 0xd0f89791), new Int_64(K_sha2[43], 0x0654be30), + new Int_64(K_sha2[44], 0xd6ef5218), new Int_64(K_sha2[45], 0x5565a910), + new Int_64(K_sha2[46], 0x5771202a), new Int_64(K_sha2[47], 0x32bbd1b8), + new Int_64(K_sha2[48], 0xb8d2d0c8), new Int_64(K_sha2[49], 0x5141ab53), + new Int_64(K_sha2[50], 0xdf8eeb99), new Int_64(K_sha2[51], 0xe19b48a8), + new Int_64(K_sha2[52], 0xc5c95a63), new Int_64(K_sha2[53], 0xe3418acb), + new Int_64(K_sha2[54], 0x7763e373), new Int_64(K_sha2[55], 0xd6b2b8a3), + new Int_64(K_sha2[56], 0x5defb2fc), new Int_64(K_sha2[57], 0x43172f60), + new Int_64(K_sha2[58], 0xa1f0ab72), new Int_64(K_sha2[59], 0x1a6439ec), + new Int_64(K_sha2[60], 0x23631e28), new Int_64(K_sha2[61], 0xde82bde9), + new Int_64(K_sha2[62], 0xb2c67915), new Int_64(K_sha2[63], 0xe372532b), + new Int_64(0xca273ece, 0xea26619c), new Int_64(0xd186b8c7, 0x21c0c207), + new Int_64(0xeada7dd6, 0xcde0eb1e), new Int_64(0xf57d4f7f, 0xee6ed178), + new Int_64(0x06f067aa, 0x72176fba), new Int_64(0x0a637dc5, 0xa2c898a6), + new Int_64(0x113f9804, 0xbef90dae), new Int_64(0x1b710b35, 0x131c471b), + new Int_64(0x28db77f5, 0x23047d84), new Int_64(0x32caab7b, 0x40c72493), + new Int_64(0x3c9ebe0a, 0x15c9bebc), new Int_64(0x431d67c4, 0x9c100d4c), + new Int_64(0x4cc5d4be, 0xcb3e42b6), new Int_64(0x597f299c, 0xfc657e2a), + new Int_64(0x5fcb6fab, 0x3ad6faec), new Int_64(0x6c44198c, 0x4a475817) + ]; + } + } + /** - * Calculates the desired SHA-2 hash of the string set at instantiation + * Performs a round of SHA-2 hashing over a block * * @private - * @param {Array.<number>} message The binary array representation of the - * string to hash - * @param {number} messageLen The number of bits in message + * @param {Array.<number>} block The binary array representation of the + * block to hash + * @param {Array.<number|Int_64>} H The intermediate H values from a previous + * round * @param {string} variant The desired SHA-2 variant - * @return {Array.<number>} The array of integers representing the SHA-2 - * hash of message + * @return {Array.<number|Int_64>} The resulting H values */ - function coreSHA2(message, messageLen, variant) + function roundSHA2(block, H, variant) { - var a, b, c, d, e, f, g, h, T1, T2, H, numRounds, lengthPosition, i, t, - binaryStringInc, binaryStringMult, safeAdd_2, safeAdd_4, safeAdd_5, - gamma0, gamma1, sigma0, sigma1, ch, maj, Int, W = [], int1, int2, offset, - appendedMessageLength, retVal, - K = [ - 0x428A2F98, 0x71374491, 0xB5C0FBCF, 0xE9B5DBA5, - 0x3956C25B, 0x59F111F1, 0x923F82A4, 0xAB1C5ED5, - 0xD807AA98, 0x12835B01, 0x243185BE, 0x550C7DC3, - 0x72BE5D74, 0x80DEB1FE, 0x9BDC06A7, 0xC19BF174, - 0xE49B69C1, 0xEFBE4786, 0x0FC19DC6, 0x240CA1CC, - 0x2DE92C6F, 0x4A7484AA, 0x5CB0A9DC, 0x76F988DA, - 0x983E5152, 0xA831C66D, 0xB00327C8, 0xBF597FC7, - 0xC6E00BF3, 0xD5A79147, 0x06CA6351, 0x14292967, - 0x27B70A85, 0x2E1B2138, 0x4D2C6DFC, 0x53380D13, - 0x650A7354, 0x766A0ABB, 0x81C2C92E, 0x92722C85, - 0xA2BFE8A1, 0xA81A664B, 0xC24B8B70, 0xC76C51A3, - 0xD192E819, 0xD6990624, 0xF40E3585, 0x106AA070, - 0x19A4C116, 0x1E376C08, 0x2748774C, 0x34B0BCB5, - 0x391C0CB3, 0x4ED8AA4A, 0x5B9CCA4F, 0x682E6FF3, - 0x748F82EE, 0x78A5636F, 0x84C87814, 0x8CC70208, - 0x90BEFFFA, 0xA4506CEB, 0xBEF9A3F7, 0xC67178F2 - ], - H_trunc = [ - 0xc1059ed8, 0x367cd507, 0x3070dd17, 0xf70e5939, - 0xffc00b31, 0x68581511, 0x64f98fa7, 0xbefa4fa4 - ], - H_full = [ - 0x6A09E667, 0xBB67AE85, 0x3C6EF372, 0xA54FF53A, - 0x510E527F, 0x9B05688C, 0x1F83D9AB, 0x5BE0CD19 - ]; + var a, b, c, d, e, f, g, h, T1, T2, numRounds, t, binaryStringMult, + safeAdd_2, safeAdd_4, safeAdd_5, gamma0, gamma1, sigma0, sigma1, + ch, maj, Int, W = [], int1, int2, offset, K; /* Set up the various function handles and variable for the specific * variant */ @@ -954,8 +1181,6 @@ var SUPPORTED_ALGS = 4 | 2 | 1; { /* 32-bit variant */ numRounds = 64; - lengthPosition = (((messageLen + 65) >>> 9) << 4) + 15; - binaryStringInc = 16; binaryStringMult = 1; Int = Number; safeAdd_2 = safeAdd_32_2; @@ -967,23 +1192,13 @@ var SUPPORTED_ALGS = 4 | 2 | 1; sigma1 = sigma1_32; maj = maj_32; ch = ch_32; - - if ("SHA-224" === variant) - { - H = H_trunc; - } - else /* "SHA-256" === variant */ - { - H = H_full; - } + K = K_sha2; } else if ((variant === "SHA-384" || variant === "SHA-512") && (4 & SUPPORTED_ALGS)) { /* 64-bit variant */ numRounds = 80; - lengthPosition = (((messageLen + 128) >>> 10) << 5) + 31; - binaryStringInc = 32; binaryStringMult = 2; Int = Int_64; safeAdd_2 = safeAdd_64_2; @@ -995,136 +1210,122 @@ var SUPPORTED_ALGS = 4 | 2 | 1; sigma1 = sigma1_64; maj = maj_64; ch = ch_64; + K = K_sha512; + } + else + { + throw new Error("Unexpected error in SHA-2 implementation"); + } - K = [ - new Int(K[ 0], 0xd728ae22), new Int(K[ 1], 0x23ef65cd), - new Int(K[ 2], 0xec4d3b2f), new Int(K[ 3], 0x8189dbbc), - new Int(K[ 4], 0xf348b538), new Int(K[ 5], 0xb605d019), - new Int(K[ 6], 0xaf194f9b), new Int(K[ 7], 0xda6d8118), - new Int(K[ 8], 0xa3030242), new Int(K[ 9], 0x45706fbe), - new Int(K[10], 0x4ee4b28c), new Int(K[11], 0xd5ffb4e2), - new Int(K[12], 0xf27b896f), new Int(K[13], 0x3b1696b1), - new Int(K[14], 0x25c71235), new Int(K[15], 0xcf692694), - new Int(K[16], 0x9ef14ad2), new Int(K[17], 0x384f25e3), - new Int(K[18], 0x8b8cd5b5), new Int(K[19], 0x77ac9c65), - new Int(K[20], 0x592b0275), new Int(K[21], 0x6ea6e483), - new Int(K[22], 0xbd41fbd4), new Int(K[23], 0x831153b5), - new Int(K[24], 0xee66dfab), new Int(K[25], 0x2db43210), - new Int(K[26], 0x98fb213f), new Int(K[27], 0xbeef0ee4), - new Int(K[28], 0x3da88fc2), new Int(K[29], 0x930aa725), - new Int(K[30], 0xe003826f), new Int(K[31], 0x0a0e6e70), - new Int(K[32], 0x46d22ffc), new Int(K[33], 0x5c26c926), - new Int(K[34], 0x5ac42aed), new Int(K[35], 0x9d95b3df), - new Int(K[36], 0x8baf63de), new Int(K[37], 0x3c77b2a8), - new Int(K[38], 0x47edaee6), new Int(K[39], 0x1482353b), - new Int(K[40], 0x4cf10364), new Int(K[41], 0xbc423001), - new Int(K[42], 0xd0f89791), new Int(K[43], 0x0654be30), - new Int(K[44], 0xd6ef5218), new Int(K[45], 0x5565a910), - new Int(K[46], 0x5771202a), new Int(K[47], 0x32bbd1b8), - new Int(K[48], 0xb8d2d0c8), new Int(K[49], 0x5141ab53), - new Int(K[50], 0xdf8eeb99), new Int(K[51], 0xe19b48a8), - new Int(K[52], 0xc5c95a63), new Int(K[53], 0xe3418acb), - new Int(K[54], 0x7763e373), new Int(K[55], 0xd6b2b8a3), - new Int(K[56], 0x5defb2fc), new Int(K[57], 0x43172f60), - new Int(K[58], 0xa1f0ab72), new Int(K[59], 0x1a6439ec), - new Int(K[60], 0x23631e28), new Int(K[61], 0xde82bde9), - new Int(K[62], 0xb2c67915), new Int(K[63], 0xe372532b), - new Int(0xca273ece, 0xea26619c), new Int(0xd186b8c7, 0x21c0c207), - new Int(0xeada7dd6, 0xcde0eb1e), new Int(0xf57d4f7f, 0xee6ed178), - new Int(0x06f067aa, 0x72176fba), new Int(0x0a637dc5, 0xa2c898a6), - new Int(0x113f9804, 0xbef90dae), new Int(0x1b710b35, 0x131c471b), - new Int(0x28db77f5, 0x23047d84), new Int(0x32caab7b, 0x40c72493), - new Int(0x3c9ebe0a, 0x15c9bebc), new Int(0x431d67c4, 0x9c100d4c), - new Int(0x4cc5d4be, 0xcb3e42b6), new Int(0x597f299c, 0xfc657e2a), - new Int(0x5fcb6fab, 0x3ad6faec), new Int(0x6c44198c, 0x4a475817) - ]; + a = H[0]; + b = H[1]; + c = H[2]; + d = H[3]; + e = H[4]; + f = H[5]; + g = H[6]; + h = H[7]; - if ("SHA-384" === variant) + for (t = 0; t < numRounds; t += 1) + { + if (t < 16) { - H = [ - new Int(0xcbbb9d5d, H_trunc[0]), new Int(0x0629a292a, H_trunc[1]), - new Int(0x9159015a, H_trunc[2]), new Int(0x0152fecd8, H_trunc[3]), - new Int(0x67332667, H_trunc[4]), new Int(0x98eb44a87, H_trunc[5]), - new Int(0xdb0c2e0d, H_trunc[6]), new Int(0x047b5481d, H_trunc[7]) - ]; + offset = t * binaryStringMult; + int1 = (block.length <= offset) ? 0 : block[offset]; + int2 = (block.length <= offset + 1) ? 0 : block[offset + 1]; + /* Bit of a hack - for 32-bit, the second term is ignored */ + W[t] = new Int(int1, int2); } - else /* "SHA-512" === variant */ + else { - H = [ - new Int(H_full[0], 0xf3bcc908), new Int(H_full[1], 0x84caa73b), - new Int(H_full[2], 0xfe94f82b), new Int(H_full[3], 0x5f1d36f1), - new Int(H_full[4], 0xade682d1), new Int(H_full[5], 0x2b3e6c1f), - new Int(H_full[6], 0xfb41bd6b), new Int(H_full[7], 0x137e2179) - ]; + W[t] = safeAdd_4( + gamma1(W[t - 2]), W[t - 7], + gamma0(W[t - 15]), W[t - 16] + ); } + + T1 = safeAdd_5(h, sigma1(e), ch(e, f, g), K[t], W[t]); + T2 = safeAdd_2(sigma0(a), maj(a, b, c)); + h = g; + g = f; + f = e; + e = safeAdd_2(d, T1); + d = c; + c = b; + b = a; + a = safeAdd_2(T1, T2); + } + + H[0] = safeAdd_2(a, H[0]); + H[1] = safeAdd_2(b, H[1]); + H[2] = safeAdd_2(c, H[2]); + H[3] = safeAdd_2(d, H[3]); + H[4] = safeAdd_2(e, H[4]); + H[5] = safeAdd_2(f, H[5]); + H[6] = safeAdd_2(g, H[6]); + H[7] = safeAdd_2(h, H[7]); + + return H; + } + + /** + * Finalizes the SHA-2 hash + * + * @private + * @param {Array.<number>} remainder Any leftover unprocessed packed ints + * that still need to be processed + * @param {number} remainderBinLen The number of bits in remainder + * @param {number} processedBinLen The number of bits already + * processed + * @param {Array.<number|Int_64>} H The intermediate H values from a previous + * round + * @param {string} variant The desired SHA-2 variant + * @return {Array.<number>} The array of integers representing the SHA-2 + * hash of message + */ + function finalizeSHA2(remainder, remainderBinLen, processedBinLen, H, variant) + { + var i, appendedMessageLength, offset, retVal, binaryStringInc; + + if ((variant === "SHA-224" || variant === "SHA-256") && + (2 & SUPPORTED_ALGS)) + { + /* 32-bit variant */ + /* Add 72 because of the 64-bit length and the extra byte because + of the bit (actually a byte) append */ + offset = (((remainderBinLen + 72) >>> 9) << 4) + 15; + binaryStringInc = 16; + } + else if ((variant === "SHA-384" || variant === "SHA-512") && + (4 & SUPPORTED_ALGS)) + { + /* 64-bit variant */ + /* Add 136 because of the 128-bit length and the extra byte because + of the bit (actually a byte) append */ + offset = (((remainderBinLen + 136) >>> 10) << 5) + 31; + binaryStringInc = 32; } else { - throw "Unexpected error in SHA-2 implementation"; + throw new Error("Unexpected error in SHA-2 implementation"); } - while (message.length <= lengthPosition) + while (remainder.length <= offset) { - message.push(0); + remainder.push(0); } /* Append '1' at the end of the binary string */ - message[messageLen >>> 5] |= 0x80 << (24 - messageLen % 32); + remainder[remainderBinLen >>> 5] |= 0x80 << (24 - remainderBinLen % 32); /* Append length of binary string in the position such that the new * length is correct */ - message[lengthPosition] = messageLen; + remainder[offset] = remainderBinLen + processedBinLen; - appendedMessageLength = message.length; + appendedMessageLength = remainder.length; + /* This will always be at least 1 full chunk */ for (i = 0; i < appendedMessageLength; i += binaryStringInc) { - a = H[0]; - b = H[1]; - c = H[2]; - d = H[3]; - e = H[4]; - f = H[5]; - g = H[6]; - h = H[7]; - - for (t = 0; t < numRounds; t += 1) - { - if (t < 16) - { - offset = t * binaryStringMult + i; - int1 = (message.length <= offset) ? 0 : message[offset]; - int2 = (message.length <= offset + 1) ? 0 : message[offset + 1]; - /* Bit of a hack - for 32-bit, the second term is ignored */ - W[t] = new Int(int1, int2); - } - else - { - W[t] = safeAdd_4( - gamma1(W[t - 2]), W[t - 7], - gamma0(W[t - 15]), W[t - 16] - ); - } - - T1 = safeAdd_5(h, sigma1(e), ch(e, f, g), K[t], W[t]); - T2 = safeAdd_2(sigma0(a), maj(a, b, c)); - h = g; - g = f; - f = e; - e = safeAdd_2(d, T1); - d = c; - c = b; - b = a; - a = safeAdd_2(T1, T2); - - } - - H[0] = safeAdd_2(a, H[0]); - H[1] = safeAdd_2(b, H[1]); - H[2] = safeAdd_2(c, H[2]); - H[3] = safeAdd_2(d, H[3]); - H[4] = safeAdd_2(e, H[4]); - H[5] = safeAdd_2(f, H[5]); - H[6] = safeAdd_2(g, H[6]); - H[7] = safeAdd_2(h, H[7]); + H = roundSHA2(remainder.slice(i, i + binaryStringInc), H, variant); } if (("SHA-224" === variant) && (2 & SUPPORTED_ALGS)) @@ -1164,7 +1365,7 @@ var SUPPORTED_ALGS = 4 | 2 | 1; } else /* This should never be reached */ { - throw "Unexpected error in SHA-2 implementation"; + throw new Error("Unexpected error in SHA-2 implementation"); } return retVal; @@ -1176,283 +1377,128 @@ var SUPPORTED_ALGS = 4 | 2 | 1; * * @constructor * @this {jsSHA} - * @param {string} srcString The string to be hashed - * @param {string} inputFormat The format of srcString, HEX, ASCII, TEXT, - * B64, or BYTES - * @param {string=} encoding The text encoding to use to encode the source - * string + * @param {string} variant The desired SHA variant (SHA-1, SHA-224, SHA-256, + * SHA-384, or SHA-512) + * @param {string} inputFormat The format of srcString: HEX, TEXT, B64, or BYTES + * @param {{encoding: (string|undefined), numRounds: (string|undefined)}=} + * options Optional values */ - var jsSHA = function(srcString, inputFormat, encoding) + var jsSHA = function(variant, inputFormat, options) { - var strBinLen = 0, strToHash = [0], utfType = '', srcConvertRet = null; + var processedLen = 0, remainder = [], remainderLen = 0, utfType, + intermediateH, converterFunc, shaVariant = variant, outputBinLen, + variantBlockSize, roundFunc, finalizeFunc, finalized = false, + hmacKeySet = false, keyWithIPad = [], keyWithOPad = [], numRounds, + updatedCalled = false, inputOptions; - utfType = encoding || "UTF8"; + inputOptions = options || {}; + utfType = inputOptions["encoding"] || "UTF8"; + numRounds = inputOptions["numRounds"] || 1; - if (!(("UTF8" === utfType) || ("UTF16BE" === utfType) || ("UTF16LE" === utfType))) - { - throw "encoding must be UTF8, UTF16BE, or UTF16LE"; - } + converterFunc = getStrConverter(inputFormat, utfType); - /* Convert the input string into the correct type */ - if ("HEX" === inputFormat) - { - if (0 !== (srcString.length % 2)) - { - throw "srcString of HEX type must be in byte increments"; - } - srcConvertRet = hex2binb(srcString); - strBinLen = srcConvertRet["binLen"]; - strToHash = srcConvertRet["value"]; - } - else if (("TEXT" === inputFormat) || ("ASCII" === inputFormat)) + if ((numRounds !== parseInt(numRounds, 10)) || (1 > numRounds)) { - srcConvertRet = str2binb(srcString, utfType); - strBinLen = srcConvertRet["binLen"]; - strToHash = srcConvertRet["value"]; + throw new Error("numRounds must a integer >= 1"); } - else if ("B64" === inputFormat) - { - srcConvertRet = b642binb(srcString); - strBinLen = srcConvertRet["binLen"]; - strToHash = srcConvertRet["value"]; - } - else if ("BYTES" === inputFormat) + + if (("SHA-1" === shaVariant) && (1 & SUPPORTED_ALGS)) { - srcConvertRet = bytes2binb(srcString); - strBinLen = srcConvertRet["binLen"]; - strToHash = srcConvertRet["value"]; + variantBlockSize = 512; + roundFunc = roundSHA1; + finalizeFunc = finalizeSHA1; + outputBinLen = 160; } else { - throw "inputFormat must be HEX, TEXT, ASCII, B64, or BYTES"; - } - - /** - * Returns the desired SHA hash of the string specified at instantiation - * using the specified parameters - * - * @expose - * @param {string} variant The desired SHA variant (SHA-1, SHA-224, - * SHA-256, SHA-384, or SHA-512) - * @param {string} format The desired output formatting (B64, HEX, or BYTES) - * @param {number=} numRounds The number of rounds of hashing to be - * executed - * @param {{outputUpper : boolean, b64Pad : string}=} outputFormatOpts - * Hash list of output formatting options - * @return {string} The string representation of the hash in the format - * specified - */ - this.getHash = function(variant, format, numRounds, outputFormatOpts) - { - var formatFunc = null, message = strToHash.slice(), - messageBinLen = strBinLen, i; - - /* Need to do argument patching since both numRounds and - outputFormatOpts are optional */ - if (3 === arguments.length) + if (6 & SUPPORTED_ALGS) { - if ("number" !== typeof numRounds) + roundFunc = function (block, H) { + return roundSHA2(block, H, shaVariant); + }; + finalizeFunc = function (remainder, remainderBinLen, processedBinLen, H) { - outputFormatOpts = numRounds; - numRounds = 1; - } - } - else if (2 === arguments.length) - { - numRounds = 1; - } - - /* Validate the numRounds argument */ - if ((numRounds !== parseInt(numRounds, 10)) || (1 > numRounds)) - { - throw "numRounds must a integer >= 1"; - } - - /* Validate the output format selection */ - switch (format) - { - case "HEX": - formatFunc = binb2hex; - break; - case "B64": - formatFunc = binb2b64; - break; - case "BYTES": - formatFunc = binb2bytes; - break; - default: - throw "format must be HEX, B64, or BYTES"; + return finalizeSHA2(remainder, remainderBinLen, processedBinLen, H, shaVariant); + }; } - if (("SHA-1" === variant) && (1 & SUPPORTED_ALGS)) + if (("SHA-224" === shaVariant) && (2 & SUPPORTED_ALGS)) { - for (i = 0; i < numRounds; i += 1) - { - message = coreSHA1(message, messageBinLen); - messageBinLen = 160; - } + variantBlockSize = 512; + outputBinLen = 224; } - else if (("SHA-224" === variant) && (2 & SUPPORTED_ALGS)) + else if (("SHA-256" === shaVariant) && (2 & SUPPORTED_ALGS)) { - for (i = 0; i < numRounds; i += 1) - { - message = coreSHA2(message, messageBinLen, variant); - messageBinLen = 224; - } + variantBlockSize = 512; + outputBinLen = 256; } - else if (("SHA-256" === variant) && (2 & SUPPORTED_ALGS)) + else if (("SHA-384" === shaVariant) && (4 & SUPPORTED_ALGS)) { - for (i = 0; i < numRounds; i += 1) - { - message = coreSHA2(message, messageBinLen, variant); - messageBinLen = 256; - } + variantBlockSize = 1024; + outputBinLen = 384; } - else if (("SHA-384" === variant) && (4 & SUPPORTED_ALGS)) + else if (("SHA-512" === shaVariant) && (4 & SUPPORTED_ALGS)) { - for (i = 0; i < numRounds; i += 1) - { - message = coreSHA2(message, messageBinLen, variant); - messageBinLen = 384; - } - } - else if (("SHA-512" === variant) && (4 & SUPPORTED_ALGS)) - { - for (i = 0; i < numRounds; i += 1) - { - message = coreSHA2(message, messageBinLen, variant); - messageBinLen = 512; - } + variantBlockSize = 1024; + outputBinLen = 512; } else { - throw "Chosen SHA variant is not supported"; + throw new Error("Chosen SHA variant is not supported"); } + } - return formatFunc(message, getOutputOpts(outputFormatOpts)); - }; + intermediateH = getH(shaVariant); /** - * Returns the desired HMAC of the string specified at instantiation - * using the key and variant parameter + * Sets the HMAC key for an eventual getHMAC call. Must be called + * immediately after jsSHA object instantiation * * @expose * @param {string} key The key used to calculate the HMAC - * @param {string} inputFormat The format of key, HEX, TEXT, ASCII, - * B64, or BYTES - * @param {string} variant The desired SHA variant (SHA-1, SHA-224, - * SHA-256, SHA-384, or SHA-512) - * @param {string} outputFormat The desired output formatting - * (B64, HEX, or BYTES) - * @param {{outputUpper : boolean, b64Pad : string}=} outputFormatOpts - * associative array of output formatting options - * @return {string} The string representation of the hash in the format - * specified + * @param {string} inputFormat The format of key, HEX, TEXT, B64, or BYTES + * @param {{encoding : (string|undefined)}=} options Associative array + * of input format options */ - this.getHMAC = function(key, inputFormat, variant, outputFormat, - outputFormatOpts) + this.setHMACKey = function(key, inputFormat, options) { - var formatFunc, keyToUse, blockByteSize, blockBitSize, i, - retVal, lastArrayIndex, keyBinLen, hashBitSize, - keyWithIPad = [], keyWithOPad = [], keyConvertRet = null; + var keyConverterFunc, convertRet, keyBinLen, keyToUse, blockByteSize, + i, lastArrayIndex, keyOptions; - /* Validate the output format selection */ - switch (outputFormat) + if (true === hmacKeySet) { - case "HEX": - formatFunc = binb2hex; - break; - case "B64": - formatFunc = binb2b64; - break; - case "BYTES": - formatFunc = binb2bytes; - break; - default: - throw "outputFormat must be HEX, B64, or BYTES"; + throw new Error("HMAC key already set"); } - /* Validate the hash variant selection and set needed variables */ - if (("SHA-1" === variant) && (1 & SUPPORTED_ALGS)) - { - blockByteSize = 64; - hashBitSize = 160; - } - else if (("SHA-224" === variant) && (2 & SUPPORTED_ALGS)) - { - blockByteSize = 64; - hashBitSize = 224; - } - else if (("SHA-256" === variant) && (2 & SUPPORTED_ALGS)) - { - blockByteSize = 64; - hashBitSize = 256; - } - else if (("SHA-384" === variant) && (4 & SUPPORTED_ALGS)) + if (true === finalized) { - blockByteSize = 128; - hashBitSize = 384; - } - else if (("SHA-512" === variant) && (4 & SUPPORTED_ALGS)) - { - blockByteSize = 128; - hashBitSize = 512; - } - else - { - throw "Chosen SHA variant is not supported"; + throw new Error("Cannot set HMAC key after finalizing hash"); } - /* Validate input format selection */ - if ("HEX" === inputFormat) - { - keyConvertRet = hex2binb(key); - keyBinLen = keyConvertRet["binLen"]; - keyToUse = keyConvertRet["value"]; - } - else if (("TEXT" === inputFormat) || ("ASCII" === inputFormat)) - { - keyConvertRet = str2binb(key, utfType); - keyBinLen = keyConvertRet["binLen"]; - keyToUse = keyConvertRet["value"]; - } - else if ("B64" === inputFormat) - { - keyConvertRet = b642binb(key); - keyBinLen = keyConvertRet["binLen"]; - keyToUse = keyConvertRet["value"]; - } - else if ("BYTES" === inputFormat) + if (true === updatedCalled) { - keyConvertRet = bytes2binb(key); - keyBinLen = keyConvertRet["binLen"]; - keyToUse = keyConvertRet["value"]; - } - else - { - throw "inputFormat must be HEX, TEXT, ASCII, B64, or BYTES"; + throw new Error("Cannot set HMAC key after calling update"); } + keyOptions = options || {}; + utfType = keyOptions["encoding"] || "UTF8"; + + keyConverterFunc = getStrConverter(inputFormat, utfType); + + convertRet = keyConverterFunc(key); + keyBinLen = convertRet["binLen"]; + keyToUse = convertRet["value"]; + + blockByteSize = variantBlockSize >>> 3; + /* These are used multiple times, calculate and store them */ - blockBitSize = blockByteSize * 8; lastArrayIndex = (blockByteSize / 4) - 1; /* Figure out what to do with the key based on its size relative to * the hash's block size */ if (blockByteSize < (keyBinLen / 8)) { - if (("SHA-1" === variant) && (1 & SUPPORTED_ALGS)) - { - keyToUse = coreSHA1(keyToUse, keyBinLen); - } - else if (6 & SUPPORTED_ALGS) - { - keyToUse = coreSHA2(keyToUse, keyBinLen, variant); - } - else - { - throw "Unexpected error in HMAC implementation"; - } + keyToUse = finalizeFunc(keyToUse, keyBinLen, 0, getH(shaVariant)); /* For all variants, the block size is bigger than the output * size so there will never be a useful byte at the end of the * string */ @@ -1481,36 +1527,145 @@ var SUPPORTED_ALGS = 4 | 2 | 1; keyWithOPad[i] = keyToUse[i] ^ 0x5C5C5C5C; } - /* Calculate the HMAC */ - if (("SHA-1" === variant) && (1 & SUPPORTED_ALGS)) + intermediateH = roundFunc(keyWithIPad, intermediateH); + processedLen = variantBlockSize; + + hmacKeySet = true; + }; + + /** + * Takes strString and hashes as many blocks as possible. Stores the + * rest for either a future update or getHash call. + * + * @expose + * @param {string} srcString The string to be hashed + */ + this.update = function(srcString) + { + var convertRet, chunkBinLen, chunkIntLen, chunk, i, updateProcessedLen = 0, + variantBlockIntInc = variantBlockSize >>> 5; + + convertRet = converterFunc(srcString, remainder, remainderLen); + chunkBinLen = convertRet["binLen"]; + chunk = convertRet["value"]; + + chunkIntLen = chunkBinLen >>> 5; + for (i = 0; i < chunkIntLen; i += variantBlockIntInc) { - retVal = coreSHA1( - keyWithOPad.concat( - coreSHA1( - keyWithIPad.concat(strToHash), - blockBitSize + strBinLen - ) - ), - blockBitSize + hashBitSize); + if (updateProcessedLen + variantBlockSize <= chunkBinLen) + { + intermediateH = roundFunc( + chunk.slice(i, i + variantBlockIntInc), + intermediateH + ); + updateProcessedLen += variantBlockSize; + } } - else if (6 & SUPPORTED_ALGS) + processedLen += updateProcessedLen; + remainder = chunk.slice(updateProcessedLen >>> 5); + remainderLen = chunkBinLen % variantBlockSize; + updatedCalled = true; + }; + + /** + * Returns the desired SHA hash of the string specified at instantiation + * using the specified parameters + * + * @expose + * @param {string} format The desired output formatting (B64, HEX, or BYTES) + * @param {{outputUpper : (boolean|undefined), b64Pad : (string|undefined)}=} + * options Hash list of output formatting options + * @return {string} The string representation of the hash in the format + * specified + */ + this.getHash = function(format, options) + { + var formatFunc, i, outputOptions; + + if (true === hmacKeySet) { - retVal = coreSHA2( - keyWithOPad.concat( - coreSHA2( - keyWithIPad.concat(strToHash), - blockBitSize + strBinLen, - variant - ) - ), - blockBitSize + hashBitSize, variant); + throw new Error("Cannot call getHash after setting HMAC key"); } - else + + outputOptions = getOutputOpts(options); + + /* Validate the output format selection */ + switch (format) + { + case "HEX": + formatFunc = function(binarray) {return binb2hex(binarray, outputOptions);}; + break; + case "B64": + formatFunc = function(binarray) {return binb2b64(binarray, outputOptions);}; + break; + case "BYTES": + formatFunc = binb2bytes; + break; + default: + throw new Error("format must be HEX, B64, or BYTES"); + } + + if (false === finalized) + { + intermediateH = finalizeFunc(remainder, remainderLen, processedLen, intermediateH); + for (i = 1; i < numRounds; i += 1) + { + intermediateH = finalizeFunc(intermediateH, outputBinLen, 0, getH(shaVariant)); + } + } + + finalized = true; + return formatFunc(intermediateH); + }; + + /** + * Returns the the HMAC in the specified format using the key given by + * a previous setHMACKey call. + * + * @expose + * @param {string} format The desired output formatting + * (B64, HEX, or BYTES) + * @param {{outputUpper : (boolean|undefined), b64Pad : (string|undefined)}=} + * options associative array of output formatting options + * @return {string} The string representation of the hash in the format + * specified + */ + this.getHMAC = function(format, options) + { + var formatFunc, firstHash, outputOptions; + + if (false === hmacKeySet) + { + throw new Error("Cannot call getHMAC without first setting HMAC key"); + } + + outputOptions = getOutputOpts(options); + + /* Validate the output format selection */ + switch (format) + { + case "HEX": + formatFunc = function(binarray) {return binb2hex(binarray, outputOptions);}; + break; + case "B64": + formatFunc = function(binarray) {return binb2b64(binarray, outputOptions);}; + break; + case "BYTES": + formatFunc = binb2bytes; + break; + default: + throw new Error("outputFormat must be HEX, B64, or BYTES"); + } + + if (false === finalized) { - throw "Unexpected error in HMAC implementation"; + firstHash = finalizeFunc(remainder, remainderLen, processedLen, intermediateH); + intermediateH = roundFunc(keyWithOPad, getH(shaVariant)); + intermediateH = finalizeFunc(firstHash, outputBinLen, variantBlockSize, intermediateH); } - return formatFunc(retVal, getOutputOpts(outputFormatOpts)); + finalized = true; + return formatFunc(intermediateH); }; }; diff --git a/test/test.html b/test/test.html index 1f62901..0572253 100644 --- a/test/test.html +++ b/test/test.html @@ -48,12 +48,11 @@ function supportedAlgs() { - var supportedAlgs = []; - var hashObj = new jsSHA("abc", "TEXT"); + var supportedAlgs = [], hashObj; try { - hashObj.getHash("SHA-1", "HEX"); + hashObj = new jsSHA("SHA-1", "TEXT"); supportedAlgs.push("SHA-1"); } catch(e) @@ -66,7 +65,7 @@ try { - hashObj.getHash("SHA-256", "HEX"); + hashObj = new jsSHA("SHA-256", "TEXT"); supportedAlgs.push("SHA-224"); supportedAlgs.push("SHA-256"); } @@ -80,7 +79,7 @@ try { - hashObj.getHash("SHA-512", "HEX"); + hashObj = new jsSHA("SHA-512", "TEXT"); supportedAlgs.push("SHA-384"); supportedAlgs.push("SHA-512"); } @@ -226,10 +225,11 @@ for (var i = 0; i < data[hashType].length; i++) { /* Grab the TEXT input for a given hash and test case */ - var shaObj = new jsSHA(data[hashType][i]['textIn'], 'TEXT'); + var shaObj = new jsSHA(hashType, 'TEXT'); + shaObj.update(data[hashType][i]['textIn']); /* Test the Hex output */ - if (data[hashType][i]['hexOut'] == shaObj.getHash(hashType, "HEX")) + if (data[hashType][i]['hexOut'] == shaObj.getHash("HEX")) { table.rows[2].cells[3*i+1].innerHTML = "PASS"; table.rows[2].cells[3*i+1].className= "correct"; @@ -241,7 +241,7 @@ } /* Test the Base-64 output */ - if (data[hashType][i]['b64Out'] == shaObj.getHash(hashType, "B64")) + if (data[hashType][i]['b64Out'] == shaObj.getHash("B64")) { table.rows[3].cells[3*i+1].innerHTML = "PASS"; table.rows[3].cells[3*i+1].className= "correct"; @@ -253,10 +253,11 @@ } /* Grab the Hex input for a given hash and test case */ - shaObj = new jsSHA(data[hashType][i]['hexIn'], 'HEX'); + shaObj = new jsSHA(hashType, 'HEX'); + shaObj.update(data[hashType][i]['hexIn']); /* Test the Hex output */ - if (data[hashType][i]['hexOut'] == shaObj.getHash(hashType, "HEX")) + if (data[hashType][i]['hexOut'] == shaObj.getHash("HEX")) { table.rows[2].cells[3*i+2].innerHTML = "PASS"; table.rows[2].cells[3*i+2].className= "correct"; @@ -268,7 +269,7 @@ } /* Test the Base-64 output */ - if (data[hashType][i]['b64Out'] == shaObj.getHash(hashType, "B64")) + if (data[hashType][i]['b64Out'] == shaObj.getHash("B64")) { table.rows[3].cells[3*i+2].innerHTML = "PASS"; table.rows[3].cells[3*i+2].className= "correct"; @@ -280,10 +281,11 @@ } /* Grab the B64 input for a given hash and test case */ - shaObj = new jsSHA(data[hashType][i]['b64In'], 'B64'); + shaObj = new jsSHA(hashType, 'B64'); + shaObj.update(data[hashType][i]['b64In']); /* Test the Hex output */ - if (data[hashType][i]['hexOut'] == shaObj.getHash(hashType, "HEX")) + if (data[hashType][i]['hexOut'] == shaObj.getHash("HEX")) { table.rows[2].cells[3*i+3].innerHTML = "PASS"; table.rows[2].cells[3*i+3].className= "correct"; @@ -295,7 +297,7 @@ } /* Test the Base-64 output */ - if (data[hashType][i]['b64Out'] == shaObj.getHash(hashType, "B64")) + if (data[hashType][i]['b64Out'] == shaObj.getHash("B64")) { table.rows[3].cells[3*i+3].innerHTML = "PASS"; table.rows[3].cells[3*i+3].className= "correct"; @@ -356,10 +358,11 @@ table_body.rows[1].insertCell(-1); /* Grab the TEXT input for a given hash and test case */ - var shaObj = new jsSHA(data[hashType]['textIn'], 'TEXT'); + var shaObj = new jsSHA(hashType, 'TEXT', {numRounds: 5}); + shaObj.update(data[hashType]['textIn']); /* Test the Hex output */ - if (data[hashType]['hexOut5'] == shaObj.getHash(hashType, "HEX", 5)) + if (data[hashType]['hexOut5'] == shaObj.getHash("HEX")) { table.rows[1].cells[j+1].innerHTML = "PASS"; table.rows[1].cells[j+1].className= "correct"; @@ -370,7 +373,10 @@ table.rows[1].cells[j+1].className= "incorrect"; } - if (data[hashType]['hexOut10'] == shaObj.getHash(hashType, "HEX", 10)) + shaObj = new jsSHA(hashType, 'TEXT', {numRounds: 10}); + shaObj.update(data[hashType]['textIn']); + + if (data[hashType]['hexOut10'] == shaObj.getHash("HEX")) { table.rows[2].cells[j+1].innerHTML = "PASS"; table.rows[2].cells[j+1].className= "correct"; @@ -542,10 +548,12 @@ for (var i = 0; i < data[hashType].length; i++) { /* Grab the TEXT input for a given hash and test case */ - var shaObj = new jsSHA(data[hashType][i]['text'], 'TEXT'); + var shaObj = new jsSHA(hashType, 'TEXT'); + shaObj.setHMACKey(data[hashType][i]['keyHex'], "HEX"); + shaObj.update(data[hashType][i]['text']); /* Test Text-Text/Key-Hex/Out-Hex */ - if (data[hashType][i]['hexOut'] == shaObj.getHMAC(data[hashType][i]['keyHex'], "HEX", hashType, "HEX")) + if (data[hashType][i]['hexOut'] == shaObj.getHMAC("HEX")) { table.rows[2].cells[3*i+2].innerHTML = "PASS" table.rows[2].cells[3*i+2].className= "correct"; @@ -557,7 +565,10 @@ } /* Test Text-Text/Key-B64/Out-Hex */ - if (data[hashType][i]['hexOut'] == shaObj.getHMAC(data[hashType][i]['keyB64'], "B64", hashType, "HEX")) + shaObj = new jsSHA(hashType, 'TEXT'); + shaObj.setHMACKey(data[hashType][i]['keyB64'], "B64"); + shaObj.update(data[hashType][i]['text']); + if (data[hashType][i]['hexOut'] == shaObj.getHMAC("HEX")) { table.rows[3].cells[3*i+1].innerHTML = "PASS" table.rows[3].cells[3*i+1].className= "correct"; @@ -569,7 +580,10 @@ } /* Test Text-Text/Key-Hex/Out-B64 */ - if (data[hashType][i]['b64Out'] == shaObj.getHMAC(data[hashType][i]['keyHex'], "HEX", hashType, "B64")) + shaObj = new jsSHA(hashType, 'TEXT'); + shaObj.setHMACKey(data[hashType][i]['keyHex'], "HEX"); + shaObj.update(data[hashType][i]['text']); + if (data[hashType][i]['b64Out'] == shaObj.getHMAC("B64")) { table.rows[4].cells[3*i+2].innerHTML = "PASS" table.rows[4].cells[3*i+2].className= "correct"; @@ -581,7 +595,10 @@ } /* Test Text-Text/Key-B64/Out-B64 */ - if (data[hashType][i]['b64Out'] == shaObj.getHMAC(data[hashType][i]['keyB64'], "B64", hashType, "B64")) + shaObj = new jsSHA(hashType, 'TEXT'); + shaObj.setHMACKey(data[hashType][i]['keyHex'], "HEX"); + shaObj.update(data[hashType][i]['text']); + if (data[hashType][i]['b64Out'] == shaObj.getHMAC("B64")) { table.rows[5].cells[3*i+1].innerHTML = "PASS" table.rows[5].cells[3*i+1].className= "correct"; @@ -593,10 +610,11 @@ } /* Grab the Hex input for a given hash and test case */ - shaObj = new jsSHA(data[hashType][i]['textHex'], 'HEX'); - + shaObj = new jsSHA(hashType,'HEX'); + shaObj.setHMACKey(data[hashType][i]['keyHex'], "HEX"); + shaObj.update(data[hashType][i]['textHex']); /* Test Text-Hex/Key-Hex/Out-Hex */ - if (data[hashType][i]['hexOut'] == shaObj.getHMAC(data[hashType][i]['keyHex'], "HEX", hashType, "HEX")) + if (data[hashType][i]['hexOut'] == shaObj.getHMAC("HEX")) { table.rows[2].cells[3*i+3].innerHTML = "PASS" table.rows[2].cells[3*i+3].className= "correct"; @@ -608,7 +626,10 @@ } /* Test Text-Hex/Key-B64/Out-Hex */ - if (data[hashType][i]['hexOut'] == shaObj.getHMAC(data[hashType][i]['keyB64'], "B64", hashType, "HEX")) + shaObj = new jsSHA(hashType,'HEX'); + shaObj.setHMACKey(data[hashType][i]['keyB64'], "B64"); + shaObj.update(data[hashType][i]['textHex']); + if (data[hashType][i]['hexOut'] == shaObj.getHMAC("HEX")) { table.rows[3].cells[3*i+2].innerHTML = "PASS" table.rows[3].cells[3*i+2].className= "correct"; @@ -620,7 +641,10 @@ } /* Test Text-Hex/Key-Hex/Out-B64 */ - if (data[hashType][i]['b64Out'] == shaObj.getHMAC(data[hashType][i]['keyHex'], "HEX", hashType, "B64")) + shaObj = new jsSHA(hashType,'HEX'); + shaObj.setHMACKey(data[hashType][i]['keyHex'], "HEX"); + shaObj.update(data[hashType][i]['textHex']); + if (data[hashType][i]['b64Out'] == shaObj.getHMAC("B64")) { table.rows[4].cells[3*i+3].innerHTML = "PASS" table.rows[4].cells[3*i+3].className= "correct"; @@ -632,7 +656,10 @@ } /* Test Text-Hex/Key-B64/Out-B64 */ - if (data[hashType][i]['b64Out'] == shaObj.getHMAC(data[hashType][i]['keyB64'], "B64", hashType, "B64")) + shaObj = new jsSHA(hashType,'HEX'); + shaObj.setHMACKey(data[hashType][i]['keyB64'], "B64"); + shaObj.update(data[hashType][i]['textHex']); + if (data[hashType][i]['b64Out'] == shaObj.getHMAC("B64")) { table.rows[5].cells[3*i+2].innerHTML = "PASS" table.rows[5].cells[3*i+2].className= "correct"; @@ -644,10 +671,11 @@ } /* Grab the B64 input for a given hash and test case */ - shaObj = new jsSHA(data[hashType][i]['textB64'], 'B64'); - + shaObj = new jsSHA(hashType,'B64'); + shaObj.setHMACKey(data[hashType][i]['keyHex'], "HEX"); + shaObj.update(data[hashType][i]['textB64']); /* Test Text-B64/Key-Hex/Out-Hex */ - if (data[hashType][i]['hexOut'] == shaObj.getHMAC(data[hashType][i]['keyHex'], "HEX", hashType, "HEX")) + if (data[hashType][i]['hexOut'] == shaObj.getHMAC("HEX")) { table.rows[2].cells[3*i+4].innerHTML = "PASS" table.rows[2].cells[3*i+4].className= "correct"; @@ -659,7 +687,10 @@ } /* Test Text-B64/Key-B64/Out-Hex */ - if (data[hashType][i]['hexOut'] == shaObj.getHMAC(data[hashType][i]['keyB64'], "B64", hashType, "HEX")) + shaObj = new jsSHA(hashType,'B64'); + shaObj.setHMACKey(data[hashType][i]['keyB64'], "B64"); + shaObj.update(data[hashType][i]['textB64']); + if (data[hashType][i]['hexOut'] == shaObj.getHMAC("HEX")) { table.rows[3].cells[3*i+3].innerHTML = "PASS" table.rows[3].cells[3*i+3].className= "correct"; @@ -671,7 +702,10 @@ } /* Test Text-B64/Key-Hex/Out-B64 */ - if (data[hashType][i]['b64Out'] == shaObj.getHMAC(data[hashType][i]['keyHex'], "HEX", hashType, "B64")) + shaObj = new jsSHA(hashType,'B64'); + shaObj.setHMACKey(data[hashType][i]['keyHex'], "HEX"); + shaObj.update(data[hashType][i]['textB64']); + if (data[hashType][i]['b64Out'] == shaObj.getHMAC("B64")) { table.rows[4].cells[3*i+4].innerHTML = "PASS" table.rows[4].cells[3*i+4].className= "correct"; @@ -683,7 +717,10 @@ } /* Test Text-B64/Key-B64/Out-B64 */ - if (data[hashType][i]['b64Out'] == shaObj.getHMAC(data[hashType][i]['keyB64'], "B64", hashType, "B64")) + shaObj = new jsSHA(hashType,'B64'); + shaObj.setHMACKey(data[hashType][i]['keyB64'], "B64"); + shaObj.update(data[hashType][i]['textB64']); + if (data[hashType][i]['b64Out'] == shaObj.getHMAC("B64")) { table.rows[5].cells[3*i+3].innerHTML = "PASS" table.rows[5].cells[3*i+3].className= "correct"; |