aegis-aead 0.2.2 → 0.2.3

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.
Files changed (55) hide show
  1. package/README.md +25 -20
  2. package/dist/aegis128l.d.ts +33 -33
  3. package/dist/aegis128l.js +225 -235
  4. package/dist/aegis128x.d.ts +35 -35
  5. package/dist/aegis128x.js +348 -282
  6. package/dist/aegis256.d.ts +34 -51
  7. package/dist/aegis256.js +215 -206
  8. package/dist/aegis256x.d.ts +32 -33
  9. package/dist/aegis256x.js +333 -265
  10. package/dist/aes-bs.d.ts +42 -35
  11. package/dist/aes-bs.js +2269 -401
  12. package/dist/index.d.ts +4 -7
  13. package/dist/index.js +4 -7
  14. package/dist/random.d.ts +0 -1
  15. package/dist/random.js +0 -1
  16. package/dist/utils.d.ts +14 -0
  17. package/dist/utils.js +31 -0
  18. package/package.json +5 -6
  19. package/dist/aegis128l-bs.d.ts +0 -137
  20. package/dist/aegis128l-bs.d.ts.map +0 -1
  21. package/dist/aegis128l-bs.js +0 -442
  22. package/dist/aegis128l-bs.js.map +0 -1
  23. package/dist/aegis128l.d.ts.map +0 -1
  24. package/dist/aegis128l.js.map +0 -1
  25. package/dist/aegis128x.d.ts.map +0 -1
  26. package/dist/aegis128x.js.map +0 -1
  27. package/dist/aegis256-bs.d.ts +0 -79
  28. package/dist/aegis256-bs.d.ts.map +0 -1
  29. package/dist/aegis256-bs.js +0 -366
  30. package/dist/aegis256-bs.js.map +0 -1
  31. package/dist/aegis256.d.ts.map +0 -1
  32. package/dist/aegis256.js.map +0 -1
  33. package/dist/aegis256x.d.ts.map +0 -1
  34. package/dist/aegis256x.js.map +0 -1
  35. package/dist/aes-bs.d.ts.map +0 -1
  36. package/dist/aes-bs.js.map +0 -1
  37. package/dist/aes.d.ts +0 -81
  38. package/dist/aes.d.ts.map +0 -1
  39. package/dist/aes.js +0 -232
  40. package/dist/aes.js.map +0 -1
  41. package/dist/index.d.ts.map +0 -1
  42. package/dist/index.js.map +0 -1
  43. package/dist/random.d.ts.map +0 -1
  44. package/dist/random.js.map +0 -1
  45. package/src/aegis128l-bs.ts +0 -600
  46. package/src/aegis128l.ts +0 -653
  47. package/src/aegis128x.ts +0 -932
  48. package/src/aegis256-bs.ts +0 -519
  49. package/src/aegis256.ts +0 -597
  50. package/src/aegis256x.ts +0 -893
  51. package/src/aes-bs.ts +0 -540
  52. package/src/aes.ts +0 -271
  53. package/src/index.ts +0 -126
  54. package/src/random.ts +0 -41
  55. package/src/typed-array.d.ts +0 -18
@@ -1,600 +0,0 @@
1
- /**
2
- * Bitsliced AEGIS-128L implementation.
3
- * Provides constant-time operation by processing all 8 state blocks simultaneously.
4
- */
5
-
6
- import { constantTimeEqual, zeroPad } from "./aes.js";
7
- import {
8
- type AesBlock,
9
- type AesBlocks,
10
- aesRound,
11
- blockFromBytes,
12
- blocksPut,
13
- blocksRotr,
14
- blocksXor,
15
- blockToBytes,
16
- blockXor,
17
- createAesBlock,
18
- createAesBlocks,
19
- pack,
20
- pack04,
21
- unpack,
22
- unpack04,
23
- wordIdx,
24
- } from "./aes-bs.js";
25
- import { randomBytes } from "./random.js";
26
-
27
- const RATE = 32;
28
-
29
- const C0: AesBlock = new Uint32Array([
30
- 0x02010100, 0x0d080503, 0x59372215, 0x6279e990,
31
- ]);
32
- const C1: AesBlock = new Uint32Array([
33
- 0x55183ddb, 0xf12fc26d, 0x42311120, 0xdd28b573,
34
- ]);
35
-
36
- /**
37
- * Bitsliced AEGIS-128L cipher state.
38
- * The state is kept in packed bitsliced form between operations so that
39
- * pack/unpack does not need to be applied at every round.
40
- */
41
- export class Aegis128LBsState {
42
- private st: AesBlocks;
43
- private st1: AesBlocks;
44
- private constantInput: AesBlocks;
45
- private tmp0: AesBlock;
46
- private tmp1: AesBlock;
47
- private z0: AesBlock;
48
- private z1: AesBlock;
49
-
50
- constructor() {
51
- this.st = createAesBlocks();
52
- this.st1 = createAesBlocks();
53
- this.constantInput = createAesBlocks();
54
- this.tmp0 = createAesBlock();
55
- this.tmp1 = createAesBlock();
56
- this.z0 = createAesBlock();
57
- this.z1 = createAesBlock();
58
- }
59
-
60
- private aegisRoundPacked(): void {
61
- const st = this.st;
62
- const st1 = this.st1;
63
-
64
- st1.set(st);
65
- aesRound(st1);
66
- blocksRotr(st1);
67
- blocksXor(st, st1);
68
- blocksXor(st, this.constantInput);
69
- }
70
-
71
- private packConstantInput(m0: AesBlock, m1: AesBlock): void {
72
- const out = this.constantInput;
73
- out.fill(0);
74
- blocksPut(out, m0, 0);
75
- blocksPut(out, m1, 4);
76
- pack04(out);
77
- }
78
-
79
- /**
80
- * Extract the keystream blocks z0 and z1 directly from the packed state.
81
- *
82
- * z0 = S6 ^ S1 ^ (S2 & S3)
83
- * z1 = S2 ^ S5 ^ (S6 & S7)
84
- *
85
- * The formula is evaluated lane-wise on the packed state, the result is
86
- * placed in positions 0 (z0) and 4 (z1), then unpack04 extracts the two
87
- * AES blocks.
88
- */
89
- private keystreamPacked(): void {
90
- const st = this.st;
91
- const z = this.st1;
92
- for (let i = 0; i < 32; i++) {
93
- const x = st[i]!;
94
- z[i] =
95
- ((x & 0x02020202) << 6) ^
96
- ((x & 0x40404040) << 1) ^
97
- ((x & (x >>> 1) & 0x10101010) << 3) ^
98
- ((x & 0x20202020) >>> 2) ^
99
- ((x & 0x04040404) << 1) ^
100
- ((x & (x >>> 1) & 0x01010101) << 3);
101
- }
102
- unpack04(z);
103
- const z0 = this.z0;
104
- const z1 = this.z1;
105
- for (let i = 0; i < 4; i++) {
106
- z0[i] = z[wordIdx(0, i)]!;
107
- z1[i] = z[wordIdx(4, i)]!;
108
- }
109
- }
110
-
111
- /**
112
- * Initializes the state with a key and nonce.
113
- * @param key - 16-byte encryption key
114
- * @param nonce - 16-byte nonce (must be unique per message)
115
- */
116
- init(key: Uint8Array, nonce: Uint8Array): void {
117
- const k = createAesBlock();
118
- const n = createAesBlock();
119
- const kn = createAesBlock();
120
- const kc0 = createAesBlock();
121
- const kc1 = createAesBlock();
122
-
123
- blockFromBytes(k, key);
124
- blockFromBytes(n, nonce);
125
- blockXor(kn, k, n);
126
- blockXor(kc0, k, C0);
127
- blockXor(kc1, k, C1);
128
-
129
- blocksPut(this.st, kn, 0);
130
- blocksPut(this.st, C1, 1);
131
- blocksPut(this.st, C0, 2);
132
- blocksPut(this.st, C1, 3);
133
- blocksPut(this.st, kn, 4);
134
- blocksPut(this.st, kc0, 5);
135
- blocksPut(this.st, kc1, 6);
136
- blocksPut(this.st, kc0, 7);
137
-
138
- this.packConstantInput(n, k);
139
- pack(this.st);
140
- for (let i = 0; i < 10; i++) {
141
- this.aegisRoundPacked();
142
- }
143
- }
144
-
145
- /**
146
- * Absorbs a 32-byte associated data block into the state.
147
- * @param ai - 32-byte associated data block
148
- */
149
- absorb(ai: Uint8Array): void {
150
- const msg0 = this.tmp0;
151
- const msg1 = this.tmp1;
152
- blockFromBytes(msg0, ai.subarray(0, 16));
153
- blockFromBytes(msg1, ai.subarray(16, 32));
154
- this.packConstantInput(msg0, msg1);
155
- this.aegisRoundPacked();
156
- }
157
-
158
- /**
159
- * Encrypts a 32-byte plaintext block and writes to output buffer.
160
- * @param xi - 32-byte plaintext block
161
- * @param out - 32-byte output buffer
162
- */
163
- encTo(xi: Uint8Array, out: Uint8Array): void {
164
- const t0 = this.tmp0;
165
- const t1 = this.tmp1;
166
-
167
- this.keystreamPacked();
168
-
169
- blockFromBytes(t0, xi.subarray(0, 16));
170
- blockFromBytes(t1, xi.subarray(16, 32));
171
-
172
- this.packConstantInput(t0, t1);
173
- this.aegisRoundPacked();
174
-
175
- blockXor(t0, t0, this.z0);
176
- blockXor(t1, t1, this.z1);
177
-
178
- blockToBytes(out.subarray(0, 16), t0);
179
- blockToBytes(out.subarray(16, 32), t1);
180
- }
181
-
182
- /**
183
- * Encrypts a 32-byte plaintext block.
184
- * @param xi - 32-byte plaintext block
185
- * @returns 32-byte ciphertext block
186
- */
187
- enc(xi: Uint8Array): Uint8Array {
188
- const out = new Uint8Array(32);
189
- this.encTo(xi, out);
190
- return out;
191
- }
192
-
193
- /**
194
- * Decrypts a 32-byte ciphertext block and writes to output buffer.
195
- * @param ci - 32-byte ciphertext block
196
- * @param out - 32-byte output buffer
197
- */
198
- decTo(ci: Uint8Array, out: Uint8Array): void {
199
- const msg0 = this.tmp0;
200
- const msg1 = this.tmp1;
201
-
202
- blockFromBytes(msg0, ci.subarray(0, 16));
203
- blockFromBytes(msg1, ci.subarray(16, 32));
204
-
205
- this.keystreamPacked();
206
- blockXor(msg0, msg0, this.z0);
207
- blockXor(msg1, msg1, this.z1);
208
-
209
- this.packConstantInput(msg0, msg1);
210
- this.aegisRoundPacked();
211
-
212
- blockToBytes(out.subarray(0, 16), msg0);
213
- blockToBytes(out.subarray(16, 32), msg1);
214
- }
215
-
216
- /**
217
- * Decrypts a 32-byte ciphertext block.
218
- * @param ci - 32-byte ciphertext block
219
- * @returns 32-byte plaintext block
220
- */
221
- dec(ci: Uint8Array): Uint8Array {
222
- const out = new Uint8Array(32);
223
- this.decTo(ci, out);
224
- return out;
225
- }
226
-
227
- encInPlace(block: Uint8Array): void {
228
- this.encTo(block, block);
229
- }
230
-
231
- decInPlace(block: Uint8Array): void {
232
- this.decTo(block, block);
233
- }
234
-
235
- /**
236
- * Decrypts a partial (final) ciphertext block smaller than 32 bytes.
237
- * @param cn - Partial ciphertext block (1-31 bytes)
238
- * @returns Decrypted plaintext of the same length
239
- */
240
- decPartial(cn: Uint8Array): Uint8Array {
241
- const msg0 = this.tmp0;
242
- const msg1 = this.tmp1;
243
-
244
- const padded = zeroPad(cn, RATE);
245
- blockFromBytes(msg0, padded.subarray(0, 16));
246
- blockFromBytes(msg1, padded.subarray(16, 32));
247
-
248
- this.keystreamPacked();
249
- blockXor(msg0, msg0, this.z0);
250
- blockXor(msg1, msg1, this.z1);
251
-
252
- const pad = new Uint8Array(RATE);
253
- blockToBytes(pad.subarray(0, 16), msg0);
254
- blockToBytes(pad.subarray(16, 32), msg1);
255
-
256
- const xn = new Uint8Array(pad.subarray(0, cn.length));
257
-
258
- pad.fill(0, cn.length);
259
- blockFromBytes(msg0, pad.subarray(0, 16));
260
- blockFromBytes(msg1, pad.subarray(16, 32));
261
-
262
- this.packConstantInput(msg0, msg1);
263
- this.aegisRoundPacked();
264
-
265
- return xn;
266
- }
267
-
268
- /**
269
- * Finalizes encryption/decryption and produces an authentication tag.
270
- * @param adLen - Associated data length in bytes
271
- * @param msgLen - Message length in bytes
272
- * @param tagLen - Tag length (16 or 32 bytes)
273
- * @returns Authentication tag
274
- */
275
- finalize(adLen: number, msgLen: number, tagLen: 16 | 32 = 16): Uint8Array {
276
- const st = this.st;
277
- const tmp = this.tmp0;
278
-
279
- tmp[0] = ((adLen * 8) & 0xffffffff) >>> 0;
280
- tmp[1] = Math.floor((adLen * 8) / 0x100000000) >>> 0;
281
- tmp[2] = ((msgLen * 8) & 0xffffffff) >>> 0;
282
- tmp[3] = Math.floor((msgLen * 8) / 0x100000000) >>> 0;
283
-
284
- const unpacked = this.st1;
285
- unpacked.set(st);
286
- unpack(unpacked);
287
-
288
- tmp[0] = (tmp[0]! ^ unpacked[wordIdx(2, 0)]!) >>> 0;
289
- tmp[1] = (tmp[1]! ^ unpacked[wordIdx(2, 1)]!) >>> 0;
290
- tmp[2] = (tmp[2]! ^ unpacked[wordIdx(2, 2)]!) >>> 0;
291
- tmp[3] = (tmp[3]! ^ unpacked[wordIdx(2, 3)]!) >>> 0;
292
-
293
- this.packConstantInput(tmp, tmp);
294
- for (let i = 0; i < 7; i++) {
295
- this.aegisRoundPacked();
296
- }
297
- unpack(st);
298
-
299
- if (tagLen === 16) {
300
- const tag = new Uint8Array(16);
301
- const tagBlock = createAesBlock();
302
- for (let i = 0; i < 4; i++) {
303
- tagBlock[i] =
304
- (st[wordIdx(0, i)]! ^
305
- st[wordIdx(1, i)]! ^
306
- st[wordIdx(2, i)]! ^
307
- st[wordIdx(3, i)]! ^
308
- st[wordIdx(4, i)]! ^
309
- st[wordIdx(5, i)]! ^
310
- st[wordIdx(6, i)]!) >>>
311
- 0;
312
- }
313
- blockToBytes(tag, tagBlock);
314
- return tag;
315
- } else {
316
- const tag = new Uint8Array(32);
317
- const tagBlock0 = createAesBlock();
318
- const tagBlock1 = createAesBlock();
319
- for (let i = 0; i < 4; i++) {
320
- tagBlock0[i] =
321
- (st[wordIdx(0, i)]! ^
322
- st[wordIdx(1, i)]! ^
323
- st[wordIdx(2, i)]! ^
324
- st[wordIdx(3, i)]!) >>>
325
- 0;
326
- }
327
- for (let i = 0; i < 4; i++) {
328
- tagBlock1[i] =
329
- (st[wordIdx(4, i)]! ^
330
- st[wordIdx(5, i)]! ^
331
- st[wordIdx(6, i)]! ^
332
- st[wordIdx(7, i)]!) >>>
333
- 0;
334
- }
335
- blockToBytes(tag.subarray(0, 16), tagBlock0);
336
- blockToBytes(tag.subarray(16, 32), tagBlock1);
337
- return tag;
338
- }
339
- }
340
- }
341
-
342
- /**
343
- * Encrypts a message using bitsliced AEGIS-128L (detached mode).
344
- * @param msg - Plaintext message
345
- * @param ad - Associated data (authenticated but not encrypted)
346
- * @param key - 16-byte encryption key
347
- * @param nonce - 16-byte nonce (must be unique per message with the same key)
348
- * @param tagLen - Authentication tag length: 16 or 32 bytes (default: 16)
349
- * @returns Object containing ciphertext and authentication tag separately
350
- */
351
- export function aegis128LBsEncryptDetached(
352
- msg: Uint8Array,
353
- ad: Uint8Array,
354
- key: Uint8Array,
355
- nonce: Uint8Array,
356
- tagLen: 16 | 32 = 16,
357
- ): { ciphertext: Uint8Array; tag: Uint8Array } {
358
- const state = new Aegis128LBsState();
359
- state.init(key, nonce);
360
-
361
- const adPadded = zeroPad(ad, RATE);
362
- for (let i = 0; i + RATE <= adPadded.length; i += RATE) {
363
- state.absorb(adPadded.subarray(i, i + RATE));
364
- }
365
-
366
- const ciphertext = new Uint8Array(msg.length);
367
- const fullBlocks = Math.floor(msg.length / RATE) * RATE;
368
-
369
- for (let i = 0; i < fullBlocks; i += RATE) {
370
- state.encTo(msg.subarray(i, i + RATE), ciphertext.subarray(i, i + RATE));
371
- }
372
-
373
- if (msg.length > fullBlocks) {
374
- const lastBlock = zeroPad(msg.subarray(fullBlocks), RATE);
375
- const encBlock = state.enc(lastBlock);
376
- ciphertext.set(encBlock.subarray(0, msg.length - fullBlocks), fullBlocks);
377
- }
378
-
379
- const tag = state.finalize(ad.length, msg.length, tagLen);
380
-
381
- return { ciphertext, tag };
382
- }
383
-
384
- /**
385
- * Decrypts a message using bitsliced AEGIS-128L (detached mode).
386
- * @param ct - Ciphertext
387
- * @param tag - Authentication tag (16 or 32 bytes)
388
- * @param ad - Associated data (must match what was used during encryption)
389
- * @param key - 16-byte encryption key
390
- * @param nonce - 16-byte nonce (must match what was used during encryption)
391
- * @returns Decrypted plaintext, or null if authentication fails
392
- */
393
- export function aegis128LBsDecryptDetached(
394
- ct: Uint8Array,
395
- tag: Uint8Array,
396
- ad: Uint8Array,
397
- key: Uint8Array,
398
- nonce: Uint8Array,
399
- ): Uint8Array | null {
400
- const tagLen = tag.length as 16 | 32;
401
- const state = new Aegis128LBsState();
402
- state.init(key, nonce);
403
-
404
- const adPadded = zeroPad(ad, RATE);
405
- for (let i = 0; i + RATE <= adPadded.length; i += RATE) {
406
- state.absorb(adPadded.subarray(i, i + RATE));
407
- }
408
-
409
- const msg = new Uint8Array(ct.length);
410
- const fullBlocks = Math.floor(ct.length / RATE) * RATE;
411
-
412
- for (let i = 0; i < fullBlocks; i += RATE) {
413
- state.decTo(ct.subarray(i, i + RATE), msg.subarray(i, i + RATE));
414
- }
415
-
416
- if (ct.length > fullBlocks) {
417
- msg.set(state.decPartial(ct.subarray(fullBlocks)), fullBlocks);
418
- }
419
-
420
- const expectedTag = state.finalize(ad.length, msg.length, tagLen);
421
-
422
- if (!constantTimeEqual(tag, expectedTag)) {
423
- msg.fill(0);
424
- return null;
425
- }
426
-
427
- return msg;
428
- }
429
-
430
- /**
431
- * Encrypts a message in-place using bitsliced AEGIS-128L (detached mode).
432
- */
433
- export function aegis128LBsEncryptDetachedInPlace(
434
- data: Uint8Array,
435
- ad: Uint8Array,
436
- key: Uint8Array,
437
- nonce: Uint8Array,
438
- tagLen: 16 | 32 = 16,
439
- ): Uint8Array {
440
- const state = new Aegis128LBsState();
441
- state.init(key, nonce);
442
-
443
- const adPadded = zeroPad(ad, RATE);
444
- for (let i = 0; i + RATE <= adPadded.length; i += RATE) {
445
- state.absorb(adPadded.subarray(i, i + RATE));
446
- }
447
-
448
- const msgLen = data.length;
449
- const fullBlocksLen = Math.floor(msgLen / RATE) * RATE;
450
-
451
- for (let i = 0; i < fullBlocksLen; i += RATE) {
452
- state.encInPlace(data.subarray(i, i + RATE));
453
- }
454
-
455
- if (msgLen > fullBlocksLen) {
456
- const lastPartial = data.subarray(fullBlocksLen);
457
- const lastBlock = zeroPad(lastPartial, RATE);
458
- const encBlock = state.enc(lastBlock);
459
- lastPartial.set(encBlock.subarray(0, lastPartial.length));
460
- }
461
-
462
- return state.finalize(ad.length, msgLen, tagLen);
463
- }
464
-
465
- /**
466
- * Decrypts a message in-place using bitsliced AEGIS-128L (detached mode).
467
- */
468
- export function aegis128LBsDecryptDetachedInPlace(
469
- data: Uint8Array,
470
- tag: Uint8Array,
471
- ad: Uint8Array,
472
- key: Uint8Array,
473
- nonce: Uint8Array,
474
- ): boolean {
475
- const tagLen = tag.length as 16 | 32;
476
- const state = new Aegis128LBsState();
477
- state.init(key, nonce);
478
-
479
- const adPadded = zeroPad(ad, RATE);
480
- for (let i = 0; i + RATE <= adPadded.length; i += RATE) {
481
- state.absorb(adPadded.subarray(i, i + RATE));
482
- }
483
-
484
- const msgLen = data.length;
485
- const fullBlocksLen = Math.floor(msgLen / RATE) * RATE;
486
-
487
- for (let i = 0; i < fullBlocksLen; i += RATE) {
488
- state.decInPlace(data.subarray(i, i + RATE));
489
- }
490
-
491
- if (msgLen > fullBlocksLen) {
492
- const lastPartial = data.subarray(fullBlocksLen);
493
- const decrypted = state.decPartial(lastPartial);
494
- lastPartial.set(decrypted);
495
- }
496
-
497
- const expectedTag = state.finalize(ad.length, msgLen, tagLen);
498
-
499
- if (!constantTimeEqual(tag, expectedTag)) {
500
- data.fill(0);
501
- return false;
502
- }
503
-
504
- return true;
505
- }
506
-
507
- export const AEGIS_128L_BS_NONCE_SIZE = 16;
508
- export const AEGIS_128L_BS_KEY_SIZE = 16;
509
-
510
- /**
511
- * Encrypts a message using bitsliced AEGIS-128L.
512
- * Returns a single buffer containing nonce || ciphertext || tag.
513
- */
514
- export function aegis128LBsEncrypt(
515
- msg: Uint8Array,
516
- ad: Uint8Array,
517
- key: Uint8Array,
518
- nonce: Uint8Array | null = null,
519
- tagLen: 16 | 32 = 16,
520
- ): Uint8Array {
521
- const actualNonce = nonce ?? randomBytes(AEGIS_128L_BS_NONCE_SIZE);
522
- const { ciphertext, tag } = aegis128LBsEncryptDetached(
523
- msg,
524
- ad,
525
- key,
526
- actualNonce,
527
- tagLen,
528
- );
529
-
530
- const result = new Uint8Array(
531
- AEGIS_128L_BS_NONCE_SIZE + ciphertext.length + tagLen,
532
- );
533
- result.set(actualNonce, 0);
534
- result.set(ciphertext, AEGIS_128L_BS_NONCE_SIZE);
535
- result.set(tag, AEGIS_128L_BS_NONCE_SIZE + ciphertext.length);
536
-
537
- return result;
538
- }
539
-
540
- /**
541
- * Decrypts a message using bitsliced AEGIS-128L.
542
- * Expects input as nonce || ciphertext || tag.
543
- */
544
- export function aegis128LBsDecrypt(
545
- sealed: Uint8Array,
546
- ad: Uint8Array,
547
- key: Uint8Array,
548
- tagLen: 16 | 32 = 16,
549
- ): Uint8Array | null {
550
- const nonceSize = AEGIS_128L_BS_NONCE_SIZE;
551
- if (sealed.length < nonceSize + tagLen) {
552
- return null;
553
- }
554
- const nonce = sealed.subarray(0, nonceSize);
555
- const ct = sealed.subarray(nonceSize, sealed.length - tagLen);
556
- const tag = sealed.subarray(sealed.length - tagLen);
557
- return aegis128LBsDecryptDetached(ct, tag, ad, key, nonce);
558
- }
559
-
560
- /**
561
- * Computes a MAC using bitsliced AEGIS-128L.
562
- */
563
- export function aegis128LBsMac(
564
- data: Uint8Array,
565
- key: Uint8Array,
566
- nonce: Uint8Array | null = null,
567
- tagLen: 16 | 32 = 16,
568
- ): Uint8Array {
569
- const state = new Aegis128LBsState();
570
- state.init(key, nonce ?? new Uint8Array(16));
571
-
572
- const dataPadded = zeroPad(data, RATE);
573
- for (let i = 0; i + RATE <= dataPadded.length; i += RATE) {
574
- state.absorb(dataPadded.subarray(i, i + RATE));
575
- }
576
-
577
- return state.finalize(data.length, tagLen, tagLen);
578
- }
579
-
580
- /**
581
- * Verifies a MAC computed using bitsliced AEGIS-128L.
582
- */
583
- export function aegis128LBsMacVerify(
584
- data: Uint8Array,
585
- tag: Uint8Array,
586
- key: Uint8Array,
587
- nonce: Uint8Array | null = null,
588
- ): boolean {
589
- const tagLen = tag.length as 16 | 32;
590
- const expectedTag = aegis128LBsMac(data, key, nonce, tagLen);
591
- return constantTimeEqual(tag, expectedTag);
592
- }
593
-
594
- export function aegis128LBsCreateKey(): Uint8Array {
595
- return randomBytes(AEGIS_128L_BS_KEY_SIZE);
596
- }
597
-
598
- export function aegis128LBsCreateNonce(): Uint8Array {
599
- return randomBytes(AEGIS_128L_BS_NONCE_SIZE);
600
- }