@digitaldefiance/ecies-lib 1.1.5 → 1.1.7
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 +561 -130
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -1,68 +1,169 @@
|
|
|
1
1
|
# @digitaldefiance/ecies-lib
|
|
2
2
|
|
|
3
|
-
A production-ready, browser-friendly implementation of Elliptic Curve Integrated Encryption Scheme (ECIES) and related primitives for modern TypeScript runtimes.
|
|
4
|
-
|
|
5
|
-
##
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
- **
|
|
9
|
-
- **
|
|
10
|
-
- **
|
|
11
|
-
- **
|
|
3
|
+
A production-ready, browser-friendly implementation of Elliptic Curve Integrated Encryption Scheme (ECIES) and related cryptographic primitives for modern TypeScript runtimes. Built on Web Crypto API and @noble/curves, this library provides comprehensive encryption, key management, and authentication services with full internationalization support.
|
|
4
|
+
|
|
5
|
+
## Key Features
|
|
6
|
+
|
|
7
|
+
### Core Cryptography
|
|
8
|
+
- **ECIES Encryption** – Three modes: Simple (minimal overhead), Single (length-prefixed), and Multiple (multi-recipient)
|
|
9
|
+
- **Elliptic Curve Operations** – secp256k1 curve for ECDH key exchange and ECDSA signatures
|
|
10
|
+
- **AES-GCM Encryption** – Authenticated symmetric encryption with Web Crypto API
|
|
11
|
+
- **PBKDF2 Key Derivation** – Configurable profiles for password-based key generation
|
|
12
|
+
|
|
13
|
+
### Key Management
|
|
14
|
+
- **BIP39 Mnemonic Support** – Generate and derive keys from 12/15/18/21/24-word mnemonics
|
|
15
|
+
- **HD Wallet Integration** – BIP32/BIP44 hierarchical deterministic key derivation
|
|
16
|
+
- **Member System** – Complete user/member abstraction with cryptographic operations
|
|
17
|
+
- **Secure Storage** – Memory-safe SecureString and SecureBuffer with auto-zeroing
|
|
18
|
+
|
|
19
|
+
### Advanced Features
|
|
20
|
+
- **Multi-Recipient Encryption** – Efficiently encrypt for up to 65,535 recipients
|
|
21
|
+
- **File Encryption Service** – Chunked file encryption with streaming support
|
|
22
|
+
- **Password Login System** – Complete authentication flow with encrypted key storage
|
|
23
|
+
- **Signature Operations** – ECDSA message signing and verification
|
|
24
|
+
|
|
25
|
+
### Developer Experience
|
|
26
|
+
- **Full TypeScript Support** – Comprehensive type definitions and interfaces
|
|
27
|
+
- **Internationalization** – Error messages in English, French, Spanish, Chinese, and Ukrainian
|
|
28
|
+
- **Runtime Configuration** – Injectable configuration profiles for different security requirements
|
|
29
|
+
- **Extensive Testing** – 380+ test specs covering unit, integration, and e2e scenarios
|
|
30
|
+
- **Cross-Platform** – Works in Node.js 18+ and modern browsers
|
|
12
31
|
|
|
13
32
|
## Installation
|
|
14
33
|
|
|
15
34
|
```bash
|
|
16
|
-
|
|
35
|
+
npm install @digitaldefiance/ecies-lib
|
|
17
36
|
# or
|
|
18
37
|
yarn add @digitaldefiance/ecies-lib
|
|
19
38
|
# or
|
|
20
|
-
|
|
39
|
+
pnpm add @digitaldefiance/ecies-lib
|
|
21
40
|
```
|
|
22
41
|
|
|
23
|
-
|
|
24
|
-
>
|
|
25
|
-
> - Node.js 18+ (ships with the Web Crypto API). For earlier Node versions, polyfill `globalThis.crypto` before importing the library.
|
|
26
|
-
> - Browsers with Web Crypto + `BigInt` support (Chromium, Firefox, Safari >= 14).
|
|
42
|
+
### Runtime Requirements
|
|
27
43
|
|
|
28
|
-
|
|
44
|
+
- **Node.js**: Version 18+ (includes Web Crypto API)
|
|
45
|
+
- For Node < 18, polyfill `globalThis.crypto` before importing
|
|
46
|
+
- **Browsers**: Modern browsers with Web Crypto API and BigInt support
|
|
47
|
+
- Chrome/Edge 60+
|
|
48
|
+
- Firefox 60+
|
|
49
|
+
- Safari 14+
|
|
50
|
+
- Opera 47+
|
|
29
51
|
|
|
30
|
-
|
|
52
|
+
### Dependencies
|
|
53
|
+
|
|
54
|
+
The library has minimal peer dependencies:
|
|
55
|
+
- `@digitaldefiance/i18n-lib` - Internationalization engine
|
|
56
|
+
- `@noble/curves` - Elliptic curve cryptography
|
|
57
|
+
- `@scure/bip32`, `@scure/bip39` - HD wallet and mnemonic support
|
|
58
|
+
- `@ethereumjs/wallet` - Ethereum wallet compatibility
|
|
59
|
+
|
|
60
|
+
## Quick Start
|
|
61
|
+
|
|
62
|
+
### Basic Encryption/Decryption
|
|
63
|
+
|
|
64
|
+
```typescript
|
|
31
65
|
import { ECIESService } from '@digitaldefiance/ecies-lib';
|
|
32
66
|
|
|
67
|
+
// Initialize the service
|
|
33
68
|
const ecies = new ECIESService();
|
|
34
69
|
|
|
35
|
-
//
|
|
36
|
-
const
|
|
37
|
-
const
|
|
70
|
+
// Generate a mnemonic and derive keys
|
|
71
|
+
const mnemonic = ecies.generateNewMnemonic();
|
|
72
|
+
const { privateKey, publicKey } = ecies.mnemonicToSimpleKeyPair(mnemonic);
|
|
38
73
|
|
|
39
|
-
//
|
|
40
|
-
const message = new TextEncoder().encode('
|
|
74
|
+
// Encrypt a message
|
|
75
|
+
const message = new TextEncoder().encode('Hello, World!');
|
|
41
76
|
const encrypted = await ecies.encryptSimpleOrSingle(
|
|
42
|
-
false, // false
|
|
43
|
-
|
|
44
|
-
message
|
|
77
|
+
false, // false = Single mode (with length prefix)
|
|
78
|
+
publicKey,
|
|
79
|
+
message
|
|
45
80
|
);
|
|
46
81
|
|
|
47
|
-
//
|
|
82
|
+
// Decrypt the message
|
|
48
83
|
const decrypted = await ecies.decryptSimpleOrSingleWithHeader(
|
|
49
84
|
false,
|
|
50
|
-
|
|
51
|
-
encrypted
|
|
85
|
+
privateKey,
|
|
86
|
+
encrypted
|
|
52
87
|
);
|
|
53
88
|
|
|
54
|
-
console.log(new TextDecoder().decode(decrypted)); // "
|
|
89
|
+
console.log(new TextDecoder().decode(decrypted)); // "Hello, World!"
|
|
55
90
|
```
|
|
56
91
|
|
|
57
|
-
|
|
92
|
+
### Using the Member System
|
|
58
93
|
|
|
59
|
-
|
|
94
|
+
```typescript
|
|
95
|
+
import { ECIESService, Member, MemberType, EmailString } from '@digitaldefiance/ecies-lib';
|
|
60
96
|
|
|
61
|
-
|
|
97
|
+
const ecies = new ECIESService();
|
|
98
|
+
|
|
99
|
+
// Create a new member with generated keys
|
|
100
|
+
const { member, mnemonic } = Member.newMember(
|
|
101
|
+
ecies,
|
|
102
|
+
MemberType.User,
|
|
103
|
+
'Alice',
|
|
104
|
+
new EmailString('alice@example.com')
|
|
105
|
+
);
|
|
106
|
+
|
|
107
|
+
// Encrypt data for the member
|
|
108
|
+
const data = 'Sensitive information';
|
|
109
|
+
const encrypted = await member.encryptData(data);
|
|
110
|
+
|
|
111
|
+
// Decrypt the data
|
|
112
|
+
const decrypted = await member.decryptData(encrypted);
|
|
113
|
+
console.log(new TextDecoder().decode(decrypted));
|
|
114
|
+
|
|
115
|
+
// Sign and verify messages
|
|
116
|
+
const signature = member.sign(new TextEncoder().encode('Message'));
|
|
117
|
+
const isValid = member.verify(signature, new TextEncoder().encode('Message'));
|
|
118
|
+
```
|
|
119
|
+
|
|
120
|
+
## Core Services
|
|
121
|
+
|
|
122
|
+
### ECIESService - Main Encryption Service
|
|
123
|
+
|
|
124
|
+
The primary service for ECIES operations:
|
|
125
|
+
|
|
126
|
+
```typescript
|
|
127
|
+
import { ECIESService, EciesEncryptionTypeEnum } from '@digitaldefiance/ecies-lib';
|
|
128
|
+
|
|
129
|
+
const ecies = new ECIESService();
|
|
130
|
+
|
|
131
|
+
// Generate keys
|
|
132
|
+
const mnemonic = ecies.generateNewMnemonic();
|
|
133
|
+
const { wallet, seed } = ecies.walletAndSeedFromMnemonic(mnemonic);
|
|
134
|
+
const { privateKey, publicKey } = ecies.seedToSimpleKeyPair(seed);
|
|
135
|
+
|
|
136
|
+
// Simple mode - minimal overhead, no length prefix
|
|
137
|
+
const simpleEncrypted = await ecies.encryptSimpleOrSingle(
|
|
138
|
+
true, // true = Simple mode
|
|
139
|
+
publicKey,
|
|
140
|
+
message
|
|
141
|
+
);
|
|
142
|
+
|
|
143
|
+
// Single mode - includes length prefix for validation
|
|
144
|
+
const singleEncrypted = await ecies.encryptSimpleOrSingle(
|
|
145
|
+
false, // false = Single mode
|
|
146
|
+
publicKey,
|
|
147
|
+
message
|
|
148
|
+
);
|
|
149
|
+
|
|
150
|
+
// Decrypt with automatic header parsing
|
|
151
|
+
const decrypted = await ecies.decryptSimpleOrSingleWithHeader(
|
|
152
|
+
false,
|
|
153
|
+
privateKey,
|
|
154
|
+
singleEncrypted
|
|
155
|
+
);
|
|
156
|
+
```
|
|
157
|
+
|
|
158
|
+
### Multi-Recipient Encryption
|
|
159
|
+
|
|
160
|
+
Encrypt once for multiple recipients efficiently:
|
|
161
|
+
|
|
162
|
+
```typescript
|
|
62
163
|
import {
|
|
63
|
-
ECIES,
|
|
64
164
|
EciesMultiRecipient,
|
|
65
165
|
EciesCryptoCore,
|
|
166
|
+
ECIES,
|
|
66
167
|
concatUint8Arrays,
|
|
67
168
|
} from '@digitaldefiance/ecies-lib';
|
|
68
169
|
|
|
@@ -78,6 +179,7 @@ const config = {
|
|
|
78
179
|
const multi = new EciesMultiRecipient(config);
|
|
79
180
|
const core = new EciesCryptoCore(config);
|
|
80
181
|
|
|
182
|
+
// Generate recipients
|
|
81
183
|
const recipients = await Promise.all(
|
|
82
184
|
[...Array(3)].map(async () => {
|
|
83
185
|
const { privateKey, publicKey } = await core.generateEphemeralKeyPair();
|
|
@@ -86,126 +188,156 @@ const recipients = await Promise.all(
|
|
|
86
188
|
privateKey,
|
|
87
189
|
publicKey,
|
|
88
190
|
};
|
|
89
|
-
})
|
|
191
|
+
})
|
|
90
192
|
);
|
|
91
193
|
|
|
92
|
-
|
|
194
|
+
// Encrypt for all recipients
|
|
195
|
+
const message = new TextEncoder().encode('Broadcast message');
|
|
93
196
|
const encrypted = await multi.encryptMultiple(
|
|
94
197
|
recipients.map(({ id, publicKey }) => ({ id, publicKey })),
|
|
95
|
-
|
|
198
|
+
message
|
|
96
199
|
);
|
|
97
200
|
|
|
98
|
-
|
|
201
|
+
// Build transport frame
|
|
202
|
+
const frame = concatUint8Arrays(
|
|
99
203
|
multi.buildHeader(encrypted),
|
|
100
|
-
encrypted.encryptedMessage
|
|
204
|
+
encrypted.encryptedMessage
|
|
101
205
|
);
|
|
102
206
|
|
|
103
|
-
//
|
|
104
|
-
const
|
|
105
|
-
multi.parseMessage(
|
|
207
|
+
// Any recipient can decrypt
|
|
208
|
+
const decrypted = await multi.decryptMultipleForRecipient(
|
|
209
|
+
multi.parseMessage(frame),
|
|
106
210
|
recipients[0].id,
|
|
107
|
-
recipients[0].privateKey
|
|
211
|
+
recipients[0].privateKey
|
|
108
212
|
);
|
|
109
213
|
```
|
|
110
214
|
|
|
111
|
-
|
|
215
|
+
### File Encryption Service
|
|
112
216
|
|
|
113
|
-
|
|
217
|
+
Chunked file encryption for large files:
|
|
114
218
|
|
|
115
|
-
```
|
|
219
|
+
```typescript
|
|
116
220
|
import { ECIESService, EciesFileService } from '@digitaldefiance/ecies-lib';
|
|
117
221
|
|
|
118
222
|
const ecies = new ECIESService();
|
|
119
|
-
const
|
|
223
|
+
const mnemonic = ecies.generateNewMnemonic();
|
|
224
|
+
const { privateKey, publicKey } = ecies.mnemonicToSimpleKeyPair(mnemonic);
|
|
225
|
+
|
|
226
|
+
// Initialize file service with user's private key
|
|
120
227
|
const fileService = new EciesFileService(ecies, privateKey);
|
|
121
228
|
|
|
122
|
-
|
|
123
|
-
const
|
|
124
|
-
fileService.
|
|
229
|
+
// Encrypt a file (browser File object)
|
|
230
|
+
const file = fileInput.files[0];
|
|
231
|
+
const encrypted = await fileService.encryptFile(file, publicKey);
|
|
232
|
+
|
|
233
|
+
// Decrypt the file
|
|
234
|
+
const decrypted = await fileService.decryptFile(encrypted);
|
|
235
|
+
|
|
236
|
+
// Download encrypted file
|
|
237
|
+
fileService.downloadEncryptedFile(encrypted, 'document.enc');
|
|
238
|
+
|
|
239
|
+
// Download decrypted file
|
|
240
|
+
fileService.downloadDecryptedFile(decrypted, 'document.pdf');
|
|
125
241
|
```
|
|
126
242
|
|
|
127
|
-
|
|
243
|
+
The file service:
|
|
244
|
+
- Chunks files into 1MB segments for memory efficiency
|
|
245
|
+
- Encrypts each chunk independently
|
|
246
|
+
- Includes metadata header with chunk information
|
|
247
|
+
- Supports files of any size within browser memory limits
|
|
128
248
|
|
|
129
|
-
|
|
249
|
+
### Password Login Service
|
|
130
250
|
|
|
131
|
-
|
|
251
|
+
Complete password-based authentication system:
|
|
132
252
|
|
|
133
|
-
```
|
|
134
|
-
import {
|
|
135
|
-
|
|
136
|
-
|
|
253
|
+
```typescript
|
|
254
|
+
import {
|
|
255
|
+
ECIESService,
|
|
256
|
+
PasswordLoginService,
|
|
257
|
+
Pbkdf2Service,
|
|
137
258
|
Pbkdf2ProfileEnum,
|
|
138
|
-
|
|
259
|
+
SecureString,
|
|
260
|
+
getEciesI18nEngine,
|
|
139
261
|
} from '@digitaldefiance/ecies-lib';
|
|
140
262
|
|
|
141
|
-
const
|
|
263
|
+
const engine = getEciesI18nEngine();
|
|
264
|
+
const ecies = new ECIESService();
|
|
265
|
+
const pbkdf2 = new Pbkdf2Service(engine);
|
|
266
|
+
const passwordLogin = new PasswordLoginService(ecies, pbkdf2, engine);
|
|
142
267
|
|
|
143
|
-
//
|
|
144
|
-
const
|
|
145
|
-
const
|
|
268
|
+
// Setup password login (first time)
|
|
269
|
+
const mnemonic = ecies.generateNewMnemonic();
|
|
270
|
+
const password = new SecureString('MySecurePassword123!');
|
|
146
271
|
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
saltBytes: 16,
|
|
152
|
-
iterations: 100000,
|
|
153
|
-
algorithm: 'SHA-256'
|
|
154
|
-
}
|
|
155
|
-
};
|
|
156
|
-
const customPbkdf2Service = new Pbkdf2Service(engine, customProfiles);
|
|
157
|
-
|
|
158
|
-
// Derive a login hash with a hardened profile
|
|
159
|
-
const passwordBytes = new TextEncoder().encode('xX_password_Xx!');
|
|
160
|
-
const pbkdf2Result = await pbkdf2Service.deriveKeyFromPasswordWithProfileAsync(
|
|
161
|
-
passwordBytes,
|
|
162
|
-
Pbkdf2ProfileEnum.BROWSER_PASSWORD,
|
|
272
|
+
const wallet = await passwordLogin.setupPasswordLoginLocalStorageBundle(
|
|
273
|
+
mnemonic,
|
|
274
|
+
password,
|
|
275
|
+
Pbkdf2ProfileEnum.BROWSER_PASSWORD
|
|
163
276
|
);
|
|
164
277
|
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
password
|
|
168
|
-
|
|
278
|
+
// Later: Login with password
|
|
279
|
+
const { wallet: recoveredWallet, mnemonic: recoveredMnemonic } =
|
|
280
|
+
await passwordLogin.getWalletAndMnemonicFromLocalStorageBundle(password);
|
|
281
|
+
|
|
282
|
+
// Check if password login is configured
|
|
283
|
+
if (PasswordLoginService.isPasswordLoginSetup()) {
|
|
284
|
+
console.log('Password login is ready');
|
|
285
|
+
}
|
|
169
286
|
```
|
|
170
287
|
|
|
171
|
-
|
|
288
|
+
### PBKDF2 Service
|
|
172
289
|
|
|
173
|
-
|
|
290
|
+
Flexible key derivation with configurable profiles:
|
|
174
291
|
|
|
175
|
-
|
|
292
|
+
```typescript
|
|
293
|
+
import {
|
|
294
|
+
Pbkdf2Service,
|
|
295
|
+
Pbkdf2ProfileEnum,
|
|
296
|
+
IPbkdf2Config,
|
|
297
|
+
getEciesI18nEngine,
|
|
298
|
+
} from '@digitaldefiance/ecies-lib';
|
|
176
299
|
|
|
177
|
-
|
|
178
|
-
|
|
300
|
+
const engine = getEciesI18nEngine();
|
|
301
|
+
const pbkdf2 = new Pbkdf2Service(engine);
|
|
179
302
|
|
|
180
|
-
//
|
|
181
|
-
const
|
|
303
|
+
// Use predefined profiles
|
|
304
|
+
const password = new TextEncoder().encode('password123');
|
|
305
|
+
const result = await pbkdf2.deriveKeyFromPasswordWithProfileAsync(
|
|
306
|
+
password,
|
|
307
|
+
Pbkdf2ProfileEnum.HIGH_SECURITY
|
|
308
|
+
);
|
|
309
|
+
|
|
310
|
+
console.log(result.hash); // Derived key
|
|
311
|
+
console.log(result.salt); // Random salt used
|
|
312
|
+
console.log(result.iterations); // Iteration count
|
|
182
313
|
|
|
183
|
-
//
|
|
314
|
+
// Custom profiles
|
|
184
315
|
const customProfiles: Record<string, IPbkdf2Config> = {
|
|
185
|
-
|
|
316
|
+
ULTRA_SECURE: {
|
|
186
317
|
hashBytes: 64,
|
|
187
|
-
saltBytes: 32,
|
|
188
|
-
iterations:
|
|
189
|
-
algorithm: 'SHA-512'
|
|
318
|
+
saltBytes: 32,
|
|
319
|
+
iterations: 5000000,
|
|
320
|
+
algorithm: 'SHA-512',
|
|
190
321
|
},
|
|
191
|
-
|
|
322
|
+
FAST_DEV: {
|
|
192
323
|
hashBytes: 32,
|
|
193
324
|
saltBytes: 16,
|
|
194
325
|
iterations: 1000,
|
|
195
|
-
algorithm: 'SHA-256'
|
|
196
|
-
}
|
|
326
|
+
algorithm: 'SHA-256',
|
|
327
|
+
},
|
|
197
328
|
};
|
|
198
329
|
|
|
199
|
-
const
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
passwordBytes,
|
|
204
|
-
'HIGH_SECURITY'
|
|
330
|
+
const customPbkdf2 = new Pbkdf2Service(engine, customProfiles);
|
|
331
|
+
const customResult = await customPbkdf2.deriveKeyFromPasswordWithProfileAsync(
|
|
332
|
+
password,
|
|
333
|
+
'ULTRA_SECURE'
|
|
205
334
|
);
|
|
206
335
|
```
|
|
207
336
|
|
|
208
|
-
|
|
337
|
+
**Built-in Profiles:**
|
|
338
|
+
- `BROWSER_PASSWORD`: 2M iterations, SHA-512, 32-byte hash
|
|
339
|
+
- `HIGH_SECURITY`: 5M iterations, SHA-256, 64-byte hash
|
|
340
|
+
- `TEST_FAST`: 1K iterations, SHA-512, 32-byte hash (testing only)
|
|
209
341
|
|
|
210
342
|
## Runtime configuration registry
|
|
211
343
|
|
|
@@ -267,51 +399,189 @@ Every configuration produced by these helpers is deeply frozen and validated so
|
|
|
267
399
|
|
|
268
400
|
> **Tip:** Services such as `ECIESService`, `Pbkdf2Service`, `AESGCMService`, and `PasswordLoginService` accept their respective configuration slices as constructor parameters. Wire them up with values from `getRuntimeConfiguration(key)` to scope behavior per feature area or tenant.
|
|
269
401
|
|
|
270
|
-
|
|
402
|
+
### Secure Memory Primitives
|
|
403
|
+
|
|
404
|
+
Protect sensitive data in memory:
|
|
405
|
+
|
|
406
|
+
```typescript
|
|
407
|
+
import { SecureString, SecureBuffer } from '@digitaldefiance/ecies-lib';
|
|
408
|
+
|
|
409
|
+
// SecureString - for passwords and mnemonics
|
|
410
|
+
const password = new SecureString('MyPassword123');
|
|
411
|
+
console.log(password.value); // Access the value
|
|
412
|
+
console.log(password.valueAsHexString); // As hex
|
|
413
|
+
console.log(password.length); // Get length
|
|
414
|
+
password.dispose(); // Zero memory
|
|
415
|
+
|
|
416
|
+
// SecureBuffer - for binary secrets
|
|
417
|
+
const privateKey = new Uint8Array(32);
|
|
418
|
+
const secureKey = new SecureBuffer(privateKey);
|
|
419
|
+
console.log(secureKey.value); // Access as Uint8Array
|
|
420
|
+
console.log(secureKey.valueAsString); // As string
|
|
421
|
+
console.log(secureKey.valueAsBase64String); // As base64
|
|
422
|
+
secureKey.dispose(); // Zero memory
|
|
423
|
+
|
|
424
|
+
// Both types:
|
|
425
|
+
// - XOR obfuscate data in memory
|
|
426
|
+
// - Include checksums for integrity
|
|
427
|
+
// - Auto-detect disposal attempts
|
|
428
|
+
// - Provide stack traces for debugging
|
|
429
|
+
```
|
|
430
|
+
|
|
431
|
+
### Value Objects
|
|
271
432
|
|
|
272
|
-
-
|
|
273
|
-
- `EmailString`: validated wrapper around critical data, catching malformed inputs early.
|
|
274
|
-
- `Guid` utilities: strong typing via `ts-brand`, plus brand-aware error classes.
|
|
433
|
+
Type-safe wrappers for common data:
|
|
275
434
|
|
|
276
|
-
|
|
435
|
+
```typescript
|
|
436
|
+
import { EmailString, GuidV4 } from '@digitaldefiance/ecies-lib';
|
|
277
437
|
|
|
278
|
-
|
|
438
|
+
// Validated email addresses
|
|
439
|
+
const email = new EmailString('user@example.com');
|
|
440
|
+
console.log(email.toString());
|
|
441
|
+
console.log(email.length);
|
|
279
442
|
|
|
280
|
-
|
|
443
|
+
// Will throw on invalid email:
|
|
444
|
+
// new EmailString('invalid'); // throws InvalidEmailError
|
|
281
445
|
|
|
282
|
-
|
|
283
|
-
|
|
446
|
+
// Type-safe GUIDs with multiple formats
|
|
447
|
+
const guid = GuidV4.new();
|
|
448
|
+
console.log(guid.asFullHexGuid); // "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
|
|
449
|
+
console.log(guid.asShortHexGuid); // "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
|
|
450
|
+
console.log(guid.asBase64Guid); // Base64 encoded
|
|
451
|
+
console.log(guid.asBigIntGuid); // As BigInt
|
|
284
452
|
|
|
453
|
+
// Create from various formats
|
|
454
|
+
const fromHex = new GuidV4('550e8400-e29b-41d4-a716-446655440000');
|
|
455
|
+
const fromBase64 = new GuidV4('VQ6EAOKbQdSnFkRmVUQAAA==');
|
|
456
|
+
|
|
457
|
+
// Compare GUIDs
|
|
458
|
+
if (guid.equals(fromHex)) {
|
|
459
|
+
console.log('GUIDs match');
|
|
460
|
+
}
|
|
461
|
+
```
|
|
462
|
+
|
|
463
|
+
## Error Handling
|
|
464
|
+
|
|
465
|
+
Comprehensive typed error system with internationalization:
|
|
466
|
+
|
|
467
|
+
```typescript
|
|
468
|
+
import {
|
|
469
|
+
ECIESError,
|
|
470
|
+
ECIESErrorTypeEnum,
|
|
471
|
+
MemberError,
|
|
472
|
+
MemberErrorType,
|
|
473
|
+
GuidError,
|
|
474
|
+
GuidErrorType,
|
|
475
|
+
Pbkdf2Error,
|
|
476
|
+
Pbkdf2ErrorType,
|
|
477
|
+
} from '@digitaldefiance/ecies-lib';
|
|
478
|
+
|
|
479
|
+
// ECIES errors
|
|
285
480
|
try {
|
|
286
481
|
await ecies.decryptSimpleOrSingleWithHeader(false, privateKey, tamperedData);
|
|
287
482
|
} catch (error) {
|
|
288
483
|
if (error instanceof ECIESError) {
|
|
289
|
-
|
|
290
|
-
|
|
484
|
+
switch (error.type) {
|
|
485
|
+
case ECIESErrorTypeEnum.DecryptionFailed:
|
|
486
|
+
console.error('Decryption failed - data may be corrupted');
|
|
487
|
+
break;
|
|
488
|
+
case ECIESErrorTypeEnum.InvalidEncryptionType:
|
|
489
|
+
console.error('Invalid encryption type in header');
|
|
490
|
+
break;
|
|
491
|
+
case ECIESErrorTypeEnum.InvalidPublicKey:
|
|
492
|
+
console.error('Public key format is invalid');
|
|
493
|
+
break;
|
|
291
494
|
}
|
|
292
495
|
}
|
|
293
496
|
}
|
|
497
|
+
|
|
498
|
+
// Member errors
|
|
499
|
+
try {
|
|
500
|
+
const member = Member.newMember(ecies, MemberType.User, '', email);
|
|
501
|
+
} catch (error) {
|
|
502
|
+
if (error instanceof MemberError) {
|
|
503
|
+
if (error.type === MemberErrorType.MissingMemberName) {
|
|
504
|
+
console.error('Member name is required');
|
|
505
|
+
}
|
|
506
|
+
}
|
|
507
|
+
}
|
|
508
|
+
|
|
509
|
+
// All errors include:
|
|
510
|
+
// - Typed error codes (enums)
|
|
511
|
+
// - Localized messages (6 languages)
|
|
512
|
+
// - Stack traces
|
|
513
|
+
// - Optional context data
|
|
294
514
|
```
|
|
295
515
|
|
|
296
|
-
|
|
516
|
+
**Error Categories:**
|
|
517
|
+
- `ECIESError` - Encryption/decryption failures
|
|
518
|
+
- `MemberError` - Member operations
|
|
519
|
+
- `GuidError` - GUID validation
|
|
520
|
+
- `Pbkdf2Error` - Key derivation
|
|
521
|
+
- `LengthError` - Data length validation
|
|
522
|
+
- `SecureStorageError` - Secure memory operations
|
|
523
|
+
- `InvalidEmailError` - Email validation
|
|
524
|
+
|
|
525
|
+
## Architecture
|
|
526
|
+
|
|
527
|
+
### Project Structure
|
|
297
528
|
|
|
298
|
-
```
|
|
529
|
+
```
|
|
299
530
|
packages/digitaldefiance-ecies-lib/
|
|
300
|
-
|
|
301
|
-
│
|
|
302
|
-
│
|
|
303
|
-
│
|
|
304
|
-
│
|
|
305
|
-
│
|
|
306
|
-
│
|
|
307
|
-
|
|
308
|
-
│
|
|
309
|
-
│
|
|
310
|
-
│
|
|
311
|
-
│
|
|
312
|
-
|
|
531
|
+
├── src/
|
|
532
|
+
│ ├── services/
|
|
533
|
+
│ │ ├── ecies/ # ECIES implementation
|
|
534
|
+
│ │ │ ├── service.ts # Main ECIESService
|
|
535
|
+
│ │ │ ├── crypto-core.ts # Core crypto operations
|
|
536
|
+
│ │ │ ├── multi-recipient.ts # Multi-recipient encryption
|
|
537
|
+
│ │ │ ├── single-recipient.ts # Single recipient encryption
|
|
538
|
+
│ │ │ ├── file.ts # File encryption service
|
|
539
|
+
│ │ │ └── signature.ts # ECDSA signatures
|
|
540
|
+
│ │ ├── aes-gcm.ts # AES-GCM encryption
|
|
541
|
+
│ │ ├── pbkdf2.ts # PBKDF2 key derivation
|
|
542
|
+
│ │ ├── password-login.ts # Password authentication
|
|
543
|
+
│ │ └── xor.ts # XOR obfuscation
|
|
544
|
+
│ ├── enumerations/ # Type-safe enums
|
|
545
|
+
│ ├── errors/ # Typed error classes
|
|
546
|
+
│ ├── interfaces/ # TypeScript interfaces
|
|
547
|
+
│ ├── types/ # Type definitions
|
|
548
|
+
│ ├── constants.ts # Library constants
|
|
549
|
+
│ ├── defaults.ts # Default configurations
|
|
550
|
+
│ ├── member.ts # Member abstraction
|
|
551
|
+
│ ├── secure-string.ts # Secure string storage
|
|
552
|
+
│ ├── secure-buffer.ts # Secure buffer storage
|
|
553
|
+
│ ├── email-string.ts # Validated email
|
|
554
|
+
│ ├── guid.ts # GUID utilities
|
|
555
|
+
│ ├── utils.ts # Helper functions
|
|
556
|
+
│ ├── i18n-setup.ts # Internationalization
|
|
557
|
+
│ └── index.ts # Public API
|
|
558
|
+
├── tests/
|
|
559
|
+
│ ├── services/ # Service tests
|
|
560
|
+
│ ├── *.spec.ts # Unit tests
|
|
561
|
+
│ ├── *.e2e.spec.ts # Integration tests
|
|
562
|
+
│ └── support/ # Test utilities
|
|
563
|
+
└── package.json
|
|
313
564
|
```
|
|
314
565
|
|
|
566
|
+
### Key Concepts
|
|
567
|
+
|
|
568
|
+
**Encryption Modes:**
|
|
569
|
+
- **Simple**: Minimal overhead, no length prefix (98 bytes overhead)
|
|
570
|
+
- **Single**: Includes 8-byte length prefix (106 bytes overhead)
|
|
571
|
+
- **Multiple**: Shared symmetric key encrypted for each recipient
|
|
572
|
+
|
|
573
|
+
**Key Derivation:**
|
|
574
|
+
- BIP39 mnemonics → BIP32 HD keys → secp256k1 key pairs
|
|
575
|
+
- Deterministic key generation from mnemonic phrases
|
|
576
|
+
- Support for custom derivation paths
|
|
577
|
+
|
|
578
|
+
**Security Features:**
|
|
579
|
+
- AES-GCM authenticated encryption (256-bit keys)
|
|
580
|
+
- ECDH key agreement on secp256k1 curve
|
|
581
|
+
- PBKDF2 password hashing with configurable iterations
|
|
582
|
+
- Memory-safe storage with automatic zeroing
|
|
583
|
+
- XOR obfuscation for in-memory secrets
|
|
584
|
+
|
|
315
585
|
## Quality gates
|
|
316
586
|
|
|
317
587
|
The project ships with mandatory linting, formatting, and testing commands:
|
|
@@ -337,6 +607,157 @@ Continuous integration mirrors these gates, and the repository currently passes
|
|
|
337
607
|
- **Browser bundlers**: the package ships TypeScript sources; rely on your bundler (Vite, Webpack, Next.js) to tree-shake unused exports. All external dependencies are ESM-friendly.
|
|
338
608
|
- **Memory hygiene**: many helpers (e.g., `SecureBuffer`) provide `.dispose()` to zero sensitive data. Call them when you’re done.
|
|
339
609
|
|
|
610
|
+
## API Reference
|
|
611
|
+
|
|
612
|
+
### Main Exports
|
|
613
|
+
|
|
614
|
+
```typescript
|
|
615
|
+
// Services
|
|
616
|
+
export { ECIESService } from './services/ecies/service';
|
|
617
|
+
export { EciesCryptoCore } from './services/ecies/crypto-core';
|
|
618
|
+
export { EciesMultiRecipient } from './services/ecies/multi-recipient';
|
|
619
|
+
export { EciesFileService } from './services/ecies/file';
|
|
620
|
+
export { AESGCMService } from './services/aes-gcm';
|
|
621
|
+
export { Pbkdf2Service } from './services/pbkdf2';
|
|
622
|
+
export { PasswordLoginService } from './services/password-login';
|
|
623
|
+
export { XorService } from './services/xor';
|
|
624
|
+
|
|
625
|
+
// Member System
|
|
626
|
+
export { Member } from './member';
|
|
627
|
+
export { MemberType } from './enumerations/member-type';
|
|
628
|
+
|
|
629
|
+
// Secure Primitives
|
|
630
|
+
export { SecureString } from './secure-string';
|
|
631
|
+
export { SecureBuffer } from './secure-buffer';
|
|
632
|
+
export { EmailString } from './email-string';
|
|
633
|
+
export { GuidV4 } from './guid';
|
|
634
|
+
|
|
635
|
+
// Configuration
|
|
636
|
+
export { Defaults, ECIES, PBKDF2, CHECKSUM } from './defaults';
|
|
637
|
+
export { DefaultsRegistry } from './defaults';
|
|
638
|
+
export { Constants } from './constants';
|
|
639
|
+
|
|
640
|
+
// Enumerations
|
|
641
|
+
export { EciesEncryptionTypeEnum } from './enumerations/ecies-encryption-type';
|
|
642
|
+
export { Pbkdf2ProfileEnum } from './enumerations/pbkdf2-profile';
|
|
643
|
+
export { MemberErrorType } from './enumerations/member-error-type';
|
|
644
|
+
export { ECIESErrorTypeEnum } from './enumerations/ecies-error-type';
|
|
645
|
+
|
|
646
|
+
// Errors
|
|
647
|
+
export { ECIESError } from './errors/ecies';
|
|
648
|
+
export { MemberError } from './errors/member';
|
|
649
|
+
export { GuidError } from './errors/guid';
|
|
650
|
+
export { Pbkdf2Error } from './errors/pbkdf2';
|
|
651
|
+
|
|
652
|
+
// Utilities
|
|
653
|
+
export * from './utils';
|
|
654
|
+
|
|
655
|
+
// Internationalization
|
|
656
|
+
export { getEciesI18nEngine } from './i18n-setup';
|
|
657
|
+
```
|
|
658
|
+
|
|
659
|
+
## Development
|
|
660
|
+
|
|
661
|
+
### Building
|
|
662
|
+
|
|
663
|
+
```bash
|
|
664
|
+
yarn install # Install dependencies
|
|
665
|
+
yarn build # Compile TypeScript
|
|
666
|
+
yarn test # Run test suite
|
|
667
|
+
yarn lint # Check code style
|
|
668
|
+
yarn format # Fix formatting and linting
|
|
669
|
+
```
|
|
670
|
+
|
|
671
|
+
### Testing
|
|
672
|
+
|
|
673
|
+
```bash
|
|
674
|
+
yarn test # Run all tests
|
|
675
|
+
yarn test:stream # Stream output
|
|
676
|
+
yarn test --watch # Watch mode
|
|
677
|
+
yarn test file.spec.ts # Run specific test
|
|
678
|
+
```
|
|
679
|
+
|
|
680
|
+
The library includes 380+ test specifications covering:
|
|
681
|
+
- Unit tests for all services and utilities
|
|
682
|
+
- Integration tests for encryption workflows
|
|
683
|
+
- E2E tests for password login and file encryption
|
|
684
|
+
- Cross-platform compatibility tests
|
|
685
|
+
- Error handling and edge cases
|
|
686
|
+
|
|
687
|
+
### Code Quality
|
|
688
|
+
|
|
689
|
+
```bash
|
|
690
|
+
yarn lint # ESLint check
|
|
691
|
+
yarn lint:fix # Auto-fix issues
|
|
692
|
+
yarn prettier:check # Format check
|
|
693
|
+
yarn prettier:fix # Auto-format
|
|
694
|
+
yarn format # Fix all issues
|
|
695
|
+
```
|
|
696
|
+
|
|
697
|
+
## Platform-Specific Notes
|
|
698
|
+
|
|
699
|
+
### Node.js
|
|
700
|
+
|
|
701
|
+
Node.js 18+ includes Web Crypto API by default. For older versions:
|
|
702
|
+
|
|
703
|
+
```typescript
|
|
704
|
+
import { webcrypto } from 'crypto';
|
|
705
|
+
globalThis.crypto = webcrypto as unknown as Crypto;
|
|
706
|
+
```
|
|
707
|
+
|
|
708
|
+
### Browser
|
|
709
|
+
|
|
710
|
+
The library works in all modern browsers:
|
|
711
|
+
- Uses Web Crypto API for cryptographic operations
|
|
712
|
+
- No polyfills required for modern browsers
|
|
713
|
+
- Tree-shakeable with modern bundlers (Vite, Webpack, Rollup)
|
|
714
|
+
- All dependencies are ESM-compatible
|
|
715
|
+
|
|
716
|
+
### Bundler Configuration
|
|
717
|
+
|
|
718
|
+
**Vite:**
|
|
719
|
+
```javascript
|
|
720
|
+
// vite.config.js
|
|
721
|
+
export default {
|
|
722
|
+
optimizeDeps: {
|
|
723
|
+
include: ['@digitaldefiance/ecies-lib']
|
|
724
|
+
}
|
|
725
|
+
}
|
|
726
|
+
```
|
|
727
|
+
|
|
728
|
+
**Webpack:**
|
|
729
|
+
```javascript
|
|
730
|
+
// webpack.config.js
|
|
731
|
+
module.exports = {
|
|
732
|
+
resolve: {
|
|
733
|
+
fallback: {
|
|
734
|
+
crypto: false,
|
|
735
|
+
stream: false
|
|
736
|
+
}
|
|
737
|
+
}
|
|
738
|
+
}
|
|
739
|
+
```
|
|
740
|
+
|
|
741
|
+
### Memory Management
|
|
742
|
+
|
|
743
|
+
Always dispose of sensitive data:
|
|
744
|
+
|
|
745
|
+
```typescript
|
|
746
|
+
const password = new SecureString('secret');
|
|
747
|
+
try {
|
|
748
|
+
// Use password
|
|
749
|
+
} finally {
|
|
750
|
+
password.dispose(); // Zeros memory
|
|
751
|
+
}
|
|
752
|
+
|
|
753
|
+
const privateKey = new SecureBuffer(keyBytes);
|
|
754
|
+
try {
|
|
755
|
+
// Use key
|
|
756
|
+
} finally {
|
|
757
|
+
privateKey.dispose(); // Zeros memory
|
|
758
|
+
}
|
|
759
|
+
```
|
|
760
|
+
|
|
340
761
|
## Contributing
|
|
341
762
|
|
|
342
763
|
1. Fork & clone the repo.
|
|
@@ -349,7 +770,7 @@ Bug reports and feature requests are welcome—open an issue with reproduction s
|
|
|
349
770
|
|
|
350
771
|
## Security
|
|
351
772
|
|
|
352
|
-
If you discover a vulnerability, please **do not** open a public issue. Email <security@digitaldefiance.
|
|
773
|
+
If you discover a vulnerability, please **do not** open a public issue. Email <security@digitaldefiance.org> with details so we can coordinate a fix and responsible disclosure timeline.
|
|
353
774
|
|
|
354
775
|
## License
|
|
355
776
|
|
|
@@ -361,6 +782,16 @@ MIT © Digital Defiance
|
|
|
361
782
|
|
|
362
783
|
## ChangeLog
|
|
363
784
|
|
|
785
|
+
### v1.1.7
|
|
786
|
+
|
|
787
|
+
- Sun Oct 26 2026 20:45:00 GMT-0700 (Pacific Daylight Time)
|
|
788
|
+
- Update readme
|
|
789
|
+
|
|
790
|
+
### v1.1.6
|
|
791
|
+
|
|
792
|
+
- Sun Oct 26 2026 15:49:00 GMT-0700 (Pacific Daylight Time)
|
|
793
|
+
- Update i18n lib
|
|
794
|
+
|
|
364
795
|
### v1.1.5
|
|
365
796
|
|
|
366
797
|
- Sun Oct 26 2026 15:37:00 GMT-0700 (Pacific Daylight Time)
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@digitaldefiance/ecies-lib",
|
|
3
|
-
"version": "1.1.
|
|
3
|
+
"version": "1.1.7",
|
|
4
4
|
"description": "Digital Defiance ECIES Library",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"types": "dist/index.d.ts",
|
|
@@ -51,7 +51,7 @@
|
|
|
51
51
|
"license": "MIT",
|
|
52
52
|
"packageManager": "yarn@4.10.3",
|
|
53
53
|
"dependencies": {
|
|
54
|
-
"@digitaldefiance/i18n-lib": "1.3.
|
|
54
|
+
"@digitaldefiance/i18n-lib": "1.3.1",
|
|
55
55
|
"@ethereumjs/wallet": "^10.0.0",
|
|
56
56
|
"@noble/curves": "^2.0.1",
|
|
57
57
|
"@noble/hashes": "^2.0.1",
|