UNPKG

5.12 kBJavaScriptView Raw
1/* eslint-disable camelcase */
2const assert = require('nanoassert')
3const { crypto_stream, crypto_stream_xor } = require('./crypto_stream')
4const { crypto_onetimeauth, crypto_onetimeauth_verify, crypto_onetimeauth_BYTES, crypto_onetimeauth_KEYBYTES } = require('./crypto_onetimeauth')
5
6const crypto_secretbox_KEYBYTES = 32
7const crypto_secretbox_NONCEBYTES = 24
8const crypto_secretbox_ZEROBYTES = 32
9const crypto_secretbox_BOXZEROBYTES = 16
10const crypto_secretbox_MACBYTES = 16
11
12module.exports = {
13 crypto_secretbox,
14 crypto_secretbox_open,
15 crypto_secretbox_detached,
16 crypto_secretbox_open_detached,
17 crypto_secretbox_easy,
18 crypto_secretbox_open_easy,
19 crypto_secretbox_KEYBYTES,
20 crypto_secretbox_NONCEBYTES,
21 crypto_secretbox_ZEROBYTES,
22 crypto_secretbox_BOXZEROBYTES,
23 crypto_secretbox_MACBYTES
24}
25
26function crypto_secretbox (c, m, n, k) {
27 assert(c.byteLength === m.byteLength, "c must be 'm.byteLength' bytes")
28 const mlen = m.byteLength
29 assert(mlen >= crypto_secretbox_ZEROBYTES, "mlen must be at least 'crypto_secretbox_ZEROBYTES'")
30 assert(n.byteLength === crypto_secretbox_NONCEBYTES, "n must be 'crypto_secretbox_NONCEBYTES' bytes")
31 assert(k.byteLength === crypto_secretbox_KEYBYTES, "k must be 'crypto_secretbox_KEYBYTES' bytes")
32
33 crypto_stream_xor(c, m, n, k)
34 crypto_onetimeauth(
35 c.subarray(crypto_secretbox_BOXZEROBYTES, crypto_secretbox_BOXZEROBYTES + crypto_onetimeauth_BYTES),
36 c.subarray(crypto_secretbox_BOXZEROBYTES + crypto_onetimeauth_BYTES, c.byteLength),
37 c.subarray(0, crypto_onetimeauth_KEYBYTES)
38 )
39 c.fill(0, 0, crypto_secretbox_BOXZEROBYTES)
40 return 0
41}
42
43function crypto_secretbox_open (m, c, n, k) {
44 assert(c.byteLength === m.byteLength, "c must be 'm.byteLength' bytes")
45 const mlen = m.byteLength
46 assert(mlen >= crypto_secretbox_ZEROBYTES, "mlen must be at least 'crypto_secretbox_ZEROBYTES'")
47 assert(n.byteLength === crypto_secretbox_NONCEBYTES, "n must be 'crypto_secretbox_NONCEBYTES' bytes")
48 assert(k.byteLength === crypto_secretbox_KEYBYTES, "k must be 'crypto_secretbox_KEYBYTES' bytes")
49
50 const x = new Uint8Array(crypto_onetimeauth_KEYBYTES)
51 crypto_stream(x, n, k)
52 const validMac = crypto_onetimeauth_verify(
53 c.subarray(crypto_secretbox_BOXZEROBYTES, crypto_secretbox_BOXZEROBYTES + crypto_onetimeauth_BYTES),
54 c.subarray(crypto_secretbox_BOXZEROBYTES + crypto_onetimeauth_BYTES, c.byteLength),
55 x
56 )
57
58 if (validMac === false) return false
59 crypto_stream_xor(m, c, n, k)
60 m.fill(0, 0, 32)
61 return true
62}
63
64function crypto_secretbox_detached (o, mac, msg, n, k) {
65 assert(o.byteLength === msg.byteLength, "o must be 'msg.byteLength' bytes")
66 assert(mac.byteLength === crypto_secretbox_MACBYTES, "mac must be 'crypto_secretbox_MACBYTES' bytes")
67 assert(n.byteLength === crypto_secretbox_NONCEBYTES, "n must be 'crypto_secretbox_NONCEBYTES' bytes")
68 assert(k.byteLength === crypto_secretbox_KEYBYTES, "k must be 'crypto_secretbox_KEYBYTES' bytes")
69
70 const tmp = new Uint8Array(msg.byteLength + mac.byteLength)
71 crypto_secretbox_easy(tmp, msg, n, k)
72 o.set(tmp.subarray(0, msg.byteLength))
73 mac.set(tmp.subarray(msg.byteLength))
74 return true
75}
76
77function crypto_secretbox_open_detached (msg, o, mac, n, k) {
78 assert(o.byteLength === msg.byteLength, "o must be 'msg.byteLength' bytes")
79 assert(mac.byteLength === crypto_secretbox_MACBYTES, "mac must be 'crypto_secretbox_MACBYTES' bytes")
80 assert(n.byteLength === crypto_secretbox_NONCEBYTES, "n must be 'crypto_secretbox_NONCEBYTES' bytes")
81 assert(k.byteLength === crypto_secretbox_KEYBYTES, "k must be 'crypto_secretbox_KEYBYTES' bytes")
82
83 const tmp = new Uint8Array(o.byteLength + mac.byteLength)
84 tmp.set(o)
85 tmp.set(mac, msg.byteLength)
86 return crypto_secretbox_open_easy(msg, tmp, n, k)
87}
88
89function crypto_secretbox_easy (o, msg, n, k) {
90 assert(o.byteLength === msg.byteLength + crypto_secretbox_MACBYTES, "o must be 'msg.byteLength + crypto_secretbox_MACBYTES' bytes")
91 assert(n.byteLength === crypto_secretbox_NONCEBYTES, "n must be 'crypto_secretbox_NONCEBYTES' bytes")
92 assert(k.byteLength === crypto_secretbox_KEYBYTES, "k must be 'crypto_secretbox_KEYBYTES' bytes")
93
94 const m = new Uint8Array(crypto_secretbox_ZEROBYTES + msg.byteLength)
95 const c = new Uint8Array(m.byteLength)
96 m.set(msg, crypto_secretbox_ZEROBYTES)
97 if (crypto_secretbox(c, m, n, k) === false) return false
98 o.set(c.subarray(crypto_secretbox_BOXZEROBYTES))
99 return true
100}
101
102function crypto_secretbox_open_easy (msg, box, n, k) {
103 assert(box.byteLength === msg.byteLength + crypto_secretbox_MACBYTES, "box must be 'msg.byteLength + crypto_secretbox_MACBYTES' bytes")
104 assert(n.byteLength === crypto_secretbox_NONCEBYTES, "n must be 'crypto_secretbox_NONCEBYTES' bytes")
105 assert(k.byteLength === crypto_secretbox_KEYBYTES, "k must be 'crypto_secretbox_KEYBYTES' bytes")
106
107 const c = new Uint8Array(crypto_secretbox_BOXZEROBYTES + box.byteLength)
108 const m = new Uint8Array(c.byteLength)
109 c.set(box, crypto_secretbox_BOXZEROBYTES)
110 if (crypto_secretbox_open(m, c, n, k) === false) return false
111 msg.set(m.subarray(crypto_secretbox_ZEROBYTES))
112 return true
113}