// https://tools.ietf.org/html/rfc2898 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; }