@ajna-inc/vaults 0.1.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 (48) hide show
  1. package/LICENSE +202 -0
  2. package/build/VaultsApi.js +263 -0
  3. package/build/VaultsEvents.js +19 -0
  4. package/build/VaultsModule.js +71 -0
  5. package/build/crypto/wasm/VaultCrypto.js +70 -0
  6. package/build/errors/BadSuiteError.js +34 -0
  7. package/build/errors/DecryptAeadError.js +34 -0
  8. package/build/errors/DecryptKemError.js +34 -0
  9. package/build/errors/PolicyError.js +34 -0
  10. package/build/errors/VaultError.js +77 -0
  11. package/build/errors/index.js +16 -0
  12. package/build/index.js +119 -0
  13. package/build/messages/CreateVaultMessage.js +126 -0
  14. package/build/messages/DeleteVaultMessage.js +114 -0
  15. package/build/messages/DenyAccessMessage.js +114 -0
  16. package/build/messages/DenyShareMessage.js +120 -0
  17. package/build/messages/GrantAccessMessage.js +126 -0
  18. package/build/messages/ProvideShareMessage.js +126 -0
  19. package/build/messages/RequestAccessMessage.js +120 -0
  20. package/build/messages/RequestShareMessage.js +120 -0
  21. package/build/messages/RetrieveVaultMessage.js +108 -0
  22. package/build/messages/StoreVaultMessage.js +114 -0
  23. package/build/messages/UpdateVaultMessage.js +120 -0
  24. package/build/messages/VaultCreatedAckMessage.js +108 -0
  25. package/build/messages/VaultDataMessage.js +121 -0
  26. package/build/messages/VaultProblemReportMessage.js +124 -0
  27. package/build/messages/VaultStoredAckMessage.js +115 -0
  28. package/build/messages/index.js +36 -0
  29. package/build/models/ThresholdSession.js +24 -0
  30. package/build/models/VaultDocument.js +28 -0
  31. package/build/models/VaultHeader.js +31 -0
  32. package/build/models/VaultPolicy.js +29 -0
  33. package/build/models/index.js +20 -0
  34. package/build/repository/ThresholdSessionRecord.js +117 -0
  35. package/build/repository/ThresholdSessionRepository.js +216 -0
  36. package/build/repository/VaultRecord.js +128 -0
  37. package/build/repository/VaultRepository.js +200 -0
  38. package/build/repository/index.js +13 -0
  39. package/build/services/VaultEncryptionService.js +613 -0
  40. package/build/services/VaultService.js +398 -0
  41. package/build/services/index.js +8 -0
  42. package/package.json +45 -0
  43. package/wasm/README.md +166 -0
  44. package/wasm/package.json +16 -0
  45. package/wasm/vault_crypto.d.ts +526 -0
  46. package/wasm/vault_crypto.js +2137 -0
  47. package/wasm/vault_crypto_bg.wasm +0 -0
  48. package/wasm/vault_crypto_bg.wasm.d.ts +66 -0
@@ -0,0 +1,526 @@
1
+ /* tslint:disable */
2
+ /* eslint-disable */
3
+ /**
4
+ * Encrypt using AES-256-GCM (§4.1 P1 suite)
5
+ *
6
+ * # Arguments
7
+ * * `key` - 32-byte encryption key
8
+ * * `nonce` - 12-byte nonce (must be unique per key)
9
+ * * `plaintext` - Data to encrypt
10
+ * * `aad` - Associated data (authenticated but not encrypted)
11
+ *
12
+ * # Returns
13
+ * Ciphertext with authentication tag appended (plaintext.len() + 16 bytes)
14
+ */
15
+ export function aesGcmEncrypt(key: Uint8Array, nonce: Uint8Array, plaintext: Uint8Array, aad: Uint8Array): AeadResult;
16
+ /**
17
+ * Decrypt using AES-256-GCM (§4.1 P1 suite)
18
+ *
19
+ * # Arguments
20
+ * * `key` - 32-byte encryption key
21
+ * * `nonce` - 12-byte nonce (same as encryption)
22
+ * * `ciphertext` - Encrypted data with tag
23
+ * * `aad` - Associated data (must match encryption)
24
+ *
25
+ * # Returns
26
+ * Plaintext (ciphertext.len() - 16 bytes)
27
+ */
28
+ export function aesGcmDecrypt(key: Uint8Array, nonce: Uint8Array, ciphertext: Uint8Array, aad: Uint8Array): Uint8Array;
29
+ /**
30
+ * Encrypt using XChaCha20-Poly1305 (§4.1 H1 suite)
31
+ *
32
+ * # Arguments
33
+ * * `key` - 32-byte encryption key
34
+ * * `nonce` - 24-byte nonce (extended nonce for XChaCha)
35
+ * * `plaintext` - Data to encrypt
36
+ * * `aad` - Associated data (authenticated but not encrypted)
37
+ *
38
+ * # Returns
39
+ * Ciphertext with authentication tag appended
40
+ */
41
+ export function xchachaEncrypt(key: Uint8Array, nonce: Uint8Array, plaintext: Uint8Array, aad: Uint8Array): AeadResult;
42
+ /**
43
+ * Decrypt using XChaCha20-Poly1305 (§4.1 H1 suite)
44
+ *
45
+ * # Arguments
46
+ * * `key` - 32-byte encryption key
47
+ * * `nonce` - 24-byte nonce (same as encryption)
48
+ * * `ciphertext` - Encrypted data with tag
49
+ * * `aad` - Associated data (must match encryption)
50
+ *
51
+ * # Returns
52
+ * Plaintext
53
+ */
54
+ export function xchachaDecrypt(key: Uint8Array, nonce: Uint8Array, ciphertext: Uint8Array, aad: Uint8Array): Uint8Array;
55
+ /**
56
+ * Generate ML-KEM-768 keypair (§4.1 P1 suite)
57
+ *
58
+ * # Returns
59
+ * Keypair with:
60
+ * - Public key: 1184 bytes
61
+ * - Secret key: 2400 bytes
62
+ */
63
+ export function kemGenerateKeypair(): KemKeypair;
64
+ /**
65
+ * Encapsulate a shared secret to a recipient's public key (§6.1)
66
+ *
67
+ * # Arguments
68
+ * * `recipient_public_key` - Recipient's ML-KEM-768 public key (1184 bytes)
69
+ *
70
+ * # Returns
71
+ * - `sharedSecret`: 32-byte shared secret (use as KEK to wrap CEK)
72
+ * - `ciphertext`: KEM ciphertext to send to recipient
73
+ */
74
+ export function kemEncapsulate(recipient_public_key: Uint8Array): KemEncapResult;
75
+ /**
76
+ * Decapsulate to recover shared secret from ciphertext (§6.1)
77
+ *
78
+ * # Arguments
79
+ * * `ciphertext` - KEM ciphertext from encapsulation
80
+ * * `secret_key` - Recipient's ML-KEM-768 secret key (2400 bytes)
81
+ *
82
+ * # Returns
83
+ * 32-byte shared secret (same as encapsulation)
84
+ */
85
+ export function kemDecapsulate(ciphertext: Uint8Array, secret_key: Uint8Array): Uint8Array;
86
+ /**
87
+ * Wrap a CEK using KEM + AES-KW pattern
88
+ *
89
+ * This is a convenience function that:
90
+ * 1. Encapsulates to get a KEK (Key Encryption Key)
91
+ * 2. Uses KEK with AES-GCM to wrap the CEK
92
+ *
93
+ * # Arguments
94
+ * * `cek` - Content Encryption Key to wrap (typically 32 bytes)
95
+ * * `recipient_public_key` - Recipient's ML-KEM-768 public key
96
+ *
97
+ * # Returns
98
+ * Wrapped CEK ciphertext (includes both KEM ciphertext and AES-GCM encrypted CEK)
99
+ */
100
+ export function kemWrapCek(cek: Uint8Array, recipient_public_key: Uint8Array): Uint8Array;
101
+ /**
102
+ * Unwrap a CEK using KEM + AES-KW pattern
103
+ *
104
+ * Inverse of `kemWrapCek`.
105
+ *
106
+ * # Arguments
107
+ * * `wrapped_cek` - Combined KEM ciphertext + AES-GCM encrypted CEK
108
+ * * `secret_key` - Recipient's ML-KEM-768 secret key
109
+ *
110
+ * # Returns
111
+ * Unwrapped CEK
112
+ */
113
+ export function kemUnwrapCek(wrapped_cek: Uint8Array, secret_key: Uint8Array): Uint8Array;
114
+ /**
115
+ * Derive key using HKDF-SHA256 (§10.3)
116
+ *
117
+ * # Arguments
118
+ * * `ikm` - Input Key Material
119
+ * * `salt` - Optional salt (use empty array for none)
120
+ * * `info` - Context/domain string
121
+ * * `length` - Output key length in bytes
122
+ *
123
+ * # Returns
124
+ * Derived key of requested length
125
+ */
126
+ export function hkdfExpand(ikm: Uint8Array, salt: Uint8Array, info: string, length: number): Uint8Array;
127
+ /**
128
+ * HKDF-join: Order-independent key folding for all-of policy (§6.2)
129
+ *
130
+ * Combines multiple keys into a single wrap key deterministically.
131
+ * Order-independent by sorting KIDs before folding.
132
+ *
133
+ * # Arguments
134
+ * * `keys` - Array of key materials (each with KID and key bytes)
135
+ * * `context` - Context string (e.g., "doc:uuid:epoch:3")
136
+ *
137
+ * # Returns
138
+ * 32-byte joint wrap key
139
+ *
140
+ * # Example
141
+ * ```javascript
142
+ * const keys = [
143
+ * { kid: "alice", key: aliceKeyBytes },
144
+ * { kid: "bob", key: bobKeyBytes },
145
+ * ];
146
+ * const wrapKey = hkdfJoin(keys, "doc:abc:epoch:0");
147
+ * ```
148
+ */
149
+ export function hkdfJoin(keys: any, context: string): Uint8Array;
150
+ /**
151
+ * Simple HKDF for CEK derivation from seed
152
+ *
153
+ * # Arguments
154
+ * * `seed` - Random seed material
155
+ * * `context` - Context string
156
+ *
157
+ * # Returns
158
+ * 32-byte CEK
159
+ */
160
+ export function deriveCek(seed: Uint8Array, context: string): Uint8Array;
161
+ /**
162
+ * Derive key identifier (KID) from public key (§10.1)
163
+ *
164
+ * KID = base64url(SHA256(publicKey))
165
+ *
166
+ * # Arguments
167
+ * * `public_key` - Public key bytes
168
+ *
169
+ * # Returns
170
+ * Base64url-encoded KID
171
+ */
172
+ export function deriveKid(public_key: Uint8Array): string;
173
+ /**
174
+ * Derive key identifier from symmetric key (§10.1)
175
+ *
176
+ * For symmetric keys, use HKDF to avoid reversibility:
177
+ * KID = base64url(HKDF-Expand(key, "kid:v1", 16))
178
+ *
179
+ * # Arguments
180
+ * * `key` - Symmetric key bytes
181
+ *
182
+ * # Returns
183
+ * Base64url-encoded KID (truncated to 16 bytes for compactness)
184
+ */
185
+ export function deriveSymmetricKid(key: Uint8Array): string;
186
+ /**
187
+ * Split secret into Shamir shares (t-of-n threshold)
188
+ *
189
+ * # Arguments
190
+ * * `secret` - Secret to split (typically a CEK, 32 bytes)
191
+ * * `threshold` - Minimum shares needed to reconstruct (t)
192
+ * * `total_shares` - Total number of shares to create (n)
193
+ *
194
+ * # Returns
195
+ * Array of n shares, any t of which can reconstruct the secret
196
+ *
197
+ * # Example
198
+ * ```javascript
199
+ * const cek = new Uint8Array(32); // 32-byte CEK
200
+ * crypto.getRandomValues(cek);
201
+ *
202
+ * // Create 5 shares, need any 3 to reconstruct
203
+ * const shares = shamirSplit(cek, 3, 5);
204
+ * ```
205
+ */
206
+ export function shamirSplit(secret: Uint8Array, threshold: number, total_shares: number): any;
207
+ /**
208
+ * Reconstruct secret from Shamir shares
209
+ *
210
+ * # Arguments
211
+ * * `shares` - Array of shares (must have at least threshold shares)
212
+ *
213
+ * # Returns
214
+ * Reconstructed secret
215
+ *
216
+ * # Example
217
+ * ```javascript
218
+ * // Use any 3 of the 5 shares
219
+ * const selectedShares = [shares[0], shares[2], shares[4]];
220
+ * const reconstructed = shamirReconstruct(selectedShares);
221
+ * ```
222
+ */
223
+ export function shamirReconstruct(shares: any): Uint8Array;
224
+ /**
225
+ * Helper: Split and KEM-wrap shares for threshold policy (§6.3)
226
+ *
227
+ * Combines Shamir splitting with KEM encapsulation.
228
+ * Each share is encrypted to a participant's public key.
229
+ *
230
+ * # Arguments
231
+ * * `secret` - CEK to split and wrap
232
+ * * `threshold` - Minimum shares needed
233
+ * * `recipient_public_keys` - Array of ML-KEM-768 public keys (1184 bytes each)
234
+ *
235
+ * # Returns
236
+ * Array of wrapped shares (each contains KEM ciphertext + encrypted share)
237
+ */
238
+ export function shamirSplitAndWrap(secret: Uint8Array, threshold: number, recipient_public_keys: any): any;
239
+ /**
240
+ * Helper: Unwrap and reconstruct from KEM-wrapped shares
241
+ *
242
+ * # Arguments
243
+ * * `wrapped_shares` - Array of wrapped shares
244
+ * * `secret_keys` - Array of ML-KEM-768 secret keys (2400 bytes each)
245
+ *
246
+ * # Returns
247
+ * Reconstructed secret (if threshold met)
248
+ */
249
+ export function shamirUnwrapAndReconstruct(wrapped_shares: any, secret_keys: any): Uint8Array;
250
+ /**
251
+ * Generate random bytes using cryptographically secure RNG
252
+ *
253
+ * # Arguments
254
+ * * `length` - Number of random bytes to generate
255
+ *
256
+ * # Returns
257
+ * Cryptographically random bytes
258
+ */
259
+ export function randomBytes(length: number): Uint8Array;
260
+ /**
261
+ * Generate a random 32-byte CEK (Content Encryption Key)
262
+ *
263
+ * # Returns
264
+ * 32-byte random CEK
265
+ */
266
+ export function generateCek(): Uint8Array;
267
+ /**
268
+ * Generate random nonce for AES-GCM (12 bytes)
269
+ *
270
+ * # Returns
271
+ * 12-byte random nonce
272
+ */
273
+ export function generateNonceAesGcm(): Uint8Array;
274
+ /**
275
+ * Generate random nonce for XChaCha20-Poly1305 (24 bytes)
276
+ *
277
+ * # Returns
278
+ * 24-byte random nonce
279
+ */
280
+ export function generateNonceXchacha(): Uint8Array;
281
+ /**
282
+ * Compute key commitment: HMAC-SHA256(CEK, "kcmp:v1") (§5.1)
283
+ *
284
+ * Key commitment ensures the CEK is bound to the ciphertext and prevents
285
+ * key substitution attacks.
286
+ *
287
+ * # Arguments
288
+ * * `cek` - Content Encryption Key
289
+ *
290
+ * # Returns
291
+ * 32-byte key commitment value
292
+ */
293
+ export function keyCommitment(cek: Uint8Array): Uint8Array;
294
+ /**
295
+ * Verify key commitment
296
+ *
297
+ * # Arguments
298
+ * * `cek` - Content Encryption Key
299
+ * * `expected_kcmp` - Expected commitment value
300
+ *
301
+ * # Returns
302
+ * true if commitment matches
303
+ */
304
+ export function verifyKeyCommitment(cek: Uint8Array, expected_kcmp: Uint8Array): boolean;
305
+ /**
306
+ * Compute SHA-256 hash
307
+ *
308
+ * # Arguments
309
+ * * `data` - Data to hash
310
+ *
311
+ * # Returns
312
+ * 32-byte SHA-256 digest
313
+ */
314
+ export function sha256(data: Uint8Array): Uint8Array;
315
+ /**
316
+ * Compute BLAKE2s-256 hash
317
+ *
318
+ * # Arguments
319
+ * * `data` - Data to hash
320
+ *
321
+ * # Returns
322
+ * 32-byte BLAKE2s-256 digest
323
+ */
324
+ export function blake2s256(data: Uint8Array): Uint8Array;
325
+ /**
326
+ * Compute summary hash for WYSIWYS (What You See Is What You Sign)
327
+ *
328
+ * Summary = BLAKE2s-256(digest)[..16]
329
+ *
330
+ * # Arguments
331
+ * * `digest` - Transaction or document digest
332
+ *
333
+ * # Returns
334
+ * 16-byte summary hash (fingerprint)
335
+ */
336
+ export function computeSummary(digest: Uint8Array): Uint8Array;
337
+ /**
338
+ * Constant-time equality comparison
339
+ *
340
+ * # Arguments
341
+ * * `a` - First byte array
342
+ * * `b` - Second byte array
343
+ *
344
+ * # Returns
345
+ * true if arrays are equal (constant-time)
346
+ */
347
+ export function constantTimeEq(a: Uint8Array, b: Uint8Array): boolean;
348
+ /**
349
+ * Encode bytes to base64url (no padding)
350
+ *
351
+ * # Arguments
352
+ * * `data` - Bytes to encode
353
+ *
354
+ * # Returns
355
+ * Base64url-encoded string
356
+ */
357
+ export function toBase64Url(data: Uint8Array): string;
358
+ /**
359
+ * Decode bytes from base64url
360
+ *
361
+ * # Arguments
362
+ * * `encoded` - Base64url-encoded string
363
+ *
364
+ * # Returns
365
+ * Decoded bytes
366
+ */
367
+ export function fromBase64Url(encoded: string): Uint8Array;
368
+ /**
369
+ * Encode bytes to hex string
370
+ *
371
+ * # Arguments
372
+ * * `data` - Bytes to encode
373
+ *
374
+ * # Returns
375
+ * Hex-encoded string
376
+ */
377
+ export function toHex(data: Uint8Array): string;
378
+ /**
379
+ * Decode bytes from hex string
380
+ *
381
+ * # Arguments
382
+ * * `encoded` - Hex-encoded string
383
+ *
384
+ * # Returns
385
+ * Decoded bytes
386
+ */
387
+ export function fromHex(encoded: string): Uint8Array;
388
+ /**
389
+ * Generate UUID v4
390
+ *
391
+ * # Returns
392
+ * UUID v4 string
393
+ */
394
+ export function generateUuid(): string;
395
+ /**
396
+ * Zeroize (securely erase) a byte array
397
+ *
398
+ * # Arguments
399
+ * * `data` - Mutable byte array to zeroize
400
+ */
401
+ export function zeroize(data: Uint8Array): void;
402
+ /**
403
+ * Create canonical AAD (Associated Authenticated Data) for envelope encryption (§5.3)
404
+ *
405
+ * AAD includes: {v, suite, aead, docId, vaultId?, epoch, policy.mode}
406
+ *
407
+ * # Arguments
408
+ * * `header_fields` - JSON object with header fields
409
+ *
410
+ * # Returns
411
+ * Canonical JSON bytes for AAD
412
+ */
413
+ export function canonicalAad(header_fields: any): Uint8Array;
414
+ /**
415
+ * Build context string for key derivation (§10.2)
416
+ *
417
+ * Format: "doc:{docId}:epoch:{epoch}"
418
+ *
419
+ * # Arguments
420
+ * * `doc_id` - Document ID
421
+ * * `epoch` - Epoch number
422
+ *
423
+ * # Returns
424
+ * Context string
425
+ */
426
+ export function buildContext(doc_id: string, epoch: number): string;
427
+ /**
428
+ * Initialize panic hook for better error messages in WASM
429
+ */
430
+ export function init(): void;
431
+ /**
432
+ * Get version info
433
+ */
434
+ export function version(): string;
435
+ /**
436
+ * AEAD encryption result
437
+ */
438
+ export class AeadResult {
439
+ private constructor();
440
+ free(): void;
441
+ [Symbol.dispose](): void;
442
+ /**
443
+ * Get ciphertext as base64url
444
+ */
445
+ toBase64Url(): string;
446
+ /**
447
+ * Get ciphertext as bytes
448
+ */
449
+ readonly ciphertext: Uint8Array;
450
+ }
451
+ /**
452
+ * KEM encapsulation result (shared secret + ciphertext)
453
+ */
454
+ export class KemEncapResult {
455
+ private constructor();
456
+ free(): void;
457
+ [Symbol.dispose](): void;
458
+ /**
459
+ * Get ciphertext as base64url
460
+ */
461
+ ciphertextBase64(): string;
462
+ /**
463
+ * Get shared secret (32 bytes)
464
+ */
465
+ readonly sharedSecret: Uint8Array;
466
+ /**
467
+ * Get ciphertext (to send to recipient)
468
+ */
469
+ readonly ciphertext: Uint8Array;
470
+ }
471
+ /**
472
+ * ML-KEM-768 keypair
473
+ */
474
+ export class KemKeypair {
475
+ private constructor();
476
+ free(): void;
477
+ [Symbol.dispose](): void;
478
+ /**
479
+ * Get public key as base64url
480
+ */
481
+ publicKeyBase64(): string;
482
+ /**
483
+ * Get secret key as base64url
484
+ */
485
+ secretKeyBase64(): string;
486
+ /**
487
+ * Get public key bytes
488
+ */
489
+ readonly publicKey: Uint8Array;
490
+ /**
491
+ * Get secret key bytes
492
+ */
493
+ readonly secretKey: Uint8Array;
494
+ }
495
+ /**
496
+ * A Shamir secret share
497
+ */
498
+ export class SecretShare {
499
+ private constructor();
500
+ free(): void;
501
+ [Symbol.dispose](): void;
502
+ /**
503
+ * Serialize share to JSON
504
+ */
505
+ toJson(): string;
506
+ /**
507
+ * Deserialize share from JSON
508
+ */
509
+ static fromJson(json: string): SecretShare;
510
+ /**
511
+ * Get share as base64url
512
+ */
513
+ toBase64(): string;
514
+ /**
515
+ * Deserialize share from base64url
516
+ */
517
+ static fromBase64(b64: string): SecretShare;
518
+ /**
519
+ * Get share identifier
520
+ */
521
+ readonly identifier: number;
522
+ /**
523
+ * Get share value as bytes
524
+ */
525
+ readonly value: Uint8Array;
526
+ }