-
-
Notifications
You must be signed in to change notification settings - Fork 4k
/
Secretbox.ts
75 lines (68 loc) · 2.29 KB
/
Secretbox.ts
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
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
import { Buffer } from 'node:buffer';
interface Methods {
close(opusPacket: Buffer, nonce: Buffer, secretKey: Uint8Array): Buffer;
open(buffer: Buffer, nonce: Buffer, secretKey: Uint8Array): Buffer | null;
random(bytes: number, nonce: Buffer): Buffer;
}
const libs = {
'sodium-native': (sodium: any): Methods => ({
open: (buffer: Buffer, nonce: Buffer, secretKey: Uint8Array) => {
if (buffer) {
const output = Buffer.allocUnsafe(buffer.length - sodium.crypto_box_MACBYTES);
if (sodium.crypto_secretbox_open_easy(output, buffer, nonce, secretKey)) return output;
}
return null;
},
close: (opusPacket: Buffer, nonce: Buffer, secretKey: Uint8Array) => {
const output = Buffer.allocUnsafe(opusPacket.length + sodium.crypto_box_MACBYTES);
sodium.crypto_secretbox_easy(output, opusPacket, nonce, secretKey);
return output;
},
random: (num: number, buffer: Buffer = Buffer.allocUnsafe(num)) => {
sodium.randombytes_buf(buffer);
return buffer;
},
}),
sodium: (sodium: any): Methods => ({
open: sodium.api.crypto_secretbox_open_easy,
close: sodium.api.crypto_secretbox_easy,
random: (num: number, buffer: Buffer = Buffer.allocUnsafe(num)) => {
sodium.api.randombytes_buf(buffer);
return buffer;
},
}),
'libsodium-wrappers': (sodium: any): Methods => ({
open: sodium.crypto_secretbox_open_easy,
close: sodium.crypto_secretbox_easy,
random: sodium.randombytes_buf,
}),
tweetnacl: (tweetnacl: any): Methods => ({
open: tweetnacl.secretbox.open,
close: tweetnacl.secretbox,
random: tweetnacl.randomBytes,
}),
} as const;
const fallbackError = () => {
throw new Error(
`Cannot play audio as no valid encryption package is installed.
- Install sodium, libsodium-wrappers, or tweetnacl.
- Use the generateDependencyReport() function for more information.\n`,
);
};
const methods: Methods = {
open: fallbackError,
close: fallbackError,
random: fallbackError,
};
void (async () => {
for (const libName of Object.keys(libs) as (keyof typeof libs)[]) {
try {
// eslint-disable-next-line @typescript-eslint/no-require-imports, @typescript-eslint/no-var-requires
const lib = require(libName);
if (libName === 'libsodium-wrappers' && lib.ready) await lib.ready;
Object.assign(methods, libs[libName](lib));
break;
} catch {}
}
})();
export { methods };