UNPKG

7.33 kBJavaScriptView Raw
1/* eslint-disable brace-style,camelcase,comma-spacing,curly,one-var,padding-line-between-statements,space-infix-ops */
2function L32(x, c) { return (x << c) | (x >>> (32 - c)); }
3function ld32(x, i) {
4 let u = x[i + 3] & 0xff;
5 u = (u << 8) | (x[i + 2] & 0xff);
6 u = (u << 8) | (x[i + 1] & 0xff);
7 return (u << 8) | (x[i + 0] & 0xff);
8}
9function st32(x, j, u) {
10 for (let i = 0; i < 4; i++) {
11 x[j + i] = u & 255;
12 u >>>= 8;
13 }
14}
15function vn(x, xi, y, yi, n) {
16 let d = 0;
17 for (let i = 0; i < n; i++)
18 d |= x[xi + i] ^ y[yi + i];
19 return (1 & ((d - 1) >>> 8)) - 1;
20}
21function core(out, inp, k, c, h) {
22 const w = new Uint32Array(16), x = new Uint32Array(16), y = new Uint32Array(16), t = new Uint32Array(4);
23 let i, j, m;
24 for (i = 0; i < 4; i++) {
25 x[5 * i] = ld32(c, 4 * i);
26 x[1 + i] = ld32(k, 4 * i);
27 x[6 + i] = ld32(inp, 4 * i);
28 x[11 + i] = ld32(k, 16 + 4 * i);
29 }
30 for (i = 0; i < 16; i++)
31 y[i] = x[i];
32 for (i = 0; i < 20; i++) {
33 for (j = 0; j < 4; j++) {
34 for (m = 0; m < 4; m++)
35 t[m] = x[(5 * j + 4 * m) % 16];
36 t[1] ^= L32((t[0] + t[3]) | 0, 7);
37 t[2] ^= L32((t[1] + t[0]) | 0, 9);
38 t[3] ^= L32((t[2] + t[1]) | 0, 13);
39 t[0] ^= L32((t[3] + t[2]) | 0, 18);
40 for (m = 0; m < 4; m++)
41 w[4 * j + (j + m) % 4] = t[m];
42 }
43 for (m = 0; m < 16; m++)
44 x[m] = w[m];
45 }
46 if (h) {
47 for (i = 0; i < 16; i++)
48 x[i] = (x[i] + y[i]) | 0;
49 for (i = 0; i < 4; i++) {
50 x[5 * i] = (x[5 * i] - ld32(c, 4 * i)) | 0;
51 x[6 + i] = (x[6 + i] - ld32(inp, 4 * i)) | 0;
52 }
53 for (i = 0; i < 4; i++) {
54 st32(out, 4 * i, x[5 * i]);
55 st32(out, 16 + 4 * i, x[6 + i]);
56 }
57 }
58 else {
59 for (i = 0; i < 16; i++)
60 st32(out, 4 * i, (x[i] + y[i]) | 0);
61 }
62}
63const sigma = new Uint8Array([101, 120, 112, 97, 110, 100, 32, 51, 50, 45, 98, 121, 116, 101, 32, 107]);
64function crypto_stream_salsa20_xor(c, cpos, m, mpos, b, n, k) {
65 const z = new Uint8Array(16), x = new Uint8Array(64);
66 let u, i;
67 if (!b)
68 return 0;
69 for (i = 0; i < 16; i++)
70 z[i] = 0;
71 for (i = 0; i < 8; i++)
72 z[i] = n[i];
73 while (b >= 64) {
74 core(x, z, k, sigma, false);
75 for (i = 0; i < 64; i++)
76 c[cpos + i] = (m ? m[mpos + i] : 0) ^ x[i];
77 u = 1;
78 for (i = 8; i < 16; i++) {
79 u = u + (z[i] & 0xff) | 0;
80 z[i] = u & 0xff;
81 u >>>= 8;
82 }
83 b -= 64;
84 cpos += 64;
85 if (m)
86 mpos += 64;
87 }
88 if (b > 0) {
89 core(x, z, k, sigma, false);
90 for (i = 0; i < b; i++)
91 c[cpos + i] = (m ? m[mpos + i] : 0) ^ x[i];
92 }
93 return 0;
94}
95function crypto_stream_xor(c, cpos, m, mpos, d, n, k) {
96 const s = new Uint8Array(32);
97 core(s, n, k, sigma, true);
98 return crypto_stream_salsa20_xor(c, cpos, m, mpos, d, n.subarray(16), s);
99}
100function add1305(h, c) {
101 let u = 0;
102 for (let j = 0; j < 17; j++) {
103 u = (u + ((h[j] + c[j]) | 0)) | 0;
104 h[j] = u & 255;
105 u >>>= 8;
106 }
107}
108const minusp = new Uint32Array([5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 252]);
109function crypto_onetimeauth(out, outpos, m, mpos, n, k) {
110 let i, j, u;
111 const x = new Uint32Array(17), r = new Uint32Array(17), h = new Uint32Array(17), c = new Uint32Array(17), g = new Uint32Array(17);
112 for (j = 0; j < 17; j++)
113 r[j] = h[j] = 0;
114 for (j = 0; j < 16; j++)
115 r[j] = k[j];
116 r[3] &= 15;
117 r[4] &= 252;
118 r[7] &= 15;
119 r[8] &= 252;
120 r[11] &= 15;
121 r[12] &= 252;
122 r[15] &= 15;
123 while (n > 0) {
124 for (j = 0; j < 17; j++)
125 c[j] = 0;
126 for (j = 0; (j < 16) && (j < n); ++j)
127 c[j] = m[mpos + j];
128 c[j] = 1;
129 mpos += j;
130 n -= j;
131 add1305(h, c);
132 for (i = 0; i < 17; i++) {
133 x[i] = 0;
134 for (j = 0; j < 17; j++)
135 x[i] = (x[i] + (h[j] * ((j <= i) ? r[i - j] : ((320 * r[i + 17 - j]) | 0))) | 0) | 0;
136 }
137 for (i = 0; i < 17; i++)
138 h[i] = x[i];
139 u = 0;
140 for (j = 0; j < 16; j++) {
141 u = (u + h[j]) | 0;
142 h[j] = u & 255;
143 u >>>= 8;
144 }
145 u = (u + h[16]) | 0;
146 h[16] = u & 3;
147 u = (5 * (u >>> 2)) | 0;
148 for (j = 0; j < 16; j++) {
149 u = (u + h[j]) | 0;
150 h[j] = u & 255;
151 u >>>= 8;
152 }
153 u = (u + h[16]) | 0;
154 h[16] = u;
155 }
156 for (j = 0; j < 17; j++)
157 g[j] = h[j];
158 add1305(h, minusp);
159 const s = (-(h[16] >>> 7) | 0);
160 for (j = 0; j < 17; j++)
161 h[j] ^= s & (g[j] ^ h[j]);
162 for (j = 0; j < 16; j++)
163 c[j] = k[j + 16];
164 c[16] = 0;
165 add1305(h, c);
166 for (j = 0; j < 16; j++)
167 out[outpos + j] = h[j];
168 return 0;
169}
170function crypto_onetimeauth_verify(h, hpos, m, mpos, n, k) {
171 const x = new Uint8Array(16);
172 crypto_onetimeauth(x, 0, m, mpos, n, k);
173 return vn(h, hpos, x, 0, 16);
174}
175function crypto_secretbox(c, m, d, n, k) {
176 if (d < 32)
177 return -1;
178 crypto_stream_xor(c, 0, m, 0, d, n, k);
179 crypto_onetimeauth(c, 16, c, 32, d - 32, c);
180 for (let i = 0; i < 16; i++)
181 c[i] = 0;
182 return 0;
183}
184function crypto_secretbox_open(m, c, d, n, k) {
185 const x = new Uint8Array(32);
186 if (d < 32)
187 return -1;
188 crypto_stream_xor(x, 0, null, 0, 32, n, k);
189 if (crypto_onetimeauth_verify(c, 16, c, 32, d - 32, x) !== 0)
190 return -1;
191 crypto_stream_xor(m, 0, c, 0, d, n, k);
192 for (let i = 0; i < 32; i++)
193 m[i] = 0;
194 return 0;
195}
196const crypto_secretbox_KEYBYTES = 32;
197const crypto_secretbox_NONCEBYTES = 24;
198const crypto_secretbox_ZEROBYTES = 32;
199const crypto_secretbox_BOXZEROBYTES = 16;
200function checkLengths(k, n) {
201 if (k.length !== crypto_secretbox_KEYBYTES)
202 throw new Error('bad key size');
203 if (n.length !== crypto_secretbox_NONCEBYTES)
204 throw new Error('bad nonce size');
205}
206function checkArrayTypes(...args) {
207 for (let i = 0, count = args.length; i < count; i++) {
208 if (!(args[i] instanceof Uint8Array))
209 throw new TypeError('unexpected type, use Uint8Array');
210 }
211}
212export function naclSecretbox(msg, nonce, key) {
213 checkArrayTypes(msg, nonce, key);
214 checkLengths(key, nonce);
215 const m = new Uint8Array(crypto_secretbox_ZEROBYTES + msg.length);
216 const c = new Uint8Array(m.length);
217 for (let i = 0; i < msg.length; i++)
218 m[i + crypto_secretbox_ZEROBYTES] = msg[i];
219 crypto_secretbox(c, m, m.length, nonce, key);
220 return c.subarray(crypto_secretbox_BOXZEROBYTES);
221}
222export function naclSecretboxOpen(box, nonce, key) {
223 checkArrayTypes(box, nonce, key);
224 checkLengths(key, nonce);
225 const c = new Uint8Array(crypto_secretbox_BOXZEROBYTES + box.length);
226 const m = new Uint8Array(c.length);
227 for (let i = 0; i < box.length; i++)
228 c[i + crypto_secretbox_BOXZEROBYTES] = box[i];
229 if (c.length < 32)
230 return null;
231 if (crypto_secretbox_open(m, c, c.length, nonce, key) !== 0)
232 return null;
233 return m.subarray(crypto_secretbox_ZEROBYTES);
234}