41 lines
1.2 KiB
JavaScript
41 lines
1.2 KiB
JavaScript
const keccak = require('./keccak');
|
|
|
|
function concatUint8Arrays(...arrays) {
|
|
let totalLength = arrays.reduce((acc, arr) => acc + arr.length, 0);
|
|
let result = new Uint8Array(totalLength);
|
|
let offset = 0;
|
|
for (const arr of arrays) {
|
|
result.set(arr, offset);
|
|
offset += arr.length;
|
|
}
|
|
return result;
|
|
}
|
|
|
|
|
|
class keccakKDF {
|
|
constructor(encryptionKeyLength = 32, privateKeyLength = 32) {
|
|
this.encryptionKeyLength = encryptionKeyLength;
|
|
this.privateKeyLength = privateKeyLength;
|
|
}
|
|
kdf(salt) {
|
|
const input = concatUint8Arrays(this.currentKey, salt);
|
|
const outputLength = this.encryptionKeyLength + this.privateKeyLength;
|
|
const output = keccak.SHAKE256(input, outputLength);
|
|
const encryptionKey = output.slice(0, this.encryptionKeyLength);
|
|
const newPrivateKey = output.slice(this.encryptionKeyLength, outputLength);
|
|
this.currentKey = newPrivateKey;
|
|
return encryptionKey;
|
|
}
|
|
init(initialKey, salt) {
|
|
this.currentKey = initialKey;
|
|
return this.kdf(salt);
|
|
}
|
|
next(salt) {
|
|
if (!this.currentKey) throw new Error("KDF not initialized");
|
|
return this.kdf(salt);
|
|
}
|
|
|
|
}
|
|
|
|
module.exports = { keccakKDF, concatUint8Arrays };
|