@digitaldefiance/ecies-lib 2.1.42 → 3.0.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.
Files changed (76) hide show
  1. package/README.md +148 -3
  2. package/package.json +3 -3
  3. package/src/enumerations/ecies-string-key.d.ts +9 -0
  4. package/src/enumerations/ecies-string-key.d.ts.map +1 -1
  5. package/src/enumerations/ecies-string-key.js +9 -0
  6. package/src/enumerations/ecies-string-key.js.map +1 -1
  7. package/src/i18n-setup.d.ts.map +1 -1
  8. package/src/i18n-setup.js +63 -0
  9. package/src/i18n-setup.js.map +1 -1
  10. package/src/index.d.ts +12 -0
  11. package/src/index.d.ts.map +1 -1
  12. package/src/index.js +15 -1
  13. package/src/index.js.map +1 -1
  14. package/src/interfaces/encrypted-chunk.d.ts +55 -0
  15. package/src/interfaces/encrypted-chunk.d.ts.map +1 -0
  16. package/src/interfaces/encrypted-chunk.js +15 -0
  17. package/src/interfaces/encrypted-chunk.js.map +1 -0
  18. package/src/interfaces/encryption-state.d.ts +18 -0
  19. package/src/interfaces/encryption-state.d.ts.map +1 -0
  20. package/src/interfaces/encryption-state.js +5 -0
  21. package/src/interfaces/encryption-state.js.map +1 -0
  22. package/src/interfaces/frontend-member-operational.d.ts +12 -1
  23. package/src/interfaces/frontend-member-operational.d.ts.map +1 -1
  24. package/src/interfaces/multi-recipient-chunk.d.ts +65 -0
  25. package/src/interfaces/multi-recipient-chunk.d.ts.map +1 -0
  26. package/src/interfaces/multi-recipient-chunk.js +25 -0
  27. package/src/interfaces/multi-recipient-chunk.js.map +1 -0
  28. package/src/interfaces/stream-config.d.ts +14 -0
  29. package/src/interfaces/stream-config.d.ts.map +1 -0
  30. package/src/interfaces/stream-config.js +11 -0
  31. package/src/interfaces/stream-config.js.map +1 -0
  32. package/src/interfaces/stream-header.d.ts +29 -0
  33. package/src/interfaces/stream-header.d.ts.map +1 -0
  34. package/src/interfaces/stream-header.js +12 -0
  35. package/src/interfaces/stream-header.js.map +1 -0
  36. package/src/interfaces/stream-progress.d.ts +33 -0
  37. package/src/interfaces/stream-progress.d.ts.map +1 -0
  38. package/src/interfaces/stream-progress.js +3 -0
  39. package/src/interfaces/stream-progress.js.map +1 -0
  40. package/src/member.d.ts +26 -0
  41. package/src/member.d.ts.map +1 -1
  42. package/src/member.js +67 -0
  43. package/src/member.js.map +1 -1
  44. package/src/services/aes-gcm.d.ts.map +1 -1
  45. package/src/services/aes-gcm.js +29 -0
  46. package/src/services/aes-gcm.js.map +1 -1
  47. package/src/services/chunk-processor.d.ts +31 -0
  48. package/src/services/chunk-processor.d.ts.map +1 -0
  49. package/src/services/chunk-processor.js +143 -0
  50. package/src/services/chunk-processor.js.map +1 -0
  51. package/src/services/ecies/crypto-core.d.ts.map +1 -1
  52. package/src/services/ecies/crypto-core.js +23 -8
  53. package/src/services/ecies/crypto-core.js.map +1 -1
  54. package/src/services/ecies/single-recipient.d.ts.map +1 -1
  55. package/src/services/ecies/single-recipient.js +55 -4
  56. package/src/services/ecies/single-recipient.js.map +1 -1
  57. package/src/services/encryption-stream.d.ts +69 -0
  58. package/src/services/encryption-stream.d.ts.map +1 -0
  59. package/src/services/encryption-stream.js +290 -0
  60. package/src/services/encryption-stream.js.map +1 -0
  61. package/src/services/multi-recipient-processor.d.ts +25 -0
  62. package/src/services/multi-recipient-processor.d.ts.map +1 -0
  63. package/src/services/multi-recipient-processor.js +234 -0
  64. package/src/services/multi-recipient-processor.js.map +1 -0
  65. package/src/services/progress-tracker.d.ts +23 -0
  66. package/src/services/progress-tracker.d.ts.map +1 -0
  67. package/src/services/progress-tracker.js +95 -0
  68. package/src/services/progress-tracker.js.map +1 -0
  69. package/src/services/resumable-encryption.d.ts +19 -0
  70. package/src/services/resumable-encryption.d.ts.map +1 -0
  71. package/src/services/resumable-encryption.js +104 -0
  72. package/src/services/resumable-encryption.js.map +1 -0
  73. package/src/test-mocks/mock-frontend-member.d.ts +15 -0
  74. package/src/test-mocks/mock-frontend-member.d.ts.map +1 -1
  75. package/src/test-mocks/mock-frontend-member.js +58 -0
  76. package/src/test-mocks/mock-frontend-member.js.map +1 -1
@@ -0,0 +1,290 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.EncryptionStream = void 0;
4
+ const constants_1 = require("../constants");
5
+ const stream_config_1 = require("../interfaces/stream-config");
6
+ const stream_header_1 = require("../interfaces/stream-header");
7
+ const chunk_processor_1 = require("./chunk-processor");
8
+ const progress_tracker_1 = require("./progress-tracker");
9
+ const multi_recipient_processor_1 = require("./multi-recipient-processor");
10
+ /**
11
+ * Streaming encryption/decryption service
12
+ */
13
+ class EncryptionStream {
14
+ ecies;
15
+ config;
16
+ eciesConsts;
17
+ processor;
18
+ multiRecipientProcessor;
19
+ constructor(ecies, config = stream_config_1.DEFAULT_STREAM_CONFIG, eciesConsts = constants_1.Constants.ECIES) {
20
+ this.ecies = ecies;
21
+ this.config = config;
22
+ this.eciesConsts = eciesConsts;
23
+ this.processor = new chunk_processor_1.ChunkProcessor(ecies, eciesConsts);
24
+ this.multiRecipientProcessor = new multi_recipient_processor_1.MultiRecipientProcessor(ecies);
25
+ }
26
+ /**
27
+ * Build stream header
28
+ */
29
+ buildStreamHeader(header) {
30
+ const buffer = new Uint8Array(stream_header_1.STREAM_HEADER_CONSTANTS.HEADER_SIZE);
31
+ const view = new DataView(buffer.buffer);
32
+ view.setUint32(0, header.magic, false);
33
+ view.setUint16(4, header.version, false);
34
+ view.setUint8(6, header.encryptionType);
35
+ view.setUint32(7, header.chunkSize, false);
36
+ view.setUint32(11, header.totalChunks, false);
37
+ view.setBigUint64(15, BigInt(header.totalBytes), false);
38
+ view.setBigUint64(23, BigInt(header.timestamp), false);
39
+ // Bytes 31-127: reserved (zeros)
40
+ return buffer;
41
+ }
42
+ /**
43
+ * Parse stream header
44
+ */
45
+ parseStreamHeader(data) {
46
+ if (data.length < stream_header_1.STREAM_HEADER_CONSTANTS.HEADER_SIZE) {
47
+ throw new Error('Data too short for stream header');
48
+ }
49
+ const view = new DataView(data.buffer, data.byteOffset);
50
+ const magic = view.getUint32(0, false);
51
+ if (magic !== stream_header_1.STREAM_HEADER_CONSTANTS.MAGIC) {
52
+ throw new Error('Invalid stream magic bytes');
53
+ }
54
+ const version = view.getUint16(4, false);
55
+ if (version !== stream_header_1.STREAM_HEADER_CONSTANTS.VERSION) {
56
+ throw new Error('Unsupported stream version');
57
+ }
58
+ return {
59
+ magic,
60
+ version,
61
+ encryptionType: view.getUint8(6),
62
+ chunkSize: view.getUint32(7, false),
63
+ totalChunks: view.getUint32(11, false),
64
+ totalBytes: Number(view.getBigUint64(15, false)),
65
+ timestamp: Number(view.getBigUint64(23, false)),
66
+ };
67
+ }
68
+ /**
69
+ * Encrypt data stream
70
+ */
71
+ async *encryptStream(source, publicKey, options = {}) {
72
+ // Validate public key (65 bytes uncompressed with 0x04 prefix)
73
+ if (!publicKey || (publicKey.length !== 65 && publicKey.length !== 33)) {
74
+ throw new Error('Invalid public key: must be 33 (compressed) or 65 (uncompressed) bytes');
75
+ }
76
+ const chunkSize = options.chunkSize ?? this.config.chunkSize;
77
+ const includeChecksums = options.includeChecksums ?? this.config.includeChecksums;
78
+ const signal = options.signal;
79
+ const onProgress = options.onProgress;
80
+ let buffer = new Uint8Array(0);
81
+ let chunkIndex = 0;
82
+ let lastYieldedChunk = null;
83
+ let tracker;
84
+ let totalBytesRead = 0;
85
+ const maxSingleChunk = 100 * 1024 * 1024; // 100MB max per source chunk
86
+ for await (const data of source) {
87
+ // Check for cancellation
88
+ if (signal?.aborted) {
89
+ throw new DOMException('Encryption cancelled', 'AbortError');
90
+ }
91
+ // Prevent buffer exhaustion from single large source chunk
92
+ if (data.length > maxSingleChunk) {
93
+ throw new Error(`Buffer overflow: source chunk exceeds ${maxSingleChunk} bytes`);
94
+ }
95
+ // Append to buffer
96
+ const newBuffer = new Uint8Array(buffer.length + data.length);
97
+ newBuffer.set(buffer);
98
+ newBuffer.set(data, buffer.length);
99
+ buffer = newBuffer;
100
+ totalBytesRead += data.length;
101
+ // Initialize tracker on first data
102
+ if (!tracker && onProgress) {
103
+ tracker = new progress_tracker_1.ProgressTracker();
104
+ }
105
+ // Process complete chunks
106
+ while (buffer.length >= chunkSize) {
107
+ if (signal?.aborted) {
108
+ throw new DOMException('Encryption cancelled', 'AbortError');
109
+ }
110
+ const chunkData = buffer.slice(0, chunkSize);
111
+ buffer = buffer.slice(chunkSize);
112
+ const encryptedChunk = await this.processor.encryptChunk(chunkData, publicKey, chunkIndex++, false, includeChecksums);
113
+ lastYieldedChunk = encryptedChunk;
114
+ yield encryptedChunk;
115
+ // Report progress
116
+ if (tracker && onProgress) {
117
+ onProgress(tracker.update(chunkSize));
118
+ }
119
+ }
120
+ }
121
+ // Process remaining data as last chunk
122
+ if (buffer.length > 0) {
123
+ if (signal?.aborted) {
124
+ throw new DOMException('Encryption cancelled', 'AbortError');
125
+ }
126
+ const encryptedChunk = await this.processor.encryptChunk(buffer, publicKey, chunkIndex, true, includeChecksums);
127
+ yield encryptedChunk;
128
+ // Report final progress
129
+ if (tracker && onProgress) {
130
+ onProgress(tracker.update(buffer.length));
131
+ }
132
+ }
133
+ else if (chunkIndex === 0) {
134
+ // Empty stream - yield nothing
135
+ return;
136
+ }
137
+ else if (lastYieldedChunk) {
138
+ // Mark the last yielded chunk as last
139
+ lastYieldedChunk.isLast = true;
140
+ }
141
+ }
142
+ /**
143
+ * Encrypt stream for multiple recipients
144
+ * Uses shared symmetric key encrypted for each recipient
145
+ */
146
+ async *encryptStreamMultiple(source, recipients, options = {}) {
147
+ if (recipients.length === 0) {
148
+ throw new Error('At least one recipient required');
149
+ }
150
+ if (recipients.length > 65535) {
151
+ throw new Error('Maximum 65535 recipients supported');
152
+ }
153
+ // Validate all recipient public keys
154
+ for (const recipient of recipients) {
155
+ if (!recipient.publicKey || (recipient.publicKey.length !== 65 && recipient.publicKey.length !== 33)) {
156
+ throw new Error('Invalid recipient public key: must be 33 (compressed) or 65 (uncompressed) bytes');
157
+ }
158
+ if (!recipient.id || recipient.id.length !== 32) {
159
+ throw new Error('Invalid recipient ID: must be 32 bytes');
160
+ }
161
+ }
162
+ const chunkSize = options.chunkSize ?? this.config.chunkSize;
163
+ const signal = options.signal;
164
+ const onProgress = options.onProgress;
165
+ // Generate shared symmetric key for this stream
166
+ const symmetricKey = crypto.getRandomValues(new Uint8Array(32));
167
+ let buffer = new Uint8Array(0);
168
+ let chunkIndex = 0;
169
+ let tracker;
170
+ const maxSingleChunk = 100 * 1024 * 1024;
171
+ for await (const data of source) {
172
+ if (signal?.aborted) {
173
+ throw new DOMException('Encryption cancelled', 'AbortError');
174
+ }
175
+ if (data.length > maxSingleChunk) {
176
+ throw new Error(`Buffer overflow: source chunk exceeds ${maxSingleChunk} bytes`);
177
+ }
178
+ const newBuffer = new Uint8Array(buffer.length + data.length);
179
+ newBuffer.set(buffer);
180
+ newBuffer.set(data, buffer.length);
181
+ buffer = newBuffer;
182
+ if (!tracker && onProgress) {
183
+ tracker = new progress_tracker_1.ProgressTracker();
184
+ }
185
+ while (buffer.length >= chunkSize) {
186
+ if (signal?.aborted) {
187
+ throw new DOMException('Encryption cancelled', 'AbortError');
188
+ }
189
+ const chunkData = buffer.slice(0, chunkSize);
190
+ buffer = buffer.slice(chunkSize);
191
+ const encryptedChunk = await this.multiRecipientProcessor.encryptChunk(chunkData, recipients, chunkIndex++, false, symmetricKey);
192
+ yield encryptedChunk;
193
+ if (tracker && onProgress) {
194
+ onProgress(tracker.update(chunkSize));
195
+ }
196
+ }
197
+ }
198
+ // Process remaining data as last chunk
199
+ if (buffer.length > 0) {
200
+ if (signal?.aborted) {
201
+ throw new DOMException('Encryption cancelled', 'AbortError');
202
+ }
203
+ const encryptedChunk = await this.multiRecipientProcessor.encryptChunk(buffer, recipients, chunkIndex, true, symmetricKey);
204
+ yield encryptedChunk;
205
+ if (tracker && onProgress) {
206
+ onProgress(tracker.update(buffer.length));
207
+ }
208
+ }
209
+ else if (chunkIndex > 0) {
210
+ // Mark last yielded chunk - need to re-yield with isLast=true
211
+ // This is handled by the processor setting isLast flag
212
+ }
213
+ }
214
+ /**
215
+ * Decrypt multi-recipient stream
216
+ */
217
+ async *decryptStreamMultiple(source, recipientId, privateKey, options = {}) {
218
+ if (!recipientId || recipientId.length !== 32) {
219
+ throw new Error('Invalid recipient ID: must be 32 bytes');
220
+ }
221
+ if (!privateKey || privateKey.length !== 32) {
222
+ throw new Error('Invalid private key: must be 32 bytes');
223
+ }
224
+ const signal = options.signal;
225
+ const onProgress = options.onProgress;
226
+ let expectedIndex = 0;
227
+ let tracker;
228
+ if (onProgress) {
229
+ tracker = new progress_tracker_1.ProgressTracker();
230
+ }
231
+ for await (const chunkData of source) {
232
+ if (signal?.aborted) {
233
+ throw new DOMException('Decryption cancelled', 'AbortError');
234
+ }
235
+ const { data, header } = await this.multiRecipientProcessor.decryptChunk(chunkData, recipientId, privateKey);
236
+ if (header.chunkIndex !== expectedIndex) {
237
+ throw new Error(`Chunk sequence error: expected ${expectedIndex}, got ${header.chunkIndex}`);
238
+ }
239
+ expectedIndex++;
240
+ yield data;
241
+ if (tracker && onProgress) {
242
+ onProgress(tracker.update(data.length));
243
+ }
244
+ const isLast = (header.flags & 0x01) !== 0;
245
+ if (isLast) {
246
+ break;
247
+ }
248
+ }
249
+ }
250
+ /**
251
+ * Decrypt data stream
252
+ */
253
+ async *decryptStream(source, privateKey, options = {}) {
254
+ // Validate private key
255
+ if (!privateKey || privateKey.length !== 32) {
256
+ throw new Error('Invalid private key: must be 32 bytes');
257
+ }
258
+ const signal = options.signal;
259
+ const onProgress = options.onProgress;
260
+ let expectedIndex = 0;
261
+ let tracker;
262
+ if (onProgress) {
263
+ tracker = new progress_tracker_1.ProgressTracker();
264
+ }
265
+ for await (const chunkData of source) {
266
+ // Check for cancellation
267
+ if (signal?.aborted) {
268
+ throw new DOMException('Decryption cancelled', 'AbortError');
269
+ }
270
+ const { data, header } = await this.processor.decryptChunk(chunkData, privateKey);
271
+ // Validate sequence
272
+ if (header.index !== expectedIndex) {
273
+ throw new Error(`Chunk sequence error: expected ${expectedIndex}, got ${header.index}`);
274
+ }
275
+ expectedIndex++;
276
+ yield data;
277
+ // Report progress
278
+ if (tracker && onProgress) {
279
+ onProgress(tracker.update(data.length));
280
+ }
281
+ // Check if this was the last chunk
282
+ const isLast = (header.flags & 0x01) !== 0;
283
+ if (isLast) {
284
+ break;
285
+ }
286
+ }
287
+ }
288
+ }
289
+ exports.EncryptionStream = EncryptionStream;
290
+ //# sourceMappingURL=encryption-stream.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"encryption-stream.js","sourceRoot":"","sources":["../../../../../packages/digitaldefiance-ecies-lib/src/services/encryption-stream.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,25 @@
1
+ import { ECIESService } from './ecies/service';
2
+ import { IMultiRecipientChunk, IMultiRecipientChunkHeader } from '../interfaces/multi-recipient-chunk';
3
+ /**
4
+ * Processes multi-recipient chunks using symmetric encryption
5
+ */
6
+ export declare class MultiRecipientProcessor {
7
+ private readonly ecies;
8
+ constructor(ecies: ECIESService);
9
+ /**
10
+ * Encrypt chunk for multiple recipients
11
+ */
12
+ encryptChunk(data: Uint8Array, recipients: Array<{
13
+ id: Uint8Array;
14
+ publicKey: Uint8Array;
15
+ }>, chunkIndex: number, isLast: boolean, symmetricKey: Uint8Array): Promise<IMultiRecipientChunk>;
16
+ /**
17
+ * Decrypt chunk for specific recipient
18
+ */
19
+ decryptChunk(chunkData: Uint8Array, recipientId: Uint8Array, privateKey: Uint8Array): Promise<{
20
+ data: Uint8Array;
21
+ header: IMultiRecipientChunkHeader;
22
+ }>;
23
+ private arraysEqual;
24
+ }
25
+ //# sourceMappingURL=multi-recipient-processor.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"multi-recipient-processor.d.ts","sourceRoot":"","sources":["../../../../../packages/digitaldefiance-ecies-lib/src/services/multi-recipient-processor.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AAC/C,OAAO,EACL,oBAAoB,EACpB,0BAA0B,EAG3B,MAAM,qCAAqC,CAAC;AAG7C;;GAEG;AACH,qBAAa,uBAAuB;IACtB,OAAO,CAAC,QAAQ,CAAC,KAAK;gBAAL,KAAK,EAAE,YAAY;IAEhD;;OAEG;IACG,YAAY,CAChB,IAAI,EAAE,UAAU,EAChB,UAAU,EAAE,KAAK,CAAC;QAAE,EAAE,EAAE,UAAU,CAAC;QAAC,SAAS,EAAE,UAAU,CAAA;KAAE,CAAC,EAC5D,UAAU,EAAE,MAAM,EAClB,MAAM,EAAE,OAAO,EACf,YAAY,EAAE,UAAU,GACvB,OAAO,CAAC,oBAAoB,CAAC;IA6HhC;;OAEG;IACG,YAAY,CAChB,SAAS,EAAE,UAAU,EACrB,WAAW,EAAE,UAAU,EACvB,UAAU,EAAE,UAAU,GACrB,OAAO,CAAC;QAAE,IAAI,EAAE,UAAU,CAAC;QAAC,MAAM,EAAE,0BAA0B,CAAA;KAAE,CAAC;IAuHpE,OAAO,CAAC,WAAW;CAUpB"}
@@ -0,0 +1,234 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.MultiRecipientProcessor = void 0;
4
+ const multi_recipient_chunk_1 = require("../interfaces/multi-recipient-chunk");
5
+ const crypto_1 = require("crypto");
6
+ /**
7
+ * Processes multi-recipient chunks using symmetric encryption
8
+ */
9
+ class MultiRecipientProcessor {
10
+ ecies;
11
+ constructor(ecies) {
12
+ this.ecies = ecies;
13
+ }
14
+ /**
15
+ * Encrypt chunk for multiple recipients
16
+ */
17
+ async encryptChunk(data, recipients, chunkIndex, isLast, symmetricKey) {
18
+ // Validate inputs
19
+ if (recipients.length === 0 || recipients.length > multi_recipient_chunk_1.MULTI_RECIPIENT_CONSTANTS.MAX_RECIPIENTS) {
20
+ throw new Error(`Invalid recipient count: ${recipients.length}`);
21
+ }
22
+ if (symmetricKey.length !== 32) {
23
+ throw new Error('Symmetric key must be 32 bytes');
24
+ }
25
+ if (chunkIndex < 0 || chunkIndex > 0xFFFFFFFF) {
26
+ throw new Error(`Invalid chunk index: ${chunkIndex}`);
27
+ }
28
+ if (data.length > 0x7FFFFFFF) {
29
+ throw new Error(`Data size exceeds maximum: ${data.length}`);
30
+ }
31
+ // Check for duplicate recipient IDs
32
+ const seenIds = new Set();
33
+ for (const recipient of recipients) {
34
+ const idStr = Buffer.from(recipient.id).toString('hex');
35
+ if (seenIds.has(idStr)) {
36
+ throw new Error('Duplicate recipient ID detected');
37
+ }
38
+ seenIds.add(idStr);
39
+ }
40
+ // Encrypt data with AES-256-GCM
41
+ const iv = (0, crypto_1.randomBytes)(12);
42
+ const cipher = (0, crypto_1.createCipheriv)('aes-256-gcm', symmetricKey, iv);
43
+ const encrypted = Buffer.concat([cipher.update(data), cipher.final()]);
44
+ const authTag = cipher.getAuthTag();
45
+ // Build recipient headers
46
+ const recipientHeaders = [];
47
+ for (const recipient of recipients) {
48
+ if (recipient.id.length !== multi_recipient_chunk_1.MULTI_RECIPIENT_CONSTANTS.RECIPIENT_ID_SIZE) {
49
+ throw new Error('Recipient ID must be 32 bytes');
50
+ }
51
+ const encryptedKey = await this.ecies.encryptSimpleOrSingle(false, recipient.publicKey, symmetricKey);
52
+ recipientHeaders.push({
53
+ id: recipient.id,
54
+ keySize: encryptedKey.length,
55
+ encryptedKey,
56
+ });
57
+ }
58
+ // Calculate sizes with overflow check
59
+ let recipientHeadersSize = 0;
60
+ for (const h of recipientHeaders) {
61
+ const headerSize = multi_recipient_chunk_1.MULTI_RECIPIENT_CONSTANTS.RECIPIENT_ID_SIZE +
62
+ multi_recipient_chunk_1.MULTI_RECIPIENT_CONSTANTS.KEY_SIZE_BYTES + h.keySize;
63
+ if (recipientHeadersSize + headerSize < recipientHeadersSize) {
64
+ throw new Error('Recipient headers size overflow');
65
+ }
66
+ recipientHeadersSize += headerSize;
67
+ }
68
+ const totalSize = multi_recipient_chunk_1.MULTI_RECIPIENT_CONSTANTS.HEADER_SIZE +
69
+ recipientHeadersSize +
70
+ 12 + // IV
71
+ encrypted.length +
72
+ 16; // Auth tag
73
+ // Check for integer overflow (max safe: 2^31 - 1 for Uint8Array)
74
+ if (totalSize > 0x7FFFFFFF || totalSize < 0) {
75
+ throw new Error('Chunk size overflow: too many recipients or data too large');
76
+ }
77
+ // Build chunk
78
+ const chunk = new Uint8Array(totalSize);
79
+ const view = new DataView(chunk.buffer);
80
+ let offset = 0;
81
+ // Write header
82
+ view.setUint32(offset, multi_recipient_chunk_1.MULTI_RECIPIENT_CONSTANTS.MAGIC, false);
83
+ offset += 4;
84
+ view.setUint16(offset, multi_recipient_chunk_1.MULTI_RECIPIENT_CONSTANTS.VERSION, false);
85
+ offset += 2;
86
+ view.setUint16(offset, recipients.length, false);
87
+ offset += 2;
88
+ view.setUint32(offset, chunkIndex, false);
89
+ offset += 4;
90
+ view.setUint32(offset, data.length, false);
91
+ offset += 4;
92
+ view.setUint32(offset, encrypted.length, false);
93
+ offset += 4;
94
+ view.setUint8(offset, isLast ? multi_recipient_chunk_1.MULTI_RECIPIENT_CONSTANTS.FLAG_IS_LAST : 0);
95
+ offset += 1;
96
+ // Padding to 32 bytes
97
+ offset = multi_recipient_chunk_1.MULTI_RECIPIENT_CONSTANTS.HEADER_SIZE;
98
+ // Write recipient headers
99
+ for (const header of recipientHeaders) {
100
+ chunk.set(header.id, offset);
101
+ offset += multi_recipient_chunk_1.MULTI_RECIPIENT_CONSTANTS.RECIPIENT_ID_SIZE;
102
+ view.setUint16(offset, header.keySize, false);
103
+ offset += multi_recipient_chunk_1.MULTI_RECIPIENT_CONSTANTS.KEY_SIZE_BYTES;
104
+ chunk.set(header.encryptedKey, offset);
105
+ offset += header.keySize;
106
+ }
107
+ // Write IV
108
+ chunk.set(iv, offset);
109
+ offset += 12;
110
+ // Write encrypted data
111
+ chunk.set(encrypted, offset);
112
+ offset += encrypted.length;
113
+ // Write auth tag
114
+ chunk.set(authTag, offset);
115
+ return {
116
+ index: chunkIndex,
117
+ data: chunk,
118
+ isLast,
119
+ recipientCount: recipients.length,
120
+ };
121
+ }
122
+ /**
123
+ * Decrypt chunk for specific recipient
124
+ */
125
+ async decryptChunk(chunkData, recipientId, privateKey) {
126
+ if (chunkData.length < multi_recipient_chunk_1.MULTI_RECIPIENT_CONSTANTS.HEADER_SIZE) {
127
+ throw new Error('Chunk too small');
128
+ }
129
+ const view = new DataView(chunkData.buffer, chunkData.byteOffset);
130
+ let offset = 0;
131
+ // Parse header
132
+ const magic = view.getUint32(offset, false);
133
+ offset += 4;
134
+ if (magic !== multi_recipient_chunk_1.MULTI_RECIPIENT_CONSTANTS.MAGIC) {
135
+ throw new Error('Invalid multi-recipient chunk magic');
136
+ }
137
+ const version = view.getUint16(offset, false);
138
+ offset += 2;
139
+ if (version !== multi_recipient_chunk_1.MULTI_RECIPIENT_CONSTANTS.VERSION) {
140
+ throw new Error(`Unsupported version: ${version}`);
141
+ }
142
+ const recipientCount = view.getUint16(offset, false);
143
+ offset += 2;
144
+ if (recipientCount === 0 || recipientCount > multi_recipient_chunk_1.MULTI_RECIPIENT_CONSTANTS.MAX_RECIPIENTS) {
145
+ throw new Error(`Invalid recipient count: ${recipientCount}`);
146
+ }
147
+ const chunkIndex = view.getUint32(offset, false);
148
+ offset += 4;
149
+ const originalSize = view.getUint32(offset, false);
150
+ offset += 4;
151
+ const encryptedSize = view.getUint32(offset, false);
152
+ offset += 4;
153
+ const flags = view.getUint8(offset);
154
+ offset = multi_recipient_chunk_1.MULTI_RECIPIENT_CONSTANTS.HEADER_SIZE;
155
+ // Validate encryptedSize against chunk size
156
+ const minChunkSize = multi_recipient_chunk_1.MULTI_RECIPIENT_CONSTANTS.HEADER_SIZE + 12 + encryptedSize + 16;
157
+ if (chunkData.length < minChunkSize) {
158
+ throw new Error('Chunk too small for declared encrypted size');
159
+ }
160
+ // Find recipient header and decrypt symmetric key
161
+ let symmetricKey = null;
162
+ let tempOffset = offset;
163
+ for (let i = 0; i < recipientCount; i++) {
164
+ // Check if we have enough data for recipient ID
165
+ if (tempOffset + multi_recipient_chunk_1.MULTI_RECIPIENT_CONSTANTS.RECIPIENT_ID_SIZE > chunkData.length) {
166
+ throw new Error('Chunk truncated: not enough data for recipient ID');
167
+ }
168
+ const id = chunkData.slice(tempOffset, tempOffset + multi_recipient_chunk_1.MULTI_RECIPIENT_CONSTANTS.RECIPIENT_ID_SIZE);
169
+ tempOffset += multi_recipient_chunk_1.MULTI_RECIPIENT_CONSTANTS.RECIPIENT_ID_SIZE;
170
+ // Check if we have enough data for keySize field
171
+ if (tempOffset + multi_recipient_chunk_1.MULTI_RECIPIENT_CONSTANTS.KEY_SIZE_BYTES > chunkData.length) {
172
+ throw new Error('Chunk truncated: not enough data for key size');
173
+ }
174
+ const keySize = view.getUint16(tempOffset, false);
175
+ tempOffset += multi_recipient_chunk_1.MULTI_RECIPIENT_CONSTANTS.KEY_SIZE_BYTES;
176
+ // Validate keySize (typical ECIES: 100-400 bytes)
177
+ if (keySize === 0 || keySize > 1000) {
178
+ throw new Error(`Invalid key size: ${keySize}`);
179
+ }
180
+ // Check if we have enough data for the encrypted key
181
+ if (tempOffset + keySize > chunkData.length) {
182
+ throw new Error('Chunk truncated: not enough data for encrypted key');
183
+ }
184
+ const encryptedKey = chunkData.slice(tempOffset, tempOffset + keySize);
185
+ tempOffset += keySize;
186
+ // Check if this is our recipient
187
+ if (this.arraysEqual(id, recipientId)) {
188
+ symmetricKey = await this.ecies.decryptSimpleOrSingleWithHeader(false, privateKey, encryptedKey);
189
+ // Don't break - need to skip all recipient headers
190
+ }
191
+ }
192
+ if (!symmetricKey) {
193
+ throw new Error('Recipient not found in chunk');
194
+ }
195
+ // Update offset to after all recipient headers
196
+ offset = tempOffset;
197
+ // Read IV
198
+ const iv = chunkData.slice(offset, offset + 12);
199
+ offset += 12;
200
+ // Read encrypted data
201
+ const encrypted = chunkData.slice(offset, offset + encryptedSize);
202
+ offset += encryptedSize;
203
+ // Read auth tag
204
+ const authTag = chunkData.slice(offset, offset + 16);
205
+ // Decrypt
206
+ const decipher = (0, crypto_1.createDecipheriv)('aes-256-gcm', symmetricKey, iv);
207
+ decipher.setAuthTag(authTag);
208
+ const decrypted = Buffer.concat([decipher.update(encrypted), decipher.final()]);
209
+ return {
210
+ data: new Uint8Array(decrypted),
211
+ header: {
212
+ magic,
213
+ version,
214
+ recipientCount,
215
+ chunkIndex,
216
+ originalSize,
217
+ encryptedSize,
218
+ flags,
219
+ },
220
+ };
221
+ }
222
+ arraysEqual(a, b) {
223
+ if (a.length !== b.length)
224
+ return false;
225
+ // Constant-time comparison to prevent timing attacks
226
+ let diff = 0;
227
+ for (let i = 0; i < a.length; i++) {
228
+ diff |= a[i] ^ b[i];
229
+ }
230
+ return diff === 0;
231
+ }
232
+ }
233
+ exports.MultiRecipientProcessor = MultiRecipientProcessor;
234
+ //# sourceMappingURL=multi-recipient-processor.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"multi-recipient-processor.js","sourceRoot":"","sources":["../../../../../packages/digitaldefiance-ecies-lib/src/services/multi-recipient-processor.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,23 @@
1
+ import { IStreamProgress } from '../interfaces/stream-progress';
2
+ /**
3
+ * Tracks progress for streaming operations
4
+ */
5
+ export declare class ProgressTracker {
6
+ private readonly totalBytes?;
7
+ private startTime;
8
+ private lastUpdateTime;
9
+ private bytesProcessed;
10
+ private chunksProcessed;
11
+ private recentThroughputs;
12
+ private readonly maxThroughputSamples;
13
+ constructor(totalBytes?: number | undefined);
14
+ /**
15
+ * Update progress with new chunk
16
+ */
17
+ update(chunkBytes: number): IStreamProgress;
18
+ /**
19
+ * Get current progress without update
20
+ */
21
+ getProgress(): IStreamProgress;
22
+ }
23
+ //# sourceMappingURL=progress-tracker.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"progress-tracker.d.ts","sourceRoot":"","sources":["../../../../../packages/digitaldefiance-ecies-lib/src/services/progress-tracker.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,+BAA+B,CAAC;AAEhE;;GAEG;AACH,qBAAa,eAAe;IAQd,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAC;IAPxC,OAAO,CAAC,SAAS,CAAS;IAC1B,OAAO,CAAC,cAAc,CAAS;IAC/B,OAAO,CAAC,cAAc,CAAa;IACnC,OAAO,CAAC,eAAe,CAAa;IACpC,OAAO,CAAC,iBAAiB,CAAgB;IACzC,OAAO,CAAC,QAAQ,CAAC,oBAAoB,CAAK;gBAEb,UAAU,CAAC,EAAE,MAAM,YAAA;IAKhD;;OAEG;IACH,MAAM,CAAC,UAAU,EAAE,MAAM,GAAG,eAAe;IAsD3C;;OAEG;IACH,WAAW,IAAI,eAAe;CAyB/B"}