aegis-aead 0.2.1 → 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.
- package/README.md +29 -22
- package/dist/aegis128l.d.ts +33 -33
- package/dist/aegis128l.js +225 -235
- package/dist/aegis128x.d.ts +35 -35
- package/dist/aegis128x.js +348 -282
- package/dist/aegis256.d.ts +34 -51
- package/dist/aegis256.js +215 -206
- package/dist/aegis256x.d.ts +32 -33
- package/dist/aegis256x.js +333 -265
- package/dist/aes-bs.d.ts +46 -23
- package/dist/aes-bs.js +2273 -331
- package/dist/index.d.ts +4 -7
- package/dist/index.js +4 -7
- package/dist/random.d.ts +0 -1
- package/dist/random.js +0 -1
- package/dist/utils.d.ts +14 -0
- package/dist/utils.js +31 -0
- package/package.json +6 -6
- package/dist/aegis128l-bs.d.ts +0 -194
- package/dist/aegis128l-bs.d.ts.map +0 -1
- package/dist/aegis128l-bs.js +0 -549
- package/dist/aegis128l-bs.js.map +0 -1
- package/dist/aegis128l.d.ts.map +0 -1
- package/dist/aegis128l.js.map +0 -1
- package/dist/aegis128x.d.ts.map +0 -1
- package/dist/aegis128x.js.map +0 -1
- package/dist/aegis256-bs.d.ts +0 -183
- package/dist/aegis256-bs.d.ts.map +0 -1
- package/dist/aegis256-bs.js +0 -477
- package/dist/aegis256-bs.js.map +0 -1
- package/dist/aegis256.d.ts.map +0 -1
- package/dist/aegis256.js.map +0 -1
- package/dist/aegis256x.d.ts.map +0 -1
- package/dist/aegis256x.js.map +0 -1
- package/dist/aes-bs.d.ts.map +0 -1
- package/dist/aes-bs.js.map +0 -1
- package/dist/aes.d.ts +0 -81
- package/dist/aes.d.ts.map +0 -1
- package/dist/aes.js +0 -232
- package/dist/aes.js.map +0 -1
- package/dist/index.d.ts.map +0 -1
- package/dist/index.js.map +0 -1
- package/dist/random.d.ts.map +0 -1
- package/dist/random.js.map +0 -1
- package/src/aegis128l-bs.ts +0 -709
- package/src/aegis128l.ts +0 -653
- package/src/aegis128x.ts +0 -932
- package/src/aegis256-bs.ts +0 -625
- package/src/aegis256.ts +0 -597
- package/src/aegis256x.ts +0 -893
- package/src/aes-bs.ts +0 -459
- package/src/aes.ts +0 -271
- package/src/index.ts +0 -126
- package/src/random.ts +0 -41
- package/src/typed-array.d.ts +0 -18
package/dist/aegis128x.js
CHANGED
|
@@ -1,8 +1,20 @@
|
|
|
1
|
-
|
|
1
|
+
/**
|
|
2
|
+
* AEGIS-128X implementation with configurable parallelism degree.
|
|
3
|
+
* Extends AEGIS-128L with parallel lanes for improved performance on wide
|
|
4
|
+
* SIMD architectures. Each lane is an independent AEGIS-128L state kept in
|
|
5
|
+
* packed bitsliced form, built on the constant-time bitsliced AES core.
|
|
6
|
+
*/
|
|
7
|
+
import { aegisRound128, blockFromBytes, blocksPut, blockToBytes, blockXor, createAesBlock, createAesBlocks, keystream128, pack, packConstantInput128, unpack, wordIdx, } from "./aes-bs.js";
|
|
2
8
|
import { randomBytes } from "./random.js";
|
|
9
|
+
import { constantTimeEqual, zeroPad } from "./utils.js";
|
|
10
|
+
const C0 = new Uint32Array([
|
|
11
|
+
0x02010100, 0x0d080503, 0x59372215, 0x6279e990,
|
|
12
|
+
]);
|
|
13
|
+
const C1 = new Uint32Array([
|
|
14
|
+
0x55183ddb, 0xf12fc26d, 0x42311120, 0xdd28b573,
|
|
15
|
+
]);
|
|
3
16
|
/**
|
|
4
17
|
* AEGIS-128X cipher state with configurable parallelism degree.
|
|
5
|
-
* Extends AEGIS-128L with parallel AES rounds for improved performance on wide SIMD architectures.
|
|
6
18
|
*/
|
|
7
19
|
export class Aegis128XState {
|
|
8
20
|
/**
|
|
@@ -11,129 +23,120 @@ export class Aegis128XState {
|
|
|
11
23
|
*/
|
|
12
24
|
constructor(degree = 2) {
|
|
13
25
|
this.d = degree;
|
|
14
|
-
this.
|
|
15
|
-
this.
|
|
16
|
-
this.
|
|
17
|
-
this.
|
|
18
|
-
this.
|
|
19
|
-
this.
|
|
20
|
-
this.
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
buf[1] = degree - 1;
|
|
24
|
-
return buf;
|
|
25
|
-
});
|
|
26
|
+
this.halfRate = 16 * degree;
|
|
27
|
+
this.rateBytes = 32 * degree;
|
|
28
|
+
this.lanes = Array.from({ length: degree }, () => createAesBlocks());
|
|
29
|
+
this.ci = createAesBlocks();
|
|
30
|
+
this.ciZero = createAesBlocks();
|
|
31
|
+
this.tmp0 = createAesBlock();
|
|
32
|
+
this.tmp1 = createAesBlock();
|
|
33
|
+
this.z0 = createAesBlock();
|
|
34
|
+
this.z1 = createAesBlock();
|
|
26
35
|
}
|
|
27
36
|
/**
|
|
28
|
-
*
|
|
29
|
-
* @param key - 16-byte encryption key
|
|
30
|
-
* @param nonce - 16-byte nonce (must be unique per message)
|
|
37
|
+
* Returns the state blocks as byte arrays indexed [block][lane] (for testing).
|
|
31
38
|
*/
|
|
32
|
-
|
|
33
|
-
const
|
|
34
|
-
const
|
|
35
|
-
const
|
|
36
|
-
xorBlocksTo(key, nonce, keyXorNonce);
|
|
37
|
-
xorBlocksTo(key, C0, keyXorC0);
|
|
38
|
-
xorBlocksTo(key, C1, keyXorC1);
|
|
39
|
-
for (let i = 0; i < this.d; i++) {
|
|
40
|
-
this.v[0][i].set(keyXorNonce);
|
|
41
|
-
this.v[1][i].set(C1);
|
|
42
|
-
this.v[2][i].set(C0);
|
|
43
|
-
this.v[3][i].set(C1);
|
|
44
|
-
this.v[4][i].set(keyXorNonce);
|
|
45
|
-
this.v[5][i].set(keyXorC0);
|
|
46
|
-
this.v[6][i].set(keyXorC1);
|
|
47
|
-
this.v[7][i].set(keyXorC0);
|
|
48
|
-
}
|
|
49
|
-
const nonceV = new Uint8Array(16 * this.d);
|
|
50
|
-
const keyV = new Uint8Array(16 * this.d);
|
|
39
|
+
get v() {
|
|
40
|
+
const out = Array.from({ length: 8 }, () => []);
|
|
41
|
+
const unpacked = createAesBlocks();
|
|
42
|
+
const w = createAesBlock();
|
|
51
43
|
for (let i = 0; i < this.d; i++) {
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
const
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
for (let j = 0; j < 16; j++)
|
|
61
|
-
this.v[7][i][j] ^= ctx[j];
|
|
44
|
+
unpacked.set(this.lanes[i]);
|
|
45
|
+
unpack(unpacked);
|
|
46
|
+
for (let b = 0; b < 8; b++) {
|
|
47
|
+
for (let j = 0; j < 4; j++)
|
|
48
|
+
w[j] = unpacked[wordIdx(b, j)];
|
|
49
|
+
const bytes = new Uint8Array(16);
|
|
50
|
+
blockToBytes(bytes, w);
|
|
51
|
+
out[b].push(bytes);
|
|
62
52
|
}
|
|
63
|
-
this.update(nonceV, keyV);
|
|
64
53
|
}
|
|
54
|
+
return out;
|
|
65
55
|
}
|
|
66
56
|
/**
|
|
67
|
-
*
|
|
68
|
-
* @param
|
|
69
|
-
* @param
|
|
57
|
+
* Initializes the state with a key and nonce.
|
|
58
|
+
* @param key - 16-byte encryption key
|
|
59
|
+
* @param nonce - 16-byte nonce (must be unique per message)
|
|
70
60
|
*/
|
|
71
|
-
|
|
72
|
-
const
|
|
73
|
-
const
|
|
61
|
+
init(key, nonce) {
|
|
62
|
+
const k = createAesBlock();
|
|
63
|
+
const n = createAesBlock();
|
|
64
|
+
const kn = createAesBlock();
|
|
65
|
+
const kc0 = createAesBlock();
|
|
66
|
+
const kc1 = createAesBlock();
|
|
67
|
+
blockFromBytes(k, key);
|
|
68
|
+
blockFromBytes(n, nonce);
|
|
69
|
+
blockXor(kn, k, n);
|
|
70
|
+
blockXor(kc0, k, C0);
|
|
71
|
+
blockXor(kc1, k, C1);
|
|
72
|
+
const base = createAesBlocks();
|
|
73
|
+
blocksPut(base, kn, 0);
|
|
74
|
+
blocksPut(base, C1, 1);
|
|
75
|
+
blocksPut(base, C0, 2);
|
|
76
|
+
blocksPut(base, C1, 3);
|
|
77
|
+
blocksPut(base, kn, 4);
|
|
78
|
+
blocksPut(base, kc0, 5);
|
|
79
|
+
blocksPut(base, kc1, 6);
|
|
80
|
+
blocksPut(base, kc0, 7);
|
|
81
|
+
pack(base);
|
|
82
|
+
const ciNK = createAesBlocks();
|
|
83
|
+
packConstantInput128(ciNK, n, k);
|
|
84
|
+
const ctx = createAesBlock();
|
|
85
|
+
const deltas = [];
|
|
74
86
|
for (let i = 0; i < this.d; i++) {
|
|
75
|
-
|
|
76
|
-
const
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
xorBlocksTo(this.v[4][i], m1i, tmp);
|
|
83
|
-
aesRoundTo(this.v[3][i], tmp, newV[4][i]);
|
|
84
|
-
aesRoundTo(this.v[4][i], this.v[5][i], newV[5][i]);
|
|
85
|
-
aesRoundTo(this.v[5][i], this.v[6][i], newV[6][i]);
|
|
86
|
-
aesRoundTo(this.v[6][i], this.v[7][i], newV[7][i]);
|
|
87
|
+
this.lanes[i].set(base);
|
|
88
|
+
const delta = createAesBlocks();
|
|
89
|
+
ctx[0] = i | ((this.d - 1) << 8);
|
|
90
|
+
blocksPut(delta, ctx, 3);
|
|
91
|
+
blocksPut(delta, ctx, 7);
|
|
92
|
+
pack(delta);
|
|
93
|
+
deltas.push(delta);
|
|
87
94
|
}
|
|
88
|
-
for (let
|
|
95
|
+
for (let round = 0; round < 10; round++) {
|
|
89
96
|
for (let i = 0; i < this.d; i++) {
|
|
90
|
-
this.
|
|
97
|
+
const st = this.lanes[i];
|
|
98
|
+
const delta = deltas[i];
|
|
99
|
+
for (let w = 0; w < 32; w++)
|
|
100
|
+
st[w] = st[w] ^ delta[w];
|
|
101
|
+
aegisRound128(st, ciNK);
|
|
91
102
|
}
|
|
92
103
|
}
|
|
93
104
|
}
|
|
94
105
|
/**
|
|
95
106
|
* Absorbs an associated data block into the state.
|
|
96
|
-
* @param ai -
|
|
107
|
+
* @param ai - Buffer holding the 32*degree-byte associated data block
|
|
108
|
+
* @param off - Offset of the block within the buffer
|
|
97
109
|
*/
|
|
98
|
-
absorb(ai) {
|
|
99
|
-
const halfRateBytes = this.rate / 16;
|
|
100
|
-
const rateBytes = this.rate / 8;
|
|
101
|
-
this.update(ai.subarray(0, halfRateBytes), ai.subarray(halfRateBytes, rateBytes));
|
|
102
|
-
}
|
|
103
|
-
computeZ() {
|
|
104
|
-
const z0 = this.z0;
|
|
105
|
-
const z1 = this.z1;
|
|
106
|
-
const tmp = this.tmp;
|
|
110
|
+
absorb(ai, off = 0) {
|
|
107
111
|
for (let i = 0; i < this.d; i++) {
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
z0[off + j] ^= tmp[j];
|
|
113
|
-
xorBlocksTo(this.v[2][i], this.v[5][i], z1.subarray(off, off + 16));
|
|
114
|
-
andBlocksTo(this.v[6][i], this.v[7][i], tmp);
|
|
115
|
-
for (let j = 0; j < 16; j++)
|
|
116
|
-
z1[off + j] ^= tmp[j];
|
|
112
|
+
blockFromBytes(this.tmp0, ai, off + i * 16);
|
|
113
|
+
blockFromBytes(this.tmp1, ai, off + this.halfRate + i * 16);
|
|
114
|
+
packConstantInput128(this.ci, this.tmp0, this.tmp1);
|
|
115
|
+
aegisRound128(this.lanes[i], this.ci);
|
|
117
116
|
}
|
|
118
117
|
}
|
|
119
118
|
/**
|
|
120
119
|
* Encrypts a plaintext block and writes to output buffer.
|
|
121
|
-
* @param xi -
|
|
122
|
-
* @param out - Output buffer
|
|
120
|
+
* @param xi - Buffer holding the 32*degree-byte plaintext block
|
|
121
|
+
* @param out - Output buffer receiving the ciphertext block
|
|
122
|
+
* @param inOff - Offset of the plaintext block within xi
|
|
123
|
+
* @param outOff - Offset of the ciphertext block within out
|
|
123
124
|
*/
|
|
124
|
-
encTo(xi, out) {
|
|
125
|
-
this.
|
|
126
|
-
const
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
125
|
+
encTo(xi, out, inOff = 0, outOff = 0) {
|
|
126
|
+
const t0 = this.tmp0;
|
|
127
|
+
const t1 = this.tmp1;
|
|
128
|
+
for (let i = 0; i < this.d; i++) {
|
|
129
|
+
const st = this.lanes[i];
|
|
130
|
+
keystream128(st, this.z0, this.z1);
|
|
131
|
+
blockFromBytes(t0, xi, inOff + i * 16);
|
|
132
|
+
blockFromBytes(t1, xi, inOff + this.halfRate + i * 16);
|
|
133
|
+
packConstantInput128(this.ci, t0, t1);
|
|
134
|
+
aegisRound128(st, this.ci);
|
|
135
|
+
blockXor(t0, t0, this.z0);
|
|
136
|
+
blockXor(t1, t1, this.z1);
|
|
137
|
+
blockToBytes(out, t0, outOff + i * 16);
|
|
138
|
+
blockToBytes(out, t1, outOff + this.halfRate + i * 16);
|
|
139
|
+
}
|
|
137
140
|
}
|
|
138
141
|
/**
|
|
139
142
|
* Encrypts a plaintext block.
|
|
@@ -141,29 +144,32 @@ export class Aegis128XState {
|
|
|
141
144
|
* @returns Ciphertext block of the same size
|
|
142
145
|
*/
|
|
143
146
|
enc(xi) {
|
|
144
|
-
const
|
|
145
|
-
const out = new Uint8Array(rateBytes);
|
|
147
|
+
const out = new Uint8Array(this.rateBytes);
|
|
146
148
|
this.encTo(xi, out);
|
|
147
149
|
return out;
|
|
148
150
|
}
|
|
149
151
|
/**
|
|
150
152
|
* Decrypts a ciphertext block and writes to output buffer.
|
|
151
|
-
* @param ci -
|
|
152
|
-
* @param out - Output buffer
|
|
153
|
+
* @param ci - Buffer holding the 32*degree-byte ciphertext block
|
|
154
|
+
* @param out - Output buffer receiving the plaintext block
|
|
155
|
+
* @param inOff - Offset of the ciphertext block within ci
|
|
156
|
+
* @param outOff - Offset of the plaintext block within out
|
|
153
157
|
*/
|
|
154
|
-
decTo(ci, out) {
|
|
155
|
-
this.
|
|
156
|
-
const
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
158
|
+
decTo(ci, out, inOff = 0, outOff = 0) {
|
|
159
|
+
const msg0 = this.tmp0;
|
|
160
|
+
const msg1 = this.tmp1;
|
|
161
|
+
for (let i = 0; i < this.d; i++) {
|
|
162
|
+
const st = this.lanes[i];
|
|
163
|
+
blockFromBytes(msg0, ci, inOff + i * 16);
|
|
164
|
+
blockFromBytes(msg1, ci, inOff + this.halfRate + i * 16);
|
|
165
|
+
keystream128(st, this.z0, this.z1);
|
|
166
|
+
blockXor(msg0, msg0, this.z0);
|
|
167
|
+
blockXor(msg1, msg1, this.z1);
|
|
168
|
+
packConstantInput128(this.ci, msg0, msg1);
|
|
169
|
+
aegisRound128(st, this.ci);
|
|
170
|
+
blockToBytes(out, msg0, outOff + i * 16);
|
|
171
|
+
blockToBytes(out, msg1, outOff + this.halfRate + i * 16);
|
|
172
|
+
}
|
|
167
173
|
}
|
|
168
174
|
/**
|
|
169
175
|
* Decrypts a ciphertext block.
|
|
@@ -171,31 +177,13 @@ export class Aegis128XState {
|
|
|
171
177
|
* @returns Plaintext block of the same size
|
|
172
178
|
*/
|
|
173
179
|
dec(ci) {
|
|
174
|
-
const
|
|
175
|
-
const out = new Uint8Array(rateBytes);
|
|
180
|
+
const out = new Uint8Array(this.rateBytes);
|
|
176
181
|
this.decTo(ci, out);
|
|
177
182
|
return out;
|
|
178
183
|
}
|
|
179
|
-
/**
|
|
180
|
-
* Encrypts a plaintext block in-place.
|
|
181
|
-
* @param block - Buffer (plaintext in, ciphertext out), size 32*degree bytes
|
|
182
|
-
*/
|
|
183
184
|
encInPlace(block) {
|
|
184
|
-
this.
|
|
185
|
-
const z0 = this.z0;
|
|
186
|
-
const z1 = this.z1;
|
|
187
|
-
const halfRateBytes = this.rate / 16;
|
|
188
|
-
const rateBytes = this.rate / 8;
|
|
189
|
-
this.update(block.subarray(0, halfRateBytes), block.subarray(halfRateBytes, rateBytes));
|
|
190
|
-
for (let i = 0; i < halfRateBytes; i++)
|
|
191
|
-
block[i] ^= z0[i];
|
|
192
|
-
for (let i = 0; i < halfRateBytes; i++)
|
|
193
|
-
block[halfRateBytes + i] ^= z1[i];
|
|
185
|
+
this.encTo(block, block);
|
|
194
186
|
}
|
|
195
|
-
/**
|
|
196
|
-
* Decrypts a ciphertext block in-place.
|
|
197
|
-
* @param block - Buffer (ciphertext in, plaintext out), size 32*degree bytes
|
|
198
|
-
*/
|
|
199
187
|
decInPlace(block) {
|
|
200
188
|
this.decTo(block, block);
|
|
201
189
|
}
|
|
@@ -205,138 +193,230 @@ export class Aegis128XState {
|
|
|
205
193
|
* @returns Decrypted plaintext of the same length
|
|
206
194
|
*/
|
|
207
195
|
decPartial(cn) {
|
|
208
|
-
this.
|
|
209
|
-
const
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
const
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
out[i] = t0[i] ^ z0[i];
|
|
219
|
-
for (let i = 0; i < halfRateBytes; i++)
|
|
220
|
-
out[halfRateBytes + i] = t1[i] ^ z1[i];
|
|
196
|
+
const padded = zeroPad(cn, this.rateBytes);
|
|
197
|
+
const ks = new Uint8Array(this.rateBytes);
|
|
198
|
+
for (let i = 0; i < this.d; i++) {
|
|
199
|
+
keystream128(this.lanes[i], this.z0, this.z1);
|
|
200
|
+
blockToBytes(ks, this.z0, i * 16);
|
|
201
|
+
blockToBytes(ks, this.z1, this.halfRate + i * 16);
|
|
202
|
+
}
|
|
203
|
+
const out = new Uint8Array(this.rateBytes);
|
|
204
|
+
for (let j = 0; j < this.rateBytes; j++)
|
|
205
|
+
out[j] = padded[j] ^ ks[j];
|
|
221
206
|
const xn = new Uint8Array(out.subarray(0, cn.length));
|
|
222
|
-
|
|
223
|
-
|
|
207
|
+
out.fill(0, cn.length);
|
|
208
|
+
for (let i = 0; i < this.d; i++) {
|
|
209
|
+
blockFromBytes(this.tmp0, out, i * 16);
|
|
210
|
+
blockFromBytes(this.tmp1, out, this.halfRate + i * 16);
|
|
211
|
+
packConstantInput128(this.ci, this.tmp0, this.tmp1);
|
|
212
|
+
aegisRound128(this.lanes[i], this.ci);
|
|
213
|
+
}
|
|
224
214
|
return xn;
|
|
225
215
|
}
|
|
226
216
|
/**
|
|
227
217
|
* Finalizes encryption/decryption and produces an authentication tag.
|
|
228
|
-
* @param
|
|
229
|
-
* @param
|
|
218
|
+
* @param adLen - Associated data length in bytes
|
|
219
|
+
* @param msgLen - Message length in bytes
|
|
230
220
|
* @param tagLen - Tag length (16 or 32 bytes)
|
|
231
221
|
* @returns Authentication tag
|
|
232
222
|
*/
|
|
233
|
-
finalize(
|
|
234
|
-
|
|
235
|
-
const
|
|
223
|
+
finalize(adLen, msgLen, tagLen = 16) {
|
|
224
|
+
const u = this.tmp0;
|
|
225
|
+
const t = this.tmp1;
|
|
226
|
+
u[0] = (adLen * 8) & 0xffffffff;
|
|
227
|
+
u[1] = Math.floor((adLen * 8) / 0x100000000);
|
|
228
|
+
u[2] = (msgLen * 8) & 0xffffffff;
|
|
229
|
+
u[3] = Math.floor((msgLen * 8) / 0x100000000);
|
|
230
|
+
const unpacked = createAesBlocks();
|
|
236
231
|
for (let i = 0; i < this.d; i++) {
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
232
|
+
const st = this.lanes[i];
|
|
233
|
+
unpacked.set(st);
|
|
234
|
+
unpack(unpacked);
|
|
235
|
+
for (let j = 0; j < 4; j++)
|
|
236
|
+
t[j] = u[j] ^ unpacked[wordIdx(2, j)];
|
|
237
|
+
packConstantInput128(this.ci, t, t);
|
|
238
|
+
for (let round = 0; round < 7; round++) {
|
|
239
|
+
aegisRound128(st, this.ci);
|
|
240
|
+
}
|
|
241
|
+
unpack(st);
|
|
241
242
|
}
|
|
242
243
|
if (tagLen === 16) {
|
|
243
|
-
|
|
244
|
+
const tagBlock = createAesBlock();
|
|
244
245
|
for (let i = 0; i < this.d; i++) {
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
246
|
+
const st = this.lanes[i];
|
|
247
|
+
for (let j = 0; j < 4; j++) {
|
|
248
|
+
tagBlock[j] =
|
|
249
|
+
tagBlock[j] ^
|
|
250
|
+
st[wordIdx(0, j)] ^
|
|
251
|
+
st[wordIdx(1, j)] ^
|
|
252
|
+
st[wordIdx(2, j)] ^
|
|
253
|
+
st[wordIdx(3, j)] ^
|
|
254
|
+
st[wordIdx(4, j)] ^
|
|
255
|
+
st[wordIdx(5, j)] ^
|
|
256
|
+
st[wordIdx(6, j)];
|
|
257
|
+
}
|
|
252
258
|
}
|
|
259
|
+
const tag = new Uint8Array(16);
|
|
260
|
+
blockToBytes(tag, tagBlock);
|
|
253
261
|
return tag;
|
|
254
262
|
}
|
|
255
263
|
else {
|
|
256
|
-
|
|
257
|
-
|
|
264
|
+
const tagBlock0 = createAesBlock();
|
|
265
|
+
const tagBlock1 = createAesBlock();
|
|
258
266
|
for (let i = 0; i < this.d; i++) {
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
+
const st = this.lanes[i];
|
|
268
|
+
for (let j = 0; j < 4; j++) {
|
|
269
|
+
tagBlock0[j] =
|
|
270
|
+
tagBlock0[j] ^
|
|
271
|
+
st[wordIdx(0, j)] ^
|
|
272
|
+
st[wordIdx(1, j)] ^
|
|
273
|
+
st[wordIdx(2, j)] ^
|
|
274
|
+
st[wordIdx(3, j)];
|
|
275
|
+
tagBlock1[j] =
|
|
276
|
+
tagBlock1[j] ^
|
|
277
|
+
st[wordIdx(4, j)] ^
|
|
278
|
+
st[wordIdx(5, j)] ^
|
|
279
|
+
st[wordIdx(6, j)] ^
|
|
280
|
+
st[wordIdx(7, j)];
|
|
281
|
+
}
|
|
267
282
|
}
|
|
268
|
-
|
|
283
|
+
const tag = new Uint8Array(32);
|
|
284
|
+
blockToBytes(tag, tagBlock0);
|
|
285
|
+
blockToBytes(tag, tagBlock1, 16);
|
|
286
|
+
return tag;
|
|
269
287
|
}
|
|
270
288
|
}
|
|
271
289
|
/**
|
|
272
290
|
* Finalizes MAC computation and produces an authentication tag.
|
|
273
291
|
* Uses a different finalization procedure than encryption/decryption.
|
|
274
|
-
* @param
|
|
292
|
+
* @param dataLen - Data length in bytes
|
|
275
293
|
* @param tagLen - Tag length (16 or 32 bytes)
|
|
276
294
|
* @returns Authentication tag
|
|
277
295
|
*/
|
|
278
|
-
finalizeMac(
|
|
279
|
-
|
|
280
|
-
const
|
|
296
|
+
finalizeMac(dataLen, tagLen = 16) {
|
|
297
|
+
const u = this.tmp0;
|
|
298
|
+
const t = this.tmp1;
|
|
299
|
+
u[0] = (dataLen * 8) & 0xffffffff;
|
|
300
|
+
u[1] = Math.floor((dataLen * 8) / 0x100000000);
|
|
301
|
+
u[2] = tagLen * 8;
|
|
302
|
+
u[3] = 0;
|
|
303
|
+
const unpacked = createAesBlocks();
|
|
281
304
|
for (let i = 0; i < this.d; i++) {
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
let ti = xorBlocks(this.v[0][i], this.v[1][i]);
|
|
291
|
-
ti = xorBlocks(ti, this.v[2][i]);
|
|
292
|
-
ti = xorBlocks(ti, this.v[3][i]);
|
|
293
|
-
ti = xorBlocks(ti, this.v[4][i]);
|
|
294
|
-
ti = xorBlocks(ti, this.v[5][i]);
|
|
295
|
-
ti = xorBlocks(ti, this.v[6][i]);
|
|
296
|
-
tags = concatBytes(tags, ti);
|
|
297
|
-
}
|
|
298
|
-
}
|
|
299
|
-
else {
|
|
300
|
-
for (let i = 1; i < this.d; i++) {
|
|
301
|
-
let ti0 = xorBlocks(this.v[0][i], this.v[1][i]);
|
|
302
|
-
ti0 = xorBlocks(ti0, this.v[2][i]);
|
|
303
|
-
ti0 = xorBlocks(ti0, this.v[3][i]);
|
|
304
|
-
let ti1 = xorBlocks(this.v[4][i], this.v[5][i]);
|
|
305
|
-
ti1 = xorBlocks(ti1, this.v[6][i]);
|
|
306
|
-
ti1 = xorBlocks(ti1, this.v[7][i]);
|
|
307
|
-
tags = concatBytes(tags, ti0, ti1);
|
|
305
|
+
const st = this.lanes[i];
|
|
306
|
+
unpacked.set(st);
|
|
307
|
+
unpack(unpacked);
|
|
308
|
+
for (let j = 0; j < 4; j++)
|
|
309
|
+
t[j] = u[j] ^ unpacked[wordIdx(2, j)];
|
|
310
|
+
packConstantInput128(this.ci, t, t);
|
|
311
|
+
for (let round = 0; round < 7; round++) {
|
|
312
|
+
aegisRound128(st, this.ci);
|
|
308
313
|
}
|
|
309
314
|
}
|
|
310
315
|
if (this.d > 1) {
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
const
|
|
315
|
-
this.
|
|
316
|
+
let tags;
|
|
317
|
+
if (tagLen === 16) {
|
|
318
|
+
tags = new Uint8Array(16 * this.d);
|
|
319
|
+
const tb = createAesBlock();
|
|
320
|
+
for (let i = 0; i < this.d; i++) {
|
|
321
|
+
unpacked.set(this.lanes[i]);
|
|
322
|
+
unpack(unpacked);
|
|
323
|
+
for (let j = 0; j < 4; j++) {
|
|
324
|
+
tb[j] =
|
|
325
|
+
unpacked[wordIdx(0, j)] ^
|
|
326
|
+
unpacked[wordIdx(1, j)] ^
|
|
327
|
+
unpacked[wordIdx(2, j)] ^
|
|
328
|
+
unpacked[wordIdx(3, j)] ^
|
|
329
|
+
unpacked[wordIdx(4, j)] ^
|
|
330
|
+
unpacked[wordIdx(5, j)] ^
|
|
331
|
+
unpacked[wordIdx(6, j)];
|
|
332
|
+
}
|
|
333
|
+
blockToBytes(tags, tb, i * 16);
|
|
334
|
+
}
|
|
335
|
+
}
|
|
336
|
+
else {
|
|
337
|
+
tags = new Uint8Array(32 * (this.d - 1));
|
|
338
|
+
const tb0 = createAesBlock();
|
|
339
|
+
const tb1 = createAesBlock();
|
|
340
|
+
for (let i = 1; i < this.d; i++) {
|
|
341
|
+
unpacked.set(this.lanes[i]);
|
|
342
|
+
unpack(unpacked);
|
|
343
|
+
for (let j = 0; j < 4; j++) {
|
|
344
|
+
tb0[j] =
|
|
345
|
+
unpacked[wordIdx(0, j)] ^
|
|
346
|
+
unpacked[wordIdx(1, j)] ^
|
|
347
|
+
unpacked[wordIdx(2, j)] ^
|
|
348
|
+
unpacked[wordIdx(3, j)];
|
|
349
|
+
tb1[j] =
|
|
350
|
+
unpacked[wordIdx(4, j)] ^
|
|
351
|
+
unpacked[wordIdx(5, j)] ^
|
|
352
|
+
unpacked[wordIdx(6, j)] ^
|
|
353
|
+
unpacked[wordIdx(7, j)];
|
|
354
|
+
}
|
|
355
|
+
blockToBytes(tags, tb0, (i - 1) * 32);
|
|
356
|
+
blockToBytes(tags, tb1, (i - 1) * 32 + 16);
|
|
357
|
+
}
|
|
316
358
|
}
|
|
317
|
-
|
|
318
|
-
|
|
359
|
+
for (let off = 0; off + 32 <= tags.length; off += 32) {
|
|
360
|
+
blockFromBytes(this.tmp0, tags, off);
|
|
361
|
+
blockFromBytes(this.tmp1, tags, off + 16);
|
|
362
|
+
packConstantInput128(this.ci, this.tmp0, this.tmp1);
|
|
363
|
+
aegisRound128(this.lanes[0], this.ci);
|
|
364
|
+
for (let i = 1; i < this.d; i++) {
|
|
365
|
+
aegisRound128(this.lanes[i], this.ciZero);
|
|
366
|
+
}
|
|
367
|
+
}
|
|
368
|
+
unpacked.set(this.lanes[0]);
|
|
369
|
+
unpack(unpacked);
|
|
370
|
+
t[0] = this.d ^ unpacked[wordIdx(2, 0)];
|
|
371
|
+
t[1] = unpacked[wordIdx(2, 1)];
|
|
372
|
+
t[2] = (tagLen * 8) ^ unpacked[wordIdx(2, 2)];
|
|
373
|
+
t[3] = unpacked[wordIdx(2, 3)];
|
|
374
|
+
packConstantInput128(this.ci, t, t);
|
|
319
375
|
for (let round = 0; round < 7; round++) {
|
|
320
|
-
this.
|
|
376
|
+
aegisRound128(this.lanes[0], this.ci);
|
|
377
|
+
for (let i = 1; i < this.d; i++) {
|
|
378
|
+
aegisRound128(this.lanes[i], this.ciZero);
|
|
379
|
+
}
|
|
321
380
|
}
|
|
322
381
|
}
|
|
382
|
+
const st = createAesBlocks();
|
|
383
|
+
st.set(this.lanes[0]);
|
|
384
|
+
unpack(st);
|
|
323
385
|
if (tagLen === 16) {
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
386
|
+
const tag = new Uint8Array(16);
|
|
387
|
+
const tagBlock = createAesBlock();
|
|
388
|
+
for (let j = 0; j < 4; j++) {
|
|
389
|
+
tagBlock[j] =
|
|
390
|
+
st[wordIdx(0, j)] ^
|
|
391
|
+
st[wordIdx(1, j)] ^
|
|
392
|
+
st[wordIdx(2, j)] ^
|
|
393
|
+
st[wordIdx(3, j)] ^
|
|
394
|
+
st[wordIdx(4, j)] ^
|
|
395
|
+
st[wordIdx(5, j)] ^
|
|
396
|
+
st[wordIdx(6, j)];
|
|
397
|
+
}
|
|
398
|
+
blockToBytes(tag, tagBlock);
|
|
330
399
|
return tag;
|
|
331
400
|
}
|
|
332
401
|
else {
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
let
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
402
|
+
const tag = new Uint8Array(32);
|
|
403
|
+
const tagBlock0 = createAesBlock();
|
|
404
|
+
const tagBlock1 = createAesBlock();
|
|
405
|
+
for (let j = 0; j < 4; j++) {
|
|
406
|
+
tagBlock0[j] =
|
|
407
|
+
st[wordIdx(0, j)] ^
|
|
408
|
+
st[wordIdx(1, j)] ^
|
|
409
|
+
st[wordIdx(2, j)] ^
|
|
410
|
+
st[wordIdx(3, j)];
|
|
411
|
+
tagBlock1[j] =
|
|
412
|
+
st[wordIdx(4, j)] ^
|
|
413
|
+
st[wordIdx(5, j)] ^
|
|
414
|
+
st[wordIdx(6, j)] ^
|
|
415
|
+
st[wordIdx(7, j)];
|
|
416
|
+
}
|
|
417
|
+
blockToBytes(tag, tagBlock0);
|
|
418
|
+
blockToBytes(tag, tagBlock1, 16);
|
|
419
|
+
return tag;
|
|
340
420
|
}
|
|
341
421
|
}
|
|
342
422
|
}
|
|
@@ -352,19 +432,23 @@ export class Aegis128XState {
|
|
|
352
432
|
*/
|
|
353
433
|
export function aegis128XEncryptDetached(msg, ad, key, nonce, tagLen = 16, degree = 2) {
|
|
354
434
|
const state = new Aegis128XState(degree);
|
|
355
|
-
const rateBytes =
|
|
435
|
+
const rateBytes = 32 * degree;
|
|
356
436
|
state.init(key, nonce);
|
|
357
437
|
const adPadded = zeroPad(ad, rateBytes);
|
|
358
438
|
for (let i = 0; i + rateBytes <= adPadded.length; i += rateBytes) {
|
|
359
|
-
state.absorb(adPadded
|
|
439
|
+
state.absorb(adPadded, i);
|
|
440
|
+
}
|
|
441
|
+
const ciphertext = new Uint8Array(msg.length);
|
|
442
|
+
const fullBlocks = Math.floor(msg.length / rateBytes) * rateBytes;
|
|
443
|
+
for (let i = 0; i < fullBlocks; i += rateBytes) {
|
|
444
|
+
state.encTo(msg, ciphertext, i, i);
|
|
360
445
|
}
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
446
|
+
if (msg.length > fullBlocks) {
|
|
447
|
+
const lastBlock = zeroPad(msg.subarray(fullBlocks), rateBytes);
|
|
448
|
+
const encBlock = state.enc(lastBlock);
|
|
449
|
+
ciphertext.set(encBlock.subarray(0, msg.length - fullBlocks), fullBlocks);
|
|
365
450
|
}
|
|
366
|
-
const tag = state.finalize(
|
|
367
|
-
const ciphertext = new Uint8Array(ct.subarray(0, msg.length));
|
|
451
|
+
const tag = state.finalize(ad.length, msg.length, tagLen);
|
|
368
452
|
return { ciphertext, tag };
|
|
369
453
|
}
|
|
370
454
|
/**
|
|
@@ -380,22 +464,21 @@ export function aegis128XEncryptDetached(msg, ad, key, nonce, tagLen = 16, degre
|
|
|
380
464
|
export function aegis128XDecryptDetached(ct, tag, ad, key, nonce, degree = 2) {
|
|
381
465
|
const tagLen = tag.length;
|
|
382
466
|
const state = new Aegis128XState(degree);
|
|
383
|
-
const rateBytes =
|
|
467
|
+
const rateBytes = 32 * degree;
|
|
384
468
|
state.init(key, nonce);
|
|
385
469
|
const adPadded = zeroPad(ad, rateBytes);
|
|
386
470
|
for (let i = 0; i + rateBytes <= adPadded.length; i += rateBytes) {
|
|
387
|
-
state.absorb(adPadded
|
|
471
|
+
state.absorb(adPadded, i);
|
|
388
472
|
}
|
|
389
|
-
const
|
|
390
|
-
const
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
state.decTo(ct.subarray(i, i + rateBytes), msg.subarray(i, i + rateBytes));
|
|
473
|
+
const msg = new Uint8Array(ct.length);
|
|
474
|
+
const fullBlocks = Math.floor(ct.length / rateBytes) * rateBytes;
|
|
475
|
+
for (let i = 0; i < fullBlocks; i += rateBytes) {
|
|
476
|
+
state.decTo(ct, msg, i, i);
|
|
394
477
|
}
|
|
395
|
-
if (
|
|
396
|
-
msg.set(state.decPartial(
|
|
478
|
+
if (ct.length > fullBlocks) {
|
|
479
|
+
msg.set(state.decPartial(ct.subarray(fullBlocks)), fullBlocks);
|
|
397
480
|
}
|
|
398
|
-
const expectedTag = state.finalize(
|
|
481
|
+
const expectedTag = state.finalize(ad.length, msg.length, tagLen);
|
|
399
482
|
if (!constantTimeEqual(tag, expectedTag)) {
|
|
400
483
|
msg.fill(0);
|
|
401
484
|
return null;
|
|
@@ -415,16 +498,16 @@ export function aegis128XDecryptDetached(ct, tag, ad, key, nonce, degree = 2) {
|
|
|
415
498
|
*/
|
|
416
499
|
export function aegis128XEncryptDetachedInPlace(data, ad, key, nonce, tagLen = 16, degree = 2) {
|
|
417
500
|
const state = new Aegis128XState(degree);
|
|
418
|
-
const rateBytes =
|
|
501
|
+
const rateBytes = 32 * degree;
|
|
419
502
|
state.init(key, nonce);
|
|
420
503
|
const adPadded = zeroPad(ad, rateBytes);
|
|
421
504
|
for (let i = 0; i + rateBytes <= adPadded.length; i += rateBytes) {
|
|
422
|
-
state.absorb(adPadded
|
|
505
|
+
state.absorb(adPadded, i);
|
|
423
506
|
}
|
|
424
507
|
const msgLen = data.length;
|
|
425
508
|
const fullBlocksLen = Math.floor(msgLen / rateBytes) * rateBytes;
|
|
426
509
|
for (let i = 0; i < fullBlocksLen; i += rateBytes) {
|
|
427
|
-
state.
|
|
510
|
+
state.encTo(data, data, i, i);
|
|
428
511
|
}
|
|
429
512
|
if (msgLen > fullBlocksLen) {
|
|
430
513
|
const lastPartial = data.subarray(fullBlocksLen);
|
|
@@ -432,7 +515,7 @@ export function aegis128XEncryptDetachedInPlace(data, ad, key, nonce, tagLen = 1
|
|
|
432
515
|
const encBlock = state.enc(lastBlock);
|
|
433
516
|
lastPartial.set(encBlock.subarray(0, lastPartial.length));
|
|
434
517
|
}
|
|
435
|
-
return state.finalize(
|
|
518
|
+
return state.finalize(ad.length, msgLen, tagLen);
|
|
436
519
|
}
|
|
437
520
|
/**
|
|
438
521
|
* Decrypts a message in-place using AEGIS-128X (detached mode).
|
|
@@ -448,23 +531,23 @@ export function aegis128XEncryptDetachedInPlace(data, ad, key, nonce, tagLen = 1
|
|
|
448
531
|
export function aegis128XDecryptDetachedInPlace(data, tag, ad, key, nonce, degree = 2) {
|
|
449
532
|
const tagLen = tag.length;
|
|
450
533
|
const state = new Aegis128XState(degree);
|
|
451
|
-
const rateBytes =
|
|
534
|
+
const rateBytes = 32 * degree;
|
|
452
535
|
state.init(key, nonce);
|
|
453
536
|
const adPadded = zeroPad(ad, rateBytes);
|
|
454
537
|
for (let i = 0; i + rateBytes <= adPadded.length; i += rateBytes) {
|
|
455
|
-
state.absorb(adPadded
|
|
538
|
+
state.absorb(adPadded, i);
|
|
456
539
|
}
|
|
457
540
|
const msgLen = data.length;
|
|
458
541
|
const fullBlocksLen = Math.floor(msgLen / rateBytes) * rateBytes;
|
|
459
542
|
for (let i = 0; i < fullBlocksLen; i += rateBytes) {
|
|
460
|
-
state.
|
|
543
|
+
state.decTo(data, data, i, i);
|
|
461
544
|
}
|
|
462
545
|
if (msgLen > fullBlocksLen) {
|
|
463
546
|
const lastPartial = data.subarray(fullBlocksLen);
|
|
464
547
|
const decrypted = state.decPartial(lastPartial);
|
|
465
548
|
lastPartial.set(decrypted);
|
|
466
549
|
}
|
|
467
|
-
const expectedTag = state.finalize(
|
|
550
|
+
const expectedTag = state.finalize(ad.length, msgLen, tagLen);
|
|
468
551
|
if (!constantTimeEqual(tag, expectedTag)) {
|
|
469
552
|
data.fill(0);
|
|
470
553
|
return false;
|
|
@@ -496,27 +579,11 @@ export const AEGIS_128X_KEY_SIZE = 16;
|
|
|
496
579
|
*/
|
|
497
580
|
export function aegis128XEncrypt(msg, ad, key, nonce = null, tagLen = 16, degree = 2) {
|
|
498
581
|
const actualNonce = nonce ?? randomBytes(AEGIS_128X_NONCE_SIZE);
|
|
499
|
-
const
|
|
500
|
-
const
|
|
501
|
-
state.init(key, actualNonce);
|
|
502
|
-
const adPadded = zeroPad(ad, rateBytes);
|
|
503
|
-
for (let i = 0; i + rateBytes <= adPadded.length; i += rateBytes) {
|
|
504
|
-
state.absorb(adPadded.subarray(i, i + rateBytes));
|
|
505
|
-
}
|
|
506
|
-
const nonceSize = AEGIS_128X_NONCE_SIZE;
|
|
507
|
-
const result = new Uint8Array(nonceSize + msg.length + tagLen);
|
|
582
|
+
const { ciphertext, tag } = aegis128XEncryptDetached(msg, ad, key, actualNonce, tagLen, degree);
|
|
583
|
+
const result = new Uint8Array(AEGIS_128X_NONCE_SIZE + ciphertext.length + tagLen);
|
|
508
584
|
result.set(actualNonce, 0);
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
state.encTo(msg.subarray(i, i + rateBytes), result.subarray(nonceSize + i, nonceSize + i + rateBytes));
|
|
512
|
-
}
|
|
513
|
-
if (msg.length > fullBlocks) {
|
|
514
|
-
const lastBlock = zeroPad(msg.subarray(fullBlocks), rateBytes);
|
|
515
|
-
const encBlock = state.enc(lastBlock);
|
|
516
|
-
result.set(encBlock.subarray(0, msg.length - fullBlocks), nonceSize + fullBlocks);
|
|
517
|
-
}
|
|
518
|
-
const tag = state.finalize(BigInt(ad.length * 8), BigInt(msg.length * 8), tagLen);
|
|
519
|
-
result.set(tag, nonceSize + msg.length);
|
|
585
|
+
result.set(ciphertext, AEGIS_128X_NONCE_SIZE);
|
|
586
|
+
result.set(tag, AEGIS_128X_NONCE_SIZE + ciphertext.length);
|
|
520
587
|
return result;
|
|
521
588
|
}
|
|
522
589
|
/**
|
|
@@ -566,13 +633,13 @@ export const aegis128X4Decrypt = (sealed, ad, key, tagLen = 16) => aegis128XDecr
|
|
|
566
633
|
*/
|
|
567
634
|
export function aegis128XMac(data, key, nonce = null, tagLen = 16, degree = 2) {
|
|
568
635
|
const state = new Aegis128XState(degree);
|
|
569
|
-
const rateBytes =
|
|
636
|
+
const rateBytes = 32 * degree;
|
|
570
637
|
state.init(key, nonce ?? new Uint8Array(16));
|
|
571
638
|
const dataPadded = zeroPad(data, rateBytes);
|
|
572
639
|
for (let i = 0; i + rateBytes <= dataPadded.length; i += rateBytes) {
|
|
573
|
-
state.absorb(dataPadded
|
|
640
|
+
state.absorb(dataPadded, i);
|
|
574
641
|
}
|
|
575
|
-
return state.finalizeMac(
|
|
642
|
+
return state.finalizeMac(data.length, tagLen);
|
|
576
643
|
}
|
|
577
644
|
/**
|
|
578
645
|
* Verifies a MAC computed using AEGIS-128X.
|
|
@@ -620,4 +687,3 @@ export const aegis128X2CreateNonce = aegis128XCreateNonce;
|
|
|
620
687
|
export const aegis128X4CreateKey = aegis128XCreateKey;
|
|
621
688
|
/** AEGIS-128X4 nonce generation (degree=4). */
|
|
622
689
|
export const aegis128X4CreateNonce = aegis128XCreateNonce;
|
|
623
|
-
//# sourceMappingURL=aegis128x.js.map
|