-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathindex.js
69 lines (54 loc) · 2.08 KB
/
index.js
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
const assert = require('nanoassert')
const sodium = require('sodium-native')
const KEYBYTES = sodium.crypto_aead_xchacha20poly1305_ietf_KEYBYTES
const NONCEBYTES = sodium.crypto_aead_xchacha20poly1305_ietf_NPUBBYTES
const TAGBYTES = sodium.crypto_aead_xchacha20poly1305_ietf_ABYTES
const HEADERBYTES = NONCEBYTES + TAGBYTES
function keygen (key) {
if (key == null) key = sodium.sodium_malloc(KEYBYTES)
assert(key.byteLength === KEYBYTES, 'key must be KEYBYTES long')
sodium.crypto_aead_xchacha20poly1305_ietf_keygen(key)
return key
}
function encrypt (plaintext, key, ciphertext) {
assert(Buffer.isBuffer(plaintext))
var clen = encryptLength(plaintext)
if (ciphertext == null) ciphertext = Buffer.alloc(clen)
assert(key.byteLength === KEYBYTES, 'key must be KEYBYTES long')
assert(ciphertext.byteLength === clen, 'ciphertext must be plaintext + HEADERBYTES long')
const nonce = ciphertext.subarray(0, NONCEBYTES)
sodium.randombytes_buf(nonce)
// Kinda SIV
sodium.crypto_generichash_batch(nonce, [nonce, plaintext], key)
const c = ciphertext.subarray(NONCEBYTES)
sodium.crypto_aead_xchacha20poly1305_ietf_encrypt(c, plaintext, null, null, nonce, key)
return ciphertext
}
function encryptLength (plaintext) {
assert(Buffer.isBuffer(plaintext))
return plaintext.byteLength + HEADERBYTES
}
function decrypt (ciphertext, key, plaintext) {
assert(Buffer.isBuffer(ciphertext))
var plen = decryptLength(ciphertext)
if (plaintext == null) plaintext = sodium.sodium_malloc(plen)
assert(key.byteLength === KEYBYTES, 'key must be KEYBYTES long')
assert(plaintext.byteLength === plen, 'plaintext must be ciphertext - HEADERBYTES long')
const nonce = ciphertext.subarray(0, NONCEBYTES)
const c = ciphertext.subarray(NONCEBYTES)
sodium.crypto_aead_xchacha20poly1305_ietf_decrypt(plaintext, null, c, null, nonce, key)
return plaintext
}
function decryptLength (ciphertext) {
assert(Buffer.isBuffer(ciphertext))
return ciphertext.byteLength - HEADERBYTES
}
module.exports = {
keygen,
encrypt,
encryptLength,
decrypt,
decryptLength,
KEYBYTES,
HEADERBYTES
}