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 CHANGED
@@ -1,12 +1,38 @@
1
- # aegis-aead
1
+ # AEGIS for JavaScript
2
2
 
3
3
  [![npm](https://img.shields.io/npm/v/aegis-aead)](https://www.npmjs.com/package/aegis-aead)
4
4
  [![CI](https://github.com/jedisct1/js-aegis-aead/actions/workflows/ci.yml/badge.svg)](https://github.com/jedisct1/js-aegis-aead/actions/workflows/ci.yml)
5
5
 
6
+ [View on npm](https://www.npmjs.com/package/aegis-aead)
7
+
6
8
  A compact, zero-dependency JavaScript/TypeScript implementation of [AEGIS](https://datatracker.ietf.org/doc/draft-irtf-cfrg-aegis-aead/), a family of fast, secure authenticated encryption algorithms.
7
9
 
8
10
  AEGIS provides both encryption with authentication and standalone MAC functionality, with a simple API that makes it hard to misuse.
9
11
 
12
+ ## Table of Contents
13
+
14
+ - [AEGIS for JavaScript](#aegis-for-javascript)
15
+ - [Table of Contents](#table-of-contents)
16
+ - [Installation](#installation)
17
+ - [Quick Start](#quick-start)
18
+ - [Choosing an Algorithm](#choosing-an-algorithm)
19
+ - [Usage Examples](#usage-examples)
20
+ - [Combined Mode](#combined-mode)
21
+ - [Detached Mode](#detached-mode)
22
+ - [In-Place Mode](#in-place-mode)
23
+ - [MAC (Message Authentication Code)](#mac-message-authentication-code)
24
+ - [API Overview](#api-overview)
25
+ - [Functions](#functions)
26
+ - [Parameters](#parameters)
27
+ - [Constants](#constants)
28
+ - [Parallel Variants (AEGIS-128X / AEGIS-256X)](#parallel-variants-aegis-128x--aegis-256x)
29
+ - [Security Considerations](#security-considerations)
30
+ - [Nonce Safety](#nonce-safety)
31
+ - [Tag Lengths](#tag-lengths)
32
+ - [Bitsliced Variants](#bitsliced-variants)
33
+ - [Compatibility](#compatibility)
34
+ - [Browser Example](#browser-example)
35
+
10
36
  ## Installation
11
37
 
12
38
  ```bash
@@ -15,32 +41,62 @@ bun add aegis-aead
15
41
  npm install aegis-aead
16
42
  ```
17
43
 
18
- ## Usage
19
-
20
- ### Encryption and Decryption
44
+ ## Quick Start
21
45
 
22
46
  ```typescript
23
- import {
24
- aegis128LCreateKey,
25
- aegis128LEncrypt,
26
- aegis128LDecrypt
27
- } from "aegis-aead";
47
+ import { aegis128LCreateKey, aegis128LEncrypt, aegis128LDecrypt } from "aegis-aead";
28
48
 
29
- const key = aegis128LCreateKey(); // 16 random bytes
49
+ const key = aegis128LCreateKey();
30
50
  const message = new TextEncoder().encode("Hello, world!");
31
51
  const associatedData = new TextEncoder().encode("metadata");
32
52
 
33
- // Encrypt - returns nonce || ciphertext || tag
34
- // A random nonce is generated automatically
53
+ // Encrypt (nonce is generated automatically)
35
54
  const sealed = aegis128LEncrypt(message, associatedData, key);
36
55
 
37
56
  // Decrypt (returns null if authentication fails)
38
57
  const decrypted = aegis128LDecrypt(sealed, associatedData, key);
39
58
  ```
40
59
 
60
+ ## Choosing an Algorithm
61
+
62
+ | Algorithm | Key | Nonce | Best For |
63
+ | ------------- | -------- | -------- | ---------------------------------------- |
64
+ | AEGIS-128L | 16 bytes | 16 bytes | General use, high throughput |
65
+ | AEGIS-256 | 32 bytes | 32 bytes | Large nonce, unlimited messages |
66
+ | AEGIS-128X | 16 bytes | 16 bytes | Interop with native SIMD implementations |
67
+ | AEGIS-256X | 32 bytes | 32 bytes | Interop + large nonce |
68
+ | AEGIS-128L-BS | 16 bytes | 16 bytes | Side-channel protection |
69
+ | AEGIS-256-BS | 32 bytes | 32 bytes | Side-channel + large nonce |
70
+
71
+ Recommendations:
72
+
73
+ - Default choice: AEGIS-128L offers excellent performance with safe random nonces up to 2^48 messages
74
+ - Unlimited messages: AEGIS-256 when you need unlimited random nonces (32-byte nonce eliminates collision risk)
75
+ - Interoperability: AEGIS-128X/256X when exchanging data with native implementations using these variants
76
+ - Hostile environments: Bitsliced variants (-BS) when attackers may observe timing
77
+
78
+ Note: The X variants are designed for SIMD parallelism in native code. In JavaScript they offer no speed benefit but are provided for interoperability.
79
+
80
+ ## Usage Examples
81
+
82
+ ### Combined Mode
83
+
84
+ The simplest API: returns `nonce || ciphertext || tag` in one buffer.
85
+
86
+ ```typescript
87
+ import { aegis128LCreateKey, aegis128LEncrypt, aegis128LDecrypt } from "aegis-aead";
88
+
89
+ const key = aegis128LCreateKey();
90
+ const message = new TextEncoder().encode("Hello, world!");
91
+ const ad = new TextEncoder().encode("metadata");
92
+
93
+ const sealed = aegis128LEncrypt(message, ad, key);
94
+ const decrypted = aegis128LDecrypt(sealed, ad, key);
95
+ ```
96
+
41
97
  ### Detached Mode
42
98
 
43
- For applications that need separate access to the ciphertext and tag:
99
+ When you need separate access to ciphertext and tag:
44
100
 
45
101
  ```typescript
46
102
  import {
@@ -53,278 +109,149 @@ import {
53
109
  const key = aegis128LCreateKey();
54
110
  const nonce = aegis128LCreateNonce();
55
111
  const message = new TextEncoder().encode("Hello, world!");
56
- const associatedData = new TextEncoder().encode("metadata");
57
-
58
- // Encrypt - returns ciphertext and tag separately
59
- const { ciphertext, tag } = aegis128LEncryptDetached(message, associatedData, key, nonce);
112
+ const ad = new TextEncoder().encode("metadata");
60
113
 
61
- // Decrypt
62
- const decrypted = aegis128LDecryptDetached(ciphertext, tag, associatedData, key, nonce);
114
+ const { ciphertext, tag } = aegis128LEncryptDetached(message, ad, key, nonce);
115
+ const decrypted = aegis128LDecryptDetached(ciphertext, tag, ad, key, nonce);
63
116
  ```
64
117
 
65
- ### MAC (Message Authentication Code)
118
+ ### In-Place Mode
119
+
120
+ Zero-copy encryption that modifies the buffer directly:
66
121
 
67
122
  ```typescript
68
123
  import {
69
124
  aegis128LCreateKey,
70
- aegis128LMac,
71
- aegis128LMacVerify
125
+ aegis128LCreateNonce,
126
+ aegis128LEncryptDetachedInPlace,
127
+ aegis128LDecryptDetachedInPlace
72
128
  } from "aegis-aead";
73
129
 
74
130
  const key = aegis128LCreateKey();
75
- const data = new TextEncoder().encode("data to authenticate");
131
+ const nonce = aegis128LCreateNonce();
132
+ const data = new TextEncoder().encode("Hello, world!");
133
+ const ad = new TextEncoder().encode("metadata");
76
134
 
77
- // Generate MAC (nonce defaults to zero if not provided)
78
- const tag = aegis128LMac(data, key);
135
+ // Encrypt: data is modified, tag is returned
136
+ const tag = aegis128LEncryptDetachedInPlace(data, ad, key, nonce);
79
137
 
80
- // Verify MAC
81
- const valid = aegis128LMacVerify(data, tag, key);
138
+ // Decrypt: returns true if authentication succeeds
139
+ const success = aegis128LDecryptDetachedInPlace(data, tag, ad, key, nonce);
82
140
  ```
83
141
 
84
- ## Algorithms
85
-
86
- | Algorithm | Key Size | Nonce Size | Block Size | Use Case |
87
- | ------------- | -------- | ---------- | ---------- | ---------------------------------- |
88
- | AEGIS-128L | 16 bytes | 16 bytes | 32 bytes | High throughput on 64-bit CPUs |
89
- | AEGIS-256 | 32 bytes | 32 bytes | 16 bytes | 256-bit security level |
90
- | AEGIS-128X | 16 bytes | 16 bytes | 32×D bytes | Multi-lane AEGIS-128L (D = degree) |
91
- | AEGIS-256X | 32 bytes | 32 bytes | 16×D bytes | Multi-lane AEGIS-256 (D = degree) |
92
- | AEGIS-128L-BS | 16 bytes | 16 bytes | 32 bytes | Bitsliced |
93
- | AEGIS-256-BS | 32 bytes | 32 bytes | 16 bytes | Bitsliced |
142
+ ### MAC (Message Authentication Code)
94
143
 
95
- ### Bitsliced Variants
144
+ Authenticate data without encrypting:
96
145
 
97
- The `-BS` (bitsliced) variants provide protection against cache-timing side-channel attacks at the cost of ~20% performance overhead. They process AES operations without lookup tables, making execution time independent of the key and data values.
146
+ ```typescript
147
+ import { aegis128LCreateKey, aegis128LMac, aegis128LMacVerify } from "aegis-aead";
98
148
 
99
- Use the bitsliced variants when:
100
- - Adversaries may be able to observe timing information (shared hosting, cloud VMs)
101
- - The key holder may encrypt or decrypt attacker-controlled data
102
- - Maximum side-channel resistance is required
149
+ const key = aegis128LCreateKey();
150
+ const data = new TextEncoder().encode("data to authenticate");
103
151
 
104
- For most use cases, the standard implementations are safe since AEGIS's continuous state mixing makes practical timing attacks extremely difficult.
152
+ const tag = aegis128LMac(data, key);
153
+ const valid = aegis128LMacVerify(data, tag, key);
154
+ ```
105
155
 
106
- ### Random Nonces
156
+ ## API Overview
107
157
 
108
- When using random nonces (the default for combined-mode functions):
158
+ All AEGIS variants follow the same API pattern. Replace `aegis128L` with your chosen algorithm (`aegis256`, `aegis128X2`, `aegis128X4`, `aegis256X2`, `aegis256X4`, `aegis128LBs`, `aegis256Bs`).
109
159
 
110
- - AEGIS-128L/128X: Safe for up to 2^48 messages per key, regardless of their size
111
- - AEGIS-256/256X: No practical limits on the number of messages per key
160
+ ### Functions
112
161
 
113
- ### Tag Lengths
162
+ | Function | Description |
163
+ | ------------------------------------------------------- | -------------------------------------------------- |
164
+ | `createKey()` | Generate a random key |
165
+ | `createNonce()` | Generate a random nonce |
166
+ | `encrypt(msg, ad, key, nonce?, tagLen?)` | Encrypt, returns `nonce \|\| ciphertext \|\| tag` |
167
+ | `decrypt(sealed, ad, key, tagLen?)` | Decrypt combined output, returns `null` on failure |
168
+ | `encryptDetached(msg, ad, key, nonce, tagLen?)` | Encrypt, returns `{ ciphertext, tag }` |
169
+ | `decryptDetached(ct, tag, ad, key, nonce)` | Decrypt detached, returns `null` on failure |
170
+ | `encryptDetachedInPlace(data, ad, key, nonce, tagLen?)` | Encrypt in-place, returns tag |
171
+ | `decryptDetachedInPlace(data, tag, ad, key, nonce)` | Decrypt in-place, returns `boolean` |
172
+ | `mac(data, key, nonce?, tagLen?)` | Generate MAC tag |
173
+ | `macVerify(data, tag, key, nonce?)` | Verify MAC tag |
114
174
 
115
- All algorithms support two tag lengths:
175
+ ### Parameters
116
176
 
117
- - 16 bytes (128-bit) - default
118
- - 32 bytes (256-bit) - pass `32` as the last parameter to encrypt/MAC functions
177
+ - msg/data: `Uint8Array` - Data to encrypt/authenticate
178
+ - ad: `Uint8Array` - Associated data (authenticated but not encrypted)
179
+ - key: `Uint8Array` - Encryption key (16 or 32 bytes depending on algorithm)
180
+ - nonce: `Uint8Array` - Number used once (auto-generated if omitted in combined mode)
181
+ - tagLen: `number` - Authentication tag length: `16` (default) or `32`
119
182
 
120
- ## API Reference
183
+ ### Constants
121
184
 
122
- ### AEGIS-128L
185
+ Each algorithm exports size constants:
123
186
 
124
187
  ```typescript
125
- // Key/Nonce generation
126
- aegis128LCreateKey(): Uint8Array // 16 random bytes
127
- aegis128LCreateNonce(): Uint8Array // 16 random bytes
128
-
129
- // Combined (nonce || ciphertext || tag)
130
- aegis128LEncrypt(msg, ad, key, nonce?, tagLen?): Uint8Array
131
- aegis128LDecrypt(sealed, ad, key, tagLen?): Uint8Array | null
132
-
133
- // Detached (separate ciphertext and tag)
134
- aegis128LEncryptDetached(msg, ad, key, nonce, tagLen?): { ciphertext, tag }
135
- aegis128LDecryptDetached(ciphertext, tag, ad, key, nonce): Uint8Array | null
136
-
137
- // MAC (nonce is optional, defaults to zero)
138
- aegis128LMac(data, key, nonce?, tagLen?): Uint8Array
139
- aegis128LMacVerify(data, tag, key, nonce?): boolean
140
-
141
- // Constants
142
- AEGIS_128L_KEY_SIZE // 16
143
- AEGIS_128L_NONCE_SIZE // 16
188
+ import { AEGIS_128L_KEY_SIZE, AEGIS_128L_NONCE_SIZE } from "aegis-aead";
189
+ // AEGIS_128L_KEY_SIZE = 16
190
+ // AEGIS_128L_NONCE_SIZE = 16
144
191
  ```
145
192
 
146
- ### AEGIS-256
147
-
148
- ```typescript
149
- // Key/Nonce generation
150
- aegis256CreateKey(): Uint8Array // 32 random bytes
151
- aegis256CreateNonce(): Uint8Array // 32 random bytes
152
-
153
- // Combined (nonce || ciphertext || tag)
154
- aegis256Encrypt(msg, ad, key, nonce?, tagLen?): Uint8Array
155
- aegis256Decrypt(sealed, ad, key, tagLen?): Uint8Array | null
193
+ ### Parallel Variants (AEGIS-128X / AEGIS-256X)
156
194
 
157
- // Detached (separate ciphertext and tag)
158
- aegis256EncryptDetached(msg, ad, key, nonce, tagLen?): { ciphertext, tag }
159
- aegis256DecryptDetached(ciphertext, tag, ad, key, nonce): Uint8Array | null
195
+ The X variants support a configurable degree of parallelism:
160
196
 
161
- // MAC (nonce is optional, defaults to zero)
162
- aegis256Mac(data, key, nonce?, tagLen?): Uint8Array
163
- aegis256MacVerify(data, tag, key, nonce?): boolean
197
+ ```typescript
198
+ // Pre-configured for degree 2 and 4
199
+ import { aegis128X2Encrypt, aegis128X4Encrypt } from "aegis-aead";
164
200
 
165
- // Constants
166
- AEGIS_256_KEY_SIZE // 32
167
- AEGIS_256_NONCE_SIZE // 32
201
+ // Or use custom degree (typically 2 or 4)
202
+ import { aegis128XEncrypt } from "aegis-aead";
203
+ const sealed = aegis128XEncrypt(msg, ad, key, nonce, 16, 4); // degree=4
168
204
  ```
169
205
 
170
- ### AEGIS-128X
206
+ ## Security Considerations
171
207
 
172
- Pre-configured variants for degree 2 and 4:
208
+ ### Nonce Safety
173
209
 
174
- ```typescript
175
- // Key/Nonce generation
176
- aegis128XCreateKey(): Uint8Array // 16 random bytes
177
- aegis128XCreateNonce(): Uint8Array // 16 random bytes
178
- aegis128X2CreateKey(): Uint8Array // alias
179
- aegis128X2CreateNonce(): Uint8Array
180
- aegis128X4CreateKey(): Uint8Array // alias
181
- aegis128X4CreateNonce(): Uint8Array
182
-
183
- // Combined (nonce || ciphertext || tag)
184
- aegis128X2Encrypt(msg, ad, key, nonce?, tagLen?): Uint8Array
185
- aegis128X2Decrypt(sealed, ad, key, tagLen?): Uint8Array | null
186
- aegis128X4Encrypt(msg, ad, key, nonce?, tagLen?): Uint8Array
187
- aegis128X4Decrypt(sealed, ad, key, tagLen?): Uint8Array | null
188
-
189
- // Detached (separate ciphertext and tag)
190
- aegis128X2EncryptDetached(msg, ad, key, nonce, tagLen?): { ciphertext, tag }
191
- aegis128X2DecryptDetached(ciphertext, tag, ad, key, nonce): Uint8Array | null
192
- aegis128X4EncryptDetached(msg, ad, key, nonce, tagLen?): { ciphertext, tag }
193
- aegis128X4DecryptDetached(ciphertext, tag, ad, key, nonce): Uint8Array | null
194
-
195
- // MAC (nonce is optional, defaults to zero)
196
- aegis128X2Mac(data, key, nonce?, tagLen?): Uint8Array
197
- aegis128X2MacVerify(data, tag, key, nonce?): boolean
198
- aegis128X4Mac(data, key, nonce?, tagLen?): Uint8Array
199
- aegis128X4MacVerify(data, tag, key, nonce?): boolean
200
-
201
- // Custom degree
202
- aegis128XEncrypt(msg, ad, key, nonce?, tagLen?, degree?): Uint8Array
203
- aegis128XDecrypt(sealed, ad, key, tagLen?, degree?): Uint8Array | null
204
- aegis128XEncryptDetached(msg, ad, key, nonce, tagLen?, degree?): { ciphertext, tag }
205
- aegis128XDecryptDetached(ciphertext, tag, ad, key, nonce, degree?): Uint8Array | null
206
- aegis128XMac(data, key, nonce?, tagLen?, degree?): Uint8Array
207
- aegis128XMacVerify(data, tag, key, nonce?, degree?): boolean
208
-
209
- // Constants
210
- AEGIS_128X_KEY_SIZE // 16
211
- AEGIS_128X_NONCE_SIZE // 16
212
- ```
210
+ - Combined mode generates random nonces automatically
211
+ - Detached mode requires you to provide nonces - never reuse a nonce with the same key
212
+ - AEGIS-128L/128X: Safe for up to 2^48 messages per key with random nonces
213
+ - AEGIS-256/256X: No practical limits on message count
213
214
 
214
- ### AEGIS-256X
215
+ ### Tag Lengths
215
216
 
216
- Pre-configured variants for degree 2 and 4:
217
+ All algorithms support 16-byte (128-bit) and 32-byte (256-bit) tags:
217
218
 
218
219
  ```typescript
219
- // Key/Nonce generation
220
- aegis256XCreateKey(): Uint8Array // 32 random bytes
221
- aegis256XCreateNonce(): Uint8Array // 32 random bytes
222
- aegis256X2CreateKey(): Uint8Array // alias
223
- aegis256X2CreateNonce(): Uint8Array
224
- aegis256X4CreateKey(): Uint8Array // alias
225
- aegis256X4CreateNonce(): Uint8Array
226
-
227
- // Combined (nonce || ciphertext || tag)
228
- aegis256X2Encrypt(msg, ad, key, nonce?, tagLen?): Uint8Array
229
- aegis256X2Decrypt(sealed, ad, key, tagLen?): Uint8Array | null
230
- aegis256X4Encrypt(msg, ad, key, nonce?, tagLen?): Uint8Array
231
- aegis256X4Decrypt(sealed, ad, key, tagLen?): Uint8Array | null
232
-
233
- // Detached (separate ciphertext and tag)
234
- aegis256X2EncryptDetached(msg, ad, key, nonce, tagLen?): { ciphertext, tag }
235
- aegis256X2DecryptDetached(ciphertext, tag, ad, key, nonce): Uint8Array | null
236
- aegis256X4EncryptDetached(msg, ad, key, nonce, tagLen?): { ciphertext, tag }
237
- aegis256X4DecryptDetached(ciphertext, tag, ad, key, nonce): Uint8Array | null
238
-
239
- // MAC (nonce is optional, defaults to zero)
240
- aegis256X2Mac(data, key, nonce?, tagLen?): Uint8Array
241
- aegis256X2MacVerify(data, tag, key, nonce?): boolean
242
- aegis256X4Mac(data, key, nonce?, tagLen?): Uint8Array
243
- aegis256X4MacVerify(data, tag, key, nonce?): boolean
244
-
245
- // Custom degree
246
- aegis256XEncrypt(msg, ad, key, nonce?, tagLen?, degree?): Uint8Array
247
- aegis256XDecrypt(sealed, ad, key, tagLen?, degree?): Uint8Array | null
248
- aegis256XEncryptDetached(msg, ad, key, nonce, tagLen?, degree?): { ciphertext, tag }
249
- aegis256XDecryptDetached(ciphertext, tag, ad, key, nonce, degree?): Uint8Array | null
250
- aegis256XMac(data, key, nonce?, tagLen?, degree?): Uint8Array
251
- aegis256XMacVerify(data, tag, key, nonce?, degree?): boolean
252
-
253
- // Constants
254
- AEGIS_256X_KEY_SIZE // 32
255
- AEGIS_256X_NONCE_SIZE // 32
220
+ // 32-byte tag
221
+ const sealed = aegis128LEncrypt(msg, ad, key, undefined, 32);
256
222
  ```
257
223
 
258
- ### AEGIS-128L-BS (Bitsliced)
259
-
260
- ```typescript
261
- // Key/Nonce generation
262
- aegis128LBsCreateKey(): Uint8Array // 16 random bytes
263
- aegis128LBsCreateNonce(): Uint8Array // 16 random bytes
264
-
265
- // Combined (nonce || ciphertext || tag)
266
- aegis128LBsEncrypt(msg, ad, key, nonce?, tagLen?): Uint8Array
267
- aegis128LBsDecrypt(sealed, ad, key, tagLen?): Uint8Array | null
224
+ ### Bitsliced Variants
268
225
 
269
- // Detached (separate ciphertext and tag)
270
- aegis128LBsEncryptDetached(msg, ad, key, nonce, tagLen?): { ciphertext, tag }
271
- aegis128LBsDecryptDetached(ciphertext, tag, ad, key, nonce): Uint8Array | null
226
+ The `-BS` variants use a constant-time bitsliced AES implementation that doesn't use lookup tables. This prevents cache-timing attacks at the cost of ~20% performance.
272
227
 
273
- // MAC (nonce is optional, defaults to zero)
274
- aegis128LBsMac(data, key, nonce?, tagLen?): Uint8Array
275
- aegis128LBsMacVerify(data, tag, key, nonce?): boolean
228
+ Use bitsliced variants when:
229
+ - Running on shared infrastructure (cloud VMs, containers)
230
+ - Attackers may observe timing information
231
+ - Processing attacker-controlled data with secret keys
276
232
 
277
- // Constants
278
- AEGIS_128L_BS_KEY_SIZE // 16
279
- AEGIS_128L_BS_NONCE_SIZE // 16
280
- ```
233
+ For most applications, standard variants are safe since AEGIS's continuous state mixing makes timing attacks impractical.
281
234
 
282
- ### AEGIS-256-BS (Bitsliced)
235
+ ## Compatibility
283
236
 
284
- ```typescript
285
- // Key/Nonce generation
286
- aegis256BsCreateKey(): Uint8Array // 32 random bytes
287
- aegis256BsCreateNonce(): Uint8Array // 32 random bytes
237
+ Runtime Requirements:
288
238
 
289
- // Combined (nonce || ciphertext || tag)
290
- aegis256BsEncrypt(msg, ad, key, nonce?, tagLen?): Uint8Array
291
- aegis256BsDecrypt(sealed, ad, key, tagLen?): Uint8Array | null
239
+ The library uses the Web Crypto API (`crypto.getRandomValues`) for key/nonce generation:
292
240
 
293
- // Detached (separate ciphertext and tag)
294
- aegis256BsEncryptDetached(msg, ad, key, nonce, tagLen?): { ciphertext, tag }
295
- aegis256BsDecryptDetached(ciphertext, tag, ad, key, nonce): Uint8Array | null
241
+ - All modern browsers
242
+ - Node.js 18+
243
+ - Deno
244
+ - Bun
296
245
 
297
- // MAC (nonce is optional, defaults to zero)
298
- aegis256BsMac(data, key, nonce?, tagLen?): Uint8Array
299
- aegis256BsMacVerify(data, tag, key, nonce?): boolean
246
+ Interoperability:
300
247
 
301
- // Constants
302
- AEGIS_256_BS_KEY_SIZE // 32
303
- AEGIS_256_BS_NONCE_SIZE // 32
304
- ```
248
+ This library implements the [AEGIS IETF draft specification](https://datatracker.ietf.org/doc/draft-irtf-cfrg-aegis-aead/) and interoperates with any compliant implementation. See the [full list of AEGIS implementations](https://github.com/cfrg/draft-irtf-cfrg-aegis-aead?tab=readme-ov-file#known-implementations).
305
249
 
306
250
  ## Browser Example
307
251
 
308
- A browser example is included in `examples/`. To build and run it:
252
+ A browser demo is included:
309
253
 
310
254
  ```bash
311
255
  bun run build:example
312
256
  open examples/index.html
313
257
  ```
314
-
315
- The example demonstrates encryption/decryption with a simple UI where you can enter a message, encrypt it, and decrypt it back.
316
-
317
- ## Compatibility
318
-
319
- The key/nonce generation functions use the Web Crypto API (`globalThis.crypto.getRandomValues`) which is available in:
320
-
321
- - All modern browsers
322
- - Node.js 18+
323
- - Deno
324
- - Bun
325
-
326
- ## Interoperability
327
-
328
- This library follows the [AEGIS IETF draft specification](https://datatracker.ietf.org/doc/draft-irtf-cfrg-aegis-aead/) and can exchange encrypted messages with any compliant implementation, including native libraries in C, Rust, Go, Zig, and more.
329
-
330
- See the [full list of AEGIS implementations](https://github.com/cfrg/draft-irtf-cfrg-aegis-aead?tab=readme-ov-file#known-implementations).
@@ -4,37 +4,31 @@
4
4
  */
5
5
  /**
6
6
  * Bitsliced AEGIS-128L cipher state.
7
- * Uses 8 AES blocks (128 bytes) stored in bitsliced form (32 uint32 words).
7
+ * The state is kept in packed bitsliced form between operations so that
8
+ * pack/unpack does not need to be applied at every round.
8
9
  */
9
10
  export declare class Aegis128LBsState {
10
11
  private st;
11
12
  private st1;
13
+ private constantInput;
12
14
  private tmp0;
13
15
  private tmp1;
14
16
  private z0;
15
17
  private z1;
16
18
  constructor();
17
- /**
18
- * AEGIS round function: applies AES round to all blocks and rotates.
19
- * st[i] = AES(st[i]) ^ st[(i-1) mod 8]
20
- */
21
- private aegisRound;
22
- /**
23
- * AEGIS round function with constant input (used in packed mode).
24
- */
25
19
  private aegisRoundPacked;
26
- /**
27
- * Pack constant input for blocks 0 and 4.
28
- */
29
20
  private packConstantInput;
30
21
  /**
31
- * Absorb rate: XOR message blocks into state positions 0 and 4.
22
+ * Extract the keystream blocks z0 and z1 directly from the packed state.
23
+ *
24
+ * z0 = S6 ^ S1 ^ (S2 & S3)
25
+ * z1 = S2 ^ S5 ^ (S6 & S7)
26
+ *
27
+ * The formula is evaluated lane-wise on the packed state, the result is
28
+ * placed in positions 0 (z0) and 4 (z1), then unpack04 extracts the two
29
+ * AES blocks.
32
30
  */
33
- private absorbRate;
34
- /**
35
- * Update state with two message blocks.
36
- */
37
- private update;
31
+ private keystreamPacked;
38
32
  /**
39
33
  * Initializes the state with a key and nonce.
40
34
  * @param key - 16-byte encryption key
@@ -70,6 +64,8 @@ export declare class Aegis128LBsState {
70
64
  * @returns 32-byte plaintext block
71
65
  */
72
66
  dec(ci: Uint8Array): Uint8Array;
67
+ encInPlace(block: Uint8Array): void;
68
+ decInPlace(block: Uint8Array): void;
73
69
  /**
74
70
  * Decrypts a partial (final) ciphertext block smaller than 32 bytes.
75
71
  * @param cn - Partial ciphertext block (1-31 bytes)
@@ -108,55 +104,34 @@ export declare function aegis128LBsEncryptDetached(msg: Uint8Array, ad: Uint8Arr
108
104
  * @returns Decrypted plaintext, or null if authentication fails
109
105
  */
110
106
  export declare function aegis128LBsDecryptDetached(ct: Uint8Array, tag: Uint8Array, ad: Uint8Array, key: Uint8Array, nonce: Uint8Array): Uint8Array | null;
107
+ /**
108
+ * Encrypts a message in-place using bitsliced AEGIS-128L (detached mode).
109
+ */
110
+ export declare function aegis128LBsEncryptDetachedInPlace(data: Uint8Array, ad: Uint8Array, key: Uint8Array, nonce: Uint8Array, tagLen?: 16 | 32): Uint8Array;
111
+ /**
112
+ * Decrypts a message in-place using bitsliced AEGIS-128L (detached mode).
113
+ */
114
+ export declare function aegis128LBsDecryptDetachedInPlace(data: Uint8Array, tag: Uint8Array, ad: Uint8Array, key: Uint8Array, nonce: Uint8Array): boolean;
111
115
  export declare const AEGIS_128L_BS_NONCE_SIZE = 16;
112
116
  export declare const AEGIS_128L_BS_KEY_SIZE = 16;
113
117
  /**
114
118
  * Encrypts a message using bitsliced AEGIS-128L.
115
119
  * Returns a single buffer containing nonce || ciphertext || tag.
116
- * @param msg - Plaintext message
117
- * @param ad - Associated data (authenticated but not encrypted)
118
- * @param key - 16-byte encryption key
119
- * @param nonce - 16-byte nonce (optional, generates random nonce if not provided)
120
- * @param tagLen - Authentication tag length: 16 or 32 bytes (default: 16)
121
- * @returns Concatenated nonce || ciphertext || tag
122
120
  */
123
121
  export declare function aegis128LBsEncrypt(msg: Uint8Array, ad: Uint8Array, key: Uint8Array, nonce?: Uint8Array | null, tagLen?: 16 | 32): Uint8Array;
124
122
  /**
125
123
  * Decrypts a message using bitsliced AEGIS-128L.
126
124
  * Expects input as nonce || ciphertext || tag.
127
- * @param sealed - Concatenated nonce || ciphertext || tag
128
- * @param ad - Associated data (must match what was used during encryption)
129
- * @param key - 16-byte encryption key
130
- * @param tagLen - Authentication tag length: 16 or 32 bytes (default: 16)
131
- * @returns Decrypted plaintext, or null if authentication fails
132
125
  */
133
126
  export declare function aegis128LBsDecrypt(sealed: Uint8Array, ad: Uint8Array, key: Uint8Array, tagLen?: 16 | 32): Uint8Array | null;
134
127
  /**
135
- * Computes a MAC (Message Authentication Code) using bitsliced AEGIS-128L.
136
- * @param data - Data to authenticate
137
- * @param key - 16-byte key
138
- * @param nonce - 16-byte nonce (optional, uses zero nonce if null)
139
- * @param tagLen - Tag length: 16 or 32 bytes (default: 16)
140
- * @returns Authentication tag
128
+ * Computes a MAC using bitsliced AEGIS-128L.
141
129
  */
142
130
  export declare function aegis128LBsMac(data: Uint8Array, key: Uint8Array, nonce?: Uint8Array | null, tagLen?: 16 | 32): Uint8Array;
143
131
  /**
144
132
  * Verifies a MAC computed using bitsliced AEGIS-128L.
145
- * @param data - Data to verify
146
- * @param tag - Expected authentication tag (16 or 32 bytes)
147
- * @param key - 16-byte key
148
- * @param nonce - 16-byte nonce (optional, uses zero nonce if null)
149
- * @returns True if the tag is valid, false otherwise
150
133
  */
151
134
  export declare function aegis128LBsMacVerify(data: Uint8Array, tag: Uint8Array, key: Uint8Array, nonce?: Uint8Array | null): boolean;
152
- /**
153
- * Generates a random 16-byte key for bitsliced AEGIS-128L.
154
- * @returns 16-byte encryption key
155
- */
156
135
  export declare function aegis128LBsCreateKey(): Uint8Array;
157
- /**
158
- * Generates a random 16-byte nonce for bitsliced AEGIS-128L.
159
- * @returns 16-byte nonce
160
- */
161
136
  export declare function aegis128LBsCreateNonce(): Uint8Array;
162
137
  //# sourceMappingURL=aegis128l-bs.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"aegis128l-bs.d.ts","sourceRoot":"","sources":["../src/aegis128l-bs.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"aegis128l-bs.d.ts","sourceRoot":"","sources":["../src/aegis128l-bs.ts"],"names":[],"mappings":"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"}