Changeset - 944bd9524df4
[Not reviewed]
default
0 2 1
Laman - 5 years ago 2019-07-01 19:28:27

added PBKDF2
3 files changed with 42 insertions and 1 deletions:
0 comments (0 inline, 0 general)
src/main.js
Show inline comments
 
import * as util from "./util.js";
 
import {blake2s} from "./blake.js";
 
import {pbkdf2} from "./pbkdf2.js";
 
import {Chacha20,encrypt,decrypt} from "./chacha.js";
 

	
 
export default {util,blake2s,Chacha20};
 
export default {util,blake2s,pbkdf2,Chacha20,encrypt,decrypt};
 

	
 
// export for tests running on Node
 
if(typeof module!=='undefined'&&module.hasOwnProperty('exports')){
 
	module.exports.util=util;
 
	module.exports.blake2s=blake2s;
 
	module.exports.pbkdf2=pbkdf2;
 
	module.exports.Chacha20=Chacha20;
 
	module.exports.encrypt=encrypt;
 
	module.exports.decrypt=decrypt;
 
}
src/pbkdf2.js
Show inline comments
 
new file 100644
 
import {int322bytesBE} from "./util.js";
 
import {blake2s} from "./blake.js";
 

	
 
const HASH_LENGTH=32;
 

	
 
export function pbkdf2(password,salt,iterationCount,outLength){
 
	// max BLAKE2 key length is 32B
 
	if(password.length>32){password=blake2s(password);}
 
	
 
	let blockCount=Math.ceil(outLength/HASH_LENGTH);
 
	let result=[];
 
	
 
	for(let i=0;i<blockCount;i++){
 
		let block=_computeBlock(password,salt,iterationCount,i+1);
 
		result=result.concat(block);
 
	}
 
	return result.slice(0,outLength);
 
}
 

	
 
function _computeBlock(password,salt,iterationCount,blockIndex){
 
	let u=blake2s(salt.concat(int322bytesBE(blockIndex)),HASH_LENGTH,password);
 
	for(let i=1;i<iterationCount;i++){
 
		let ui=blake2s(u,HASH_LENGTH,password);
 
		u=u.map((b,j)=>b^ui[j]);
 
	}
 
	return u;
 
}
src/util.js
Show inline comments
 
export const MASK=0xffffffff;
 

	
 
export function zeroPad(arr,length){
 
	return arr.concat((new Array(length)).fill(0)).slice(0,length);
 
}
 

	
 
export function bytes2int32(arr){
 
	return arr.reduce((acc,b,i)=>acc|b<<(i*8));
 
}
 

	
 
export function bytes2int32s(arr){
 
	let res=[];
 
	for(let i=0;i<arr.length;i+=4){
 
		res.push(bytes2int32(arr.slice(i,i+4)));
 
	}
 
	return res;
 
}
 

	
 
/**
 
 * Converts a 32 bit integer into 4 bytes in little endian order.
 
 */
 
export function int322bytes(x){
 
	let res=[];
 
	for(let i=0;i<4;i++){
 
		res.push(x&0xff);
 
		x>>>=8;
 
	}
 
	return res;
 
}
 

	
 
/**
 
 * Converts a 32 bit integer into 4 bytes in big endian order.
 
 */
 
export function int322bytesBE(x){
 
	let res=int322bytes(x);
 
	res.reverse();
 
	return res;
 
}
 

	
 
export function int32s2bytes(arr){
 
	return arr.map(int322bytes).reduce((acc,bytes)=>acc.concat(bytes));
 
}
 

	
 
export function bytes2hex(arr){
 
	return arr.map(x=>x.toString(16).padStart(2,"0")).join("");
 
}
 

	
 
export function str2utf8(s){
 
	let res=[];
 
	let c=s.codePointAt(0);
 
	for(let i=0; c!==undefined; i++,c=s.codePointAt(i)){
 
		if(c<0x80){res.push(c);}
 
		else if(c<0x800){
 
			res.push(0b11000000|(c>>>6));
 
			res.push(0b10000000|(c&0b111111));
 
		}
 
		else if(c<0x10000){
 
			res.push(0b11100000|(c>>>12));
 
			res.push(0b10000000|((c>>>6)&0b111111));
 
			res.push(0b10000000|(c&0b111111));
 
		}
 
		else{
 
			res.push(0b11110000|(c>>>18));
0 comments (0 inline, 0 general)