@cryptforge/cryptography 0.2.0

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 ADDED
@@ -0,0 +1,331 @@
1
+ # @cryptforge/cryptography
2
+
3
+ Cryptographic operations for CryptForge applications with support for both client (browser) and server (Node.js) environments.
4
+
5
+ ## Features
6
+
7
+ - 🔐 **Encryption & Decryption**: Symmetric and asymmetric encryption operations
8
+ - 🌐 **Cross-Platform**: Separate implementations for browser and Node.js environments
9
+ - 🔑 **Key Management**: Utilities for key generation, derivation, and storage
10
+ - 🛡️ **Type-Safe**: Full TypeScript support with comprehensive type definitions
11
+ - 📦 **Tree-Shakeable**: Optimized bundle sizes with separate entry points
12
+
13
+ ## Installation
14
+
15
+ ```bash
16
+ npm install @cryptforge/cryptography
17
+ ```
18
+
19
+ ## Usage
20
+
21
+ ### Client/Browser Usage
22
+
23
+ The client export provides `CryptoBrowser`, which uses the Web Crypto API for encryption/decryption:
24
+
25
+ ```typescript
26
+ import { CryptoBrowser } from '@cryptforge/cryptography';
27
+ import { createAuthClient } from '@cryptforge/auth';
28
+
29
+ // Create auth client and unlock wallet
30
+ const auth = createAuthClient();
31
+ await auth.unlock({ password: 'your-password', chainId: 'ethereum' });
32
+
33
+ // Derive encryption key from wallet
34
+ const encryptionKey = await auth.deriveDataEncryptionKey({
35
+ purpose: 'my-app-data',
36
+ version: 1,
37
+ });
38
+
39
+ // Create CryptoBrowser instance
40
+ const crypto = new CryptoBrowser();
41
+ crypto.setEncryptionKey(encryptionKey);
42
+
43
+ // Encrypt data
44
+ const encrypted = await crypto.encrypt()('Hello, World!');
45
+ console.log('Encrypted:', encrypted); // Base64-encoded string
46
+
47
+ // Decrypt data
48
+ const decrypted = await crypto.decrypt()(encrypted);
49
+ console.log('Decrypted:', decrypted); // "Hello, World!"
50
+ ```
51
+
52
+ ### Using with Callback Pattern
53
+
54
+ ```typescript
55
+ import { CryptoBrowser } from '@cryptforge/cryptography';
56
+
57
+ // Create instance with dynamic key retrieval
58
+ const crypto = new CryptoBrowser();
59
+
60
+ // Set key when wallet is unlocked
61
+ const unlockWallet = async () => {
62
+ await auth.unlock({ password: 'password', chainId: 'ethereum' });
63
+ const key = await auth.deriveDataEncryptionKey({
64
+ purpose: 'my-app-data',
65
+ });
66
+ crypto.setEncryptionKey(key);
67
+ };
68
+
69
+ // Use encryption after unlocking
70
+ await unlockWallet();
71
+ const encrypted = await crypto.encrypt()('Secret message');
72
+ ```
73
+
74
+ ### Encryption Details
75
+
76
+ `CryptoBrowser` uses **AES-256-GCM** encryption:
77
+
78
+ - **Algorithm**: AES-GCM (Galois/Counter Mode)
79
+ - **Key Size**: 256 bits
80
+ - **IV Size**: 12 bytes (96 bits)
81
+ - **Output Format**: Base64-encoded (IV + ciphertext)
82
+
83
+ The initialization vector (IV) is randomly generated for each encryption operation and prepended to the ciphertext. This ensures each encryption produces a unique result, even for the same plaintext.
84
+
85
+ ### Server/Node.js Usage
86
+
87
+ The server export provides both browser and server-specific functionality:
88
+
89
+ ```typescript
90
+ import { CryptoServer } from '@cryptforge/cryptography/server';
91
+
92
+ // CryptoServer provides Node.js-specific crypto operations
93
+ const crypto = new CryptoServer();
94
+
95
+ // Server-side encryption/decryption
96
+ // (Implementation similar to CryptoBrowser but optimized for Node.js)
97
+ ```
98
+
99
+ **Note**: The server implementation is currently under development. For now, you can use `CryptoBrowser` in Node.js environments as the Web Crypto API is available in Node.js v15+.
100
+
101
+ ## Architecture
102
+
103
+ This package maintains strict separation between client and server environments:
104
+
105
+ - **`src/client/`**: Browser-compatible implementations using Web Crypto API
106
+ - **`src/server/`**: Node.js-specific implementations using Node's crypto module
107
+ - **`src/shared/`**: Environment-agnostic utilities and helpers
108
+ - **`src/types/`**: Shared TypeScript type definitions
109
+
110
+ ## Entry Points
111
+
112
+ - **`@cryptforge/cryptography`**: Client/browser-safe exports (default)
113
+ - **`@cryptforge/cryptography/server`**: Server-specific exports + client exports
114
+
115
+ ## API Reference
116
+
117
+ ### CryptoBrowser
118
+
119
+ Browser-compatible cryptographic operations using Web Crypto API.
120
+
121
+ #### Constructor
122
+
123
+ ```typescript
124
+ new CryptoBrowser()
125
+ ```
126
+
127
+ Creates a new CryptoBrowser instance. The encryption key must be set before using encrypt/decrypt methods.
128
+
129
+ #### Methods
130
+
131
+ ##### `setEncryptionKey(key: CryptoKey): void`
132
+
133
+ Sets the encryption key for subsequent operations. Key must be:
134
+ - Algorithm: AES-GCM
135
+ - Length: 256 bits
136
+ - Usages: `['encrypt', 'decrypt']`
137
+
138
+ ```typescript
139
+ const key = await auth.deriveDataEncryptionKey({
140
+ purpose: 'my-data',
141
+ algorithm: 'AES-GCM',
142
+ length: 256,
143
+ });
144
+
145
+ crypto.setEncryptionKey(key);
146
+ ```
147
+
148
+ ##### `encrypt(): (data: string) => Promise<string>`
149
+
150
+ Returns a curried function that encrypts string data.
151
+
152
+ ```typescript
153
+ const encryptFn = crypto.encrypt();
154
+ const encrypted = await encryptFn('Hello, World!');
155
+ ```
156
+
157
+ **Returns**: Base64-encoded string containing IV + ciphertext
158
+
159
+ ##### `decrypt(): (encryptedData: string) => Promise<string>`
160
+
161
+ Returns a curried function that decrypts encrypted string data.
162
+
163
+ ```typescript
164
+ const decryptFn = crypto.decrypt();
165
+ const decrypted = await decryptFn(encrypted);
166
+ ```
167
+
168
+ **Throws**: Error if decryption fails (wrong key, corrupted data, etc.)
169
+
170
+ ## Examples
171
+
172
+ ### Basic Encryption/Decryption
173
+
174
+ ```typescript
175
+ import { CryptoBrowser } from '@cryptforge/cryptography';
176
+ import { createAuthClient } from '@cryptforge/auth';
177
+
178
+ // Setup
179
+ const auth = createAuthClient();
180
+ await auth.unlock({ password: 'password', chainId: 'ethereum' });
181
+
182
+ const key = await auth.deriveDataEncryptionKey({
183
+ purpose: 'user-documents',
184
+ });
185
+
186
+ const crypto = new CryptoBrowser();
187
+ crypto.setEncryptionKey(key);
188
+
189
+ // Encrypt
190
+ const data = JSON.stringify({ title: 'My Document', content: 'Secret data' });
191
+ const encrypted = await crypto.encrypt()(data);
192
+
193
+ // Store encrypted data
194
+ localStorage.setItem('myDocument', encrypted);
195
+
196
+ // Later... decrypt
197
+ const stored = localStorage.getItem('myDocument');
198
+ const decrypted = await crypto.decrypt()(stored!);
199
+ const document = JSON.parse(decrypted);
200
+ ```
201
+
202
+ ### Encrypting Multiple Items
203
+
204
+ ```typescript
205
+ const encrypt = crypto.encrypt();
206
+ const decrypt = crypto.decrypt();
207
+
208
+ // Encrypt multiple items
209
+ const items = ['Item 1', 'Item 2', 'Item 3'];
210
+ const encryptedItems = await Promise.all(
211
+ items.map(item => encrypt(item))
212
+ );
213
+
214
+ // Decrypt multiple items
215
+ const decryptedItems = await Promise.all(
216
+ encryptedItems.map(item => decrypt(item))
217
+ );
218
+ ```
219
+
220
+ ### Error Handling
221
+
222
+ ```typescript
223
+ try {
224
+ const encrypted = await crypto.encrypt()('Secret data');
225
+ const decrypted = await crypto.decrypt()(encrypted);
226
+ } catch (error) {
227
+ if (error.message.includes('Encryption key not available')) {
228
+ // Key not set - unlock wallet first
229
+ await auth.unlock({ password: 'password' });
230
+ const key = await auth.deriveDataEncryptionKey({ purpose: 'data' });
231
+ crypto.setEncryptionKey(key);
232
+ } else {
233
+ // Decryption failed - wrong key or corrupted data
234
+ console.error('Decryption failed:', error);
235
+ }
236
+ }
237
+ ```
238
+
239
+ ### With Automerge Documents
240
+
241
+ Perfect for encrypting Automerge documents:
242
+
243
+ ```typescript
244
+ import { CryptoBrowser } from '@cryptforge/cryptography';
245
+ import * as Automerge from '@automerge/automerge';
246
+
247
+ // Create Automerge document
248
+ let doc = Automerge.init();
249
+ doc = Automerge.change(doc, doc => {
250
+ doc.notes = 'Secret notes';
251
+ });
252
+
253
+ // Encrypt document
254
+ const docBytes = Automerge.save(doc);
255
+ const docString = btoa(String.fromCharCode(...docBytes));
256
+ const encrypted = await crypto.encrypt()(docString);
257
+
258
+ // Store encrypted document
259
+ await storage.save('doc_id', encrypted);
260
+
261
+ // Later... decrypt and load
262
+ const stored = await storage.load('doc_id');
263
+ const decrypted = await crypto.decrypt()(stored);
264
+ const docBytesRestored = Uint8Array.from(atob(decrypted), c => c.charCodeAt(0));
265
+ const restoredDoc = Automerge.load(docBytesRestored);
266
+ ```
267
+
268
+ ## Security Considerations
269
+
270
+ ### Best Practices
271
+
272
+ 1. **Key Management**: Never hardcode encryption keys. Always derive them from user credentials or secure key storage.
273
+
274
+ 2. **Key Rotation**: Use the `version` parameter in `deriveDataEncryptionKey` to support key rotation:
275
+
276
+ ```typescript
277
+ // Old data encrypted with v1
278
+ const keyV1 = await auth.deriveDataEncryptionKey({ purpose: 'data', version: 1 });
279
+
280
+ // New data encrypted with v2
281
+ const keyV2 = await auth.deriveDataEncryptionKey({ purpose: 'data', version: 2 });
282
+ ```
283
+
284
+ 3. **Secure Key Storage**: The encryption key is kept in memory only. When the user locks their wallet, the key is cleared.
285
+
286
+ 4. **No Key Export**: Keys are created with `extractable: false` by default, preventing them from being exported.
287
+
288
+ ### What's Protected
289
+
290
+ ✅ **Data at Rest** - Encrypted data stored in IndexedDB, localStorage, or disk
291
+ ✅ **Data in Transit** - Can encrypt before sending over network
292
+ ✅ **Memory Safety** - Keys cleared when wallet locks
293
+
294
+ ### What's NOT Protected
295
+
296
+ ❌ **Data in Use** - Decrypted data in application memory
297
+ ❌ **Side Channels** - Timing attacks, power analysis
298
+ ❌ **Compromised Device** - Malware, keyloggers
299
+
300
+ Always follow security best practices for your specific use case.
301
+
302
+ ## Cross-Platform Compatibility
303
+
304
+ This package uses **AES-256-GCM**, which is supported across all platforms:
305
+
306
+ | Platform | Support | Notes |
307
+ |----------|---------|-------|
308
+ | **Browser** | ✅ | Web Crypto API (all modern browsers) |
309
+ | **Node.js** | ✅ | Native crypto module (v15+) |
310
+ | **Electron** | ✅ | Both main and renderer processes |
311
+ | **React Native** | ✅ | Via polyfills |
312
+ | **Web Workers** | ✅ | Web Crypto API available |
313
+
314
+ ## Development
315
+
316
+ ```bash
317
+ # Build the package
318
+ npm run build
319
+
320
+ # Run tests
321
+ npm test
322
+ ```
323
+
324
+ ## Related Packages
325
+
326
+ - **[@cryptforge/auth](../auth)** - Key derivation using `deriveDataEncryptionKey()`
327
+ - **[@cryptforge/core](../core)** - Core types and interfaces
328
+
329
+ ## License
330
+
331
+ MIT
@@ -0,0 +1,125 @@
1
+ /**
2
+ * Generic interface for cryptographic operations.
3
+ *
4
+ * @template TKey - The encryption key type (CryptoKey for browser, Buffer for Node.js)
5
+ */
6
+ interface CryptoOperations<TKey = unknown> {
7
+ /**
8
+ * Encryption key for all document operations.
9
+ * All documents are encrypted at rest using this key.
10
+ * Browser implementations use CryptoKey, Node.js implementations use Buffer.
11
+ */
12
+ setEncryptionKey?: (key: TKey) => void;
13
+ /**
14
+ * Creates an encryption function that encrypts string data using AES-GCM encryption.
15
+ * Returns a curried function that uses the instance's encryption key from `setEncryptionKey`.
16
+ *
17
+ * The returned function signature:
18
+ * - `data`: The plaintext string to encrypt
19
+ * - Returns: A promise resolving to the encrypted data as a string
20
+ */
21
+ encrypt: () => (data: string) => Promise<string>;
22
+ /**
23
+ * Creates a decryption function that decrypts encrypted string data using AES-GCM decryption.
24
+ * Returns a curried function that uses the instance's encryption key from `setEncryptionKey`.
25
+ *
26
+ * The returned function signature:
27
+ * - `encryptedData`: The encrypted string data to decrypt
28
+ * - Returns: A promise resolving to the decrypted plaintext string
29
+ */
30
+ decrypt: () => (encryptedData: string) => Promise<string>;
31
+ }
32
+ /**
33
+ * Configuration options for cryptographic operations
34
+ */
35
+ interface CryptoConfig {
36
+ /**
37
+ * Algorithm to use for encryption/decryption
38
+ */
39
+ algorithm?: string;
40
+ /**
41
+ * Key derivation iterations (if applicable)
42
+ */
43
+ iterations?: number;
44
+ }
45
+ /**
46
+ * Result of an encryption operation
47
+ */
48
+ interface EncryptionResult {
49
+ /**
50
+ * Encrypted data
51
+ */
52
+ ciphertext: Uint8Array;
53
+ /**
54
+ * Initialization vector or nonce
55
+ */
56
+ iv: Uint8Array;
57
+ /**
58
+ * Authentication tag (for authenticated encryption)
59
+ */
60
+ tag?: Uint8Array;
61
+ }
62
+ /**
63
+ * Result of a decryption operation
64
+ */
65
+ interface DecryptionResult {
66
+ /**
67
+ * Decrypted plaintext data
68
+ */
69
+ plaintext: Uint8Array;
70
+ }
71
+ /**
72
+ * Key pair for asymmetric cryptography
73
+ */
74
+ interface KeyPair {
75
+ /**
76
+ * Public key
77
+ */
78
+ publicKey: Uint8Array;
79
+ /**
80
+ * Private key
81
+ */
82
+ privateKey: Uint8Array;
83
+ }
84
+
85
+ /**
86
+ * Browser implementation of cryptographic operations using Web Crypto API.
87
+ * Uses CryptoKey for encryption/decryption operations.
88
+ */
89
+ declare class CryptoBrowser implements CryptoOperations<CryptoKey> {
90
+ private encryptionKey?;
91
+ /**
92
+ * Creates a new CryptoBrowser instance.
93
+ * @param getEncryptionKey - Function that returns the encryption key for this instance
94
+ */
95
+ constructor();
96
+ /**
97
+ * Sets the encryption key for the encrypt and decrypt operations.
98
+ * Validates that the key is AES-GCM with 256-bit length for cross-platform compatibility.
99
+ *
100
+ * @param key - The encryption key to set (must be AES-GCM 256-bit)
101
+ * @throws {Error} If key is not AES-GCM or not 256-bit
102
+ */
103
+ setEncryptionKey: (key: CryptoKey) => void;
104
+ /**
105
+ * Creates an encryption function that encrypts string data using AES-GCM encryption.
106
+ * Uses a random initialization vector (IV) for each encryption operation.
107
+ * The IV is prepended to the ciphertext and the result is base64-encoded.
108
+ * Uses the encryption key provided via the `setEncryptionKey` method.
109
+ *
110
+ * @returns A curried function that encrypts data
111
+ */
112
+ encrypt: () => (data: string) => Promise<string>;
113
+ /**
114
+ * Creates a decryption function that decrypts encrypted string data using AES-GCM decryption.
115
+ * Extracts the IV from the beginning of the encrypted data and uses it to decrypt the ciphertext.
116
+ * Uses the encryption key provided via the constructor.
117
+ *
118
+ * @returns A curried function that decrypts data
119
+ */
120
+ decrypt: () => (encryptedData: string) => Promise<string>;
121
+ }
122
+
123
+ declare const version = "0.1.0";
124
+
125
+ export { CryptoBrowser, type CryptoConfig, type CryptoOperations, type DecryptionResult, type EncryptionResult, type KeyPair, version };
@@ -0,0 +1,125 @@
1
+ /**
2
+ * Generic interface for cryptographic operations.
3
+ *
4
+ * @template TKey - The encryption key type (CryptoKey for browser, Buffer for Node.js)
5
+ */
6
+ interface CryptoOperations<TKey = unknown> {
7
+ /**
8
+ * Encryption key for all document operations.
9
+ * All documents are encrypted at rest using this key.
10
+ * Browser implementations use CryptoKey, Node.js implementations use Buffer.
11
+ */
12
+ setEncryptionKey?: (key: TKey) => void;
13
+ /**
14
+ * Creates an encryption function that encrypts string data using AES-GCM encryption.
15
+ * Returns a curried function that uses the instance's encryption key from `setEncryptionKey`.
16
+ *
17
+ * The returned function signature:
18
+ * - `data`: The plaintext string to encrypt
19
+ * - Returns: A promise resolving to the encrypted data as a string
20
+ */
21
+ encrypt: () => (data: string) => Promise<string>;
22
+ /**
23
+ * Creates a decryption function that decrypts encrypted string data using AES-GCM decryption.
24
+ * Returns a curried function that uses the instance's encryption key from `setEncryptionKey`.
25
+ *
26
+ * The returned function signature:
27
+ * - `encryptedData`: The encrypted string data to decrypt
28
+ * - Returns: A promise resolving to the decrypted plaintext string
29
+ */
30
+ decrypt: () => (encryptedData: string) => Promise<string>;
31
+ }
32
+ /**
33
+ * Configuration options for cryptographic operations
34
+ */
35
+ interface CryptoConfig {
36
+ /**
37
+ * Algorithm to use for encryption/decryption
38
+ */
39
+ algorithm?: string;
40
+ /**
41
+ * Key derivation iterations (if applicable)
42
+ */
43
+ iterations?: number;
44
+ }
45
+ /**
46
+ * Result of an encryption operation
47
+ */
48
+ interface EncryptionResult {
49
+ /**
50
+ * Encrypted data
51
+ */
52
+ ciphertext: Uint8Array;
53
+ /**
54
+ * Initialization vector or nonce
55
+ */
56
+ iv: Uint8Array;
57
+ /**
58
+ * Authentication tag (for authenticated encryption)
59
+ */
60
+ tag?: Uint8Array;
61
+ }
62
+ /**
63
+ * Result of a decryption operation
64
+ */
65
+ interface DecryptionResult {
66
+ /**
67
+ * Decrypted plaintext data
68
+ */
69
+ plaintext: Uint8Array;
70
+ }
71
+ /**
72
+ * Key pair for asymmetric cryptography
73
+ */
74
+ interface KeyPair {
75
+ /**
76
+ * Public key
77
+ */
78
+ publicKey: Uint8Array;
79
+ /**
80
+ * Private key
81
+ */
82
+ privateKey: Uint8Array;
83
+ }
84
+
85
+ /**
86
+ * Browser implementation of cryptographic operations using Web Crypto API.
87
+ * Uses CryptoKey for encryption/decryption operations.
88
+ */
89
+ declare class CryptoBrowser implements CryptoOperations<CryptoKey> {
90
+ private encryptionKey?;
91
+ /**
92
+ * Creates a new CryptoBrowser instance.
93
+ * @param getEncryptionKey - Function that returns the encryption key for this instance
94
+ */
95
+ constructor();
96
+ /**
97
+ * Sets the encryption key for the encrypt and decrypt operations.
98
+ * Validates that the key is AES-GCM with 256-bit length for cross-platform compatibility.
99
+ *
100
+ * @param key - The encryption key to set (must be AES-GCM 256-bit)
101
+ * @throws {Error} If key is not AES-GCM or not 256-bit
102
+ */
103
+ setEncryptionKey: (key: CryptoKey) => void;
104
+ /**
105
+ * Creates an encryption function that encrypts string data using AES-GCM encryption.
106
+ * Uses a random initialization vector (IV) for each encryption operation.
107
+ * The IV is prepended to the ciphertext and the result is base64-encoded.
108
+ * Uses the encryption key provided via the `setEncryptionKey` method.
109
+ *
110
+ * @returns A curried function that encrypts data
111
+ */
112
+ encrypt: () => (data: string) => Promise<string>;
113
+ /**
114
+ * Creates a decryption function that decrypts encrypted string data using AES-GCM decryption.
115
+ * Extracts the IV from the beginning of the encrypted data and uses it to decrypt the ciphertext.
116
+ * Uses the encryption key provided via the constructor.
117
+ *
118
+ * @returns A curried function that decrypts data
119
+ */
120
+ decrypt: () => (encryptedData: string) => Promise<string>;
121
+ }
122
+
123
+ declare const version = "0.1.0";
124
+
125
+ export { CryptoBrowser, type CryptoConfig, type CryptoOperations, type DecryptionResult, type EncryptionResult, type KeyPair, version };
package/dist/index.js ADDED
@@ -0,0 +1,119 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") {
12
+ for (let key of __getOwnPropNames(from))
13
+ if (!__hasOwnProp.call(to, key) && key !== except)
14
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
+ }
16
+ return to;
17
+ };
18
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
+
20
+ // src/index.ts
21
+ var index_exports = {};
22
+ __export(index_exports, {
23
+ CryptoBrowser: () => CryptoBrowser,
24
+ version: () => version
25
+ });
26
+ module.exports = __toCommonJS(index_exports);
27
+
28
+ // src/client/CryptoBrowser.ts
29
+ var CryptoBrowser = class {
30
+ encryptionKey;
31
+ /**
32
+ * Creates a new CryptoBrowser instance.
33
+ * @param getEncryptionKey - Function that returns the encryption key for this instance
34
+ */
35
+ constructor() {
36
+ }
37
+ /**
38
+ * Sets the encryption key for the encrypt and decrypt operations.
39
+ * Validates that the key is AES-GCM with 256-bit length for cross-platform compatibility.
40
+ *
41
+ * @param key - The encryption key to set (must be AES-GCM 256-bit)
42
+ * @throws {Error} If key is not AES-GCM or not 256-bit
43
+ */
44
+ setEncryptionKey = (key) => {
45
+ if (key.algorithm.name !== "AES-GCM") {
46
+ throw new Error(
47
+ `Invalid key algorithm: ${key.algorithm.name}. Key must be AES-GCM for cross-platform compatibility with CryptoServer.`
48
+ );
49
+ }
50
+ const keyLength = key.algorithm.length;
51
+ if (keyLength !== 256) {
52
+ throw new Error(
53
+ `Invalid key length: ${keyLength} bits. Key must be 256-bit for cross-platform compatibility with CryptoServer (AES-256-GCM).`
54
+ );
55
+ }
56
+ this.encryptionKey = key;
57
+ };
58
+ /**
59
+ * Creates an encryption function that encrypts string data using AES-GCM encryption.
60
+ * Uses a random initialization vector (IV) for each encryption operation.
61
+ * The IV is prepended to the ciphertext and the result is base64-encoded.
62
+ * Uses the encryption key provided via the `setEncryptionKey` method.
63
+ *
64
+ * @returns A curried function that encrypts data
65
+ */
66
+ encrypt = () => async (data) => {
67
+ const key = this.encryptionKey;
68
+ if (!key) {
69
+ throw new Error(
70
+ "Encryption key not available. You must call `setEncryptionKey` before using this instance."
71
+ );
72
+ }
73
+ const iv = crypto.getRandomValues(new Uint8Array(12));
74
+ const encrypted = await crypto.subtle.encrypt(
75
+ { name: "AES-GCM", iv },
76
+ key,
77
+ new TextEncoder().encode(data)
78
+ );
79
+ const combined = new Uint8Array(iv.length + encrypted.byteLength);
80
+ combined.set(iv);
81
+ combined.set(new Uint8Array(encrypted), iv.length);
82
+ return btoa(String.fromCharCode(...combined));
83
+ };
84
+ /**
85
+ * Creates a decryption function that decrypts encrypted string data using AES-GCM decryption.
86
+ * Extracts the IV from the beginning of the encrypted data and uses it to decrypt the ciphertext.
87
+ * Uses the encryption key provided via the constructor.
88
+ *
89
+ * @returns A curried function that decrypts data
90
+ */
91
+ decrypt = () => async (encryptedData) => {
92
+ const key = this.encryptionKey;
93
+ if (!key) {
94
+ throw new Error(
95
+ "Encryption key not available. You must call `setEncryptionKey` before using this instance."
96
+ );
97
+ }
98
+ const combined = Uint8Array.from(
99
+ atob(encryptedData),
100
+ (c) => c.charCodeAt(0)
101
+ );
102
+ const iv = combined.slice(0, 12);
103
+ const ciphertext = combined.slice(12);
104
+ const decrypted = await crypto.subtle.decrypt(
105
+ { name: "AES-GCM", iv },
106
+ key,
107
+ ciphertext
108
+ );
109
+ return new TextDecoder().decode(decrypted);
110
+ };
111
+ };
112
+
113
+ // src/index.ts
114
+ var version = "0.1.0";
115
+ // Annotate the CommonJS export names for ESM import in node:
116
+ 0 && (module.exports = {
117
+ CryptoBrowser,
118
+ version
119
+ });