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.
Files changed (55) hide show
  1. package/README.md +29 -22
  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 +46 -23
  11. package/dist/aes-bs.js +2273 -331
  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 +6 -6
  19. package/dist/aegis128l-bs.d.ts +0 -194
  20. package/dist/aegis128l-bs.d.ts.map +0 -1
  21. package/dist/aegis128l-bs.js +0 -549
  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 -183
  28. package/dist/aegis256-bs.d.ts.map +0 -1
  29. package/dist/aegis256-bs.js +0 -477
  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 -709
  46. package/src/aegis128l.ts +0 -653
  47. package/src/aegis128x.ts +0 -932
  48. package/src/aegis256-bs.ts +0 -625
  49. package/src/aegis256.ts +0 -597
  50. package/src/aegis256x.ts +0 -893
  51. package/src/aes-bs.ts +0 -459
  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
package/dist/aegis256.js CHANGED
@@ -1,32 +1,59 @@
1
- import { aesRoundTo, andBlocksTo, C0, C1, constantTimeEqual, le64To, xorBlocksTo, zeroPad, } from "./aes.js";
1
+ /**
2
+ * AEGIS-256 implementation.
3
+ * Built on the constant-time bitsliced AES core, which processes the state
4
+ * blocks simultaneously without lookup tables.
5
+ */
6
+ import { aegisRound256, blockFromBytes, blocksPut, blockToBytes, blockXor, createAesBlock, createAesBlocks, keystream256, pack, packConstantInput256, unpack, wordIdx, } from "./aes-bs.js";
2
7
  import { randomBytes } from "./random.js";
8
+ import { constantTimeEqual, zeroPad } from "./utils.js";
9
+ const RATE = 16;
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-256 cipher state.
5
- * Uses 6 AES blocks (96 bytes) of internal state and processes 16-byte blocks.
18
+ * Uses 6 AES blocks stored in packed bitsliced form throughout the lifetime
19
+ * of the state.
6
20
  */
7
21
  export class Aegis256State {
8
22
  constructor() {
9
- this.s0 = new Uint8Array(16);
10
- this.s1 = new Uint8Array(16);
11
- this.s2 = new Uint8Array(16);
12
- this.s3 = new Uint8Array(16);
13
- this.s4 = new Uint8Array(16);
14
- this.s5 = new Uint8Array(16);
15
- this.tmp = new Uint8Array(16);
16
- this.z = new Uint8Array(16);
17
- this.newS = Array.from({ length: 6 }, () => new Uint8Array(16));
18
- this.tBuf = new Uint8Array(16);
23
+ this.st = createAesBlocks();
24
+ this.constantInput = createAesBlocks();
25
+ this.tmp = createAesBlock();
26
+ this.z = createAesBlock();
19
27
  }
28
+ /**
29
+ * Returns the 6 state blocks as byte arrays (for testing).
30
+ */
20
31
  get s() {
21
- return [this.s0, this.s1, this.s2, this.s3, this.s4, this.s5];
32
+ const unpacked = createAesBlocks();
33
+ unpacked.set(this.st);
34
+ unpack(unpacked);
35
+ const blocks = [];
36
+ const w = createAesBlock();
37
+ for (let i = 0; i < 6; i++) {
38
+ for (let j = 0; j < 4; j++)
39
+ w[j] = unpacked[wordIdx(i, j)];
40
+ const bytes = new Uint8Array(16);
41
+ blockToBytes(bytes, w);
42
+ blocks.push(bytes);
43
+ }
44
+ return blocks;
22
45
  }
23
- set s(states) {
24
- this.s0.set(states[0]);
25
- this.s1.set(states[1]);
26
- this.s2.set(states[2]);
27
- this.s3.set(states[3]);
28
- this.s4.set(states[4]);
29
- this.s5.set(states[5]);
46
+ /**
47
+ * Sets the 6 state blocks from byte arrays (for testing).
48
+ */
49
+ set s(blocks) {
50
+ this.st.fill(0);
51
+ const w = createAesBlock();
52
+ for (let i = 0; i < 6; i++) {
53
+ blockFromBytes(w, blocks[i]);
54
+ blocksPut(this.st, w, i);
55
+ }
56
+ pack(this.st);
30
57
  }
31
58
  /**
32
59
  * Initializes the state with a key and nonce.
@@ -34,184 +61,179 @@ export class Aegis256State {
34
61
  * @param nonce - 32-byte nonce (must be unique per message)
35
62
  */
36
63
  init(key, nonce) {
37
- const k0 = key.subarray(0, 16);
38
- const k1 = key.subarray(16, 32);
39
- const n0 = nonce.subarray(0, 16);
40
- const n1 = nonce.subarray(16, 32);
41
- xorBlocksTo(k0, n0, this.s0);
42
- xorBlocksTo(k1, n1, this.s1);
43
- this.s2.set(C1);
44
- this.s3.set(C0);
45
- xorBlocksTo(k0, C0, this.s4);
46
- xorBlocksTo(k1, C1, this.s5);
47
- const k0Xorn0 = new Uint8Array(16);
48
- const k1Xorn1 = new Uint8Array(16);
49
- xorBlocksTo(k0, n0, k0Xorn0);
50
- xorBlocksTo(k1, n1, k1Xorn1);
64
+ const k0 = createAesBlock();
65
+ const k1 = createAesBlock();
66
+ const n0 = createAesBlock();
67
+ const n1 = createAesBlock();
68
+ const k0n0 = createAesBlock();
69
+ const k1n1 = createAesBlock();
70
+ const k0c0 = createAesBlock();
71
+ const k1c1 = createAesBlock();
72
+ blockFromBytes(k0, key);
73
+ blockFromBytes(k1, key, 16);
74
+ blockFromBytes(n0, nonce);
75
+ blockFromBytes(n1, nonce, 16);
76
+ blockXor(k0n0, k0, n0);
77
+ blockXor(k1n1, k1, n1);
78
+ blockXor(k0c0, k0, C0);
79
+ blockXor(k1c1, k1, C1);
80
+ this.st.fill(0);
81
+ blocksPut(this.st, k0n0, 0);
82
+ blocksPut(this.st, k1n1, 1);
83
+ blocksPut(this.st, C1, 2);
84
+ blocksPut(this.st, C0, 3);
85
+ blocksPut(this.st, k0c0, 4);
86
+ blocksPut(this.st, k1c1, 5);
87
+ const ciK0 = createAesBlocks();
88
+ const ciK1 = createAesBlocks();
89
+ const ciK0N0 = createAesBlocks();
90
+ const ciK1N1 = createAesBlocks();
91
+ packConstantInput256(ciK0, k0);
92
+ packConstantInput256(ciK1, k1);
93
+ packConstantInput256(ciK0N0, k0n0);
94
+ packConstantInput256(ciK1N1, k1n1);
95
+ pack(this.st);
51
96
  for (let i = 0; i < 4; i++) {
52
- this.update(k0);
53
- this.update(k1);
54
- this.update(k0Xorn0);
55
- this.update(k1Xorn1);
97
+ aegisRound256(this.st, ciK0);
98
+ aegisRound256(this.st, ciK1);
99
+ aegisRound256(this.st, ciK0N0);
100
+ aegisRound256(this.st, ciK1N1);
56
101
  }
57
102
  }
58
103
  /**
59
104
  * Updates the state with a 16-byte message block.
60
- * @param m - ArrayLike<number> - 16-byte message block
105
+ * @param m - 16-byte message block
61
106
  */
62
107
  update(m) {
63
- const newS = this.newS;
64
- xorBlocksTo(this.s0, m, this.tmp);
65
- aesRoundTo(this.s5, this.tmp, newS[0]);
66
- aesRoundTo(this.s0, this.s1, newS[1]);
67
- aesRoundTo(this.s1, this.s2, newS[2]);
68
- aesRoundTo(this.s2, this.s3, newS[3]);
69
- aesRoundTo(this.s3, this.s4, newS[4]);
70
- aesRoundTo(this.s4, this.s5, newS[5]);
71
- this.s0.set(newS[0]);
72
- this.s1.set(newS[1]);
73
- this.s2.set(newS[2]);
74
- this.s3.set(newS[3]);
75
- this.s4.set(newS[4]);
76
- this.s5.set(newS[5]);
108
+ blockFromBytes(this.tmp, m);
109
+ packConstantInput256(this.constantInput, this.tmp);
110
+ aegisRound256(this.st, this.constantInput);
77
111
  }
78
112
  /**
79
113
  * Absorbs a 16-byte associated data block into the state.
80
- * @param ai - 16-byte associated data block
114
+ * @param ai - Buffer holding the 16-byte associated data block
115
+ * @param off - Offset of the block within the buffer
81
116
  */
82
- absorb(ai) {
83
- this.update(ai);
117
+ absorb(ai, off = 0) {
118
+ const msg = this.tmp;
119
+ blockFromBytes(msg, ai, off);
120
+ packConstantInput256(this.constantInput, msg);
121
+ aegisRound256(this.st, this.constantInput);
84
122
  }
85
123
  /**
86
- * Encrypts a 16-byte plaintext block and writes to output.
87
- * @param xi - 16-byte plaintext block
88
- * @param out - 16-byte output buffer
124
+ * Encrypts a 16-byte plaintext block and writes to output buffer.
125
+ * @param xi - Buffer holding the 16-byte plaintext block
126
+ * @param out - Output buffer receiving the 16-byte ciphertext block
127
+ * @param inOff - Offset of the plaintext block within xi
128
+ * @param outOff - Offset of the ciphertext block within out
89
129
  */
90
- encTo(xi, out) {
91
- const z = this.z;
92
- const tmp = this.tmp;
93
- xorBlocksTo(this.s1, this.s4, z);
94
- for (let i = 0; i < 16; i++)
95
- z[i] ^= this.s5[i];
96
- andBlocksTo(this.s2, this.s3, tmp);
97
- for (let i = 0; i < 16; i++)
98
- z[i] ^= tmp[i];
99
- this.update(xi);
100
- for (let i = 0; i < 16; i++)
101
- out[i] = xi[i] ^ z[i];
130
+ encTo(xi, out, inOff = 0, outOff = 0) {
131
+ const t = this.tmp;
132
+ keystream256(this.st, this.z);
133
+ blockFromBytes(t, xi, inOff);
134
+ packConstantInput256(this.constantInput, t);
135
+ aegisRound256(this.st, this.constantInput);
136
+ blockXor(t, t, this.z);
137
+ blockToBytes(out, t, outOff);
102
138
  }
103
- /**
104
- * Encrypts a 16-byte plaintext block.
105
- * @param xi - 16-byte plaintext block
106
- * @returns 16-byte ciphertext block
107
- */
108
139
  enc(xi) {
109
140
  const out = new Uint8Array(16);
110
141
  this.encTo(xi, out);
111
142
  return out;
112
143
  }
113
144
  /**
114
- * Decrypts a 16-byte ciphertext block and writes to output.
115
- * @param ci - 16-byte ciphertext block
116
- * @param out - 16-byte output buffer
145
+ * Decrypts a 16-byte ciphertext block and writes to output buffer.
146
+ * @param ci - Buffer holding the 16-byte ciphertext block
147
+ * @param out - Output buffer receiving the 16-byte plaintext block
148
+ * @param inOff - Offset of the ciphertext block within ci
149
+ * @param outOff - Offset of the plaintext block within out
117
150
  */
118
- decTo(ci, out) {
119
- const z = this.z;
120
- const tmp = this.tmp;
121
- xorBlocksTo(this.s1, this.s4, z);
122
- for (let i = 0; i < 16; i++)
123
- z[i] ^= this.s5[i];
124
- andBlocksTo(this.s2, this.s3, tmp);
125
- for (let i = 0; i < 16; i++)
126
- z[i] ^= tmp[i];
127
- for (let i = 0; i < 16; i++)
128
- out[i] = ci[i] ^ z[i];
129
- this.update(out);
151
+ decTo(ci, out, inOff = 0, outOff = 0) {
152
+ const msg = this.tmp;
153
+ blockFromBytes(msg, ci, inOff);
154
+ keystream256(this.st, this.z);
155
+ blockXor(msg, msg, this.z);
156
+ packConstantInput256(this.constantInput, msg);
157
+ aegisRound256(this.st, this.constantInput);
158
+ blockToBytes(out, msg, outOff);
130
159
  }
131
- /**
132
- * Decrypts a 16-byte ciphertext block.
133
- * @param ci - 16-byte ciphertext block
134
- * @returns 16-byte plaintext block
135
- */
136
160
  dec(ci) {
137
161
  const out = new Uint8Array(16);
138
162
  this.decTo(ci, out);
139
163
  return out;
140
164
  }
141
- /**
142
- * Encrypts a 16-byte plaintext block in-place.
143
- * @param block - 16-byte buffer (plaintext in, ciphertext out)
144
- */
145
165
  encInPlace(block) {
146
166
  this.encTo(block, block);
147
167
  }
148
- /**
149
- * Decrypts a 16-byte ciphertext block in-place.
150
- * @param block - 16-byte buffer (ciphertext in, plaintext out)
151
- */
152
168
  decInPlace(block) {
153
169
  this.decTo(block, block);
154
170
  }
155
- /**
156
- * Decrypts a partial (final) ciphertext block smaller than 16 bytes.
157
- * @param cn - Partial ciphertext block (1-15 bytes)
158
- * @returns Decrypted plaintext of the same length
159
- */
160
171
  decPartial(cn) {
161
- const z = this.z;
162
- const tmp = this.tmp;
163
- xorBlocksTo(this.s1, this.s4, z);
164
- for (let i = 0; i < 16; i++)
165
- z[i] ^= this.s5[i];
166
- andBlocksTo(this.s2, this.s3, tmp);
167
- for (let i = 0; i < 16; i++)
168
- z[i] ^= tmp[i];
169
- const t = zeroPad(cn, 16);
170
- const out = new Uint8Array(16);
171
- for (let i = 0; i < 16; i++)
172
- out[i] = t[i] ^ z[i];
173
- const xn = new Uint8Array(out.subarray(0, cn.length));
174
- const v = zeroPad(xn, 16);
175
- this.update(v);
172
+ const msg = this.tmp;
173
+ const padded = zeroPad(cn, RATE);
174
+ blockFromBytes(msg, padded);
175
+ keystream256(this.st, this.z);
176
+ blockXor(msg, msg, this.z);
177
+ const pad = new Uint8Array(RATE);
178
+ blockToBytes(pad, msg);
179
+ const xn = new Uint8Array(pad.subarray(0, cn.length));
180
+ pad.fill(0, cn.length);
181
+ blockFromBytes(msg, pad);
182
+ packConstantInput256(this.constantInput, msg);
183
+ aegisRound256(this.st, this.constantInput);
176
184
  return xn;
177
185
  }
178
186
  /**
179
187
  * Finalizes encryption/decryption and produces an authentication tag.
180
- * @param adLenBits - Associated data length in bits
181
- * @param msgLenBits - Message length in bits
182
- * @param tagLen - Tag length (16 or 32 bytes)
183
- * @returns Authentication tag
184
188
  */
185
- finalize(adLenBits, msgLenBits, tagLen = 16) {
186
- const t = this.tBuf;
187
- le64To(adLenBits, t, 0);
188
- le64To(msgLenBits, t, 8);
189
- for (let i = 0; i < 16; i++)
190
- t[i] ^= this.s3[i];
189
+ finalize(adLen, msgLen, tagLen = 16) {
190
+ const st = this.st;
191
+ const tmp = this.tmp;
192
+ tmp[0] = (adLen * 8) & 0xffffffff;
193
+ tmp[1] = Math.floor((adLen * 8) / 0x100000000);
194
+ tmp[2] = (msgLen * 8) & 0xffffffff;
195
+ tmp[3] = Math.floor((msgLen * 8) / 0x100000000);
196
+ const unpacked = createAesBlocks();
197
+ unpacked.set(st);
198
+ unpack(unpacked);
199
+ tmp[0] = tmp[0] ^ unpacked[wordIdx(3, 0)];
200
+ tmp[1] = tmp[1] ^ unpacked[wordIdx(3, 1)];
201
+ tmp[2] = tmp[2] ^ unpacked[wordIdx(3, 2)];
202
+ tmp[3] = tmp[3] ^ unpacked[wordIdx(3, 3)];
203
+ packConstantInput256(this.constantInput, tmp);
191
204
  for (let i = 0; i < 7; i++) {
192
- this.update(t);
205
+ aegisRound256(st, this.constantInput);
193
206
  }
207
+ unpack(st);
194
208
  if (tagLen === 16) {
195
209
  const tag = new Uint8Array(16);
196
- for (let i = 0; i < 16; i++) {
197
- tag[i] =
198
- this.s0[i] ^
199
- this.s1[i] ^
200
- this.s2[i] ^
201
- this.s3[i] ^
202
- this.s4[i] ^
203
- this.s5[i];
210
+ const tagBlock = createAesBlock();
211
+ for (let i = 0; i < 4; i++) {
212
+ tagBlock[i] =
213
+ st[wordIdx(0, i)] ^
214
+ st[wordIdx(1, i)] ^
215
+ st[wordIdx(2, i)] ^
216
+ st[wordIdx(3, i)] ^
217
+ st[wordIdx(4, i)] ^
218
+ st[wordIdx(5, i)];
204
219
  }
220
+ blockToBytes(tag, tagBlock);
205
221
  return tag;
206
222
  }
207
223
  else {
208
224
  const tag = new Uint8Array(32);
209
- for (let i = 0; i < 16; i++) {
210
- tag[i] = this.s0[i] ^ this.s1[i] ^ this.s2[i];
225
+ const tagBlock0 = createAesBlock();
226
+ const tagBlock1 = createAesBlock();
227
+ for (let i = 0; i < 4; i++) {
228
+ tagBlock0[i] =
229
+ st[wordIdx(0, i)] ^ st[wordIdx(1, i)] ^ st[wordIdx(2, i)];
211
230
  }
212
- for (let i = 0; i < 16; i++) {
213
- tag[16 + i] = this.s3[i] ^ this.s4[i] ^ this.s5[i];
231
+ for (let i = 0; i < 4; i++) {
232
+ tagBlock1[i] =
233
+ st[wordIdx(3, i)] ^ st[wordIdx(4, i)] ^ st[wordIdx(5, i)];
214
234
  }
235
+ blockToBytes(tag, tagBlock0);
236
+ blockToBytes(tag, tagBlock1, 16);
215
237
  return tag;
216
238
  }
217
239
  }
@@ -228,17 +250,21 @@ export class Aegis256State {
228
250
  export function aegis256EncryptDetached(msg, ad, key, nonce, tagLen = 16) {
229
251
  const state = new Aegis256State();
230
252
  state.init(key, nonce);
231
- const adPadded = zeroPad(ad, 16);
232
- for (let i = 0; i + 16 <= adPadded.length; i += 16) {
233
- state.absorb(adPadded.subarray(i, i + 16));
253
+ const adPadded = zeroPad(ad, RATE);
254
+ for (let i = 0; i + RATE <= adPadded.length; i += RATE) {
255
+ state.absorb(adPadded, i);
234
256
  }
235
- const msgPadded = zeroPad(msg, 16);
236
- const ct = new Uint8Array(msgPadded.length);
237
- for (let i = 0; i + 16 <= msgPadded.length; i += 16) {
238
- state.encTo(msgPadded.subarray(i, i + 16), ct.subarray(i, i + 16));
257
+ const ciphertext = new Uint8Array(msg.length);
258
+ const fullBlocks = Math.floor(msg.length / RATE) * RATE;
259
+ for (let i = 0; i < fullBlocks; i += RATE) {
260
+ state.encTo(msg, ciphertext, i, i);
261
+ }
262
+ if (msg.length > fullBlocks) {
263
+ const lastBlock = zeroPad(msg.subarray(fullBlocks), RATE);
264
+ const encBlock = state.enc(lastBlock);
265
+ ciphertext.set(encBlock.subarray(0, msg.length - fullBlocks), fullBlocks);
239
266
  }
240
- const tag = state.finalize(BigInt(ad.length * 8), BigInt(msg.length * 8), tagLen);
241
- const ciphertext = new Uint8Array(ct.subarray(0, msg.length));
267
+ const tag = state.finalize(ad.length, msg.length, tagLen);
242
268
  return { ciphertext, tag };
243
269
  }
244
270
  /**
@@ -254,20 +280,19 @@ export function aegis256DecryptDetached(ct, tag, ad, key, nonce) {
254
280
  const tagLen = tag.length;
255
281
  const state = new Aegis256State();
256
282
  state.init(key, nonce);
257
- const adPadded = zeroPad(ad, 16);
258
- for (let i = 0; i + 16 <= adPadded.length; i += 16) {
259
- state.absorb(adPadded.subarray(i, i + 16));
283
+ const adPadded = zeroPad(ad, RATE);
284
+ for (let i = 0; i + RATE <= adPadded.length; i += RATE) {
285
+ state.absorb(adPadded, i);
260
286
  }
261
- const fullBlocksLen = Math.floor(ct.length / 16) * 16;
262
- const cn = ct.subarray(fullBlocksLen);
263
- const msg = new Uint8Array(fullBlocksLen + (cn.length > 0 ? cn.length : 0));
264
- for (let i = 0; i + 16 <= ct.length; i += 16) {
265
- state.decTo(ct.subarray(i, i + 16), msg.subarray(i, i + 16));
287
+ const msg = new Uint8Array(ct.length);
288
+ const fullBlocks = Math.floor(ct.length / RATE) * RATE;
289
+ for (let i = 0; i < fullBlocks; i += RATE) {
290
+ state.decTo(ct, msg, i, i);
266
291
  }
267
- if (cn.length > 0) {
268
- msg.set(state.decPartial(cn), fullBlocksLen);
292
+ if (ct.length > fullBlocks) {
293
+ msg.set(state.decPartial(ct.subarray(fullBlocks)), fullBlocks);
269
294
  }
270
- const expectedTag = state.finalize(BigInt(ad.length * 8), BigInt(msg.length * 8), tagLen);
295
+ const expectedTag = state.finalize(ad.length, msg.length, tagLen);
271
296
  if (!constantTimeEqual(tag, expectedTag)) {
272
297
  msg.fill(0);
273
298
  return null;
@@ -287,22 +312,22 @@ export function aegis256DecryptDetached(ct, tag, ad, key, nonce) {
287
312
  export function aegis256EncryptDetachedInPlace(data, ad, key, nonce, tagLen = 16) {
288
313
  const state = new Aegis256State();
289
314
  state.init(key, nonce);
290
- const adPadded = zeroPad(ad, 16);
291
- for (let i = 0; i + 16 <= adPadded.length; i += 16) {
292
- state.absorb(adPadded.subarray(i, i + 16));
315
+ const adPadded = zeroPad(ad, RATE);
316
+ for (let i = 0; i + RATE <= adPadded.length; i += RATE) {
317
+ state.absorb(adPadded, i);
293
318
  }
294
319
  const msgLen = data.length;
295
- const fullBlocksLen = Math.floor(msgLen / 16) * 16;
296
- for (let i = 0; i < fullBlocksLen; i += 16) {
297
- state.encInPlace(data.subarray(i, i + 16));
320
+ const fullBlocksLen = Math.floor(msgLen / RATE) * RATE;
321
+ for (let i = 0; i < fullBlocksLen; i += RATE) {
322
+ state.encTo(data, data, i, i);
298
323
  }
299
324
  if (msgLen > fullBlocksLen) {
300
325
  const lastPartial = data.subarray(fullBlocksLen);
301
- const lastBlock = zeroPad(lastPartial, 16);
326
+ const lastBlock = zeroPad(lastPartial, RATE);
302
327
  const encBlock = state.enc(lastBlock);
303
328
  lastPartial.set(encBlock.subarray(0, lastPartial.length));
304
329
  }
305
- return state.finalize(BigInt(ad.length * 8), BigInt(msgLen * 8), tagLen);
330
+ return state.finalize(ad.length, msgLen, tagLen);
306
331
  }
307
332
  /**
308
333
  * Decrypts a message in-place using AEGIS-256 (detached mode).
@@ -318,21 +343,21 @@ export function aegis256DecryptDetachedInPlace(data, tag, ad, key, nonce) {
318
343
  const tagLen = tag.length;
319
344
  const state = new Aegis256State();
320
345
  state.init(key, nonce);
321
- const adPadded = zeroPad(ad, 16);
322
- for (let i = 0; i + 16 <= adPadded.length; i += 16) {
323
- state.absorb(adPadded.subarray(i, i + 16));
346
+ const adPadded = zeroPad(ad, RATE);
347
+ for (let i = 0; i + RATE <= adPadded.length; i += RATE) {
348
+ state.absorb(adPadded, i);
324
349
  }
325
350
  const msgLen = data.length;
326
- const fullBlocksLen = Math.floor(msgLen / 16) * 16;
327
- for (let i = 0; i < fullBlocksLen; i += 16) {
328
- state.decInPlace(data.subarray(i, i + 16));
351
+ const fullBlocksLen = Math.floor(msgLen / RATE) * RATE;
352
+ for (let i = 0; i < fullBlocksLen; i += RATE) {
353
+ state.decTo(data, data, i, i);
329
354
  }
330
355
  if (msgLen > fullBlocksLen) {
331
356
  const lastPartial = data.subarray(fullBlocksLen);
332
357
  const decrypted = state.decPartial(lastPartial);
333
358
  lastPartial.set(decrypted);
334
359
  }
335
- const expectedTag = state.finalize(BigInt(ad.length * 8), BigInt(msgLen * 8), tagLen);
360
+ const expectedTag = state.finalize(ad.length, msgLen, tagLen);
336
361
  if (!constantTimeEqual(tag, expectedTag)) {
337
362
  data.fill(0);
338
363
  return false;
@@ -355,26 +380,11 @@ export const AEGIS_256_KEY_SIZE = 32;
355
380
  */
356
381
  export function aegis256Encrypt(msg, ad, key, nonce = null, tagLen = 16) {
357
382
  const actualNonce = nonce ?? randomBytes(AEGIS_256_NONCE_SIZE);
358
- const state = new Aegis256State();
359
- state.init(key, actualNonce);
360
- const adPadded = zeroPad(ad, 16);
361
- for (let i = 0; i + 16 <= adPadded.length; i += 16) {
362
- state.absorb(adPadded.subarray(i, i + 16));
363
- }
364
- const nonceSize = AEGIS_256_NONCE_SIZE;
365
- const result = new Uint8Array(nonceSize + msg.length + tagLen);
383
+ const { ciphertext, tag } = aegis256EncryptDetached(msg, ad, key, actualNonce, tagLen);
384
+ const result = new Uint8Array(AEGIS_256_NONCE_SIZE + ciphertext.length + tagLen);
366
385
  result.set(actualNonce, 0);
367
- const fullBlocks = Math.floor(msg.length / 16) * 16;
368
- for (let i = 0; i < fullBlocks; i += 16) {
369
- state.encTo(msg.subarray(i, i + 16), result.subarray(nonceSize + i, nonceSize + i + 16));
370
- }
371
- if (msg.length > fullBlocks) {
372
- const lastBlock = zeroPad(msg.subarray(fullBlocks), 16);
373
- const encBlock = state.enc(lastBlock);
374
- result.set(encBlock.subarray(0, msg.length - fullBlocks), nonceSize + fullBlocks);
375
- }
376
- const tag = state.finalize(BigInt(ad.length * 8), BigInt(msg.length * 8), tagLen);
377
- result.set(tag, nonceSize + msg.length);
386
+ result.set(ciphertext, AEGIS_256_NONCE_SIZE);
387
+ result.set(tag, AEGIS_256_NONCE_SIZE + ciphertext.length);
378
388
  return result;
379
389
  }
380
390
  /**
@@ -407,11 +417,11 @@ export function aegis256Decrypt(sealed, ad, key, tagLen = 16) {
407
417
  export function aegis256Mac(data, key, nonce = null, tagLen = 16) {
408
418
  const state = new Aegis256State();
409
419
  state.init(key, nonce ?? new Uint8Array(32));
410
- const dataPadded = zeroPad(data, 16);
411
- for (let i = 0; i + 16 <= dataPadded.length; i += 16) {
412
- state.absorb(dataPadded.subarray(i, i + 16));
420
+ const dataPadded = zeroPad(data, RATE);
421
+ for (let i = 0; i + RATE <= dataPadded.length; i += RATE) {
422
+ state.absorb(dataPadded, i);
413
423
  }
414
- return state.finalize(BigInt(data.length * 8), BigInt(tagLen * 8), tagLen);
424
+ return state.finalize(data.length, tagLen, tagLen);
415
425
  }
416
426
  /**
417
427
  * Verifies a MAC computed using AEGIS-256.
@@ -442,4 +452,3 @@ export function aegis256CreateKey() {
442
452
  export function aegis256CreateNonce() {
443
453
  return randomBytes(AEGIS_256_NONCE_SIZE);
444
454
  }
445
- //# sourceMappingURL=aegis256.js.map