From fb7e6403d947c3e8fa164190df015b975572f9f1 Mon Sep 17 00:00:00 2001 From: Yi-Cyuan Chen Date: Fri, 1 Dec 2017 21:04:32 +0800 Subject: [PATCH] Added - AMD support. - support for web worker. #13 Changed - throw error if input type is incorrect when cSHAKE and KMAC. - freeze hash after finalize. --- .covignore | 2 - .gitignore | 4 +- .npmignore | 7 + .travis.yml | 8 +- CHANGELOG.md | 9 + bower.json | 2 +- build/sha3.min.js | 4 +- package-lock.json | 1802 ++++++++++++++++++++++++++++++++++++++++++ package.json | 24 +- src/sha3.js | 137 ++-- tests/node-test.js | 204 +++-- tests/test-cshake.js | 2 +- tests/test-shake.js | 1 + tests/test.js | 309 ++++---- tests/worker-test.js | 21 + tests/worker.html | 26 + tests/worker.js | 12 + 17 files changed, 2289 insertions(+), 285 deletions(-) delete mode 100644 .covignore create mode 100644 .npmignore create mode 100644 package-lock.json create mode 100644 tests/worker-test.js create mode 100644 tests/worker.html create mode 100644 tests/worker.js diff --git a/.covignore b/.covignore deleted file mode 100644 index c5e2446..0000000 --- a/.covignore +++ /dev/null @@ -1,2 +0,0 @@ -/node_modules/ -/tests/ diff --git a/.gitignore b/.gitignore index c2635c1..ecccf38 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,3 @@ /node_modules/ -/covreporter/ -/my_test/ +/coverage/ +/.nyc_output/ diff --git a/.npmignore b/.npmignore new file mode 100644 index 0000000..140f89b --- /dev/null +++ b/.npmignore @@ -0,0 +1,7 @@ +/node_modules/ +/coverage/ +/.nyc_output/ +/tests/ +.travis.yml +.npmignore +bower.json diff --git a/.travis.yml b/.travis.yml index 4036a6f..cea9e7f 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,12 +1,10 @@ language: node_js node_js: - - "0.12.15" - - "4.5" - - "6.5.0" + - "6.11.4" + - "8.6.0" before_install: - npm install coveralls - - npm install mocha-lcov-reporter -script: npm run-script coveralls +after_success: npm run coveralls branches: only: - master diff --git a/CHANGELOG.md b/CHANGELOG.md index 5e565db..6743ed4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,14 @@ # Change Log +## v0.7.0 / 2017-12-01 +### Added +- AMD support. +- support for web worker. #13 + +### Changed +- throw error if input type is incorrect when cSHAKE and KMAC. +- freeze hash after finalize. + ## v0.6.1 / 2017-07-03 ### Fixed - Typo on variable kmac_256 type definition. #12 diff --git a/bower.json b/bower.json index d5b6fef..22f0582 100644 --- a/bower.json +++ b/bower.json @@ -1,6 +1,6 @@ { "name": "js-sha3", - "version": "0.6.1", + "version": "0.7.0", "main": ["src/sha3.js"], "ignore": [ "samples", diff --git a/build/sha3.min.js b/build/sha3.min.js index 1d47e7d..36b7292 100644 --- a/build/sha3.min.js +++ b/build/sha3.min.js @@ -1,9 +1,9 @@ /** * [js-sha3]{@link https://github.com/emn178/js-sha3} * - * @version 0.6.1 + * @version 0.7.0 * @author Chen, Yi-Cyuan [emn178@gmail.com] * @copyright Chen, Yi-Cyuan 2015-2017 * @license MIT */ -!function(){"use strict";function t(t,e,r){this.blocks=[],this.s=[],this.padding=e,this.outputBits=r,this.reset=!0,this.block=0,this.start=0,this.blockCount=1600-(t<<1)>>5,this.byteCount=this.blockCount<<2,this.outputBlocks=r>>5,this.extraBytes=(31&r)>>3;for(var n=0;50>n;++n)this.s[n]=0}function e(e,r,n){t.call(this,e,r,n)}var r="object"==typeof window?window:{},n=!r.JS_SHA3_NO_NODE_JS&&"object"==typeof process&&process.versions&&process.versions.node;n&&(r=global);var o=!r.JS_SHA3_NO_COMMON_JS&&"object"==typeof module&&module.exports,i=!r.JS_SHA3_NO_ARRAY_BUFFER&&"undefined"!=typeof ArrayBuffer,a="0123456789abcdef".split(""),s=[31,7936,2031616,520093696],u=[4,1024,262144,67108864],f=[1,256,65536,16777216],c=[6,1536,393216,100663296],h=[0,8,16,24],p=[1,0,32898,0,32906,2147483648,2147516416,2147483648,32907,0,2147483649,0,2147516545,2147483648,32777,2147483648,138,0,136,0,2147516425,0,2147483658,0,2147516555,0,139,2147483648,32905,2147483648,32771,2147483648,32770,2147483648,128,2147483648,32778,0,2147483658,2147483648,2147516545,2147483648,32896,2147483648,2147483649,0,2147516424,2147483648],d=[224,256,384,512],y=[128,256],l=["hex","buffer","arrayBuffer","array"],b={128:168,256:136};(r.JS_SHA3_NO_NODE_JS||!Array.isArray)&&(Array.isArray=function(t){return"[object Array]"===Object.prototype.toString.call(t)});for(var v=function(e,r,n){return function(o){return new t(e,r,e).update(o)[n]()}},A=function(e,r,n){return function(o,i){return new t(e,r,i).update(o)[n]()}},g=function(t,e,r){return function(e,n,o,i){return S["cshake"+t].update(e,n,o,i)[r]()}},k=function(t,e,r){return function(e,n,o,i){return S["kmac"+t].update(e,n,o,i)[r]()}},B=function(t,e,r,n){for(var o=0;oc;){if(this.reset)for(this.reset=!1,s[0]=this.block,o=1;f+1>o;++o)s[o]=0;if(e)for(o=this.start;n>c&&u>o;++c)s[o>>2]|=t[c]<c&&u>o;++c)a=t.charCodeAt(c),128>a?s[o>>2]|=a<a?(s[o>>2]|=(192|a>>6)<>2]|=(128|63&a)<a||a>=57344?(s[o>>2]|=(224|a>>12)<>2]|=(128|a>>6&63)<>2]|=(128|63&a)<>2]|=(240|a>>18)<>2]|=(128|a>>12&63)<>2]|=(128|a>>6&63)<>2]|=(128|63&a)<=u){for(this.start=o-u,this.block=s[f],o=0;f>o;++o)p[o]^=s[o];U(p),this.reset=!0}else this.start=o}return this},t.prototype.encode=function(t,e){var r=255&t,n=1,o=[r];for(t>>=8,r=255&t;r>0;)o.unshift(r),t>>=8,r=255&t,++n;return e?o.push(n):o.unshift(n),this.update(o),o.length},t.prototype.encodeString=function(t){t=t||"";var e="string"!=typeof t;e&&t.constructor===r.ArrayBuffer&&(t=new Uint8Array(t));var n=t.length;if(!(!e||"number"==typeof n&&(Array.isArray(t)||i&&ArrayBuffer.isView(t))))throw"input is invalid type";var o=0;if(e)o=n;else for(var a=0;as?o+=1:2048>s?o+=2:55296>s||s>=57344?o+=3:(s=65536+((1023&s)<<10|1023&t.charCodeAt(++a)),o+=4)}return o+=this.encode(8*o),this.update(t),o},t.prototype.bytepad=function(t,e){for(var r=this.encode(e),n=0;n>2]|=this.padding[3&e],this.lastByteIndex===this.byteCount)for(t[0]=t[r],e=1;r+1>e;++e)t[e]=0;for(t[r-1]|=2147483648,e=0;r>e;++e)n[e]^=t[e];U(n)},t.prototype.toString=t.prototype.hex=function(){this.finalize();for(var t,e=this.blockCount,r=this.s,n=this.outputBlocks,o=this.extraBytes,i=0,s=0,u="";n>s;){for(i=0;e>i&&n>s;++i,++s)t=r[i],u+=a[t>>4&15]+a[15&t]+a[t>>12&15]+a[t>>8&15]+a[t>>20&15]+a[t>>16&15]+a[t>>28&15]+a[t>>24&15];s%e===0&&(U(r),i=0)}return o&&(t=r[i],o>0&&(u+=a[t>>4&15]+a[15&t]),o>1&&(u+=a[t>>12&15]+a[t>>8&15]),o>2&&(u+=a[t>>20&15]+a[t>>16&15])),u},t.prototype.arrayBuffer=function(){this.finalize();var t,e=this.blockCount,r=this.s,n=this.outputBlocks,o=this.extraBytes,i=0,a=0,s=this.outputBits>>3;t=new ArrayBuffer(o?n+1<<2:s);for(var u=new Uint32Array(t);n>a;){for(i=0;e>i&&n>a;++i,++a)u[a]=r[i];a%e===0&&U(r)}return o&&(u[i]=r[i],t=t.slice(0,s)),t},t.prototype.buffer=t.prototype.arrayBuffer,t.prototype.digest=t.prototype.array=function(){this.finalize();for(var t,e,r=this.blockCount,n=this.s,o=this.outputBlocks,i=this.extraBytes,a=0,s=0,u=[];o>s;){for(a=0;r>a&&o>s;++a,++s)t=s<<2,e=n[a],u[t]=255&e,u[t+1]=e>>8&255,u[t+2]=e>>16&255,u[t+3]=e>>24&255;s%r===0&&U(n)}return i&&(t=s<<2,e=n[a],i>0&&(u[t]=255&e),i>1&&(u[t+1]=e>>8&255),i>2&&(u[t+2]=e>>16&255)),u},e.prototype=new t,e.prototype.finalize=function(){return this.encode(this.outputBits,!0),t.prototype.finalize.call(this)};var U=function(t){var e,r,n,o,i,a,s,u,f,c,h,d,y,l,b,v,A,g,k,B,w,_,C,m,x,S,M,O,J,N,z,j,H,U,E,I,R,D,F,V,K,Y,q,G,L,P,Q,T,W,X,Z,$,tt,et,rt,nt,ot,it,at,st,ut,ft,ct;for(n=0;48>n;n+=2)o=t[0]^t[10]^t[20]^t[30]^t[40],i=t[1]^t[11]^t[21]^t[31]^t[41],a=t[2]^t[12]^t[22]^t[32]^t[42],s=t[3]^t[13]^t[23]^t[33]^t[43],u=t[4]^t[14]^t[24]^t[34]^t[44],f=t[5]^t[15]^t[25]^t[35]^t[45],c=t[6]^t[16]^t[26]^t[36]^t[46],h=t[7]^t[17]^t[27]^t[37]^t[47],d=t[8]^t[18]^t[28]^t[38]^t[48],y=t[9]^t[19]^t[29]^t[39]^t[49],e=d^(a<<1|s>>>31),r=y^(s<<1|a>>>31),t[0]^=e,t[1]^=r,t[10]^=e,t[11]^=r,t[20]^=e,t[21]^=r,t[30]^=e,t[31]^=r,t[40]^=e,t[41]^=r,e=o^(u<<1|f>>>31),r=i^(f<<1|u>>>31),t[2]^=e,t[3]^=r,t[12]^=e,t[13]^=r,t[22]^=e,t[23]^=r,t[32]^=e,t[33]^=r,t[42]^=e,t[43]^=r,e=a^(c<<1|h>>>31),r=s^(h<<1|c>>>31),t[4]^=e,t[5]^=r,t[14]^=e,t[15]^=r,t[24]^=e,t[25]^=r,t[34]^=e,t[35]^=r,t[44]^=e,t[45]^=r,e=u^(d<<1|y>>>31),r=f^(y<<1|d>>>31),t[6]^=e,t[7]^=r,t[16]^=e,t[17]^=r,t[26]^=e,t[27]^=r,t[36]^=e,t[37]^=r,t[46]^=e,t[47]^=r,e=c^(o<<1|i>>>31),r=h^(i<<1|o>>>31),t[8]^=e,t[9]^=r,t[18]^=e,t[19]^=r,t[28]^=e,t[29]^=r,t[38]^=e,t[39]^=r,t[48]^=e,t[49]^=r,l=t[0],b=t[1],P=t[11]<<4|t[10]>>>28,Q=t[10]<<4|t[11]>>>28,O=t[20]<<3|t[21]>>>29,J=t[21]<<3|t[20]>>>29,st=t[31]<<9|t[30]>>>23,ut=t[30]<<9|t[31]>>>23,Y=t[40]<<18|t[41]>>>14,q=t[41]<<18|t[40]>>>14,U=t[2]<<1|t[3]>>>31,E=t[3]<<1|t[2]>>>31,v=t[13]<<12|t[12]>>>20,A=t[12]<<12|t[13]>>>20,T=t[22]<<10|t[23]>>>22,W=t[23]<<10|t[22]>>>22,N=t[33]<<13|t[32]>>>19,z=t[32]<<13|t[33]>>>19,ft=t[42]<<2|t[43]>>>30,ct=t[43]<<2|t[42]>>>30,et=t[5]<<30|t[4]>>>2,rt=t[4]<<30|t[5]>>>2,I=t[14]<<6|t[15]>>>26,R=t[15]<<6|t[14]>>>26,g=t[25]<<11|t[24]>>>21,k=t[24]<<11|t[25]>>>21,X=t[34]<<15|t[35]>>>17,Z=t[35]<<15|t[34]>>>17,j=t[45]<<29|t[44]>>>3,H=t[44]<<29|t[45]>>>3,m=t[6]<<28|t[7]>>>4,x=t[7]<<28|t[6]>>>4,nt=t[17]<<23|t[16]>>>9,ot=t[16]<<23|t[17]>>>9,D=t[26]<<25|t[27]>>>7,F=t[27]<<25|t[26]>>>7,B=t[36]<<21|t[37]>>>11,w=t[37]<<21|t[36]>>>11,$=t[47]<<24|t[46]>>>8,tt=t[46]<<24|t[47]>>>8,G=t[8]<<27|t[9]>>>5,L=t[9]<<27|t[8]>>>5,S=t[18]<<20|t[19]>>>12,M=t[19]<<20|t[18]>>>12,it=t[29]<<7|t[28]>>>25,at=t[28]<<7|t[29]>>>25,V=t[38]<<8|t[39]>>>24,K=t[39]<<8|t[38]>>>24,_=t[48]<<14|t[49]>>>18,C=t[49]<<14|t[48]>>>18,t[0]=l^~v&g,t[1]=b^~A&k,t[10]=m^~S&O,t[11]=x^~M&J,t[20]=U^~I&D,t[21]=E^~R&F,t[30]=G^~P&T,t[31]=L^~Q&W,t[40]=et^~nt&it,t[41]=rt^~ot&at,t[2]=v^~g&B,t[3]=A^~k&w,t[12]=S^~O&N,t[13]=M^~J&z,t[22]=I^~D&V,t[23]=R^~F&K,t[32]=P^~T&X,t[33]=Q^~W&Z,t[42]=nt^~it&st,t[43]=ot^~at&ut,t[4]=g^~B&_,t[5]=k^~w&C,t[14]=O^~N&j,t[15]=J^~z&H,t[24]=D^~V&Y,t[25]=F^~K&q,t[34]=T^~X&$,t[35]=W^~Z&tt,t[44]=it^~st&ft,t[45]=at^~ut&ct,t[6]=B^~_&l,t[7]=w^~C&b,t[16]=N^~j&m,t[17]=z^~H&x,t[26]=V^~Y&U,t[27]=K^~q&E,t[36]=X^~$&G,t[37]=Z^~tt&L,t[46]=st^~ft&et,t[47]=ut^~ct&rt,t[8]=_^~l&v,t[9]=C^~b&A,t[18]=j^~m&S,t[19]=H^~x&M,t[28]=Y^~U&I,t[29]=q^~E&R,t[38]=$^~G&P,t[39]=tt^~L&Q,t[48]=ft^~et&nt,t[49]=ct^~rt&ot,t[0]^=p[n],t[1]^=p[n+1]};if(o)module.exports=S;else for(var O=0;O>5,this.byteCount=this.blockCount<<2,this.outputBlocks=r>>5,this.extraBytes=(31&r)>>3;for(var n=0;n<50;++n)this.s[n]=0}function e(e,r,n){t.call(this,e,r,n)}var r="input is invalid type",n="object"==typeof window,i=n?window:{};i.JS_SHA3_NO_WINDOW&&(n=!1);var o=!n&&"object"==typeof self;!i.JS_SHA3_NO_NODE_JS&&"object"==typeof process&&process.versions&&process.versions.node?i=global:o&&(i=self);var s=!i.JS_SHA3_NO_COMMON_JS&&"object"==typeof module&&module.exports,a="function"==typeof define&&define.amd,u=!i.JS_SHA3_NO_ARRAY_BUFFER&&"undefined"!=typeof ArrayBuffer,f="0123456789abcdef".split(""),c=[4,1024,262144,67108864],h=[0,8,16,24],p=[1,0,32898,0,32906,2147483648,2147516416,2147483648,32907,0,2147483649,0,2147516545,2147483648,32777,2147483648,138,0,136,0,2147516425,0,2147483658,0,2147516555,0,139,2147483648,32905,2147483648,32771,2147483648,32770,2147483648,128,2147483648,32778,0,2147483658,2147483648,2147516545,2147483648,32896,2147483648,2147483649,0,2147516424,2147483648],d=[224,256,384,512],l=[128,256],y=["hex","buffer","arrayBuffer","array","digest"],b={128:168,256:136};!i.JS_SHA3_NO_NODE_JS&&Array.isArray||(Array.isArray=function(t){return"[object Array]"===Object.prototype.toString.call(t)}),!u||!i.JS_SHA3_NO_ARRAY_BUFFER_IS_VIEW&&ArrayBuffer.isView||(ArrayBuffer.isView=function(t){return"object"==typeof t&&t.buffer&&t.buffer.constructor===ArrayBuffer});for(var A=function(e,r,n){return function(i){return new t(e,r,e).update(i)[n]()}},v=function(e,r,n){return function(i,o){return new t(e,r,o).update(i)[n]()}},B=function(t,e,r){return function(e,n,i,o){return S["cshake"+t].update(e,n,i,o)[r]()}},g=function(t,e,r){return function(e,n,i,o){return S["kmac"+t].update(e,n,i,o)[r]()}},w=function(t,e,r,n){for(var i=0;i>2]|=t[p]<>2]|=o<>2]|=(192|o>>6)<>2]|=(128|63&o)<=57344?(s[i>>2]|=(224|o>>12)<>2]|=(128|o>>6&63)<>2]|=(128|63&o)<>2]|=(240|o>>18)<>2]|=(128|o>>12&63)<>2]|=(128|o>>6&63)<>2]|=(128|63&o)<=a){for(this.start=i-a,this.block=s[c],i=0;i>=8);r>0;)i.unshift(r),r=255&(t>>=8),++n;return e?i.push(n):i.unshift(n),this.update(i),i.length},t.prototype.encodeString=function(t){var e,n=typeof t;if("string"!==n){if("object"!==n)throw r;if(null===t)throw r;if(u&&t.constructor===ArrayBuffer)t=new Uint8Array(t);else if(!(Array.isArray(t)||u&&ArrayBuffer.isView(t)))throw r;e=!0}var i=0,o=t.length;if(e)i=o;else for(var s=0;s=57344?i+=3:(a=65536+((1023&a)<<10|1023&t.charCodeAt(++s)),i+=4)}return i+=this.encode(8*i),this.update(t),i},t.prototype.bytepad=function(t,e){for(var r=this.encode(e),n=0;n>2]|=this.padding[3&e],this.lastByteIndex===this.byteCount)for(t[0]=t[r],e=1;e>4&15]+f[15&t]+f[t>>12&15]+f[t>>8&15]+f[t>>20&15]+f[t>>16&15]+f[t>>28&15]+f[t>>24&15];s%e==0&&(J(r),o=0)}return i&&(t=r[o],a+=f[t>>4&15]+f[15&t],i>1&&(a+=f[t>>12&15]+f[t>>8&15]),i>2&&(a+=f[t>>20&15]+f[t>>16&15])),a},t.prototype.arrayBuffer=function(){this.finalize();var t,e=this.blockCount,r=this.s,n=this.outputBlocks,i=this.extraBytes,o=0,s=0,a=this.outputBits>>3;t=i?new ArrayBuffer(n+1<<2):new ArrayBuffer(a);for(var u=new Uint32Array(t);s>8&255,u[t+2]=e>>16&255,u[t+3]=e>>24&255;a%r==0&&J(n)}return o&&(t=a<<2,e=n[s],u[t]=255&e,o>1&&(u[t+1]=e>>8&255),o>2&&(u[t+2]=e>>16&255)),u},(e.prototype=new t).finalize=function(){return this.encode(this.outputBits,!0),t.prototype.finalize.call(this)};var J=function(t){var e,r,n,i,o,s,a,u,f,c,h,d,l,y,b,A,v,B,g,w,_,k,S,C,x,m,O,z,N,j,J,M,H,I,R,E,U,V,F,D,W,Y,K,q,G,L,P,Q,T,X,Z,$,tt,et,rt,nt,it,ot,st,at,ut,ft,ct;for(n=0;n<48;n+=2)i=t[0]^t[10]^t[20]^t[30]^t[40],o=t[1]^t[11]^t[21]^t[31]^t[41],s=t[2]^t[12]^t[22]^t[32]^t[42],a=t[3]^t[13]^t[23]^t[33]^t[43],u=t[4]^t[14]^t[24]^t[34]^t[44],f=t[5]^t[15]^t[25]^t[35]^t[45],c=t[6]^t[16]^t[26]^t[36]^t[46],h=t[7]^t[17]^t[27]^t[37]^t[47],e=(d=t[8]^t[18]^t[28]^t[38]^t[48])^(s<<1|a>>>31),r=(l=t[9]^t[19]^t[29]^t[39]^t[49])^(a<<1|s>>>31),t[0]^=e,t[1]^=r,t[10]^=e,t[11]^=r,t[20]^=e,t[21]^=r,t[30]^=e,t[31]^=r,t[40]^=e,t[41]^=r,e=i^(u<<1|f>>>31),r=o^(f<<1|u>>>31),t[2]^=e,t[3]^=r,t[12]^=e,t[13]^=r,t[22]^=e,t[23]^=r,t[32]^=e,t[33]^=r,t[42]^=e,t[43]^=r,e=s^(c<<1|h>>>31),r=a^(h<<1|c>>>31),t[4]^=e,t[5]^=r,t[14]^=e,t[15]^=r,t[24]^=e,t[25]^=r,t[34]^=e,t[35]^=r,t[44]^=e,t[45]^=r,e=u^(d<<1|l>>>31),r=f^(l<<1|d>>>31),t[6]^=e,t[7]^=r,t[16]^=e,t[17]^=r,t[26]^=e,t[27]^=r,t[36]^=e,t[37]^=r,t[46]^=e,t[47]^=r,e=c^(i<<1|o>>>31),r=h^(o<<1|i>>>31),t[8]^=e,t[9]^=r,t[18]^=e,t[19]^=r,t[28]^=e,t[29]^=r,t[38]^=e,t[39]^=r,t[48]^=e,t[49]^=r,y=t[0],b=t[1],L=t[11]<<4|t[10]>>>28,P=t[10]<<4|t[11]>>>28,z=t[20]<<3|t[21]>>>29,N=t[21]<<3|t[20]>>>29,at=t[31]<<9|t[30]>>>23,ut=t[30]<<9|t[31]>>>23,Y=t[40]<<18|t[41]>>>14,K=t[41]<<18|t[40]>>>14,I=t[2]<<1|t[3]>>>31,R=t[3]<<1|t[2]>>>31,A=t[13]<<12|t[12]>>>20,v=t[12]<<12|t[13]>>>20,Q=t[22]<<10|t[23]>>>22,T=t[23]<<10|t[22]>>>22,j=t[33]<<13|t[32]>>>19,J=t[32]<<13|t[33]>>>19,ft=t[42]<<2|t[43]>>>30,ct=t[43]<<2|t[42]>>>30,et=t[5]<<30|t[4]>>>2,rt=t[4]<<30|t[5]>>>2,E=t[14]<<6|t[15]>>>26,U=t[15]<<6|t[14]>>>26,B=t[25]<<11|t[24]>>>21,g=t[24]<<11|t[25]>>>21,X=t[34]<<15|t[35]>>>17,Z=t[35]<<15|t[34]>>>17,M=t[45]<<29|t[44]>>>3,H=t[44]<<29|t[45]>>>3,C=t[6]<<28|t[7]>>>4,x=t[7]<<28|t[6]>>>4,nt=t[17]<<23|t[16]>>>9,it=t[16]<<23|t[17]>>>9,V=t[26]<<25|t[27]>>>7,F=t[27]<<25|t[26]>>>7,w=t[36]<<21|t[37]>>>11,_=t[37]<<21|t[36]>>>11,$=t[47]<<24|t[46]>>>8,tt=t[46]<<24|t[47]>>>8,q=t[8]<<27|t[9]>>>5,G=t[9]<<27|t[8]>>>5,m=t[18]<<20|t[19]>>>12,O=t[19]<<20|t[18]>>>12,ot=t[29]<<7|t[28]>>>25,st=t[28]<<7|t[29]>>>25,D=t[38]<<8|t[39]>>>24,W=t[39]<<8|t[38]>>>24,k=t[48]<<14|t[49]>>>18,S=t[49]<<14|t[48]>>>18,t[0]=y^~A&B,t[1]=b^~v&g,t[10]=C^~m&z,t[11]=x^~O&N,t[20]=I^~E&V,t[21]=R^~U&F,t[30]=q^~L&Q,t[31]=G^~P&T,t[40]=et^~nt&ot,t[41]=rt^~it&st,t[2]=A^~B&w,t[3]=v^~g&_,t[12]=m^~z&j,t[13]=O^~N&J,t[22]=E^~V&D,t[23]=U^~F&W,t[32]=L^~Q&X,t[33]=P^~T&Z,t[42]=nt^~ot&at,t[43]=it^~st&ut,t[4]=B^~w&k,t[5]=g^~_&S,t[14]=z^~j&M,t[15]=N^~J&H,t[24]=V^~D&Y,t[25]=F^~W&K,t[34]=Q^~X&$,t[35]=T^~Z&tt,t[44]=ot^~at&ft,t[45]=st^~ut&ct,t[6]=w^~k&y,t[7]=_^~S&b,t[16]=j^~M&C,t[17]=J^~H&x,t[26]=D^~Y&I,t[27]=W^~K&R,t[36]=X^~$&q,t[37]=Z^~tt&G,t[46]=at^~ft&et,t[47]=ut^~ct&rt,t[8]=k^~y&A,t[9]=S^~b&v,t[18]=M^~C&m,t[19]=H^~x&O,t[28]=Y^~I&E,t[29]=K^~R&U,t[38]=$^~q&L,t[39]=tt^~G&P,t[48]=ft^~et&nt,t[49]=ct^~rt&it,t[0]^=p[n],t[1]^=p[n+1]};if(s)module.exports=S;else{for(x=0;x> 5; @@ -168,19 +184,27 @@ } Keccak.prototype.update = function (message) { - var notString = typeof message !== 'string'; - if (notString && message.constructor === root.ArrayBuffer) { - message = new Uint8Array(message); + if (this.finalized) { + return; } - var length = message.length; - if (notString) { - if (typeof length !== 'number' || - !Array.isArray(message) && - !(ARRAY_BUFFER && ArrayBuffer.isView(message))) { - throw 'input is invalid type'; + var notString, type = typeof message; + if (type !== 'string') { + if (type === 'object') { + if (message === null) { + throw ERROR; + } else if (ARRAY_BUFFER && message.constructor === ArrayBuffer) { + message = new Uint8Array(message); + } else if (!Array.isArray(message)) { + if (!ARRAY_BUFFER || !ArrayBuffer.isView(message)) { + throw ERROR; + } + } + } else { + throw ERROR; } + notString = true; } - var blocks = this.blocks, byteCount = this.byteCount, + var blocks = this.blocks, byteCount = this.byteCount, length = message.length, blockCount = this.blockCount, index = 0, s = this.s, i, code; while (index < length) { @@ -253,20 +277,24 @@ }; Keccak.prototype.encodeString = function (str) { - str = str || ''; - var notString = typeof str !== 'string'; - if (notString && str.constructor === root.ArrayBuffer) { - str = new Uint8Array(str); - } - var length = str.length; - if (notString) { - if (typeof length !== 'number' || - !Array.isArray(str) && - !(ARRAY_BUFFER && ArrayBuffer.isView(str))) { - throw 'input is invalid type'; + var notString, type = typeof str; + if (type !== 'string') { + if (type === 'object') { + if (str === null) { + throw ERROR; + } else if (ARRAY_BUFFER && str.constructor === ArrayBuffer) { + str = new Uint8Array(str); + } else if (!Array.isArray(str)) { + if (!ARRAY_BUFFER || !ArrayBuffer.isView(str)) { + throw ERROR; + } + } + } else { + throw ERROR; } + notString = true; } - var bytes = 0; + var bytes = 0, length = str.length; if (notString) { bytes = length; } else { @@ -291,7 +319,7 @@ Keccak.prototype.bytepad = function (strs, w) { var bytes = this.encode(w); - for (var i = 0;i < strs.length;++i) { + for (var i = 0; i < strs.length; ++i) { bytes += this.encodeString(strs[i]); } var paddingBytes = w - bytes % w; @@ -302,6 +330,10 @@ }; Keccak.prototype.finalize = function () { + if (this.finalized) { + return; + } + this.finalized = true; var blocks = this.blocks, i = this.lastByteIndex, blockCount = this.blockCount, s = this.s; blocks[i >> 2] |= this.padding[i & 3]; if (this.lastByteIndex === this.byteCount) { @@ -321,15 +353,15 @@ this.finalize(); var blockCount = this.blockCount, s = this.s, outputBlocks = this.outputBlocks, - extraBytes = this.extraBytes, i = 0, j = 0; + extraBytes = this.extraBytes, i = 0, j = 0; var hex = '', block; while (j < outputBlocks) { for (i = 0; i < blockCount && j < outputBlocks; ++i, ++j) { block = s[i]; hex += HEX_CHARS[(block >> 4) & 0x0F] + HEX_CHARS[block & 0x0F] + - HEX_CHARS[(block >> 12) & 0x0F] + HEX_CHARS[(block >> 8) & 0x0F] + - HEX_CHARS[(block >> 20) & 0x0F] + HEX_CHARS[(block >> 16) & 0x0F] + - HEX_CHARS[(block >> 28) & 0x0F] + HEX_CHARS[(block >> 24) & 0x0F]; + HEX_CHARS[(block >> 12) & 0x0F] + HEX_CHARS[(block >> 8) & 0x0F] + + HEX_CHARS[(block >> 20) & 0x0F] + HEX_CHARS[(block >> 16) & 0x0F] + + HEX_CHARS[(block >> 28) & 0x0F] + HEX_CHARS[(block >> 24) & 0x0F]; } if (j % blockCount === 0) { f(s); @@ -338,9 +370,7 @@ } if (extraBytes) { block = s[i]; - if (extraBytes > 0) { - hex += HEX_CHARS[(block >> 4) & 0x0F] + HEX_CHARS[block & 0x0F]; - } + hex += HEX_CHARS[(block >> 4) & 0x0F] + HEX_CHARS[block & 0x0F]; if (extraBytes > 1) { hex += HEX_CHARS[(block >> 12) & 0x0F] + HEX_CHARS[(block >> 8) & 0x0F]; } @@ -355,7 +385,7 @@ this.finalize(); var blockCount = this.blockCount, s = this.s, outputBlocks = this.outputBlocks, - extraBytes = this.extraBytes, i = 0, j = 0; + extraBytes = this.extraBytes, i = 0, j = 0; var bytes = this.outputBits >> 3; var buffer; if (extraBytes) { @@ -385,7 +415,7 @@ this.finalize(); var blockCount = this.blockCount, s = this.s, outputBlocks = this.outputBlocks, - extraBytes = this.extraBytes, i = 0, j = 0; + extraBytes = this.extraBytes, i = 0, j = 0; var array = [], offset, block; while (j < outputBlocks) { for (i = 0; i < blockCount && j < outputBlocks; ++i, ++j) { @@ -403,9 +433,7 @@ if (extraBytes) { offset = j << 2; block = s[i]; - if (extraBytes > 0) { - array[offset] = block & 0xFF; - } + array[offset] = block & 0xFF; if (extraBytes > 1) { array[offset + 1] = (block >> 8) & 0xFF; } @@ -429,9 +457,9 @@ var f = function (s) { var h, l, n, c0, c1, c2, c3, c4, c5, c6, c7, c8, c9, - b0, b1, b2, b3, b4, b5, b6, b7, b8, b9, b10, b11, b12, b13, b14, b15, b16, b17, - b18, b19, b20, b21, b22, b23, b24, b25, b26, b27, b28, b29, b30, b31, b32, b33, - b34, b35, b36, b37, b38, b39, b40, b41, b42, b43, b44, b45, b46, b47, b48, b49; + b0, b1, b2, b3, b4, b5, b6, b7, b8, b9, b10, b11, b12, b13, b14, b15, b16, b17, + b18, b19, b20, b21, b22, b23, b24, b25, b26, b27, b28, b29, b30, b31, b32, b33, + b34, b35, b36, b37, b38, b39, b40, b41, b42, b43, b44, b45, b46, b47, b48, b49; for (n = 0; n < 48; n += 2) { c0 = s[0] ^ s[10] ^ s[20] ^ s[30] ^ s[40]; c1 = s[1] ^ s[11] ^ s[21] ^ s[31] ^ s[41]; @@ -615,8 +643,13 @@ if (COMMON_JS) { module.exports = methods; } else { - for (var i = 0; i < methodNames.length; ++i) { + for (i = 0; i < methodNames.length; ++i) { root[methodNames[i]] = methods[methodNames[i]]; } + if (AMD) { + define(function () { + return methods; + }); + } } })(); diff --git a/tests/node-test.js b/tests/node-test.js index f51d280..3f60d2e 100644 --- a/tests/node-test.js +++ b/tests/node-test.js @@ -1,80 +1,150 @@ expect = require('expect.js'); +Worker = require('webworker-threads').Worker; + +function unset() { + delete require.cache[require.resolve('../src/sha3.js')]; + delete require.cache[require.resolve('./test.js')]; + sha3_512 = null; + sha3_384 = null; + sha3_256 = null; + sha3_224 = null; + keccak512 = null; + keccak384 = null; + keccak256 = null; + keccak224 = null; + shake128 = null; + shake256 = null; + kmac128 = null; + kmac256 = null; + BUFFER = undefined; + JS_SHA3_NO_WINDOW = undefined; + JS_SHA3_NO_NODE_JS = undefined; + JS_SHA3_NO_COMMON_JS = undefined; + JS_SHA3_NO_ARRAY_BUFFER = undefined; + JS_SHA3_NO_ARRAY_BUFFER_IS_VIEW = undefined; + window = undefined; +} + +function requireToGlobal() { + var sha3 = require('../src/sha3.js'); + keccak512 = sha3.keccak512; + keccak384 = sha3.keccak384; + keccak256 = sha3.keccak256; + keccak224 = sha3.keccak224; + sha3_512 = sha3.sha3_512; + sha3_384 = sha3.sha3_384; + sha3_256 = sha3.sha3_256; + sha3_224 = sha3.sha3_224; + shake128 = sha3.shake128; + shake256 = sha3.shake256; + cshake128 = sha3.cshake128; + cshake256 = sha3.cshake256; + kmac128 = sha3.kmac128; + kmac256 = sha3.kmac256; +} + +function runCommonJsTest() { + requireToGlobal(); + require('./test.js'); + unset(); +} + +function runWindowTest(extra) { + window = global; + require('../src/sha3.js'); + require('./test.js'); + if (extra) { + require('./test-shake.js'); + require('./test-cshake.js'); + require('./test-kmac.js'); + } + unset(); +} // Node.js env -var sha3 = require('../src/sha3.js'); -keccak512 = sha3.keccak512; -keccak384 = sha3.keccak384; -keccak256 = sha3.keccak256; -keccak224 = sha3.keccak224; -sha3_512 = sha3.sha3_512; -sha3_384 = sha3.sha3_384; -sha3_256 = sha3.sha3_256; -sha3_224 = sha3.sha3_224; -shake128 = sha3.shake128; -shake256 = sha3.shake256; -cshake128 = sha3.cshake128; -cshake256 = sha3.cshake256; -kmac128 = sha3.kmac128; -kmac256 = sha3.kmac256; -require('./test.js'); -require('./test-shake.js'); -require('./test-cshake.js'); -require('./test-kmac.js'); - -delete require.cache[require.resolve('../src/sha3.js')]; -delete require.cache[require.resolve('./test.js')]; -delete require.cache[require.resolve('./test-shake.js')]; -delete require.cache[require.resolve('./test-cshake.js')]; -delete require.cache[require.resolve('./test-kmac.js')]; +BUFFER = true; +runCommonJsTest(); // Webpack browser env JS_SHA3_NO_NODE_JS = true; window = global; -expect = require('expect.js'); -var sha3 = require('../src/sha3.js'); -keccak512 = sha3.keccak512; -keccak384 = sha3.keccak384; -keccak256 = sha3.keccak256; -keccak224 = sha3.keccak224; -sha3_512 = sha3.sha3_512; -sha3_384 = sha3.sha3_384; -sha3_256 = sha3.sha3_256; -sha3_224 = sha3.sha3_224; -shake128 = sha3.shake128; -shake256 = sha3.shake256; -cshake128 = sha3.cshake128; -cshake256 = sha3.cshake256; -kmac128 = sha3.kmac128; -kmac256 = sha3.kmac256; -require('./test.js'); -require('./test-shake.js'); -require('./test-cshake.js'); -require('./test-kmac.js'); - -delete require.cache[require.resolve('../src/sha3.js')]; -delete require.cache[require.resolve('./test.js')]; -delete require.cache[require.resolve('./test-shake.js')]; -delete require.cache[require.resolve('./test-cshake.js')]; -delete require.cache[require.resolve('./test-kmac.js')]; -sha3_512 = null; -sha3_384 = null; -sha3_256 = null; -sha3_224 = null; -keccak512 = null; -keccak384 = null; -keccak256 = null; -keccak224 = null; -shake128 = null; -shake256 = null; -kmac128 = null; -kmac256 = null; +runCommonJsTest(); // browser env JS_SHA3_NO_NODE_JS = true; JS_SHA3_NO_COMMON_JS = true; +runWindowTest(true); + +// browser env and no array buffer +JS_SHA3_NO_NODE_JS = true; +JS_SHA3_NO_COMMON_JS = true; +JS_SHA3_NO_ARRAY_BUFFER = true; +runWindowTest(); + +// browser env and no isView +JS_SHA3_NO_NODE_JS = true; +JS_SHA3_NO_COMMON_JS = true; +JS_SHA3_NO_ARRAY_BUFFER_IS_VIEW = true; +runWindowTest(); + +// browser AMD +JS_SHA3_NO_NODE_JS = true; +JS_SHA3_NO_COMMON_JS = true; +JS_SHA3_NO_ARRAY_BUFFER_IS_VIEW = false; window = global; +define = function (func) { + sha3 = func(); + keccak512 = sha3.keccak512; + keccak384 = sha3.keccak384; + keccak256 = sha3.keccak256; + keccak224 = sha3.keccak224; + sha3_512 = sha3.sha3_512; + sha3_384 = sha3.sha3_384; + sha3_256 = sha3.sha3_256; + sha3_224 = sha3.sha3_224; + shake128 = sha3.shake128; + shake256 = sha3.shake256; + cshake128 = sha3.cshake128; + cshake256 = sha3.cshake256; + kmac128 = sha3.kmac128; + kmac256 = sha3.kmac256; + require('./test.js'); +}; +define.amd = true; + require('../src/sha3.js'); -require('./test.js'); -require('./test-shake.js'); -require('./test-cshake.js'); -require('./test-kmac.js'); +unset(); + +// webworker +WORKER = 'tests/worker.js'; +SOURCE = 'src/sha3.js'; + +require('./worker-test.js'); + +delete require.cache[require.resolve('./worker-test.js')]; + +// cover webworker +JS_SHA3_NO_WINDOW = true; +JS_SHA3_NO_NODE_JS = true; +WORKER = './worker.js'; +SOURCE = '../src/sha3.js'; +window = global; +self = global; + +Worker = function (file) { + require(file); + currentWorker = this; + + this.postMessage = function (data) { + onmessage({data: data}); + }; +} + +postMessage = function (data) { + currentWorker.onmessage({data: data}); +} + +importScripts = function () {}; + +requireToGlobal(); +require('./worker-test.js'); diff --git a/tests/test-cshake.js b/tests/test-cshake.js index 03e4df4..bcc2be2 100644 --- a/tests/test-cshake.js +++ b/tests/test-cshake.js @@ -64,6 +64,6 @@ expect(testCase.method(c.input, c.bits, c.n, c.s)).to.be(c.output); }); }); - }); + }); }); })(cshake256, cshake128); diff --git a/tests/test-shake.js b/tests/test-shake.js index 4c3d729..2d17aa7 100644 --- a/tests/test-shake.js +++ b/tests/test-shake.js @@ -27,6 +27,7 @@ it('should be equal', function () { expect(shake128('', 16)).to.be('7f9c'); expect(shake128('', 24)).to.be('7f9c2b'); + expect(shake128.array('', 8)).to.eql([0x7f]); expect(shake128.array('', 16)).to.eql([0x7f, 0x9c]); expect(shake128.array('', 24)).to.eql([0x7f, 0x9c, 0x2b]); }); diff --git a/tests/test.js b/tests/test.js index c09c615..953aa52 100644 --- a/tests/test.js +++ b/tests/test.js @@ -9,63 +9,6 @@ return hex; }; - function runTestCases(methods, testCases) { - methods.forEach(function (method) { - describe('#' + method.name, function () { - var methodTestCases = testCases[method.name]; - for (var testCaseName in methodTestCases) { - (function (testCaseName) { - var testCase = methodTestCases[testCaseName]; - context('when ' + testCaseName, function () { - for (var hash in testCase) { - (function (message, hash) { - it('should be equal', function () { - expect(method.call(message)).to.be(hash); - }); - })(testCase[hash], hash); - } - }); - })(testCaseName); - } - }); - }); - } - - var methods = [ - { - name: 'sha3_512', - call: sha3_512 - }, - { - name: 'sha3_384', - call: sha3_384 - }, - { - name: 'sha3_256', - call: sha3_256 - }, - { - name: 'sha3_224', - call: sha3_224 - }, - { - name: 'keccak512', - call: keccak512 - }, - { - name: 'keccak384', - call: keccak384 - }, - { - name: 'keccak256', - call: keccak256 - }, - { - name: 'keccak224', - call: keccak224 - } - ]; - var testCases = { sha3_512: { 'ascii': { @@ -92,14 +35,6 @@ 'Array': { 'a69f73cca23a9ac5c8b567dc185a756e97c982164fe25859e0d1dcc1475c80a615b2123af1f5f94c11e3e9402c3ac558f500199d95b6d3e301758586281dcd26': [], '01dedd5de4ef14642445ba5f5b97c15e47b9ad931326e4b0727cd94cefc44fff23f07bf543139939b49128caf436dc1bdee54fcb24023a08d9403f9b4bf0d450': [84, 104, 101, 32, 113, 117, 105, 99, 107, 32, 98, 114, 111, 119, 110, 32, 102, 111, 120, 32, 106, 117, 109, 112, 115, 32, 111, 118, 101, 114, 32, 116, 104, 101, 32, 108, 97, 122, 121, 32, 100, 111, 103] - }, - 'Uint8Array': { - 'a69f73cca23a9ac5c8b567dc185a756e97c982164fe25859e0d1dcc1475c80a615b2123af1f5f94c11e3e9402c3ac558f500199d95b6d3e301758586281dcd26': new Uint8Array([]), - '01dedd5de4ef14642445ba5f5b97c15e47b9ad931326e4b0727cd94cefc44fff23f07bf543139939b49128caf436dc1bdee54fcb24023a08d9403f9b4bf0d450': new Uint8Array([84, 104, 101, 32, 113, 117, 105, 99, 107, 32, 98, 114, 111, 119, 110, 32, 102, 111, 120, 32, 106, 117, 109, 112, 115, 32, 111, 118, 101, 114, 32, 116, 104, 101, 32, 108, 97, 122, 121, 32, 100, 111, 103]) - }, - 'ArrayBuffer': { - 'a69f73cca23a9ac5c8b567dc185a756e97c982164fe25859e0d1dcc1475c80a615b2123af1f5f94c11e3e9402c3ac558f500199d95b6d3e301758586281dcd26': new ArrayBuffer(0), - '01dedd5de4ef14642445ba5f5b97c15e47b9ad931326e4b0727cd94cefc44fff23f07bf543139939b49128caf436dc1bdee54fcb24023a08d9403f9b4bf0d450': new Uint8Array([84, 104, 101, 32, 113, 117, 105, 99, 107, 32, 98, 114, 111, 119, 110, 32, 102, 111, 120, 32, 106, 117, 109, 112, 115, 32, 111, 118, 101, 114, 32, 116, 104, 101, 32, 108, 97, 122, 121, 32, 100, 111, 103]).buffer } }, sha3_384: { @@ -237,104 +172,192 @@ } }; - runTestCases(methods, testCases); - - describe('sha3_512', function () { - context('#arrayBuffer', function () { - it('should be equal', function () { - expect(sha3_512.arrayBuffer('').toHexString()).to.be('a69f73cca23a9ac5c8b567dc185a756e97c982164fe25859e0d1dcc1475c80a615b2123af1f5f94c11e3e9402c3ac558f500199d95b6d3e301758586281dcd26'); - expect(sha3_512.buffer('').toHexString()).to.be('a69f73cca23a9ac5c8b567dc185a756e97c982164fe25859e0d1dcc1475c80a615b2123af1f5f94c11e3e9402c3ac558f500199d95b6d3e301758586281dcd26'); - }); - }); + if (!(typeof JS_SHA3_NO_ARRAY_BUFFER === 'boolean' && JS_SHA3_NO_ARRAY_BUFFER)) { + testCases.sha3_512.Uint8Array = { + 'a69f73cca23a9ac5c8b567dc185a756e97c982164fe25859e0d1dcc1475c80a615b2123af1f5f94c11e3e9402c3ac558f500199d95b6d3e301758586281dcd26': new Uint8Array([]), + '01dedd5de4ef14642445ba5f5b97c15e47b9ad931326e4b0727cd94cefc44fff23f07bf543139939b49128caf436dc1bdee54fcb24023a08d9403f9b4bf0d450': new Uint8Array([84, 104, 101, 32, 113, 117, 105, 99, 107, 32, 98, 114, 111, 119, 110, 32, 102, 111, 120, 32, 106, 117, 109, 112, 115, 32, 111, 118, 101, 114, 32, 116, 104, 101, 32, 108, 97, 122, 121, 32, 100, 111, 103]) + }; + testCases.sha3_512.ArrayBuffer = { + 'a69f73cca23a9ac5c8b567dc185a756e97c982164fe25859e0d1dcc1475c80a615b2123af1f5f94c11e3e9402c3ac558f500199d95b6d3e301758586281dcd26': new ArrayBuffer(0), + '01dedd5de4ef14642445ba5f5b97c15e47b9ad931326e4b0727cd94cefc44fff23f07bf543139939b49128caf436dc1bdee54fcb24023a08d9403f9b4bf0d450': new Uint8Array([84, 104, 101, 32, 113, 117, 105, 99, 107, 32, 98, 114, 111, 119, 110, 32, 102, 111, 120, 32, 106, 117, 109, 112, 115, 32, 111, 118, 101, 114, 32, 116, 104, 101, 32, 108, 97, 122, 121, 32, 100, 111, 103]).buffer + }; + } - context('#hex', function () { - it('should be equal', function () { - expect(sha3_512.hex('')).to.be('a69f73cca23a9ac5c8b567dc185a756e97c982164fe25859e0d1dcc1475c80a615b2123af1f5f94c11e3e9402c3ac558f500199d95b6d3e301758586281dcd26'); - }); - }); + if (typeof BUFFER === 'boolean' && BUFFER) { + testCases.sha3_512.Buffer = { + 'a69f73cca23a9ac5c8b567dc185a756e97c982164fe25859e0d1dcc1475c80a615b2123af1f5f94c11e3e9402c3ac558f500199d95b6d3e301758586281dcd26': new Buffer(0), + '01dedd5de4ef14642445ba5f5b97c15e47b9ad931326e4b0727cd94cefc44fff23f07bf543139939b49128caf436dc1bdee54fcb24023a08d9403f9b4bf0d450': new Buffer(new Uint8Array([84, 104, 101, 32, 113, 117, 105, 99, 107, 32, 98, 114, 111, 119, 110, 32, 102, 111, 120, 32, 106, 117, 109, 112, 115, 32, 111, 118, 101, 114, 32, 116, 104, 101, 32, 108, 97, 122, 121, 32, 100, 111, 103])) + }; + } - context('#update', function () { - it('should be equal', function () { - expect(sha3_512.update('').hex()).to.be('a69f73cca23a9ac5c8b567dc185a756e97c982164fe25859e0d1dcc1475c80a615b2123af1f5f94c11e3e9402c3ac558f500199d95b6d3e301758586281dcd26'); - expect(sha3_512.update('The quick brown fox ').update('jumps over the lazy dog').hex()).to.be('01dedd5de4ef14642445ba5f5b97c15e47b9ad931326e4b0727cd94cefc44fff23f07bf543139939b49128caf436dc1bdee54fcb24023a08d9403f9b4bf0d450'); - }); - }); + var errorTestCases = [null, undefined, { length: 0 }, 0, 1, false, true, NaN, Infinity, function () {}]; - context('#create', function () { - it('should be equal', function () { - var bytes = [84, 104, 101, 32, 113, 117, 105, 99, 107, 32, 98, 114, 111, 119, 110, 32, 102, 111, 120, 32, 106, 117, 109, 112, 115, 32, 111, 118, 101, 114, 32, 116, 104, 101, 32, 108, 97, 122, 121, 32, 100, 111, 103]; - var hash = sha3_512.create(); - for (var i = 0; i < bytes.length; ++i) { - hash.update([bytes[i]]); + function runTestCases(name, algorithm) { + var methods = [ + { + name: name, + call: algorithm, + }, + { + name: name + '.hex', + call: algorithm.hex + }, + { + name: name + '.array', + call: function (message) { + return algorithm.array(message).toHexString(); } - expect(hash.hex()).to.be('01dedd5de4ef14642445ba5f5b97c15e47b9ad931326e4b0727cd94cefc44fff23f07bf543139939b49128caf436dc1bdee54fcb24023a08d9403f9b4bf0d450'); - }); - }); - }); - - describe('#keccak512', function () { - context('when special length', function () { - it('should be equal', function () { - expect(keccak512('012345678901234567890123456789012345678901234567890123456789012345678901')).to.be('90b1d032c3bf06dcc78a46fe52054bab1250600224bfc6dfbfb40a7877c55e89bb982799a2edf198568a4166f6736678b45e76b12fac813cfdf0a76714e5eae8'); - expect(keccak512('01234567890123456789012345678901234567890123456789012345678901234567890')).to.be('3173e7abc754a0b2909410d78986428a9183e996864af02f421d273d9fa1b4e4a5b14e2998b20767712f53a01ff8f6ae2c3e71e51e2c0f24257b03e6da09eb77'); - }); - }); + }, + { + name: name + '.digest', + call: function (message) { + return algorithm.digest(message).toHexString(); + } + }, + { + name: name + '.arrayBuffer', + call: function (message) { + return algorithm.arrayBuffer(message).toHexString(); + } + } + ]; - context('when Array', function () { - it('should be equal', function () { - expect(keccak512([])).to.be('0eab42de4c3ceb9235fc91acffe746b29c29a8c366b7c60e4e67c466f36a4304c00fa9caf9d87976ba469bcbe06713b435f091ef2769fb160cdab33d3670680e'); - expect(keccak512([84, 104, 101, 32, 113, 117, 105, 99, 107, 32, 98, 114, 111, 119, 110, 32, 102, 111, 120, 32, 106, 117, 109, 112, 115, 32, 111, 118, 101, 114, 32, 116, 104, 101, 32, 108, 97, 122, 121, 32, 100, 111, 103])).to.be('d135bb84d0439dbac432247ee573a23ea7d3c9deb2a968eb31d47c4fb45f1ef4422d6c531b5b9bd6f449ebcc449ea94d0a8f05f62130fda612da53c79659f609'); - }); - }); + var classMethods = [ + { + name: 'create', + call: function (message) { + return algorithm.create().update(message).toString(); + } + }, + { + name: 'update', + call: function (message) { + return algorithm.update(message).toString(); + } + }, + { + name: 'hex', + call: function (message) { + return algorithm.update(message).hex(); + } + }, + { + name: 'array', + call: function (message) { + return algorithm.update(message).array().toHexString(); + } + }, + { + name: 'digest', + call: function (message) { + return algorithm.update(message).digest().toHexString(); + } + }, + { + name: 'arrayBuffer', + call: function (message) { + return algorithm.update(message).arrayBuffer().toHexString(); + } + }, + { + name: 'finalize', + call: function (message) { + var hash = algorithm.update(message); + hash.hex(); + hash.update(message); + return hash.hex(); + } + } + ]; - context('when Uint8Array', function () { - it('should be equal', function () { - expect(keccak512(new Uint8Array([]))).to.be('0eab42de4c3ceb9235fc91acffe746b29c29a8c366b7c60e4e67c466f36a4304c00fa9caf9d87976ba469bcbe06713b435f091ef2769fb160cdab33d3670680e'); - expect(keccak512(new Uint8Array([84, 104, 101, 32, 113, 117, 105, 99, 107, 32, 98, 114, 111, 119, 110, 32, 102, 111, 120, 32, 106, 117, 109, 112, 115, 32, 111, 118, 101, 114, 32, 116, 104, 101, 32, 108, 97, 122, 121, 32, 100, 111, 103]))).to.be('d135bb84d0439dbac432247ee573a23ea7d3c9deb2a968eb31d47c4fb45f1ef4422d6c531b5b9bd6f449ebcc449ea94d0a8f05f62130fda612da53c79659f609'); - }); - }); + var subTestCases = testCases[name]; - context('when ArrayBuffer', function () { - it('should be equal', function () { - expect(keccak512(new ArrayBuffer(0))).to.be('0eab42de4c3ceb9235fc91acffe746b29c29a8c366b7c60e4e67c466f36a4304c00fa9caf9d87976ba469bcbe06713b435f091ef2769fb160cdab33d3670680e'); + describe(name, function () { + methods.forEach(function (method) { + describe('#' + method.name, function () { + for (var testCaseName in subTestCases) { + (function (testCaseName) { + var testCase = subTestCases[testCaseName]; + context('when ' + testCaseName, function () { + for (var hash in testCase) { + (function (message, hash) { + it('should be equal', function () { + expect(method.call(message)).to.be(hash); + }); + })(testCase[hash], hash); + } + }); + })(testCaseName); + } + }); }); - }); - context('when output ArrayBuffer', function () { - it('should be equal', function () { - expect(keccak512.arrayBuffer('').toHexString()).to.be('0eab42de4c3ceb9235fc91acffe746b29c29a8c366b7c60e4e67c466f36a4304c00fa9caf9d87976ba469bcbe06713b435f091ef2769fb160cdab33d3670680e'); - expect(keccak512.buffer('').toHexString()).to.be('0eab42de4c3ceb9235fc91acffe746b29c29a8c366b7c60e4e67c466f36a4304c00fa9caf9d87976ba469bcbe06713b435f091ef2769fb160cdab33d3670680e'); + classMethods.forEach(function (method) { + describe('#' + method.name, function () { + for (var testCaseName in subTestCases) { + (function (testCaseName) { + var testCase = subTestCases[testCaseName]; + context('when ' + testCaseName, function () { + for (var hash in testCase) { + (function (message, hash) { + it('should be equal', function () { + expect(method.call(message)).to.be(hash); + }); + })(testCase[hash], hash); + } + }); + })(testCaseName); + } + }); }); - }); - context('when output Array', function () { - it('should be equal', function () { - expect(keccak512.array('').toHexString()).to.be('0eab42de4c3ceb9235fc91acffe746b29c29a8c366b7c60e4e67c466f36a4304c00fa9caf9d87976ba469bcbe06713b435f091ef2769fb160cdab33d3670680e'); + describe('#' + name, function () { + errorTestCases.forEach(function (testCase) { + context('when ' + testCase, function () { + it('should throw error', function () { + expect(function () { + algorithm(testCase); + }).to.throwError(/input is invalid type/); + }); + }); + }); }); }); + } - context('when incorrect input', function () { - it('should throw error', function () { - expect(function () { - keccak512(1); - }).to.throwError(); - }); - }); + runTestCases('sha3_512', sha3_512); + runTestCases('sha3_384', sha3_384); + runTestCases('sha3_256', sha3_256); + runTestCases('sha3_224', sha3_224); + runTestCases('keccak512', keccak512); + runTestCases('keccak384', keccak384); + runTestCases('keccak256', keccak256); + runTestCases('keccak224', keccak224); + describe('#keccak512', function () { context('#encodeString', function () { - context('when incorrect input', function () { - it('should throw error', function () { - expect(function () { - keccak512.create().encodeString(1); - }).to.throwError(); + errorTestCases.forEach(function (testCase) { + context('when ' + testCase, function () { + it('should throw error', function () { + expect(function () { + keccak512.create().encodeString(testCase); + }).to.throwError(/input is invalid type/); + }); }); }); - context('when ArrayBuffer', function () { - it('should throw error', function () { - expect(keccak512.create().encodeString(new ArrayBuffer(0))).to.be(2); + if (!(typeof JS_SHA3_NO_ARRAY_BUFFER === 'boolean' && JS_SHA3_NO_ARRAY_BUFFER)) { + context('when ArrayBuffer', function () { + it('should throw error', function () { + expect(keccak512.create().encodeString(new ArrayBuffer(0))).to.be(2); + }); }); - }); + context('when Uint8Array', function () { + it('should throw error', function () { + expect(keccak512.create().encodeString(new Uint8Array(0))).to.be(2); + }); + }); + } context('when UTF-8', function () { it('should throw error', function () { diff --git a/tests/worker-test.js b/tests/worker-test.js new file mode 100644 index 0000000..49d05e4 --- /dev/null +++ b/tests/worker-test.js @@ -0,0 +1,21 @@ +(function (Worker, WORKER, SOURCE) { + var cases = { + 'a69f73cca23a9ac5c8b567dc185a756e97c982164fe25859e0d1dcc1475c80a615b2123af1f5f94c11e3e9402c3ac558f500199d95b6d3e301758586281dcd26': '', + '01dedd5de4ef14642445ba5f5b97c15e47b9ad931326e4b0727cd94cefc44fff23f07bf543139939b49128caf436dc1bdee54fcb24023a08d9403f9b4bf0d450': 'The quick brown fox jumps over the lazy dog', + '18f4f4bd419603f95538837003d9d254c26c23765565162247483f65c50303597bc9ce4d289f21d1c2f1f458828e33dc442100331b35e7eb031b5d38ba6460f8': 'The quick brown fox jumps over the lazy dog.' + }; + + describe('#sha3_512', function () { + Object.keys(cases).forEach(function (hash) { + it('should be equal', function (done) { + var worker = new Worker(WORKER); + worker.onmessage = function(event) { + expect(event.data).to.be(hash); + done(); + }; + worker.postMessage(SOURCE); + worker.postMessage(cases[hash]); + }); + }); + }); +})(Worker, WORKER, SOURCE); diff --git a/tests/worker.html b/tests/worker.html new file mode 100644 index 0000000..50e39bb --- /dev/null +++ b/tests/worker.html @@ -0,0 +1,26 @@ + + + + + SHA3 + + + + + + +
+ + + + + + diff --git a/tests/worker.js b/tests/worker.js new file mode 100644 index 0000000..0756bda --- /dev/null +++ b/tests/worker.js @@ -0,0 +1,12 @@ +var imported = false; +onmessage = function(e) { + if (imported) { + postMessage(sha3_512(e.data)); + if (typeof exports !== 'undefined') { + imported = false; + } + } else { + imported = true; + importScripts(e.data); + } +}