add shake algorithm

pull/6/head
Yi-Cyuan 10 years ago
parent 61300d2d34
commit 7423f9ef37

@ -1,10 +1,10 @@
language: node_js language: node_js
node_js: node_js:
- "0.12"
- "0.11" - "0.11"
- "0.10" - "0.10"
- "0.8" - "0.8"
before_install: before_install:
- npm install mocha -g
- npm install coveralls -g - npm install coveralls -g
- npm install mocha-lcov-reporter -g - npm install mocha-lcov-reporter -g
script: npm run-script coveralls script: npm run-script coveralls

@ -1,3 +1,8 @@
# v0.4.0 / 2015-09-17
* Support to output ArrayBuffer.
* Add shake alogirthms.
# v0.3.1 / 2015-05-22 # v0.3.1 / 2015-05-22
* Fixed bugs. * Fixed bugs.

@ -2,7 +2,7 @@
[![Build Status](https://travis-ci.org/emn178/js-sha3.svg?branch=master)](https://travis-ci.org/emn178/js-sha3) [![Build Status](https://travis-ci.org/emn178/js-sha3.svg?branch=master)](https://travis-ci.org/emn178/js-sha3)
[![Coverage Status](https://coveralls.io/repos/emn178/js-sha3/badge.svg?branch=master)](https://coveralls.io/r/emn178/js-sha3?branch=master) [![Coverage Status](https://coveralls.io/repos/emn178/js-sha3/badge.svg?branch=master)](https://coveralls.io/r/emn178/js-sha3?branch=master)
[![NPM](https://nodei.co/npm/js-sha3.png?stars&downloads)](https://nodei.co/npm/js-sha3/) [![NPM](https://nodei.co/npm/js-sha3.png?stars&downloads)](https://nodei.co/npm/js-sha3/)
A simple SHA-3 / Keccak hash function for JavaScript supports UTF-8 encoding. A simple SHA-3 / Keccak / Shake hash function for JavaScript supports UTF-8 encoding.
## Notice ## Notice
Sha3 methods has been renamed to keccak since v0.2.0. It means that sha3 methods of v0.1.x are equal to keccak methods of v0.2.x and later. Sha3 methods has been renamed to keccak since v0.2.0. It means that sha3 methods of v0.1.x are equal to keccak methods of v0.2.x and later.
@ -41,6 +41,11 @@ keccak_512('Message to hash');
keccak_384('Message to hash'); keccak_384('Message to hash');
keccak_256('Message to hash'); keccak_256('Message to hash');
keccak_224('Message to hash'); keccak_224('Message to hash');
shake_128('Message to hash', 256);
shake_256('Message to hash', 512);
// Support ArrayBuffer output
var buffer = keccak_224.buffer('Message to hash');
``` ```
If you use node.js, you should require the module first: If you use node.js, you should require the module first:
```JavaScript ```JavaScript
@ -52,6 +57,8 @@ keccak_512 = require('js-sha3').keccak_512;
keccak_384 = require('js-sha3').keccak_384; keccak_384 = require('js-sha3').keccak_384;
keccak_256 = require('js-sha3').keccak_256; keccak_256 = require('js-sha3').keccak_256;
keccak_224 = require('js-sha3').keccak_224; keccak_224 = require('js-sha3').keccak_224;
shake_128 = require('js-sha3').shake_128;
shake_256 = require('js-sha3').shake_256;
``` ```
## Example ## Example
@ -128,6 +135,12 @@ keccak_224('The quick brown fox jumps over the lazy dog');
keccak_224('The quick brown fox jumps over the lazy dog.'); keccak_224('The quick brown fox jumps over the lazy dog.');
// c59d4eaeac728671c635ff645014e2afa935bebffdb5fbd207ffdeab // c59d4eaeac728671c635ff645014e2afa935bebffdb5fbd207ffdeab
shake_128('', 256);
// 7f9c2ba4e88f827d616045507605853ed73b8093f6efbc88eb1a6eacfa66ef26
shake_256('', 512);
// 46b9dd2b0ba88d13233b3feb743eeb243fcd52ea62b81b82b50c27646ed5762fd75dc4ddd8c0f200cb05019d67b592f6fc821c49479ab48640292eacb3b7c4be
``` ```
It also supports UTF-8 encoding: It also supports UTF-8 encoding:

@ -1,6 +1,6 @@
{ {
"name": "js-sha3", "name": "js-sha3",
"version": "0.3.1", "version": "0.4.0",
"main": ["src/sha3.js"], "main": ["src/sha3.js"],
"ignore": [ "ignore": [
"samples", "samples",

26
build/sha3.min.js vendored

@ -1,5 +1,5 @@
/* /*
* js-sha3 v0.3.1 * js-sha3 v0.4.0
* https://github.com/emn178/js-sha3 * https://github.com/emn178/js-sha3
* *
* Copyright 2015, emn178@gmail.com * Copyright 2015, emn178@gmail.com
@ -7,16 +7,14 @@
* Licensed under the MIT license: * Licensed under the MIT license:
* http://www.opensource.org/licenses/MIT * http://www.opensource.org/licenses/MIT
*/ */
(function(w,Ba){var E="undefined"!=typeof module;E&&(w=global,w.JS_SHA3_TEST&&(w.navigator={userAgent:"Chrome"}));var Ca=(w.JS_SHA3_TEST||!E)&&-1!=navigator.userAgent.indexOf("Chrome"),b="0123456789abcdef".split(""),H=[1,256,65536,16777216],D=[6,1536,393216,100663296],C=[0,8,16,24],ua=[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, (function(E,Da){var xa="undefined"!=typeof module;xa&&(E=global,E.JS_SHA3_TEST&&(E.navigator={userAgent:"Chrome"}));for(var g="0123456789abcdef".split(""),r=[0,8,16,24],ya=[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,128,2147483648,32778,0,2147483658,2147483648,2147516545,2147483648,32896,2147483648,2147483649,0,2147516424,2147483648],e=[],a=[],G=function(a){return h(a,224,H)},va=function(a){return h(a,256,H)},wa=function(a){return h(a,384,H)},xa=function(a){return h(a,224,D)},ya=function(a){return h(a,256,D)},za=function(a){return h(a,384,D)},Aa=function(a){return h(a,512,D)},h=function(g,h,D){var E="string"!=typeof g;E&&g.constructor==w.ArrayBuffer&&(g=new Uint8Array(g));h===Ba&&(h=512,D=H);var sa, 2147483648],m=[224,256,384,512],za=["hex","buffer","shake"],p=function(a,e,l){return function(f){return Aa(f,a,e,a,l)}},m=[{name:"keccak",padding:[1,256,65536,16777216],bits:m,createMethod:p},{name:"sha3",padding:[6,1536,393216,100663296],bits:m,createMethod:p},{name:"shake",padding:[31,7936,2031616,520093696],bits:[128,256],createMethod:function(a,e,l){return function(f,g){return Aa(f,a,e,g,l)}}}],e=[],a=[],F={},ua=0;ua<m.length;++ua)for(var va=m[ua],Ba=va.bits,p=va.createMethod,wa=0;wa<Ba.length;++wa)(function(a,
f,G=!1,B=0,ta=0,I=g.length,c,d,k,l,m,n,p,q,r,t,u,v,x,y,z,A,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,aa,ba,ca,da,ea,fa,ga,ha,ia,ja,ka,la,ma,na,oa,pa,qa,F=(1600-2*h)/32,ra=4*F;for(c=0;50>c;++c)a[c]=0;sa=0;do{e[0]=sa;for(c=1;c<F+1;++c)e[c]=0;if(E)for(c=ta;B<I&&c<ra;++B)e[c>>2]|=g[B]<<C[c++&3];else for(c=ta;B<I&&c<ra;++B)f=g.charCodeAt(B),128>f?e[c>>2]|=f<<C[c++&3]:(2048>f?e[c>>2]|=(192|f>>6)<<C[c++&3]:(55296>f||57344<=f?e[c>>2]|=(224|f>>12)<<C[c++&3]:(f=65536+((f&1023)<<10|g.charCodeAt(++B)&1023),e[c>>2]|= e){var g=p(e,a.padding,"hex");F[a.name+"_"+e]=g;for(var f=0;f<za.length;++f){var q=za[f];g[q]=p(e,a.padding,q)}})(va,Ba[wa]);var Aa=function(k,t,l,f,q){var m="string"!=typeof k;m&&k.constructor==E.ArrayBuffer&&(k=new Uint8Array(k));var p,h,F=!1,n=0;h=0;var G=k.length,b,c,d,u,v,w,x,y,z,A,B,C,D,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,aa,ba,ca,da,ea,fa,ga,ha,ia,ja,ka,la,ma,na,oa,pa,qa,ra,sa;t=(1600-2*t)/32;var ta=4*t;for(b=0;50>b;++b)a[b]=0;p=0;do{e[0]=p;for(b=1;b<t+1;++b)e[b]=0;if(m)for(b=h;n<G&&b<ta;++n)e[b>>
(240|f>>18)<<C[c++&3],e[c>>2]|=(128|f>>12&63)<<C[c++&3]),e[c>>2]|=(128|f>>6&63)<<C[c++&3]),e[c>>2]|=(128|f&63)<<C[c++&3]);ta=c-ra;B==I&&(e[c>>2]|=D[c&3],++B);sa=e[F];B>I&&c<ra&&(e[F-1]|=2147483648,G=!0);for(c=0;c<F;++c)a[c]^=e[c];for(f=0;48>f;f+=2)k=a[0]^a[10]^a[20]^a[30]^a[40],l=a[1]^a[11]^a[21]^a[31]^a[41],m=a[2]^a[12]^a[22]^a[32]^a[42],n=a[3]^a[13]^a[23]^a[33]^a[43],p=a[4]^a[14]^a[24]^a[34]^a[44],q=a[5]^a[15]^a[25]^a[35]^a[45],r=a[6]^a[16]^a[26]^a[36]^a[46],t=a[7]^a[17]^a[27]^a[37]^a[47],u=a[8]^ 2]|=k[n]<<r[b++&3];else for(b=h;n<G&&b<ta;++n)h=k.charCodeAt(n),128>h?e[b>>2]|=h<<r[b++&3]:(2048>h?e[b>>2]|=(192|h>>6)<<r[b++&3]:(55296>h||57344<=h?e[b>>2]|=(224|h>>12)<<r[b++&3]:(h=65536+((h&1023)<<10|k.charCodeAt(++n)&1023),e[b>>2]|=(240|h>>18)<<r[b++&3],e[b>>2]|=(128|h>>12&63)<<r[b++&3]),e[b>>2]|=(128|h>>6&63)<<r[b++&3]),e[b>>2]|=(128|h&63)<<r[b++&3]);h=b-ta;n==G&&(e[b>>2]|=l[b&3],++n);p=e[t];n>G&&b<ta&&(e[t-1]|=2147483648,F=!0);for(b=0;b<t;++b)a[b]^=e[b];for(b=0;48>b;b+=2)u=a[0]^a[10]^a[20]^a[30]^
a[18]^a[28]^a[38]^a[48],v=a[9]^a[19]^a[29]^a[39]^a[49],d=u^(m<<1|n>>>31),c=v^(n<<1|m>>>31),a[0]^=d,a[1]^=c,a[10]^=d,a[11]^=c,a[20]^=d,a[21]^=c,a[30]^=d,a[31]^=c,a[40]^=d,a[41]^=c,d=k^(p<<1|q>>>31),c=l^(q<<1|p>>>31),a[2]^=d,a[3]^=c,a[12]^=d,a[13]^=c,a[22]^=d,a[23]^=c,a[32]^=d,a[33]^=c,a[42]^=d,a[43]^=c,d=m^(r<<1|t>>>31),c=n^(t<<1|r>>>31),a[4]^=d,a[5]^=c,a[14]^=d,a[15]^=c,a[24]^=d,a[25]^=c,a[34]^=d,a[35]^=c,a[44]^=d,a[45]^=c,d=p^(u<<1|v>>>31),c=q^(v<<1|u>>>31),a[6]^=d,a[7]^=c,a[16]^=d,a[17]^=c,a[26]^= a[40],v=a[1]^a[11]^a[21]^a[31]^a[41],w=a[2]^a[12]^a[22]^a[32]^a[42],x=a[3]^a[13]^a[23]^a[33]^a[43],y=a[4]^a[14]^a[24]^a[34]^a[44],z=a[5]^a[15]^a[25]^a[35]^a[45],A=a[6]^a[16]^a[26]^a[36]^a[46],B=a[7]^a[17]^a[27]^a[37]^a[47],C=a[8]^a[18]^a[28]^a[38]^a[48],D=a[9]^a[19]^a[29]^a[39]^a[49],c=C^(w<<1|x>>>31),d=D^(x<<1|w>>>31),a[0]^=c,a[1]^=d,a[10]^=c,a[11]^=d,a[20]^=c,a[21]^=d,a[30]^=c,a[31]^=d,a[40]^=c,a[41]^=d,c=u^(y<<1|z>>>31),d=v^(z<<1|y>>>31),a[2]^=c,a[3]^=d,a[12]^=c,a[13]^=d,a[22]^=c,a[23]^=d,a[32]^=
d,a[27]^=c,a[36]^=d,a[37]^=c,a[46]^=d,a[47]^=c,d=r^(k<<1|l>>>31),c=t^(l<<1|k>>>31),a[8]^=d,a[9]^=c,a[18]^=d,a[19]^=c,a[28]^=d,a[29]^=c,a[38]^=d,a[39]^=c,a[48]^=d,a[49]^=c,d=a[0],c=a[1],Z=a[11]<<4|a[10]>>>28,aa=a[10]<<4|a[11]>>>28,z=a[20]<<3|a[21]>>>29,A=a[21]<<3|a[20]>>>29,na=a[31]<<9|a[30]>>>23,oa=a[30]<<9|a[31]>>>23,V=a[40]<<18|a[41]>>>14,W=a[41]<<18|a[40]>>>14,N=a[2]<<1|a[3]>>>31,O=a[3]<<1|a[2]>>>31,k=a[13]<<12|a[12]>>>20,l=a[12]<<12|a[13]>>>20,ba=a[22]<<10|a[23]>>>22,ca=a[23]<<10|a[22]>>>22,J= c,a[33]^=d,a[42]^=c,a[43]^=d,c=w^(A<<1|B>>>31),d=x^(B<<1|A>>>31),a[4]^=c,a[5]^=d,a[14]^=c,a[15]^=d,a[24]^=c,a[25]^=d,a[34]^=c,a[35]^=d,a[44]^=c,a[45]^=d,c=y^(C<<1|D>>>31),d=z^(D<<1|C>>>31),a[6]^=c,a[7]^=d,a[16]^=c,a[17]^=d,a[26]^=c,a[27]^=d,a[36]^=c,a[37]^=d,a[46]^=c,a[47]^=d,c=A^(u<<1|v>>>31),d=B^(v<<1|u>>>31),a[8]^=c,a[9]^=d,a[18]^=c,a[19]^=d,a[28]^=c,a[29]^=d,a[38]^=c,a[39]^=d,a[48]^=c,a[49]^=d,c=a[0],d=a[1],ba=a[11]<<4|a[10]>>>28,ca=a[10]<<4|a[11]>>>28,J=a[20]<<3|a[21]>>>29,K=a[21]<<3|a[20]>>>
a[33]<<13|a[32]>>>19,K=a[32]<<13|a[33]>>>19,pa=a[42]<<2|a[43]>>>30,qa=a[43]<<2|a[42]>>>30,ha=a[5]<<30|a[4]>>>2,ia=a[4]<<30|a[5]>>>2,P=a[14]<<6|a[15]>>>26,Q=a[15]<<6|a[14]>>>26,m=a[25]<<11|a[24]>>>21,n=a[24]<<11|a[25]>>>21,da=a[34]<<15|a[35]>>>17,ea=a[35]<<15|a[34]>>>17,L=a[45]<<29|a[44]>>>3,M=a[44]<<29|a[45]>>>3,u=a[6]<<28|a[7]>>>4,v=a[7]<<28|a[6]>>>4,ja=a[17]<<23|a[16]>>>9,ka=a[16]<<23|a[17]>>>9,R=a[26]<<25|a[27]>>>7,S=a[27]<<25|a[26]>>>7,p=a[36]<<21|a[37]>>>11,q=a[37]<<21|a[36]>>>11,fa=a[47]<<24| 29,pa=a[31]<<9|a[30]>>>23,qa=a[30]<<9|a[31]>>>23,X=a[40]<<18|a[41]>>>14,Y=a[41]<<18|a[40]>>>14,P=a[2]<<1|a[3]>>>31,Q=a[3]<<1|a[2]>>>31,u=a[13]<<12|a[12]>>>20,v=a[12]<<12|a[13]>>>20,da=a[22]<<10|a[23]>>>22,ea=a[23]<<10|a[22]>>>22,L=a[33]<<13|a[32]>>>19,M=a[32]<<13|a[33]>>>19,ra=a[42]<<2|a[43]>>>30,sa=a[43]<<2|a[42]>>>30,ja=a[5]<<30|a[4]>>>2,ka=a[4]<<30|a[5]>>>2,R=a[14]<<6|a[15]>>>26,S=a[15]<<6|a[14]>>>26,w=a[25]<<11|a[24]>>>21,x=a[24]<<11|a[25]>>>21,fa=a[34]<<15|a[35]>>>17,ga=a[35]<<15|a[34]>>>17,
a[46]>>>8,ga=a[46]<<24|a[47]>>>8,X=a[8]<<27|a[9]>>>5,Y=a[9]<<27|a[8]>>>5,x=a[18]<<20|a[19]>>>12,y=a[19]<<20|a[18]>>>12,la=a[29]<<7|a[28]>>>25,ma=a[28]<<7|a[29]>>>25,T=a[38]<<8|a[39]>>>24,U=a[39]<<8|a[38]>>>24,r=a[48]<<14|a[49]>>>18,t=a[49]<<14|a[48]>>>18,a[0]=d^~k&m,a[1]=c^~l&n,a[10]=u^~x&z,a[11]=v^~y&A,a[20]=N^~P&R,a[21]=O^~Q&S,a[30]=X^~Z&ba,a[31]=Y^~aa&ca,a[40]=ha^~ja&la,a[41]=ia^~ka&ma,a[2]=k^~m&p,a[3]=l^~n&q,a[12]=x^~z&J,a[13]=y^~A&K,a[22]=P^~R&T,a[23]=Q^~S&U,a[32]=Z^~ba&da,a[33]=aa^~ca&ea,a[42]= N=a[45]<<29|a[44]>>>3,O=a[44]<<29|a[45]>>>3,C=a[6]<<28|a[7]>>>4,D=a[7]<<28|a[6]>>>4,la=a[17]<<23|a[16]>>>9,ma=a[16]<<23|a[17]>>>9,T=a[26]<<25|a[27]>>>7,U=a[27]<<25|a[26]>>>7,y=a[36]<<21|a[37]>>>11,z=a[37]<<21|a[36]>>>11,ha=a[47]<<24|a[46]>>>8,ia=a[46]<<24|a[47]>>>8,Z=a[8]<<27|a[9]>>>5,aa=a[9]<<27|a[8]>>>5,H=a[18]<<20|a[19]>>>12,I=a[19]<<20|a[18]>>>12,na=a[29]<<7|a[28]>>>25,oa=a[28]<<7|a[29]>>>25,V=a[38]<<8|a[39]>>>24,W=a[39]<<8|a[38]>>>24,A=a[48]<<14|a[49]>>>18,B=a[49]<<14|a[48]>>>18,a[0]=c^~u&w,
ja^~la&na,a[43]=ka^~ma&oa,a[4]=m^~p&r,a[5]=n^~q&t,a[14]=z^~J&L,a[15]=A^~K&M,a[24]=R^~T&V,a[25]=S^~U&W,a[34]=ba^~da&fa,a[35]=ca^~ea&ga,a[44]=la^~na&pa,a[45]=ma^~oa&qa,a[6]=p^~r&d,a[7]=q^~t&c,a[16]=J^~L&u,a[17]=K^~M&v,a[26]=T^~V&N,a[27]=U^~W&O,a[36]=da^~fa&X,a[37]=ea^~ga&Y,a[46]=na^~pa&ha,a[47]=oa^~qa&ia,a[8]=r^~d&k,a[9]=t^~c&l,a[18]=L^~u&x,a[19]=M^~v&y,a[28]=V^~N&P,a[29]=W^~O&Q,a[38]=fa^~X&Z,a[39]=ga^~Y&aa,a[48]=pa^~ha&ja,a[49]=qa^~ia&ka,a[0]^=ua[f],a[1]^=ua[f+1]}while(!G);g="";if(Ca)d=a[0],c=a[1], a[1]=d^~v&x,a[10]=C^~H&J,a[11]=D^~I&K,a[20]=P^~R&T,a[21]=Q^~S&U,a[30]=Z^~ba&da,a[31]=aa^~ca&ea,a[40]=ja^~la&na,a[41]=ka^~ma&oa,a[2]=u^~w&y,a[3]=v^~x&z,a[12]=H^~J&L,a[13]=I^~K&M,a[22]=R^~T&V,a[23]=S^~U&W,a[32]=ba^~da&fa,a[33]=ca^~ea&ga,a[42]=la^~na&pa,a[43]=ma^~oa&qa,a[4]=w^~y&A,a[5]=x^~z&B,a[14]=J^~L&N,a[15]=K^~M&O,a[24]=T^~V&X,a[25]=U^~W&Y,a[34]=da^~fa&ha,a[35]=ea^~ga&ia,a[44]=na^~pa&ra,a[45]=oa^~qa&sa,a[6]=y^~A&c,a[7]=z^~B&d,a[16]=L^~N&C,a[17]=M^~O&D,a[26]=V^~X&P,a[27]=W^~Y&Q,a[36]=fa^~ha&Z,a[37]=
k=a[2],l=a[3],m=a[4],n=a[5],p=a[6],q=a[7],r=a[8],t=a[9],u=a[10],v=a[11],x=a[12],y=a[13],z=a[14],A=a[15],g+=b[d>>4&15]+b[d&15]+b[d>>12&15]+b[d>>8&15]+b[d>>20&15]+b[d>>16&15]+b[d>>28&15]+b[d>>24&15]+b[c>>4&15]+b[c&15]+b[c>>12&15]+b[c>>8&15]+b[c>>20&15]+b[c>>16&15]+b[c>>28&15]+b[c>>24&15]+b[k>>4&15]+b[k&15]+b[k>>12&15]+b[k>>8&15]+b[k>>20&15]+b[k>>16&15]+b[k>>28&15]+b[k>>24&15]+b[l>>4&15]+b[l&15]+b[l>>12&15]+b[l>>8&15]+b[l>>20&15]+b[l>>16&15]+b[l>>28&15]+b[l>>24&15]+b[m>>4&15]+b[m&15]+b[m>>12&15]+b[m>> ga^~ia&aa,a[46]=pa^~ra&ja,a[47]=qa^~sa&ka,a[8]=A^~c&u,a[9]=B^~d&v,a[18]=N^~C&H,a[19]=O^~D&I,a[28]=X^~P&R,a[29]=Y^~Q&S,a[38]=ha^~Z&ba,a[39]=ia^~aa&ca,a[48]=ra^~ja&la,a[49]=sa^~ka&ma,a[0]^=ya[b],a[1]^=ya[b+1]}while(!F);k=parseInt(f/32);l=parseInt(f%32/8);if("buffer"==q){f/=8;q=l?new ArrayBuffer(4*(k+1)):new ArrayBuffer(f);m=new Uint32Array(q);for(b=0;b<k;++b)m[b]=a[b];l&&(m[b]=a[b],q=q.slice(0,f));return q}f="";for(b=0;b<k;++b)c=a[b],f+=g[c>>4&15]+g[c&15]+g[c>>12&15]+g[c>>8&15]+g[c>>20&15]+g[c>>16&
8&15]+b[m>>20&15]+b[m>>16&15]+b[m>>28&15]+b[m>>24&15]+b[n>>4&15]+b[n&15]+b[n>>12&15]+b[n>>8&15]+b[n>>20&15]+b[n>>16&15]+b[n>>28&15]+b[n>>24&15]+b[p>>4&15]+b[p&15]+b[p>>12&15]+b[p>>8&15]+b[p>>20&15]+b[p>>16&15]+b[p>>28&15]+b[p>>24&15],256<=h&&(g+=b[q>>4&15]+b[q&15]+b[q>>12&15]+b[q>>8&15]+b[q>>20&15]+b[q>>16&15]+b[q>>28&15]+b[q>>24&15]),384<=h&&(g+=b[r>>4&15]+b[r&15]+b[r>>12&15]+b[r>>8&15]+b[r>>20&15]+b[r>>16&15]+b[r>>28&15]+b[r>>24&15]+b[t>>4&15]+b[t&15]+b[t>>12&15]+b[t>>8&15]+b[t>>20&15]+b[t>>16& 15]+g[c>>28&15]+g[c>>24&15];l&&(c=a[b],0<l&&(f+=g[c>>4&15]+g[c&15]),1<l&&(f+=g[c>>12&15]+g[c>>8&15]),2<l&&(f+=g[c>>20&15]+g[c>>16&15]));return f};if(!E.JS_SHA3_TEST&&xa)module.exports=F;else if(E)for(var Ca in F)E[Ca]=F[Ca]})(this);
15]+b[t>>28&15]+b[t>>24&15]+b[u>>4&15]+b[u&15]+b[u>>12&15]+b[u>>8&15]+b[u>>20&15]+b[u>>16&15]+b[u>>28&15]+b[u>>24&15]+b[v>>4&15]+b[v&15]+b[v>>12&15]+b[v>>8&15]+b[v>>20&15]+b[v>>16&15]+b[v>>28&15]+b[v>>24&15]),512==h&&(g+=b[x>>4&15]+b[x&15]+b[x>>12&15]+b[x>>8&15]+b[x>>20&15]+b[x>>16&15]+b[x>>28&15]+b[x>>24&15]+b[y>>4&15]+b[y&15]+b[y>>12&15]+b[y>>8&15]+b[y>>20&15]+b[y>>16&15]+b[y>>28&15]+b[y>>24&15]+b[z>>4&15]+b[z&15]+b[z>>12&15]+b[z>>8&15]+b[z>>20&15]+b[z>>16&15]+b[z>>28&15]+b[z>>24&15]+b[A>>4&15]+
b[A&15]+b[A>>12&15]+b[A>>8&15]+b[A>>20&15]+b[A>>16&15]+b[A>>28&15]+b[A>>24&15]);else for(c=0,f=h/32;c<f;++c)d=a[c],g+=b[d>>4&15]+b[d&15]+b[d>>12&15]+b[d>>8&15]+b[d>>20&15]+b[d>>16&15]+b[d>>28&15]+b[d>>24&15];return g};!w.JS_SHA3_TEST&&E?module.exports={sha3_512:Aa,sha3_384:za,sha3_256:ya,sha3_224:xa,keccak_512:h,keccak_384:wa,keccak_256:va,keccak_224:G}:w&&(w.sha3_512=Aa,w.sha3_384=za,w.sha3_256=ya,w.sha3_224=xa,w.keccak_512=h,w.keccak_384=wa,w.keccak_256=va,w.keccak_224=G)})(this);

@ -1,11 +1,12 @@
{ {
"name": "js-sha3", "name": "js-sha3",
"version": "0.3.1", "version": "0.4.0",
"description": "A simple SHA-3 / Keccak hash function for JavaScript supports UTF-8 encoding.", "description": "A simple SHA-3 / Keccak / Shake hash function for JavaScript supports UTF-8 encoding.",
"main": "src/sha3.js", "main": "src/sha3.js",
"devDependencies": { "devDependencies": {
"expect.js": "~0.3.1", "expect.js": "~0.3.1",
"jscoverage": "~0.5.9" "jscoverage": "~0.5.9",
"mocha": "~2.3.2"
}, },
"scripts": { "scripts": {
"test": "mocha tests/node-test.js -r jscoverage", "test": "mocha tests/node-test.js -r jscoverage",

@ -17,8 +17,8 @@
root.navigator = { userAgent: 'Chrome'}; root.navigator = { userAgent: 'Chrome'};
} }
} }
var CHROME = (root.JS_SHA3_TEST || !NODE_JS) && navigator.userAgent.indexOf('Chrome') != -1;
var HEX_CHARS = '0123456789abcdef'.split(''); var HEX_CHARS = '0123456789abcdef'.split('');
var SHAKE_PADDING = [31, 7936, 2031616, 520093696];
var KECCAK_PADDING = [1, 256, 65536, 16777216]; var KECCAK_PADDING = [1, 256, 65536, 16777216];
var PADDING = [6, 1536, 393216, 100663296]; var PADDING = [6, 1536, 393216, 100663296];
var SHIFT = [0, 8, 16, 24]; var SHIFT = [0, 8, 16, 24];
@ -28,23 +28,34 @@
2147483648, 32770, 2147483648, 128, 2147483648, 32778, 0, 2147483658, 2147483648, 2147483648, 32770, 2147483648, 128, 2147483648, 32778, 0, 2147483658, 2147483648,
2147516545, 2147483648, 32896, 2147483648, 2147483649, 0, 2147516424, 2147483648]; 2147516545, 2147483648, 32896, 2147483648, 2147483649, 0, 2147516424, 2147483648];
var BITS = [224, 256, 384, 512]; var BITS = [224, 256, 384, 512];
var ALGORITHMS = [ var SHAKE_BITS = [128, 256];
{name: 'keccak', padding: KECCAK_PADDING}, var OUTPUT_TYPES = ['hex', 'buffer', 'shake'];
{name: 'sha3', padding: PADDING}
];
var OUTPUT_TYPES = ['hex', 'buffer'];
var blocks = [], s = [], methods = {};
var createMethod = function(bits, padding, outputType) { var createMethod = function(bits, padding, outputType) {
return function(message) { return function(message) {
return keccak(message, bits, padding, outputType); return keccak(message, bits, padding, bits, outputType);
}
};
var createShakeMethod = function(bits, padding, outputType) {
return function(message, outputBits) {
return keccak(message, bits, padding, outputBits, outputType);
} }
}; };
for(var i = 0;i < ALGORITHMS.length;++i) { var algorithms = [
var algorithm = ALGORITHMS[i]; {name: 'keccak', padding: KECCAK_PADDING, bits: BITS, createMethod: createMethod},
for(var j = 0;j < BITS.length;++j) { {name: 'sha3', padding: PADDING, bits: BITS, createMethod: createMethod},
{name: 'shake', padding: SHAKE_PADDING, bits: SHAKE_BITS, createMethod: createShakeMethod}
];
var blocks = [], s = [], methods = {};
for(var i = 0;i < algorithms.length;++i) {
var algorithm = algorithms[i];
var bits = algorithm.bits;
var createMethod = algorithm.createMethod;
for(var j = 0;j < bits.length;++j) {
(function(algorithm, bits) { (function(algorithm, bits) {
var method = createMethod(bits, algorithm.padding, 'hex'); var method = createMethod(bits, algorithm.padding, 'hex');
methods[algorithm.name +'_' + bits] = method; methods[algorithm.name +'_' + bits] = method;
@ -52,11 +63,11 @@
var type = OUTPUT_TYPES[k]; var type = OUTPUT_TYPES[k];
method[type] = createMethod(bits, algorithm.padding, type); method[type] = createMethod(bits, algorithm.padding, type);
} }
})(algorithm, BITS[j]); })(algorithm, bits[j]);
} }
} }
var keccak = function(message, bits, padding, outputType) { var keccak = function(message, bits, padding, outputBits, outputType) {
var notString = typeof(message) != 'string'; var notString = typeof(message) != 'string';
if(notString && message.constructor == root.ArrayBuffer) { if(notString && message.constructor == root.ArrayBuffer) {
message = new Uint8Array(message); message = new Uint8Array(message);
@ -300,111 +311,44 @@
} }
} while(!end); } while(!end);
var outputBlocks = parseInt(outputBits / 32);
var extraBytes = parseInt((outputBits % 32) / 8);
if(outputType == 'buffer') { if(outputType == 'buffer') {
var length = bits / 32; var bytes = outputBits / 8;
var buffer = new ArrayBuffer(bits / 8); var buffer;
if(extraBytes) {
buffer = new ArrayBuffer((outputBlocks + 1) * 4);
} else {
buffer = new ArrayBuffer(bytes);
}
var array = new Uint32Array(buffer); var array = new Uint32Array(buffer);
for(var i = 0;i < length;++i) { for(i = 0;i < outputBlocks;++i) {
array[i] = s[i]; array[i] = s[i];
} }
if(extraBytes) {
array[i] = s[i];
buffer = buffer.slice(0, bytes);
}
return buffer; return buffer;
} else { } else {
var hex = ''; var hex = '';
if(CHROME) { for(i = 0;i < outputBlocks;++i) {
b0 = s[0]; h = s[i];
b1 = s[1]; hex += HEX_CHARS[(h >> 4) & 0x0F] + HEX_CHARS[h & 0x0F] +
b2 = s[2]; HEX_CHARS[(h >> 12) & 0x0F] + HEX_CHARS[(h >> 8) & 0x0F] +
b3 = s[3]; HEX_CHARS[(h >> 20) & 0x0F] + HEX_CHARS[(h >> 16) & 0x0F] +
b4 = s[4]; HEX_CHARS[(h >> 28) & 0x0F] + HEX_CHARS[(h >> 24) & 0x0F];
b5 = s[5]; }
b6 = s[6]; if(extraBytes) {
b7 = s[7]; h = s[i];
b8 = s[8]; if(extraBytes > 0) {
b9 = s[9]; hex += HEX_CHARS[(h >> 4) & 0x0F] + HEX_CHARS[h & 0x0F];
b10 = s[10];
b11 = s[11];
b12 = s[12];
b13 = s[13];
b14 = s[14];
b15 = s[15];
hex += HEX_CHARS[(b0 >> 4) & 0x0F] + HEX_CHARS[b0 & 0x0F] +
HEX_CHARS[(b0 >> 12) & 0x0F] + HEX_CHARS[(b0 >> 8) & 0x0F] +
HEX_CHARS[(b0 >> 20) & 0x0F] + HEX_CHARS[(b0 >> 16) & 0x0F] +
HEX_CHARS[(b0 >> 28) & 0x0F] + HEX_CHARS[(b0 >> 24) & 0x0F] +
HEX_CHARS[(b1 >> 4) & 0x0F] + HEX_CHARS[b1 & 0x0F] +
HEX_CHARS[(b1 >> 12) & 0x0F] + HEX_CHARS[(b1 >> 8) & 0x0F] +
HEX_CHARS[(b1 >> 20) & 0x0F] + HEX_CHARS[(b1 >> 16) & 0x0F] +
HEX_CHARS[(b1 >> 28) & 0x0F] + HEX_CHARS[(b1 >> 24) & 0x0F] +
HEX_CHARS[(b2 >> 4) & 0x0F] + HEX_CHARS[b2 & 0x0F] +
HEX_CHARS[(b2 >> 12) & 0x0F] + HEX_CHARS[(b2 >> 8) & 0x0F] +
HEX_CHARS[(b2 >> 20) & 0x0F] + HEX_CHARS[(b2 >> 16) & 0x0F] +
HEX_CHARS[(b2 >> 28) & 0x0F] + HEX_CHARS[(b2 >> 24) & 0x0F] +
HEX_CHARS[(b3 >> 4) & 0x0F] + HEX_CHARS[b3 & 0x0F] +
HEX_CHARS[(b3 >> 12) & 0x0F] + HEX_CHARS[(b3 >> 8) & 0x0F] +
HEX_CHARS[(b3 >> 20) & 0x0F] + HEX_CHARS[(b3 >> 16) & 0x0F] +
HEX_CHARS[(b3 >> 28) & 0x0F] + HEX_CHARS[(b3 >> 24) & 0x0F] +
HEX_CHARS[(b4 >> 4) & 0x0F] + HEX_CHARS[b4 & 0x0F] +
HEX_CHARS[(b4 >> 12) & 0x0F] + HEX_CHARS[(b4 >> 8) & 0x0F] +
HEX_CHARS[(b4 >> 20) & 0x0F] + HEX_CHARS[(b4 >> 16) & 0x0F] +
HEX_CHARS[(b4 >> 28) & 0x0F] + HEX_CHARS[(b4 >> 24) & 0x0F] +
HEX_CHARS[(b5 >> 4) & 0x0F] + HEX_CHARS[b5 & 0x0F] +
HEX_CHARS[(b5 >> 12) & 0x0F] + HEX_CHARS[(b5 >> 8) & 0x0F] +
HEX_CHARS[(b5 >> 20) & 0x0F] + HEX_CHARS[(b5 >> 16) & 0x0F] +
HEX_CHARS[(b5 >> 28) & 0x0F] + HEX_CHARS[(b5 >> 24) & 0x0F] +
HEX_CHARS[(b6 >> 4) & 0x0F] + HEX_CHARS[b6 & 0x0F] +
HEX_CHARS[(b6 >> 12) & 0x0F] + HEX_CHARS[(b6 >> 8) & 0x0F] +
HEX_CHARS[(b6 >> 20) & 0x0F] + HEX_CHARS[(b6 >> 16) & 0x0F] +
HEX_CHARS[(b6 >> 28) & 0x0F] + HEX_CHARS[(b6 >> 24) & 0x0F];
if(bits >= 256) {
hex += HEX_CHARS[(b7 >> 4) & 0x0F] + HEX_CHARS[b7 & 0x0F] +
HEX_CHARS[(b7 >> 12) & 0x0F] + HEX_CHARS[(b7 >> 8) & 0x0F] +
HEX_CHARS[(b7 >> 20) & 0x0F] + HEX_CHARS[(b7 >> 16) & 0x0F] +
HEX_CHARS[(b7 >> 28) & 0x0F] + HEX_CHARS[(b7 >> 24) & 0x0F];
}
if(bits >= 384) {
hex += HEX_CHARS[(b8 >> 4) & 0x0F] + HEX_CHARS[b8 & 0x0F] +
HEX_CHARS[(b8 >> 12) & 0x0F] + HEX_CHARS[(b8 >> 8) & 0x0F] +
HEX_CHARS[(b8 >> 20) & 0x0F] + HEX_CHARS[(b8 >> 16) & 0x0F] +
HEX_CHARS[(b8 >> 28) & 0x0F] + HEX_CHARS[(b8 >> 24) & 0x0F] +
HEX_CHARS[(b9 >> 4) & 0x0F] + HEX_CHARS[b9 & 0x0F] +
HEX_CHARS[(b9 >> 12) & 0x0F] + HEX_CHARS[(b9 >> 8) & 0x0F] +
HEX_CHARS[(b9 >> 20) & 0x0F] + HEX_CHARS[(b9 >> 16) & 0x0F] +
HEX_CHARS[(b9 >> 28) & 0x0F] + HEX_CHARS[(b9 >> 24) & 0x0F] +
HEX_CHARS[(b10 >> 4) & 0x0F] + HEX_CHARS[b10 & 0x0F] +
HEX_CHARS[(b10 >> 12) & 0x0F] + HEX_CHARS[(b10 >> 8) & 0x0F] +
HEX_CHARS[(b10 >> 20) & 0x0F] + HEX_CHARS[(b10 >> 16) & 0x0F] +
HEX_CHARS[(b10 >> 28) & 0x0F] + HEX_CHARS[(b10 >> 24) & 0x0F] +
HEX_CHARS[(b11 >> 4) & 0x0F] + HEX_CHARS[b11 & 0x0F] +
HEX_CHARS[(b11 >> 12) & 0x0F] + HEX_CHARS[(b11 >> 8) & 0x0F] +
HEX_CHARS[(b11 >> 20) & 0x0F] + HEX_CHARS[(b11 >> 16) & 0x0F] +
HEX_CHARS[(b11 >> 28) & 0x0F] + HEX_CHARS[(b11 >> 24) & 0x0F];
} }
if(bits == 512) { if(extraBytes > 1) {
hex += HEX_CHARS[(b12 >> 4) & 0x0F] + HEX_CHARS[b12 & 0x0F] + hex += HEX_CHARS[(h >> 12) & 0x0F] + HEX_CHARS[(h >> 8) & 0x0F];
HEX_CHARS[(b12 >> 12) & 0x0F] + HEX_CHARS[(b12 >> 8) & 0x0F] +
HEX_CHARS[(b12 >> 20) & 0x0F] + HEX_CHARS[(b12 >> 16) & 0x0F] +
HEX_CHARS[(b12 >> 28) & 0x0F] + HEX_CHARS[(b12 >> 24) & 0x0F] +
HEX_CHARS[(b13 >> 4) & 0x0F] + HEX_CHARS[b13 & 0x0F] +
HEX_CHARS[(b13 >> 12) & 0x0F] + HEX_CHARS[(b13 >> 8) & 0x0F] +
HEX_CHARS[(b13 >> 20) & 0x0F] + HEX_CHARS[(b13 >> 16) & 0x0F] +
HEX_CHARS[(b13 >> 28) & 0x0F] + HEX_CHARS[(b13 >> 24) & 0x0F] +
HEX_CHARS[(b14 >> 4) & 0x0F] + HEX_CHARS[b14 & 0x0F] +
HEX_CHARS[(b14 >> 12) & 0x0F] + HEX_CHARS[(b14 >> 8) & 0x0F] +
HEX_CHARS[(b14 >> 20) & 0x0F] + HEX_CHARS[(b14 >> 16) & 0x0F] +
HEX_CHARS[(b14 >> 28) & 0x0F] + HEX_CHARS[(b14 >> 24) & 0x0F] +
HEX_CHARS[(b15 >> 4) & 0x0F] + HEX_CHARS[b15 & 0x0F] +
HEX_CHARS[(b15 >> 12) & 0x0F] + HEX_CHARS[(b15 >> 8) & 0x0F] +
HEX_CHARS[(b15 >> 20) & 0x0F] + HEX_CHARS[(b15 >> 16) & 0x0F] +
HEX_CHARS[(b15 >> 28) & 0x0F] + HEX_CHARS[(b15 >> 24) & 0x0F];
} }
} else { if(extraBytes > 2) {
for(i = 0, n = bits / 32;i < n;++i) { hex += HEX_CHARS[(h >> 20) & 0x0F] + HEX_CHARS[(h >> 16) & 0x0F];
h = s[i];
hex += HEX_CHARS[(h >> 4) & 0x0F] + HEX_CHARS[h & 0x0F] +
HEX_CHARS[(h >> 12) & 0x0F] + HEX_CHARS[(h >> 8) & 0x0F] +
HEX_CHARS[(h >> 20) & 0x0F] + HEX_CHARS[(h >> 16) & 0x0F] +
HEX_CHARS[(h >> 28) & 0x0F] + HEX_CHARS[(h >> 24) & 0x0F];
} }
} }
return hex; return hex;

@ -15,6 +15,7 @@
</script> </script>
<script src="test.js"></script> <script src="test.js"></script>
<script src="test-keccak.js"></script> <script src="test-keccak.js"></script>
<script src="test-shake.js"></script>
<script> <script>
mocha.checkLeaks(); mocha.checkLeaks();
mocha.run(); mocha.run();

@ -7,12 +7,15 @@ sha3_512 = require('../src/sha3.js').sha3_512;
sha3_384 = require('../src/sha3.js').sha3_384; sha3_384 = require('../src/sha3.js').sha3_384;
sha3_256 = require('../src/sha3.js').sha3_256; sha3_256 = require('../src/sha3.js').sha3_256;
sha3_224 = require('../src/sha3.js').sha3_224; sha3_224 = require('../src/sha3.js').sha3_224;
shake_128 = require('../src/sha3.js').shake_128;
shake_256 = require('../src/sha3.js').shake_256;
require('./test-keccak.js'); require('./test-keccak.js');
require('./test.js'); require('./test.js');
delete require.cache[require.resolve('../src/sha3.js')] delete require.cache[require.resolve('../src/sha3.js')]
delete require.cache[require.resolve('./test.js')] delete require.cache[require.resolve('./test.js')]
delete require.cache[require.resolve('./test-keccak.js')] delete require.cache[require.resolve('./test-keccak.js')]
delete require.cache[require.resolve('./test-shake.js')]
sha3_512 = null; sha3_512 = null;
sha3_384 = null; sha3_384 = null;
sha3_256 = null; sha3_256 = null;
@ -21,8 +24,11 @@ keccak_512 = null;
keccak_384 = null; keccak_384 = null;
keccak_256 = null; keccak_256 = null;
keccak_224 = null; keccak_224 = null;
shake_128 = null;
shake_256 = null;
JS_SHA3_TEST = true; JS_SHA3_TEST = true;
require('../src/sha3.js'); require('../src/sha3.js');
require('./test-keccak.js'); require('./test-keccak.js');
require('./test-shake.js');
require('./test.js'); require('./test.js');

@ -0,0 +1,47 @@
(function(shake_256, shake_128) {
describe('shake_128', function() {
context('with 256 output', function() {
it('should be equal', function() {
expect(shake_128('', 256)).to.be('7f9c2ba4e88f827d616045507605853ed73b8093f6efbc88eb1a6eacfa66ef26');
expect(shake_128('The quick brown fox jumps over the lazy dog', 256)).to.be('f4202e3c5852f9182a0430fd8144f0a74b95e7417ecae17db0f8cfeed0e3e66e');
expect(shake_128('The quick brown fox jumps over the lazy dof', 256)).to.be('853f4538be0db9621a6cea659a06c1107b1f83f02b13d18297bd39d7411cf10c');
});
});
context('with 8 output', function() {
it('should be equal', function() {
expect(shake_128('', 8)).to.be('7f');
expect(shake_128('The quick brown fox jumps over the lazy dog', 8)).to.be('f4');
expect(shake_128('The quick brown fox jumps over the lazy dof', 8)).to.be('85');
});
});
context('with more output', function() {
it('should be equal', function() {
expect(shake_128('', 16)).to.be('7f9c');
expect(shake_128('', 24)).to.be('7f9c2b');
});
});
context('with 8 output ArrayBuffer', function() {
it('should be equal', function() {
expect(shake_128.buffer('', 8).toHexString()).to.be('7f');
expect(shake_128.buffer('The quick brown fox jumps over the lazy dog', 8).toHexString()).to.be('f4');
expect(shake_128.buffer('The quick brown fox jumps over the lazy dof', 8).toHexString()).to.be('85');
});
});
});
describe('shake_256', function() {
context('with 512 output', function() {
it('should be equal', function() {
expect(shake_256('', 512)).to.be('46b9dd2b0ba88d13233b3feb743eeb243fcd52ea62b81b82b50c27646ed5762fd75dc4ddd8c0f200cb05019d67b592f6fc821c49479ab48640292eacb3b7c4be');
});
});
context('with 8 output', function() {
it('should be equal', function() {
expect(shake_256('', 8)).to.be('46');
});
});
});
})(shake_256, shake_128);

@ -1,13 +1,13 @@
ArrayBuffer.prototype.toHexString = function (argument) {
var array = new Uint8Array(this);
var hex = '';
for(var i = 0;i < array.length;++i) {
var c = array[i].toString('16');
hex += c.length == 1 ? '0' + c : c;
}
return hex;
};
(function(sha3_512, sha3_384, sha3_256, sha3_224) { (function(sha3_512, sha3_384, sha3_256, sha3_224) {
ArrayBuffer.prototype.toHexString = function (argument) {
var array = new Uint8Array(this);
var hex = '';
for(var i = 0;i < array.length;++i) {
var c = array[i].toString('16');
hex += c.length == 1 ? '0' + c : c;
}
return hex;
};
describe('sha3_512', function() { describe('sha3_512', function() {
context('when ascii', function() { context('when ascii', function() {
context('and less than 128 bytes', function() { context('and less than 128 bytes', function() {
@ -74,6 +74,12 @@ ArrayBuffer.prototype.toHexString = function (argument) {
expect(sha3_512.buffer('').toHexString()).to.be('a69f73cca23a9ac5c8b567dc185a756e97c982164fe25859e0d1dcc1475c80a615b2123af1f5f94c11e3e9402c3ac558f500199d95b6d3e301758586281dcd26'); expect(sha3_512.buffer('').toHexString()).to.be('a69f73cca23a9ac5c8b567dc185a756e97c982164fe25859e0d1dcc1475c80a615b2123af1f5f94c11e3e9402c3ac558f500199d95b6d3e301758586281dcd26');
}); });
}); });
context('#hex', function() {
it('should be equal', function() {
expect(sha3_512.hex('')).to.be(sha3_512(''));
});
});
}); });
describe('sha3_384', function() { describe('sha3_384', function() {

Loading…
Cancel
Save