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