@zkim-platform/file-format 1.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.
- package/CHANGELOG.md +72 -0
- package/LICENSE +22 -0
- package/README.md +695 -0
- package/dist/index.cjs +12170 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +1918 -0
- package/dist/index.d.ts +1918 -0
- package/dist/index.js +12126 -0
- package/dist/index.js.map +1 -0
- package/package.json +78 -0
package/README.md
ADDED
|
@@ -0,0 +1,695 @@
|
|
|
1
|
+
# @zkim/file-format
|
|
2
|
+
|
|
3
|
+

|
|
4
|
+

|
|
5
|
+

|
|
6
|
+

|
|
7
|
+

|
|
8
|
+

|
|
9
|
+

|
|
10
|
+
|
|
11
|
+
Secure, encrypted file format with three-layer encryption, integrity validation, and privacy-preserving search capabilities.
|
|
12
|
+
|
|
13
|
+
## 📊 Project Status
|
|
14
|
+
|
|
15
|
+
- **Version:** 1.0.0
|
|
16
|
+
- **Tests:** 1,307 passing (99.8% pass rate)
|
|
17
|
+
- **Coverage:** 92.09% statements, 82.15% branches, 95.83% functions
|
|
18
|
+
- **Build:** ✅ Passing
|
|
19
|
+
- **License:** MIT
|
|
20
|
+
- **Status:** Production Ready
|
|
21
|
+
|
|
22
|
+
## Features
|
|
23
|
+
|
|
24
|
+
- 🔐 **Three-Layer Encryption**: XChaCha20-Poly1305 encryption with platform, user, and content layers
|
|
25
|
+
- 🔍 **Privacy-Preserving Search**: Searchable encryption with OPRF-based trapdoors and rotation
|
|
26
|
+
- ✅ **Integrity Validation**: BLAKE3-based integrity checks and Ed25519 signatures
|
|
27
|
+
- 📦 **Compression Support**: Optional GZIP/Brotli compression for efficient storage
|
|
28
|
+
- 🛡️ **Error Recovery**: Advanced error detection and recovery mechanisms
|
|
29
|
+
- ⚡ **Performance Monitoring**: Built-in performance tracking and optimization
|
|
30
|
+
- 🔒 **Constant-Time Security**: Timing attack prevention for cryptographic operations
|
|
31
|
+
- 🌐 **Cross-Platform**: Works in both browser and Node.js environments
|
|
32
|
+
|
|
33
|
+
## Installation
|
|
34
|
+
|
|
35
|
+
```bash
|
|
36
|
+
npm install @zkim/file-format
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
### Requirements
|
|
40
|
+
|
|
41
|
+
- Node.js 18+ (for Node.js environments)
|
|
42
|
+
- Modern browser with TypedArray and ES2020+ support (for browser environments)
|
|
43
|
+
- TypeScript 5.0+ (recommended for type safety)
|
|
44
|
+
|
|
45
|
+
### Dependencies
|
|
46
|
+
|
|
47
|
+
This package includes the following dependencies (automatically installed):
|
|
48
|
+
|
|
49
|
+
- `@noble/curves` - Ristretto255 operations for searchable encryption
|
|
50
|
+
- `@noble/hashes` - BLAKE3 hashing (standard ZKIM hash algorithm)
|
|
51
|
+
- `libsodium-wrappers-sumo` - Cryptographic operations (encryption, decryption, key generation)
|
|
52
|
+
|
|
53
|
+
These are bundled with the package and do not need to be installed separately.
|
|
54
|
+
|
|
55
|
+
## Quick Start
|
|
56
|
+
|
|
57
|
+
### Basic Usage
|
|
58
|
+
|
|
59
|
+
```typescript
|
|
60
|
+
import { ZKIMFileService, InMemoryStorage, defaultLogger } from "@zkim/file-format";
|
|
61
|
+
import sodium from "libsodium-wrappers-sumo";
|
|
62
|
+
|
|
63
|
+
async function main() {
|
|
64
|
+
// Wait for libsodium to be ready
|
|
65
|
+
await sodium.ready;
|
|
66
|
+
|
|
67
|
+
// Generate encryption keys
|
|
68
|
+
const platformKey = sodium.randombytes_buf(32);
|
|
69
|
+
const userKey = sodium.randombytes_buf(32);
|
|
70
|
+
const userId = "example-user";
|
|
71
|
+
|
|
72
|
+
// Create storage backend (optional - in-memory for this example)
|
|
73
|
+
const storage = new InMemoryStorage();
|
|
74
|
+
|
|
75
|
+
// Initialize the file service
|
|
76
|
+
const fileService = new ZKIMFileService(
|
|
77
|
+
{
|
|
78
|
+
enableCompression: true,
|
|
79
|
+
enableSearchableEncryption: false,
|
|
80
|
+
enableIntegrityValidation: true,
|
|
81
|
+
},
|
|
82
|
+
defaultLogger,
|
|
83
|
+
storage
|
|
84
|
+
);
|
|
85
|
+
|
|
86
|
+
await fileService.initialize();
|
|
87
|
+
|
|
88
|
+
// Create some test data
|
|
89
|
+
const testData = new TextEncoder().encode("Hello, ZKIM File Format!");
|
|
90
|
+
|
|
91
|
+
// Create an encrypted ZKIM file
|
|
92
|
+
const result = await fileService.createZkimFile(
|
|
93
|
+
testData,
|
|
94
|
+
userId,
|
|
95
|
+
platformKey,
|
|
96
|
+
userKey,
|
|
97
|
+
{
|
|
98
|
+
fileName: "example.txt",
|
|
99
|
+
mimeType: "text/plain",
|
|
100
|
+
}
|
|
101
|
+
);
|
|
102
|
+
|
|
103
|
+
if (!result.success || !result.file) {
|
|
104
|
+
throw new Error("Failed to create file");
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
// File created successfully
|
|
108
|
+
const fileId = result.file.header.fileId;
|
|
109
|
+
|
|
110
|
+
// Retrieve the file
|
|
111
|
+
const retrievedResult = await fileService.getZkimFile(
|
|
112
|
+
result.objectId ?? result.file.header.fileId
|
|
113
|
+
);
|
|
114
|
+
|
|
115
|
+
if (!retrievedResult.success || !retrievedResult.data) {
|
|
116
|
+
throw new Error(`Failed to retrieve file: ${retrievedResult.error}`);
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
// Decrypt the file
|
|
120
|
+
const decryptedData = await fileService.decryptZkimFile(
|
|
121
|
+
retrievedResult.data,
|
|
122
|
+
userId,
|
|
123
|
+
userKey
|
|
124
|
+
);
|
|
125
|
+
|
|
126
|
+
const decryptedText = new TextDecoder().decode(decryptedData);
|
|
127
|
+
// File decrypted successfully
|
|
128
|
+
|
|
129
|
+
// Cleanup
|
|
130
|
+
await fileService.cleanup();
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
main().catch((error) => {
|
|
134
|
+
// Handle error appropriately
|
|
135
|
+
throw error;
|
|
136
|
+
});
|
|
137
|
+
```
|
|
138
|
+
|
|
139
|
+
## API Reference
|
|
140
|
+
|
|
141
|
+
### Core Services
|
|
142
|
+
|
|
143
|
+
#### `ZKIMFileService`
|
|
144
|
+
|
|
145
|
+
Main service for creating, managing, and operating on ZKIM files.
|
|
146
|
+
|
|
147
|
+
```typescript
|
|
148
|
+
import { ZKIMFileService } from "@zkim/file-format";
|
|
149
|
+
|
|
150
|
+
const fileService = new ZKIMFileService(config?, logger?, storage?);
|
|
151
|
+
await fileService.initialize();
|
|
152
|
+
|
|
153
|
+
// Create a file
|
|
154
|
+
const result = await fileService.createZkimFile(
|
|
155
|
+
content: Uint8Array,
|
|
156
|
+
userId: string,
|
|
157
|
+
platformKey: Uint8Array,
|
|
158
|
+
userKey: Uint8Array,
|
|
159
|
+
metadata?: ZkimFileMetadata
|
|
160
|
+
);
|
|
161
|
+
|
|
162
|
+
// Retrieve a file
|
|
163
|
+
const file = await fileService.getZkimFile(objectId: string);
|
|
164
|
+
|
|
165
|
+
// Decrypt a file
|
|
166
|
+
const decrypted = await fileService.decryptZkimFile(
|
|
167
|
+
file: ZkimFile,
|
|
168
|
+
userId: string,
|
|
169
|
+
userKey: Uint8Array
|
|
170
|
+
);
|
|
171
|
+
```
|
|
172
|
+
|
|
173
|
+
#### `ZkimEncryption`
|
|
174
|
+
|
|
175
|
+
Three-layer encryption service for encrypting and decrypting data.
|
|
176
|
+
|
|
177
|
+
```typescript
|
|
178
|
+
import { ZkimEncryption } from "@zkim/file-format";
|
|
179
|
+
|
|
180
|
+
const encryption = new ZkimEncryption(config?, logger?);
|
|
181
|
+
await encryption.initialize();
|
|
182
|
+
|
|
183
|
+
// Encrypt data
|
|
184
|
+
const encrypted = await encryption.encryptData(
|
|
185
|
+
data: Uint8Array,
|
|
186
|
+
platformKey: Uint8Array,
|
|
187
|
+
userKey: Uint8Array,
|
|
188
|
+
fileId: string,
|
|
189
|
+
metadata?: Record<string, unknown>
|
|
190
|
+
);
|
|
191
|
+
|
|
192
|
+
// Decrypt data
|
|
193
|
+
const decrypted = await encryption.decrypt(
|
|
194
|
+
encryptedData: Uint8Array,
|
|
195
|
+
key: Uint8Array,
|
|
196
|
+
nonce: Uint8Array
|
|
197
|
+
);
|
|
198
|
+
```
|
|
199
|
+
|
|
200
|
+
#### `ZkimIntegrity`
|
|
201
|
+
|
|
202
|
+
Integrity validation service for validating file integrity and detecting tampering.
|
|
203
|
+
|
|
204
|
+
```typescript
|
|
205
|
+
import { ZkimIntegrity } from "@zkim/file-format";
|
|
206
|
+
|
|
207
|
+
const integrity = new ZkimIntegrity(config?, logger?);
|
|
208
|
+
await integrity.initialize();
|
|
209
|
+
|
|
210
|
+
// Validate file
|
|
211
|
+
const result = await integrity.validateFile(
|
|
212
|
+
file: ZkimFile,
|
|
213
|
+
platformKey?: Uint8Array,
|
|
214
|
+
userKey?: Uint8Array
|
|
215
|
+
);
|
|
216
|
+
|
|
217
|
+
// Detect tampering
|
|
218
|
+
const tampering = await integrity.detectTampering(file: ZkimFile);
|
|
219
|
+
```
|
|
220
|
+
|
|
221
|
+
#### `SearchableEncryption`
|
|
222
|
+
|
|
223
|
+
Privacy-preserving search service using OPRF-based trapdoors.
|
|
224
|
+
|
|
225
|
+
```typescript
|
|
226
|
+
import { SearchableEncryption } from "@zkim/file-format";
|
|
227
|
+
|
|
228
|
+
const search = new SearchableEncryption(config?, logger?);
|
|
229
|
+
await search.initialize();
|
|
230
|
+
|
|
231
|
+
// Index a file
|
|
232
|
+
await search.indexFile(file: ZkimFile, keywords: string[]);
|
|
233
|
+
|
|
234
|
+
// Search for files
|
|
235
|
+
const results = await search.search(
|
|
236
|
+
query: string,
|
|
237
|
+
limit?: number
|
|
238
|
+
);
|
|
239
|
+
```
|
|
240
|
+
|
|
241
|
+
### Configuration Options
|
|
242
|
+
|
|
243
|
+
#### `ZKIMFileServiceConfig`
|
|
244
|
+
|
|
245
|
+
```typescript
|
|
246
|
+
interface ZKIMFileServiceConfig {
|
|
247
|
+
enableCompression?: boolean; // Enable compression (default: true)
|
|
248
|
+
enableDeduplication?: boolean; // Enable deduplication (default: true)
|
|
249
|
+
chunkSize?: number; // Chunk size in bytes (default: 512KB)
|
|
250
|
+
compressionLevel?: number; // Compression level 1-9 (default: 6)
|
|
251
|
+
compressionAlgorithm?: "brotli" | "gzip"; // Compression algorithm (default: "gzip")
|
|
252
|
+
enableSearchableEncryption?: boolean; // Enable searchable encryption (default: true)
|
|
253
|
+
enableIntegrityValidation?: boolean; // Enable integrity validation (default: true)
|
|
254
|
+
enableMetadataIndexing?: boolean; // Enable metadata indexing (default: true)
|
|
255
|
+
maxFileSize?: number; // Maximum file size in bytes (default: 10GB)
|
|
256
|
+
enableStreaming?: boolean; // Enable streaming (default: true)
|
|
257
|
+
}
|
|
258
|
+
```
|
|
259
|
+
|
|
260
|
+
#### `ZkimEncryptionConfig`
|
|
261
|
+
|
|
262
|
+
```typescript
|
|
263
|
+
interface ZkimEncryptionConfig {
|
|
264
|
+
enableThreeLayerEncryption?: boolean; // Enable three-layer encryption (default: true)
|
|
265
|
+
enableKeyRotation?: boolean; // Enable key rotation (default: true)
|
|
266
|
+
enablePerfectForwardSecrecy?: boolean; // Enable PFS (default: true)
|
|
267
|
+
enableCompromiseDetection?: boolean; // Enable compromise detection (default: true)
|
|
268
|
+
defaultAlgorithm?: string; // Default encryption algorithm (default: "xchacha20-poly1305")
|
|
269
|
+
keySize?: number; // Key size in bytes (default: 32)
|
|
270
|
+
nonceSize?: number; // Nonce size in bytes (default: 24)
|
|
271
|
+
compressionEnabled?: boolean; // Enable compression (default: true)
|
|
272
|
+
compressionAlgorithm?: "gzip" | "brotli"; // Compression algorithm (default: "gzip")
|
|
273
|
+
compressionLevel?: number; // Compression level 1-9 (default: 6)
|
|
274
|
+
}
|
|
275
|
+
```
|
|
276
|
+
|
|
277
|
+
#### `ZkimIntegrityConfig`
|
|
278
|
+
|
|
279
|
+
```typescript
|
|
280
|
+
interface ZkimIntegrityConfig {
|
|
281
|
+
enableHeaderValidation?: boolean; // Enable header validation (default: true)
|
|
282
|
+
enableChunkValidation?: boolean; // Enable chunk validation (default: true)
|
|
283
|
+
enableSignatureValidation?: boolean; // Enable signature validation (default: true)
|
|
284
|
+
enableMetadataValidation?: boolean; // Enable metadata validation (default: true)
|
|
285
|
+
enableTamperDetection?: boolean; // Enable tamper detection (default: true)
|
|
286
|
+
validationThreshold?: number; // Validation threshold 0-1 (default: 0.95)
|
|
287
|
+
enableAuditLogging?: boolean; // Enable audit logging (default: true)
|
|
288
|
+
enablePerformanceMetrics?: boolean; // Enable performance metrics (default: true)
|
|
289
|
+
hashAlgorithm?: string; // Hash algorithm (default: "blake3")
|
|
290
|
+
signatureAlgorithm?: string; // Signature algorithm (default: "ed25519")
|
|
291
|
+
}
|
|
292
|
+
```
|
|
293
|
+
|
|
294
|
+
### Storage Backends
|
|
295
|
+
|
|
296
|
+
#### `InMemoryStorage`
|
|
297
|
+
|
|
298
|
+
In-memory storage backend for testing and temporary storage.
|
|
299
|
+
|
|
300
|
+
```typescript
|
|
301
|
+
import { InMemoryStorage } from "@zkim/file-format";
|
|
302
|
+
|
|
303
|
+
const storage = new InMemoryStorage();
|
|
304
|
+
const fileService = new ZKIMFileService(config, logger, storage);
|
|
305
|
+
```
|
|
306
|
+
|
|
307
|
+
#### `LocalStorageBackend`
|
|
308
|
+
|
|
309
|
+
Browser localStorage-based storage backend.
|
|
310
|
+
|
|
311
|
+
```typescript
|
|
312
|
+
import { LocalStorageBackend } from "@zkim/file-format";
|
|
313
|
+
|
|
314
|
+
const storage = new LocalStorageBackend();
|
|
315
|
+
const fileService = new ZKIMFileService(config, logger, storage);
|
|
316
|
+
```
|
|
317
|
+
|
|
318
|
+
#### Custom Storage Backend
|
|
319
|
+
|
|
320
|
+
Implement the `IStorageBackend` interface for custom storage:
|
|
321
|
+
|
|
322
|
+
```typescript
|
|
323
|
+
import { IStorageBackend } from "@zkim/file-format";
|
|
324
|
+
|
|
325
|
+
class CustomStorage implements IStorageBackend {
|
|
326
|
+
async get(key: string): Promise<Uint8Array | null> {
|
|
327
|
+
// Implement retrieval logic
|
|
328
|
+
}
|
|
329
|
+
|
|
330
|
+
async set(key: string, value: Uint8Array): Promise<void> {
|
|
331
|
+
// Implement storage logic
|
|
332
|
+
}
|
|
333
|
+
|
|
334
|
+
async delete(key: string): Promise<void> {
|
|
335
|
+
// Implement deletion logic
|
|
336
|
+
}
|
|
337
|
+
|
|
338
|
+
async list(): Promise<string[]> {
|
|
339
|
+
// Implement listing logic
|
|
340
|
+
}
|
|
341
|
+
}
|
|
342
|
+
```
|
|
343
|
+
|
|
344
|
+
### Utilities
|
|
345
|
+
|
|
346
|
+
#### Crypto Utilities
|
|
347
|
+
|
|
348
|
+
```typescript
|
|
349
|
+
import {
|
|
350
|
+
generateRandomBytes,
|
|
351
|
+
generateRandomHex,
|
|
352
|
+
hashData,
|
|
353
|
+
hashDataToHex,
|
|
354
|
+
generateKeyPair,
|
|
355
|
+
generateSigningKeyPair,
|
|
356
|
+
encryptData,
|
|
357
|
+
decryptData,
|
|
358
|
+
toBase64,
|
|
359
|
+
fromBase64,
|
|
360
|
+
toHex,
|
|
361
|
+
fromHex,
|
|
362
|
+
} from "@zkim/file-format";
|
|
363
|
+
|
|
364
|
+
// Generate random bytes
|
|
365
|
+
const randomBytes = await generateRandomBytes(32);
|
|
366
|
+
|
|
367
|
+
// Hash data
|
|
368
|
+
const hash = hashData(data, 32); // 32-byte hash
|
|
369
|
+
const hashHex = hashDataToHex(data, 32);
|
|
370
|
+
|
|
371
|
+
// Generate key pairs
|
|
372
|
+
const keyPair = await generateKeyPair(); // X25519
|
|
373
|
+
const signingKeyPair = await generateSigningKeyPair(); // Ed25519
|
|
374
|
+
|
|
375
|
+
// Encrypt/decrypt
|
|
376
|
+
const encrypted = await encryptData(data, key, nonce);
|
|
377
|
+
const decrypted = await decryptData(encrypted.ciphertext, key, encrypted.nonce);
|
|
378
|
+
|
|
379
|
+
// Base64 encoding
|
|
380
|
+
const base64 = await toBase64(data);
|
|
381
|
+
const decoded = await fromBase64(base64);
|
|
382
|
+
```
|
|
383
|
+
|
|
384
|
+
#### Compression Utilities
|
|
385
|
+
|
|
386
|
+
```typescript
|
|
387
|
+
import { compressGzip, decompressGzip } from "@zkim/file-format";
|
|
388
|
+
|
|
389
|
+
// Compress data
|
|
390
|
+
const compressed = await compressGzip(data);
|
|
391
|
+
|
|
392
|
+
// Decompress data
|
|
393
|
+
const decompressed = await decompressGzip(compressed);
|
|
394
|
+
```
|
|
395
|
+
|
|
396
|
+
## Examples
|
|
397
|
+
|
|
398
|
+
### Example 1: Basic File Encryption
|
|
399
|
+
|
|
400
|
+
```typescript
|
|
401
|
+
import { ZKIMFileService, InMemoryStorage } from "@zkim/file-format";
|
|
402
|
+
import sodium from "libsodium-wrappers-sumo";
|
|
403
|
+
|
|
404
|
+
await sodium.ready;
|
|
405
|
+
|
|
406
|
+
const platformKey = sodium.randombytes_buf(32);
|
|
407
|
+
const userKey = sodium.randombytes_buf(32);
|
|
408
|
+
const storage = new InMemoryStorage();
|
|
409
|
+
|
|
410
|
+
const fileService = new ZKIMFileService(
|
|
411
|
+
{ enableCompression: true },
|
|
412
|
+
undefined,
|
|
413
|
+
storage
|
|
414
|
+
);
|
|
415
|
+
await fileService.initialize();
|
|
416
|
+
|
|
417
|
+
const content = new TextEncoder().encode("Secret message");
|
|
418
|
+
const result = await fileService.createZkimFile(
|
|
419
|
+
content,
|
|
420
|
+
"user-123",
|
|
421
|
+
platformKey,
|
|
422
|
+
userKey,
|
|
423
|
+
{ fileName: "secret.txt", mimeType: "text/plain" }
|
|
424
|
+
);
|
|
425
|
+
|
|
426
|
+
if (result.success && result.file) {
|
|
427
|
+
// File created successfully
|
|
428
|
+
const fileId = result.file.header.fileId;
|
|
429
|
+
}
|
|
430
|
+
```
|
|
431
|
+
|
|
432
|
+
### Example 2: Integrity Validation
|
|
433
|
+
|
|
434
|
+
```typescript
|
|
435
|
+
import { ZkimIntegrity } from "@zkim/file-format";
|
|
436
|
+
|
|
437
|
+
const integrity = new ZkimIntegrity();
|
|
438
|
+
await integrity.initialize();
|
|
439
|
+
|
|
440
|
+
const validationResult = await integrity.validateFile(
|
|
441
|
+
zkimFile,
|
|
442
|
+
platformKey,
|
|
443
|
+
userKey
|
|
444
|
+
);
|
|
445
|
+
|
|
446
|
+
if (validationResult.isValid) {
|
|
447
|
+
// File is valid
|
|
448
|
+
} else {
|
|
449
|
+
// Handle validation errors
|
|
450
|
+
const errors = validationResult.errors;
|
|
451
|
+
}
|
|
452
|
+
```
|
|
453
|
+
|
|
454
|
+
### Example 3: Searchable Encryption
|
|
455
|
+
|
|
456
|
+
```typescript
|
|
457
|
+
import { SearchableEncryption } from "@zkim/file-format";
|
|
458
|
+
|
|
459
|
+
const search = new SearchableEncryption();
|
|
460
|
+
await search.initialize();
|
|
461
|
+
|
|
462
|
+
// Index a file with keywords
|
|
463
|
+
await search.indexFile(zkimFile, ["document", "important", "2025"]);
|
|
464
|
+
|
|
465
|
+
// Search for files
|
|
466
|
+
const results = await search.search("document", 10);
|
|
467
|
+
// Found results.length files
|
|
468
|
+
```
|
|
469
|
+
|
|
470
|
+
## Security Considerations
|
|
471
|
+
|
|
472
|
+
### Web Crypto API Prohibition
|
|
473
|
+
|
|
474
|
+
**CRITICAL**: This package **PROHIBITS** the use of Web Crypto API (`crypto.subtle`, `crypto.getRandomValues`, `window.crypto`) for security and consistency reasons.
|
|
475
|
+
|
|
476
|
+
**Required patterns:**
|
|
477
|
+
- ✅ Use `libsodium-wrappers-sumo` for all cryptographic operations
|
|
478
|
+
- ✅ Use `@noble/hashes` for BLAKE3 hashing
|
|
479
|
+
- ✅ Use `sodium.randombytes_buf()` for random number generation
|
|
480
|
+
- ✅ Always call `await sodium.ready` before using libsodium functions
|
|
481
|
+
|
|
482
|
+
**Forbidden patterns:**
|
|
483
|
+
- ❌ `crypto.subtle.*` - All Web Crypto API subtle methods
|
|
484
|
+
- ❌ `crypto.getRandomValues()` - Web Crypto API random generation
|
|
485
|
+
- ❌ `window.crypto.*` - Web Crypto API access
|
|
486
|
+
- ❌ `WebCrypto`, `CryptoKey`, `SubtleCrypto` - Web Crypto API types
|
|
487
|
+
|
|
488
|
+
This prohibition is enforced by ESLint and will cause build failures if violated.
|
|
489
|
+
|
|
490
|
+
### Key Management
|
|
491
|
+
|
|
492
|
+
- **Never store keys in plaintext**: Always use secure key storage mechanisms
|
|
493
|
+
- **Use proper key derivation**: Use Argon2id for password-based key derivation
|
|
494
|
+
- **Rotate keys regularly**: Implement key rotation policies
|
|
495
|
+
- **Protect keys in memory**: Clear sensitive data from memory when possible
|
|
496
|
+
|
|
497
|
+
### Best Practices
|
|
498
|
+
|
|
499
|
+
1. **Always validate file integrity** before decryption
|
|
500
|
+
2. **Use constant-time comparisons** for security-sensitive operations
|
|
501
|
+
3. **Enable all security features** in production (integrity validation, signature verification)
|
|
502
|
+
4. **Monitor for tampering** using `detectTampering()`
|
|
503
|
+
5. **Use secure random number generation** for all cryptographic operations
|
|
504
|
+
6. **Implement proper error handling** to avoid information leakage
|
|
505
|
+
|
|
506
|
+
### Cryptographic Algorithms
|
|
507
|
+
|
|
508
|
+
- **Encryption**: XChaCha20-Poly1305 (AEAD) via libsodium
|
|
509
|
+
- **Hashing**: BLAKE3 (256-bit output) via @noble/hashes
|
|
510
|
+
- **Signatures**: Ed25519 via libsodium
|
|
511
|
+
- **Key Exchange**: X25519 via libsodium
|
|
512
|
+
- **Searchable Encryption**: OPRF (Oblivious Pseudorandom Function) via @noble/curves
|
|
513
|
+
- **Random Generation**: libsodium `randombytes_buf()`
|
|
514
|
+
|
|
515
|
+
## Troubleshooting
|
|
516
|
+
|
|
517
|
+
### Common Issues
|
|
518
|
+
|
|
519
|
+
#### "libsodium is not ready"
|
|
520
|
+
|
|
521
|
+
**Solution**: Always wait for `sodium.ready` before using cryptographic functions:
|
|
522
|
+
|
|
523
|
+
```typescript
|
|
524
|
+
import sodium from "libsodium-wrappers-sumo";
|
|
525
|
+
await sodium.ready;
|
|
526
|
+
// Now you can use crypto functions
|
|
527
|
+
```
|
|
528
|
+
|
|
529
|
+
#### "Storage backend not available"
|
|
530
|
+
|
|
531
|
+
**Solution**: Provide a storage backend or use `InMemoryStorage`:
|
|
532
|
+
|
|
533
|
+
```typescript
|
|
534
|
+
const storage = new InMemoryStorage();
|
|
535
|
+
const fileService = new ZKIMFileService(config, logger, storage);
|
|
536
|
+
```
|
|
537
|
+
|
|
538
|
+
#### "Decryption failed"
|
|
539
|
+
|
|
540
|
+
**Possible causes**:
|
|
541
|
+
- Wrong encryption key
|
|
542
|
+
- Corrupted file data
|
|
543
|
+
- Missing nonce or metadata
|
|
544
|
+
|
|
545
|
+
**Solution**: Validate file integrity first, then check keys:
|
|
546
|
+
|
|
547
|
+
```typescript
|
|
548
|
+
const validation = await integrity.validateFile(file, platformKey, userKey);
|
|
549
|
+
if (!validation.isValid) {
|
|
550
|
+
// Handle validation errors
|
|
551
|
+
const errors = validation.errors;
|
|
552
|
+
}
|
|
553
|
+
```
|
|
554
|
+
|
|
555
|
+
#### "Compression not working"
|
|
556
|
+
|
|
557
|
+
**Solution**:
|
|
558
|
+
- **Node.js**: `zlib` is built-in and used automatically
|
|
559
|
+
- **Browser**: The package includes fallback compression using `pako`-compatible algorithms. No additional installation needed.
|
|
560
|
+
|
|
561
|
+
If you encounter compression issues, ensure your environment supports TypedArray operations.
|
|
562
|
+
|
|
563
|
+
## TypeScript Support
|
|
564
|
+
|
|
565
|
+
This package is written in TypeScript and includes full type definitions. All types are exported and can be imported:
|
|
566
|
+
|
|
567
|
+
```typescript
|
|
568
|
+
import type {
|
|
569
|
+
ZkimFile,
|
|
570
|
+
ZkimFileHeader,
|
|
571
|
+
ZkimFileMetadata,
|
|
572
|
+
ZKIMFileServiceConfig,
|
|
573
|
+
ZkimEncryptionConfig,
|
|
574
|
+
SearchQuery,
|
|
575
|
+
SearchResult,
|
|
576
|
+
} from "@zkim/file-format";
|
|
577
|
+
```
|
|
578
|
+
|
|
579
|
+
## Browser Support
|
|
580
|
+
|
|
581
|
+
This package works in modern browsers with:
|
|
582
|
+
- TypedArray support
|
|
583
|
+
- ES2020+ features
|
|
584
|
+
- ES Modules support
|
|
585
|
+
- `libsodium-wrappers-sumo` for cryptographic operations
|
|
586
|
+
- `@noble/hashes` for BLAKE3 hashing
|
|
587
|
+
|
|
588
|
+
Tested in:
|
|
589
|
+
- Chrome 90+
|
|
590
|
+
- Firefox 88+
|
|
591
|
+
- Safari 14+
|
|
592
|
+
- Edge 90+
|
|
593
|
+
|
|
594
|
+
## Node.js Support
|
|
595
|
+
|
|
596
|
+
This package works in Node.js 18+ with:
|
|
597
|
+
- Built-in `zlib` for compression (GZIP)
|
|
598
|
+
- `libsodium-wrappers-sumo` for cryptographic operations
|
|
599
|
+
- `@noble/hashes` for BLAKE3 hashing
|
|
600
|
+
- ES Modules (ESM) support
|
|
601
|
+
|
|
602
|
+
## Contributing
|
|
603
|
+
|
|
604
|
+
Contributions are welcome! Please see our [Contributing Guide](../../CONTRIBUTING.md) for details.
|
|
605
|
+
|
|
606
|
+
### Development Setup
|
|
607
|
+
|
|
608
|
+
```bash
|
|
609
|
+
# Clone the repository
|
|
610
|
+
git clone https://github.com/zkdotim/zkim-file-format.git
|
|
611
|
+
cd zkim-file-format
|
|
612
|
+
|
|
613
|
+
# Install dependencies
|
|
614
|
+
npm install
|
|
615
|
+
|
|
616
|
+
# Run tests
|
|
617
|
+
npm test
|
|
618
|
+
|
|
619
|
+
# Build the package
|
|
620
|
+
npm run build
|
|
621
|
+
|
|
622
|
+
# Run linting
|
|
623
|
+
npm run lint
|
|
624
|
+
|
|
625
|
+
# Run type checking
|
|
626
|
+
npm run typecheck
|
|
627
|
+
|
|
628
|
+
# Generate test coverage
|
|
629
|
+
npm run test:coverage
|
|
630
|
+
```
|
|
631
|
+
|
|
632
|
+
### CI/CD
|
|
633
|
+
|
|
634
|
+
This package uses GitHub Actions for continuous integration:
|
|
635
|
+
|
|
636
|
+
- **Lint & Type Check**: Runs on every push and pull request
|
|
637
|
+
- **Tests**: Automated testing with coverage reporting
|
|
638
|
+
- **Build**: Verifies package builds successfully
|
|
639
|
+
- **Security**: Automated security scanning
|
|
640
|
+
- **Publishing**: Automated npm publishing on release tags
|
|
641
|
+
|
|
642
|
+
See `.github/workflows/` for workflow definitions.
|
|
643
|
+
|
|
644
|
+
## 📊 Statistics
|
|
645
|
+
|
|
646
|
+
- **Total Tests:** 1,307 (1,305 passing, 2 skipped)
|
|
647
|
+
- **Test Coverage:** 92.09% statements, 82.15% branches, 95.83% functions, 92.16% lines
|
|
648
|
+
- **Dependencies:** 3 production dependencies (libsodium, @noble/hashes, @noble/curves)
|
|
649
|
+
- **Bundle Size:** ~384 KB (ESM), ~390 KB (CJS)
|
|
650
|
+
- **TypeScript:** Full type definitions included
|
|
651
|
+
|
|
652
|
+
## 🤝 Contributing
|
|
653
|
+
|
|
654
|
+
Contributions are welcome! Please see our [Contributing Guide](./CONTRIBUTING.md) for details.
|
|
655
|
+
|
|
656
|
+
### Quick Start for Contributors
|
|
657
|
+
|
|
658
|
+
```bash
|
|
659
|
+
# Clone the repository
|
|
660
|
+
git clone https://github.com/zkdotim/zkim-file-format.git
|
|
661
|
+
cd zkim-file-format
|
|
662
|
+
|
|
663
|
+
# Install dependencies
|
|
664
|
+
npm install
|
|
665
|
+
|
|
666
|
+
# Run tests
|
|
667
|
+
npm test
|
|
668
|
+
|
|
669
|
+
# Run linting
|
|
670
|
+
npm run lint
|
|
671
|
+
|
|
672
|
+
# Build the package
|
|
673
|
+
npm run build
|
|
674
|
+
```
|
|
675
|
+
|
|
676
|
+
## 📚 Support & Resources
|
|
677
|
+
|
|
678
|
+
- 📖 [Full Documentation](./README.md)
|
|
679
|
+
- 🐛 [Report a Bug](https://github.com/zkdotim/zkim-file-format/issues/new?template=bug_report.md)
|
|
680
|
+
- 💡 [Request a Feature](https://github.com/zkdotim/zkim-file-format/issues/new?template=feature_request.md)
|
|
681
|
+
- ❓ [Ask a Question](https://github.com/zkdotim/zkim-file-format/issues/new?template=question.md)
|
|
682
|
+
- 💬 [Discussions](https://github.com/zkdotim/zkim-file-format/discussions)
|
|
683
|
+
- 🔒 [Security Policy](./.github/SECURITY.md)
|
|
684
|
+
|
|
685
|
+
## 📄 Changelog
|
|
686
|
+
|
|
687
|
+
See [CHANGELOG.md](./CHANGELOG.md) for a list of changes and version history.
|
|
688
|
+
|
|
689
|
+
## 📜 License
|
|
690
|
+
|
|
691
|
+
MIT License - see [LICENSE](./LICENSE) for details.
|
|
692
|
+
|
|
693
|
+
---
|
|
694
|
+
|
|
695
|
+
**Made with ❤️ by the ZKIM Team**
|