@ray-js/wechat-tycrypto 0.0.1-beta-1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/index.esm.js ADDED
@@ -0,0 +1,1740 @@
1
+ class IllegalStateError extends Error {
2
+ constructor(...args) {
3
+ super(...args);
4
+ }
5
+
6
+ }
7
+ class IllegalArgumentError extends Error {
8
+ constructor(...args) {
9
+ super(...args);
10
+ }
11
+
12
+ }
13
+ class SecurityError extends Error {
14
+ constructor(...args) {
15
+ super(...args);
16
+ }
17
+
18
+ }
19
+
20
+ function is_bytes(a) {
21
+ return a instanceof Uint8Array;
22
+ }
23
+ function _heap_init(heap, heapSize) {
24
+ const size = heap ? heap.byteLength : heapSize || 65536;
25
+ if (size & 0xfff || size <= 0) throw new Error('heap size must be a positive integer and a multiple of 4096');
26
+ heap = heap || new Uint8Array(new ArrayBuffer(size));
27
+ return heap;
28
+ }
29
+ function _heap_write(heap, hpos, data, dpos, dlen) {
30
+ const hlen = heap.length - hpos;
31
+ const wlen = hlen < dlen ? hlen : dlen;
32
+ heap.set(data.subarray(dpos, dpos + wlen), hpos);
33
+ return wlen;
34
+ }
35
+ function joinBytes(...arg) {
36
+ const totalLenght = arg.reduce((sum, curr) => sum + curr.length, 0);
37
+ const ret = new Uint8Array(totalLenght);
38
+ let cursor = 0;
39
+
40
+ for (let i = 0; i < arg.length; i++) {
41
+ ret.set(arg[i], cursor);
42
+ cursor += arg[i].length;
43
+ }
44
+
45
+ return ret;
46
+ }
47
+
48
+ /**
49
+ * @file {@link http://asmjs.org Asm.js} implementation of the {@link https://en.wikipedia.org/wiki/Advanced_Encryption_Standard Advanced Encryption Standard}.
50
+ * @author Artem S Vybornov <vybornov@gmail.com>
51
+ * @license MIT
52
+ */
53
+
54
+ /**
55
+ * Galois Field stuff init flag
56
+ */
57
+ let ginit_done = false;
58
+ /**
59
+ * Galois Field exponentiation and logarithm tables for 3 (the generator)
60
+ */
61
+
62
+ let gexp3;
63
+ let glog3;
64
+ /**
65
+ * Init Galois Field tables
66
+ */
67
+
68
+ function ginit() {
69
+ gexp3 = [];
70
+ glog3 = [];
71
+ let a = 1,
72
+ c,
73
+ d;
74
+
75
+ for (c = 0; c < 255; c++) {
76
+ gexp3[c] = a; // Multiply by three
77
+
78
+ d = a & 0x80, a <<= 1, a &= 255;
79
+ if (d === 0x80) a ^= 0x1b;
80
+ a ^= gexp3[c]; // Set the log table value
81
+
82
+ glog3[gexp3[c]] = c;
83
+ }
84
+
85
+ gexp3[255] = gexp3[0];
86
+ glog3[0] = 0;
87
+ ginit_done = true;
88
+ }
89
+ /**
90
+ * Galois Field multiplication
91
+ * @param {number} a
92
+ * @param {number} b
93
+ * @return {number}
94
+ */
95
+
96
+
97
+ function gmul(a, b) {
98
+ let c = gexp3[(glog3[a] + glog3[b]) % 255];
99
+ if (a === 0 || b === 0) c = 0;
100
+ return c;
101
+ }
102
+ /**
103
+ * Galois Field reciprocal
104
+ * @param {number} a
105
+ * @return {number}
106
+ */
107
+
108
+
109
+ function ginv(a) {
110
+ let i = gexp3[255 - glog3[a]];
111
+ if (a === 0) i = 0;
112
+ return i;
113
+ }
114
+ /**
115
+ * AES stuff init flag
116
+ */
117
+
118
+
119
+ let aes_init_done = false;
120
+ /**
121
+ * Encryption, Decryption, S-Box and KeyTransform tables
122
+ *
123
+ * @type {number[]}
124
+ */
125
+
126
+ let aes_sbox;
127
+ /**
128
+ * @type {number[]}
129
+ */
130
+
131
+ let aes_sinv;
132
+ /**
133
+ * @type {number[][]}
134
+ */
135
+
136
+ let aes_enc;
137
+ /**
138
+ * @type {number[][]}
139
+ */
140
+
141
+ let aes_dec;
142
+ /**
143
+ * Init AES tables
144
+ */
145
+
146
+ function aes_init() {
147
+ if (!ginit_done) ginit(); // Calculates AES S-Box value
148
+
149
+ function _s(a) {
150
+ let c, s, x;
151
+ s = x = ginv(a);
152
+
153
+ for (c = 0; c < 4; c++) {
154
+ s = (s << 1 | s >>> 7) & 255;
155
+ x ^= s;
156
+ }
157
+
158
+ x ^= 99;
159
+ return x;
160
+ } // Tables
161
+
162
+
163
+ aes_sbox = [], aes_sinv = [], aes_enc = [[], [], [], []], aes_dec = [[], [], [], []];
164
+
165
+ for (let i = 0; i < 256; i++) {
166
+ const s = _s(i); // S-Box and its inverse
167
+
168
+
169
+ aes_sbox[i] = s;
170
+ aes_sinv[s] = i; // Ecryption and Decryption tables
171
+
172
+ aes_enc[0][i] = gmul(2, s) << 24 | s << 16 | s << 8 | gmul(3, s);
173
+ aes_dec[0][s] = gmul(14, i) << 24 | gmul(9, i) << 16 | gmul(13, i) << 8 | gmul(11, i); // Rotate tables
174
+
175
+ for (let t = 1; t < 4; t++) {
176
+ aes_enc[t][i] = aes_enc[t - 1][i] >>> 8 | aes_enc[t - 1][i] << 24;
177
+ aes_dec[t][s] = aes_dec[t - 1][s] >>> 8 | aes_dec[t - 1][s] << 24;
178
+ }
179
+ }
180
+
181
+ aes_init_done = true;
182
+ }
183
+ /**
184
+ * Asm.js module constructor.
185
+ *
186
+ * <p>
187
+ * Heap buffer layout by offset:
188
+ * <pre>
189
+ * 0x0000 encryption key schedule
190
+ * 0x0400 decryption key schedule
191
+ * 0x0800 sbox
192
+ * 0x0c00 inv sbox
193
+ * 0x1000 encryption tables
194
+ * 0x2000 decryption tables
195
+ * 0x3000 reserved (future GCM multiplication lookup table)
196
+ * 0x4000 data
197
+ * </pre>
198
+ * Don't touch anything before <code>0x400</code>.
199
+ * </p>
200
+ *
201
+ * @alias AES_asm
202
+ * @class
203
+ * @param foreign - <i>ignored</i>
204
+ * @param buffer - heap buffer to link with
205
+ */
206
+
207
+
208
+ const wrapper = function wrapper(foreign, buffer) {
209
+ // Init AES stuff for the first time
210
+ if (!aes_init_done) aes_init(); // Fill up AES tables
211
+
212
+ const heap = new Uint32Array(buffer);
213
+ heap.set(aes_sbox, 0x0800 >> 2);
214
+ heap.set(aes_sinv, 0x0c00 >> 2);
215
+
216
+ for (let i = 0; i < 4; i++) {
217
+ heap.set(aes_enc[i], 0x1000 + 0x400 * i >> 2);
218
+ heap.set(aes_dec[i], 0x2000 + 0x400 * i >> 2);
219
+ }
220
+ /**
221
+ * Calculate AES key schedules.
222
+ * @instance
223
+ * @memberof AES_asm
224
+ * @param {number} ks - key size, 4/6/8 (for 128/192/256-bit key correspondingly)
225
+ * @param {number} k0 - key vector components
226
+ * @param {number} k1 - key vector components
227
+ * @param {number} k2 - key vector components
228
+ * @param {number} k3 - key vector components
229
+ * @param {number} k4 - key vector components
230
+ * @param {number} k5 - key vector components
231
+ * @param {number} k6 - key vector components
232
+ * @param {number} k7 - key vector components
233
+ */
234
+
235
+
236
+ function set_key(ks, k0, k1, k2, k3, k4, k5, k6, k7) {
237
+ const ekeys = heap.subarray(0x000, 60),
238
+ dkeys = heap.subarray(0x100, 0x100 + 60); // Encryption key schedule
239
+
240
+ ekeys.set([k0, k1, k2, k3, k4, k5, k6, k7]);
241
+ let i = ks;
242
+
243
+ for (let rcon = 1; i < 4 * ks + 28; i++) {
244
+ let k = ekeys[i - 1];
245
+
246
+ if (i % ks === 0 || ks === 8 && i % ks === 4) {
247
+ k = aes_sbox[k >>> 24] << 24 ^ aes_sbox[k >>> 16 & 255] << 16 ^ aes_sbox[k >>> 8 & 255] << 8 ^ aes_sbox[k & 255];
248
+ }
249
+
250
+ if (i % ks === 0) {
251
+ k = k << 8 ^ k >>> 24 ^ rcon << 24;
252
+ rcon = rcon << 1 ^ (rcon & 0x80 ? 0x1b : 0);
253
+ }
254
+
255
+ ekeys[i] = ekeys[i - ks] ^ k;
256
+ } // Decryption key schedule
257
+
258
+
259
+ for (let j = 0; j < i; j += 4) {
260
+ for (let jj = 0; jj < 4; jj++) {
261
+ const kk = ekeys[i - (4 + j) + (4 - jj) % 4];
262
+
263
+ if (j < 4 || j >= i - 4) {
264
+ dkeys[j + jj] = kk;
265
+ } else {
266
+ dkeys[j + jj] = aes_dec[0][aes_sbox[kk >>> 24]] ^ aes_dec[1][aes_sbox[kk >>> 16 & 255]] ^ aes_dec[2][aes_sbox[kk >>> 8 & 255]] ^ aes_dec[3][aes_sbox[kk & 255]];
267
+ }
268
+ }
269
+ } // Set rounds number
270
+
271
+
272
+ asm.set_rounds(ks + 5);
273
+ }
274
+
275
+ const asm = function (foreign, buffer) {
276
+ 'use asm';
277
+
278
+ let S0 = 0,
279
+ S1 = 0,
280
+ S2 = 0,
281
+ S3 = 0,
282
+ I0 = 0,
283
+ I1 = 0,
284
+ I2 = 0,
285
+ I3 = 0,
286
+ N0 = 0,
287
+ N1 = 0,
288
+ N2 = 0,
289
+ N3 = 0,
290
+ M0 = 0,
291
+ M1 = 0,
292
+ M2 = 0,
293
+ M3 = 0,
294
+ H0 = 0,
295
+ H1 = 0,
296
+ H2 = 0,
297
+ H3 = 0,
298
+ R = 0;
299
+ const HEAP = new Uint32Array(buffer),
300
+ DATA = new Uint8Array(buffer);
301
+ /**
302
+ * AES core
303
+ * @param {number} k - precomputed key schedule offset
304
+ * @param {number} s - precomputed sbox table offset
305
+ * @param {number} t - precomputed round table offset
306
+ * @param {number} r - number of inner rounds to perform
307
+ * @param {number} x0 - 128-bit input block vector
308
+ * @param {number} x1 - 128-bit input block vector
309
+ * @param {number} x2 - 128-bit input block vector
310
+ * @param {number} x3 - 128-bit input block vector
311
+ */
312
+
313
+ function _core(k, s, t, r, x0, x1, x2, x3) {
314
+ k = k | 0;
315
+ s = s | 0;
316
+ t = t | 0;
317
+ r = r | 0;
318
+ x0 = x0 | 0;
319
+ x1 = x1 | 0;
320
+ x2 = x2 | 0;
321
+ x3 = x3 | 0;
322
+ let t1 = 0,
323
+ t2 = 0,
324
+ t3 = 0,
325
+ y0 = 0,
326
+ y1 = 0,
327
+ y2 = 0,
328
+ y3 = 0,
329
+ i = 0;
330
+ t1 = t | 0x400, t2 = t | 0x800, t3 = t | 0xc00; // round 0
331
+
332
+ x0 = x0 ^ HEAP[(k | 0) >> 2], x1 = x1 ^ HEAP[(k | 4) >> 2], x2 = x2 ^ HEAP[(k | 8) >> 2], x3 = x3 ^ HEAP[(k | 12) >> 2]; // round 1..r
333
+
334
+ for (i = 16; (i | 0) <= r << 4; i = i + 16 | 0) {
335
+ y0 = HEAP[(t | x0 >> 22 & 1020) >> 2] ^ HEAP[(t1 | x1 >> 14 & 1020) >> 2] ^ HEAP[(t2 | x2 >> 6 & 1020) >> 2] ^ HEAP[(t3 | x3 << 2 & 1020) >> 2] ^ HEAP[(k | i | 0) >> 2], y1 = HEAP[(t | x1 >> 22 & 1020) >> 2] ^ HEAP[(t1 | x2 >> 14 & 1020) >> 2] ^ HEAP[(t2 | x3 >> 6 & 1020) >> 2] ^ HEAP[(t3 | x0 << 2 & 1020) >> 2] ^ HEAP[(k | i | 4) >> 2], y2 = HEAP[(t | x2 >> 22 & 1020) >> 2] ^ HEAP[(t1 | x3 >> 14 & 1020) >> 2] ^ HEAP[(t2 | x0 >> 6 & 1020) >> 2] ^ HEAP[(t3 | x1 << 2 & 1020) >> 2] ^ HEAP[(k | i | 8) >> 2], y3 = HEAP[(t | x3 >> 22 & 1020) >> 2] ^ HEAP[(t1 | x0 >> 14 & 1020) >> 2] ^ HEAP[(t2 | x1 >> 6 & 1020) >> 2] ^ HEAP[(t3 | x2 << 2 & 1020) >> 2] ^ HEAP[(k | i | 12) >> 2];
336
+ x0 = y0, x1 = y1, x2 = y2, x3 = y3;
337
+ } // final round
338
+
339
+
340
+ S0 = HEAP[(s | x0 >> 22 & 1020) >> 2] << 24 ^ HEAP[(s | x1 >> 14 & 1020) >> 2] << 16 ^ HEAP[(s | x2 >> 6 & 1020) >> 2] << 8 ^ HEAP[(s | x3 << 2 & 1020) >> 2] ^ HEAP[(k | i | 0) >> 2], S1 = HEAP[(s | x1 >> 22 & 1020) >> 2] << 24 ^ HEAP[(s | x2 >> 14 & 1020) >> 2] << 16 ^ HEAP[(s | x3 >> 6 & 1020) >> 2] << 8 ^ HEAP[(s | x0 << 2 & 1020) >> 2] ^ HEAP[(k | i | 4) >> 2], S2 = HEAP[(s | x2 >> 22 & 1020) >> 2] << 24 ^ HEAP[(s | x3 >> 14 & 1020) >> 2] << 16 ^ HEAP[(s | x0 >> 6 & 1020) >> 2] << 8 ^ HEAP[(s | x1 << 2 & 1020) >> 2] ^ HEAP[(k | i | 8) >> 2], S3 = HEAP[(s | x3 >> 22 & 1020) >> 2] << 24 ^ HEAP[(s | x0 >> 14 & 1020) >> 2] << 16 ^ HEAP[(s | x1 >> 6 & 1020) >> 2] << 8 ^ HEAP[(s | x2 << 2 & 1020) >> 2] ^ HEAP[(k | i | 12) >> 2];
341
+ }
342
+ /**
343
+ * ECB mode encryption
344
+ * @param {number} x0 - 128-bit input block vector
345
+ * @param {number} x1 - 128-bit input block vector
346
+ * @param {number} x2 - 128-bit input block vector
347
+ * @param {number} x3 - 128-bit input block vector
348
+ */
349
+
350
+
351
+ function _ecb_enc(x0, x1, x2, x3) {
352
+ x0 = x0 | 0;
353
+ x1 = x1 | 0;
354
+ x2 = x2 | 0;
355
+ x3 = x3 | 0;
356
+
357
+ _core(0x0000, 0x0800, 0x1000, R, x0, x1, x2, x3);
358
+ }
359
+ /**
360
+ * ECB mode decryption
361
+ * @param {number} x0 - 128-bit input block vector
362
+ * @param {number} x1 - 128-bit input block vector
363
+ * @param {number} x2 - 128-bit input block vector
364
+ * @param {number} x3 - 128-bit input block vector
365
+ */
366
+
367
+
368
+ function _ecb_dec(x0, x1, x2, x3) {
369
+ x0 = x0 | 0;
370
+ x1 = x1 | 0;
371
+ x2 = x2 | 0;
372
+ x3 = x3 | 0;
373
+ let t = 0;
374
+
375
+ _core(0x0400, 0x0c00, 0x2000, R, x0, x3, x2, x1);
376
+
377
+ t = S1, S1 = S3, S3 = t;
378
+ }
379
+ /**
380
+ * CBC mode encryption
381
+ * @param {number} x0 - 128-bit input block vector
382
+ * @param {number} x1 - 128-bit input block vector
383
+ * @param {number} x2 - 128-bit input block vector
384
+ * @param {number} x3 - 128-bit input block vector
385
+ */
386
+
387
+
388
+ function _cbc_enc(x0, x1, x2, x3) {
389
+ x0 = x0 | 0;
390
+ x1 = x1 | 0;
391
+ x2 = x2 | 0;
392
+ x3 = x3 | 0;
393
+
394
+ _core(0x0000, 0x0800, 0x1000, R, I0 ^ x0, I1 ^ x1, I2 ^ x2, I3 ^ x3);
395
+
396
+ I0 = S0, I1 = S1, I2 = S2, I3 = S3;
397
+ }
398
+ /**
399
+ * CBC mode decryption
400
+ * @param {number} x0 - 128-bit input block vector
401
+ * @param {number} x1 - 128-bit input block vector
402
+ * @param {number} x2 - 128-bit input block vector
403
+ * @param {number} x3 - 128-bit input block vector
404
+ */
405
+
406
+
407
+ function _cbc_dec(x0, x1, x2, x3) {
408
+ x0 = x0 | 0;
409
+ x1 = x1 | 0;
410
+ x2 = x2 | 0;
411
+ x3 = x3 | 0;
412
+ let t = 0;
413
+
414
+ _core(0x0400, 0x0c00, 0x2000, R, x0, x3, x2, x1);
415
+
416
+ t = S1, S1 = S3, S3 = t;
417
+ S0 = S0 ^ I0, S1 = S1 ^ I1, S2 = S2 ^ I2, S3 = S3 ^ I3;
418
+ I0 = x0, I1 = x1, I2 = x2, I3 = x3;
419
+ }
420
+ /**
421
+ * CFB mode encryption
422
+ * @param {number} x0 - 128-bit input block vector
423
+ * @param {number} x1 - 128-bit input block vector
424
+ * @param {number} x2 - 128-bit input block vector
425
+ * @param {number} x3 - 128-bit input block vector
426
+ */
427
+
428
+
429
+ function _cfb_enc(x0, x1, x2, x3) {
430
+ x0 = x0 | 0;
431
+ x1 = x1 | 0;
432
+ x2 = x2 | 0;
433
+ x3 = x3 | 0;
434
+
435
+ _core(0x0000, 0x0800, 0x1000, R, I0, I1, I2, I3);
436
+
437
+ I0 = S0 = S0 ^ x0, I1 = S1 = S1 ^ x1, I2 = S2 = S2 ^ x2, I3 = S3 = S3 ^ x3;
438
+ }
439
+ /**
440
+ * CFB mode decryption
441
+ * @param {number} x0 - 128-bit input block vector
442
+ * @param {number} x1 - 128-bit input block vector
443
+ * @param {number} x2 - 128-bit input block vector
444
+ * @param {number} x3 - 128-bit input block vector
445
+ */
446
+
447
+
448
+ function _cfb_dec(x0, x1, x2, x3) {
449
+ x0 = x0 | 0;
450
+ x1 = x1 | 0;
451
+ x2 = x2 | 0;
452
+ x3 = x3 | 0;
453
+
454
+ _core(0x0000, 0x0800, 0x1000, R, I0, I1, I2, I3);
455
+
456
+ S0 = S0 ^ x0, S1 = S1 ^ x1, S2 = S2 ^ x2, S3 = S3 ^ x3;
457
+ I0 = x0, I1 = x1, I2 = x2, I3 = x3;
458
+ }
459
+ /**
460
+ * OFB mode encryption / decryption
461
+ * @param {number} x0 - 128-bit input block vector
462
+ * @param {number} x1 - 128-bit input block vector
463
+ * @param {number} x2 - 128-bit input block vector
464
+ * @param {number} x3 - 128-bit input block vector
465
+ */
466
+
467
+
468
+ function _ofb(x0, x1, x2, x3) {
469
+ x0 = x0 | 0;
470
+ x1 = x1 | 0;
471
+ x2 = x2 | 0;
472
+ x3 = x3 | 0;
473
+
474
+ _core(0x0000, 0x0800, 0x1000, R, I0, I1, I2, I3);
475
+
476
+ I0 = S0, I1 = S1, I2 = S2, I3 = S3;
477
+ S0 = S0 ^ x0, S1 = S1 ^ x1, S2 = S2 ^ x2, S3 = S3 ^ x3;
478
+ }
479
+ /**
480
+ * CTR mode encryption / decryption
481
+ * @param {number} x0 - 128-bit input block vector
482
+ * @param {number} x1 - 128-bit input block vector
483
+ * @param {number} x2 - 128-bit input block vector
484
+ * @param {number} x3 - 128-bit input block vector
485
+ */
486
+
487
+
488
+ function _ctr(x0, x1, x2, x3) {
489
+ x0 = x0 | 0;
490
+ x1 = x1 | 0;
491
+ x2 = x2 | 0;
492
+ x3 = x3 | 0;
493
+
494
+ _core(0x0000, 0x0800, 0x1000, R, N0, N1, N2, N3);
495
+
496
+ N3 = ~M3 & N3 | M3 & N3 + 1;
497
+ N2 = ~M2 & N2 | M2 & N2 + Number((N3 | 0) === 0);
498
+ N1 = ~M1 & N1 | M1 & N1 + Number((N2 | 0) === 0);
499
+ N0 = ~M0 & N0 | M0 & N0 + Number((N1 | 0) === 0);
500
+ S0 = S0 ^ x0;
501
+ S1 = S1 ^ x1;
502
+ S2 = S2 ^ x2;
503
+ S3 = S3 ^ x3;
504
+ }
505
+ /**
506
+ * GCM mode MAC calculation
507
+ * @param {number} x0 - 128-bit input block vector
508
+ * @param {number} x1 - 128-bit input block vector
509
+ * @param {number} x2 - 128-bit input block vector
510
+ * @param {number} x3 - 128-bit input block vector
511
+ */
512
+
513
+
514
+ function _gcm_mac(x0, x1, x2, x3) {
515
+ x0 = x0 | 0;
516
+ x1 = x1 | 0;
517
+ x2 = x2 | 0;
518
+ x3 = x3 | 0;
519
+ let y0 = 0,
520
+ y1 = 0,
521
+ y2 = 0,
522
+ y3 = 0,
523
+ z0 = 0,
524
+ z1 = 0,
525
+ z2 = 0,
526
+ z3 = 0,
527
+ i = 0,
528
+ c = 0;
529
+ x0 = x0 ^ I0, x1 = x1 ^ I1, x2 = x2 ^ I2, x3 = x3 ^ I3;
530
+ y0 = H0 | 0, y1 = H1 | 0, y2 = H2 | 0, y3 = H3 | 0;
531
+
532
+ for (; (i | 0) < 128; i = i + 1 | 0) {
533
+ if (y0 >>> 31) {
534
+ z0 = z0 ^ x0, z1 = z1 ^ x1, z2 = z2 ^ x2, z3 = z3 ^ x3;
535
+ }
536
+
537
+ y0 = y0 << 1 | y1 >>> 31, y1 = y1 << 1 | y2 >>> 31, y2 = y2 << 1 | y3 >>> 31, y3 = y3 << 1;
538
+ c = x3 & 1;
539
+ x3 = x3 >>> 1 | x2 << 31, x2 = x2 >>> 1 | x1 << 31, x1 = x1 >>> 1 | x0 << 31, x0 = x0 >>> 1;
540
+ if (c) x0 = x0 ^ 0xe1000000;
541
+ }
542
+
543
+ I0 = z0, I1 = z1, I2 = z2, I3 = z3;
544
+ }
545
+ /**
546
+ * Set the internal rounds number.
547
+ * @instance
548
+ * @memberof AES_asm
549
+ * @param {number} r - number if inner AES rounds
550
+ */
551
+
552
+
553
+ function set_rounds(r) {
554
+ r = r | 0;
555
+ R = r;
556
+ }
557
+ /**
558
+ * Populate the internal state of the module.
559
+ * @instance
560
+ * @memberof AES_asm
561
+ * @param {number} s0 - state vector
562
+ * @param {number} s1 - state vector
563
+ * @param {number} s2 - state vector
564
+ * @param {number} s3 - state vector
565
+ */
566
+
567
+
568
+ function set_state(s0, s1, s2, s3) {
569
+ s0 = s0 | 0;
570
+ s1 = s1 | 0;
571
+ s2 = s2 | 0;
572
+ s3 = s3 | 0;
573
+ S0 = s0, S1 = s1, S2 = s2, S3 = s3;
574
+ }
575
+ /**
576
+ * Populate the internal iv of the module.
577
+ * @instance
578
+ * @memberof AES_asm
579
+ * @param {number} i0 - iv vector
580
+ * @param {number} i1 - iv vector
581
+ * @param {number} i2 - iv vector
582
+ * @param {number} i3 - iv vector
583
+ */
584
+
585
+
586
+ function set_iv(i0, i1, i2, i3) {
587
+ i0 = i0 | 0;
588
+ i1 = i1 | 0;
589
+ i2 = i2 | 0;
590
+ i3 = i3 | 0;
591
+ I0 = i0, I1 = i1, I2 = i2, I3 = i3;
592
+ }
593
+ /**
594
+ * Set nonce for CTR-family modes.
595
+ * @instance
596
+ * @memberof AES_asm
597
+ * @param {number} n0 - nonce vector
598
+ * @param {number} n1 - nonce vector
599
+ * @param {number} n2 - nonce vector
600
+ * @param {number} n3 - nonce vector
601
+ */
602
+
603
+
604
+ function set_nonce(n0, n1, n2, n3) {
605
+ n0 = n0 | 0;
606
+ n1 = n1 | 0;
607
+ n2 = n2 | 0;
608
+ n3 = n3 | 0;
609
+ N0 = n0, N1 = n1, N2 = n2, N3 = n3;
610
+ }
611
+ /**
612
+ * Set counter mask for CTR-family modes.
613
+ * @instance
614
+ * @memberof AES_asm
615
+ * @param {number} m0 - counter mask vector
616
+ * @param {number} m1 - counter mask vector
617
+ * @param {number} m2 - counter mask vector
618
+ * @param {number} m3 - counter mask vector
619
+ */
620
+
621
+
622
+ function set_mask(m0, m1, m2, m3) {
623
+ m0 = m0 | 0;
624
+ m1 = m1 | 0;
625
+ m2 = m2 | 0;
626
+ m3 = m3 | 0;
627
+ M0 = m0, M1 = m1, M2 = m2, M3 = m3;
628
+ }
629
+ /**
630
+ * Set counter for CTR-family modes.
631
+ * @instance
632
+ * @memberof AES_asm
633
+ * @param {number} c0 - counter vector
634
+ * @param {number} c1 - counter vector
635
+ * @param {number} c2 - counter vector
636
+ * @param {number} c3 - counter vector
637
+ */
638
+
639
+
640
+ function set_counter(c0, c1, c2, c3) {
641
+ c0 = c0 | 0;
642
+ c1 = c1 | 0;
643
+ c2 = c2 | 0;
644
+ c3 = c3 | 0;
645
+ N3 = ~M3 & N3 | M3 & c3, N2 = ~M2 & N2 | M2 & c2, N1 = ~M1 & N1 | M1 & c1, N0 = ~M0 & N0 | M0 & c0;
646
+ }
647
+ /**
648
+ * Store the internal state vector into the heap.
649
+ * @instance
650
+ * @memberof AES_asm
651
+ * @param {number} pos - offset where to put the data
652
+ * @return {number} The number of bytes have been written into the heap, always 16.
653
+ */
654
+
655
+
656
+ function get_state(pos) {
657
+ pos = pos | 0;
658
+ if (pos & 15) return -1;
659
+ DATA[pos | 0] = S0 >>> 24, DATA[pos | 1] = S0 >>> 16 & 255, DATA[pos | 2] = S0 >>> 8 & 255, DATA[pos | 3] = S0 & 255, DATA[pos | 4] = S1 >>> 24, DATA[pos | 5] = S1 >>> 16 & 255, DATA[pos | 6] = S1 >>> 8 & 255, DATA[pos | 7] = S1 & 255, DATA[pos | 8] = S2 >>> 24, DATA[pos | 9] = S2 >>> 16 & 255, DATA[pos | 10] = S2 >>> 8 & 255, DATA[pos | 11] = S2 & 255, DATA[pos | 12] = S3 >>> 24, DATA[pos | 13] = S3 >>> 16 & 255, DATA[pos | 14] = S3 >>> 8 & 255, DATA[pos | 15] = S3 & 255;
660
+ return 16;
661
+ }
662
+ /**
663
+ * Store the internal iv vector into the heap.
664
+ * @instance
665
+ * @memberof AES_asm
666
+ * @param {number} pos - offset where to put the data
667
+ * @return {number} The number of bytes have been written into the heap, always 16.
668
+ */
669
+
670
+
671
+ function get_iv(pos) {
672
+ pos = pos | 0;
673
+ if (pos & 15) return -1;
674
+ DATA[pos | 0] = I0 >>> 24, DATA[pos | 1] = I0 >>> 16 & 255, DATA[pos | 2] = I0 >>> 8 & 255, DATA[pos | 3] = I0 & 255, DATA[pos | 4] = I1 >>> 24, DATA[pos | 5] = I1 >>> 16 & 255, DATA[pos | 6] = I1 >>> 8 & 255, DATA[pos | 7] = I1 & 255, DATA[pos | 8] = I2 >>> 24, DATA[pos | 9] = I2 >>> 16 & 255, DATA[pos | 10] = I2 >>> 8 & 255, DATA[pos | 11] = I2 & 255, DATA[pos | 12] = I3 >>> 24, DATA[pos | 13] = I3 >>> 16 & 255, DATA[pos | 14] = I3 >>> 8 & 255, DATA[pos | 15] = I3 & 255;
675
+ return 16;
676
+ }
677
+ /**
678
+ * GCM initialization.
679
+ * @instance
680
+ * @memberof AES_asm
681
+ */
682
+
683
+
684
+ function gcm_init() {
685
+ _ecb_enc(0, 0, 0, 0);
686
+
687
+ H0 = S0, H1 = S1, H2 = S2, H3 = S3;
688
+ }
689
+ /**
690
+ * Perform ciphering operation on the supplied data.
691
+ * @instance
692
+ * @memberof AES_asm
693
+ * @param {number} mode - block cipher mode (see {@link AES_asm} mode constants)
694
+ * @param {number} pos - offset of the data being processed
695
+ * @param {number} len - length of the data being processed
696
+ * @return {number} Actual amount of data have been processed.
697
+ */
698
+
699
+
700
+ function cipher(mode, pos, len) {
701
+ mode = mode | 0;
702
+ pos = pos | 0;
703
+ len = len | 0;
704
+ let ret = 0;
705
+ if (pos & 15) return -1;
706
+
707
+ while ((len | 0) >= 16) {
708
+ _cipher_modes[mode & 7](DATA[pos | 0] << 24 | DATA[pos | 1] << 16 | DATA[pos | 2] << 8 | DATA[pos | 3], DATA[pos | 4] << 24 | DATA[pos | 5] << 16 | DATA[pos | 6] << 8 | DATA[pos | 7], DATA[pos | 8] << 24 | DATA[pos | 9] << 16 | DATA[pos | 10] << 8 | DATA[pos | 11], DATA[pos | 12] << 24 | DATA[pos | 13] << 16 | DATA[pos | 14] << 8 | DATA[pos | 15]);
709
+
710
+ DATA[pos | 0] = S0 >>> 24, DATA[pos | 1] = S0 >>> 16 & 255, DATA[pos | 2] = S0 >>> 8 & 255, DATA[pos | 3] = S0 & 255, DATA[pos | 4] = S1 >>> 24, DATA[pos | 5] = S1 >>> 16 & 255, DATA[pos | 6] = S1 >>> 8 & 255, DATA[pos | 7] = S1 & 255, DATA[pos | 8] = S2 >>> 24, DATA[pos | 9] = S2 >>> 16 & 255, DATA[pos | 10] = S2 >>> 8 & 255, DATA[pos | 11] = S2 & 255, DATA[pos | 12] = S3 >>> 24, DATA[pos | 13] = S3 >>> 16 & 255, DATA[pos | 14] = S3 >>> 8 & 255, DATA[pos | 15] = S3 & 255;
711
+ ret = ret + 16 | 0, pos = pos + 16 | 0, len = len - 16 | 0;
712
+ }
713
+
714
+ return ret | 0;
715
+ }
716
+ /**
717
+ * Calculates MAC of the supplied data.
718
+ * @instance
719
+ * @memberof AES_asm
720
+ * @param {number} mode - block cipher mode (see {@link AES_asm} mode constants)
721
+ * @param {number} pos - offset of the data being processed
722
+ * @param {number} len - length of the data being processed
723
+ * @return {number} Actual amount of data have been processed.
724
+ */
725
+
726
+
727
+ function mac(mode, pos, len) {
728
+ mode = mode | 0;
729
+ pos = pos | 0;
730
+ len = len | 0;
731
+ let ret = 0;
732
+ if (pos & 15) return -1;
733
+
734
+ while ((len | 0) >= 16) {
735
+ _mac_modes[mode & 1](DATA[pos | 0] << 24 | DATA[pos | 1] << 16 | DATA[pos | 2] << 8 | DATA[pos | 3], DATA[pos | 4] << 24 | DATA[pos | 5] << 16 | DATA[pos | 6] << 8 | DATA[pos | 7], DATA[pos | 8] << 24 | DATA[pos | 9] << 16 | DATA[pos | 10] << 8 | DATA[pos | 11], DATA[pos | 12] << 24 | DATA[pos | 13] << 16 | DATA[pos | 14] << 8 | DATA[pos | 15]);
736
+
737
+ ret = ret + 16 | 0, pos = pos + 16 | 0, len = len - 16 | 0;
738
+ }
739
+
740
+ return ret | 0;
741
+ }
742
+ /**
743
+ * AES cipher modes table (virual methods)
744
+ */
745
+
746
+
747
+ const _cipher_modes = [_ecb_enc, _ecb_dec, _cbc_enc, _cbc_dec, _cfb_enc, _cfb_dec, _ofb, _ctr];
748
+ /**
749
+ * AES MAC modes table (virual methods)
750
+ */
751
+
752
+ const _mac_modes = [_cbc_enc, _gcm_mac];
753
+ /**
754
+ * Asm.js module exports
755
+ */
756
+
757
+ return {
758
+ set_rounds: set_rounds,
759
+ set_state: set_state,
760
+ set_iv: set_iv,
761
+ set_nonce: set_nonce,
762
+ set_mask: set_mask,
763
+ set_counter: set_counter,
764
+ get_state: get_state,
765
+ get_iv: get_iv,
766
+ gcm_init: gcm_init,
767
+ cipher: cipher,
768
+ mac: mac,
769
+ set_key
770
+ };
771
+ }(foreign, buffer);
772
+
773
+ return asm;
774
+ };
775
+
776
+ class AES_asm {
777
+ constructor(foreign, heap) {
778
+ return wrapper(foreign, heap);
779
+ }
780
+ /**
781
+ * @param ks - key size, 4/6/8 (for 128/192/256-bit key correspondingly)
782
+ * @param k0 - key vector components
783
+ * @param k1 - key vector components
784
+ * @param k2 - key vector components
785
+ * @param k3 - key vector components
786
+ * @param k4 - key vector components
787
+ * @param k5 - key vector components
788
+ * @param k6 - key vector components
789
+ * @param k7 - key vector components
790
+ */
791
+
792
+
793
+ set_key(ks, k0, k1, k2, k3, k4, k5, k6, k7) {// 此处不需要实现
794
+ }
795
+
796
+ /**
797
+ * Populate the internal iv of the module
798
+ */
799
+ set_iv(i0, i1, i2, i3) {// 此处不需要实现
800
+ }
801
+ /**
802
+ * Set counter mask for CTR-family modes
803
+ */
804
+
805
+
806
+ set_mask(m0, m1, m2, m3) {// 此处不需要实现
807
+ }
808
+ /**
809
+ * Set nonce for CTR-family modes
810
+ */
811
+
812
+
813
+ set_nonce(n0, n1, n2, n3) {// 此处不需要实现
814
+ }
815
+
816
+ /**
817
+ * Set counter for CTR-family modes
818
+ */
819
+ set_counter(c0, c1, c2, c3) {// 此处不需要实现
820
+ }
821
+
822
+ /**
823
+ * Perform ciphering operation on the supplied data
824
+ *
825
+ * @param mode - block cipher mode (see {@link AES_asm} mode constants)
826
+ * @param pos - offset of the data being processed
827
+ * @param len - length of the data being processed
828
+ * @return Actual amount of data have been processed
829
+ */
830
+ cipher(mode, pos, len) {
831
+ // 此处实现忽略
832
+ return 0;
833
+ }
834
+ /**
835
+ * GCM initialization
836
+ */
837
+
838
+
839
+ gcm_init() {// 此处不需要实现
840
+ }
841
+ /**
842
+ * Store the internal iv vector into the heap
843
+ *
844
+ * @returns The number of bytes have been written into the heap, always 16
845
+ */
846
+
847
+
848
+ get_iv(pos) {
849
+ // 此处实现忽略
850
+ return 16;
851
+ }
852
+ /**
853
+ * Calculates MAC of the supplied data
854
+ *
855
+ * @param mode - block cipher mode (see {@link AES_asm} mode constants)
856
+ * @param pos - offset of the data being processed
857
+ * @param len - length of the data being processed
858
+ * @return Actual amount of data have been processed
859
+ */
860
+
861
+
862
+ mac(mode, pos, len) {
863
+ // 此处实现忽略
864
+ return 0;
865
+ }
866
+ /**
867
+ * Store the internal state vector into the heap.
868
+ *
869
+ * @param pos - offset where to put the data
870
+ * @return The number of bytes have been written into the heap, always 16.
871
+ */
872
+
873
+
874
+ get_state(pos) {
875
+ // 此处实现忽略
876
+ return 16;
877
+ }
878
+
879
+ }
880
+ /**
881
+ * AES enciphering mode constants
882
+ * @enum {number}
883
+ * @const
884
+ */
885
+
886
+ AES_asm.ENC = {
887
+ ECB: 0,
888
+ CBC: 2,
889
+ CFB: 4,
890
+ OFB: 6,
891
+ CTR: 7
892
+ };
893
+ /**
894
+ * AES deciphering mode constants
895
+ * @enum {number}
896
+ * @const
897
+ */
898
+
899
+ AES_asm.DEC = {
900
+ ECB: 1,
901
+ CBC: 3,
902
+ CFB: 5,
903
+ OFB: 6,
904
+ CTR: 7
905
+ };
906
+ /**
907
+ * AES MAC mode constants
908
+ * @enum {number}
909
+ * @const
910
+ */
911
+
912
+ AES_asm.MAC = {
913
+ CBC: 0,
914
+ GCM: 1
915
+ };
916
+ /**
917
+ * Heap data offset
918
+ * @type {number}
919
+ * @const
920
+ */
921
+
922
+ AES_asm.HEAP_DATA = 0x4000;
923
+
924
+ class AES {
925
+ constructor(key, iv, padding = true, mode, heap, asm) {
926
+ this.pos = 0;
927
+ this.len = 0;
928
+ this.mode = mode; // The AES "worker"
929
+
930
+ this.heap = heap ? heap : _heap_init().subarray(AES_asm.HEAP_DATA);
931
+ this.asm = asm ? asm : new AES_asm(null, this.heap.buffer); // The AES object state
932
+
933
+ this.pos = 0;
934
+ this.len = 0; // Key
935
+
936
+ const keylen = key.length;
937
+ if (keylen !== 16 && keylen !== 24 && keylen !== 32) throw new IllegalArgumentError('illegal key size');
938
+ const keyview = new DataView(key.buffer, key.byteOffset, key.byteLength);
939
+ this.asm.set_key(keylen >> 2, keyview.getUint32(0), keyview.getUint32(4), keyview.getUint32(8), keyview.getUint32(12), keylen > 16 ? keyview.getUint32(16) : 0, keylen > 16 ? keyview.getUint32(20) : 0, keylen > 24 ? keyview.getUint32(24) : 0, keylen > 24 ? keyview.getUint32(28) : 0); // IV
940
+
941
+ if (iv !== undefined) {
942
+ if (iv.length !== 16) throw new IllegalArgumentError('illegal iv size');
943
+ const ivview = new DataView(iv.buffer, iv.byteOffset, iv.byteLength);
944
+ this.asm.set_iv(ivview.getUint32(0), ivview.getUint32(4), ivview.getUint32(8), ivview.getUint32(12));
945
+ } else {
946
+ this.asm.set_iv(0, 0, 0, 0);
947
+ }
948
+
949
+ this.padding = padding;
950
+ }
951
+
952
+ AES_Encrypt_process(data) {
953
+ if (!is_bytes(data)) throw new TypeError("data isn't of expected type");
954
+ const asm = this.asm;
955
+ const heap = this.heap;
956
+ const amode = AES_asm.ENC[this.mode];
957
+ const hpos = AES_asm.HEAP_DATA;
958
+ let pos = this.pos;
959
+ let len = this.len;
960
+ let dpos = 0;
961
+ let dlen = data.length || 0;
962
+ let rpos = 0;
963
+ const rlen = len + dlen & -16;
964
+ let wlen = 0;
965
+ const result = new Uint8Array(rlen);
966
+
967
+ while (dlen > 0) {
968
+ wlen = _heap_write(heap, pos + len, data, dpos, dlen);
969
+ len += wlen;
970
+ dpos += wlen;
971
+ dlen -= wlen;
972
+ wlen = asm.cipher(amode, hpos + pos, len);
973
+ if (wlen) result.set(heap.subarray(pos, pos + wlen), rpos);
974
+ rpos += wlen;
975
+
976
+ if (wlen < len) {
977
+ pos += wlen;
978
+ len -= wlen;
979
+ } else {
980
+ pos = 0;
981
+ len = 0;
982
+ }
983
+ }
984
+
985
+ this.pos = pos;
986
+ this.len = len;
987
+ return result;
988
+ }
989
+
990
+ AES_Encrypt_finish() {
991
+ const asm = this.asm;
992
+ const heap = this.heap;
993
+ const amode = AES_asm.ENC[this.mode];
994
+ const hpos = AES_asm.HEAP_DATA;
995
+ const pos = this.pos;
996
+ let len = this.len;
997
+ const plen = 16 - len % 16;
998
+ let rlen = len; // eslint-disable-next-line no-prototype-builtins
999
+
1000
+ if (this.hasOwnProperty('padding')) {
1001
+ if (this.padding) {
1002
+ for (let p = 0; p < plen; ++p) {
1003
+ heap[pos + len + p] = plen;
1004
+ }
1005
+
1006
+ len += plen;
1007
+ rlen = len;
1008
+ } else if (len % 16) {
1009
+ throw new IllegalArgumentError('data length must be a multiple of the block size');
1010
+ }
1011
+ } else {
1012
+ len += plen;
1013
+ }
1014
+
1015
+ const result = new Uint8Array(rlen);
1016
+ if (len) asm.cipher(amode, hpos + pos, len);
1017
+ if (rlen) result.set(heap.subarray(pos, pos + rlen));
1018
+ this.pos = 0;
1019
+ this.len = 0;
1020
+ return result;
1021
+ }
1022
+
1023
+ AES_Decrypt_process(data) {
1024
+ if (!is_bytes(data)) throw new TypeError("data isn't of expected type");
1025
+ const asm = this.asm;
1026
+ const heap = this.heap;
1027
+ const amode = AES_asm.DEC[this.mode];
1028
+ const hpos = AES_asm.HEAP_DATA;
1029
+ let pos = this.pos;
1030
+ let len = this.len;
1031
+ let dpos = 0;
1032
+ let dlen = data.length || 0;
1033
+ let rpos = 0;
1034
+ let rlen = len + dlen & -16;
1035
+ let plen = 0;
1036
+ let wlen = 0;
1037
+
1038
+ if (this.padding) {
1039
+ plen = len + dlen - rlen || 16;
1040
+ rlen -= plen;
1041
+ }
1042
+
1043
+ const result = new Uint8Array(rlen);
1044
+
1045
+ while (dlen > 0) {
1046
+ wlen = _heap_write(heap, pos + len, data, dpos, dlen);
1047
+ len += wlen;
1048
+ dpos += wlen;
1049
+ dlen -= wlen;
1050
+ wlen = asm.cipher(amode, hpos + pos, len - (!dlen ? plen : 0));
1051
+ if (wlen) result.set(heap.subarray(pos, pos + wlen), rpos);
1052
+ rpos += wlen;
1053
+
1054
+ if (wlen < len) {
1055
+ pos += wlen;
1056
+ len -= wlen;
1057
+ } else {
1058
+ pos = 0;
1059
+ len = 0;
1060
+ }
1061
+ }
1062
+
1063
+ this.pos = pos;
1064
+ this.len = len;
1065
+ return result;
1066
+ }
1067
+
1068
+ AES_Decrypt_finish() {
1069
+ const asm = this.asm;
1070
+ const heap = this.heap;
1071
+ const amode = AES_asm.DEC[this.mode];
1072
+ const hpos = AES_asm.HEAP_DATA;
1073
+ const pos = this.pos;
1074
+ let len = this.len;
1075
+ let rlen = len;
1076
+
1077
+ if (len > 0) {
1078
+ if (len % 16) {
1079
+ // eslint-disable-next-line no-prototype-builtins
1080
+ if (this.hasOwnProperty('padding')) {
1081
+ throw new IllegalArgumentError('data length must be a multiple of the block size');
1082
+ } else {
1083
+ len += 16 - len % 16;
1084
+ }
1085
+ }
1086
+
1087
+ asm.cipher(amode, hpos + pos, len); // eslint-disable-next-line no-prototype-builtins
1088
+
1089
+ if (this.hasOwnProperty('padding') && this.padding) {
1090
+ const pad = heap[pos + rlen - 1];
1091
+ if (pad < 1 || pad > 16 || pad > rlen) throw new SecurityError('bad padding');
1092
+ let pcheck = 0;
1093
+
1094
+ for (let i = pad; i > 1; i--) pcheck |= pad ^ heap[pos + rlen - i];
1095
+
1096
+ if (pcheck) throw new SecurityError('bad padding');
1097
+ rlen -= pad;
1098
+ }
1099
+ }
1100
+
1101
+ const result = new Uint8Array(rlen);
1102
+
1103
+ if (rlen > 0) {
1104
+ result.set(heap.subarray(pos, pos + rlen));
1105
+ }
1106
+
1107
+ this.pos = 0;
1108
+ this.len = 0;
1109
+ return result;
1110
+ }
1111
+
1112
+ }
1113
+
1114
+ const _AES_GCM_data_maxLength = 68719476704; // 2^36 - 2^5
1115
+
1116
+ class AES_GCM {
1117
+ constructor(key, nonce, adata, tagSize = 16, aes) {
1118
+ this.tagSize = tagSize;
1119
+ this.gamma0 = 0;
1120
+ this.counter = 1;
1121
+ this.aes = aes ? aes : new AES(key, undefined, false, 'CTR'); // Init GCM
1122
+
1123
+ this.aes.asm.gcm_init(); // Tag size
1124
+
1125
+ if (this.tagSize < 4 || this.tagSize > 16) throw new IllegalArgumentError('illegal tagSize value'); // Nonce
1126
+
1127
+ const noncelen = nonce.length || 0;
1128
+ const noncebuf = new Uint8Array(16);
1129
+
1130
+ if (noncelen !== 12) {
1131
+ this._gcm_mac_process(nonce);
1132
+
1133
+ this.aes.heap[0] = 0;
1134
+ this.aes.heap[1] = 0;
1135
+ this.aes.heap[2] = 0;
1136
+ this.aes.heap[3] = 0;
1137
+ this.aes.heap[4] = 0;
1138
+ this.aes.heap[5] = 0;
1139
+ this.aes.heap[6] = 0;
1140
+ this.aes.heap[7] = 0;
1141
+ this.aes.heap[8] = 0;
1142
+ this.aes.heap[9] = 0;
1143
+ this.aes.heap[10] = 0;
1144
+ this.aes.heap[11] = noncelen >>> 29;
1145
+ this.aes.heap[12] = noncelen >>> 21 & 255;
1146
+ this.aes.heap[13] = noncelen >>> 13 & 255;
1147
+ this.aes.heap[14] = noncelen >>> 5 & 255;
1148
+ this.aes.heap[15] = noncelen << 3 & 255;
1149
+ this.aes.asm.mac(AES_asm.MAC.GCM, AES_asm.HEAP_DATA, 16);
1150
+ this.aes.asm.get_iv(AES_asm.HEAP_DATA);
1151
+ this.aes.asm.set_iv(0, 0, 0, 0);
1152
+ noncebuf.set(this.aes.heap.subarray(0, 16));
1153
+ } else {
1154
+ noncebuf.set(nonce);
1155
+ noncebuf[15] = 1;
1156
+ }
1157
+
1158
+ const nonceview = new DataView(noncebuf.buffer);
1159
+ this.gamma0 = nonceview.getUint32(12);
1160
+ this.aes.asm.set_nonce(nonceview.getUint32(0), nonceview.getUint32(4), nonceview.getUint32(8), 0);
1161
+ this.aes.asm.set_mask(0, 0, 0, 0xffffffff); // Associated data
1162
+
1163
+ if (adata !== undefined) {
1164
+ if (adata.length > _AES_GCM_data_maxLength) throw new IllegalArgumentError('illegal adata length');
1165
+
1166
+ if (adata.length) {
1167
+ this.adata = adata;
1168
+
1169
+ this._gcm_mac_process(adata);
1170
+ } else {
1171
+ this.adata = undefined;
1172
+ }
1173
+ } else {
1174
+ this.adata = undefined;
1175
+ } // Counter
1176
+
1177
+
1178
+ if (this.counter < 1 || this.counter > 0xffffffff) throw new RangeError('counter must be a positive 32-bit integer');
1179
+ this.aes.asm.set_counter(0, 0, 0, this.gamma0 + this.counter | 0);
1180
+ }
1181
+
1182
+ static encrypt(cleartext, key, nonce, adata, tagsize) {
1183
+ return new AES_GCM(key, nonce, adata, tagsize).encrypt(cleartext);
1184
+ }
1185
+
1186
+ static decrypt(ciphertext, key, nonce, adata, tagsize) {
1187
+ return new AES_GCM(key, nonce, adata, tagsize).decrypt(ciphertext);
1188
+ }
1189
+
1190
+ encrypt(data) {
1191
+ return this.AES_GCM_encrypt(data);
1192
+ }
1193
+
1194
+ decrypt(data) {
1195
+ return this.AES_GCM_decrypt(data);
1196
+ }
1197
+
1198
+ AES_GCM_Encrypt_process(data) {
1199
+ let dpos = 0;
1200
+ let dlen = data.length || 0;
1201
+ const asm = this.aes.asm;
1202
+ const heap = this.aes.heap;
1203
+ let counter = this.counter;
1204
+ let pos = this.aes.pos;
1205
+ let len = this.aes.len;
1206
+ let rpos = 0;
1207
+ const rlen = len + dlen & -16;
1208
+ let wlen = 0;
1209
+ if ((counter - 1 << 4) + len + dlen > _AES_GCM_data_maxLength) throw new RangeError('counter overflow');
1210
+ const result = new Uint8Array(rlen);
1211
+
1212
+ while (dlen > 0) {
1213
+ wlen = _heap_write(heap, pos + len, data, dpos, dlen);
1214
+ len += wlen;
1215
+ dpos += wlen;
1216
+ dlen -= wlen;
1217
+ wlen = asm.cipher(AES_asm.ENC.CTR, AES_asm.HEAP_DATA + pos, len);
1218
+ wlen = asm.mac(AES_asm.MAC.GCM, AES_asm.HEAP_DATA + pos, wlen);
1219
+ if (wlen) result.set(heap.subarray(pos, pos + wlen), rpos);
1220
+ counter += wlen >>> 4;
1221
+ rpos += wlen;
1222
+
1223
+ if (wlen < len) {
1224
+ pos += wlen;
1225
+ len -= wlen;
1226
+ } else {
1227
+ pos = 0;
1228
+ len = 0;
1229
+ }
1230
+ }
1231
+
1232
+ this.counter = counter;
1233
+ this.aes.pos = pos;
1234
+ this.aes.len = len;
1235
+ return result;
1236
+ }
1237
+
1238
+ AES_GCM_Encrypt_finish() {
1239
+ const asm = this.aes.asm;
1240
+ const heap = this.aes.heap;
1241
+ const counter = this.counter;
1242
+ const tagSize = this.tagSize;
1243
+ const adata = this.adata;
1244
+ const pos = this.aes.pos;
1245
+ const len = this.aes.len;
1246
+ const result = new Uint8Array(len + tagSize);
1247
+ asm.cipher(AES_asm.ENC.CTR, AES_asm.HEAP_DATA + pos, len + 15 & -16);
1248
+ if (len) result.set(heap.subarray(pos, pos + len));
1249
+ let i = len;
1250
+
1251
+ for (; i & 15; i++) heap[pos + i] = 0;
1252
+
1253
+ asm.mac(AES_asm.MAC.GCM, AES_asm.HEAP_DATA + pos, i);
1254
+ const alen = adata !== undefined ? adata.length : 0;
1255
+ const clen = (counter - 1 << 4) + len;
1256
+ heap[0] = 0;
1257
+ heap[1] = 0;
1258
+ heap[2] = 0;
1259
+ heap[3] = alen >>> 29;
1260
+ heap[4] = alen >>> 21;
1261
+ heap[5] = alen >>> 13 & 255;
1262
+ heap[6] = alen >>> 5 & 255;
1263
+ heap[7] = alen << 3 & 255;
1264
+ heap[8] = heap[9] = heap[10] = 0;
1265
+ heap[11] = clen >>> 29;
1266
+ heap[12] = clen >>> 21 & 255;
1267
+ heap[13] = clen >>> 13 & 255;
1268
+ heap[14] = clen >>> 5 & 255;
1269
+ heap[15] = clen << 3 & 255;
1270
+ asm.mac(AES_asm.MAC.GCM, AES_asm.HEAP_DATA, 16);
1271
+ asm.get_iv(AES_asm.HEAP_DATA);
1272
+ asm.set_counter(0, 0, 0, this.gamma0);
1273
+ asm.cipher(AES_asm.ENC.CTR, AES_asm.HEAP_DATA, 16);
1274
+ result.set(heap.subarray(0, tagSize), len);
1275
+ this.counter = 1;
1276
+ this.aes.pos = 0;
1277
+ this.aes.len = 0;
1278
+ return result;
1279
+ }
1280
+
1281
+ AES_GCM_Decrypt_process(data) {
1282
+ let dpos = 0;
1283
+ let dlen = data.length || 0;
1284
+ const asm = this.aes.asm;
1285
+ const heap = this.aes.heap;
1286
+ let counter = this.counter;
1287
+ const tagSize = this.tagSize;
1288
+ let pos = this.aes.pos;
1289
+ let len = this.aes.len;
1290
+ let rpos = 0;
1291
+ const rlen = len + dlen > tagSize ? len + dlen - tagSize & -16 : 0;
1292
+ const tlen = len + dlen - rlen;
1293
+ let wlen = 0;
1294
+ if ((counter - 1 << 4) + len + dlen > _AES_GCM_data_maxLength) throw new RangeError('counter overflow');
1295
+ const result = new Uint8Array(rlen);
1296
+
1297
+ while (dlen > tlen) {
1298
+ wlen = _heap_write(heap, pos + len, data, dpos, dlen - tlen);
1299
+ len += wlen;
1300
+ dpos += wlen;
1301
+ dlen -= wlen;
1302
+ wlen = asm.mac(AES_asm.MAC.GCM, AES_asm.HEAP_DATA + pos, wlen);
1303
+ wlen = asm.cipher(AES_asm.DEC.CTR, AES_asm.HEAP_DATA + pos, wlen);
1304
+ if (wlen) result.set(heap.subarray(pos, pos + wlen), rpos);
1305
+ counter += wlen >>> 4;
1306
+ rpos += wlen;
1307
+ pos = 0;
1308
+ len = 0;
1309
+ }
1310
+
1311
+ if (dlen > 0) {
1312
+ len += _heap_write(heap, 0, data, dpos, dlen);
1313
+ }
1314
+
1315
+ this.counter = counter;
1316
+ this.aes.pos = pos;
1317
+ this.aes.len = len;
1318
+ return result;
1319
+ }
1320
+
1321
+ AES_GCM_Decrypt_finish() {
1322
+ const asm = this.aes.asm;
1323
+ const heap = this.aes.heap;
1324
+ const tagSize = this.tagSize;
1325
+ const adata = this.adata;
1326
+ const counter = this.counter;
1327
+ const pos = this.aes.pos;
1328
+ const len = this.aes.len;
1329
+ const rlen = len - tagSize;
1330
+ if (len < tagSize) throw new IllegalStateError('authentication tag not found');
1331
+ const result = new Uint8Array(rlen);
1332
+ const atag = new Uint8Array(heap.subarray(pos + rlen, pos + len));
1333
+ let i = rlen;
1334
+
1335
+ for (; i & 15; i++) heap[pos + i] = 0;
1336
+
1337
+ asm.mac(AES_asm.MAC.GCM, AES_asm.HEAP_DATA + pos, i);
1338
+ asm.cipher(AES_asm.DEC.CTR, AES_asm.HEAP_DATA + pos, i);
1339
+ if (rlen) result.set(heap.subarray(pos, pos + rlen));
1340
+ const alen = adata !== undefined ? adata.length : 0;
1341
+ const clen = (counter - 1 << 4) + len - tagSize;
1342
+ heap[0] = 0;
1343
+ heap[1] = 0;
1344
+ heap[2] = 0;
1345
+ heap[3] = alen >>> 29;
1346
+ heap[4] = alen >>> 21;
1347
+ heap[5] = alen >>> 13 & 255;
1348
+ heap[6] = alen >>> 5 & 255;
1349
+ heap[7] = alen << 3 & 255;
1350
+ heap[8] = heap[9] = heap[10] = 0;
1351
+ heap[11] = clen >>> 29;
1352
+ heap[12] = clen >>> 21 & 255;
1353
+ heap[13] = clen >>> 13 & 255;
1354
+ heap[14] = clen >>> 5 & 255;
1355
+ heap[15] = clen << 3 & 255;
1356
+ asm.mac(AES_asm.MAC.GCM, AES_asm.HEAP_DATA, 16);
1357
+ asm.get_iv(AES_asm.HEAP_DATA);
1358
+ asm.set_counter(0, 0, 0, this.gamma0);
1359
+ asm.cipher(AES_asm.ENC.CTR, AES_asm.HEAP_DATA, 16);
1360
+ let acheck = 0;
1361
+
1362
+ for (let _i = 0; _i < tagSize; ++_i) acheck |= atag[_i] ^ heap[_i];
1363
+
1364
+ if (acheck) throw new SecurityError('data integrity check failed');
1365
+ this.counter = 1;
1366
+ this.aes.pos = 0;
1367
+ this.aes.len = 0;
1368
+ return result;
1369
+ }
1370
+
1371
+ AES_GCM_decrypt(data) {
1372
+ const result1 = this.AES_GCM_Decrypt_process(data);
1373
+ const result2 = this.AES_GCM_Decrypt_finish();
1374
+ const result = new Uint8Array(result1.length + result2.length);
1375
+ if (result1.length) result.set(result1);
1376
+ if (result2.length) result.set(result2, result1.length);
1377
+ return result;
1378
+ }
1379
+
1380
+ AES_GCM_encrypt(data) {
1381
+ const result1 = this.AES_GCM_Encrypt_process(data);
1382
+ const result2 = this.AES_GCM_Encrypt_finish();
1383
+ const result = new Uint8Array(result1.length + result2.length);
1384
+ if (result1.length) result.set(result1);
1385
+ if (result2.length) result.set(result2, result1.length);
1386
+ return result;
1387
+ }
1388
+
1389
+ _gcm_mac_process(data) {
1390
+ const heap = this.aes.heap;
1391
+ const asm = this.aes.asm;
1392
+ let dpos = 0;
1393
+ let dlen = data.length || 0;
1394
+ let wlen = 0;
1395
+
1396
+ while (dlen > 0) {
1397
+ wlen = _heap_write(heap, 0, data, dpos, dlen);
1398
+ dpos += wlen;
1399
+ dlen -= wlen;
1400
+
1401
+ while (wlen & 15) heap[wlen++] = 0;
1402
+
1403
+ asm.mac(AES_asm.MAC.GCM, AES_asm.HEAP_DATA, wlen);
1404
+ }
1405
+ }
1406
+
1407
+ }
1408
+
1409
+ class AES_ECB {
1410
+ constructor(key, padding = false, aes) {
1411
+ this.aes = aes ? aes : new AES(key, undefined, padding, 'ECB');
1412
+ }
1413
+
1414
+ static encrypt(data, key, padding = false) {
1415
+ return new AES_ECB(key, padding).encrypt(data);
1416
+ }
1417
+
1418
+ static decrypt(data, key, padding = false) {
1419
+ return new AES_ECB(key, padding).decrypt(data);
1420
+ }
1421
+
1422
+ encrypt(data) {
1423
+ const r1 = this.aes.AES_Encrypt_process(data);
1424
+ const r2 = this.aes.AES_Encrypt_finish();
1425
+ return joinBytes(r1, r2);
1426
+ }
1427
+
1428
+ decrypt(data) {
1429
+ const r1 = this.aes.AES_Decrypt_process(data);
1430
+ const r2 = this.aes.AES_Decrypt_finish();
1431
+ return joinBytes(r1, r2);
1432
+ }
1433
+
1434
+ }
1435
+
1436
+ class AES_CBC {
1437
+ constructor(key, iv, padding = true, aes) {
1438
+ this.aes = aes ? aes : new AES(key, iv, padding, 'CBC');
1439
+ }
1440
+
1441
+ static encrypt(data, key, padding = true, iv) {
1442
+ return new AES_CBC(key, iv, padding).encrypt(data);
1443
+ }
1444
+
1445
+ static decrypt(data, key, padding = true, iv) {
1446
+ return new AES_CBC(key, iv, padding).decrypt(data);
1447
+ }
1448
+
1449
+ encrypt(data) {
1450
+ const r1 = this.aes.AES_Encrypt_process(data);
1451
+ const r2 = this.aes.AES_Encrypt_finish();
1452
+ return joinBytes(r1, r2);
1453
+ }
1454
+
1455
+ decrypt(data) {
1456
+ const r1 = this.aes.AES_Decrypt_process(data);
1457
+ const r2 = this.aes.AES_Decrypt_finish();
1458
+ return joinBytes(r1, r2);
1459
+ }
1460
+
1461
+ }
1462
+
1463
+ /**
1464
+ * Counter with CBC-MAC (CCM)
1465
+ *
1466
+ * Due to JS limitations (52 bits of Number precision) maximum encrypted message length
1467
+ * is limited to ~4 PiB ( 2^52 - 16 ) per `nonce`-`key` pair.
1468
+ * That also limits `lengthSize` parameter maximum value to 7 (not 8 as described in RFC3610).
1469
+ *
1470
+ * Additional authenticated data `adata` maximum length is chosen to be no more than 65279 bytes ( 2^16 - 2^8 ),
1471
+ * which is considered enough for the most of use-cases.
1472
+ *
1473
+ * And one more important thing: in case of progressive ciphering of a data stream (in other
1474
+ * words when data can't be held in-memory at a whole and are ciphered chunk-by-chunk)
1475
+ * you have to know the `dataLength` in advance and pass that value to the cipher options.
1476
+ */
1477
+ const _AES_CCM_adata_maxLength = 65279; // 2^16 - 2^8
1478
+
1479
+ const _AES_CCM_data_maxLength = 4503599627370480; // 2^52 - 2^4
1480
+
1481
+ class AES_CCM {
1482
+ constructor(key, nonce, adata, tagSize = 16, dataLength, aes) {
1483
+ this.counter = 1;
1484
+ this.dataLength = -1;
1485
+ this.aes = aes ? aes : new AES(key, undefined, undefined, 'CCM'); // Tag size
1486
+
1487
+ if (tagSize < 4 || tagSize > 16 || tagSize & 1) throw new IllegalArgumentError('illegal tagSize value');
1488
+ this.tagSize = tagSize; // Nonce
1489
+
1490
+ this.nonce = nonce;
1491
+ if (nonce.length < 8 || nonce.length > 13) throw new IllegalArgumentError('illegal nonce length');
1492
+ this.lengthSize = 15 - nonce.length;
1493
+ nonce = new Uint8Array(nonce.length + 1);
1494
+ nonce[0] = this.lengthSize - 1;
1495
+ nonce.set(this.nonce, 1);
1496
+ if (dataLength < 0 || dataLength > _AES_CCM_data_maxLength || dataLength > Math.pow(2, 8 * this.lengthSize) - 16) throw new IllegalArgumentError('illegal dataLength value');
1497
+
1498
+ if (adata !== undefined) {
1499
+ if (adata.length > _AES_CCM_adata_maxLength) throw new IllegalArgumentError('illegal adata length');
1500
+ this.adata = adata.length ? adata : undefined;
1501
+ }
1502
+
1503
+ this.dataLength = dataLength;
1504
+ this.counter = 1;
1505
+ this.AES_CCM_calculate_iv();
1506
+ this.AES_CTR_set_options(nonce, this.counter, 8 * this.lengthSize);
1507
+ }
1508
+
1509
+ static encrypt(clear, key, nonce, adata, tagsize = 16) {
1510
+ return new AES_CCM(key, nonce, adata, tagsize, clear.length).encrypt(clear);
1511
+ }
1512
+
1513
+ static decrypt(cipher, key, nonce, adata, tagsize = 16) {
1514
+ return new AES_CCM(key, nonce, adata, tagsize, cipher.length - tagsize).decrypt(cipher);
1515
+ }
1516
+
1517
+ encrypt(data) {
1518
+ this.dataLength = data.length || 0;
1519
+ const result1 = this.AES_CCM_Encrypt_process(data);
1520
+ const result2 = this.AES_CCM_Encrypt_finish();
1521
+ const result = new Uint8Array(result1.length + result2.length);
1522
+ if (result1.length) result.set(result1);
1523
+ if (result2.length) result.set(result2, result1.length);
1524
+ return result;
1525
+ }
1526
+
1527
+ decrypt(data) {
1528
+ this.dataLength = data.length || 0;
1529
+ const result1 = this.AES_CCM_Decrypt_process(data);
1530
+ const result2 = this.AES_CCM_Decrypt_finish();
1531
+ const result = new Uint8Array(result1.length + result2.length);
1532
+ if (result1.length) result.set(result1);
1533
+ if (result2.length) result.set(result2, result1.length);
1534
+ return result;
1535
+ }
1536
+
1537
+ AES_CCM_calculate_iv() {
1538
+ const nonce = this.nonce;
1539
+ const adata = this.adata;
1540
+ const tagSize = this.tagSize;
1541
+ const lengthSize = this.lengthSize;
1542
+ const dataLength = this.dataLength;
1543
+ const data = new Uint8Array(16 + (adata ? 2 + adata.length : 0)); // B0: flags(adata?, M', L'), nonce, len(data)
1544
+
1545
+ data[0] = (adata ? 64 : 0) | tagSize - 2 << 2 | lengthSize - 1;
1546
+ data.set(nonce, 1);
1547
+ if (lengthSize > 6) data[9] = dataLength / 0x100000000 >>> 16 & 15;
1548
+ if (lengthSize > 5) data[10] = dataLength / 0x100000000 >>> 8 & 255;
1549
+ if (lengthSize > 4) data[11] = dataLength / 0x100000000 & 255;
1550
+ if (lengthSize > 3) data[12] = dataLength >>> 24;
1551
+ if (lengthSize > 2) data[13] = dataLength >>> 16 & 255;
1552
+ data[14] = dataLength >>> 8 & 255;
1553
+ data[15] = dataLength & 255; // B*: len(adata), adata
1554
+
1555
+ if (adata) {
1556
+ data[16] = adata.length >>> 8 & 255;
1557
+ data[17] = adata.length & 255;
1558
+ data.set(adata, 18);
1559
+ }
1560
+
1561
+ this._cbc_mac_process(data);
1562
+
1563
+ this.aes.asm.get_state(AES_asm.HEAP_DATA);
1564
+ const iv = new Uint8Array(this.aes.heap.subarray(0, 16));
1565
+ const ivview = new DataView(iv.buffer, iv.byteOffset, iv.byteLength);
1566
+ this.aes.asm.set_iv(ivview.getUint32(0), ivview.getUint32(4), ivview.getUint32(8), ivview.getUint32(12));
1567
+ }
1568
+
1569
+ _cbc_mac_process(data) {
1570
+ const heap = this.aes.heap;
1571
+ const asm = this.aes.asm;
1572
+ let dpos = 0;
1573
+ let dlen = data.length || 0;
1574
+ let wlen = 0;
1575
+
1576
+ while (dlen > 0) {
1577
+ wlen = _heap_write(heap, 0, data, dpos, dlen);
1578
+
1579
+ while (wlen & 15) heap[wlen++] = 0;
1580
+
1581
+ dpos += wlen;
1582
+ dlen -= wlen;
1583
+ asm.mac(AES_asm.MAC.CBC, AES_asm.HEAP_DATA, wlen);
1584
+ }
1585
+ }
1586
+
1587
+ AES_CCM_Encrypt_process(data) {
1588
+ const asm = this.aes.asm;
1589
+ const heap = this.aes.heap;
1590
+ let dpos = 0;
1591
+ let dlen = data.length || 0;
1592
+ let counter = this.counter;
1593
+ let pos = this.aes.pos;
1594
+ let len = this.aes.len;
1595
+ const rlen = len + dlen & -16;
1596
+ let rpos = 0;
1597
+ let wlen = 0;
1598
+ if ((counter - 1 << 4) + len + dlen > _AES_CCM_data_maxLength) // ??? should check against lengthSize
1599
+ throw new RangeError('counter overflow');
1600
+ const result = new Uint8Array(rlen);
1601
+
1602
+ while (dlen > 0) {
1603
+ wlen = _heap_write(heap, pos + len, data, dpos, dlen);
1604
+ len += wlen;
1605
+ dpos += wlen;
1606
+ dlen -= wlen;
1607
+ wlen = asm.mac(AES_asm.MAC.CBC, AES_asm.HEAP_DATA + pos, len);
1608
+ wlen = asm.cipher(AES_asm.ENC.CTR, AES_asm.HEAP_DATA + pos, wlen);
1609
+ if (wlen) result.set(heap.subarray(pos, pos + wlen), rpos);
1610
+ counter += wlen >>> 4;
1611
+ rpos += wlen;
1612
+
1613
+ if (wlen < len) {
1614
+ pos += wlen;
1615
+ len -= wlen;
1616
+ } else {
1617
+ pos = 0;
1618
+ len = 0;
1619
+ }
1620
+ }
1621
+
1622
+ this.counter = counter;
1623
+ this.aes.pos = pos;
1624
+ this.aes.len = len;
1625
+ return result;
1626
+ }
1627
+
1628
+ AES_CCM_Encrypt_finish() {
1629
+ const asm = this.aes.asm;
1630
+ const heap = this.aes.heap;
1631
+ const tagSize = this.tagSize;
1632
+ const pos = this.aes.pos;
1633
+ const len = this.aes.len;
1634
+ const result = new Uint8Array(len + tagSize);
1635
+ let i = len;
1636
+
1637
+ for (; i & 15; i++) heap[pos + i] = 0;
1638
+
1639
+ asm.mac(AES_asm.MAC.CBC, AES_asm.HEAP_DATA + pos, i);
1640
+ asm.cipher(AES_asm.ENC.CTR, AES_asm.HEAP_DATA + pos, i);
1641
+ if (len) result.set(heap.subarray(pos, pos + len));
1642
+ asm.set_counter(0, 0, 0, 0);
1643
+ asm.get_iv(AES_asm.HEAP_DATA);
1644
+ asm.cipher(AES_asm.ENC.CTR, AES_asm.HEAP_DATA, 16);
1645
+ result.set(heap.subarray(0, tagSize), len);
1646
+ this.counter = 1;
1647
+ this.aes.pos = 0;
1648
+ this.aes.len = 0;
1649
+ return result;
1650
+ }
1651
+
1652
+ AES_CCM_Decrypt_process(data) {
1653
+ let dpos = 0;
1654
+ let dlen = data.length || 0;
1655
+ const asm = this.aes.asm;
1656
+ const heap = this.aes.heap;
1657
+ let counter = this.counter;
1658
+ const tagSize = this.tagSize;
1659
+ let pos = this.aes.pos;
1660
+ let len = this.aes.len;
1661
+ let rpos = 0;
1662
+ const rlen = len + dlen > tagSize ? len + dlen - tagSize & -16 : 0;
1663
+ const tlen = len + dlen - rlen;
1664
+ let wlen = 0;
1665
+ if ((counter - 1 << 4) + len + dlen > _AES_CCM_data_maxLength) throw new RangeError('counter overflow');
1666
+ const result = new Uint8Array(rlen);
1667
+
1668
+ while (dlen > tlen) {
1669
+ wlen = _heap_write(heap, pos + len, data, dpos, dlen - tlen);
1670
+ len += wlen;
1671
+ dpos += wlen;
1672
+ dlen -= wlen;
1673
+ wlen = asm.cipher(AES_asm.DEC.CTR, AES_asm.HEAP_DATA + pos, wlen);
1674
+ wlen = asm.mac(AES_asm.MAC.CBC, AES_asm.HEAP_DATA + pos, wlen);
1675
+ if (wlen) result.set(heap.subarray(pos, pos + wlen), rpos);
1676
+ counter += wlen >>> 4;
1677
+ rpos += wlen;
1678
+ pos = 0;
1679
+ len = 0;
1680
+ }
1681
+
1682
+ if (dlen > 0) {
1683
+ len += _heap_write(heap, 0, data, dpos, dlen);
1684
+ }
1685
+
1686
+ this.counter = counter;
1687
+ this.aes.pos = pos;
1688
+ this.aes.len = len;
1689
+ return result;
1690
+ }
1691
+
1692
+ AES_CCM_Decrypt_finish() {
1693
+ const asm = this.aes.asm;
1694
+ const heap = this.aes.heap;
1695
+ const tagSize = this.tagSize;
1696
+ const pos = this.aes.pos;
1697
+ const len = this.aes.len;
1698
+ const rlen = len - tagSize;
1699
+ if (len < tagSize) throw new IllegalStateError('authentication tag not found');
1700
+ const result = new Uint8Array(rlen);
1701
+ const atag = new Uint8Array(heap.subarray(pos + rlen, pos + len));
1702
+ asm.cipher(AES_asm.DEC.CTR, AES_asm.HEAP_DATA + pos, rlen + 15 & -16);
1703
+ result.set(heap.subarray(pos, pos + rlen));
1704
+ let i = rlen;
1705
+
1706
+ for (; i & 15; i++) heap[pos + i] = 0;
1707
+
1708
+ asm.mac(AES_asm.MAC.CBC, AES_asm.HEAP_DATA + pos, i);
1709
+ asm.set_counter(0, 0, 0, 0);
1710
+ asm.get_iv(AES_asm.HEAP_DATA);
1711
+ asm.cipher(AES_asm.ENC.CTR, AES_asm.HEAP_DATA, 16);
1712
+ let acheck = 0;
1713
+
1714
+ for (let j = 0; j < tagSize; ++j) acheck |= atag[j] ^ heap[j];
1715
+
1716
+ if (acheck) throw new SecurityError('data integrity check failed');
1717
+ this.counter = 1;
1718
+ this.aes.pos = 0;
1719
+ this.aes.len = 0;
1720
+ return result;
1721
+ }
1722
+
1723
+ AES_CTR_set_options(nonce, counter, size) {
1724
+ if (size < 8 || size > 48) throw new IllegalArgumentError('illegal counter size');
1725
+ const mask = Math.pow(2, size) - 1;
1726
+ this.aes.asm.set_mask(0, 0, mask / 0x100000000 | 0, mask | 0);
1727
+ const len = nonce.length;
1728
+ if (!len || len > 16) throw new IllegalArgumentError('illegal nonce size');
1729
+ this.nonce = nonce;
1730
+ const view = new DataView(new ArrayBuffer(16));
1731
+ new Uint8Array(view.buffer).set(nonce);
1732
+ this.aes.asm.set_nonce(view.getUint32(0), view.getUint32(4), view.getUint32(8), view.getUint32(12));
1733
+ if (counter < 0 || counter >= Math.pow(2, size)) throw new IllegalArgumentError('illegal counter value');
1734
+ this.counter = counter;
1735
+ this.aes.asm.set_counter(0, 0, counter / 0x100000000 | 0, counter | 0);
1736
+ }
1737
+
1738
+ }
1739
+
1740
+ export { AES, AES_CBC, AES_CCM, AES_ECB, AES_GCM, IllegalArgumentError, IllegalStateError, SecurityError };