aegis-aead 0.2.0 → 0.2.2
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/README.md +155 -228
- package/dist/aegis128l-bs.d.ts +23 -48
- package/dist/aegis128l-bs.d.ts.map +1 -1
- package/dist/aegis128l-bs.js +124 -152
- package/dist/aegis128l-bs.js.map +1 -1
- package/dist/aegis128l.d.ts +32 -0
- package/dist/aegis128l.d.ts.map +1 -1
- package/dist/aegis128l.js +94 -0
- package/dist/aegis128l.js.map +1 -1
- package/dist/aegis128x.d.ts +42 -0
- package/dist/aegis128x.d.ts.map +1 -1
- package/dist/aegis128x.js +100 -0
- package/dist/aegis128x.js.map +1 -1
- package/dist/aegis256-bs.d.ts +19 -91
- package/dist/aegis256-bs.d.ts.map +1 -1
- package/dist/aegis256-bs.js +124 -156
- package/dist/aegis256-bs.js.map +1 -1
- package/dist/aegis256.d.ts +32 -0
- package/dist/aegis256.d.ts.map +1 -1
- package/dist/aegis256.js +79 -0
- package/dist/aegis256.js.map +1 -1
- package/dist/aegis256x.d.ts +42 -0
- package/dist/aegis256x.d.ts.map +1 -1
- package/dist/aegis256x.js +91 -0
- package/dist/aegis256x.js.map +1 -1
- package/dist/aes-bs.d.ts +16 -0
- package/dist/aes-bs.d.ts.map +1 -1
- package/dist/aes-bs.js +173 -99
- package/dist/aes-bs.js.map +1 -1
- package/dist/index.d.ts +6 -6
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +6 -6
- package/dist/index.js.map +1 -1
- package/package.json +3 -2
- package/src/aegis128l-bs.ts +154 -156
- package/src/aegis128l.ts +126 -0
- package/src/aegis128x.ts +168 -0
- package/src/aegis256-bs.ts +158 -157
- package/src/aegis256.ts +111 -0
- package/src/aegis256x.ts +155 -0
- package/src/aes-bs.ts +187 -106
- package/src/index.ts +20 -0
package/src/aegis256.ts
CHANGED
|
@@ -173,6 +173,22 @@ export class Aegis256State {
|
|
|
173
173
|
return out;
|
|
174
174
|
}
|
|
175
175
|
|
|
176
|
+
/**
|
|
177
|
+
* Encrypts a 16-byte plaintext block in-place.
|
|
178
|
+
* @param block - 16-byte buffer (plaintext in, ciphertext out)
|
|
179
|
+
*/
|
|
180
|
+
encInPlace(block: Uint8Array): void {
|
|
181
|
+
this.encTo(block, block);
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
/**
|
|
185
|
+
* Decrypts a 16-byte ciphertext block in-place.
|
|
186
|
+
* @param block - 16-byte buffer (ciphertext in, plaintext out)
|
|
187
|
+
*/
|
|
188
|
+
decInPlace(block: Uint8Array): void {
|
|
189
|
+
this.decTo(block, block);
|
|
190
|
+
}
|
|
191
|
+
|
|
176
192
|
/**
|
|
177
193
|
* Decrypts a partial (final) ciphertext block smaller than 16 bytes.
|
|
178
194
|
* @param cn - Partial ciphertext block (1-15 bytes)
|
|
@@ -335,6 +351,101 @@ export function aegis256DecryptDetached(
|
|
|
335
351
|
return msg;
|
|
336
352
|
}
|
|
337
353
|
|
|
354
|
+
/**
|
|
355
|
+
* Encrypts a message in-place using AEGIS-256 (detached mode).
|
|
356
|
+
* The input buffer is modified to contain the ciphertext.
|
|
357
|
+
* @param data - Buffer containing plaintext (will be overwritten with ciphertext)
|
|
358
|
+
* @param ad - Associated data (authenticated but not encrypted)
|
|
359
|
+
* @param key - 32-byte encryption key
|
|
360
|
+
* @param nonce - 32-byte nonce (must be unique per message with the same key)
|
|
361
|
+
* @param tagLen - Authentication tag length: 16 or 32 bytes (default: 16)
|
|
362
|
+
* @returns Authentication tag
|
|
363
|
+
*/
|
|
364
|
+
export function aegis256EncryptDetachedInPlace(
|
|
365
|
+
data: Uint8Array,
|
|
366
|
+
ad: Uint8Array,
|
|
367
|
+
key: Uint8Array,
|
|
368
|
+
nonce: Uint8Array,
|
|
369
|
+
tagLen: 16 | 32 = 16,
|
|
370
|
+
): Uint8Array {
|
|
371
|
+
const state = new Aegis256State();
|
|
372
|
+
state.init(key, nonce);
|
|
373
|
+
|
|
374
|
+
const adPadded = zeroPad(ad, 16);
|
|
375
|
+
for (let i = 0; i + 16 <= adPadded.length; i += 16) {
|
|
376
|
+
state.absorb(adPadded.subarray(i, i + 16));
|
|
377
|
+
}
|
|
378
|
+
|
|
379
|
+
const msgLen = data.length;
|
|
380
|
+
const fullBlocksLen = Math.floor(msgLen / 16) * 16;
|
|
381
|
+
|
|
382
|
+
for (let i = 0; i < fullBlocksLen; i += 16) {
|
|
383
|
+
state.encInPlace(data.subarray(i, i + 16));
|
|
384
|
+
}
|
|
385
|
+
|
|
386
|
+
if (msgLen > fullBlocksLen) {
|
|
387
|
+
const lastPartial = data.subarray(fullBlocksLen);
|
|
388
|
+
const lastBlock = zeroPad(lastPartial, 16);
|
|
389
|
+
const encBlock = state.enc(lastBlock);
|
|
390
|
+
lastPartial.set(encBlock.subarray(0, lastPartial.length));
|
|
391
|
+
}
|
|
392
|
+
|
|
393
|
+
return state.finalize(BigInt(ad.length * 8), BigInt(msgLen * 8), tagLen);
|
|
394
|
+
}
|
|
395
|
+
|
|
396
|
+
/**
|
|
397
|
+
* Decrypts a message in-place using AEGIS-256 (detached mode).
|
|
398
|
+
* The input buffer is modified to contain the plaintext (or zeroed on failure).
|
|
399
|
+
* @param data - Buffer containing ciphertext (will be overwritten with plaintext)
|
|
400
|
+
* @param tag - Authentication tag (16 or 32 bytes)
|
|
401
|
+
* @param ad - Associated data (must match what was used during encryption)
|
|
402
|
+
* @param key - 32-byte encryption key
|
|
403
|
+
* @param nonce - 32-byte nonce (must match what was used during encryption)
|
|
404
|
+
* @returns True if authentication succeeds, false otherwise
|
|
405
|
+
*/
|
|
406
|
+
export function aegis256DecryptDetachedInPlace(
|
|
407
|
+
data: Uint8Array,
|
|
408
|
+
tag: Uint8Array,
|
|
409
|
+
ad: Uint8Array,
|
|
410
|
+
key: Uint8Array,
|
|
411
|
+
nonce: Uint8Array,
|
|
412
|
+
): boolean {
|
|
413
|
+
const tagLen = tag.length as 16 | 32;
|
|
414
|
+
const state = new Aegis256State();
|
|
415
|
+
state.init(key, nonce);
|
|
416
|
+
|
|
417
|
+
const adPadded = zeroPad(ad, 16);
|
|
418
|
+
for (let i = 0; i + 16 <= adPadded.length; i += 16) {
|
|
419
|
+
state.absorb(adPadded.subarray(i, i + 16));
|
|
420
|
+
}
|
|
421
|
+
|
|
422
|
+
const msgLen = data.length;
|
|
423
|
+
const fullBlocksLen = Math.floor(msgLen / 16) * 16;
|
|
424
|
+
|
|
425
|
+
for (let i = 0; i < fullBlocksLen; i += 16) {
|
|
426
|
+
state.decInPlace(data.subarray(i, i + 16));
|
|
427
|
+
}
|
|
428
|
+
|
|
429
|
+
if (msgLen > fullBlocksLen) {
|
|
430
|
+
const lastPartial = data.subarray(fullBlocksLen);
|
|
431
|
+
const decrypted = state.decPartial(lastPartial);
|
|
432
|
+
lastPartial.set(decrypted);
|
|
433
|
+
}
|
|
434
|
+
|
|
435
|
+
const expectedTag = state.finalize(
|
|
436
|
+
BigInt(ad.length * 8),
|
|
437
|
+
BigInt(msgLen * 8),
|
|
438
|
+
tagLen,
|
|
439
|
+
);
|
|
440
|
+
|
|
441
|
+
if (!constantTimeEqual(tag, expectedTag)) {
|
|
442
|
+
data.fill(0);
|
|
443
|
+
return false;
|
|
444
|
+
}
|
|
445
|
+
|
|
446
|
+
return true;
|
|
447
|
+
}
|
|
448
|
+
|
|
338
449
|
/** Nonce size for AEGIS-256 in bytes. */
|
|
339
450
|
export const AEGIS_256_NONCE_SIZE = 32;
|
|
340
451
|
|
package/src/aegis256x.ts
CHANGED
|
@@ -220,6 +220,22 @@ export class Aegis256XState {
|
|
|
220
220
|
return out;
|
|
221
221
|
}
|
|
222
222
|
|
|
223
|
+
/**
|
|
224
|
+
* Encrypts a plaintext block in-place.
|
|
225
|
+
* @param block - Buffer (plaintext in, ciphertext out), size 16*degree bytes
|
|
226
|
+
*/
|
|
227
|
+
encInPlace(block: Uint8Array): void {
|
|
228
|
+
this.encTo(block, block);
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
/**
|
|
232
|
+
* Decrypts a ciphertext block in-place.
|
|
233
|
+
* @param block - Buffer (ciphertext in, plaintext out), size 16*degree bytes
|
|
234
|
+
*/
|
|
235
|
+
decInPlace(block: Uint8Array): void {
|
|
236
|
+
this.decTo(block, block);
|
|
237
|
+
}
|
|
238
|
+
|
|
223
239
|
/**
|
|
224
240
|
* Decrypts a partial (final) ciphertext block.
|
|
225
241
|
* @param cn - Partial ciphertext block (smaller than 16*degree bytes)
|
|
@@ -461,6 +477,145 @@ export function aegis256XDecryptDetached(
|
|
|
461
477
|
return msg;
|
|
462
478
|
}
|
|
463
479
|
|
|
480
|
+
/**
|
|
481
|
+
* Encrypts a message in-place using AEGIS-256X (detached mode).
|
|
482
|
+
* The input buffer is modified to contain the ciphertext.
|
|
483
|
+
* @param data - Buffer containing plaintext (will be overwritten with ciphertext)
|
|
484
|
+
* @param ad - Associated data (authenticated but not encrypted)
|
|
485
|
+
* @param key - 32-byte encryption key
|
|
486
|
+
* @param nonce - 32-byte nonce (must be unique per message with the same key)
|
|
487
|
+
* @param tagLen - Authentication tag length: 16 or 32 bytes (default: 16)
|
|
488
|
+
* @param degree - Parallelism degree (default: 2)
|
|
489
|
+
* @returns Authentication tag
|
|
490
|
+
*/
|
|
491
|
+
export function aegis256XEncryptDetachedInPlace(
|
|
492
|
+
data: Uint8Array,
|
|
493
|
+
ad: Uint8Array,
|
|
494
|
+
key: Uint8Array,
|
|
495
|
+
nonce: Uint8Array,
|
|
496
|
+
tagLen: 16 | 32 = 16,
|
|
497
|
+
degree: number = 2,
|
|
498
|
+
): Uint8Array {
|
|
499
|
+
const state = new Aegis256XState(degree);
|
|
500
|
+
const rateBytes = (128 * degree) / 8;
|
|
501
|
+
|
|
502
|
+
state.init(key, nonce);
|
|
503
|
+
|
|
504
|
+
const adPadded = zeroPad(ad, rateBytes);
|
|
505
|
+
for (let i = 0; i + rateBytes <= adPadded.length; i += rateBytes) {
|
|
506
|
+
state.absorb(adPadded.subarray(i, i + rateBytes));
|
|
507
|
+
}
|
|
508
|
+
|
|
509
|
+
const msgLen = data.length;
|
|
510
|
+
const fullBlocksLen = Math.floor(msgLen / rateBytes) * rateBytes;
|
|
511
|
+
|
|
512
|
+
for (let i = 0; i < fullBlocksLen; i += rateBytes) {
|
|
513
|
+
state.encInPlace(data.subarray(i, i + rateBytes));
|
|
514
|
+
}
|
|
515
|
+
|
|
516
|
+
if (msgLen > fullBlocksLen) {
|
|
517
|
+
const lastPartial = data.subarray(fullBlocksLen);
|
|
518
|
+
const lastBlock = zeroPad(lastPartial, rateBytes);
|
|
519
|
+
const encBlock = state.enc(lastBlock);
|
|
520
|
+
lastPartial.set(encBlock.subarray(0, lastPartial.length));
|
|
521
|
+
}
|
|
522
|
+
|
|
523
|
+
return state.finalize(BigInt(ad.length * 8), BigInt(msgLen * 8), tagLen);
|
|
524
|
+
}
|
|
525
|
+
|
|
526
|
+
/**
|
|
527
|
+
* Decrypts a message in-place using AEGIS-256X (detached mode).
|
|
528
|
+
* The input buffer is modified to contain the plaintext (or zeroed on failure).
|
|
529
|
+
* @param data - Buffer containing ciphertext (will be overwritten with plaintext)
|
|
530
|
+
* @param tag - Authentication tag (16 or 32 bytes)
|
|
531
|
+
* @param ad - Associated data (must match what was used during encryption)
|
|
532
|
+
* @param key - 32-byte encryption key
|
|
533
|
+
* @param nonce - 32-byte nonce (must match what was used during encryption)
|
|
534
|
+
* @param degree - Parallelism degree (default: 2)
|
|
535
|
+
* @returns True if authentication succeeds, false otherwise
|
|
536
|
+
*/
|
|
537
|
+
export function aegis256XDecryptDetachedInPlace(
|
|
538
|
+
data: Uint8Array,
|
|
539
|
+
tag: Uint8Array,
|
|
540
|
+
ad: Uint8Array,
|
|
541
|
+
key: Uint8Array,
|
|
542
|
+
nonce: Uint8Array,
|
|
543
|
+
degree: number = 2,
|
|
544
|
+
): boolean {
|
|
545
|
+
const tagLen = tag.length as 16 | 32;
|
|
546
|
+
const state = new Aegis256XState(degree);
|
|
547
|
+
const rateBytes = (128 * degree) / 8;
|
|
548
|
+
|
|
549
|
+
state.init(key, nonce);
|
|
550
|
+
|
|
551
|
+
const adPadded = zeroPad(ad, rateBytes);
|
|
552
|
+
for (let i = 0; i + rateBytes <= adPadded.length; i += rateBytes) {
|
|
553
|
+
state.absorb(adPadded.subarray(i, i + rateBytes));
|
|
554
|
+
}
|
|
555
|
+
|
|
556
|
+
const msgLen = data.length;
|
|
557
|
+
const fullBlocksLen = Math.floor(msgLen / rateBytes) * rateBytes;
|
|
558
|
+
|
|
559
|
+
for (let i = 0; i < fullBlocksLen; i += rateBytes) {
|
|
560
|
+
state.decInPlace(data.subarray(i, i + rateBytes));
|
|
561
|
+
}
|
|
562
|
+
|
|
563
|
+
if (msgLen > fullBlocksLen) {
|
|
564
|
+
const lastPartial = data.subarray(fullBlocksLen);
|
|
565
|
+
const decrypted = state.decPartial(lastPartial);
|
|
566
|
+
lastPartial.set(decrypted);
|
|
567
|
+
}
|
|
568
|
+
|
|
569
|
+
const expectedTag = state.finalize(
|
|
570
|
+
BigInt(ad.length * 8),
|
|
571
|
+
BigInt(msgLen * 8),
|
|
572
|
+
tagLen,
|
|
573
|
+
);
|
|
574
|
+
|
|
575
|
+
if (!constantTimeEqual(tag, expectedTag)) {
|
|
576
|
+
data.fill(0);
|
|
577
|
+
return false;
|
|
578
|
+
}
|
|
579
|
+
|
|
580
|
+
return true;
|
|
581
|
+
}
|
|
582
|
+
|
|
583
|
+
/** AEGIS-256X2 in-place encryption - detached mode (degree=2). */
|
|
584
|
+
export const aegis256X2EncryptDetachedInPlace = (
|
|
585
|
+
data: Uint8Array,
|
|
586
|
+
ad: Uint8Array,
|
|
587
|
+
key: Uint8Array,
|
|
588
|
+
nonce: Uint8Array,
|
|
589
|
+
tagLen: 16 | 32 = 16,
|
|
590
|
+
) => aegis256XEncryptDetachedInPlace(data, ad, key, nonce, tagLen, 2);
|
|
591
|
+
|
|
592
|
+
/** AEGIS-256X2 in-place decryption - detached mode (degree=2). */
|
|
593
|
+
export const aegis256X2DecryptDetachedInPlace = (
|
|
594
|
+
data: Uint8Array,
|
|
595
|
+
tag: Uint8Array,
|
|
596
|
+
ad: Uint8Array,
|
|
597
|
+
key: Uint8Array,
|
|
598
|
+
nonce: Uint8Array,
|
|
599
|
+
) => aegis256XDecryptDetachedInPlace(data, tag, ad, key, nonce, 2);
|
|
600
|
+
|
|
601
|
+
/** AEGIS-256X4 in-place encryption - detached mode (degree=4). */
|
|
602
|
+
export const aegis256X4EncryptDetachedInPlace = (
|
|
603
|
+
data: Uint8Array,
|
|
604
|
+
ad: Uint8Array,
|
|
605
|
+
key: Uint8Array,
|
|
606
|
+
nonce: Uint8Array,
|
|
607
|
+
tagLen: 16 | 32 = 16,
|
|
608
|
+
) => aegis256XEncryptDetachedInPlace(data, ad, key, nonce, tagLen, 4);
|
|
609
|
+
|
|
610
|
+
/** AEGIS-256X4 in-place decryption - detached mode (degree=4). */
|
|
611
|
+
export const aegis256X4DecryptDetachedInPlace = (
|
|
612
|
+
data: Uint8Array,
|
|
613
|
+
tag: Uint8Array,
|
|
614
|
+
ad: Uint8Array,
|
|
615
|
+
key: Uint8Array,
|
|
616
|
+
nonce: Uint8Array,
|
|
617
|
+
) => aegis256XDecryptDetachedInPlace(data, tag, ad, key, nonce, 4);
|
|
618
|
+
|
|
464
619
|
/** Nonce size for AEGIS-256X in bytes. */
|
|
465
620
|
export const AEGIS_256X_NONCE_SIZE = 32;
|
|
466
621
|
|
package/src/aes-bs.ts
CHANGED
|
@@ -52,115 +52,116 @@ function rotl32(x: number, b: number): number {
|
|
|
52
52
|
return ((x << b) | (x >>> (32 - b))) >>> 0;
|
|
53
53
|
}
|
|
54
54
|
|
|
55
|
-
/**
|
|
56
|
-
* S-box implementation using bitsliced logic gates.
|
|
57
|
-
* Maximov & Ekdahl circuit.
|
|
58
|
-
*/
|
|
59
55
|
function sbox(st: Uint32Array, offset: number): void {
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
const z24 =
|
|
70
|
-
const q17 =
|
|
71
|
-
const q16 =
|
|
72
|
-
const q0 =
|
|
73
|
-
const q7 =
|
|
74
|
-
const q2 =
|
|
75
|
-
const q1 =
|
|
76
|
-
const q3 =
|
|
77
|
-
const q4 =
|
|
78
|
-
const q5 =
|
|
79
|
-
const q6 =
|
|
80
|
-
const q10 =
|
|
81
|
-
const q8 =
|
|
82
|
-
const q9 =
|
|
83
|
-
const q12 =
|
|
84
|
-
const q15 =
|
|
85
|
-
const
|
|
86
|
-
const
|
|
56
|
+
const u0 = st[offset]!;
|
|
57
|
+
const u1 = st[offset + 1]!;
|
|
58
|
+
const u2 = st[offset + 2]!;
|
|
59
|
+
const u3 = st[offset + 3]!;
|
|
60
|
+
const u4 = st[offset + 4]!;
|
|
61
|
+
const u5 = st[offset + 5]!;
|
|
62
|
+
const u6 = st[offset + 6]!;
|
|
63
|
+
const u7 = st[offset + 7]!;
|
|
64
|
+
|
|
65
|
+
const z24 = u3 ^ u4;
|
|
66
|
+
const q17 = u1 ^ u7;
|
|
67
|
+
const q16 = u5 ^ q17;
|
|
68
|
+
const q0 = z24 ^ q16;
|
|
69
|
+
const q7 = z24 ^ u1 ^ u6;
|
|
70
|
+
const q2 = u2 ^ q0;
|
|
71
|
+
const q1 = q7 ^ q2;
|
|
72
|
+
const q3 = u0 ^ q7;
|
|
73
|
+
const q4 = u0 ^ q2;
|
|
74
|
+
const q5 = u1 ^ q4;
|
|
75
|
+
const q6 = u2 ^ u3;
|
|
76
|
+
const q10 = q6 ^ q7;
|
|
77
|
+
const q8 = u0 ^ q10;
|
|
78
|
+
const q9 = q8 ^ q2;
|
|
79
|
+
const q12 = z24 ^ q17;
|
|
80
|
+
const q15 = u7 ^ q4;
|
|
81
|
+
const m02 = u0 ^ u2;
|
|
82
|
+
const m15 = u1 ^ u5;
|
|
83
|
+
const q13 = m02 ^ m15;
|
|
84
|
+
const q14 = m02 ^ u7;
|
|
87
85
|
const q11 = u5;
|
|
88
86
|
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
const
|
|
94
|
-
const
|
|
95
|
-
const
|
|
96
|
-
const
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
const
|
|
100
|
-
const
|
|
101
|
-
const
|
|
102
|
-
const
|
|
103
|
-
const
|
|
104
|
-
const
|
|
105
|
-
const
|
|
106
|
-
|
|
107
|
-
const
|
|
108
|
-
const
|
|
109
|
-
const
|
|
110
|
-
const
|
|
111
|
-
const
|
|
112
|
-
const
|
|
113
|
-
const
|
|
114
|
-
const
|
|
115
|
-
|
|
116
|
-
const
|
|
117
|
-
|
|
118
|
-
const
|
|
119
|
-
const
|
|
120
|
-
const
|
|
121
|
-
const
|
|
122
|
-
const
|
|
123
|
-
const
|
|
124
|
-
const
|
|
125
|
-
const
|
|
126
|
-
const
|
|
127
|
-
const
|
|
128
|
-
const
|
|
129
|
-
const
|
|
130
|
-
const
|
|
131
|
-
const
|
|
132
|
-
const
|
|
133
|
-
const
|
|
134
|
-
|
|
135
|
-
const
|
|
136
|
-
|
|
137
|
-
const
|
|
138
|
-
|
|
139
|
-
const
|
|
140
|
-
|
|
141
|
-
const
|
|
142
|
-
const
|
|
143
|
-
|
|
144
|
-
const
|
|
145
|
-
const
|
|
146
|
-
|
|
147
|
-
const
|
|
148
|
-
const
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
const
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
st[offset +
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
st[offset +
|
|
163
|
-
|
|
87
|
+
const t20 = q6 & q12;
|
|
88
|
+
const t21 = q3 & q14;
|
|
89
|
+
const t22 = q1 & q16;
|
|
90
|
+
const t23 = q2 & q17;
|
|
91
|
+
const x0 = (q3 | q14) ^ (q0 & q7) ^ (t20 ^ t22);
|
|
92
|
+
const x1 = (q4 | q13) ^ (q10 & q11) ^ (t21 ^ t20);
|
|
93
|
+
const x2 = (q2 | q17) ^ (q5 & q9) ^ (t21 ^ t22);
|
|
94
|
+
const x3 = (q8 | q15) ^ t23 ^ (t21 ^ (q4 & q13));
|
|
95
|
+
|
|
96
|
+
const a = x1 & ~x3;
|
|
97
|
+
const b = x0 & ~x3;
|
|
98
|
+
const c = x3 & ~x1;
|
|
99
|
+
const d = x2 & ~x1;
|
|
100
|
+
const e = x0 ^ a;
|
|
101
|
+
const y0 = x3 ^ (x2 & ~e);
|
|
102
|
+
const f = x1 ^ b;
|
|
103
|
+
const y1 = c ^ (x2 & f);
|
|
104
|
+
const g = x2 ^ c;
|
|
105
|
+
const y2 = x1 ^ (x0 & ~g);
|
|
106
|
+
const h = x3 ^ d;
|
|
107
|
+
const y3 = a ^ (x0 & h);
|
|
108
|
+
const y02 = y2 ^ y0;
|
|
109
|
+
const y13 = y3 ^ y1;
|
|
110
|
+
const y23 = y3 ^ y2;
|
|
111
|
+
const y01 = y1 ^ y0;
|
|
112
|
+
const y00 = y02 ^ y13;
|
|
113
|
+
|
|
114
|
+
const a0 = y01 & q11;
|
|
115
|
+
const a1 = y0 & q12;
|
|
116
|
+
const a2 = y1 & q0;
|
|
117
|
+
const a3 = y23 & q17;
|
|
118
|
+
const a4 = y2 & q5;
|
|
119
|
+
const a5 = y3 & q15;
|
|
120
|
+
const a6 = y13 & q14;
|
|
121
|
+
const a7 = y00 & q16;
|
|
122
|
+
const a8 = y02 & q13;
|
|
123
|
+
const a9 = y01 & q7;
|
|
124
|
+
const a10 = y0 & q10;
|
|
125
|
+
const a11 = y1 & q6;
|
|
126
|
+
const a12 = y23 & q2;
|
|
127
|
+
const a13 = y2 & q9;
|
|
128
|
+
const a14 = y3 & q8;
|
|
129
|
+
const a15 = y13 & q3;
|
|
130
|
+
const a16 = y00 & q1;
|
|
131
|
+
const a17 = y02 & q4;
|
|
132
|
+
|
|
133
|
+
const r0 = a1 ^ a5;
|
|
134
|
+
const r1 = a9 ^ a15;
|
|
135
|
+
const r2 = a4 ^ r0;
|
|
136
|
+
const r3 = a2 ^ a10;
|
|
137
|
+
const r4 = a11 ^ a17;
|
|
138
|
+
const r5 = a8 ^ r1;
|
|
139
|
+
const r6 = a0 ^ a16;
|
|
140
|
+
const r7 = a7 ^ a13;
|
|
141
|
+
const r8 = a11 ^ a14;
|
|
142
|
+
const r9 = r3 ^ r4;
|
|
143
|
+
const r10 = r5 ^ r6;
|
|
144
|
+
const r11 = r2 ^ r9;
|
|
145
|
+
const r12 = a3 ^ r0;
|
|
146
|
+
const r13 = r7 ^ r8;
|
|
147
|
+
const r14 = r12 ^ r13;
|
|
148
|
+
st[offset] = r10 ^ r14;
|
|
149
|
+
const r15 = a6 ^ a10;
|
|
150
|
+
const r16 = r15 ^ r2;
|
|
151
|
+
st[offset + 1] = ~(r10 ^ r16);
|
|
152
|
+
st[offset + 2] = ~(a2 ^ r2);
|
|
153
|
+
const r17 = a12 ^ a13;
|
|
154
|
+
const r18 = a15 ^ r17;
|
|
155
|
+
st[offset + 3] = r18 ^ r11;
|
|
156
|
+
const r19 = a1 ^ a14;
|
|
157
|
+
const r20 = a17 ^ r3;
|
|
158
|
+
const r21 = r7 ^ r19;
|
|
159
|
+
const r22 = r5 ^ r20;
|
|
160
|
+
st[offset + 4] = r21 ^ r22;
|
|
161
|
+
const r23 = a9 ^ a12;
|
|
162
|
+
st[offset + 5] = r8 ^ r23;
|
|
163
|
+
st[offset + 6] = ~(r1 ^ r4);
|
|
164
|
+
st[offset + 7] = ~(a16 ^ r11);
|
|
164
165
|
}
|
|
165
166
|
|
|
166
167
|
/**
|
|
@@ -387,6 +388,76 @@ export function pack04(st: AesBlocks): void {
|
|
|
387
388
|
}
|
|
388
389
|
}
|
|
389
390
|
|
|
391
|
+
/**
|
|
392
|
+
* Inverse of pack04: unpack only blocks 0 and 4.
|
|
393
|
+
*/
|
|
394
|
+
export function unpack04(st: AesBlocks): void {
|
|
395
|
+
for (let i = 0; i < 32; i += 8) {
|
|
396
|
+
swapmove(st, i + 7, i + 3, 0x0f0f0f0f, 4);
|
|
397
|
+
swapmove(st, i + 6, i + 2, 0x0f0f0f0f, 4);
|
|
398
|
+
swapmove(st, i + 5, i + 1, 0x0f0f0f0f, 4);
|
|
399
|
+
swapmove(st, i + 4, i, 0x0f0f0f0f, 4);
|
|
400
|
+
swapmove(st, i + 7, i + 5, 0x33333333, 2);
|
|
401
|
+
swapmove(st, i + 6, i + 4, 0x33333333, 2);
|
|
402
|
+
swapmove(st, i + 3, i + 1, 0x33333333, 2);
|
|
403
|
+
swapmove(st, i + 2, i, 0x33333333, 2);
|
|
404
|
+
swapmove(st, i + 5, i + 4, 0x55555555, 1);
|
|
405
|
+
swapmove(st, i + 1, i, 0x55555555, 1);
|
|
406
|
+
}
|
|
407
|
+
|
|
408
|
+
swapmove(st, 12, 12 + 16, 0x0000ffff, 16);
|
|
409
|
+
swapmove(st, 8, 8 + 16, 0x0000ffff, 16);
|
|
410
|
+
swapmove(st, 4, 4 + 16, 0x0000ffff, 16);
|
|
411
|
+
swapmove(st, 0, 0 + 16, 0x0000ffff, 16);
|
|
412
|
+
|
|
413
|
+
swapmove(st, 4 + 16, 4 + 24, 0x00ff00ff, 8);
|
|
414
|
+
swapmove(st, 4, 4 + 8, 0x00ff00ff, 8);
|
|
415
|
+
swapmove(st, 0 + 16, 0 + 24, 0x00ff00ff, 8);
|
|
416
|
+
swapmove(st, 0, 0 + 8, 0x00ff00ff, 8);
|
|
417
|
+
}
|
|
418
|
+
|
|
419
|
+
/**
|
|
420
|
+
* Pack only block 0 (used for constant inputs in AEGIS-256).
|
|
421
|
+
*/
|
|
422
|
+
export function pack04_6(st: AesBlocks): void {
|
|
423
|
+
swapmove(st, 0, 0 + 8, 0x00ff00ff, 8);
|
|
424
|
+
swapmove(st, 0 + 16, 0 + 24, 0x00ff00ff, 8);
|
|
425
|
+
|
|
426
|
+
swapmove(st, 0, 0 + 16, 0x0000ffff, 16);
|
|
427
|
+
swapmove(st, 8, 8 + 16, 0x0000ffff, 16);
|
|
428
|
+
|
|
429
|
+
for (let i = 0; i < 32; i += 8) {
|
|
430
|
+
swapmove(st, i + 1, i, 0x55555555, 1);
|
|
431
|
+
swapmove(st, i + 2, i, 0x33333333, 2);
|
|
432
|
+
swapmove(st, i + 3, i + 1, 0x33333333, 2);
|
|
433
|
+
swapmove(st, i + 4, i, 0x0f0f0f0f, 4);
|
|
434
|
+
swapmove(st, i + 5, i + 1, 0x0f0f0f0f, 4);
|
|
435
|
+
swapmove(st, i + 6, i + 2, 0x0f0f0f0f, 4);
|
|
436
|
+
swapmove(st, i + 7, i + 3, 0x0f0f0f0f, 4);
|
|
437
|
+
}
|
|
438
|
+
}
|
|
439
|
+
|
|
440
|
+
/**
|
|
441
|
+
* Inverse of pack04_6: unpack only block 0.
|
|
442
|
+
*/
|
|
443
|
+
export function unpack04_6(st: AesBlocks): void {
|
|
444
|
+
for (let i = 0; i < 32; i += 8) {
|
|
445
|
+
swapmove(st, i + 7, i + 3, 0x0f0f0f0f, 4);
|
|
446
|
+
swapmove(st, i + 6, i + 2, 0x0f0f0f0f, 4);
|
|
447
|
+
swapmove(st, i + 5, i + 1, 0x0f0f0f0f, 4);
|
|
448
|
+
swapmove(st, i + 4, i, 0x0f0f0f0f, 4);
|
|
449
|
+
swapmove(st, i + 3, i + 1, 0x33333333, 2);
|
|
450
|
+
swapmove(st, i + 2, i, 0x33333333, 2);
|
|
451
|
+
swapmove(st, i + 1, i, 0x55555555, 1);
|
|
452
|
+
}
|
|
453
|
+
|
|
454
|
+
swapmove(st, 8, 8 + 16, 0x0000ffff, 16);
|
|
455
|
+
swapmove(st, 0, 0 + 16, 0x0000ffff, 16);
|
|
456
|
+
|
|
457
|
+
swapmove(st, 0 + 16, 0 + 24, 0x00ff00ff, 8);
|
|
458
|
+
swapmove(st, 0, 0 + 8, 0x00ff00ff, 8);
|
|
459
|
+
}
|
|
460
|
+
|
|
390
461
|
/**
|
|
391
462
|
* Computes the index into the bitsliced state array.
|
|
392
463
|
* @param block - Block index (0-7)
|
|
@@ -407,6 +478,16 @@ export function blocksRotr(st: AesBlocks): void {
|
|
|
407
478
|
}
|
|
408
479
|
}
|
|
409
480
|
|
|
481
|
+
/**
|
|
482
|
+
* Rotate within the bottom 6 lanes (for AEGIS-256, 6 blocks).
|
|
483
|
+
*/
|
|
484
|
+
export function blocksRotr6(st: AesBlocks): void {
|
|
485
|
+
for (let i = 0; i < 32; i++) {
|
|
486
|
+
st[i] =
|
|
487
|
+
(((st[i]! & 0xf8f8f8f8) >>> 1) | ((st[i]! & 0x04040404) << 5)) >>> 0;
|
|
488
|
+
}
|
|
489
|
+
}
|
|
490
|
+
|
|
410
491
|
/**
|
|
411
492
|
* Put a single AES block into the bitsliced state at the given block position.
|
|
412
493
|
*/
|