@fgv/ts-extras 5.1.0-24 → 5.1.0-26

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 (38) hide show
  1. package/dist/packlets/crypto-utils/index.browser.js +2 -0
  2. package/dist/packlets/crypto-utils/index.browser.js.map +1 -1
  3. package/dist/packlets/crypto-utils/index.js +2 -0
  4. package/dist/packlets/crypto-utils/index.js.map +1 -1
  5. package/dist/packlets/crypto-utils/keyPairAlgorithmParams.js +8 -0
  6. package/dist/packlets/crypto-utils/keyPairAlgorithmParams.js.map +1 -1
  7. package/dist/packlets/crypto-utils/model.js +2 -1
  8. package/dist/packlets/crypto-utils/model.js.map +1 -1
  9. package/dist/packlets/crypto-utils/nodeCryptoProvider.js +25 -0
  10. package/dist/packlets/crypto-utils/nodeCryptoProvider.js.map +1 -1
  11. package/dist/packlets/crypto-utils/spkiHelpers.js +130 -0
  12. package/dist/packlets/crypto-utils/spkiHelpers.js.map +1 -0
  13. package/dist/ts-extras.d.ts +100 -7
  14. package/lib/packlets/crypto-utils/index.browser.d.ts +1 -0
  15. package/lib/packlets/crypto-utils/index.browser.d.ts.map +1 -1
  16. package/lib/packlets/crypto-utils/index.browser.js +7 -1
  17. package/lib/packlets/crypto-utils/index.browser.js.map +1 -1
  18. package/lib/packlets/crypto-utils/index.d.ts +1 -0
  19. package/lib/packlets/crypto-utils/index.d.ts.map +1 -1
  20. package/lib/packlets/crypto-utils/index.js +7 -1
  21. package/lib/packlets/crypto-utils/index.js.map +1 -1
  22. package/lib/packlets/crypto-utils/keyPairAlgorithmParams.d.ts +10 -6
  23. package/lib/packlets/crypto-utils/keyPairAlgorithmParams.d.ts.map +1 -1
  24. package/lib/packlets/crypto-utils/keyPairAlgorithmParams.js +8 -0
  25. package/lib/packlets/crypto-utils/keyPairAlgorithmParams.js.map +1 -1
  26. package/lib/packlets/crypto-utils/model.d.ts +19 -1
  27. package/lib/packlets/crypto-utils/model.d.ts.map +1 -1
  28. package/lib/packlets/crypto-utils/model.js +2 -1
  29. package/lib/packlets/crypto-utils/model.js.map +1 -1
  30. package/lib/packlets/crypto-utils/nodeCryptoProvider.d.ts +13 -0
  31. package/lib/packlets/crypto-utils/nodeCryptoProvider.d.ts.map +1 -1
  32. package/lib/packlets/crypto-utils/nodeCryptoProvider.js +25 -0
  33. package/lib/packlets/crypto-utils/nodeCryptoProvider.js.map +1 -1
  34. package/lib/packlets/crypto-utils/spkiHelpers.d.ts +53 -0
  35. package/lib/packlets/crypto-utils/spkiHelpers.d.ts.map +1 -0
  36. package/lib/packlets/crypto-utils/spkiHelpers.js +136 -0
  37. package/lib/packlets/crypto-utils/spkiHelpers.js.map +1 -0
  38. package/package.json +7 -7
@@ -507,6 +507,10 @@ declare namespace CryptoUtils {
507
507
  ICreateEncryptedFileParams,
508
508
  toBase64,
509
509
  tryDecryptFile,
510
+ exportPublicKeyAsMultibaseSpki,
511
+ importPublicKeyFromMultibaseSpki,
512
+ multibaseBase64UrlDecode,
513
+ multibaseBase64UrlEncode,
510
514
  isEncryptedFile,
511
515
  EncryptionAlgorithm,
512
516
  EncryptedFileFormat,
@@ -713,6 +717,20 @@ declare namespace Experimental {
713
717
  }
714
718
  export { Experimental }
715
719
 
720
+ /**
721
+ * Exports a public `CryptoKey` as a multibase base64url-encoded SPKI blob.
722
+ *
723
+ * The SPKI (SubjectPublicKeyInfo) format is the standard DER-encoded structure
724
+ * for public keys defined in RFC 5280, RFC 5480, and RFC 8410. It is
725
+ * algorithm-agnostic and suitable for storage and transmission.
726
+ *
727
+ * @param key - The `CryptoKey` to export. Must have `key.type === 'public'`.
728
+ * @param provider - The {@link CryptoUtils.ICryptoProvider} to use for the export operation.
729
+ * @returns `Success` with the multibase SPKI string, or `Failure` with error context.
730
+ * @public
731
+ */
732
+ declare function exportPublicKeyAsMultibaseSpki(key: CryptoKey, provider: ICryptoProvider): Promise<Result<string>>;
733
+
716
734
  /**
717
735
  * An experimental array template which extend built-in `Array` to include a handful
718
736
  * of predicates which return `Result<T>`.
@@ -1667,6 +1685,20 @@ declare interface ICryptoProvider {
1667
1685
  * @returns Success with the imported public `CryptoKey`, or Failure with error context.
1668
1686
  */
1669
1687
  importPublicKeyJwk(jwk: JsonWebKey, algorithm: KeyPairAlgorithm): Promise<Result<CryptoKey>>;
1688
+ /**
1689
+ * Exports a public `CryptoKey` as a DER-encoded SPKI (SubjectPublicKeyInfo) blob.
1690
+ * SPKI is the standard algorithm-agnostic format for public key storage and transport.
1691
+ * @param publicKey - The `CryptoKey` to export. Must have `key.type === 'public'`.
1692
+ * @returns `Success` with the raw SPKI bytes, or `Failure` with error context.
1693
+ */
1694
+ exportPublicKeySpki(publicKey: CryptoKey): Promise<Result<Uint8Array>>;
1695
+ /**
1696
+ * Imports a public key from a DER-encoded SPKI blob.
1697
+ * @param spkiBytes - The raw SPKI bytes produced by {@link CryptoUtils.ICryptoProvider.exportPublicKeySpki | exportPublicKeySpki}.
1698
+ * @param algorithm - The {@link CryptoUtils.KeyPairAlgorithm | algorithm} the key was generated for.
1699
+ * @returns `Success` with the imported public `CryptoKey`, or `Failure` with error context.
1700
+ */
1701
+ importPublicKeySpki(spkiBytes: Uint8Array, algorithm: KeyPairAlgorithm): Promise<Result<CryptoKey>>;
1670
1702
  /**
1671
1703
  * Wraps `plaintext` for delivery to the holder of the private key paired
1672
1704
  * with `recipientPublicKey`. Uses ECIES with ECDH P-256, HKDF-SHA256, and
@@ -1966,22 +1998,26 @@ declare interface IKeyPairAlgorithmParams {
1966
1998
  * Algorithm parameters for `crypto.subtle.generateKey`. Always an asymmetric
1967
1999
  * variant — these algorithms produce a `CryptoKeyPair`, not a single key.
1968
2000
  * The literal `{ name: 'Ed25519' }` member covers WebCrypto's Secure-Curves
1969
- * Ed25519 algorithm, which takes only a `name`; using a literal rather than
1970
- * the base `Algorithm` keeps the union closed to the algorithms this table
1971
- * supports.
2001
+ * Ed25519 algorithm; `{ name: 'X25519' }` covers the X25519 key-agreement
2002
+ * algorithm. Both take only a `name`; using literals rather than the base
2003
+ * `Algorithm` keeps the union closed to the algorithms this table supports.
1972
2004
  */
1973
2005
  readonly generateKey: RsaHashedKeyGenParams | EcKeyGenParams | {
1974
2006
  readonly name: 'Ed25519';
2007
+ } | {
2008
+ readonly name: 'X25519';
1975
2009
  };
1976
2010
  /**
1977
2011
  * Algorithm parameters for `crypto.subtle.importKey('jwk', ...)` when
1978
2012
  * importing the public half of a keypair. The literal `{ name: 'Ed25519' }`
1979
- * member covers Ed25519 imports, which take only a `name`; using a literal
1980
- * rather than the base `Algorithm` keeps the union closed to the algorithms
1981
- * this table supports.
2013
+ * member covers Ed25519 imports; `{ name: 'X25519' }` covers X25519 imports.
2014
+ * Both take only a `name`; using literals rather than the base `Algorithm`
2015
+ * keeps the union closed to the algorithms this table supports.
1982
2016
  */
1983
2017
  readonly importPublicKey: RsaHashedImportParams | EcKeyImportParams | {
1984
2018
  readonly name: 'Ed25519';
2019
+ } | {
2020
+ readonly name: 'X25519';
1985
2021
  };
1986
2022
  /**
1987
2023
  * Default key usages for the generated `CryptoKeyPair`. Both halves receive
@@ -2307,6 +2343,21 @@ declare interface IModelSpecMap {
2307
2343
  readonly [key: string]: ModelSpec;
2308
2344
  }
2309
2345
 
2346
+ /**
2347
+ * Imports a public key from a multibase base64url-encoded SPKI blob.
2348
+ *
2349
+ * Decodes the multibase prefix, decodes the base64url body, then uses
2350
+ * the provider to import the key with the algorithm parameters from
2351
+ * {@link CryptoUtils.keyPairAlgorithmParams}.
2352
+ *
2353
+ * @param encoded - A multibase SPKI string produced by {@link CryptoUtils.exportPublicKeyAsMultibaseSpki}.
2354
+ * @param algorithm - The {@link CryptoUtils.KeyPairAlgorithm} the key was generated for.
2355
+ * @param provider - The {@link CryptoUtils.ICryptoProvider} to use for the import operation.
2356
+ * @returns `Success` with the imported public `CryptoKey`, or `Failure` with error context.
2357
+ * @public
2358
+ */
2359
+ declare function importPublicKeyFromMultibaseSpki(encoded: string, algorithm: KeyPairAlgorithm, provider: ICryptoProvider): Promise<Result<CryptoKey>>;
2360
+
2310
2361
  /**
2311
2362
  * Options for template parsing and validation.
2312
2363
  * @public
@@ -2802,9 +2853,13 @@ declare const keyDerivationParams: Converter<IKeyDerivationParams>;
2802
2853
  * and message rather than sampled randomly, eliminating the random-nonce
2803
2854
  * reuse risk that ECDSA carries. Distinct from X25519 (key agreement over
2804
2855
  * the Montgomery form, Curve25519).
2856
+ * - `'x25519'`: Diffie-Hellman key agreement over the Montgomery form of
2857
+ * Curve25519. Key-agreement only — use `deriveBits`/`deriveKey` to produce
2858
+ * a shared secret from one party's private key and the peer's public key.
2859
+ * Distinct from Ed25519 (which uses the twisted-Edwards form for signing).
2805
2860
  * @public
2806
2861
  */
2807
- declare type KeyPairAlgorithm = 'ecdsa-p256' | 'rsa-oaep-2048' | 'ecdh-p256' | 'ed25519';
2862
+ declare type KeyPairAlgorithm = 'ecdsa-p256' | 'rsa-oaep-2048' | 'ecdh-p256' | 'ed25519' | 'x25519';
2808
2863
 
2809
2864
  /**
2810
2865
  * Converter for {@link CryptoUtils.KeyStore.KeyPairAlgorithm | key pair algorithm}.
@@ -3420,6 +3475,31 @@ declare type ModelSpecKey = 'base' | 'tools' | 'image';
3420
3475
  */
3421
3476
  declare const modelSpecKey: Converter<ModelSpecKey>;
3422
3477
 
3478
+ /**
3479
+ * Decodes a multibase base64url (no-padding) string back to a `Uint8Array`.
3480
+ *
3481
+ * Validates that the first character is `'m'` (the multibase prefix for
3482
+ * RFC 4648 base64url without padding), then decodes the remaining body.
3483
+ *
3484
+ * @param encoded - A multibase-prefixed base64url string.
3485
+ * @returns `Success` with the decoded bytes, or `Failure` with error context.
3486
+ * @public
3487
+ */
3488
+ declare function multibaseBase64UrlDecode(encoded: string): Result<Uint8Array>;
3489
+
3490
+ /**
3491
+ * Encodes a `Uint8Array` as a multibase base64url (no-padding) string.
3492
+ *
3493
+ * The multibase prefix `'m'` identifies the encoding as RFC 4648 base64url
3494
+ * without padding. The body uses base64url alphabet: `+` → `-`, `/` → `_`,
3495
+ * and trailing `=` padding is stripped.
3496
+ *
3497
+ * @param data - The binary data to encode.
3498
+ * @returns A multibase-prefixed base64url string (`'m' + base64url-no-pad`).
3499
+ * @public
3500
+ */
3501
+ declare function multibaseBase64UrlEncode(data: Uint8Array): string;
3502
+
3423
3503
  declare namespace Mustache {
3424
3504
  export {
3425
3505
  IContextValidationResult,
@@ -3609,6 +3689,19 @@ declare class NodeCryptoProvider implements ICryptoProvider {
3609
3689
  * @returns `Success` with the imported public `CryptoKey`, or `Failure` with an error.
3610
3690
  */
3611
3691
  importPublicKeyJwk(jwk: JsonWebKey, algorithm: KeyPairAlgorithm): Promise<Result<CryptoKey>>;
3692
+ /**
3693
+ * Exports a public `CryptoKey` as a DER-encoded SPKI blob.
3694
+ * @param publicKey - The public `CryptoKey` to export.
3695
+ * @returns `Success` with the raw SPKI bytes, or `Failure` with error context.
3696
+ */
3697
+ exportPublicKeySpki(publicKey: CryptoKey): Promise<Result<Uint8Array>>;
3698
+ /**
3699
+ * Imports a public key from a DER-encoded SPKI blob.
3700
+ * @param spkiBytes - The raw SPKI bytes.
3701
+ * @param algorithm - The algorithm the key was generated for.
3702
+ * @returns `Success` with the imported public `CryptoKey`, or `Failure` with error context.
3703
+ */
3704
+ importPublicKeySpki(spkiBytes: Uint8Array, algorithm: KeyPairAlgorithm): Promise<Result<CryptoKey>>;
3612
3705
  /**
3613
3706
  * Wraps `plaintext` for the holder of `recipientPublicKey` using
3614
3707
  * ECIES (ECDH P-256 + HKDF-SHA256 + AES-GCM-256). See
@@ -12,4 +12,5 @@ export { Converters };
12
12
  export { DirectEncryptionProvider, IDirectEncryptionProviderParams } from './directEncryptionProvider';
13
13
  export { IKeyPairAlgorithmParams, keyPairAlgorithmParams } from './keyPairAlgorithmParams';
14
14
  export { createEncryptedFile, decryptFile, fromBase64, ICreateEncryptedFileParams, toBase64, tryDecryptFile } from './encryptedFile';
15
+ export { exportPublicKeyAsMultibaseSpki, importPublicKeyFromMultibaseSpki, multibaseBase64UrlDecode, multibaseBase64UrlEncode } from './spkiHelpers';
15
16
  //# sourceMappingURL=index.browser.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.browser.d.ts","sourceRoot":"","sources":["../../../src/packlets/crypto-utils/index.browser.ts"],"names":[],"mappings":"AAoBA;;;;GAIG;AAGH,cAAc,SAAS,CAAC;AAGxB,OAAO,EACL,gBAAgB,EAChB,iBAAiB,EACjB,qBAAqB,EACrB,iBAAiB,EACjB,WAAW,EACZ,MAAM,aAAa,CAAC;AAGrB,OAAO,KAAK,QAAQ,MAAM,YAAY,CAAC;AACvC,OAAO,EAAE,QAAQ,EAAE,CAAC;AAGpB,OAAO,KAAK,UAAU,MAAM,cAAc,CAAC;AAC3C,OAAO,EAAE,UAAU,EAAE,CAAC;AAGtB,OAAO,EAAE,wBAAwB,EAAE,+BAA+B,EAAE,MAAM,4BAA4B,CAAC;AAGvG,OAAO,EAAE,uBAAuB,EAAE,sBAAsB,EAAE,MAAM,0BAA0B,CAAC;AAM3F,OAAO,EACL,mBAAmB,EACnB,WAAW,EACX,UAAU,EACV,0BAA0B,EAC1B,QAAQ,EACR,cAAc,EACf,MAAM,iBAAiB,CAAC"}
1
+ {"version":3,"file":"index.browser.d.ts","sourceRoot":"","sources":["../../../src/packlets/crypto-utils/index.browser.ts"],"names":[],"mappings":"AAoBA;;;;GAIG;AAGH,cAAc,SAAS,CAAC;AAGxB,OAAO,EACL,gBAAgB,EAChB,iBAAiB,EACjB,qBAAqB,EACrB,iBAAiB,EACjB,WAAW,EACZ,MAAM,aAAa,CAAC;AAGrB,OAAO,KAAK,QAAQ,MAAM,YAAY,CAAC;AACvC,OAAO,EAAE,QAAQ,EAAE,CAAC;AAGpB,OAAO,KAAK,UAAU,MAAM,cAAc,CAAC;AAC3C,OAAO,EAAE,UAAU,EAAE,CAAC;AAGtB,OAAO,EAAE,wBAAwB,EAAE,+BAA+B,EAAE,MAAM,4BAA4B,CAAC;AAGvG,OAAO,EAAE,uBAAuB,EAAE,sBAAsB,EAAE,MAAM,0BAA0B,CAAC;AAM3F,OAAO,EACL,mBAAmB,EACnB,WAAW,EACX,UAAU,EACV,0BAA0B,EAC1B,QAAQ,EACR,cAAc,EACf,MAAM,iBAAiB,CAAC;AAGzB,OAAO,EACL,8BAA8B,EAC9B,gCAAgC,EAChC,wBAAwB,EACxB,wBAAwB,EACzB,MAAM,eAAe,CAAC"}
@@ -55,7 +55,7 @@ var __importStar = (this && this.__importStar) || (function () {
55
55
  };
56
56
  })();
57
57
  Object.defineProperty(exports, "__esModule", { value: true });
58
- exports.tryDecryptFile = exports.toBase64 = exports.fromBase64 = exports.decryptFile = exports.createEncryptedFile = exports.keyPairAlgorithmParams = exports.DirectEncryptionProvider = exports.Converters = exports.KeyStore = exports.GCM_IV_SIZE = exports.GCM_AUTH_TAG_SIZE = exports.ENCRYPTED_FILE_FORMAT = exports.DEFAULT_ALGORITHM = exports.AES_256_KEY_SIZE = void 0;
58
+ exports.multibaseBase64UrlEncode = exports.multibaseBase64UrlDecode = exports.importPublicKeyFromMultibaseSpki = exports.exportPublicKeyAsMultibaseSpki = exports.tryDecryptFile = exports.toBase64 = exports.fromBase64 = exports.decryptFile = exports.createEncryptedFile = exports.keyPairAlgorithmParams = exports.DirectEncryptionProvider = exports.Converters = exports.KeyStore = exports.GCM_IV_SIZE = exports.GCM_AUTH_TAG_SIZE = exports.ENCRYPTED_FILE_FORMAT = exports.DEFAULT_ALGORITHM = exports.AES_256_KEY_SIZE = void 0;
59
59
  /**
60
60
  * Crypto utilities for encrypted file handling and key management (browser version).
61
61
  * Note: For browser crypto provider, use \@fgv/ts-web-extras.
@@ -91,4 +91,10 @@ Object.defineProperty(exports, "decryptFile", { enumerable: true, get: function
91
91
  Object.defineProperty(exports, "fromBase64", { enumerable: true, get: function () { return encryptedFile_1.fromBase64; } });
92
92
  Object.defineProperty(exports, "toBase64", { enumerable: true, get: function () { return encryptedFile_1.toBase64; } });
93
93
  Object.defineProperty(exports, "tryDecryptFile", { enumerable: true, get: function () { return encryptedFile_1.tryDecryptFile; } });
94
+ // Multibase/SPKI helpers
95
+ var spkiHelpers_1 = require("./spkiHelpers");
96
+ Object.defineProperty(exports, "exportPublicKeyAsMultibaseSpki", { enumerable: true, get: function () { return spkiHelpers_1.exportPublicKeyAsMultibaseSpki; } });
97
+ Object.defineProperty(exports, "importPublicKeyFromMultibaseSpki", { enumerable: true, get: function () { return spkiHelpers_1.importPublicKeyFromMultibaseSpki; } });
98
+ Object.defineProperty(exports, "multibaseBase64UrlDecode", { enumerable: true, get: function () { return spkiHelpers_1.multibaseBase64UrlDecode; } });
99
+ Object.defineProperty(exports, "multibaseBase64UrlEncode", { enumerable: true, get: function () { return spkiHelpers_1.multibaseBase64UrlEncode; } });
94
100
  //# sourceMappingURL=index.browser.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.browser.js","sourceRoot":"","sources":["../../../src/packlets/crypto-utils/index.browser.ts"],"names":[],"mappings":";AAAA,kCAAkC;AAClC,EAAE;AACF,+EAA+E;AAC/E,gFAAgF;AAChF,+EAA+E;AAC/E,4EAA4E;AAC5E,wEAAwE;AACxE,2DAA2D;AAC3D,EAAE;AACF,iFAAiF;AACjF,kDAAkD;AAClD,EAAE;AACF,6EAA6E;AAC7E,2EAA2E;AAC3E,8EAA8E;AAC9E,yEAAyE;AACzE,gFAAgF;AAChF,gFAAgF;AAChF,YAAY;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAEZ;;;;GAIG;AAEH,iCAAiC;AACjC,0CAAwB;AAExB,YAAY;AACZ,yCAMqB;AALnB,6GAAA,gBAAgB,OAAA;AAChB,8GAAA,iBAAiB,OAAA;AACjB,kHAAA,qBAAqB,OAAA;AACrB,8GAAA,iBAAiB,OAAA;AACjB,wGAAA,WAAW,OAAA;AAGb,qBAAqB;AACrB,qDAAuC;AAC9B,4BAAQ;AAEjB,uBAAuB;AACvB,yDAA2C;AAClC,gCAAU;AAEnB,6BAA6B;AAC7B,uEAAuG;AAA9F,oIAAA,wBAAwB,OAAA;AAEjC,8DAA8D;AAC9D,mEAA2F;AAAzD,gIAAA,sBAAsB,OAAA;AAExD,8DAA8D;AAC9D,4DAA4D;AAE5D,yBAAyB;AACzB,iDAOyB;AANvB,oHAAA,mBAAmB,OAAA;AACnB,4GAAA,WAAW,OAAA;AACX,2GAAA,UAAU,OAAA;AAEV,yGAAA,QAAQ,OAAA;AACR,+GAAA,cAAc,OAAA","sourcesContent":["// Copyright (c) 2024 Erik Fortune\n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\n/**\n * Crypto utilities for encrypted file handling and key management (browser version).\n * Note: For browser crypto provider, use \\@fgv/ts-web-extras.\n * @packageDocumentation\n */\n\n// Re-export all types from model\nexport * from './model';\n\n// Constants\nexport {\n AES_256_KEY_SIZE,\n DEFAULT_ALGORITHM,\n ENCRYPTED_FILE_FORMAT,\n GCM_AUTH_TAG_SIZE,\n GCM_IV_SIZE\n} from './constants';\n\n// KeyStore namespace\nimport * as KeyStore from './keystore';\nexport { KeyStore };\n\n// Converters namespace\nimport * as Converters from './converters';\nexport { Converters };\n\n// Direct encryption provider\nexport { DirectEncryptionProvider, IDirectEncryptionProviderParams } from './directEncryptionProvider';\n\n// WebCrypto parameter table for asymmetric keypair algorithms\nexport { IKeyPairAlgorithmParams, keyPairAlgorithmParams } from './keyPairAlgorithmParams';\n\n// Note: NodeCryptoProvider is NOT exported in browser version\n// Use BrowserCryptoProvider from @fgv/ts-web-extras instead\n\n// Encrypted file helpers\nexport {\n createEncryptedFile,\n decryptFile,\n fromBase64,\n ICreateEncryptedFileParams,\n toBase64,\n tryDecryptFile\n} from './encryptedFile';\n"]}
1
+ {"version":3,"file":"index.browser.js","sourceRoot":"","sources":["../../../src/packlets/crypto-utils/index.browser.ts"],"names":[],"mappings":";AAAA,kCAAkC;AAClC,EAAE;AACF,+EAA+E;AAC/E,gFAAgF;AAChF,+EAA+E;AAC/E,4EAA4E;AAC5E,wEAAwE;AACxE,2DAA2D;AAC3D,EAAE;AACF,iFAAiF;AACjF,kDAAkD;AAClD,EAAE;AACF,6EAA6E;AAC7E,2EAA2E;AAC3E,8EAA8E;AAC9E,yEAAyE;AACzE,gFAAgF;AAChF,gFAAgF;AAChF,YAAY;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAEZ;;;;GAIG;AAEH,iCAAiC;AACjC,0CAAwB;AAExB,YAAY;AACZ,yCAMqB;AALnB,6GAAA,gBAAgB,OAAA;AAChB,8GAAA,iBAAiB,OAAA;AACjB,kHAAA,qBAAqB,OAAA;AACrB,8GAAA,iBAAiB,OAAA;AACjB,wGAAA,WAAW,OAAA;AAGb,qBAAqB;AACrB,qDAAuC;AAC9B,4BAAQ;AAEjB,uBAAuB;AACvB,yDAA2C;AAClC,gCAAU;AAEnB,6BAA6B;AAC7B,uEAAuG;AAA9F,oIAAA,wBAAwB,OAAA;AAEjC,8DAA8D;AAC9D,mEAA2F;AAAzD,gIAAA,sBAAsB,OAAA;AAExD,8DAA8D;AAC9D,4DAA4D;AAE5D,yBAAyB;AACzB,iDAOyB;AANvB,oHAAA,mBAAmB,OAAA;AACnB,4GAAA,WAAW,OAAA;AACX,2GAAA,UAAU,OAAA;AAEV,yGAAA,QAAQ,OAAA;AACR,+GAAA,cAAc,OAAA;AAGhB,yBAAyB;AACzB,6CAKuB;AAJrB,6HAAA,8BAA8B,OAAA;AAC9B,+HAAA,gCAAgC,OAAA;AAChC,uHAAA,wBAAwB,OAAA;AACxB,uHAAA,wBAAwB,OAAA","sourcesContent":["// Copyright (c) 2024 Erik Fortune\n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\n/**\n * Crypto utilities for encrypted file handling and key management (browser version).\n * Note: For browser crypto provider, use \\@fgv/ts-web-extras.\n * @packageDocumentation\n */\n\n// Re-export all types from model\nexport * from './model';\n\n// Constants\nexport {\n AES_256_KEY_SIZE,\n DEFAULT_ALGORITHM,\n ENCRYPTED_FILE_FORMAT,\n GCM_AUTH_TAG_SIZE,\n GCM_IV_SIZE\n} from './constants';\n\n// KeyStore namespace\nimport * as KeyStore from './keystore';\nexport { KeyStore };\n\n// Converters namespace\nimport * as Converters from './converters';\nexport { Converters };\n\n// Direct encryption provider\nexport { DirectEncryptionProvider, IDirectEncryptionProviderParams } from './directEncryptionProvider';\n\n// WebCrypto parameter table for asymmetric keypair algorithms\nexport { IKeyPairAlgorithmParams, keyPairAlgorithmParams } from './keyPairAlgorithmParams';\n\n// Note: NodeCryptoProvider is NOT exported in browser version\n// Use BrowserCryptoProvider from @fgv/ts-web-extras instead\n\n// Encrypted file helpers\nexport {\n createEncryptedFile,\n decryptFile,\n fromBase64,\n ICreateEncryptedFileParams,\n toBase64,\n tryDecryptFile\n} from './encryptedFile';\n\n// Multibase/SPKI helpers\nexport {\n exportPublicKeyAsMultibaseSpki,\n importPublicKeyFromMultibaseSpki,\n multibaseBase64UrlDecode,\n multibaseBase64UrlEncode\n} from './spkiHelpers';\n"]}
@@ -13,4 +13,5 @@ export { DirectEncryptionProvider, IDirectEncryptionProviderParams } from './dir
13
13
  export { IKeyPairAlgorithmParams, keyPairAlgorithmParams } from './keyPairAlgorithmParams';
14
14
  export { NodeCryptoProvider, nodeCryptoProvider } from './nodeCryptoProvider';
15
15
  export { createEncryptedFile, decryptFile, fromBase64, ICreateEncryptedFileParams, toBase64, tryDecryptFile } from './encryptedFile';
16
+ export { exportPublicKeyAsMultibaseSpki, importPublicKeyFromMultibaseSpki, multibaseBase64UrlDecode, multibaseBase64UrlEncode } from './spkiHelpers';
16
17
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/packlets/crypto-utils/index.ts"],"names":[],"mappings":"AAoBA;;;GAGG;AAGH,cAAc,SAAS,CAAC;AAGxB,OAAO,KAAK,SAAS,MAAM,aAAa,CAAC;AACzC,OAAO,EAAE,SAAS,EAAE,CAAC;AAGrB,OAAO,KAAK,QAAQ,MAAM,YAAY,CAAC;AACvC,OAAO,EAAE,QAAQ,EAAE,CAAC;AAGpB,OAAO,KAAK,UAAU,MAAM,cAAc,CAAC;AAC3C,OAAO,EAAE,UAAU,EAAE,CAAC;AAGtB,OAAO,EAAE,wBAAwB,EAAE,+BAA+B,EAAE,MAAM,4BAA4B,CAAC;AAGvG,OAAO,EAAE,uBAAuB,EAAE,sBAAsB,EAAE,MAAM,0BAA0B,CAAC;AAG3F,OAAO,EAAE,kBAAkB,EAAE,kBAAkB,EAAE,MAAM,sBAAsB,CAAC;AAG9E,OAAO,EACL,mBAAmB,EACnB,WAAW,EACX,UAAU,EACV,0BAA0B,EAC1B,QAAQ,EACR,cAAc,EACf,MAAM,iBAAiB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/packlets/crypto-utils/index.ts"],"names":[],"mappings":"AAoBA;;;GAGG;AAGH,cAAc,SAAS,CAAC;AAGxB,OAAO,KAAK,SAAS,MAAM,aAAa,CAAC;AACzC,OAAO,EAAE,SAAS,EAAE,CAAC;AAGrB,OAAO,KAAK,QAAQ,MAAM,YAAY,CAAC;AACvC,OAAO,EAAE,QAAQ,EAAE,CAAC;AAGpB,OAAO,KAAK,UAAU,MAAM,cAAc,CAAC;AAC3C,OAAO,EAAE,UAAU,EAAE,CAAC;AAGtB,OAAO,EAAE,wBAAwB,EAAE,+BAA+B,EAAE,MAAM,4BAA4B,CAAC;AAGvG,OAAO,EAAE,uBAAuB,EAAE,sBAAsB,EAAE,MAAM,0BAA0B,CAAC;AAG3F,OAAO,EAAE,kBAAkB,EAAE,kBAAkB,EAAE,MAAM,sBAAsB,CAAC;AAG9E,OAAO,EACL,mBAAmB,EACnB,WAAW,EACX,UAAU,EACV,0BAA0B,EAC1B,QAAQ,EACR,cAAc,EACf,MAAM,iBAAiB,CAAC;AAGzB,OAAO,EACL,8BAA8B,EAC9B,gCAAgC,EAChC,wBAAwB,EACxB,wBAAwB,EACzB,MAAM,eAAe,CAAC"}
@@ -55,7 +55,7 @@ var __importStar = (this && this.__importStar) || (function () {
55
55
  };
56
56
  })();
57
57
  Object.defineProperty(exports, "__esModule", { value: true });
58
- exports.tryDecryptFile = exports.toBase64 = exports.fromBase64 = exports.decryptFile = exports.createEncryptedFile = exports.nodeCryptoProvider = exports.NodeCryptoProvider = exports.keyPairAlgorithmParams = exports.DirectEncryptionProvider = exports.Converters = exports.KeyStore = exports.Constants = void 0;
58
+ exports.multibaseBase64UrlEncode = exports.multibaseBase64UrlDecode = exports.importPublicKeyFromMultibaseSpki = exports.exportPublicKeyAsMultibaseSpki = exports.tryDecryptFile = exports.toBase64 = exports.fromBase64 = exports.decryptFile = exports.createEncryptedFile = exports.nodeCryptoProvider = exports.NodeCryptoProvider = exports.keyPairAlgorithmParams = exports.DirectEncryptionProvider = exports.Converters = exports.KeyStore = exports.Constants = void 0;
59
59
  /**
60
60
  * Crypto utilities for encrypted file handling and key management.
61
61
  * @packageDocumentation
@@ -88,4 +88,10 @@ Object.defineProperty(exports, "decryptFile", { enumerable: true, get: function
88
88
  Object.defineProperty(exports, "fromBase64", { enumerable: true, get: function () { return encryptedFile_1.fromBase64; } });
89
89
  Object.defineProperty(exports, "toBase64", { enumerable: true, get: function () { return encryptedFile_1.toBase64; } });
90
90
  Object.defineProperty(exports, "tryDecryptFile", { enumerable: true, get: function () { return encryptedFile_1.tryDecryptFile; } });
91
+ // Multibase/SPKI helpers
92
+ var spkiHelpers_1 = require("./spkiHelpers");
93
+ Object.defineProperty(exports, "exportPublicKeyAsMultibaseSpki", { enumerable: true, get: function () { return spkiHelpers_1.exportPublicKeyAsMultibaseSpki; } });
94
+ Object.defineProperty(exports, "importPublicKeyFromMultibaseSpki", { enumerable: true, get: function () { return spkiHelpers_1.importPublicKeyFromMultibaseSpki; } });
95
+ Object.defineProperty(exports, "multibaseBase64UrlDecode", { enumerable: true, get: function () { return spkiHelpers_1.multibaseBase64UrlDecode; } });
96
+ Object.defineProperty(exports, "multibaseBase64UrlEncode", { enumerable: true, get: function () { return spkiHelpers_1.multibaseBase64UrlEncode; } });
91
97
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/packlets/crypto-utils/index.ts"],"names":[],"mappings":";AAAA,kCAAkC;AAClC,EAAE;AACF,+EAA+E;AAC/E,gFAAgF;AAChF,+EAA+E;AAC/E,4EAA4E;AAC5E,wEAAwE;AACxE,2DAA2D;AAC3D,EAAE;AACF,iFAAiF;AACjF,kDAAkD;AAClD,EAAE;AACF,6EAA6E;AAC7E,2EAA2E;AAC3E,8EAA8E;AAC9E,yEAAyE;AACzE,gFAAgF;AAChF,gFAAgF;AAChF,YAAY;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAEZ;;;GAGG;AAEH,iCAAiC;AACjC,0CAAwB;AAExB,YAAY;AACZ,uDAAyC;AAChC,8BAAS;AAElB,qBAAqB;AACrB,qDAAuC;AAC9B,4BAAQ;AAEjB,uBAAuB;AACvB,yDAA2C;AAClC,gCAAU;AAEnB,6BAA6B;AAC7B,uEAAuG;AAA9F,oIAAA,wBAAwB,OAAA;AAEjC,8DAA8D;AAC9D,mEAA2F;AAAzD,gIAAA,sBAAsB,OAAA;AAExD,qDAAqD;AACrD,2DAA8E;AAArE,wHAAA,kBAAkB,OAAA;AAAE,wHAAA,kBAAkB,OAAA;AAE/C,yBAAyB;AACzB,iDAOyB;AANvB,oHAAA,mBAAmB,OAAA;AACnB,4GAAA,WAAW,OAAA;AACX,2GAAA,UAAU,OAAA;AAEV,yGAAA,QAAQ,OAAA;AACR,+GAAA,cAAc,OAAA","sourcesContent":["// Copyright (c) 2024 Erik Fortune\n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\n/**\n * Crypto utilities for encrypted file handling and key management.\n * @packageDocumentation\n */\n\n// Re-export all types from model\nexport * from './model';\n\n// Constants\nimport * as Constants from './constants';\nexport { Constants };\n\n// KeyStore namespace\nimport * as KeyStore from './keystore';\nexport { KeyStore };\n\n// Converters namespace\nimport * as Converters from './converters';\nexport { Converters };\n\n// Direct encryption provider\nexport { DirectEncryptionProvider, IDirectEncryptionProviderParams } from './directEncryptionProvider';\n\n// WebCrypto parameter table for asymmetric keypair algorithms\nexport { IKeyPairAlgorithmParams, keyPairAlgorithmParams } from './keyPairAlgorithmParams';\n\n// Node.js crypto provider (Node.js environment only)\nexport { NodeCryptoProvider, nodeCryptoProvider } from './nodeCryptoProvider';\n\n// Encrypted file helpers\nexport {\n createEncryptedFile,\n decryptFile,\n fromBase64,\n ICreateEncryptedFileParams,\n toBase64,\n tryDecryptFile\n} from './encryptedFile';\n"]}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/packlets/crypto-utils/index.ts"],"names":[],"mappings":";AAAA,kCAAkC;AAClC,EAAE;AACF,+EAA+E;AAC/E,gFAAgF;AAChF,+EAA+E;AAC/E,4EAA4E;AAC5E,wEAAwE;AACxE,2DAA2D;AAC3D,EAAE;AACF,iFAAiF;AACjF,kDAAkD;AAClD,EAAE;AACF,6EAA6E;AAC7E,2EAA2E;AAC3E,8EAA8E;AAC9E,yEAAyE;AACzE,gFAAgF;AAChF,gFAAgF;AAChF,YAAY;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAEZ;;;GAGG;AAEH,iCAAiC;AACjC,0CAAwB;AAExB,YAAY;AACZ,uDAAyC;AAChC,8BAAS;AAElB,qBAAqB;AACrB,qDAAuC;AAC9B,4BAAQ;AAEjB,uBAAuB;AACvB,yDAA2C;AAClC,gCAAU;AAEnB,6BAA6B;AAC7B,uEAAuG;AAA9F,oIAAA,wBAAwB,OAAA;AAEjC,8DAA8D;AAC9D,mEAA2F;AAAzD,gIAAA,sBAAsB,OAAA;AAExD,qDAAqD;AACrD,2DAA8E;AAArE,wHAAA,kBAAkB,OAAA;AAAE,wHAAA,kBAAkB,OAAA;AAE/C,yBAAyB;AACzB,iDAOyB;AANvB,oHAAA,mBAAmB,OAAA;AACnB,4GAAA,WAAW,OAAA;AACX,2GAAA,UAAU,OAAA;AAEV,yGAAA,QAAQ,OAAA;AACR,+GAAA,cAAc,OAAA;AAGhB,yBAAyB;AACzB,6CAKuB;AAJrB,6HAAA,8BAA8B,OAAA;AAC9B,+HAAA,gCAAgC,OAAA;AAChC,uHAAA,wBAAwB,OAAA;AACxB,uHAAA,wBAAwB,OAAA","sourcesContent":["// Copyright (c) 2024 Erik Fortune\n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\n/**\n * Crypto utilities for encrypted file handling and key management.\n * @packageDocumentation\n */\n\n// Re-export all types from model\nexport * from './model';\n\n// Constants\nimport * as Constants from './constants';\nexport { Constants };\n\n// KeyStore namespace\nimport * as KeyStore from './keystore';\nexport { KeyStore };\n\n// Converters namespace\nimport * as Converters from './converters';\nexport { Converters };\n\n// Direct encryption provider\nexport { DirectEncryptionProvider, IDirectEncryptionProviderParams } from './directEncryptionProvider';\n\n// WebCrypto parameter table for asymmetric keypair algorithms\nexport { IKeyPairAlgorithmParams, keyPairAlgorithmParams } from './keyPairAlgorithmParams';\n\n// Node.js crypto provider (Node.js environment only)\nexport { NodeCryptoProvider, nodeCryptoProvider } from './nodeCryptoProvider';\n\n// Encrypted file helpers\nexport {\n createEncryptedFile,\n decryptFile,\n fromBase64,\n ICreateEncryptedFileParams,\n toBase64,\n tryDecryptFile\n} from './encryptedFile';\n\n// Multibase/SPKI helpers\nexport {\n exportPublicKeyAsMultibaseSpki,\n importPublicKeyFromMultibaseSpki,\n multibaseBase64UrlDecode,\n multibaseBase64UrlEncode\n} from './spkiHelpers';\n"]}
@@ -11,22 +11,26 @@ export interface IKeyPairAlgorithmParams {
11
11
  * Algorithm parameters for `crypto.subtle.generateKey`. Always an asymmetric
12
12
  * variant — these algorithms produce a `CryptoKeyPair`, not a single key.
13
13
  * The literal `{ name: 'Ed25519' }` member covers WebCrypto's Secure-Curves
14
- * Ed25519 algorithm, which takes only a `name`; using a literal rather than
15
- * the base `Algorithm` keeps the union closed to the algorithms this table
16
- * supports.
14
+ * Ed25519 algorithm; `{ name: 'X25519' }` covers the X25519 key-agreement
15
+ * algorithm. Both take only a `name`; using literals rather than the base
16
+ * `Algorithm` keeps the union closed to the algorithms this table supports.
17
17
  */
18
18
  readonly generateKey: RsaHashedKeyGenParams | EcKeyGenParams | {
19
19
  readonly name: 'Ed25519';
20
+ } | {
21
+ readonly name: 'X25519';
20
22
  };
21
23
  /**
22
24
  * Algorithm parameters for `crypto.subtle.importKey('jwk', ...)` when
23
25
  * importing the public half of a keypair. The literal `{ name: 'Ed25519' }`
24
- * member covers Ed25519 imports, which take only a `name`; using a literal
25
- * rather than the base `Algorithm` keeps the union closed to the algorithms
26
- * this table supports.
26
+ * member covers Ed25519 imports; `{ name: 'X25519' }` covers X25519 imports.
27
+ * Both take only a `name`; using literals rather than the base `Algorithm`
28
+ * keeps the union closed to the algorithms this table supports.
27
29
  */
28
30
  readonly importPublicKey: RsaHashedImportParams | EcKeyImportParams | {
29
31
  readonly name: 'Ed25519';
32
+ } | {
33
+ readonly name: 'X25519';
30
34
  };
31
35
  /**
32
36
  * Default key usages for the generated `CryptoKeyPair`. Both halves receive
@@ -1 +1 @@
1
- {"version":3,"file":"keyPairAlgorithmParams.d.ts","sourceRoot":"","sources":["../../../src/packlets/crypto-utils/keyPairAlgorithmParams.ts"],"names":[],"mappings":"AAoBA,OAAO,EAAE,gBAAgB,EAAE,MAAM,SAAS,CAAC;AAE3C;;;;;;GAMG;AACH,MAAM,WAAW,uBAAuB;IACtC;;;;;;;OAOG;IACH,QAAQ,CAAC,WAAW,EAAE,qBAAqB,GAAG,cAAc,GAAG;QAAE,QAAQ,CAAC,IAAI,EAAE,SAAS,CAAA;KAAE,CAAC;IAE5F;;;;;;OAMG;IACH,QAAQ,CAAC,eAAe,EAAE,qBAAqB,GAAG,iBAAiB,GAAG;QAAE,QAAQ,CAAC,IAAI,EAAE,SAAS,CAAA;KAAE,CAAC;IAEnG;;;OAGG;IACH,QAAQ,CAAC,aAAa,EAAE,aAAa,CAAC,QAAQ,CAAC,CAAC;IAEhD;;OAEG;IACH,QAAQ,CAAC,eAAe,EAAE,aAAa,CAAC,QAAQ,CAAC,CAAC;CACnD;AAED;;;;;;;GAOG;AACH,eAAO,MAAM,sBAAsB,EAAE,QAAQ,CAAC,MAAM,CAAC,gBAAgB,EAAE,uBAAuB,CAAC,CAkC9F,CAAC"}
1
+ {"version":3,"file":"keyPairAlgorithmParams.d.ts","sourceRoot":"","sources":["../../../src/packlets/crypto-utils/keyPairAlgorithmParams.ts"],"names":[],"mappings":"AAoBA,OAAO,EAAE,gBAAgB,EAAE,MAAM,SAAS,CAAC;AAE3C;;;;;;GAMG;AACH,MAAM,WAAW,uBAAuB;IACtC;;;;;;;OAOG;IACH,QAAQ,CAAC,WAAW,EAChB,qBAAqB,GACrB,cAAc,GACd;QAAE,QAAQ,CAAC,IAAI,EAAE,SAAS,CAAA;KAAE,GAC5B;QAAE,QAAQ,CAAC,IAAI,EAAE,QAAQ,CAAA;KAAE,CAAC;IAEhC;;;;;;OAMG;IACH,QAAQ,CAAC,eAAe,EACpB,qBAAqB,GACrB,iBAAiB,GACjB;QAAE,QAAQ,CAAC,IAAI,EAAE,SAAS,CAAA;KAAE,GAC5B;QAAE,QAAQ,CAAC,IAAI,EAAE,QAAQ,CAAA;KAAE,CAAC;IAEhC;;;OAGG;IACH,QAAQ,CAAC,aAAa,EAAE,aAAa,CAAC,QAAQ,CAAC,CAAC;IAEhD;;OAEG;IACH,QAAQ,CAAC,eAAe,EAAE,aAAa,CAAC,QAAQ,CAAC,CAAC;CACnD;AAED;;;;;;;GAOG;AACH,eAAO,MAAM,sBAAsB,EAAE,QAAQ,CAAC,MAAM,CAAC,gBAAgB,EAAE,uBAAuB,CAAC,CA0C9F,CAAC"}
@@ -61,6 +61,14 @@ exports.keyPairAlgorithmParams = {
61
61
  importPublicKey: { name: 'Ed25519' },
62
62
  keyPairUsages: ['sign', 'verify'],
63
63
  publicKeyUsages: ['verify']
64
+ },
65
+ x25519: {
66
+ generateKey: { name: 'X25519' },
67
+ importPublicKey: { name: 'X25519' },
68
+ // WebCrypto filters per-role: the private key takes both derive usages,
69
+ // the public key gets [] since a standalone X25519 public key cannot derive.
70
+ keyPairUsages: ['deriveKey', 'deriveBits'],
71
+ publicKeyUsages: []
64
72
  }
65
73
  };
66
74
  //# sourceMappingURL=keyPairAlgorithmParams.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"keyPairAlgorithmParams.js","sourceRoot":"","sources":["../../../src/packlets/crypto-utils/keyPairAlgorithmParams.ts"],"names":[],"mappings":";AAAA,kCAAkC;AAClC,EAAE;AACF,+EAA+E;AAC/E,gFAAgF;AAChF,+EAA+E;AAC/E,4EAA4E;AAC5E,wEAAwE;AACxE,2DAA2D;AAC3D,EAAE;AACF,iFAAiF;AACjF,kDAAkD;AAClD,EAAE;AACF,6EAA6E;AAC7E,2EAA2E;AAC3E,8EAA8E;AAC9E,yEAAyE;AACzE,gFAAgF;AAChF,gFAAgF;AAChF,YAAY;;;AA2CZ;;;;;;;GAOG;AACU,QAAA,sBAAsB,GAAgE;IACjG,YAAY,EAAE;QACZ,WAAW,EAAE,EAAE,IAAI,EAAE,OAAO,EAAE,UAAU,EAAE,OAAO,EAAE;QACnD,eAAe,EAAE,EAAE,IAAI,EAAE,OAAO,EAAE,UAAU,EAAE,OAAO,EAAE;QACvD,aAAa,EAAE,CAAC,MAAM,EAAE,QAAQ,CAAC;QACjC,eAAe,EAAE,CAAC,QAAQ,CAAC;KAC5B;IACD,eAAe,EAAE;QACf,WAAW,EAAE;YACX,IAAI,EAAE,UAAU;YAChB,aAAa,EAAE,IAAI;YACnB,cAAc,EAAE,IAAI,UAAU,CAAC,CAAC,IAAI,EAAE,IAAI,EAAE,IAAI,CAAC,CAAC;YAClD,IAAI,EAAE,SAAS;SAChB;QACD,eAAe,EAAE,EAAE,IAAI,EAAE,UAAU,EAAE,IAAI,EAAE,SAAS,EAAE;QACtD,aAAa,EAAE,CAAC,SAAS,EAAE,SAAS,CAAC;QACrC,eAAe,EAAE,CAAC,SAAS,CAAC;KAC7B;IACD,WAAW,EAAE;QACX,WAAW,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,UAAU,EAAE,OAAO,EAAE;QAClD,eAAe,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,UAAU,EAAE,OAAO,EAAE;QACtD,wEAAwE;QACxE,2EAA2E;QAC3E,aAAa,EAAE,CAAC,WAAW,EAAE,YAAY,CAAC;QAC1C,qEAAqE;QACrE,2DAA2D;QAC3D,eAAe,EAAE,EAAE;KACpB;IACD,OAAO,EAAE;QACP,WAAW,EAAE,EAAE,IAAI,EAAE,SAAS,EAAE;QAChC,eAAe,EAAE,EAAE,IAAI,EAAE,SAAS,EAAE;QACpC,aAAa,EAAE,CAAC,MAAM,EAAE,QAAQ,CAAC;QACjC,eAAe,EAAE,CAAC,QAAQ,CAAC;KAC5B;CACF,CAAC","sourcesContent":["// Copyright (c) 2026 Erik Fortune\n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\nimport { KeyPairAlgorithm } from './model';\n\n/**\n * WebCrypto parameters for a single {@link CryptoUtils.KeyPairAlgorithm}.\n * Implementations of {@link CryptoUtils.ICryptoProvider} use this table to\n * translate the small public algorithm enum into the WebCrypto algorithm\n * objects and key-usage arrays expected by `crypto.subtle`.\n * @public\n */\nexport interface IKeyPairAlgorithmParams {\n /**\n * Algorithm parameters for `crypto.subtle.generateKey`. Always an asymmetric\n * variant — these algorithms produce a `CryptoKeyPair`, not a single key.\n * The literal `{ name: 'Ed25519' }` member covers WebCrypto's Secure-Curves\n * Ed25519 algorithm, which takes only a `name`; using a literal rather than\n * the base `Algorithm` keeps the union closed to the algorithms this table\n * supports.\n */\n readonly generateKey: RsaHashedKeyGenParams | EcKeyGenParams | { readonly name: 'Ed25519' };\n\n /**\n * Algorithm parameters for `crypto.subtle.importKey('jwk', ...)` when\n * importing the public half of a keypair. The literal `{ name: 'Ed25519' }`\n * member covers Ed25519 imports, which take only a `name`; using a literal\n * rather than the base `Algorithm` keeps the union closed to the algorithms\n * this table supports.\n */\n readonly importPublicKey: RsaHashedImportParams | EcKeyImportParams | { readonly name: 'Ed25519' };\n\n /**\n * Default key usages for the generated `CryptoKeyPair`. Both halves receive\n * the usages WebCrypto considers valid for their role; the platform filters.\n */\n readonly keyPairUsages: ReadonlyArray<KeyUsage>;\n\n /**\n * Key usages applied when re-importing only the public key.\n */\n readonly publicKeyUsages: ReadonlyArray<KeyUsage>;\n}\n\n/**\n * Lookup table from {@link CryptoUtils.KeyPairAlgorithm} to the WebCrypto\n * parameters needed to drive `crypto.subtle`. Shared between every\n * {@link CryptoUtils.ICryptoProvider} implementation since both Node and\n * browser providers speak the same WebCrypto API. Exposed for downstream\n * provider implementations (e.g. browser-side providers in `@fgv/ts-web-extras`).\n * @public\n */\nexport const keyPairAlgorithmParams: Readonly<Record<KeyPairAlgorithm, IKeyPairAlgorithmParams>> = {\n 'ecdsa-p256': {\n generateKey: { name: 'ECDSA', namedCurve: 'P-256' },\n importPublicKey: { name: 'ECDSA', namedCurve: 'P-256' },\n keyPairUsages: ['sign', 'verify'],\n publicKeyUsages: ['verify']\n },\n 'rsa-oaep-2048': {\n generateKey: {\n name: 'RSA-OAEP',\n modulusLength: 2048,\n publicExponent: new Uint8Array([0x01, 0x00, 0x01]),\n hash: 'SHA-256'\n },\n importPublicKey: { name: 'RSA-OAEP', hash: 'SHA-256' },\n keyPairUsages: ['encrypt', 'decrypt'],\n publicKeyUsages: ['encrypt']\n },\n 'ecdh-p256': {\n generateKey: { name: 'ECDH', namedCurve: 'P-256' },\n importPublicKey: { name: 'ECDH', namedCurve: 'P-256' },\n // WebCrypto filters per-role: the private key takes both derive usages,\n // and the public key gets [] since an ECDH public key alone cannot derive.\n keyPairUsages: ['deriveKey', 'deriveBits'],\n // Importing only the recipient's public key — empty usages because a\n // standalone ECDH public key has no derivation capability.\n publicKeyUsages: []\n },\n ed25519: {\n generateKey: { name: 'Ed25519' },\n importPublicKey: { name: 'Ed25519' },\n keyPairUsages: ['sign', 'verify'],\n publicKeyUsages: ['verify']\n }\n};\n"]}
1
+ {"version":3,"file":"keyPairAlgorithmParams.js","sourceRoot":"","sources":["../../../src/packlets/crypto-utils/keyPairAlgorithmParams.ts"],"names":[],"mappings":";AAAA,kCAAkC;AAClC,EAAE;AACF,+EAA+E;AAC/E,gFAAgF;AAChF,+EAA+E;AAC/E,4EAA4E;AAC5E,wEAAwE;AACxE,2DAA2D;AAC3D,EAAE;AACF,iFAAiF;AACjF,kDAAkD;AAClD,EAAE;AACF,6EAA6E;AAC7E,2EAA2E;AAC3E,8EAA8E;AAC9E,yEAAyE;AACzE,gFAAgF;AAChF,gFAAgF;AAChF,YAAY;;;AAmDZ;;;;;;;GAOG;AACU,QAAA,sBAAsB,GAAgE;IACjG,YAAY,EAAE;QACZ,WAAW,EAAE,EAAE,IAAI,EAAE,OAAO,EAAE,UAAU,EAAE,OAAO,EAAE;QACnD,eAAe,EAAE,EAAE,IAAI,EAAE,OAAO,EAAE,UAAU,EAAE,OAAO,EAAE;QACvD,aAAa,EAAE,CAAC,MAAM,EAAE,QAAQ,CAAC;QACjC,eAAe,EAAE,CAAC,QAAQ,CAAC;KAC5B;IACD,eAAe,EAAE;QACf,WAAW,EAAE;YACX,IAAI,EAAE,UAAU;YAChB,aAAa,EAAE,IAAI;YACnB,cAAc,EAAE,IAAI,UAAU,CAAC,CAAC,IAAI,EAAE,IAAI,EAAE,IAAI,CAAC,CAAC;YAClD,IAAI,EAAE,SAAS;SAChB;QACD,eAAe,EAAE,EAAE,IAAI,EAAE,UAAU,EAAE,IAAI,EAAE,SAAS,EAAE;QACtD,aAAa,EAAE,CAAC,SAAS,EAAE,SAAS,CAAC;QACrC,eAAe,EAAE,CAAC,SAAS,CAAC;KAC7B;IACD,WAAW,EAAE;QACX,WAAW,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,UAAU,EAAE,OAAO,EAAE;QAClD,eAAe,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,UAAU,EAAE,OAAO,EAAE;QACtD,wEAAwE;QACxE,2EAA2E;QAC3E,aAAa,EAAE,CAAC,WAAW,EAAE,YAAY,CAAC;QAC1C,qEAAqE;QACrE,2DAA2D;QAC3D,eAAe,EAAE,EAAE;KACpB;IACD,OAAO,EAAE;QACP,WAAW,EAAE,EAAE,IAAI,EAAE,SAAS,EAAE;QAChC,eAAe,EAAE,EAAE,IAAI,EAAE,SAAS,EAAE;QACpC,aAAa,EAAE,CAAC,MAAM,EAAE,QAAQ,CAAC;QACjC,eAAe,EAAE,CAAC,QAAQ,CAAC;KAC5B;IACD,MAAM,EAAE;QACN,WAAW,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE;QAC/B,eAAe,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE;QACnC,wEAAwE;QACxE,6EAA6E;QAC7E,aAAa,EAAE,CAAC,WAAW,EAAE,YAAY,CAAC;QAC1C,eAAe,EAAE,EAAE;KACpB;CACF,CAAC","sourcesContent":["// Copyright (c) 2026 Erik Fortune\n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\nimport { KeyPairAlgorithm } from './model';\n\n/**\n * WebCrypto parameters for a single {@link CryptoUtils.KeyPairAlgorithm}.\n * Implementations of {@link CryptoUtils.ICryptoProvider} use this table to\n * translate the small public algorithm enum into the WebCrypto algorithm\n * objects and key-usage arrays expected by `crypto.subtle`.\n * @public\n */\nexport interface IKeyPairAlgorithmParams {\n /**\n * Algorithm parameters for `crypto.subtle.generateKey`. Always an asymmetric\n * variant — these algorithms produce a `CryptoKeyPair`, not a single key.\n * The literal `{ name: 'Ed25519' }` member covers WebCrypto's Secure-Curves\n * Ed25519 algorithm; `{ name: 'X25519' }` covers the X25519 key-agreement\n * algorithm. Both take only a `name`; using literals rather than the base\n * `Algorithm` keeps the union closed to the algorithms this table supports.\n */\n readonly generateKey:\n | RsaHashedKeyGenParams\n | EcKeyGenParams\n | { readonly name: 'Ed25519' }\n | { readonly name: 'X25519' };\n\n /**\n * Algorithm parameters for `crypto.subtle.importKey('jwk', ...)` when\n * importing the public half of a keypair. The literal `{ name: 'Ed25519' }`\n * member covers Ed25519 imports; `{ name: 'X25519' }` covers X25519 imports.\n * Both take only a `name`; using literals rather than the base `Algorithm`\n * keeps the union closed to the algorithms this table supports.\n */\n readonly importPublicKey:\n | RsaHashedImportParams\n | EcKeyImportParams\n | { readonly name: 'Ed25519' }\n | { readonly name: 'X25519' };\n\n /**\n * Default key usages for the generated `CryptoKeyPair`. Both halves receive\n * the usages WebCrypto considers valid for their role; the platform filters.\n */\n readonly keyPairUsages: ReadonlyArray<KeyUsage>;\n\n /**\n * Key usages applied when re-importing only the public key.\n */\n readonly publicKeyUsages: ReadonlyArray<KeyUsage>;\n}\n\n/**\n * Lookup table from {@link CryptoUtils.KeyPairAlgorithm} to the WebCrypto\n * parameters needed to drive `crypto.subtle`. Shared between every\n * {@link CryptoUtils.ICryptoProvider} implementation since both Node and\n * browser providers speak the same WebCrypto API. Exposed for downstream\n * provider implementations (e.g. browser-side providers in `@fgv/ts-web-extras`).\n * @public\n */\nexport const keyPairAlgorithmParams: Readonly<Record<KeyPairAlgorithm, IKeyPairAlgorithmParams>> = {\n 'ecdsa-p256': {\n generateKey: { name: 'ECDSA', namedCurve: 'P-256' },\n importPublicKey: { name: 'ECDSA', namedCurve: 'P-256' },\n keyPairUsages: ['sign', 'verify'],\n publicKeyUsages: ['verify']\n },\n 'rsa-oaep-2048': {\n generateKey: {\n name: 'RSA-OAEP',\n modulusLength: 2048,\n publicExponent: new Uint8Array([0x01, 0x00, 0x01]),\n hash: 'SHA-256'\n },\n importPublicKey: { name: 'RSA-OAEP', hash: 'SHA-256' },\n keyPairUsages: ['encrypt', 'decrypt'],\n publicKeyUsages: ['encrypt']\n },\n 'ecdh-p256': {\n generateKey: { name: 'ECDH', namedCurve: 'P-256' },\n importPublicKey: { name: 'ECDH', namedCurve: 'P-256' },\n // WebCrypto filters per-role: the private key takes both derive usages,\n // and the public key gets [] since an ECDH public key alone cannot derive.\n keyPairUsages: ['deriveKey', 'deriveBits'],\n // Importing only the recipient's public key — empty usages because a\n // standalone ECDH public key has no derivation capability.\n publicKeyUsages: []\n },\n ed25519: {\n generateKey: { name: 'Ed25519' },\n importPublicKey: { name: 'Ed25519' },\n keyPairUsages: ['sign', 'verify'],\n publicKeyUsages: ['verify']\n },\n x25519: {\n generateKey: { name: 'X25519' },\n importPublicKey: { name: 'X25519' },\n // WebCrypto filters per-role: the private key takes both derive usages,\n // the public key gets [] since a standalone X25519 public key cannot derive.\n keyPairUsages: ['deriveKey', 'deriveBits'],\n publicKeyUsages: []\n }\n};\n"]}
@@ -57,9 +57,13 @@ export interface IEncryptionResult {
57
57
  * and message rather than sampled randomly, eliminating the random-nonce
58
58
  * reuse risk that ECDSA carries. Distinct from X25519 (key agreement over
59
59
  * the Montgomery form, Curve25519).
60
+ * - `'x25519'`: Diffie-Hellman key agreement over the Montgomery form of
61
+ * Curve25519. Key-agreement only — use `deriveBits`/`deriveKey` to produce
62
+ * a shared secret from one party's private key and the peer's public key.
63
+ * Distinct from Ed25519 (which uses the twisted-Edwards form for signing).
60
64
  * @public
61
65
  */
62
- export type KeyPairAlgorithm = 'ecdsa-p256' | 'rsa-oaep-2048' | 'ecdh-p256' | 'ed25519';
66
+ export type KeyPairAlgorithm = 'ecdsa-p256' | 'rsa-oaep-2048' | 'ecdh-p256' | 'ed25519' | 'x25519';
63
67
  /**
64
68
  * Caller-supplied HKDF parameters that domain-separate one
65
69
  * {@link CryptoUtils.ICryptoProvider.wrapBytes | wrapBytes} call from another.
@@ -276,6 +280,20 @@ export interface ICryptoProvider {
276
280
  * @returns Success with the imported public `CryptoKey`, or Failure with error context.
277
281
  */
278
282
  importPublicKeyJwk(jwk: JsonWebKey, algorithm: KeyPairAlgorithm): Promise<Result<CryptoKey>>;
283
+ /**
284
+ * Exports a public `CryptoKey` as a DER-encoded SPKI (SubjectPublicKeyInfo) blob.
285
+ * SPKI is the standard algorithm-agnostic format for public key storage and transport.
286
+ * @param publicKey - The `CryptoKey` to export. Must have `key.type === 'public'`.
287
+ * @returns `Success` with the raw SPKI bytes, or `Failure` with error context.
288
+ */
289
+ exportPublicKeySpki(publicKey: CryptoKey): Promise<Result<Uint8Array>>;
290
+ /**
291
+ * Imports a public key from a DER-encoded SPKI blob.
292
+ * @param spkiBytes - The raw SPKI bytes produced by {@link CryptoUtils.ICryptoProvider.exportPublicKeySpki | exportPublicKeySpki}.
293
+ * @param algorithm - The {@link CryptoUtils.KeyPairAlgorithm | algorithm} the key was generated for.
294
+ * @returns `Success` with the imported public `CryptoKey`, or `Failure` with error context.
295
+ */
296
+ importPublicKeySpki(spkiBytes: Uint8Array, algorithm: KeyPairAlgorithm): Promise<Result<CryptoKey>>;
279
297
  /**
280
298
  * Wraps `plaintext` for delivery to the holder of the private key paired
281
299
  * with `recipientPublicKey`. Uses ECIES with ECDH P-256, HKDF-SHA256, and
@@ -1 +1 @@
1
- {"version":3,"file":"model.d.ts","sourceRoot":"","sources":["../../../src/packlets/crypto-utils/model.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"model.d.ts","sourceRoot":"","sources":["../../../src/packlets/crypto-utils/model.ts"],"names":[],"mappings":"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"}
@@ -64,7 +64,8 @@ exports.allKeyPairAlgorithms = [
64
64
  'ecdsa-p256',
65
65
  'rsa-oaep-2048',
66
66
  'ecdh-p256',
67
- 'ed25519'
67
+ 'ed25519',
68
+ 'x25519'
68
69
  ];
69
70
  // ============================================================================
70
71
  // Detection Helper
@@ -1 +1 @@
1
- {"version":3,"file":"model.js","sourceRoot":"","sources":["../../../src/packlets/crypto-utils/model.ts"],"names":[],"mappings":";AAAA,kCAAkC;AAClC,EAAE;AACF,+EAA+E;AAC/E,gFAAgF;AAChF,+EAA+E;AAC/E,4EAA4E;AAC5E,wEAAwE;AACxE,2DAA2D;AAC3D,EAAE;AACF,iFAAiF;AACjF,kDAAkD;AAClD,EAAE;AACF,6EAA6E;AAC7E,2EAA2E;AAC3E,8EAA8E;AAC9E,yEAAyE;AACzE,gFAAgF;AAChF,gFAAgF;AAChF,YAAY;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA6eZ,0CAMC;AA9eD,uDAAyC;AAChC,8BAAS;AAgIlB;;;GAGG;AACU,QAAA,oBAAoB,GAAoC;IACnE,YAAY;IACZ,eAAe;IACf,WAAW;IACX,SAAS;CACV,CAAC;AAmVF,+EAA+E;AAC/E,mBAAmB;AACnB,+EAA+E;AAE/E;;;;;;GAMG;AACH,SAAgB,eAAe,CAAC,IAAa;IAC3C,IAAI,OAAO,IAAI,KAAK,QAAQ,IAAI,IAAI,KAAK,IAAI,EAAE,CAAC;QAC9C,OAAO,KAAK,CAAC;IACf,CAAC;IACD,MAAM,GAAG,GAAG,IAA+B,CAAC;IAC5C,OAAO,GAAG,CAAC,MAAM,KAAK,SAAS,CAAC,qBAAqB,CAAC;AACxD,CAAC","sourcesContent":["// Copyright (c) 2024 Erik Fortune\n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\nimport { JsonValue } from '@fgv/ts-json-base';\nimport { Result, Uuid } from '@fgv/ts-utils';\n\nimport * as Constants from './constants';\nexport { Constants };\n\n// ============================================================================\n// Encryption Types\n// ============================================================================\n\n/**\n * Supported encryption algorithms.\n * @public\n */\nexport type EncryptionAlgorithm = typeof Constants.DEFAULT_ALGORITHM;\n\n/**\n * Format version for encrypted files.\n * @public\n */\nexport type EncryptedFileFormat = typeof Constants.ENCRYPTED_FILE_FORMAT;\n\n/**\n * Named secret for encryption/decryption.\n * @public\n */\nexport interface INamedSecret {\n /**\n * Unique name for this secret (referenced in encrypted files).\n */\n readonly name: string;\n\n /**\n * The actual secret key (32 bytes for AES-256).\n */\n readonly key: Uint8Array;\n}\n\n/**\n * Result of an encryption operation.\n * @public\n */\nexport interface IEncryptionResult {\n /**\n * Initialization vector used for encryption (12 bytes for GCM).\n */\n readonly iv: Uint8Array;\n\n /**\n * Authentication tag from GCM mode (16 bytes).\n */\n readonly authTag: Uint8Array;\n\n /**\n * The encrypted data.\n */\n readonly encryptedData: Uint8Array;\n}\n\n/**\n * Asymmetric keypair algorithms supported by the crypto provider.\n * - `'ecdsa-p256'`: ECDSA over the P-256 curve, for signing.\n * - `'rsa-oaep-2048'`: RSA-OAEP, 2048-bit modulus with SHA-256, for encryption.\n * - `'ecdh-p256'`: ECDH over the P-256 curve, for key agreement\n * (e.g. as the recipient keypair in\n * {@link CryptoUtils.ICryptoProvider.wrapBytes | wrapBytes} /\n * {@link CryptoUtils.ICryptoProvider.unwrapBytes | unwrapBytes}).\n * - `'ed25519'`: EdDSA over the Edwards25519 curve, for signing.\n * Deterministic — the per-signature nonce is derived from the private key\n * and message rather than sampled randomly, eliminating the random-nonce\n * reuse risk that ECDSA carries. Distinct from X25519 (key agreement over\n * the Montgomery form, Curve25519).\n * @public\n */\nexport type KeyPairAlgorithm = 'ecdsa-p256' | 'rsa-oaep-2048' | 'ecdh-p256' | 'ed25519';\n\n/**\n * Caller-supplied HKDF parameters that domain-separate one\n * {@link CryptoUtils.ICryptoProvider.wrapBytes | wrapBytes} call from another.\n * Two wraps that share recipient but differ on `salt` or `info` derive distinct\n * wrap keys, so callers should pick values that bind the wrap to its\n * application context (e.g. a content hash for `salt` and a secret name for\n * `info`).\n *\n * Both fields are required; pass an empty `Uint8Array` if the caller has no\n * value to bind on a given axis. Silent defaulting would hide protocol\n * mistakes, so the API does not pick defaults.\n * @public\n */\nexport interface IWrapBytesOptions {\n /**\n * HKDF salt. Domain-separates this wrap from others in different contexts.\n * Caller picks; common choices include a content hash, document id, channel\n * id, etc.\n */\n readonly salt: Uint8Array;\n\n /**\n * HKDF info. Further binds the derived key to a specific use within the\n * calling application. Caller picks; common choices include a secret name,\n * message type, or version tag.\n */\n readonly info: Uint8Array;\n}\n\n/**\n * Output of {@link CryptoUtils.ICryptoProvider.wrapBytes | wrapBytes}. The\n * shape is JSON-serializable so it can travel directly over the wire or be\n * persisted as-is.\n * @public\n */\nexport interface IWrappedBytes {\n /**\n * Sender's ephemeral ECDH P-256 public key as a JSON Web Key. The matching\n * ephemeral private key is dropped after the shared-secret derive.\n */\n readonly ephemeralPublicKey: JsonWebKey;\n\n /**\n * AES-GCM nonce, base64-encoded. 12 bytes (96 bits) — the standard AES-GCM\n * nonce length.\n */\n readonly nonce: string;\n\n /**\n * AES-GCM ciphertext concatenated with the 16-byte authentication tag,\n * base64-encoded. Tampering with either the nonce or the ciphertext causes\n * unwrap to fail GCM authentication.\n */\n readonly ciphertext: string;\n}\n\n/**\n * All valid key pair algorithms.\n * @public\n */\nexport const allKeyPairAlgorithms: ReadonlyArray<KeyPairAlgorithm> = [\n 'ecdsa-p256',\n 'rsa-oaep-2048',\n 'ecdh-p256',\n 'ed25519'\n];\n\n/**\n * Supported key derivation functions.\n * @public\n */\nexport type KeyDerivationFunction = 'pbkdf2';\n\n/**\n * Key derivation parameters stored in encrypted files.\n * Allows decryption with password without needing to know the original salt/iterations.\n * @public\n */\nexport interface IKeyDerivationParams {\n /**\n * Key derivation function used.\n */\n readonly kdf: KeyDerivationFunction;\n\n /**\n * Base64-encoded salt used for key derivation.\n */\n readonly salt: string;\n\n /**\n * Number of iterations used for key derivation.\n */\n readonly iterations: number;\n}\n\n/**\n * Generic encrypted file format.\n * This is the JSON structure stored in encrypted files.\n * @typeParam TMetadata - Type of optional unencrypted metadata\n * @public\n */\nexport interface IEncryptedFile<TMetadata = JsonValue> {\n /**\n * Format identifier for versioning.\n */\n readonly format: EncryptedFileFormat;\n\n /**\n * Name of the secret required to decrypt (references INamedSecret.name).\n */\n readonly secretName: string;\n\n /**\n * Algorithm used for encryption.\n */\n readonly algorithm: EncryptionAlgorithm;\n\n /**\n * Base64-encoded initialization vector.\n */\n readonly iv: string;\n\n /**\n * Base64-encoded authentication tag (for GCM mode).\n */\n readonly authTag: string;\n\n /**\n * Base64-encoded encrypted data (JSON string when decrypted).\n */\n readonly encryptedData: string;\n\n /**\n * Optional unencrypted metadata for display/filtering.\n */\n readonly metadata?: TMetadata;\n\n /**\n * Optional key derivation parameters.\n * If present, allows decryption using a password with these parameters.\n * If absent, a pre-derived key must be provided.\n */\n readonly keyDerivation?: IKeyDerivationParams;\n}\n\n// ============================================================================\n// Crypto Provider Interface\n// ============================================================================\n\n/**\n * Crypto provider interface for cross-platform encryption.\n * Implementations provided for Node.js (crypto module) and browser (Web Crypto API).\n * @public\n */\nexport interface ICryptoProvider {\n /**\n * Encrypts plaintext using AES-256-GCM.\n * @param plaintext - UTF-8 string to encrypt\n * @param key - 32-byte encryption key\n * @returns Success with encryption result, or Failure with error\n */\n encrypt(plaintext: string, key: Uint8Array): Promise<Result<IEncryptionResult>>;\n\n /**\n * Decrypts ciphertext using AES-256-GCM.\n * @param encryptedData - Encrypted bytes\n * @param key - 32-byte decryption key\n * @param iv - Initialization vector (12 bytes)\n * @param authTag - GCM authentication tag (16 bytes)\n * @returns Success with decrypted UTF-8 string, or Failure with error\n */\n decrypt(\n encryptedData: Uint8Array,\n key: Uint8Array,\n iv: Uint8Array,\n authTag: Uint8Array\n ): Promise<Result<string>>;\n\n /**\n * Generates a random 32-byte key suitable for AES-256.\n * @returns Success with generated key, or Failure with error\n */\n generateKey(): Promise<Result<Uint8Array>>;\n\n /**\n * Derives a key from a password using PBKDF2.\n * @param password - Password string\n * @param salt - Salt bytes (should be at least 16 bytes)\n * @param iterations - Number of iterations (recommend 100000+)\n * @returns Success with derived 32-byte key, or Failure with error\n */\n deriveKey(password: string, salt: Uint8Array, iterations: number): Promise<Result<Uint8Array>>;\n\n /**\n * Computes a SHA-256 hash of the given data.\n * @param data - UTF-8 string to hash\n * @returns Success with hex-encoded hash string, or Failure with error\n */\n sha256(data: string): Promise<Result<string>>;\n\n // ============================================================================\n // Platform Utility Methods\n // ============================================================================\n\n /**\n * Generates cryptographically secure random bytes.\n * @param length - Number of bytes to generate\n * @returns Success with random bytes, or Failure with error\n */\n generateRandomBytes(length: number): Result<Uint8Array>;\n\n /**\n * Generates a cryptographically random UUIDv4 using the provider's\n * underlying source of randomness. The default Node and browser\n * implementations delegate to `globalThis.crypto.randomUUID`;\n * deterministic providers (e.g. test stubs) may override to produce\n * reproducible values.\n * @returns Success with a canonical UUID, or Failure with error.\n */\n generateUuid(): Result<Uuid>;\n\n /**\n * Encodes binary data to base64 string.\n * @param data - Binary data to encode\n * @returns Base64-encoded string\n */\n toBase64(data: Uint8Array): string;\n\n /**\n * Decodes base64 string to binary data.\n * @param base64 - Base64-encoded string\n * @returns Success with decoded bytes, or Failure if invalid base64\n */\n fromBase64(base64: string): Result<Uint8Array>;\n\n // ============================================================================\n // Asymmetric Key Operations\n // ============================================================================\n\n /**\n * Generates a new asymmetric keypair for the requested algorithm.\n * @param algorithm - The {@link CryptoUtils.KeyPairAlgorithm | algorithm} to use.\n * @param extractable - Whether the resulting `CryptoKey` objects may be exported.\n * Set `false` on backends that store `CryptoKey` references directly (e.g.\n * IndexedDB). Set `true` when the private key must round-trip through JWK or\n * PKCS#8 (e.g. encrypted-file backends).\n * @returns Success with the generated `CryptoKeyPair`, or Failure with error context.\n */\n generateKeyPair(algorithm: KeyPairAlgorithm, extractable: boolean): Promise<Result<CryptoKeyPair>>;\n\n /**\n * Exports the public half of a keypair as a JSON Web Key.\n * @param publicKey - The public `CryptoKey` to export. Must be an `extractable`\n * key generated for an asymmetric algorithm.\n * @returns Success with the JWK, or Failure with error context.\n */\n exportPublicKeyJwk(publicKey: CryptoKey): Promise<Result<JsonWebKey>>;\n\n /**\n * Re-imports a public-key JWK as a `CryptoKey` usable for verification or\n * encryption (depending on algorithm).\n * @param jwk - The JSON Web Key produced by {@link CryptoUtils.ICryptoProvider.exportPublicKeyJwk | exportPublicKeyJwk}.\n * @param algorithm - The {@link CryptoUtils.KeyPairAlgorithm | algorithm} the\n * key was generated for. Determines the import parameters and key usages.\n * @returns Success with the imported public `CryptoKey`, or Failure with error context.\n */\n importPublicKeyJwk(jwk: JsonWebKey, algorithm: KeyPairAlgorithm): Promise<Result<CryptoKey>>;\n\n /**\n * Wraps `plaintext` for delivery to the holder of the private key paired\n * with `recipientPublicKey`. Uses ECIES with ECDH P-256, HKDF-SHA256, and\n * AES-GCM-256.\n *\n * Generates a fresh ephemeral keypair per call; the ephemeral private key\n * is discarded after the shared-secret derive. Only the recipient (with the\n * matching private key) and the same HKDF parameters can recover\n * `plaintext`.\n *\n * Empty `plaintext` is permitted; the resulting wrap contains only the\n * 16-byte GCM authentication tag and round-trips back to an empty\n * `Uint8Array`.\n * @param plaintext - The bytes to wrap. Any length supported by AES-GCM\n * (in practice, well below 2^39 - 256 bits).\n * @param recipientPublicKey - The recipient's ECDH P-256 public `CryptoKey`.\n * Must have algorithm name `'ECDH'` and named curve `'P-256'`; mismatched\n * algorithm or curve yields a `Failure` with error context.\n * @param options - HKDF parameters; see {@link CryptoUtils.IWrapBytesOptions | IWrapBytesOptions}.\n * @returns `Success` with the wrapped payload, or `Failure` with error context.\n */\n wrapBytes(\n plaintext: Uint8Array,\n recipientPublicKey: CryptoKey,\n options: IWrapBytesOptions\n ): Promise<Result<IWrappedBytes>>;\n\n /**\n * Inverse of {@link CryptoUtils.ICryptoProvider.wrapBytes | wrapBytes}.\n * Recovers the original `plaintext` from a wrapped payload using the\n * recipient's private key.\n *\n * Returns a `Failure` (never throws) on any of:\n * - Tampered nonce or ciphertext (AES-GCM authentication fails)\n * - Wrong private key (different shared secret derives a different wrap key)\n * - Wrong HKDF parameters (different wrap key)\n * - Malformed `ephemeralPublicKey` JWK\n * - Malformed base64 in `nonce` or `ciphertext`\n * @param wrapped - The wrapped payload produced by `wrapBytes`.\n * @param recipientPrivateKey - The recipient's ECDH P-256 private\n * `CryptoKey`. Must have algorithm name `'ECDH'` and named curve `'P-256'`,\n * and key usages including `'deriveKey'` or `'deriveBits'`.\n * @param options - The same HKDF parameters used at wrap time.\n * @returns `Success` with the original `plaintext`, or `Failure` with error context.\n */\n unwrapBytes(\n wrapped: IWrappedBytes,\n recipientPrivateKey: CryptoKey,\n options: IWrapBytesOptions\n ): Promise<Result<Uint8Array>>;\n}\n\n// ============================================================================\n// Encryption Provider Interface\n// ============================================================================\n\n/**\n * High-level interface for encrypting JSON content by secret name.\n *\n * This abstraction unifies two common encryption workflows:\n * - **KeyStore**: looks up the named secret and crypto provider from the vault\n * - **DirectEncryptionProvider**: uses a pre-supplied key and crypto provider,\n * optionally bound to a specific secret name for safety\n *\n * Callers that need to encrypt (e.g. `EditableCollection.save()`) depend on\n * this interface rather than on `KeyStore` directly, allowing mix-and-match.\n *\n * @public\n */\nexport interface IEncryptionProvider {\n /**\n * Encrypts JSON content under a named secret.\n *\n * @param secretName - Name of the secret to encrypt with\n * @param content - JSON-safe content to encrypt\n * @param metadata - Optional unencrypted metadata to include in the encrypted file\n * @returns Success with encrypted file structure, or Failure with error context\n */\n encryptByName<TMetadata = JsonValue>(\n secretName: string,\n content: JsonValue,\n metadata?: TMetadata\n ): Promise<Result<IEncryptedFile<TMetadata>>>;\n}\n\n// ============================================================================\n// Encryption Configuration\n// ============================================================================\n\n/**\n * Behavior when an encrypted file cannot be decrypted.\n * @public\n */\nexport type EncryptedFileErrorMode =\n | 'fail' // Return failure, abort loading\n | 'skip' // Skip file silently, continue loading others\n | 'warn'; // Log warning, skip file, continue loading\n\n/**\n * Function type for dynamic secret retrieval.\n * @public\n */\nexport type SecretProvider = (secretName: string) => Promise<Result<Uint8Array>>;\n\n/**\n * Configuration for encrypted file handling during loading.\n * @public\n */\nexport interface IEncryptionConfig {\n /**\n * Named secrets available for decryption.\n */\n readonly secrets?: ReadonlyArray<INamedSecret>;\n\n /**\n * Alternative: dynamic secret provider function.\n * Called when a secret is not found in the secrets array.\n */\n readonly secretProvider?: SecretProvider;\n\n /**\n * Crypto provider implementation (Node.js or browser).\n */\n readonly cryptoProvider: ICryptoProvider;\n\n /**\n * Behavior when decryption key is missing (default: 'fail').\n */\n readonly onMissingKey?: EncryptedFileErrorMode;\n\n /**\n * Behavior when decryption fails (default: 'fail').\n */\n readonly onDecryptionError?: EncryptedFileErrorMode;\n}\n\n// ============================================================================\n// Detection Helper\n// ============================================================================\n\n/**\n * Checks if a JSON object appears to be an encrypted file.\n * Uses the format field as a discriminator.\n * @param json - JSON object to check\n * @returns true if the object has the encrypted file format field\n * @public\n */\nexport function isEncryptedFile(json: unknown): boolean {\n if (typeof json !== 'object' || json === null) {\n return false;\n }\n const obj = json as Record<string, unknown>;\n return obj.format === Constants.ENCRYPTED_FILE_FORMAT;\n}\n"]}
1
+ {"version":3,"file":"model.js","sourceRoot":"","sources":["../../../src/packlets/crypto-utils/model.ts"],"names":[],"mappings":";AAAA,kCAAkC;AAClC,EAAE;AACF,+EAA+E;AAC/E,gFAAgF;AAChF,+EAA+E;AAC/E,4EAA4E;AAC5E,wEAAwE;AACxE,2DAA2D;AAC3D,EAAE;AACF,iFAAiF;AACjF,kDAAkD;AAClD,EAAE;AACF,6EAA6E;AAC7E,2EAA2E;AAC3E,8EAA8E;AAC9E,yEAAyE;AACzE,gFAAgF;AAChF,gFAAgF;AAChF,YAAY;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAkgBZ,0CAMC;AAngBD,uDAAyC;AAChC,8BAAS;AAoIlB;;;GAGG;AACU,QAAA,oBAAoB,GAAoC;IACnE,YAAY;IACZ,eAAe;IACf,WAAW;IACX,SAAS;IACT,QAAQ;CACT,CAAC;AAmWF,+EAA+E;AAC/E,mBAAmB;AACnB,+EAA+E;AAE/E;;;;;;GAMG;AACH,SAAgB,eAAe,CAAC,IAAa;IAC3C,IAAI,OAAO,IAAI,KAAK,QAAQ,IAAI,IAAI,KAAK,IAAI,EAAE,CAAC;QAC9C,OAAO,KAAK,CAAC;IACf,CAAC;IACD,MAAM,GAAG,GAAG,IAA+B,CAAC;IAC5C,OAAO,GAAG,CAAC,MAAM,KAAK,SAAS,CAAC,qBAAqB,CAAC;AACxD,CAAC","sourcesContent":["// Copyright (c) 2024 Erik Fortune\n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\nimport { JsonValue } from '@fgv/ts-json-base';\nimport { Result, Uuid } from '@fgv/ts-utils';\n\nimport * as Constants from './constants';\nexport { Constants };\n\n// ============================================================================\n// Encryption Types\n// ============================================================================\n\n/**\n * Supported encryption algorithms.\n * @public\n */\nexport type EncryptionAlgorithm = typeof Constants.DEFAULT_ALGORITHM;\n\n/**\n * Format version for encrypted files.\n * @public\n */\nexport type EncryptedFileFormat = typeof Constants.ENCRYPTED_FILE_FORMAT;\n\n/**\n * Named secret for encryption/decryption.\n * @public\n */\nexport interface INamedSecret {\n /**\n * Unique name for this secret (referenced in encrypted files).\n */\n readonly name: string;\n\n /**\n * The actual secret key (32 bytes for AES-256).\n */\n readonly key: Uint8Array;\n}\n\n/**\n * Result of an encryption operation.\n * @public\n */\nexport interface IEncryptionResult {\n /**\n * Initialization vector used for encryption (12 bytes for GCM).\n */\n readonly iv: Uint8Array;\n\n /**\n * Authentication tag from GCM mode (16 bytes).\n */\n readonly authTag: Uint8Array;\n\n /**\n * The encrypted data.\n */\n readonly encryptedData: Uint8Array;\n}\n\n/**\n * Asymmetric keypair algorithms supported by the crypto provider.\n * - `'ecdsa-p256'`: ECDSA over the P-256 curve, for signing.\n * - `'rsa-oaep-2048'`: RSA-OAEP, 2048-bit modulus with SHA-256, for encryption.\n * - `'ecdh-p256'`: ECDH over the P-256 curve, for key agreement\n * (e.g. as the recipient keypair in\n * {@link CryptoUtils.ICryptoProvider.wrapBytes | wrapBytes} /\n * {@link CryptoUtils.ICryptoProvider.unwrapBytes | unwrapBytes}).\n * - `'ed25519'`: EdDSA over the Edwards25519 curve, for signing.\n * Deterministic — the per-signature nonce is derived from the private key\n * and message rather than sampled randomly, eliminating the random-nonce\n * reuse risk that ECDSA carries. Distinct from X25519 (key agreement over\n * the Montgomery form, Curve25519).\n * - `'x25519'`: Diffie-Hellman key agreement over the Montgomery form of\n * Curve25519. Key-agreement only — use `deriveBits`/`deriveKey` to produce\n * a shared secret from one party's private key and the peer's public key.\n * Distinct from Ed25519 (which uses the twisted-Edwards form for signing).\n * @public\n */\nexport type KeyPairAlgorithm = 'ecdsa-p256' | 'rsa-oaep-2048' | 'ecdh-p256' | 'ed25519' | 'x25519';\n\n/**\n * Caller-supplied HKDF parameters that domain-separate one\n * {@link CryptoUtils.ICryptoProvider.wrapBytes | wrapBytes} call from another.\n * Two wraps that share recipient but differ on `salt` or `info` derive distinct\n * wrap keys, so callers should pick values that bind the wrap to its\n * application context (e.g. a content hash for `salt` and a secret name for\n * `info`).\n *\n * Both fields are required; pass an empty `Uint8Array` if the caller has no\n * value to bind on a given axis. Silent defaulting would hide protocol\n * mistakes, so the API does not pick defaults.\n * @public\n */\nexport interface IWrapBytesOptions {\n /**\n * HKDF salt. Domain-separates this wrap from others in different contexts.\n * Caller picks; common choices include a content hash, document id, channel\n * id, etc.\n */\n readonly salt: Uint8Array;\n\n /**\n * HKDF info. Further binds the derived key to a specific use within the\n * calling application. Caller picks; common choices include a secret name,\n * message type, or version tag.\n */\n readonly info: Uint8Array;\n}\n\n/**\n * Output of {@link CryptoUtils.ICryptoProvider.wrapBytes | wrapBytes}. The\n * shape is JSON-serializable so it can travel directly over the wire or be\n * persisted as-is.\n * @public\n */\nexport interface IWrappedBytes {\n /**\n * Sender's ephemeral ECDH P-256 public key as a JSON Web Key. The matching\n * ephemeral private key is dropped after the shared-secret derive.\n */\n readonly ephemeralPublicKey: JsonWebKey;\n\n /**\n * AES-GCM nonce, base64-encoded. 12 bytes (96 bits) — the standard AES-GCM\n * nonce length.\n */\n readonly nonce: string;\n\n /**\n * AES-GCM ciphertext concatenated with the 16-byte authentication tag,\n * base64-encoded. Tampering with either the nonce or the ciphertext causes\n * unwrap to fail GCM authentication.\n */\n readonly ciphertext: string;\n}\n\n/**\n * All valid key pair algorithms.\n * @public\n */\nexport const allKeyPairAlgorithms: ReadonlyArray<KeyPairAlgorithm> = [\n 'ecdsa-p256',\n 'rsa-oaep-2048',\n 'ecdh-p256',\n 'ed25519',\n 'x25519'\n];\n\n/**\n * Supported key derivation functions.\n * @public\n */\nexport type KeyDerivationFunction = 'pbkdf2';\n\n/**\n * Key derivation parameters stored in encrypted files.\n * Allows decryption with password without needing to know the original salt/iterations.\n * @public\n */\nexport interface IKeyDerivationParams {\n /**\n * Key derivation function used.\n */\n readonly kdf: KeyDerivationFunction;\n\n /**\n * Base64-encoded salt used for key derivation.\n */\n readonly salt: string;\n\n /**\n * Number of iterations used for key derivation.\n */\n readonly iterations: number;\n}\n\n/**\n * Generic encrypted file format.\n * This is the JSON structure stored in encrypted files.\n * @typeParam TMetadata - Type of optional unencrypted metadata\n * @public\n */\nexport interface IEncryptedFile<TMetadata = JsonValue> {\n /**\n * Format identifier for versioning.\n */\n readonly format: EncryptedFileFormat;\n\n /**\n * Name of the secret required to decrypt (references INamedSecret.name).\n */\n readonly secretName: string;\n\n /**\n * Algorithm used for encryption.\n */\n readonly algorithm: EncryptionAlgorithm;\n\n /**\n * Base64-encoded initialization vector.\n */\n readonly iv: string;\n\n /**\n * Base64-encoded authentication tag (for GCM mode).\n */\n readonly authTag: string;\n\n /**\n * Base64-encoded encrypted data (JSON string when decrypted).\n */\n readonly encryptedData: string;\n\n /**\n * Optional unencrypted metadata for display/filtering.\n */\n readonly metadata?: TMetadata;\n\n /**\n * Optional key derivation parameters.\n * If present, allows decryption using a password with these parameters.\n * If absent, a pre-derived key must be provided.\n */\n readonly keyDerivation?: IKeyDerivationParams;\n}\n\n// ============================================================================\n// Crypto Provider Interface\n// ============================================================================\n\n/**\n * Crypto provider interface for cross-platform encryption.\n * Implementations provided for Node.js (crypto module) and browser (Web Crypto API).\n * @public\n */\nexport interface ICryptoProvider {\n /**\n * Encrypts plaintext using AES-256-GCM.\n * @param plaintext - UTF-8 string to encrypt\n * @param key - 32-byte encryption key\n * @returns Success with encryption result, or Failure with error\n */\n encrypt(plaintext: string, key: Uint8Array): Promise<Result<IEncryptionResult>>;\n\n /**\n * Decrypts ciphertext using AES-256-GCM.\n * @param encryptedData - Encrypted bytes\n * @param key - 32-byte decryption key\n * @param iv - Initialization vector (12 bytes)\n * @param authTag - GCM authentication tag (16 bytes)\n * @returns Success with decrypted UTF-8 string, or Failure with error\n */\n decrypt(\n encryptedData: Uint8Array,\n key: Uint8Array,\n iv: Uint8Array,\n authTag: Uint8Array\n ): Promise<Result<string>>;\n\n /**\n * Generates a random 32-byte key suitable for AES-256.\n * @returns Success with generated key, or Failure with error\n */\n generateKey(): Promise<Result<Uint8Array>>;\n\n /**\n * Derives a key from a password using PBKDF2.\n * @param password - Password string\n * @param salt - Salt bytes (should be at least 16 bytes)\n * @param iterations - Number of iterations (recommend 100000+)\n * @returns Success with derived 32-byte key, or Failure with error\n */\n deriveKey(password: string, salt: Uint8Array, iterations: number): Promise<Result<Uint8Array>>;\n\n /**\n * Computes a SHA-256 hash of the given data.\n * @param data - UTF-8 string to hash\n * @returns Success with hex-encoded hash string, or Failure with error\n */\n sha256(data: string): Promise<Result<string>>;\n\n // ============================================================================\n // Platform Utility Methods\n // ============================================================================\n\n /**\n * Generates cryptographically secure random bytes.\n * @param length - Number of bytes to generate\n * @returns Success with random bytes, or Failure with error\n */\n generateRandomBytes(length: number): Result<Uint8Array>;\n\n /**\n * Generates a cryptographically random UUIDv4 using the provider's\n * underlying source of randomness. The default Node and browser\n * implementations delegate to `globalThis.crypto.randomUUID`;\n * deterministic providers (e.g. test stubs) may override to produce\n * reproducible values.\n * @returns Success with a canonical UUID, or Failure with error.\n */\n generateUuid(): Result<Uuid>;\n\n /**\n * Encodes binary data to base64 string.\n * @param data - Binary data to encode\n * @returns Base64-encoded string\n */\n toBase64(data: Uint8Array): string;\n\n /**\n * Decodes base64 string to binary data.\n * @param base64 - Base64-encoded string\n * @returns Success with decoded bytes, or Failure if invalid base64\n */\n fromBase64(base64: string): Result<Uint8Array>;\n\n // ============================================================================\n // Asymmetric Key Operations\n // ============================================================================\n\n /**\n * Generates a new asymmetric keypair for the requested algorithm.\n * @param algorithm - The {@link CryptoUtils.KeyPairAlgorithm | algorithm} to use.\n * @param extractable - Whether the resulting `CryptoKey` objects may be exported.\n * Set `false` on backends that store `CryptoKey` references directly (e.g.\n * IndexedDB). Set `true` when the private key must round-trip through JWK or\n * PKCS#8 (e.g. encrypted-file backends).\n * @returns Success with the generated `CryptoKeyPair`, or Failure with error context.\n */\n generateKeyPair(algorithm: KeyPairAlgorithm, extractable: boolean): Promise<Result<CryptoKeyPair>>;\n\n /**\n * Exports the public half of a keypair as a JSON Web Key.\n * @param publicKey - The public `CryptoKey` to export. Must be an `extractable`\n * key generated for an asymmetric algorithm.\n * @returns Success with the JWK, or Failure with error context.\n */\n exportPublicKeyJwk(publicKey: CryptoKey): Promise<Result<JsonWebKey>>;\n\n /**\n * Re-imports a public-key JWK as a `CryptoKey` usable for verification or\n * encryption (depending on algorithm).\n * @param jwk - The JSON Web Key produced by {@link CryptoUtils.ICryptoProvider.exportPublicKeyJwk | exportPublicKeyJwk}.\n * @param algorithm - The {@link CryptoUtils.KeyPairAlgorithm | algorithm} the\n * key was generated for. Determines the import parameters and key usages.\n * @returns Success with the imported public `CryptoKey`, or Failure with error context.\n */\n importPublicKeyJwk(jwk: JsonWebKey, algorithm: KeyPairAlgorithm): Promise<Result<CryptoKey>>;\n\n /**\n * Exports a public `CryptoKey` as a DER-encoded SPKI (SubjectPublicKeyInfo) blob.\n * SPKI is the standard algorithm-agnostic format for public key storage and transport.\n * @param publicKey - The `CryptoKey` to export. Must have `key.type === 'public'`.\n * @returns `Success` with the raw SPKI bytes, or `Failure` with error context.\n */\n exportPublicKeySpki(publicKey: CryptoKey): Promise<Result<Uint8Array>>;\n\n /**\n * Imports a public key from a DER-encoded SPKI blob.\n * @param spkiBytes - The raw SPKI bytes produced by {@link CryptoUtils.ICryptoProvider.exportPublicKeySpki | exportPublicKeySpki}.\n * @param algorithm - The {@link CryptoUtils.KeyPairAlgorithm | algorithm} the key was generated for.\n * @returns `Success` with the imported public `CryptoKey`, or `Failure` with error context.\n */\n importPublicKeySpki(spkiBytes: Uint8Array, algorithm: KeyPairAlgorithm): Promise<Result<CryptoKey>>;\n\n /**\n * Wraps `plaintext` for delivery to the holder of the private key paired\n * with `recipientPublicKey`. Uses ECIES with ECDH P-256, HKDF-SHA256, and\n * AES-GCM-256.\n *\n * Generates a fresh ephemeral keypair per call; the ephemeral private key\n * is discarded after the shared-secret derive. Only the recipient (with the\n * matching private key) and the same HKDF parameters can recover\n * `plaintext`.\n *\n * Empty `plaintext` is permitted; the resulting wrap contains only the\n * 16-byte GCM authentication tag and round-trips back to an empty\n * `Uint8Array`.\n * @param plaintext - The bytes to wrap. Any length supported by AES-GCM\n * (in practice, well below 2^39 - 256 bits).\n * @param recipientPublicKey - The recipient's ECDH P-256 public `CryptoKey`.\n * Must have algorithm name `'ECDH'` and named curve `'P-256'`; mismatched\n * algorithm or curve yields a `Failure` with error context.\n * @param options - HKDF parameters; see {@link CryptoUtils.IWrapBytesOptions | IWrapBytesOptions}.\n * @returns `Success` with the wrapped payload, or `Failure` with error context.\n */\n wrapBytes(\n plaintext: Uint8Array,\n recipientPublicKey: CryptoKey,\n options: IWrapBytesOptions\n ): Promise<Result<IWrappedBytes>>;\n\n /**\n * Inverse of {@link CryptoUtils.ICryptoProvider.wrapBytes | wrapBytes}.\n * Recovers the original `plaintext` from a wrapped payload using the\n * recipient's private key.\n *\n * Returns a `Failure` (never throws) on any of:\n * - Tampered nonce or ciphertext (AES-GCM authentication fails)\n * - Wrong private key (different shared secret derives a different wrap key)\n * - Wrong HKDF parameters (different wrap key)\n * - Malformed `ephemeralPublicKey` JWK\n * - Malformed base64 in `nonce` or `ciphertext`\n * @param wrapped - The wrapped payload produced by `wrapBytes`.\n * @param recipientPrivateKey - The recipient's ECDH P-256 private\n * `CryptoKey`. Must have algorithm name `'ECDH'` and named curve `'P-256'`,\n * and key usages including `'deriveKey'` or `'deriveBits'`.\n * @param options - The same HKDF parameters used at wrap time.\n * @returns `Success` with the original `plaintext`, or `Failure` with error context.\n */\n unwrapBytes(\n wrapped: IWrappedBytes,\n recipientPrivateKey: CryptoKey,\n options: IWrapBytesOptions\n ): Promise<Result<Uint8Array>>;\n}\n\n// ============================================================================\n// Encryption Provider Interface\n// ============================================================================\n\n/**\n * High-level interface for encrypting JSON content by secret name.\n *\n * This abstraction unifies two common encryption workflows:\n * - **KeyStore**: looks up the named secret and crypto provider from the vault\n * - **DirectEncryptionProvider**: uses a pre-supplied key and crypto provider,\n * optionally bound to a specific secret name for safety\n *\n * Callers that need to encrypt (e.g. `EditableCollection.save()`) depend on\n * this interface rather than on `KeyStore` directly, allowing mix-and-match.\n *\n * @public\n */\nexport interface IEncryptionProvider {\n /**\n * Encrypts JSON content under a named secret.\n *\n * @param secretName - Name of the secret to encrypt with\n * @param content - JSON-safe content to encrypt\n * @param metadata - Optional unencrypted metadata to include in the encrypted file\n * @returns Success with encrypted file structure, or Failure with error context\n */\n encryptByName<TMetadata = JsonValue>(\n secretName: string,\n content: JsonValue,\n metadata?: TMetadata\n ): Promise<Result<IEncryptedFile<TMetadata>>>;\n}\n\n// ============================================================================\n// Encryption Configuration\n// ============================================================================\n\n/**\n * Behavior when an encrypted file cannot be decrypted.\n * @public\n */\nexport type EncryptedFileErrorMode =\n | 'fail' // Return failure, abort loading\n | 'skip' // Skip file silently, continue loading others\n | 'warn'; // Log warning, skip file, continue loading\n\n/**\n * Function type for dynamic secret retrieval.\n * @public\n */\nexport type SecretProvider = (secretName: string) => Promise<Result<Uint8Array>>;\n\n/**\n * Configuration for encrypted file handling during loading.\n * @public\n */\nexport interface IEncryptionConfig {\n /**\n * Named secrets available for decryption.\n */\n readonly secrets?: ReadonlyArray<INamedSecret>;\n\n /**\n * Alternative: dynamic secret provider function.\n * Called when a secret is not found in the secrets array.\n */\n readonly secretProvider?: SecretProvider;\n\n /**\n * Crypto provider implementation (Node.js or browser).\n */\n readonly cryptoProvider: ICryptoProvider;\n\n /**\n * Behavior when decryption key is missing (default: 'fail').\n */\n readonly onMissingKey?: EncryptedFileErrorMode;\n\n /**\n * Behavior when decryption fails (default: 'fail').\n */\n readonly onDecryptionError?: EncryptedFileErrorMode;\n}\n\n// ============================================================================\n// Detection Helper\n// ============================================================================\n\n/**\n * Checks if a JSON object appears to be an encrypted file.\n * Uses the format field as a discriminator.\n * @param json - JSON object to check\n * @returns true if the object has the encrypted file format field\n * @public\n */\nexport function isEncryptedFile(json: unknown): boolean {\n if (typeof json !== 'object' || json === null) {\n return false;\n }\n const obj = json as Record<string, unknown>;\n return obj.format === Constants.ENCRYPTED_FILE_FORMAT;\n}\n"]}
@@ -90,6 +90,19 @@ export declare class NodeCryptoProvider implements ICryptoProvider {
90
90
  * @returns `Success` with the imported public `CryptoKey`, or `Failure` with an error.
91
91
  */
92
92
  importPublicKeyJwk(jwk: JsonWebKey, algorithm: KeyPairAlgorithm): Promise<Result<CryptoKey>>;
93
+ /**
94
+ * Exports a public `CryptoKey` as a DER-encoded SPKI blob.
95
+ * @param publicKey - The public `CryptoKey` to export.
96
+ * @returns `Success` with the raw SPKI bytes, or `Failure` with error context.
97
+ */
98
+ exportPublicKeySpki(publicKey: CryptoKey): Promise<Result<Uint8Array>>;
99
+ /**
100
+ * Imports a public key from a DER-encoded SPKI blob.
101
+ * @param spkiBytes - The raw SPKI bytes.
102
+ * @param algorithm - The algorithm the key was generated for.
103
+ * @returns `Success` with the imported public `CryptoKey`, or `Failure` with error context.
104
+ */
105
+ importPublicKeySpki(spkiBytes: Uint8Array, algorithm: KeyPairAlgorithm): Promise<Result<CryptoKey>>;
93
106
  /**
94
107
  * Wraps `plaintext` for the holder of `recipientPublicKey` using
95
108
  * ECIES (ECDH P-256 + HKDF-SHA256 + AES-GCM-256). See
@@ -1 +1 @@
1
- {"version":3,"file":"nodeCryptoProvider.d.ts","sourceRoot":"","sources":["../../../src/packlets/crypto-utils/nodeCryptoProvider.ts"],"names":[],"mappings":"AAqBA,OAAO,EAML,MAAM,EAGN,IAAI,EACL,MAAM,eAAe,CAAC;AAGvB,OAAO,EACL,eAAe,EACf,iBAAiB,EACjB,iBAAiB,EACjB,aAAa,EACb,gBAAgB,EACjB,MAAM,SAAS,CAAC;AAEjB;;;;GAIG;AACH,qBAAa,kBAAmB,YAAW,eAAe;IACxD;;;;;OAKG;IACU,OAAO,CAAC,SAAS,EAAE,MAAM,EAAE,GAAG,EAAE,UAAU,GAAG,OAAO,CAAC,MAAM,CAAC,iBAAiB,CAAC,CAAC;IA0B5F;;;;;;;OAOG;IACU,OAAO,CAClB,aAAa,EAAE,UAAU,EACzB,GAAG,EAAE,UAAU,EACf,EAAE,EAAE,UAAU,EACd,OAAO,EAAE,UAAU,GAClB,OAAO,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;IAyB1B;;;OAGG;IACU,WAAW,IAAI,OAAO,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC;IAOvD;;;;;;OAMG;IACU,SAAS,CACpB,QAAQ,EAAE,MAAM,EAChB,IAAI,EAAE,UAAU,EAChB,UAAU,EAAE,MAAM,GACjB,OAAO,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC;IA2B9B;;;;OAIG;IACU,MAAM,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;IAY1D;;;;OAIG;IACI,mBAAmB,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAAC,UAAU,CAAC;IAO9D;;;;OAIG;IACI,YAAY,IAAI,MAAM,CAAC,IAAI,CAAC;IAInC;;;;OAIG;IACI,QAAQ,CAAC,IAAI,EAAE,UAAU,GAAG,MAAM;IAIzC;;;;OAIG;IACI,UAAU,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAAC,UAAU,CAAC;IAYrD;;;;;OAKG;IACU,eAAe,CAC1B,SAAS,EAAE,gBAAgB,EAC3B,WAAW,EAAE,OAAO,GACnB,OAAO,CAAC,MAAM,CAAC,aAAa,CAAC,CAAC;IAqBjC;;;;;;;;;OASG;IACU,kBAAkB,CAAC,SAAS,EAAE,SAAS,GAAG,OAAO,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC;IAQlF;;;;;OAKG;IACU,kBAAkB,CAAC,GAAG,EAAE,UAAU,EAAE,SAAS,EAAE,gBAAgB,GAAG,OAAO,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC;IAQzG;;;;;;;;OAQG;IACU,SAAS,CACpB,SAAS,EAAE,UAAU,EACrB,kBAAkB,EAAE,SAAS,EAC7B,OAAO,EAAE,iBAAiB,GACzB,OAAO,CAAC,MAAM,CAAC,aAAa,CAAC,CAAC;IAoCjC;;;;;;;OAOG;IACU,WAAW,CACtB,OAAO,EAAE,aAAa,EACtB,mBAAmB,EAAE,SAAS,EAC9B,OAAO,EAAE,iBAAiB,GACzB,OAAO,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC;CAuD/B;AA8BD;;;GAGG;AACH,eAAO,MAAM,kBAAkB,EAAE,kBAA6C,CAAC"}
1
+ {"version":3,"file":"nodeCryptoProvider.d.ts","sourceRoot":"","sources":["../../../src/packlets/crypto-utils/nodeCryptoProvider.ts"],"names":[],"mappings":"AAqBA,OAAO,EAML,MAAM,EAGN,IAAI,EACL,MAAM,eAAe,CAAC;AAGvB,OAAO,EACL,eAAe,EACf,iBAAiB,EACjB,iBAAiB,EACjB,aAAa,EACb,gBAAgB,EACjB,MAAM,SAAS,CAAC;AAEjB;;;;GAIG;AACH,qBAAa,kBAAmB,YAAW,eAAe;IACxD;;;;;OAKG;IACU,OAAO,CAAC,SAAS,EAAE,MAAM,EAAE,GAAG,EAAE,UAAU,GAAG,OAAO,CAAC,MAAM,CAAC,iBAAiB,CAAC,CAAC;IA0B5F;;;;;;;OAOG;IACU,OAAO,CAClB,aAAa,EAAE,UAAU,EACzB,GAAG,EAAE,UAAU,EACf,EAAE,EAAE,UAAU,EACd,OAAO,EAAE,UAAU,GAClB,OAAO,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;IAyB1B;;;OAGG;IACU,WAAW,IAAI,OAAO,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC;IAOvD;;;;;;OAMG;IACU,SAAS,CACpB,QAAQ,EAAE,MAAM,EAChB,IAAI,EAAE,UAAU,EAChB,UAAU,EAAE,MAAM,GACjB,OAAO,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC;IA2B9B;;;;OAIG;IACU,MAAM,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;IAY1D;;;;OAIG;IACI,mBAAmB,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAAC,UAAU,CAAC;IAO9D;;;;OAIG;IACI,YAAY,IAAI,MAAM,CAAC,IAAI,CAAC;IAInC;;;;OAIG;IACI,QAAQ,CAAC,IAAI,EAAE,UAAU,GAAG,MAAM;IAIzC;;;;OAIG;IACI,UAAU,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAAC,UAAU,CAAC;IAYrD;;;;;OAKG;IACU,eAAe,CAC1B,SAAS,EAAE,gBAAgB,EAC3B,WAAW,EAAE,OAAO,GACnB,OAAO,CAAC,MAAM,CAAC,aAAa,CAAC,CAAC;IAqBjC;;;;;;;;;OASG;IACU,kBAAkB,CAAC,SAAS,EAAE,SAAS,GAAG,OAAO,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC;IAQlF;;;;;OAKG;IACU,kBAAkB,CAAC,GAAG,EAAE,UAAU,EAAE,SAAS,EAAE,gBAAgB,GAAG,OAAO,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC;IAQzG;;;;OAIG;IACU,mBAAmB,CAAC,SAAS,EAAE,SAAS,GAAG,OAAO,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC;IAUnF;;;;;OAKG;IACU,mBAAmB,CAC9B,SAAS,EAAE,UAAU,EACrB,SAAS,EAAE,gBAAgB,GAC1B,OAAO,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC;IAgB7B;;;;;;;;OAQG;IACU,SAAS,CACpB,SAAS,EAAE,UAAU,EACrB,kBAAkB,EAAE,SAAS,EAC7B,OAAO,EAAE,iBAAiB,GACzB,OAAO,CAAC,MAAM,CAAC,aAAa,CAAC,CAAC;IAoCjC;;;;;;;OAOG;IACU,WAAW,CACtB,OAAO,EAAE,aAAa,EACtB,mBAAmB,EAAE,SAAS,EAC9B,OAAO,EAAE,iBAAiB,GACzB,OAAO,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC;CAuD/B;AA8BD;;;GAGG;AACH,eAAO,MAAM,kBAAkB,EAAE,kBAA6C,CAAC"}