1
0
mirror of https://github.com/laurent22/joplin.git synced 2024-12-18 09:35:20 +02:00
joplin/packages/lib/services/e2ee/cryptoShared.ts
Self Not Found aa6348c5c2
All: Add new encryption methods based on native crypto libraries (#10696)
Co-authored-by: Laurent Cozic <laurent22@users.noreply.github.com>
Co-authored-by: Henry Heino <personalizedrefrigerator@gmail.com>
2024-10-26 21:15:10 +01:00

53 lines
1.7 KiB
TypeScript

import { CryptoBuffer } from './types';
const nonceCounterLength = 8;
const nonceTimestampLength = 7;
type RandomBytesImplementation = (size: number)=> Promise<CryptoBuffer>;
let randomBytesImplementation: RandomBytesImplementation = null;
export const setRandomBytesImplementation = (implementation: RandomBytesImplementation) => {
randomBytesImplementation = implementation;
};
export const generateNonce = async (nonce: Uint8Array) => {
const randomLength = nonce.length - nonceTimestampLength - nonceCounterLength;
if (randomLength < 1) {
throw new Error(`Nonce length should be greater than ${(nonceTimestampLength + nonceCounterLength) * 8} bits`);
}
nonce.set(await randomBytesImplementation(randomLength));
const timestampArray = new Uint8Array(nonceTimestampLength);
let timestamp = Date.now();
let timestampMsb = Math.floor(timestamp / 2 ** 32);
const lsbCount = Math.min(4, nonceTimestampLength);
for (let i = 0; i < lsbCount; i++) {
timestampArray[i] = timestamp & 0xFF;
timestamp >>>= 8;
}
// The bitwise operators in Typescript only take the 32 LSBs to calculate, so we need to extract the MSBs manually.
for (let i = 4; i < nonceTimestampLength; i++) {
timestampArray[i] = timestampMsb & 0xFF;
timestampMsb >>>= 8;
}
nonce.set(timestampArray, randomLength);
nonce.set(new Uint8Array(nonceCounterLength), randomLength + nonceTimestampLength);
return nonce;
};
export const increaseNonce = async (nonce: Uint8Array) => {
const carry = 1;
const end = nonce.length - nonceCounterLength;
let i = nonce.length;
while (i-- > end) {
nonce[i] += carry;
if (nonce[i] !== 0 || carry !== 1) {
break;
}
}
if (i < end) {
await generateNonce(nonce);
}
return nonce;
};