@fgv/ts-extras 5.1.0-27 → 5.1.0-29

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 (73) hide show
  1. package/dist/index.browser.js +2 -1
  2. package/dist/index.browser.js.map +1 -1
  3. package/dist/packlets/crypto-utils/converters.js +24 -4
  4. package/dist/packlets/crypto-utils/converters.js.map +1 -1
  5. package/dist/packlets/crypto-utils/hpkeProvider.js +333 -0
  6. package/dist/packlets/crypto-utils/hpkeProvider.js.map +1 -0
  7. package/dist/packlets/crypto-utils/index.browser.js +3 -0
  8. package/dist/packlets/crypto-utils/index.browser.js.map +1 -1
  9. package/dist/packlets/crypto-utils/index.js +2 -0
  10. package/dist/packlets/crypto-utils/index.js.map +1 -1
  11. package/dist/packlets/crypto-utils/keystore/converters.js +2 -2
  12. package/dist/packlets/crypto-utils/keystore/converters.js.map +1 -1
  13. package/dist/packlets/crypto-utils/keystore/keyStore.js +108 -3
  14. package/dist/packlets/crypto-utils/keystore/keyStore.js.map +1 -1
  15. package/dist/packlets/crypto-utils/keystore/model.js.map +1 -1
  16. package/dist/packlets/crypto-utils/model.js +21 -0
  17. package/dist/packlets/crypto-utils/model.js.map +1 -1
  18. package/dist/packlets/crypto-utils/nodeCryptoProvider.js +74 -0
  19. package/dist/packlets/crypto-utils/nodeCryptoProvider.js.map +1 -1
  20. package/dist/packlets/mustache/index.js.map +1 -1
  21. package/dist/packlets/mustache/interfaces.js.map +1 -1
  22. package/dist/packlets/mustache/mustacheTemplate.js +42 -4
  23. package/dist/packlets/mustache/mustacheTemplate.js.map +1 -1
  24. package/dist/ts-extras.d.ts +472 -18
  25. package/dist/tsdoc-metadata.json +1 -1
  26. package/lib/index.browser.d.ts +2 -1
  27. package/lib/index.browser.d.ts.map +1 -1
  28. package/lib/index.browser.js +3 -1
  29. package/lib/index.browser.js.map +1 -1
  30. package/lib/packlets/crypto-utils/converters.d.ts +12 -1
  31. package/lib/packlets/crypto-utils/converters.d.ts.map +1 -1
  32. package/lib/packlets/crypto-utils/converters.js +25 -5
  33. package/lib/packlets/crypto-utils/converters.js.map +1 -1
  34. package/lib/packlets/crypto-utils/hpkeProvider.d.ts +142 -0
  35. package/lib/packlets/crypto-utils/hpkeProvider.d.ts.map +1 -0
  36. package/lib/packlets/crypto-utils/hpkeProvider.js +337 -0
  37. package/lib/packlets/crypto-utils/hpkeProvider.js.map +1 -0
  38. package/lib/packlets/crypto-utils/index.browser.d.ts +1 -0
  39. package/lib/packlets/crypto-utils/index.browser.d.ts.map +1 -1
  40. package/lib/packlets/crypto-utils/index.browser.js +5 -1
  41. package/lib/packlets/crypto-utils/index.browser.js.map +1 -1
  42. package/lib/packlets/crypto-utils/index.d.ts +1 -0
  43. package/lib/packlets/crypto-utils/index.d.ts.map +1 -1
  44. package/lib/packlets/crypto-utils/index.js +4 -1
  45. package/lib/packlets/crypto-utils/index.js.map +1 -1
  46. package/lib/packlets/crypto-utils/keystore/converters.js +1 -1
  47. package/lib/packlets/crypto-utils/keystore/converters.js.map +1 -1
  48. package/lib/packlets/crypto-utils/keystore/keyStore.d.ts +32 -2
  49. package/lib/packlets/crypto-utils/keystore/keyStore.d.ts.map +1 -1
  50. package/lib/packlets/crypto-utils/keystore/keyStore.js +116 -11
  51. package/lib/packlets/crypto-utils/keystore/keyStore.js.map +1 -1
  52. package/lib/packlets/crypto-utils/keystore/model.d.ts +21 -3
  53. package/lib/packlets/crypto-utils/keystore/model.d.ts.map +1 -1
  54. package/lib/packlets/crypto-utils/keystore/model.js.map +1 -1
  55. package/lib/packlets/crypto-utils/model.d.ts +165 -9
  56. package/lib/packlets/crypto-utils/model.d.ts.map +1 -1
  57. package/lib/packlets/crypto-utils/model.js +22 -1
  58. package/lib/packlets/crypto-utils/model.js.map +1 -1
  59. package/lib/packlets/crypto-utils/nodeCryptoProvider.d.ts +39 -0
  60. package/lib/packlets/crypto-utils/nodeCryptoProvider.d.ts.map +1 -1
  61. package/lib/packlets/crypto-utils/nodeCryptoProvider.js +74 -0
  62. package/lib/packlets/crypto-utils/nodeCryptoProvider.js.map +1 -1
  63. package/lib/packlets/mustache/index.d.ts +1 -1
  64. package/lib/packlets/mustache/index.d.ts.map +1 -1
  65. package/lib/packlets/mustache/index.js.map +1 -1
  66. package/lib/packlets/mustache/interfaces.d.ts +34 -0
  67. package/lib/packlets/mustache/interfaces.d.ts.map +1 -1
  68. package/lib/packlets/mustache/interfaces.js.map +1 -1
  69. package/lib/packlets/mustache/mustacheTemplate.d.ts +2 -0
  70. package/lib/packlets/mustache/mustacheTemplate.d.ts.map +1 -1
  71. package/lib/packlets/mustache/mustacheTemplate.js +42 -4
  72. package/lib/packlets/mustache/mustacheTemplate.js.map +1 -1
  73. package/package.json +7 -7
@@ -54,7 +54,7 @@ var __importStar = (this && this.__importStar) || (function () {
54
54
  };
55
55
  })();
56
56
  Object.defineProperty(exports, "__esModule", { value: true });
57
- exports.ZipFileTree = exports.RecordJar = exports.Mustache = exports.Hash = exports.Experimental = exports.Csv = exports.Crypto = exports.CryptoUtils = exports.Converters = exports.AiAssist = void 0;
57
+ exports.ZipFileTree = exports.Yaml = exports.RecordJar = exports.Mustache = exports.Hash = exports.Experimental = exports.Csv = exports.Crypto = exports.CryptoUtils = exports.Converters = exports.AiAssist = void 0;
58
58
  /* c8 ignore start - Browser-specific export used conditionally in package.json */
59
59
  const AiAssist = __importStar(require("./packlets/ai-assist"));
60
60
  exports.AiAssist = AiAssist;
@@ -75,6 +75,8 @@ exports.Mustache = Mustache;
75
75
  // eslint-disable-next-line @rushstack/packlets/mechanics
76
76
  const RecordJar = __importStar(require("./packlets/record-jar/index.browser"));
77
77
  exports.RecordJar = RecordJar;
78
+ const Yaml = __importStar(require("./packlets/yaml"));
79
+ exports.Yaml = Yaml;
78
80
  const ZipFileTree = __importStar(require("./packlets/zip-file-tree"));
79
81
  exports.ZipFileTree = ZipFileTree;
80
82
  const conversion_1 = require("./packlets/conversion");
@@ -1 +1 @@
1
- {"version":3,"file":"index.browser.js","sourceRoot":"","sources":["../src/index.browser.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAEH,kFAAkF;AAClF,+DAAiD;AAkB/C,4BAAQ;AAjBV,yDAAyD;AACzD,mFAAqE;AAkBnE,kCAAW;AACI,6BAAM;AAlBvB,yDAAyD;AACzD,kEAAoD;AAkBlD,kBAAG;AAjBL,sEAAwD;AAkBtD,oCAAY;AAjBd,yDAAyD;AACzD,oEAAsD;AAiBpD,oBAAI;AAhBN,8DAAgD;AAiB9C,4BAAQ;AAhBV,yDAAyD;AACzD,+EAAiE;AAgB/D,8BAAS;AAfX,sEAAwD;AAgBtD,kCAAW;AAdb,sDAAmD;AAMjD,2FANO,uBAAU,OAMP;AAUZ,oBAAoB","sourcesContent":["/*\n * Copyright (c) 2020 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/* c8 ignore start - Browser-specific export used conditionally in package.json */\nimport * as AiAssist from './packlets/ai-assist';\n// eslint-disable-next-line @rushstack/packlets/mechanics\nimport * as CryptoUtils from './packlets/crypto-utils/index.browser';\n// eslint-disable-next-line @rushstack/packlets/mechanics\nimport * as Csv from './packlets/csv/index.browser';\nimport * as Experimental from './packlets/experimental';\n// eslint-disable-next-line @rushstack/packlets/mechanics\nimport * as Hash from './packlets/hash/index.browser';\nimport * as Mustache from './packlets/mustache';\n// eslint-disable-next-line @rushstack/packlets/mechanics\nimport * as RecordJar from './packlets/record-jar/index.browser';\nimport * as ZipFileTree from './packlets/zip-file-tree';\n\nimport { Converters } from './packlets/conversion';\n\n// Browser-safe exports - Node.js crypto-based providers excluded\n// Use BrowserCryptoProvider from @fgv/ts-web-extras for browser crypto\nexport {\n AiAssist,\n Converters,\n CryptoUtils,\n CryptoUtils as Crypto,\n Csv,\n Experimental,\n Hash,\n Mustache,\n RecordJar,\n ZipFileTree\n};\n/* c8 ignore stop */\n"]}
1
+ {"version":3,"file":"index.browser.js","sourceRoot":"","sources":["../src/index.browser.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAEH,kFAAkF;AAClF,+DAAiD;AAmB/C,4BAAQ;AAlBV,yDAAyD;AACzD,mFAAqE;AAmBnE,kCAAW;AACI,6BAAM;AAnBvB,yDAAyD;AACzD,kEAAoD;AAmBlD,kBAAG;AAlBL,sEAAwD;AAmBtD,oCAAY;AAlBd,yDAAyD;AACzD,oEAAsD;AAkBpD,oBAAI;AAjBN,8DAAgD;AAkB9C,4BAAQ;AAjBV,yDAAyD;AACzD,+EAAiE;AAiB/D,8BAAS;AAhBX,sDAAwC;AAiBtC,oBAAI;AAhBN,sEAAwD;AAiBtD,kCAAW;AAfb,sDAAmD;AAMjD,2FANO,uBAAU,OAMP;AAWZ,oBAAoB","sourcesContent":["/*\n * Copyright (c) 2020 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/* c8 ignore start - Browser-specific export used conditionally in package.json */\nimport * as AiAssist from './packlets/ai-assist';\n// eslint-disable-next-line @rushstack/packlets/mechanics\nimport * as CryptoUtils from './packlets/crypto-utils/index.browser';\n// eslint-disable-next-line @rushstack/packlets/mechanics\nimport * as Csv from './packlets/csv/index.browser';\nimport * as Experimental from './packlets/experimental';\n// eslint-disable-next-line @rushstack/packlets/mechanics\nimport * as Hash from './packlets/hash/index.browser';\nimport * as Mustache from './packlets/mustache';\n// eslint-disable-next-line @rushstack/packlets/mechanics\nimport * as RecordJar from './packlets/record-jar/index.browser';\nimport * as Yaml from './packlets/yaml';\nimport * as ZipFileTree from './packlets/zip-file-tree';\n\nimport { Converters } from './packlets/conversion';\n\n// Browser-safe exports - Node.js crypto-based providers excluded\n// Use BrowserCryptoProvider from @fgv/ts-web-extras for browser crypto\nexport {\n AiAssist,\n Converters,\n CryptoUtils,\n CryptoUtils as Crypto,\n Csv,\n Experimental,\n Hash,\n Mustache,\n RecordJar,\n Yaml,\n ZipFileTree\n};\n/* c8 ignore stop */\n"]}
@@ -1,6 +1,6 @@
1
1
  import { JsonValue } from '@fgv/ts-json-base';
2
2
  import { Converter } from '@fgv/ts-utils';
3
- import { EncryptedFileErrorMode, EncryptedFileFormat, EncryptionAlgorithm, IEncryptedFile, IKeyDerivationParams, INamedSecret, KeyDerivationFunction } from './model';
3
+ import { EncryptedFileErrorMode, EncryptedFileFormat, EncryptionAlgorithm, IArgon2idKeyDerivationParams, IEncryptedFile, IKeyDerivationParams, INamedSecret, IPbkdf2KeyDerivationParams, KeyDerivationFunction } from './model';
4
4
  /**
5
5
  * Converter for {@link CryptoUtils.EncryptionAlgorithm | encryption algorithm} values.
6
6
  * @public
@@ -21,8 +21,19 @@ export declare const encryptedFileErrorMode: Converter<EncryptedFileErrorMode>;
21
21
  * @public
22
22
  */
23
23
  export declare const keyDerivationFunction: Converter<KeyDerivationFunction>;
24
+ /**
25
+ * Converter for {@link CryptoUtils.IPbkdf2KeyDerivationParams | PBKDF2 key derivation parameters}.
26
+ * @public
27
+ */
28
+ export declare const pbkdf2KeyDerivationParams: Converter<IPbkdf2KeyDerivationParams>;
29
+ /**
30
+ * Converter for {@link CryptoUtils.IArgon2idKeyDerivationParams | Argon2id key derivation parameters}.
31
+ * @public
32
+ */
33
+ export declare const argon2idKeyDerivationParams: Converter<IArgon2idKeyDerivationParams>;
24
34
  /**
25
35
  * Converter for {@link CryptoUtils.IKeyDerivationParams | key derivation parameters}.
36
+ * Handles both PBKDF2 and Argon2id discriminated union arms.
26
37
  * @public
27
38
  */
28
39
  export declare const keyDerivationParams: Converter<IKeyDerivationParams>;
@@ -1 +1 @@
1
- {"version":3,"file":"converters.d.ts","sourceRoot":"","sources":["../../../src/packlets/crypto-utils/converters.ts"],"names":[],"mappings":"AAoBA,OAAO,EAAgC,SAAS,EAAE,MAAM,mBAAmB,CAAC;AAC5E,OAAO,EAAE,SAAS,EAA6B,MAAM,eAAe,CAAC;AAErE,OAAO,EACL,sBAAsB,EACtB,mBAAmB,EACnB,mBAAmB,EACnB,cAAc,EACd,oBAAoB,EACpB,YAAY,EACZ,qBAAqB,EACtB,MAAM,SAAS,CAAC;AAMjB;;;GAGG;AACH,eAAO,MAAM,mBAAmB,EAAE,SAAS,CAAC,mBAAmB,CACiB,CAAC;AAEjF;;;GAGG;AACH,eAAO,MAAM,mBAAmB,EAAE,SAAS,CAAC,mBAAmB,CAE7D,CAAC;AAEH;;;GAGG;AACH,eAAO,MAAM,sBAAsB,EAAE,SAAS,CAAC,sBAAsB,CACS,CAAC;AAE/E;;;GAGG;AACH,eAAO,MAAM,qBAAqB,EAAE,SAAS,CAAC,qBAAqB,CACJ,CAAC;AAEhE;;;GAGG;AACH,eAAO,MAAM,mBAAmB,EAAE,SAAS,CAAC,oBAAoB,CAI9D,CAAC;AAEH;;;GAGG;AACH,eAAO,MAAM,YAAY,EAAE,SAAS,CAAC,MAAM,CAOzC,CAAC;AAMH;;;GAGG;AACH,eAAO,MAAM,oBAAoB,EAAE,SAAS,CAAC,UAAU,CAoBrD,CAAC;AAMH;;;;GAIG;AACH,eAAO,MAAM,WAAW,EAAE,SAAS,CAAC,YAAY,CAG9C,CAAC;AAsCH;;;;;;GAMG;AACH,wBAAgB,4BAA4B,CAAC,SAAS,GAAG,SAAS,EAChE,iBAAiB,CAAC,EAAE,SAAS,CAAC,SAAS,CAAC,GACvC,SAAS,CAAC,cAAc,CAAC,SAAS,CAAC,CAAC,CAyBtC;AAED;;;GAGG;AACH,eAAO,MAAM,aAAa,EAAE,SAAS,CAAC,cAAc,CAAkC,CAAC"}
1
+ {"version":3,"file":"converters.d.ts","sourceRoot":"","sources":["../../../src/packlets/crypto-utils/converters.ts"],"names":[],"mappings":"AAoBA,OAAO,EAAgC,SAAS,EAAE,MAAM,mBAAmB,CAAC;AAC5E,OAAO,EAAE,SAAS,EAA6B,MAAM,eAAe,CAAC;AAErE,OAAO,EACL,sBAAsB,EACtB,mBAAmB,EACnB,mBAAmB,EACnB,4BAA4B,EAC5B,cAAc,EACd,oBAAoB,EACpB,YAAY,EACZ,0BAA0B,EAC1B,qBAAqB,EACtB,MAAM,SAAS,CAAC;AAMjB;;;GAGG;AACH,eAAO,MAAM,mBAAmB,EAAE,SAAS,CAAC,mBAAmB,CACiB,CAAC;AAEjF;;;GAGG;AACH,eAAO,MAAM,mBAAmB,EAAE,SAAS,CAAC,mBAAmB,CAE7D,CAAC;AAEH;;;GAGG;AACH,eAAO,MAAM,sBAAsB,EAAE,SAAS,CAAC,sBAAsB,CACS,CAAC;AAE/E;;;GAGG;AACH,eAAO,MAAM,qBAAqB,EAAE,SAAS,CAAC,qBAAqB,CACQ,CAAC;AAE5E;;;GAGG;AACH,eAAO,MAAM,yBAAyB,EAAE,SAAS,CAAC,0BAA0B,CAKxE,CAAC;AAEL;;;GAGG;AACH,eAAO,MAAM,2BAA2B,EAAE,SAAS,CAAC,4BAA4B,CAO5E,CAAC;AAEL;;;;GAIG;AACH,eAAO,MAAM,mBAAmB,EAAE,SAAS,CAAC,oBAAoB,CAG9D,CAAC;AAEH;;;GAGG;AACH,eAAO,MAAM,YAAY,EAAE,SAAS,CAAC,MAAM,CAOzC,CAAC;AAMH;;;GAGG;AACH,eAAO,MAAM,oBAAoB,EAAE,SAAS,CAAC,UAAU,CAoBrD,CAAC;AAMH;;;;GAIG;AACH,eAAO,MAAM,WAAW,EAAE,SAAS,CAAC,YAAY,CAG9C,CAAC;AAsCH;;;;;;GAMG;AACH,wBAAgB,4BAA4B,CAAC,SAAS,GAAG,SAAS,EAChE,iBAAiB,CAAC,EAAE,SAAS,CAAC,SAAS,CAAC,GACvC,SAAS,CAAC,cAAc,CAAC,SAAS,CAAC,CAAC,CAyBtC;AAED;;;GAGG;AACH,eAAO,MAAM,aAAa,EAAE,SAAS,CAAC,cAAc,CAAkC,CAAC"}
@@ -52,7 +52,7 @@ var __importStar = (this && this.__importStar) || (function () {
52
52
  };
53
53
  })();
54
54
  Object.defineProperty(exports, "__esModule", { value: true });
55
- exports.encryptedFile = exports.namedSecret = exports.uint8ArrayFromBase64 = exports.base64String = exports.keyDerivationParams = exports.keyDerivationFunction = exports.encryptedFileErrorMode = exports.encryptedFileFormat = exports.encryptionAlgorithm = void 0;
55
+ exports.encryptedFile = exports.namedSecret = exports.uint8ArrayFromBase64 = exports.base64String = exports.keyDerivationParams = exports.argon2idKeyDerivationParams = exports.pbkdf2KeyDerivationParams = exports.keyDerivationFunction = exports.encryptedFileErrorMode = exports.encryptedFileFormat = exports.encryptionAlgorithm = void 0;
56
56
  exports.createEncryptedFileConverter = createEncryptedFileConverter;
57
57
  const ts_json_base_1 = require("@fgv/ts-json-base");
58
58
  const ts_utils_1 = require("@fgv/ts-utils");
@@ -81,16 +81,36 @@ exports.encryptedFileErrorMode = ts_utils_1.Converters.enumeratedValue(['fail',
81
81
  * Converter for {@link CryptoUtils.KeyDerivationFunction | key derivation function} type.
82
82
  * @public
83
83
  */
84
- exports.keyDerivationFunction = ts_utils_1.Converters.enumeratedValue(['pbkdf2']);
84
+ exports.keyDerivationFunction = ts_utils_1.Converters.enumeratedValue(['pbkdf2', 'argon2id']);
85
85
  /**
86
- * Converter for {@link CryptoUtils.IKeyDerivationParams | key derivation parameters}.
86
+ * Converter for {@link CryptoUtils.IPbkdf2KeyDerivationParams | PBKDF2 key derivation parameters}.
87
87
  * @public
88
88
  */
89
- exports.keyDerivationParams = ts_utils_1.Converters.object({
90
- kdf: exports.keyDerivationFunction,
89
+ exports.pbkdf2KeyDerivationParams = ts_utils_1.Converters.object({
90
+ kdf: ts_utils_1.Converters.enumeratedValue(['pbkdf2']),
91
91
  salt: ts_utils_1.Converters.string,
92
92
  iterations: ts_utils_1.Converters.number
93
93
  });
94
+ /**
95
+ * Converter for {@link CryptoUtils.IArgon2idKeyDerivationParams | Argon2id key derivation parameters}.
96
+ * @public
97
+ */
98
+ exports.argon2idKeyDerivationParams = ts_utils_1.Converters.object({
99
+ kdf: ts_utils_1.Converters.enumeratedValue(['argon2id']),
100
+ salt: ts_utils_1.Converters.string,
101
+ memoryKiB: ts_utils_1.Converters.number,
102
+ iterations: ts_utils_1.Converters.number,
103
+ parallelism: ts_utils_1.Converters.number
104
+ });
105
+ /**
106
+ * Converter for {@link CryptoUtils.IKeyDerivationParams | key derivation parameters}.
107
+ * Handles both PBKDF2 and Argon2id discriminated union arms.
108
+ * @public
109
+ */
110
+ exports.keyDerivationParams = ts_utils_1.Converters.oneOf([
111
+ exports.pbkdf2KeyDerivationParams,
112
+ exports.argon2idKeyDerivationParams
113
+ ]);
94
114
  /**
95
115
  * Converter for base64 strings (validates format).
96
116
  * @public
@@ -1 +1 @@
1
- {"version":3,"file":"converters.js","sourceRoot":"","sources":["../../../src/packlets/crypto-utils/converters.ts"],"names":[],"mappings":"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","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 { Converters as JsonConverters, JsonValue } from '@fgv/ts-json-base';\nimport { Converter, Converters, fail, succeed } from '@fgv/ts-utils';\nimport * as Constants from './constants';\nimport {\n EncryptedFileErrorMode,\n EncryptedFileFormat,\n EncryptionAlgorithm,\n IEncryptedFile,\n IKeyDerivationParams,\n INamedSecret,\n KeyDerivationFunction\n} from './model';\n\n// ============================================================================\n// Base Converters\n// ============================================================================\n\n/**\n * Converter for {@link CryptoUtils.EncryptionAlgorithm | encryption algorithm} values.\n * @public\n */\nexport const encryptionAlgorithm: Converter<EncryptionAlgorithm> =\n Converters.enumeratedValue<EncryptionAlgorithm>([Constants.DEFAULT_ALGORITHM]);\n\n/**\n * Converter for {@link CryptoUtils.EncryptedFileFormat | encrypted file format} version.\n * @public\n */\nexport const encryptedFileFormat: Converter<EncryptedFileFormat> = Converters.enumeratedValue([\n Constants.ENCRYPTED_FILE_FORMAT\n]);\n\n/**\n * Converter for {@link CryptoUtils.EncryptedFileErrorMode | encrypted file error mode}.\n * @public\n */\nexport const encryptedFileErrorMode: Converter<EncryptedFileErrorMode> =\n Converters.enumeratedValue<EncryptedFileErrorMode>(['fail', 'skip', 'warn']);\n\n/**\n * Converter for {@link CryptoUtils.KeyDerivationFunction | key derivation function} type.\n * @public\n */\nexport const keyDerivationFunction: Converter<KeyDerivationFunction> =\n Converters.enumeratedValue<KeyDerivationFunction>(['pbkdf2']);\n\n/**\n * Converter for {@link CryptoUtils.IKeyDerivationParams | key derivation parameters}.\n * @public\n */\nexport const keyDerivationParams: Converter<IKeyDerivationParams> = Converters.object<IKeyDerivationParams>({\n kdf: keyDerivationFunction,\n salt: Converters.string,\n iterations: Converters.number\n});\n\n/**\n * Converter for base64 strings (validates format).\n * @public\n */\nexport const base64String: Converter<string> = Converters.string.withConstraint((value) => {\n // Basic base64 validation - check for valid characters and padding\n const base64Regex = /^[A-Za-z0-9+/]*={0,2}$/;\n if (!base64Regex.test(value)) {\n return fail('Invalid base64 encoding');\n }\n return succeed(value);\n});\n\n// ============================================================================\n// Uint8Array Converter\n// ============================================================================\n\n/**\n * Converter which converts a base64 string to a Uint8Array.\n * @public\n */\nexport const uint8ArrayFromBase64: Converter<Uint8Array> = Converters.string.map((base64) => {\n try {\n // Use Buffer in Node.js environment, atob in browser\n if (typeof Buffer !== 'undefined') {\n return succeed(Uint8Array.from(Buffer.from(base64, 'base64')));\n }\n /* c8 ignore start - Browser-only fallback cannot be tested in Node.js environment */\n const binaryString = atob(base64);\n const bytes = new Uint8Array(binaryString.length);\n for (let i = 0; i < binaryString.length; i++) {\n bytes[i] = binaryString.charCodeAt(i);\n }\n return succeed(bytes);\n } catch (e) {\n // This catch is for browser's atob() which throws on invalid base64\n // Node's Buffer.from() doesn't throw, it ignores invalid characters\n const message = e instanceof Error ? e.message : String(e);\n return fail(`Invalid base64: ${message}`);\n }\n /* c8 ignore stop */\n});\n\n// ============================================================================\n// Named Secret Converter\n// ============================================================================\n\n/**\n * Converter for {@link CryptoUtils.INamedSecret | named secret} from JSON representation.\n * Expects key as base64 string in JSON, converts to Uint8Array.\n * @public\n */\nexport const namedSecret: Converter<INamedSecret> = Converters.object<INamedSecret>({\n name: Converters.string,\n key: uint8ArrayFromBase64\n});\n\n// ============================================================================\n// Encrypted File Converter Factory\n// ============================================================================\n\n/**\n * Base encrypted file structure without metadata typing.\n * Used internally by the converter factory.\n */\ninterface IBaseEncryptedFile {\n readonly format: EncryptedFileFormat;\n readonly secretName: string;\n readonly algorithm: EncryptionAlgorithm;\n readonly iv: string;\n readonly authTag: string;\n readonly encryptedData: string;\n readonly keyDerivation?: IKeyDerivationParams;\n readonly metadata?: JsonValue;\n}\n\n/**\n * Base converter for encrypted file structure (without typed metadata).\n */\nconst baseEncryptedFileConverter: Converter<IBaseEncryptedFile> = Converters.object<IBaseEncryptedFile>(\n {\n format: encryptedFileFormat,\n secretName: Converters.string,\n algorithm: encryptionAlgorithm,\n iv: base64String,\n authTag: base64String,\n encryptedData: base64String,\n keyDerivation: keyDerivationParams,\n metadata: JsonConverters.jsonValue\n },\n { optionalFields: ['keyDerivation', 'metadata'] }\n);\n\n/**\n * Creates a converter for {@link CryptoUtils.IEncryptedFile | encrypted files} with optional typed metadata.\n * @typeParam TMetadata - Type of optional unencrypted metadata\n * @param metadataConverter - Optional converter for validating metadata field\n * @returns A converter that validates and converts encrypted file structures\n * @public\n */\nexport function createEncryptedFileConverter<TMetadata = JsonValue>(\n metadataConverter?: Converter<TMetadata>\n): Converter<IEncryptedFile<TMetadata>> {\n return Converters.generic<IEncryptedFile<TMetadata>>((from: unknown) => {\n // First validate base structure\n const baseResult = baseEncryptedFileConverter.convert(from);\n if (baseResult.isFailure()) {\n return fail(baseResult.message);\n }\n\n const base = baseResult.value;\n\n // Validate metadata with specific converter if provided and metadata exists\n if (metadataConverter !== undefined && base.metadata !== undefined) {\n const metaResult = metadataConverter.convert(base.metadata);\n if (metaResult.isFailure()) {\n return fail(`Invalid metadata: ${metaResult.message}`);\n }\n return succeed({\n ...base,\n metadata: metaResult.value\n } as IEncryptedFile<TMetadata>);\n }\n\n // Return as-is (metadata is either undefined or untyped JsonValue)\n return succeed(base as IEncryptedFile<TMetadata>);\n });\n}\n\n/**\n * Default converter for encrypted files without typed metadata.\n * @public\n */\nexport const encryptedFile: Converter<IEncryptedFile> = createEncryptedFileConverter();\n"]}
1
+ {"version":3,"file":"converters.js","sourceRoot":"","sources":["../../../src/packlets/crypto-utils/converters.ts"],"names":[],"mappings":"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","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 { Converters as JsonConverters, JsonValue } from '@fgv/ts-json-base';\nimport { Converter, Converters, fail, succeed } from '@fgv/ts-utils';\nimport * as Constants from './constants';\nimport {\n EncryptedFileErrorMode,\n EncryptedFileFormat,\n EncryptionAlgorithm,\n IArgon2idKeyDerivationParams,\n IEncryptedFile,\n IKeyDerivationParams,\n INamedSecret,\n IPbkdf2KeyDerivationParams,\n KeyDerivationFunction\n} from './model';\n\n// ============================================================================\n// Base Converters\n// ============================================================================\n\n/**\n * Converter for {@link CryptoUtils.EncryptionAlgorithm | encryption algorithm} values.\n * @public\n */\nexport const encryptionAlgorithm: Converter<EncryptionAlgorithm> =\n Converters.enumeratedValue<EncryptionAlgorithm>([Constants.DEFAULT_ALGORITHM]);\n\n/**\n * Converter for {@link CryptoUtils.EncryptedFileFormat | encrypted file format} version.\n * @public\n */\nexport const encryptedFileFormat: Converter<EncryptedFileFormat> = Converters.enumeratedValue([\n Constants.ENCRYPTED_FILE_FORMAT\n]);\n\n/**\n * Converter for {@link CryptoUtils.EncryptedFileErrorMode | encrypted file error mode}.\n * @public\n */\nexport const encryptedFileErrorMode: Converter<EncryptedFileErrorMode> =\n Converters.enumeratedValue<EncryptedFileErrorMode>(['fail', 'skip', 'warn']);\n\n/**\n * Converter for {@link CryptoUtils.KeyDerivationFunction | key derivation function} type.\n * @public\n */\nexport const keyDerivationFunction: Converter<KeyDerivationFunction> =\n Converters.enumeratedValue<KeyDerivationFunction>(['pbkdf2', 'argon2id']);\n\n/**\n * Converter for {@link CryptoUtils.IPbkdf2KeyDerivationParams | PBKDF2 key derivation parameters}.\n * @public\n */\nexport const pbkdf2KeyDerivationParams: Converter<IPbkdf2KeyDerivationParams> =\n Converters.object<IPbkdf2KeyDerivationParams>({\n kdf: Converters.enumeratedValue<'pbkdf2'>(['pbkdf2']),\n salt: Converters.string,\n iterations: Converters.number\n });\n\n/**\n * Converter for {@link CryptoUtils.IArgon2idKeyDerivationParams | Argon2id key derivation parameters}.\n * @public\n */\nexport const argon2idKeyDerivationParams: Converter<IArgon2idKeyDerivationParams> =\n Converters.object<IArgon2idKeyDerivationParams>({\n kdf: Converters.enumeratedValue<'argon2id'>(['argon2id']),\n salt: Converters.string,\n memoryKiB: Converters.number,\n iterations: Converters.number,\n parallelism: Converters.number\n });\n\n/**\n * Converter for {@link CryptoUtils.IKeyDerivationParams | key derivation parameters}.\n * Handles both PBKDF2 and Argon2id discriminated union arms.\n * @public\n */\nexport const keyDerivationParams: Converter<IKeyDerivationParams> = Converters.oneOf<IKeyDerivationParams>([\n pbkdf2KeyDerivationParams,\n argon2idKeyDerivationParams\n]);\n\n/**\n * Converter for base64 strings (validates format).\n * @public\n */\nexport const base64String: Converter<string> = Converters.string.withConstraint((value) => {\n // Basic base64 validation - check for valid characters and padding\n const base64Regex = /^[A-Za-z0-9+/]*={0,2}$/;\n if (!base64Regex.test(value)) {\n return fail('Invalid base64 encoding');\n }\n return succeed(value);\n});\n\n// ============================================================================\n// Uint8Array Converter\n// ============================================================================\n\n/**\n * Converter which converts a base64 string to a Uint8Array.\n * @public\n */\nexport const uint8ArrayFromBase64: Converter<Uint8Array> = Converters.string.map((base64) => {\n try {\n // Use Buffer in Node.js environment, atob in browser\n if (typeof Buffer !== 'undefined') {\n return succeed(Uint8Array.from(Buffer.from(base64, 'base64')));\n }\n /* c8 ignore start - Browser-only fallback cannot be tested in Node.js environment */\n const binaryString = atob(base64);\n const bytes = new Uint8Array(binaryString.length);\n for (let i = 0; i < binaryString.length; i++) {\n bytes[i] = binaryString.charCodeAt(i);\n }\n return succeed(bytes);\n } catch (e) {\n // This catch is for browser's atob() which throws on invalid base64\n // Node's Buffer.from() doesn't throw, it ignores invalid characters\n const message = e instanceof Error ? e.message : String(e);\n return fail(`Invalid base64: ${message}`);\n }\n /* c8 ignore stop */\n});\n\n// ============================================================================\n// Named Secret Converter\n// ============================================================================\n\n/**\n * Converter for {@link CryptoUtils.INamedSecret | named secret} from JSON representation.\n * Expects key as base64 string in JSON, converts to Uint8Array.\n * @public\n */\nexport const namedSecret: Converter<INamedSecret> = Converters.object<INamedSecret>({\n name: Converters.string,\n key: uint8ArrayFromBase64\n});\n\n// ============================================================================\n// Encrypted File Converter Factory\n// ============================================================================\n\n/**\n * Base encrypted file structure without metadata typing.\n * Used internally by the converter factory.\n */\ninterface IBaseEncryptedFile {\n readonly format: EncryptedFileFormat;\n readonly secretName: string;\n readonly algorithm: EncryptionAlgorithm;\n readonly iv: string;\n readonly authTag: string;\n readonly encryptedData: string;\n readonly keyDerivation?: IKeyDerivationParams;\n readonly metadata?: JsonValue;\n}\n\n/**\n * Base converter for encrypted file structure (without typed metadata).\n */\nconst baseEncryptedFileConverter: Converter<IBaseEncryptedFile> = Converters.object<IBaseEncryptedFile>(\n {\n format: encryptedFileFormat,\n secretName: Converters.string,\n algorithm: encryptionAlgorithm,\n iv: base64String,\n authTag: base64String,\n encryptedData: base64String,\n keyDerivation: keyDerivationParams,\n metadata: JsonConverters.jsonValue\n },\n { optionalFields: ['keyDerivation', 'metadata'] }\n);\n\n/**\n * Creates a converter for {@link CryptoUtils.IEncryptedFile | encrypted files} with optional typed metadata.\n * @typeParam TMetadata - Type of optional unencrypted metadata\n * @param metadataConverter - Optional converter for validating metadata field\n * @returns A converter that validates and converts encrypted file structures\n * @public\n */\nexport function createEncryptedFileConverter<TMetadata = JsonValue>(\n metadataConverter?: Converter<TMetadata>\n): Converter<IEncryptedFile<TMetadata>> {\n return Converters.generic<IEncryptedFile<TMetadata>>((from: unknown) => {\n // First validate base structure\n const baseResult = baseEncryptedFileConverter.convert(from);\n if (baseResult.isFailure()) {\n return fail(baseResult.message);\n }\n\n const base = baseResult.value;\n\n // Validate metadata with specific converter if provided and metadata exists\n if (metadataConverter !== undefined && base.metadata !== undefined) {\n const metaResult = metadataConverter.convert(base.metadata);\n if (metaResult.isFailure()) {\n return fail(`Invalid metadata: ${metaResult.message}`);\n }\n return succeed({\n ...base,\n metadata: metaResult.value\n } as IEncryptedFile<TMetadata>);\n }\n\n // Return as-is (metadata is either undefined or untyped JsonValue)\n return succeed(base as IEncryptedFile<TMetadata>);\n });\n}\n\n/**\n * Default converter for encrypted files without typed metadata.\n * @public\n */\nexport const encryptedFile: Converter<IEncryptedFile> = createEncryptedFileConverter();\n"]}
@@ -0,0 +1,142 @@
1
+ import { Result } from '@fgv/ts-utils';
2
+ /**
3
+ * Output of {@link HpkeProvider.sealBase}.
4
+ *
5
+ * The `ciphertext` field includes the 16-byte AES-256-GCM authentication tag
6
+ * appended by Web Crypto's `encrypt()` operation: `length = plaintext.length + 16`.
7
+ * @public
8
+ */
9
+ export interface IHpkeSealResult {
10
+ /**
11
+ * Encapsulated key — 32-byte raw X25519 ephemeral public key (`enc` in RFC 9180).
12
+ * Must be transmitted to the recipient alongside `ciphertext`.
13
+ */
14
+ readonly enc: Uint8Array;
15
+ /**
16
+ * AES-256-GCM ciphertext with the 16-byte authentication tag appended.
17
+ * Length = `plaintext.length + 16`.
18
+ */
19
+ readonly ciphertext: Uint8Array;
20
+ }
21
+ /**
22
+ * HPKE base mode (RFC 9180) — `DHKEM(X25519, HKDF-SHA256) + HKDF-SHA256 + AES-256-GCM`.
23
+ *
24
+ * Class-based provider that captures a `SubtleCrypto` instance at construction,
25
+ * matching the existing `NodeCryptoProvider` / `BrowserCryptoProvider` / `KeyStore`
26
+ * factory pattern used throughout `@fgv/ts-extras/crypto-utils`.
27
+ *
28
+ * **Node.js usage:**
29
+ * ```typescript
30
+ * import * as crypto from 'crypto';
31
+ * const hpke = HpkeProvider.create(crypto.webcrypto.subtle).orThrow();
32
+ * ```
33
+ *
34
+ * **Browser usage:**
35
+ * ```typescript
36
+ * const hpke = HpkeProvider.create(globalThis.crypto.subtle).orThrow();
37
+ * ```
38
+ *
39
+ * **Runtime requirements:** Node.js 20+ (X25519 in `crypto.webcrypto`);
40
+ * Chrome 113+, Safari 16.4+, Firefox 118+ (X25519 added to Web Crypto in 2023).
41
+ * @public
42
+ */
43
+ export declare class HpkeProvider {
44
+ private readonly _subtle;
45
+ private constructor();
46
+ /**
47
+ * Creates an `HpkeProvider` bound to the given `SubtleCrypto` instance.
48
+ *
49
+ * @param subtle - Web Crypto SubtleCrypto instance.
50
+ * Node.js: `(await import('crypto')).webcrypto.subtle`.
51
+ * Browser: `globalThis.crypto.subtle`.
52
+ * @returns `Success` with the provider, or `Failure` if construction fails.
53
+ */
54
+ static create(subtle: SubtleCrypto): Result<HpkeProvider>;
55
+ /**
56
+ * HPKE base-mode seal (sender side). RFC 9180 §6.1.
57
+ *
58
+ * Generates a fresh ephemeral X25519 keypair, runs DHKEM Encap to produce a
59
+ * shared secret and `enc` (32-byte raw ephemeral public key), derives the AEAD
60
+ * key and nonce deterministically via the RFC 9180 key schedule, then encrypts
61
+ * `plaintext` with AES-256-GCM.
62
+ *
63
+ * @param recipientPublicKey - Recipient's X25519 public `CryptoKey`
64
+ * (`algorithm.name === 'X25519'`, `type === 'public'`, **`extractable: true`**).
65
+ * Must be extractable — DHKEM Encap calls `exportKey('raw', ...)` on this key to
66
+ * build the KEM shared-secret context. Keys imported with `extractable: false` will
67
+ * cause this method to return a `Failure`.
68
+ * @param info - Context-binding bytes. **Load-bearing — no default.**
69
+ * Binds this ciphertext to a specific application context, preventing replay
70
+ * across different contexts sharing the same recipient keypair.
71
+ * Use `new TextEncoder().encode('myapp/v1/use-case\x00' + contextId)` pattern.
72
+ * Never pass an empty array in production: empty `info` provides no context binding.
73
+ * @param aad - Additional authenticated data. Integrity-protected but not encrypted.
74
+ * `new Uint8Array(0)` is valid when no AAD is needed.
75
+ * @param plaintext - Bytes to encrypt. `new Uint8Array(0)` is valid.
76
+ * @returns `Success` with `{ enc, ciphertext }`, or `Failure` with error context.
77
+ */
78
+ sealBase(recipientPublicKey: CryptoKey, info: Uint8Array, aad: Uint8Array, plaintext: Uint8Array): Promise<Result<IHpkeSealResult>>;
79
+ /**
80
+ * HPKE base-mode open (recipient side). RFC 9180 §6.1.
81
+ *
82
+ * Decapsulates `enc` using the recipient's X25519 private key, derives the same
83
+ * AEAD key and nonce from the shared secret and `info`, then authenticates and
84
+ * decrypts `ciphertext` with AES-256-GCM.
85
+ *
86
+ * Returns `Failure` on any of:
87
+ * - Wrong private key (different DH output → different key derivation)
88
+ * - Wrong `info` (different key schedule context → different AEAD key)
89
+ * - Wrong `aad` (AES-GCM authentication fails)
90
+ * - Tampered `ciphertext` or `enc` (authentication fails or DH fails)
91
+ * - `enc` not exactly 32 bytes
92
+ * - `ciphertext` shorter than 16 bytes (no room for authentication tag)
93
+ *
94
+ * @param recipientPrivateKey - Recipient's X25519 private `CryptoKey`
95
+ * (`algorithm.name === 'X25519'`, `type === 'private'`, `usages` includes `'deriveBits'`).
96
+ * **Must be extractable** (`extractable: true`) — the recipient's public key bytes
97
+ * are recovered from the JWK `x` field during Decap.
98
+ * @param info - Context-binding bytes. Must exactly match `info` from `sealBase`.
99
+ * @param aad - Must exactly match `aad` from `sealBase`.
100
+ * @param enc - The encapsulated key from `sealBase` — exactly 32 bytes.
101
+ * @param ciphertext - The ciphertext from `sealBase` — `plaintext.length + 16` bytes.
102
+ * @returns `Success` with decrypted plaintext bytes, or `Failure` with error context.
103
+ */
104
+ openBase(recipientPrivateKey: CryptoKey, info: Uint8Array, aad: Uint8Array, enc: Uint8Array, ciphertext: Uint8Array): Promise<Result<Uint8Array>>;
105
+ /**
106
+ * HKDF-SHA256 key derivation (RFC 5869). Extract-then-Expand using SHA-256.
107
+ *
108
+ * This is raw RFC 5869 HKDF — it does **not** use RFC 9180's labeled variants.
109
+ * The HPKE key schedule internally uses labeled HKDF; this method is the unlabeled
110
+ * version for callers that need standalone key derivation.
111
+ *
112
+ * @param secret - Input keying material (IKM). Any length.
113
+ * @param salt - Optional salt. Use `new Uint8Array(0)` if no salt is available
114
+ * (RFC 5869: 32 zero bytes are used internally when salt is empty).
115
+ * @param info - Context / application-binding bytes. Any length.
116
+ * @param length - Number of output bytes to derive. Maximum 8160 bytes (255 × 32).
117
+ * @returns `Success` with derived bytes, or `Failure` with error context.
118
+ */
119
+ hkdf(secret: Uint8Array, salt: Uint8Array, info: Uint8Array, length: number): Promise<Result<Uint8Array>>;
120
+ /**
121
+ * Encodes an {@link IHpkeSealResult} as a single contiguous byte array for wire transport.
122
+ *
123
+ * Format: `enc` (32 bytes, fixed) || `ciphertext` (variable length).
124
+ * The 32-byte `enc` length is fixed for X25519; the split point is unambiguous.
125
+ *
126
+ * @param result - The output of {@link HpkeProvider.sealBase}.
127
+ * @returns Concatenated bytes: `enc || ciphertext`.
128
+ */
129
+ static encodeEnvelope(result: IHpkeSealResult): Uint8Array;
130
+ /**
131
+ * Decodes an envelope produced by {@link HpkeProvider.encodeEnvelope}.
132
+ *
133
+ * Validates that the buffer is at least 48 bytes (32-byte enc + 16-byte minimum
134
+ * ciphertext containing the AES-GCM auth tag; zero-length plaintext is the minimum
135
+ * meaningful case).
136
+ *
137
+ * @param envelope - Envelope bytes from `encodeEnvelope`.
138
+ * @returns `Success` with `{ enc, ciphertext }`, or `Failure` if malformed.
139
+ */
140
+ static decodeEnvelope(envelope: Uint8Array): Result<IHpkeSealResult>;
141
+ }
142
+ //# sourceMappingURL=hpkeProvider.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"hpkeProvider.d.ts","sourceRoot":"","sources":["../../../src/packlets/crypto-utils/hpkeProvider.ts"],"names":[],"mappings":"AAoBA,OAAO,EAAE,MAAM,EAAoD,MAAM,eAAe,CAAC;AAoOzF;;;;;;GAMG;AACH,MAAM,WAAW,eAAe;IAC9B;;;OAGG;IACH,QAAQ,CAAC,GAAG,EAAE,UAAU,CAAC;IAEzB;;;OAGG;IACH,QAAQ,CAAC,UAAU,EAAE,UAAU,CAAC;CACjC;AAID;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,qBAAa,YAAY;IACvB,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAe;IAEvC,OAAO;IAIP;;;;;;;OAOG;WACW,MAAM,CAAC,MAAM,EAAE,YAAY,GAAG,MAAM,CAAC,YAAY,CAAC;IAIhE;;;;;;;;;;;;;;;;;;;;;;OAsBG;IACU,QAAQ,CACnB,kBAAkB,EAAE,SAAS,EAC7B,IAAI,EAAE,UAAU,EAChB,GAAG,EAAE,UAAU,EACf,SAAS,EAAE,UAAU,GACpB,OAAO,CAAC,MAAM,CAAC,eAAe,CAAC,CAAC;IAenC;;;;;;;;;;;;;;;;;;;;;;;;OAwBG;IACU,QAAQ,CACnB,mBAAmB,EAAE,SAAS,EAC9B,IAAI,EAAE,UAAU,EAChB,GAAG,EAAE,UAAU,EACf,GAAG,EAAE,UAAU,EACf,UAAU,EAAE,UAAU,GACrB,OAAO,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC;IAuB9B;;;;;;;;;;;;;OAaG;IACU,IAAI,CACf,MAAM,EAAE,UAAU,EAClB,IAAI,EAAE,UAAU,EAChB,IAAI,EAAE,UAAU,EAChB,MAAM,EAAE,MAAM,GACb,OAAO,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC;IAQ9B;;;;;;;;OAQG;WACW,cAAc,CAAC,MAAM,EAAE,eAAe,GAAG,UAAU;IAIjE;;;;;;;;;OASG;WACW,cAAc,CAAC,QAAQ,EAAE,UAAU,GAAG,MAAM,CAAC,eAAe,CAAC;CAY5E"}