-
Notifications
You must be signed in to change notification settings - Fork 3
Expand file tree
/
Copy pathsodium.js
More file actions
115 lines (107 loc) · 3.06 KB
/
sodium.js
File metadata and controls
115 lines (107 loc) · 3.06 KB
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
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
function u8ToBuf(u8) {
return Buffer.isBuffer(u8)
? u8
: Buffer.from(u8.buffer, u8.byteOffset, u8.byteLength)
}
let api = null
/* INFO: using sodium-native first because its more performant than libsodium-wrappers, but if it fails to load
(e.g. not supported platform), it will fallback to libsodium-wrappers. Sodium-native is preffered because it
allows writing directly into libsodium buffers.
USAGE: const ok = sodium.crypto_aead_xchacha20poly1305_ietf_decrypt(
out, // m: output buffer ('out')
null, // nsec: must be null
cipher, // c: ciphertext to decrypt
aad, // ad: additional data (optional, can be null)
nonce, // npub: nonce
key // k: key
)
SOURCES:
- https://sodium-friends.github.io/docs/docs/aead
- https://sodium-friends.github.io/docs/docs/aead#crypto_aead_xchacha20poly1305_ietf_decrypt
*/
try {
const mod = await import('sodium-native')
const sodium = mod.default ?? mod
const ABYTES = sodium.crypto_aead_xchacha20poly1305_ietf_ABYTES
api = {
kind: 'sodium-native',
ABYTES,
crypto_aead_xchacha20poly1305_ietf_encrypt_into(out, msg, aad, nonce, key) {
sodium.crypto_aead_xchacha20poly1305_ietf_encrypt(out, null, msg, aad, nonce, key)
return out
},
crypto_aead_xchacha20poly1305_ietf_encrypt(msg, aad, nonce, key) {
const out = Buffer.allocUnsafe(msg.length + ABYTES)
sodium.crypto_aead_xchacha20poly1305_ietf_encrypt(
out,
null,
msg,
aad,
nonce,
key
)
return out
},
crypto_aead_xchacha20poly1305_ietf_decrypt(cipher, aad, nonce, key) {
const out = Buffer.allocUnsafe(cipher.length - ABYTES)
const ok = sodium.crypto_aead_xchacha20poly1305_ietf_decrypt(
out,
null,
cipher,
aad,
nonce,
key
)
if (ok === false) throw new Error('sodium decrypt failed')
return out
}
}
} catch {
// ignore, it will fallback to libsodium-wrappers
}
if (!api) {
const mod = await import('libsodium-wrappers')
const sodium = mod.default ?? mod
await sodium.ready
const ABYTES = sodium.crypto_aead_xchacha20poly1305_ietf_ABYTES
api = {
kind: 'libsodium-wrappers',
ABYTES,
crypto_aead_xchacha20poly1305_ietf_encrypt_into(out, msg, aad, nonce, key) {
const enc = u8ToBuf(
sodium.crypto_aead_xchacha20poly1305_ietf_encrypt(
msg,
aad,
null,
nonce,
key
)
)
enc.copy(out)
return out
},
crypto_aead_xchacha20poly1305_ietf_encrypt(msg, aad, nonce, key) {
return u8ToBuf(
sodium.crypto_aead_xchacha20poly1305_ietf_encrypt(
msg,
aad,
null,
nonce,
key
)
)
},
crypto_aead_xchacha20poly1305_ietf_decrypt(cipher, aad, nonce, key) {
return u8ToBuf(
sodium.crypto_aead_xchacha20poly1305_ietf_decrypt(
null,
cipher,
aad,
nonce,
key
)
)
}
}
}
export default api