Files
@ 63e17c1c419e
Branch filter:
Location: CryptoJS/chacha.js - annotation
63e17c1c419e
2.3 KiB
text/javascript
String <--> UTF-8 conversion
d27d9e2dd943 c0f165783af4 c0f165783af4 c0f165783af4 c0f165783af4 c0f165783af4 d27d9e2dd943 d27d9e2dd943 d27d9e2dd943 d27d9e2dd943 d27d9e2dd943 d27d9e2dd943 d27d9e2dd943 d27d9e2dd943 d27d9e2dd943 d27d9e2dd943 d27d9e2dd943 d27d9e2dd943 d27d9e2dd943 d27d9e2dd943 d27d9e2dd943 d27d9e2dd943 d27d9e2dd943 d27d9e2dd943 d27d9e2dd943 d27d9e2dd943 d27d9e2dd943 d27d9e2dd943 d27d9e2dd943 d27d9e2dd943 d27d9e2dd943 d27d9e2dd943 d27d9e2dd943 d27d9e2dd943 d27d9e2dd943 d27d9e2dd943 d27d9e2dd943 d27d9e2dd943 d27d9e2dd943 d27d9e2dd943 d27d9e2dd943 d27d9e2dd943 c0f165783af4 c0f165783af4 c0f165783af4 c0f165783af4 c0f165783af4 d27d9e2dd943 d27d9e2dd943 d27d9e2dd943 d27d9e2dd943 d27d9e2dd943 d27d9e2dd943 d27d9e2dd943 d27d9e2dd943 d27d9e2dd943 d27d9e2dd943 d27d9e2dd943 d27d9e2dd943 d27d9e2dd943 d27d9e2dd943 d27d9e2dd943 d27d9e2dd943 d27d9e2dd943 d27d9e2dd943 d27d9e2dd943 d27d9e2dd943 d27d9e2dd943 d27d9e2dd943 d27d9e2dd943 d27d9e2dd943 d27d9e2dd943 d27d9e2dd943 d27d9e2dd943 d27d9e2dd943 d27d9e2dd943 d27d9e2dd943 c0f165783af4 c0f165783af4 d27d9e2dd943 d27d9e2dd943 d27d9e2dd943 d27d9e2dd943 d27d9e2dd943 d27d9e2dd943 d27d9e2dd943 d27d9e2dd943 c0f165783af4 | // https://tools.ietf.org/html/rfc7539
function lrot(x,shift){
return (x<<shift|x>>>(32-shift))&MASK;
}
function createNonce(){
let nonce=new Uint8Array(12);
window.crypto.getRandomValues(nonce);
return nonce;
}
function Chacha20(key,nonce){
if(nonce===undefined){
let nonce=createNonce();
}
nonce=bytes2int32s(nonce);
key=bytes2int32s(key);
this._state=[
0x61707865,0x3320646e,0x79622d32,0x6b206574,
key[0],key[1],key[2],key[3],
key[4],key[5],key[6],key[7],
0,nonce[0],nonce[1],nonce[2]
];
this._buffer=[];
}
Chacha20.prototype.setPos=function(pos){
this._state[12]=pos;
this._buffer=[];
}
Chacha20.prototype.getByte=function(){
if(this._buffer.length==0){
this._buffer=int32s2bytes(this._computeBlock());
}
return this._buffer.shift();
};
Chacha20.prototype._quarterRound=function(arr,ia,ib,ic,id){
let a=arr[ia], b=arr[ib], c=arr[ic], d=arr[id];
a=(a+b)&MASK; d=lrot(d^a,16);
c=(c+d)&MASK; b=lrot(b^c,12);
a=(a+b)&MASK; d=lrot(d^a,8);
c=(c+d)&MASK; b=lrot(b^c,7);
arr[ia]=a; arr[ib]=b; arr[ic]=c; arr[id]=d;
};
Chacha20.prototype._computeBlock=function(){
let state=this._state.slice();
for(let i=0;i<10;i++){ // 10 double rounds
// column round
this._quarterRound(state,0,4,8,12);
this._quarterRound(state,1,5,9,13);
this._quarterRound(state,2,6,10,14);
this._quarterRound(state,3,7,11,15);
// diagonal round
this._quarterRound(state,0,5,10,15);
this._quarterRound(state,1,6,11,12);
this._quarterRound(state,2,7,8,13);
this._quarterRound(state,3,4,9,14);
}
return state.map((xi,i)=>(xi+this._state[i])&MASK);
};
Chacha20.prototype._incrementPos=function(){
this._state[12]=(this._state[12]+1)&MASK;
};
function encrypt(message,key){
let nonce=Date.now();
let nonce0=nonce;
let hashedKey=blake2s(str2bytes(key));
message=str2bytes(message);
}
function testChacha(){
let key=[0,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];
let nonce=[0,0,0,9,0,0,0,74,0,0,0,0];
let cipher=new Chacha20(key,nonce);
cipher.setPos(1);
let output=cipher._computeBlock().map(x=>(x>>>0).toString(16).padStart(8,"0"));
let example=["e4e7f110","15593bd1","1fdd0f50","c47120a3","c7f4d1c7","0368c033","9aaa2204","4e6cd4c3","466482d2","09aa9f07","05d7c214","a2028bd9","d19c12b5","b94e16de","e883d0cb","4e3c50a2"];
console.log(output.every((x,i)=>x==example[i]));
}
|