Files
@ 63e17c1c419e
Branch filter:
Location: CryptoJS/blake.js
63e17c1c419e
4.0 KiB
text/javascript
String <--> UTF-8 conversion
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 | // https://tools.ietf.org/html/rfc7693
const BLOCK_LEN=64;
const IV=[0x6A09E667,0xBB67AE85,0x3C6EF372,0xA54FF53A,0x510E527F,0x9B05688C,0x1F83D9AB,0x5BE0CD19];
function padEnd(arr,length,val=0){
return arr.concat((new Array(length-arr.length)).fill(0));
}
function rrot(x,shift){
return ((x>>>shift)|(x<<(32-shift)))&MASK;
}
function BLAKE2S(outputLen=32,key=[]){
this._buffer=[];
this._dataLen=[0,0]; // low, high
this._outputLen=outputLen;
this._state=IV.slice();
this._state[0]^=0x01010000^(key.length<<8)^this._outputLen;
if(key.length>0){this.update(padEnd(key,BLOCK_LEN,0));}
}
BLAKE2S.prototype.update=function(data){
for(let i=0;i<data.length;i++){
if(this._buffer.length==BLOCK_LEN){
this._compress(false);
this._buffer=[];
}
this._buffer.push(data[i]);
this._dataLen[0]=(this._dataLen[0]+1)&MASK;
if(this._dataLen[0]<this._buffer.length){this._dataLen[1]++;}
}
};
BLAKE2S.prototype.digest=function(){
this._buffer=padEnd(this._buffer,BLOCK_LEN,0);
this._compress(true);
return int32s2bytes(this._state).slice(0,this._outputLen);
};
BLAKE2S.prototype._compress=function(last){
const SIGMA=[
[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15],
[14,10,4,8,9,15,13,6,1,12,0,2,11,7,5,3],
[11,8,12,0,5,2,15,13,10,14,3,6,7,1,9,4],
[7,9,3,1,13,12,11,14,2,6,5,10,4,0,15,8],
[9,0,5,7,2,4,10,15,14,1,11,12,6,8,3,13],
[2,12,6,10,0,11,8,3,4,13,7,5,15,14,1,9],
[12,5,1,15,14,13,4,10,0,7,6,3,9,2,8,11],
[13,11,7,14,12,1,3,9,5,0,15,4,8,6,2,10],
[6,15,14,9,11,3,0,8,12,2,13,7,1,4,10,5],
[10,2,8,4,7,6,1,5,15,11,9,14,3,12,13,0]
];
let v=this._state.concat(IV);
v[12]^=this._dataLen[0];
v[13]^=this._dataLen[1];
if(last){v[14]^=MASK;}
let data=bytes2int32s(this._buffer);
for(let i=0;i<10;i++){
let perm=SIGMA[i%10];
this._mix(v,0,4,8,12,data[perm[0]],data[perm[1]]);
this._mix(v,1,5,9,13,data[perm[2]],data[perm[3]]);
this._mix(v,2,6,10,14,data[perm[4]],data[perm[5]]);
this._mix(v,3,7,11,15,data[perm[6]],data[perm[7]]);
this._mix(v,0,5,10,15,data[perm[8]],data[perm[9]]);
this._mix(v,1,6,11,12,data[perm[10]],data[perm[11]]);
this._mix(v,2,7,8,13,data[perm[12]],data[perm[13]]);
this._mix(v,3,4,9,14,data[perm[14]],data[perm[15]]);
}
this._state=this._state.map((x,i)=>x^v[i]^v[i+8]);
};
BLAKE2S.prototype._mix=function(arr,ia,ib,ic,id,x,y){
let a=arr[ia], b=arr[ib], c=arr[ic], d=arr[id];
a=(a+b+x)&MASK; d=rrot(d^a,16);
c=(c+d)&MASK; b=rrot(b^c,12);
a=(a+b+y)&MASK; d=rrot(d^a,8);
c=(c+d)&MASK; b=rrot(b^c,7);
arr[ia]=a; arr[ib]=b; arr[ic]=c; arr[id]=d;
};
function blake2s(data,outputLen=32,key=[]){
let h=new BLAKE2S(outputLen,key);
for(let i=0;i<data.length;i+=BLOCK_LEN){h.update(data.slice(i,i+BLOCK_LEN));}
return h.digest();
}
function testBlake(){
let msg=str2utf8("abc");
let longMsg=str2utf8("0123456789.10.456789.20.456789.30.456789.40.456789.50.456789.60.456789.70.456789.80.456789.90.456789");
let key=str2utf8("zoqpiz");
let longKey=str2utf8("zoqpizjutyclcmkamzhhmhvchxjtefjy");
console.log(bytes2hex(blake2s(msg,16))=="aa4938119b1dc7b87cbad0ffd200d0ae");
console.log(bytes2hex(blake2s(msg,20))=="5ae3b99be29b01834c3b508521ede60438f8de17");
console.log(bytes2hex(blake2s(msg,28))=="0b033fc226df7abde29f67a05d3dc62cf271ef3dfea4d387407fbd55");
console.log(bytes2hex(blake2s(msg))=="508c5e8c327c14e2e1a72ba34eeb452f37458b209ed63a294d999b4c86675982");
console.log(bytes2hex(blake2s(longMsg))=="59a44e5e417d07fb382505ee7e67c23e0d476d354abc81899960bcab677beee1");
console.log(bytes2hex(blake2s(msg,32,key))=="0da0b6a54e8f294b60bb25c572700166ddb9d124257ff36f9f43f18b844adf9f");
console.log(bytes2hex(blake2s(msg,32,longKey))=="09ef85c9942bebdeb866c6ade769220fd9b851aead642017f6d59bf7e2a32037");
console.log(bytes2hex(blake2s([]))=="69217a3079908094e11121d042354a7c1f55b6482ca1a51e1b250dfd1ed0eef9");
console.log(bytes2hex(blake2s(longMsg.slice(0,64)))=="70484f89974551454d596350dda8af2aa6f0811b527549b9ecfe7adede063753");
console.log(bytes2hex(blake2s(longMsg.slice(0,65)))=="af14d4f74947bbde734d0e3015c667cc80676efe4349be235be8046e9e45e0ae");
}
|