@sumicom/quicksave-shared 0.7.0 → 0.8.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md ADDED
@@ -0,0 +1,44 @@
1
+ # @sumicom/quicksave-shared
2
+
3
+ Shared TypeScript types, crypto utilities, and wire-format helpers used by
4
+ all three Quicksave apps (`agent`, `pwa`, `relay`). Not intended for
5
+ external consumption — it's published so the agent and PWA can depend on it
6
+ via the normal npm resolution, not because it has a stable standalone API.
7
+
8
+ ## Modules
9
+
10
+ | Entry | Contents |
11
+ | ----------------------------- | -------------------------------------------------------------------------- |
12
+ | `@sumicom/quicksave-shared` | Everything (re-exports all of the below) |
13
+ | `.../crypto` | NaCl box/sign wrappers, gzip+encrypt envelope helpers |
14
+ | `.../protocol` | `Message` envelope helpers, handshake types, message-type narrowing |
15
+
16
+ ## What lives here
17
+
18
+ - **`types.ts`** — the canonical `MessageType` enum and every payload /
19
+ response type exchanged between PWA and agent (`claude:*`, `git:*`,
20
+ `agent:*`, `ai:*`, `push:*`, etc.). This is the wire contract.
21
+ - **`cards.ts`** — `Card` / `CardEvent` data model used for streamed
22
+ assistant output (user text, assistant text, thinking, tool calls,
23
+ subagent blocks, system). Consumed by `StreamCardBuilder` in the agent
24
+ and by `CardRenderer` in the PWA.
25
+ - **`crypto.ts`** — X25519 + XSalsa20-Poly1305 box for E2E message
26
+ encryption; Ed25519 for signed HTTP calls to the relay's push routes;
27
+ gzip+encrypt envelope used for all wire messages.
28
+ - **`protocol.ts`** — helpers for building and parsing the `Message<T>`
29
+ envelope that wraps every request, response, and push.
30
+ - **`permissions.ts`** — permission-mode enum (`bypassPermissions`,
31
+ `acceptEdits`, `default`, `plan`) and per-mode auto-approve tables.
32
+ - **`defaults.ts`** — default signaling URL and other shared constants.
33
+
34
+ ## Wire contract note
35
+
36
+ Anything added to or changed in `MessageType` in `types.ts` is a protocol
37
+ change — both the agent's `MessageHandler` and the PWA hooks
38
+ (`useClaudeOperations`, `useGitOperations`) must be updated at the same
39
+ time. See `docs/references/quicksave-architecture.md` §四 for the full
40
+ message-type catalog and bus-path mappings.
41
+
42
+ ## License
43
+
44
+ MIT
package/dist/cards.d.ts CHANGED
@@ -81,7 +81,14 @@ export interface CardUpdateEvent {
81
81
  streamId: string;
82
82
  sessionId: string;
83
83
  cardId: CardId;
84
- /** Partial card fields to merge (only changed fields sent). */
84
+ /**
85
+ * Partial card fields to merge (only changed fields sent).
86
+ *
87
+ * Wire convention: `null` means "delete this key". JSON.stringify drops
88
+ * `undefined`, so we use `null` as the clear sentinel (e.g. clearing
89
+ * `pendingInput` after permission resolution). Receivers must delete
90
+ * null-valued keys after spreading the patch.
91
+ */
85
92
  patch: Record<string, unknown>;
86
93
  }
87
94
  export interface CardAppendTextEvent {
@@ -111,7 +118,7 @@ export interface CardHistoryResponse {
111
118
  error?: string;
112
119
  /** Pending permission/question requests for this session (agent-authoritative). */
113
120
  pendingInputs?: PendingInputWithContext[];
114
- /** Session title (set via SetTitle MCP tool or derived from session registry). */
121
+ /** Session title / subject (set via the UpdateSessionStatus MCP tool or derived from session registry). */
115
122
  title?: string;
116
123
  }
117
124
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"cards.d.ts","sourceRoot":"","sources":["../src/cards.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"cards.d.ts","sourceRoot":"","sources":["../src/cards.ts"],"names":[],"mappings":"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"}
package/dist/crypto.d.ts CHANGED
@@ -119,9 +119,47 @@ export declare function decodeKeyPair(encoded: {
119
119
  publicKey: string;
120
120
  secretKey: string;
121
121
  }): KeyPair;
122
+ /**
123
+ * Validate that a string is a base64-encoded key of the expected byte length.
124
+ * Curve25519/Ed25519 public/secret keys are 32 bytes → 44 base64 chars.
125
+ * Returns false for empty strings, non-base64 input, or wrong-length decodes.
126
+ */
127
+ export declare function isValidBase64Key(s: unknown, expectedBytes?: number): s is string;
122
128
  /**
123
129
  * Generate a random agent ID (used for signaling)
124
130
  */
125
131
  export declare function generateAgentId(): string;
132
+ /**
133
+ * Derive the shared X25519 and Ed25519 keypairs used by all PWA clients
134
+ * that share this `masterSecret`. Both keypairs are fully deterministic
135
+ * from `masterSecret` + a fixed domain string, so every PWA that holds
136
+ * the same secret derives bit-identical pubkeys.
137
+ */
138
+ export declare function deriveSharedKeys(masterSecret: Uint8Array): {
139
+ x25519: KeyPair;
140
+ ed25519: KeyPair;
141
+ };
142
+ export declare const SAS_ALPHABET = "23456789ABCDEFGHJKLMNPQRSTUVWXYZ";
143
+ /**
144
+ * Encode the first `chars * 5` bits of `hmacOutput` into the 32-symbol SAS
145
+ * alphabet. Reads bits big-endian (MSB first) from consecutive bytes.
146
+ */
147
+ export declare function sasEncode(hmacOutput: Uint8Array, chars: number): string;
148
+ /**
149
+ * Compute the current bucket index for a SAS window. Default 60s window.
150
+ * A and B only agree if they fall in the same bucket (or adjacent, checked
151
+ * at verify time).
152
+ */
153
+ export declare function sasBucket(now: number, windowMs?: number): number;
154
+ /**
155
+ * Compute the SAS string for a given pubkey and bucket.
156
+ *
157
+ * Deterministic hash of (domain || pubkey || bucket_be8); the same inputs
158
+ * always yield the same SAS on both A and B. The "HMAC" in the design doc
159
+ * is interpreted as "a domain-separated cryptographic hash": SAS isn't a
160
+ * MAC (there's no secret key both sides share before pairing), it's a
161
+ * visual comparison of two independently-computed values.
162
+ */
163
+ export declare function sasCompute(pubkey: Uint8Array, bucket: number, chars?: number): string;
126
164
  export { encodeBase64, decodeBase64, encodeUTF8, decodeUTF8 };
127
165
  //# sourceMappingURL=crypto.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"crypto.d.ts","sourceRoot":"","sources":["../src/crypto.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"crypto.d.ts","sourceRoot":"","sources":["../src/crypto.ts"],"names":[],"mappings":"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"}
package/dist/crypto.js CHANGED
@@ -288,6 +288,21 @@ export function decodeKeyPair(encoded) {
288
288
  secretKey: decodeBase64(encoded.secretKey),
289
289
  };
290
290
  }
291
+ /**
292
+ * Validate that a string is a base64-encoded key of the expected byte length.
293
+ * Curve25519/Ed25519 public/secret keys are 32 bytes → 44 base64 chars.
294
+ * Returns false for empty strings, non-base64 input, or wrong-length decodes.
295
+ */
296
+ export function isValidBase64Key(s, expectedBytes = 32) {
297
+ if (typeof s !== 'string' || s.length === 0)
298
+ return false;
299
+ try {
300
+ return decodeBase64(s).length === expectedBytes;
301
+ }
302
+ catch {
303
+ return false;
304
+ }
305
+ }
291
306
  /**
292
307
  * Generate a random agent ID (used for signaling)
293
308
  */
@@ -298,6 +313,110 @@ export function generateAgentId() {
298
313
  .replace(/\//g, '_')
299
314
  .replace(/=/g, '');
300
315
  }
316
+ // ============================================================================
317
+ // Shared-Secret Key Derivation (PWA sync identity)
318
+ // ============================================================================
319
+ const X25519_DOMAIN = 'quicksave-sync-x25519-v1';
320
+ const ED25519_DOMAIN = 'quicksave-sync-ed25519-v1';
321
+ function deriveSeed(masterSecret, domain) {
322
+ const domainBytes = decodeUTF8(domain);
323
+ const input = new Uint8Array(domainBytes.length + masterSecret.length);
324
+ input.set(domainBytes);
325
+ input.set(masterSecret, domainBytes.length);
326
+ return nacl.hash(input).slice(0, 32);
327
+ }
328
+ /**
329
+ * Derive the shared X25519 and Ed25519 keypairs used by all PWA clients
330
+ * that share this `masterSecret`. Both keypairs are fully deterministic
331
+ * from `masterSecret` + a fixed domain string, so every PWA that holds
332
+ * the same secret derives bit-identical pubkeys.
333
+ */
334
+ export function deriveSharedKeys(masterSecret) {
335
+ if (masterSecret.length !== 32) {
336
+ throw new Error('masterSecret must be 32 bytes');
337
+ }
338
+ const x25519Seed = deriveSeed(masterSecret, X25519_DOMAIN);
339
+ const ed25519Seed = deriveSeed(masterSecret, ED25519_DOMAIN);
340
+ return {
341
+ x25519: nacl.box.keyPair.fromSecretKey(x25519Seed),
342
+ ed25519: nacl.sign.keyPair.fromSeed(ed25519Seed),
343
+ };
344
+ }
345
+ // ============================================================================
346
+ // SAS (Short Authentication String) for PWA pairing
347
+ // ============================================================================
348
+ // 32 symbols, case-insensitive, removed 0/1/I/O to avoid typo ambiguity.
349
+ // 5 bits per character.
350
+ export const SAS_ALPHABET = '23456789ABCDEFGHJKLMNPQRSTUVWXYZ';
351
+ const SAS_DOMAIN = 'quicksave-sas-v1';
352
+ /**
353
+ * Encode the first `chars * 5` bits of `hmacOutput` into the 32-symbol SAS
354
+ * alphabet. Reads bits big-endian (MSB first) from consecutive bytes.
355
+ */
356
+ export function sasEncode(hmacOutput, chars) {
357
+ if (!Number.isInteger(chars) || chars <= 0) {
358
+ throw new Error('chars must be a positive integer');
359
+ }
360
+ const bytesNeeded = Math.ceil((chars * 5) / 8);
361
+ if (hmacOutput.length < bytesNeeded) {
362
+ throw new Error(`hmacOutput too short: need >= ${bytesNeeded} bytes for ${chars} chars`);
363
+ }
364
+ let result = '';
365
+ let bitBuffer = 0;
366
+ let bitsInBuffer = 0;
367
+ let byteIdx = 0;
368
+ for (let i = 0; i < chars; i++) {
369
+ while (bitsInBuffer < 5) {
370
+ bitBuffer = (bitBuffer << 8) | hmacOutput[byteIdx++];
371
+ bitsInBuffer += 8;
372
+ }
373
+ bitsInBuffer -= 5;
374
+ const idx = (bitBuffer >> bitsInBuffer) & 0x1f;
375
+ result += SAS_ALPHABET[idx];
376
+ }
377
+ return result;
378
+ }
379
+ /**
380
+ * Compute the current bucket index for a SAS window. Default 60s window.
381
+ * A and B only agree if they fall in the same bucket (or adjacent, checked
382
+ * at verify time).
383
+ */
384
+ export function sasBucket(now, windowMs = 60_000) {
385
+ if (!Number.isFinite(now) || now < 0) {
386
+ throw new Error('now must be a non-negative finite number');
387
+ }
388
+ if (!Number.isFinite(windowMs) || windowMs <= 0) {
389
+ throw new Error('windowMs must be a positive number');
390
+ }
391
+ return Math.floor(now / windowMs);
392
+ }
393
+ /**
394
+ * Compute the SAS string for a given pubkey and bucket.
395
+ *
396
+ * Deterministic hash of (domain || pubkey || bucket_be8); the same inputs
397
+ * always yield the same SAS on both A and B. The "HMAC" in the design doc
398
+ * is interpreted as "a domain-separated cryptographic hash": SAS isn't a
399
+ * MAC (there's no secret key both sides share before pairing), it's a
400
+ * visual comparison of two independently-computed values.
401
+ */
402
+ export function sasCompute(pubkey, bucket, chars = 6) {
403
+ if (pubkey.length === 0) {
404
+ throw new Error('pubkey must not be empty');
405
+ }
406
+ if (!Number.isInteger(bucket) || bucket < 0) {
407
+ throw new Error('bucket must be a non-negative integer');
408
+ }
409
+ const domainBytes = decodeUTF8(SAS_DOMAIN);
410
+ const bucketBytes = new Uint8Array(8);
411
+ // Big-endian 64-bit encoding of the bucket index.
412
+ const view = new DataView(bucketBytes.buffer, bucketBytes.byteOffset, bucketBytes.byteLength);
413
+ view.setBigUint64(0, BigInt(bucket), false);
414
+ const input = new Uint8Array(domainBytes.length + pubkey.length + bucketBytes.length);
415
+ input.set(domainBytes);
416
+ input.set(pubkey, domainBytes.length);
417
+ input.set(bucketBytes, domainBytes.length + pubkey.length);
418
+ return sasEncode(nacl.hash(input), chars);
419
+ }
301
420
  // Re-export encoding utilities
302
421
  export { encodeBase64, decodeBase64, encodeUTF8, decodeUTF8 };
303
422
  //# sourceMappingURL=crypto.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"crypto.js","sourceRoot":"","sources":["../src/crypto.ts"],"names":[],"mappings":"AAAA,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,QAAQ,MAAM,gBAAgB,CAAC;AAGtC,MAAM,EAAE,YAAY,EAAE,YAAY,EAAE,UAAU,EAAE,UAAU,EAAE,GAAG,QAAQ,CAAC;AAWxE;;GAEG;AACH,MAAM,UAAU,eAAe;IAC7B,OAAO,IAAI,CAAC,GAAG,CAAC,OAAO,EAAE,CAAC;AAC5B,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,sBAAsB;IACpC,OAAO,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,CAAC;AAC7B,CAAC;AAED,+EAA+E;AAC/E,0BAA0B;AAC1B,+EAA+E;AAE/E;;;;;;GAMG;AACH,MAAM,UAAU,OAAO,CACrB,OAAe,EACf,cAA0B,EAC1B,WAAuB;IAEvB,MAAM,KAAK,GAAG,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,GAAG,CAAC,WAAW,CAAC,CAAC;IACrD,MAAM,YAAY,GAAG,UAAU,CAAC,OAAO,CAAC,CAAC;IAEzC,MAAM,SAAS,GAAG,IAAI,CAAC,GAAG,CAAC,YAAY,EAAE,KAAK,EAAE,cAAc,EAAE,WAAW,CAAC,CAAC;IAE7E,IAAI,CAAC,SAAS,EAAE,CAAC;QACf,MAAM,IAAI,KAAK,CAAC,mBAAmB,CAAC,CAAC;IACvC,CAAC;IAED,6BAA6B;IAC7B,MAAM,QAAQ,GAAG,IAAI,UAAU,CAAC,KAAK,CAAC,MAAM,GAAG,SAAS,CAAC,MAAM,CAAC,CAAC;IACjE,QAAQ,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;IACpB,QAAQ,CAAC,GAAG,CAAC,SAAS,EAAE,KAAK,CAAC,MAAM,CAAC,CAAC;IAEtC,OAAO,YAAY,CAAC,QAAQ,CAAC,CAAC;AAChC,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,OAAO,CACrB,gBAAwB,EACxB,cAA0B,EAC1B,WAAuB;IAEvB,MAAM,QAAQ,GAAG,YAAY,CAAC,gBAAgB,CAAC,CAAC;IAEhD,MAAM,KAAK,GAAG,QAAQ,CAAC,KAAK,CAAC,CAAC,EAAE,IAAI,CAAC,GAAG,CAAC,WAAW,CAAC,CAAC;IACtD,MAAM,UAAU,GAAG,QAAQ,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,WAAW,CAAC,CAAC;IAExD,MAAM,SAAS,GAAG,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,UAAU,EAAE,KAAK,EAAE,cAAc,EAAE,WAAW,CAAC,CAAC;IAEhF,IAAI,CAAC,SAAS,EAAE,CAAC;QACf,MAAM,IAAI,KAAK,CAAC,kDAAkD,CAAC,CAAC;IACtE,CAAC;IAED,OAAO,UAAU,CAAC,SAAS,CAAC,CAAC;AAC/B,CAAC;AAED,+EAA+E;AAC/E,2CAA2C;AAC3C,+EAA+E;AAE/E;;GAEG;AACH,MAAM,UAAU,kBAAkB,CAChC,cAA0B,EAC1B,WAAuB;IAEvB,OAAO,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,cAAc,EAAE,WAAW,CAAC,CAAC;AACtD,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,uBAAuB,CACrC,OAAe,EACf,YAAwB;IAExB,MAAM,KAAK,GAAG,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,SAAS,CAAC,WAAW,CAAC,CAAC;IAC3D,MAAM,YAAY,GAAG,UAAU,CAAC,OAAO,CAAC,CAAC;IAEzC,MAAM,SAAS,GAAG,IAAI,CAAC,SAAS,CAAC,YAAY,EAAE,KAAK,EAAE,YAAY,CAAC,CAAC;IAEpE,IAAI,CAAC,SAAS,EAAE,CAAC;QACf,MAAM,IAAI,KAAK,CAAC,mBAAmB,CAAC,CAAC;IACvC,CAAC;IAED,MAAM,QAAQ,GAAG,IAAI,UAAU,CAAC,KAAK,CAAC,MAAM,GAAG,SAAS,CAAC,MAAM,CAAC,CAAC;IACjE,QAAQ,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;IACpB,QAAQ,CAAC,GAAG,CAAC,SAAS,EAAE,KAAK,CAAC,MAAM,CAAC,CAAC;IAEtC,OAAO,YAAY,CAAC,QAAQ,CAAC,CAAC;AAChC,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,uBAAuB,CACrC,gBAAwB,EACxB,YAAwB;IAExB,MAAM,QAAQ,GAAG,YAAY,CAAC,gBAAgB,CAAC,CAAC;IAEhD,MAAM,KAAK,GAAG,QAAQ,CAAC,KAAK,CAAC,CAAC,EAAE,IAAI,CAAC,SAAS,CAAC,WAAW,CAAC,CAAC;IAC5D,MAAM,UAAU,GAAG,QAAQ,CAAC,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,WAAW,CAAC,CAAC;IAE9D,MAAM,SAAS,GAAG,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,UAAU,EAAE,KAAK,EAAE,YAAY,CAAC,CAAC;IAEvE,IAAI,CAAC,SAAS,EAAE,CAAC;QACf,MAAM,IAAI,KAAK,CAAC,kDAAkD,CAAC,CAAC;IACtE,CAAC;IAED,OAAO,UAAU,CAAC,SAAS,CAAC,CAAC;AAC/B,CAAC;AAED,+EAA+E;AAC/E,kDAAkD;AAClD,+EAA+E;AAE/E;;;GAGG;AACH,MAAM,UAAU,kBAAkB;IAChC,OAAO,IAAI,CAAC,WAAW,CAAC,EAAE,CAAC,CAAC;AAC9B,CAAC;AAED;;;;;;;;;GASG;AACH,MAAM,UAAU,UAAU,CACxB,GAAe,EACf,kBAA8B;IAE9B,IAAI,GAAG,CAAC,MAAM,KAAK,EAAE,EAAE,CAAC;QACtB,MAAM,IAAI,KAAK,CAAC,sBAAsB,CAAC,CAAC;IAC1C,CAAC;IAED,iDAAiD;IACjD,MAAM,SAAS,GAAG,IAAI,CAAC,GAAG,CAAC,OAAO,EAAE,CAAC;IACrC,MAAM,KAAK,GAAG,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,GAAG,CAAC,WAAW,CAAC,CAAC;IAErD,MAAM,SAAS,GAAG,IAAI,CAAC,GAAG,CAAC,GAAG,EAAE,KAAK,EAAE,kBAAkB,EAAE,SAAS,CAAC,SAAS,CAAC,CAAC;IAEhF,IAAI,CAAC,SAAS,EAAE,CAAC;QACf,MAAM,IAAI,KAAK,CAAC,uBAAuB,CAAC,CAAC;IAC3C,CAAC;IAED,mDAAmD;IACnD,MAAM,QAAQ,GAAG,IAAI,UAAU,CAC7B,SAAS,CAAC,SAAS,CAAC,MAAM,GAAG,KAAK,CAAC,MAAM,GAAG,SAAS,CAAC,MAAM,CAC7D,CAAC;IACF,QAAQ,CAAC,GAAG,CAAC,SAAS,CAAC,SAAS,CAAC,CAAC;IAClC,QAAQ,CAAC,GAAG,CAAC,KAAK,EAAE,SAAS,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC;IAChD,QAAQ,CAAC,GAAG,CAAC,SAAS,EAAE,SAAS,CAAC,SAAS,CAAC,MAAM,GAAG,KAAK,CAAC,MAAM,CAAC,CAAC;IAEnE,OAAO,YAAY,CAAC,QAAQ,CAAC,CAAC;AAChC,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,UAAU,CACxB,YAAoB,EACpB,WAAuB;IAEvB,MAAM,QAAQ,GAAG,YAAY,CAAC,YAAY,CAAC,CAAC;IAE5C,qBAAqB;IACrB,MAAM,kBAAkB,GAAG,QAAQ,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;IACjD,MAAM,KAAK,GAAG,QAAQ,CAAC,KAAK,CAAC,EAAE,EAAE,EAAE,GAAG,IAAI,CAAC,GAAG,CAAC,WAAW,CAAC,CAAC;IAC5D,MAAM,UAAU,GAAG,QAAQ,CAAC,KAAK,CAAC,EAAE,GAAG,IAAI,CAAC,GAAG,CAAC,WAAW,CAAC,CAAC;IAE7D,MAAM,SAAS,GAAG,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,UAAU,EAAE,KAAK,EAAE,kBAAkB,EAAE,WAAW,CAAC,CAAC;IAEpF,IAAI,CAAC,SAAS,EAAE,CAAC;QACf,MAAM,IAAI,KAAK,CAAC,sDAAsD,CAAC,CAAC;IAC1E,CAAC;IAED,IAAI,SAAS,CAAC,MAAM,KAAK,EAAE,EAAE,CAAC;QAC5B,MAAM,IAAI,KAAK,CAAC,kCAAkC,CAAC,CAAC;IACtD,CAAC;IAED,OAAO,SAAS,CAAC;AACnB,CAAC;AAED,+EAA+E;AAC/E,yBAAyB;AACzB,+EAA+E;AAE/E;;GAEG;AACH,MAAM,UAAU,IAAI,CAAC,OAAe,EAAE,SAAqB;IACzD,MAAM,YAAY,GAAG,UAAU,CAAC,OAAO,CAAC,CAAC;IACzC,MAAM,SAAS,GAAG,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,YAAY,EAAE,SAAS,CAAC,CAAC;IAC9D,OAAO,YAAY,CAAC,SAAS,CAAC,CAAC;AACjC,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,MAAM,CACpB,OAAe,EACf,SAAiB,EACjB,SAAqB;IAErB,MAAM,YAAY,GAAG,UAAU,CAAC,OAAO,CAAC,CAAC;IACzC,MAAM,cAAc,GAAG,YAAY,CAAC,SAAS,CAAC,CAAC;IAC/C,OAAO,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,YAAY,EAAE,cAAc,EAAE,SAAS,CAAC,CAAC;AAC5E,CAAC;AAED,+EAA+E;AAC/E,uBAAuB;AACvB,+EAA+E;AAE/E,4DAA4D;AAC5D,6CAA6C;AAC7C,gDAAgD;AAChD,MAAM,2BAA2B,GAAG,8CAA8C,CAAC;AAEnF,MAAM,UAAU,qBAAqB;IACnC,OAAO,YAAY,CAAC,2BAA2B,CAAC,CAAC;AACnD,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,aAAa,CAAC,OAAgB;IAC5C,MAAM,OAAO,GAAG,GAAG,OAAO,CAAC,OAAO,IAAI,OAAO,CAAC,SAAS,IAAI,OAAO,CAAC,QAAQ,IAAI,OAAO,CAAC,IAAI,EAAE,CAAC;IAC9F,OAAO,MAAM,CAAC,OAAO,EAAE,OAAO,CAAC,SAAS,EAAE,qBAAqB,EAAE,CAAC,CAAC;AACrE,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,aAAa,CAC3B,aAAqB,EACrB,gBAA4B;IAE5B,MAAM,OAAO,GAA+B;QAC1C,OAAO,EAAE,CAAC;QACV,SAAS,EAAE,aAAa;QACxB,QAAQ,EAAE,IAAI,CAAC,GAAG,EAAE;QACpB,IAAI,EAAE,KAAK;KACZ,CAAC;IAEF,MAAM,OAAO,GAAG,GAAG,OAAO,CAAC,OAAO,IAAI,OAAO,CAAC,SAAS,IAAI,OAAO,CAAC,QAAQ,IAAI,OAAO,CAAC,IAAI,EAAE,CAAC;IAC9F,MAAM,SAAS,GAAG,IAAI,CAAC,OAAO,EAAE,gBAAgB,CAAC,CAAC;IAElD,OAAO;QACL,GAAG,OAAO;QACV,SAAS;KACV,CAAC;AACJ,CAAC;AAED,+EAA+E;AAC/E,oBAAoB;AACpB,+EAA+E;AAE/E;;;GAGG;AACH,MAAM,UAAU,eAAe,CAC7B,eAAuB,EACvB,gBAA4B;IAE5B,MAAM,OAAO,GAAG,WAAW,eAAe,EAAE,CAAC;IAC7C,MAAM,SAAS,GAAG,IAAI,CAAC,OAAO,EAAE,gBAAgB,CAAC,CAAC;IAClD,OAAO;QACL,IAAI,EAAE,SAAS;QACf,YAAY,EAAE,eAAe;QAC7B,SAAS;KACV,CAAC;AACJ,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,eAAe,CAC7B,SAAoB,EACpB,gBAA4B;IAE5B,MAAM,OAAO,GAAG,WAAW,SAAS,CAAC,YAAY,EAAE,CAAC;IACpD,OAAO,MAAM,CAAC,OAAO,EAAE,SAAS,CAAC,SAAS,EAAE,gBAAgB,CAAC,CAAC;AAChE,CAAC;AAED,+EAA+E;AAC/E,uBAAuB;AACvB,+EAA+E;AAE/E;;;;;;GAMG;AACH,MAAM,UAAU,eAAe,CAC7B,SAAiB,EACjB,kBAA8B;IAE9B,MAAM,IAAI,GAAG,UAAU,CAAC,SAAS,CAAC,CAAC;IAEnC,MAAM,SAAS,GAAG,IAAI,CAAC,GAAG,CAAC,OAAO,EAAE,CAAC;IACrC,MAAM,KAAK,GAAG,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,GAAG,CAAC,WAAW,CAAC,CAAC;IAErD,MAAM,SAAS,GAAG,IAAI,CAAC,GAAG,CAAC,IAAI,EAAE,KAAK,EAAE,kBAAkB,EAAE,SAAS,CAAC,SAAS,CAAC,CAAC;IAEjF,IAAI,CAAC,SAAS,EAAE,CAAC;QACf,MAAM,IAAI,KAAK,CAAC,6BAA6B,CAAC,CAAC;IACjD,CAAC;IAED,MAAM,QAAQ,GAAG,IAAI,UAAU,CAC7B,SAAS,CAAC,SAAS,CAAC,MAAM,GAAG,KAAK,CAAC,MAAM,GAAG,SAAS,CAAC,MAAM,CAC7D,CAAC;IACF,QAAQ,CAAC,GAAG,CAAC,SAAS,CAAC,SAAS,CAAC,CAAC;IAClC,QAAQ,CAAC,GAAG,CAAC,KAAK,EAAE,SAAS,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC;IAChD,QAAQ,CAAC,GAAG,CAAC,SAAS,EAAE,SAAS,CAAC,SAAS,CAAC,MAAM,GAAG,KAAK,CAAC,MAAM,CAAC,CAAC;IAEnE,OAAO,YAAY,CAAC,QAAQ,CAAC,CAAC;AAChC,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,eAAe,CAC7B,SAAiB,EACjB,WAAuB;IAEvB,MAAM,QAAQ,GAAG,YAAY,CAAC,SAAS,CAAC,CAAC;IAEzC,MAAM,kBAAkB,GAAG,QAAQ,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;IACjD,MAAM,KAAK,GAAG,QAAQ,CAAC,KAAK,CAAC,EAAE,EAAE,EAAE,GAAG,IAAI,CAAC,GAAG,CAAC,WAAW,CAAC,CAAC;IAC5D,MAAM,UAAU,GAAG,QAAQ,CAAC,KAAK,CAAC,EAAE,GAAG,IAAI,CAAC,GAAG,CAAC,WAAW,CAAC,CAAC;IAE7D,MAAM,SAAS,GAAG,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,UAAU,EAAE,KAAK,EAAE,kBAAkB,EAAE,WAAW,CAAC,CAAC;IAEpF,IAAI,CAAC,SAAS,EAAE,CAAC;QACf,MAAM,IAAI,KAAK,CAAC,4DAA4D,CAAC,CAAC;IAChF,CAAC;IAED,OAAO,UAAU,CAAC,SAAS,CAAC,CAAC;AAC/B,CAAC;AAED,+EAA+E;AAC/E,oBAAoB;AACpB,+EAA+E;AAE/E;;GAEG;AACH,MAAM,UAAU,aAAa,CAAC,OAAgB;IAC5C,OAAO;QACL,SAAS,EAAE,YAAY,CAAC,OAAO,CAAC,SAAS,CAAC;QAC1C,SAAS,EAAE,YAAY,CAAC,OAAO,CAAC,SAAS,CAAC;KAC3C,CAAC;AACJ,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,aAAa,CAAC,OAAiD;IAC7E,OAAO;QACL,SAAS,EAAE,YAAY,CAAC,OAAO,CAAC,SAAS,CAAC;QAC1C,SAAS,EAAE,YAAY,CAAC,OAAO,CAAC,SAAS,CAAC;KAC3C,CAAC;AACJ,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,eAAe;IAC7B,MAAM,KAAK,GAAG,IAAI,CAAC,WAAW,CAAC,EAAE,CAAC,CAAC;IACnC,OAAO,YAAY,CAAC,KAAK,CAAC;SACvB,OAAO,CAAC,KAAK,EAAE,GAAG,CAAC;SACnB,OAAO,CAAC,KAAK,EAAE,GAAG,CAAC;SACnB,OAAO,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC;AACvB,CAAC;AAED,+BAA+B;AAC/B,OAAO,EAAE,YAAY,EAAE,YAAY,EAAE,UAAU,EAAE,UAAU,EAAE,CAAC"}
1
+ {"version":3,"file":"crypto.js","sourceRoot":"","sources":["../src/crypto.ts"],"names":[],"mappings":"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"}
@@ -1,6 +1,6 @@
1
1
  import { describe, it, expect } from 'vitest';
2
2
  import nacl from 'tweetnacl';
3
- import { generateKeyPair, generateSigningKeyPair, encrypt, decrypt, deriveSharedSecret, encryptWithSharedSecret, decryptWithSharedSecret, generateSessionDEK, encryptDEK, decryptDEK, sign, verify, encodeKeyPair, decodeKeyPair, generateAgentId, encodeBase64, decodeBase64, createTombstone, verifyTombstone, encryptSyncBlob, decryptSyncBlob, } from './crypto.js';
3
+ import { generateKeyPair, generateSigningKeyPair, encrypt, decrypt, deriveSharedSecret, encryptWithSharedSecret, decryptWithSharedSecret, generateSessionDEK, encryptDEK, decryptDEK, sign, verify, encodeKeyPair, decodeKeyPair, generateAgentId, isValidBase64Key, encodeBase64, decodeBase64, createTombstone, verifyTombstone, encryptSyncBlob, decryptSyncBlob, SAS_ALPHABET, deriveSharedKeys, sasEncode, sasBucket, sasCompute, } from './crypto.js';
4
4
  describe('Key Generation', () => {
5
5
  it('should generate valid encryption key pair', () => {
6
6
  const keyPair = generateKeyPair();
@@ -236,6 +236,36 @@ describe('Agent ID Generation', () => {
236
236
  expect(ids.size).toBe(100);
237
237
  });
238
238
  });
239
+ describe('isValidBase64Key', () => {
240
+ it('accepts a 32-byte standard base64 key', () => {
241
+ const pk = encodeBase64(nacl.randomBytes(32));
242
+ expect(isValidBase64Key(pk)).toBe(true);
243
+ });
244
+ it('rejects wrong byte length', () => {
245
+ const sixteen = encodeBase64(nacl.randomBytes(16));
246
+ expect(isValidBase64Key(sixteen)).toBe(false);
247
+ expect(isValidBase64Key(sixteen, 16)).toBe(true);
248
+ });
249
+ it('rejects empty string', () => {
250
+ expect(isValidBase64Key('')).toBe(false);
251
+ });
252
+ it('rejects non-string input', () => {
253
+ expect(isValidBase64Key(null)).toBe(false);
254
+ expect(isValidBase64Key(undefined)).toBe(false);
255
+ expect(isValidBase64Key(42)).toBe(false);
256
+ expect(isValidBase64Key({})).toBe(false);
257
+ });
258
+ it('rejects base64url (agentId-style) input', () => {
259
+ // generateAgentId uses URL-safe alphabet + no padding; tweetnacl-util
260
+ // only accepts standard base64, so these must be rejected.
261
+ expect(isValidBase64Key('FTjVcBEtjSGurpvw34_oWw')).toBe(false);
262
+ expect(isValidBase64Key(generateAgentId())).toBe(false);
263
+ });
264
+ it('rejects garbage strings', () => {
265
+ expect(isValidBase64Key('not base64!')).toBe(false);
266
+ expect(isValidBase64Key('###')).toBe(false);
267
+ });
268
+ });
239
269
  describe('Base64 Encoding Utilities', () => {
240
270
  it('should encode and decode bytes correctly', () => {
241
271
  const original = new Uint8Array([1, 2, 3, 4, 5, 255, 0, 128]);
@@ -283,4 +313,225 @@ describe('sync blob encryption', () => {
283
313
  expect(() => decryptSyncBlob(encrypted, otherKeyPair.secretKey)).toThrow();
284
314
  });
285
315
  });
316
+ describe('SAS_ALPHABET', () => {
317
+ it('should have exactly 32 characters', () => {
318
+ expect(SAS_ALPHABET.length).toBe(32);
319
+ });
320
+ it('should not contain the ambiguous characters 0, 1, I, O', () => {
321
+ expect(SAS_ALPHABET).not.toContain('0');
322
+ expect(SAS_ALPHABET).not.toContain('1');
323
+ expect(SAS_ALPHABET).not.toContain('I');
324
+ expect(SAS_ALPHABET).not.toContain('O');
325
+ });
326
+ it('should only contain characters from the set 23456789A-HJ-NP-Z', () => {
327
+ expect(SAS_ALPHABET).toMatch(/^[23456789A-HJ-NP-Z]+$/);
328
+ });
329
+ it('should contain all distinct characters', () => {
330
+ const uniqueChars = new Set(SAS_ALPHABET.split(''));
331
+ expect(uniqueChars.size).toBe(SAS_ALPHABET.length);
332
+ });
333
+ });
334
+ describe('deriveSharedKeys', () => {
335
+ it('should be deterministic: same secret produces same pubkeys', () => {
336
+ const secret = new Uint8Array(32);
337
+ for (let i = 0; i < 32; i++)
338
+ secret[i] = i;
339
+ const a = deriveSharedKeys(secret);
340
+ const b = deriveSharedKeys(secret);
341
+ expect(encodeBase64(a.x25519.publicKey)).toBe(encodeBase64(b.x25519.publicKey));
342
+ expect(encodeBase64(a.x25519.secretKey)).toBe(encodeBase64(b.x25519.secretKey));
343
+ expect(encodeBase64(a.ed25519.publicKey)).toBe(encodeBase64(b.ed25519.publicKey));
344
+ expect(encodeBase64(a.ed25519.secretKey)).toBe(encodeBase64(b.ed25519.secretKey));
345
+ });
346
+ it('should produce different pubkeys for different secrets', () => {
347
+ const s1 = nacl.randomBytes(32);
348
+ const s2 = nacl.randomBytes(32);
349
+ const a = deriveSharedKeys(s1);
350
+ const b = deriveSharedKeys(s2);
351
+ expect(encodeBase64(a.x25519.publicKey)).not.toBe(encodeBase64(b.x25519.publicKey));
352
+ expect(encodeBase64(a.ed25519.publicKey)).not.toBe(encodeBase64(b.ed25519.publicKey));
353
+ });
354
+ it('should return keys with the correct lengths', () => {
355
+ const secret = nacl.randomBytes(32);
356
+ const derived = deriveSharedKeys(secret);
357
+ expect(derived.x25519.publicKey).toBeInstanceOf(Uint8Array);
358
+ expect(derived.x25519.secretKey).toBeInstanceOf(Uint8Array);
359
+ expect(derived.ed25519.publicKey).toBeInstanceOf(Uint8Array);
360
+ expect(derived.ed25519.secretKey).toBeInstanceOf(Uint8Array);
361
+ expect(derived.x25519.publicKey.length).toBe(32);
362
+ expect(derived.x25519.secretKey.length).toBe(32);
363
+ expect(derived.ed25519.publicKey.length).toBe(32);
364
+ expect(derived.ed25519.secretKey.length).toBe(64);
365
+ });
366
+ it('should produce usable x25519 keypair (sync-blob roundtrip)', () => {
367
+ const secret = nacl.randomBytes(32);
368
+ const { x25519 } = deriveSharedKeys(secret);
369
+ const plaintext = 'hello derived world';
370
+ const encrypted = encryptSyncBlob(plaintext, x25519.publicKey);
371
+ const decrypted = decryptSyncBlob(encrypted, x25519.secretKey);
372
+ expect(decrypted).toBe(plaintext);
373
+ });
374
+ it('should produce usable ed25519 keypair (sign/verify)', () => {
375
+ const secret = nacl.randomBytes(32);
376
+ const { ed25519 } = deriveSharedKeys(secret);
377
+ const message = 'sign me';
378
+ const signature = sign(message, ed25519.secretKey);
379
+ expect(verify(message, signature, ed25519.publicKey)).toBe(true);
380
+ });
381
+ it('should throw for a 0-byte master secret', () => {
382
+ expect(() => deriveSharedKeys(new Uint8Array(0))).toThrow();
383
+ });
384
+ it('should throw for a 16-byte master secret', () => {
385
+ expect(() => deriveSharedKeys(new Uint8Array(16))).toThrow();
386
+ });
387
+ it('should throw for a 33-byte master secret', () => {
388
+ expect(() => deriveSharedKeys(new Uint8Array(33))).toThrow();
389
+ });
390
+ it('should throw for a 64-byte master secret', () => {
391
+ expect(() => deriveSharedKeys(new Uint8Array(64))).toThrow();
392
+ });
393
+ it('should domain-separate x25519 and ed25519 seeds', () => {
394
+ const secret = nacl.randomBytes(32);
395
+ const derived = deriveSharedKeys(secret);
396
+ expect(encodeBase64(derived.x25519.publicKey)).not.toBe(encodeBase64(derived.ed25519.publicKey));
397
+ });
398
+ });
399
+ describe('sasEncode', () => {
400
+ it('should return exactly `chars` characters', () => {
401
+ const buf = nacl.randomBytes(16);
402
+ expect(sasEncode(buf, 6).length).toBe(6);
403
+ expect(sasEncode(buf, 4).length).toBe(4);
404
+ expect(sasEncode(buf, 8).length).toBe(8);
405
+ });
406
+ it('should produce output with only alphabet characters', () => {
407
+ const buf = nacl.randomBytes(16);
408
+ const out = sasEncode(buf, 6);
409
+ for (const ch of out) {
410
+ expect(SAS_ALPHABET).toContain(ch);
411
+ }
412
+ });
413
+ it('should be deterministic', () => {
414
+ const buf = new Uint8Array([1, 2, 3, 4, 5, 6, 7, 8, 9, 10]);
415
+ expect(sasEncode(buf, 6)).toBe(sasEncode(buf, 6));
416
+ expect(sasEncode(buf, 4)).toBe(sasEncode(buf, 4));
417
+ });
418
+ it('should encode all-zero input to the first alphabet char repeated', () => {
419
+ const buf = new Uint8Array([0x00, 0x00, 0x00, 0x00]);
420
+ const result = sasEncode(buf, 6);
421
+ expect(result).toBe('222222');
422
+ expect(SAS_ALPHABET[0]).toBe('2');
423
+ });
424
+ it('should encode all-0xff input to the last alphabet char repeated', () => {
425
+ const buf = new Uint8Array([0xff, 0xff, 0xff, 0xff]);
426
+ const result = sasEncode(buf, 6);
427
+ const last = SAS_ALPHABET[SAS_ALPHABET.length - 1];
428
+ expect(result).toBe(last.repeat(6));
429
+ });
430
+ it('should throw when chars is 0', () => {
431
+ const buf = nacl.randomBytes(16);
432
+ expect(() => sasEncode(buf, 0)).toThrow();
433
+ });
434
+ it('should throw when chars is negative', () => {
435
+ const buf = nacl.randomBytes(16);
436
+ expect(() => sasEncode(buf, -1)).toThrow();
437
+ });
438
+ it('should throw when chars is not an integer', () => {
439
+ const buf = nacl.randomBytes(16);
440
+ expect(() => sasEncode(buf, 2.5)).toThrow();
441
+ });
442
+ it('should throw when hmacOutput is too short for requested chars', () => {
443
+ // 6 chars need ceil(30/8) = 4 bytes; supply only 3
444
+ expect(() => sasEncode(new Uint8Array(3), 6)).toThrow();
445
+ });
446
+ });
447
+ describe('sasBucket', () => {
448
+ it('should return 0 for now=0', () => {
449
+ expect(sasBucket(0)).toBe(0);
450
+ });
451
+ it('should return 0 for now=59_999 (within first 60s bucket)', () => {
452
+ expect(sasBucket(59_999)).toBe(0);
453
+ });
454
+ it('should return 1 for now=60_000', () => {
455
+ expect(sasBucket(60_000)).toBe(1);
456
+ });
457
+ it('should return 2 for now=120_000', () => {
458
+ expect(sasBucket(120_000)).toBe(2);
459
+ });
460
+ it('should honor custom windowMs (60_000 @ 30_000 => 2)', () => {
461
+ expect(sasBucket(60_000, 30_000)).toBe(2);
462
+ });
463
+ it('should honor custom windowMs (59_999 @ 30_000 => 1)', () => {
464
+ expect(sasBucket(59_999, 30_000)).toBe(1);
465
+ });
466
+ it('should throw when now is negative', () => {
467
+ expect(() => sasBucket(-1)).toThrow();
468
+ });
469
+ it('should throw when windowMs is 0', () => {
470
+ expect(() => sasBucket(60_000, 0)).toThrow();
471
+ });
472
+ it('should throw when windowMs is negative', () => {
473
+ expect(() => sasBucket(60_000, -1)).toThrow();
474
+ });
475
+ it('should throw when now is NaN', () => {
476
+ expect(() => sasBucket(Number.NaN)).toThrow();
477
+ });
478
+ it('should throw when now is Infinity', () => {
479
+ expect(() => sasBucket(Number.POSITIVE_INFINITY)).toThrow();
480
+ });
481
+ });
482
+ describe('sasCompute', () => {
483
+ it('should return 6 characters by default from SAS_ALPHABET', () => {
484
+ const pubkey = nacl.randomBytes(32);
485
+ const result = sasCompute(pubkey, 0);
486
+ expect(result.length).toBe(6);
487
+ for (const ch of result) {
488
+ expect(SAS_ALPHABET).toContain(ch);
489
+ }
490
+ });
491
+ it('should be deterministic for same (pubkey, bucket, chars)', () => {
492
+ const pubkey = nacl.randomBytes(32);
493
+ const a = sasCompute(pubkey, 42);
494
+ const b = sasCompute(pubkey, 42);
495
+ expect(a).toBe(b);
496
+ const c = sasCompute(pubkey, 42, 8);
497
+ const d = sasCompute(pubkey, 42, 8);
498
+ expect(c).toBe(d);
499
+ });
500
+ it('should (very likely) produce different output for adjacent buckets', () => {
501
+ const pubkey = nacl.randomBytes(32);
502
+ expect(sasCompute(pubkey, 100)).not.toBe(sasCompute(pubkey, 101));
503
+ });
504
+ it('should (very likely) produce different output for different pubkeys', () => {
505
+ const pk1 = nacl.randomBytes(32);
506
+ const pk2 = nacl.randomBytes(32);
507
+ expect(sasCompute(pk1, 0)).not.toBe(sasCompute(pk2, 0));
508
+ });
509
+ it('should respect custom chars=4', () => {
510
+ const pubkey = nacl.randomBytes(32);
511
+ const result = sasCompute(pubkey, 0, 4);
512
+ expect(result.length).toBe(4);
513
+ for (const ch of result) {
514
+ expect(SAS_ALPHABET).toContain(ch);
515
+ }
516
+ });
517
+ it('should respect custom chars=8', () => {
518
+ const pubkey = nacl.randomBytes(32);
519
+ const result = sasCompute(pubkey, 0, 8);
520
+ expect(result.length).toBe(8);
521
+ for (const ch of result) {
522
+ expect(SAS_ALPHABET).toContain(ch);
523
+ }
524
+ });
525
+ it('should throw when pubkey is empty', () => {
526
+ expect(() => sasCompute(new Uint8Array(0), 0)).toThrow();
527
+ });
528
+ it('should throw when bucket is negative', () => {
529
+ const pubkey = nacl.randomBytes(32);
530
+ expect(() => sasCompute(pubkey, -1)).toThrow();
531
+ });
532
+ it('should throw when bucket is non-integer', () => {
533
+ const pubkey = nacl.randomBytes(32);
534
+ expect(() => sasCompute(pubkey, 1.5)).toThrow();
535
+ });
536
+ });
286
537
  //# sourceMappingURL=crypto.test.js.map