@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
@@ -317,6 +317,25 @@ declare const allProviderIds: ReadonlyArray<AiProviderId>;
317
317
  */
318
318
  declare type AnthropicThinkingModelNames = 'claude-sonnet-4-5' | 'claude-sonnet-4-6' | 'claude-opus-4-6' | 'claude-opus-4-7';
319
319
 
320
+ /**
321
+ * Recommended OWASP 2023 minimum Argon2id parameters.
322
+ * Suitable for recovery-row key derivation (high-entropy inputs).
323
+ * @public
324
+ */
325
+ declare const ARGON2ID_OWASP_MIN: IArgon2idParams;
326
+
327
+ /**
328
+ * Stronger Argon2id parameters suitable for user-typed passphrases.
329
+ * @public
330
+ */
331
+ declare const ARGON2ID_PASSPHRASE: IArgon2idParams;
332
+
333
+ /**
334
+ * Converter for {@link CryptoUtils.IArgon2idKeyDerivationParams | Argon2id key derivation parameters}.
335
+ * @public
336
+ */
337
+ declare const argon2idKeyDerivationParams: Converter<IArgon2idKeyDerivationParams>;
338
+
320
339
  /**
321
340
  * Converter for base64 strings (validates format).
322
341
  * @public
@@ -481,6 +500,8 @@ declare namespace Converters_3 {
481
500
  encryptedFileFormat,
482
501
  encryptedFileErrorMode,
483
502
  keyDerivationFunction,
503
+ pbkdf2KeyDerivationParams,
504
+ argon2idKeyDerivationParams,
484
505
  keyDerivationParams,
485
506
  base64String,
486
507
  uint8ArrayFromBase64,
@@ -534,6 +555,8 @@ declare namespace CryptoUtils {
534
555
  importPublicKeyFromMultibaseSpki,
535
556
  multibaseBase64UrlDecode,
536
557
  multibaseBase64UrlEncode,
558
+ HpkeProvider,
559
+ IHpkeSealResult,
537
560
  isEncryptedFile,
538
561
  EncryptionAlgorithm,
539
562
  EncryptedFileFormat,
@@ -544,7 +567,13 @@ declare namespace CryptoUtils {
544
567
  IWrappedBytes,
545
568
  allKeyPairAlgorithms,
546
569
  KeyDerivationFunction,
570
+ IPbkdf2KeyDerivationParams,
571
+ IArgon2idKeyDerivationParams,
547
572
  IKeyDerivationParams,
573
+ IArgon2idParams,
574
+ ARGON2ID_OWASP_MIN,
575
+ ARGON2ID_PASSPHRASE,
576
+ IArgon2idProvider,
548
577
  IEncryptedFile,
549
578
  ICryptoProvider,
550
579
  IEncryptionProvider,
@@ -1035,6 +1064,128 @@ declare namespace Hash {
1035
1064
  }
1036
1065
  export { Hash }
1037
1066
 
1067
+ /**
1068
+ * HPKE base mode (RFC 9180) — `DHKEM(X25519, HKDF-SHA256) + HKDF-SHA256 + AES-256-GCM`.
1069
+ *
1070
+ * Class-based provider that captures a `SubtleCrypto` instance at construction,
1071
+ * matching the existing `NodeCryptoProvider` / `BrowserCryptoProvider` / `KeyStore`
1072
+ * factory pattern used throughout `@fgv/ts-extras/crypto-utils`.
1073
+ *
1074
+ * **Node.js usage:**
1075
+ * ```typescript
1076
+ * import * as crypto from 'crypto';
1077
+ * const hpke = HpkeProvider.create(crypto.webcrypto.subtle).orThrow();
1078
+ * ```
1079
+ *
1080
+ * **Browser usage:**
1081
+ * ```typescript
1082
+ * const hpke = HpkeProvider.create(globalThis.crypto.subtle).orThrow();
1083
+ * ```
1084
+ *
1085
+ * **Runtime requirements:** Node.js 20+ (X25519 in `crypto.webcrypto`);
1086
+ * Chrome 113+, Safari 16.4+, Firefox 118+ (X25519 added to Web Crypto in 2023).
1087
+ * @public
1088
+ */
1089
+ declare class HpkeProvider {
1090
+ private readonly _subtle;
1091
+ private constructor();
1092
+ /**
1093
+ * Creates an `HpkeProvider` bound to the given `SubtleCrypto` instance.
1094
+ *
1095
+ * @param subtle - Web Crypto SubtleCrypto instance.
1096
+ * Node.js: `(await import('crypto')).webcrypto.subtle`.
1097
+ * Browser: `globalThis.crypto.subtle`.
1098
+ * @returns `Success` with the provider, or `Failure` if construction fails.
1099
+ */
1100
+ static create(subtle: SubtleCrypto): Result<HpkeProvider>;
1101
+ /**
1102
+ * HPKE base-mode seal (sender side). RFC 9180 §6.1.
1103
+ *
1104
+ * Generates a fresh ephemeral X25519 keypair, runs DHKEM Encap to produce a
1105
+ * shared secret and `enc` (32-byte raw ephemeral public key), derives the AEAD
1106
+ * key and nonce deterministically via the RFC 9180 key schedule, then encrypts
1107
+ * `plaintext` with AES-256-GCM.
1108
+ *
1109
+ * @param recipientPublicKey - Recipient's X25519 public `CryptoKey`
1110
+ * (`algorithm.name === 'X25519'`, `type === 'public'`, **`extractable: true`**).
1111
+ * Must be extractable — DHKEM Encap calls `exportKey('raw', ...)` on this key to
1112
+ * build the KEM shared-secret context. Keys imported with `extractable: false` will
1113
+ * cause this method to return a `Failure`.
1114
+ * @param info - Context-binding bytes. **Load-bearing — no default.**
1115
+ * Binds this ciphertext to a specific application context, preventing replay
1116
+ * across different contexts sharing the same recipient keypair.
1117
+ * Use `new TextEncoder().encode('myapp/v1/use-case\x00' + contextId)` pattern.
1118
+ * Never pass an empty array in production: empty `info` provides no context binding.
1119
+ * @param aad - Additional authenticated data. Integrity-protected but not encrypted.
1120
+ * `new Uint8Array(0)` is valid when no AAD is needed.
1121
+ * @param plaintext - Bytes to encrypt. `new Uint8Array(0)` is valid.
1122
+ * @returns `Success` with `{ enc, ciphertext }`, or `Failure` with error context.
1123
+ */
1124
+ sealBase(recipientPublicKey: CryptoKey, info: Uint8Array, aad: Uint8Array, plaintext: Uint8Array): Promise<Result<IHpkeSealResult>>;
1125
+ /**
1126
+ * HPKE base-mode open (recipient side). RFC 9180 §6.1.
1127
+ *
1128
+ * Decapsulates `enc` using the recipient's X25519 private key, derives the same
1129
+ * AEAD key and nonce from the shared secret and `info`, then authenticates and
1130
+ * decrypts `ciphertext` with AES-256-GCM.
1131
+ *
1132
+ * Returns `Failure` on any of:
1133
+ * - Wrong private key (different DH output → different key derivation)
1134
+ * - Wrong `info` (different key schedule context → different AEAD key)
1135
+ * - Wrong `aad` (AES-GCM authentication fails)
1136
+ * - Tampered `ciphertext` or `enc` (authentication fails or DH fails)
1137
+ * - `enc` not exactly 32 bytes
1138
+ * - `ciphertext` shorter than 16 bytes (no room for authentication tag)
1139
+ *
1140
+ * @param recipientPrivateKey - Recipient's X25519 private `CryptoKey`
1141
+ * (`algorithm.name === 'X25519'`, `type === 'private'`, `usages` includes `'deriveBits'`).
1142
+ * **Must be extractable** (`extractable: true`) — the recipient's public key bytes
1143
+ * are recovered from the JWK `x` field during Decap.
1144
+ * @param info - Context-binding bytes. Must exactly match `info` from `sealBase`.
1145
+ * @param aad - Must exactly match `aad` from `sealBase`.
1146
+ * @param enc - The encapsulated key from `sealBase` — exactly 32 bytes.
1147
+ * @param ciphertext - The ciphertext from `sealBase` — `plaintext.length + 16` bytes.
1148
+ * @returns `Success` with decrypted plaintext bytes, or `Failure` with error context.
1149
+ */
1150
+ openBase(recipientPrivateKey: CryptoKey, info: Uint8Array, aad: Uint8Array, enc: Uint8Array, ciphertext: Uint8Array): Promise<Result<Uint8Array>>;
1151
+ /**
1152
+ * HKDF-SHA256 key derivation (RFC 5869). Extract-then-Expand using SHA-256.
1153
+ *
1154
+ * This is raw RFC 5869 HKDF — it does **not** use RFC 9180's labeled variants.
1155
+ * The HPKE key schedule internally uses labeled HKDF; this method is the unlabeled
1156
+ * version for callers that need standalone key derivation.
1157
+ *
1158
+ * @param secret - Input keying material (IKM). Any length.
1159
+ * @param salt - Optional salt. Use `new Uint8Array(0)` if no salt is available
1160
+ * (RFC 5869: 32 zero bytes are used internally when salt is empty).
1161
+ * @param info - Context / application-binding bytes. Any length.
1162
+ * @param length - Number of output bytes to derive. Maximum 8160 bytes (255 × 32).
1163
+ * @returns `Success` with derived bytes, or `Failure` with error context.
1164
+ */
1165
+ hkdf(secret: Uint8Array, salt: Uint8Array, info: Uint8Array, length: number): Promise<Result<Uint8Array>>;
1166
+ /**
1167
+ * Encodes an {@link IHpkeSealResult} as a single contiguous byte array for wire transport.
1168
+ *
1169
+ * Format: `enc` (32 bytes, fixed) || `ciphertext` (variable length).
1170
+ * The 32-byte `enc` length is fixed for X25519; the split point is unambiguous.
1171
+ *
1172
+ * @param result - The output of {@link HpkeProvider.sealBase}.
1173
+ * @returns Concatenated bytes: `enc || ciphertext`.
1174
+ */
1175
+ static encodeEnvelope(result: IHpkeSealResult): Uint8Array;
1176
+ /**
1177
+ * Decodes an envelope produced by {@link HpkeProvider.encodeEnvelope}.
1178
+ *
1179
+ * Validates that the buffer is at least 48 bytes (32-byte enc + 16-byte minimum
1180
+ * ciphertext containing the AES-GCM auth tag; zero-length plaintext is the minimum
1181
+ * meaningful case).
1182
+ *
1183
+ * @param envelope - Envelope bytes from `encodeEnvelope`.
1184
+ * @returns `Success` with `{ enc, ciphertext }`, or `Failure` if malformed.
1185
+ */
1186
+ static decodeEnvelope(envelope: Uint8Array): Result<IHpkeSealResult>;
1187
+ }
1188
+
1038
1189
  /**
1039
1190
  * Options for adding an asymmetric keypair to the key store.
1040
1191
  * @public
@@ -1079,6 +1230,25 @@ declare interface IAddKeyPairResult {
1079
1230
  readonly warning?: string;
1080
1231
  }
1081
1232
 
1233
+ /**
1234
+ * Options for adding an Argon2id password-derived secret.
1235
+ * @public
1236
+ */
1237
+ declare interface IAddSecretFromPasswordArgon2idOptions {
1238
+ /**
1239
+ * Argon2id parameters. Defaults to {@link CryptoUtils.ARGON2ID_OWASP_MIN}.
1240
+ */
1241
+ readonly params?: IArgon2idParams;
1242
+ /**
1243
+ * Optional description for the secret.
1244
+ */
1245
+ readonly description?: string;
1246
+ /**
1247
+ * Whether to replace an existing secret with the same name.
1248
+ */
1249
+ readonly replace?: boolean;
1250
+ }
1251
+
1082
1252
  /**
1083
1253
  * Options for adding a secret derived from a password.
1084
1254
  * @public
@@ -1615,6 +1785,81 @@ declare interface IAnthropicThinkingOptions {
1615
1785
  readonly config: IAnthropicThinkingConfig;
1616
1786
  }
1617
1787
 
1788
+ /**
1789
+ * Argon2id key derivation parameters (RFC 9106).
1790
+ * @public
1791
+ */
1792
+ declare interface IArgon2idKeyDerivationParams {
1793
+ /** Key derivation function discriminator. */
1794
+ readonly kdf: 'argon2id';
1795
+ /** Base64-encoded salt used for key derivation. */
1796
+ readonly salt: string;
1797
+ /** Memory cost in kibibytes. */
1798
+ readonly memoryKiB: number;
1799
+ /** Number of passes (time cost). */
1800
+ readonly iterations: number;
1801
+ /** Degree of parallelism. */
1802
+ readonly parallelism: number;
1803
+ }
1804
+
1805
+ /**
1806
+ * Parameters for Argon2id key derivation (RFC 9106).
1807
+ * All fields are required; fgv does not pick defaults silently.
1808
+ * @public
1809
+ */
1810
+ declare interface IArgon2idParams {
1811
+ /**
1812
+ * Memory cost in kibibytes (KiB).
1813
+ * OWASP 2023 minimum: 19456 (19 MiB). Stronger: 65536 (64 MiB).
1814
+ * Constraint: \>= 8.
1815
+ */
1816
+ readonly memoryKiB: number;
1817
+ /**
1818
+ * Number of passes (iterations / time cost).
1819
+ * OWASP 2023 minimum: 2. Range: \>= 1.
1820
+ */
1821
+ readonly iterations: number;
1822
+ /**
1823
+ * Degree of parallelism (threads).
1824
+ * Note: WASM-based implementations compute sequentially regardless of this value,
1825
+ * but the value is wired into the algorithm and AFFECTS the output hash bytes.
1826
+ * Callers must use the same parallelism value consistently for a given secret.
1827
+ * Range: 1–255.
1828
+ */
1829
+ readonly parallelism: number;
1830
+ /**
1831
+ * Number of output bytes (hash length).
1832
+ * Typical values: 16 (128-bit), 32 (256-bit, AES-256 key), 64 (512-bit).
1833
+ * Constraint: \>= 4.
1834
+ */
1835
+ readonly outputBytes: number;
1836
+ }
1837
+
1838
+ /**
1839
+ * Argon2id key derivation provider (RFC 9106).
1840
+ *
1841
+ * Implementations are in separate packages to avoid WASM bundle costs for
1842
+ * consumers who don't need Argon2id:
1843
+ * - Node: `@fgv/ts-extras-argon2` (`NodeArgon2Provider`)
1844
+ * - Browser: `@fgv/ts-web-extras-argon2` (`BrowserArgon2Provider`)
1845
+ *
1846
+ * @public
1847
+ */
1848
+ declare interface IArgon2idProvider {
1849
+ /**
1850
+ * Derives key material from a password using Argon2id (RFC 9106 §3.1).
1851
+ *
1852
+ * Returns the raw derived bytes as a `Uint8Array`. Both Node and browser
1853
+ * implementations produce bit-identical output for identical inputs.
1854
+ *
1855
+ * @param password - Password or passphrase. Accepts string (UTF-8) or raw bytes.
1856
+ * @param salt - Salt bytes. Must be random and unique per credential (\>= 16 bytes recommended).
1857
+ * @param params - Argon2id parameters. Use `ARGON2ID_OWASP_MIN` as a starting point.
1858
+ * @returns Success with derived bytes, Failure with error context.
1859
+ */
1860
+ argon2id(password: Uint8Array | string, salt: Uint8Array, params: IArgon2idParams): Promise<Result<Uint8Array>>;
1861
+ }
1862
+
1618
1863
  /**
1619
1864
  * A single chat message in OpenAI format.
1620
1865
  * @public
@@ -1845,6 +2090,80 @@ declare interface ICryptoProvider {
1845
2090
  * @returns `Success` with the original `plaintext`, or `Failure` with error context.
1846
2091
  */
1847
2092
  unwrapBytes(wrapped: IWrappedBytes, recipientPrivateKey: CryptoKey, options: IWrapBytesOptions): Promise<Result<Uint8Array>>;
2093
+ /**
2094
+ * Signs `data` with `privateKey` using the algorithm inferred from the key.
2095
+ * Delegates to `crypto.subtle.sign`; the algorithm is derived from
2096
+ * `privateKey.algorithm.name` — ECDSA keys are augmented with
2097
+ * `hash: 'SHA-256'` at sign time (the hash is not stored in the key);
2098
+ * all other algorithm names are passed through as-is.
2099
+ * Intended for Ed25519 and ECDSA-P256 asymmetric private keys; for
2100
+ * HMAC-SHA256 authentication codes use {@link ICryptoProvider.hmacSha256} instead.
2101
+ * @param privateKey - A `CryptoKey` with `'sign'` usage (e.g. generated by
2102
+ * {@link CryptoUtils.ICryptoProvider.generateKeyPair | generateKeyPair} with
2103
+ * `'ecdsa-p256'` or `'ed25519'`).
2104
+ * @param data - The bytes to sign.
2105
+ * @returns `Success` with the raw signature bytes, or `Failure` with error context.
2106
+ */
2107
+ sign(privateKey: CryptoKey, data: Uint8Array): Promise<Result<Uint8Array>>;
2108
+ /**
2109
+ * Verifies a signature produced by {@link ICryptoProvider.sign}.
2110
+ * Delegates to `crypto.subtle.verify`; the algorithm is derived from
2111
+ * `publicKey.algorithm.name` — ECDSA keys are augmented with
2112
+ * `hash: 'SHA-256'`; all other algorithm names are passed through as-is.
2113
+ * Intended for Ed25519 and ECDSA-P256 asymmetric public keys; for
2114
+ * HMAC-SHA256 verification use {@link ICryptoProvider.verifyHmacSha256} instead.
2115
+ * @param publicKey - A `CryptoKey` with `'verify'` usage (e.g. the public
2116
+ * half of a keypair generated by
2117
+ * {@link CryptoUtils.ICryptoProvider.generateKeyPair | generateKeyPair} with
2118
+ * `'ecdsa-p256'` or `'ed25519'`).
2119
+ * @param signature - The raw signature bytes produced by `sign`.
2120
+ * @param data - The original data that was signed.
2121
+ * @returns `Success` with `true` if the signature is valid, `false` if it is
2122
+ * not, or `Failure` with error context if the operation itself failed.
2123
+ */
2124
+ verify(publicKey: CryptoKey, signature: Uint8Array, data: Uint8Array): Promise<Result<boolean>>;
2125
+ /**
2126
+ * Compares two byte arrays in constant time.
2127
+ *
2128
+ * The comparison visits all bytes of `a` and `b` regardless of where they
2129
+ * diverge, accumulating XOR differences with bitwise-OR. No early-return is
2130
+ * possible once the length check passes, making timing independent of the
2131
+ * byte values. This prevents timing side-channels when comparing MAC outputs,
2132
+ * signed-token bytes, or any secret-derived byte sequences.
2133
+ *
2134
+ * Returns `false` immediately (before the loop) when `a.length !== b.length`;
2135
+ * the length mismatch itself is not secret in normal use.
2136
+ * @param a - First byte array.
2137
+ * @param b - Second byte array.
2138
+ * @returns `true` if the arrays have the same length and identical contents,
2139
+ * `false` otherwise.
2140
+ */
2141
+ timingSafeEqual(a: Uint8Array, b: Uint8Array): boolean;
2142
+ /**
2143
+ * Computes an HMAC-SHA256 authentication code for `data` using `key`.
2144
+ *
2145
+ * The key must be a `CryptoKey` with `'sign'` usage and algorithm name
2146
+ * `'HMAC'` (e.g. derived via PBKDF2 or imported with
2147
+ * `crypto.subtle.importKey`). Use {@link ICryptoProvider.verifyHmacSha256}
2148
+ * for constant-time verification of the output.
2149
+ * @param key - An HMAC `CryptoKey` with `'sign'` usage.
2150
+ * @param data - The bytes to authenticate.
2151
+ * @returns `Success` with the 32-byte MAC, or `Failure` with error context.
2152
+ */
2153
+ hmacSha256(key: CryptoKey, data: Uint8Array): Promise<Result<Uint8Array>>;
2154
+ /**
2155
+ * Verifies an HMAC-SHA256 authentication code in constant time.
2156
+ *
2157
+ * Computes the expected MAC over `data` with `key`, then compares it to
2158
+ * `signature` using {@link ICryptoProvider.timingSafeEqual} so that
2159
+ * mismatches do not leak information through timing.
2160
+ * @param key - An HMAC `CryptoKey` with `'sign'` usage.
2161
+ * @param signature - The MAC bytes to verify (typically 32 bytes).
2162
+ * @param data - The original data that was authenticated.
2163
+ * @returns `Success` with `true` if the MAC is valid, `false` if it is not,
2164
+ * or `Failure` with error context if the MAC computation itself failed.
2165
+ */
2166
+ verifyHmacSha256(key: CryptoKey, signature: Uint8Array, data: Uint8Array): Promise<Result<boolean>>;
1848
2167
  }
1849
2168
 
1850
2169
  /**
@@ -2181,6 +2500,26 @@ declare interface IGrokImagineModelOptions extends INamedModelFamilyConfig {
2181
2500
  readonly config: IGrokImagineImageGenerationConfig;
2182
2501
  }
2183
2502
 
2503
+ /**
2504
+ * Output of {@link HpkeProvider.sealBase}.
2505
+ *
2506
+ * The `ciphertext` field includes the 16-byte AES-256-GCM authentication tag
2507
+ * appended by Web Crypto's `encrypt()` operation: `length = plaintext.length + 16`.
2508
+ * @public
2509
+ */
2510
+ declare interface IHpkeSealResult {
2511
+ /**
2512
+ * Encapsulated key — 32-byte raw X25519 ephemeral public key (`enc` in RFC 9180).
2513
+ * Must be transmitted to the recipient alongside `ciphertext`.
2514
+ */
2515
+ readonly enc: Uint8Array;
2516
+ /**
2517
+ * AES-256-GCM ciphertext with the 16-byte authentication tag appended.
2518
+ * Length = `plaintext.length + 16`.
2519
+ */
2520
+ readonly ciphertext: Uint8Array;
2521
+ }
2522
+
2184
2523
  /**
2185
2524
  * Provider-specific config for Google Imagen 4 models.
2186
2525
  * @public
@@ -2239,23 +2578,10 @@ declare interface IImportSecretOptions extends IAddSecretOptions {
2239
2578
 
2240
2579
  /**
2241
2580
  * Key derivation parameters stored in encrypted files.
2242
- * Allows decryption with password without needing to know the original salt/iterations.
2581
+ * Discriminated union on `kdf` field: `'pbkdf2'` or `'argon2id'`.
2243
2582
  * @public
2244
2583
  */
2245
- declare interface IKeyDerivationParams {
2246
- /**
2247
- * Key derivation function used.
2248
- */
2249
- readonly kdf: KeyDerivationFunction;
2250
- /**
2251
- * Base64-encoded salt used for key derivation.
2252
- */
2253
- readonly salt: string;
2254
- /**
2255
- * Number of iterations used for key derivation.
2256
- */
2257
- readonly iterations: number;
2258
- }
2584
+ declare type IKeyDerivationParams = IPbkdf2KeyDerivationParams | IArgon2idKeyDerivationParams;
2259
2585
 
2260
2586
  /**
2261
2587
  * WebCrypto parameters for a single {@link CryptoUtils.KeyPairAlgorithm}.
@@ -2436,9 +2762,9 @@ declare interface IKeyStoreFile {
2436
2762
  */
2437
2763
  readonly encryptedData: string;
2438
2764
  /**
2439
- * Key derivation parameters (required for key store - always password-derived).
2765
+ * Key derivation parameters for the vault master key (always PBKDF2).
2440
2766
  */
2441
- readonly keyDerivation: IKeyDerivationParams;
2767
+ readonly keyDerivation: IPbkdf2KeyDerivationParams;
2442
2768
  }
2443
2769
 
2444
2770
  /**
@@ -2656,6 +2982,23 @@ declare interface IMustacheTemplateOptions {
2656
2982
  * Whether to include partial references in variable extraction (default: false)
2657
2983
  */
2658
2984
  readonly includePartials?: boolean;
2985
+ /**
2986
+ * Escape strategy applied to double-brace `{{name}}` tokens at render
2987
+ * time. Default `'html'` preserves the existing mustache.js behavior
2988
+ * (back-compat).
2989
+ *
2990
+ * Pass `'none'` for LLM-prompt or other non-HTML targets where the
2991
+ * default `& → &amp;` escape would corrupt the output. Pass a custom
2992
+ * function for any other escape policy.
2993
+ *
2994
+ * The strategy is applied per-template via a private `Mustache.Writer`
2995
+ * instance; no global state on the `mustache` module is mutated, so
2996
+ * concurrent templates with different strategies are safe.
2997
+ *
2998
+ * Note: triple-brace `{{{name}}}` tokens are always rendered unescaped
2999
+ * regardless of strategy (standard mustache.js semantics).
3000
+ */
3001
+ readonly escape?: MustacheEscapeStrategy;
2659
3002
  }
2660
3003
 
2661
3004
  /**
@@ -2743,6 +3086,19 @@ declare interface IOtherThinkingOptions {
2743
3086
  readonly config: JsonObject;
2744
3087
  }
2745
3088
 
3089
+ /**
3090
+ * PBKDF2 key derivation parameters.
3091
+ * @public
3092
+ */
3093
+ declare interface IPbkdf2KeyDerivationParams {
3094
+ /** Key derivation function discriminator. */
3095
+ readonly kdf: 'pbkdf2';
3096
+ /** Base64-encoded salt used for key derivation. */
3097
+ readonly salt: string;
3098
+ /** Number of iterations used for key derivation. */
3099
+ readonly iterations: number;
3100
+ }
3101
+
2746
3102
  /**
2747
3103
  * Pluggable backend that persists raw asymmetric private keys outside of the
2748
3104
  * encrypted keystore vault. Concrete implementations live in platform-specific
@@ -2942,6 +3298,7 @@ declare interface IRequiredMustacheTemplateOptions {
2942
3298
  readonly tags: [string, string];
2943
3299
  readonly includeComments: boolean;
2944
3300
  readonly includePartials: boolean;
3301
+ readonly escape: MustacheEscapeStrategy;
2945
3302
  }
2946
3303
 
2947
3304
  /**
@@ -3253,7 +3610,7 @@ declare const jsonWebKeyShape: Validator<JsonWebKey>;
3253
3610
  * Supported key derivation functions.
3254
3611
  * @public
3255
3612
  */
3256
- declare type KeyDerivationFunction = 'pbkdf2';
3613
+ declare type KeyDerivationFunction = 'pbkdf2' | 'argon2id';
3257
3614
 
3258
3615
  /**
3259
3616
  * Converter for {@link CryptoUtils.KeyDerivationFunction | key derivation function} type.
@@ -3263,6 +3620,7 @@ declare const keyDerivationFunction: Converter<KeyDerivationFunction>;
3263
3620
 
3264
3621
  /**
3265
3622
  * Converter for {@link CryptoUtils.IKeyDerivationParams | key derivation parameters}.
3623
+ * Handles both PBKDF2 and Argon2id discriminated union arms.
3266
3624
  * @public
3267
3625
  */
3268
3626
  declare const keyDerivationParams: Converter<IKeyDerivationParams>;
@@ -3341,6 +3699,7 @@ declare namespace KeyStore {
3341
3699
  IAddSecretFromPasswordOptions,
3342
3700
  DEFAULT_SECRET_ITERATIONS,
3343
3701
  IAddSecretFromPasswordResult,
3702
+ IAddSecretFromPasswordArgon2idOptions,
3344
3703
  IAddKeyPairOptions,
3345
3704
  IAddKeyPairResult,
3346
3705
  IRemoveSecretResult,
@@ -3577,6 +3936,36 @@ declare class KeyStore_2 implements IEncryptionProvider {
3577
3936
  * @public
3578
3937
  */
3579
3938
  verifySecretFromPassword(name: string, password: string, keyDerivation: IKeyDerivationParams): Promise<Result<boolean>>;
3939
+ /**
3940
+ * Adds a secret derived from a password using Argon2id (RFC 9106).
3941
+ *
3942
+ * The Argon2id provider must be supplied explicitly; the KeyStore does not
3943
+ * hold one by default (consumers opt in by depending on the argon2 package).
3944
+ *
3945
+ * Returns the key derivation parameters so callers can store them alongside
3946
+ * encrypted artifacts, enabling future re-derivation and verification.
3947
+ *
3948
+ * @param name - Unique name for the secret
3949
+ * @param password - Password or passphrase
3950
+ * @param argon2idProvider - Argon2id provider (Node or Browser implementation)
3951
+ * @param options - Optional: Argon2id params (defaults to ARGON2ID_OWASP_MIN), description, replace flag
3952
+ * @returns Success with entry and keyDerivation params, Failure if locked or invalid
3953
+ * @public
3954
+ */
3955
+ addSecretFromPasswordArgon2id(name: string, password: string, argon2idProvider: IArgon2idProvider, options?: IAddSecretFromPasswordArgon2idOptions): Promise<Result<IAddSecretFromPasswordResult>>;
3956
+ /**
3957
+ * Verifies a candidate password against an Argon2id-derived entry using the
3958
+ * supplied key derivation parameters. Constant-time comparison.
3959
+ *
3960
+ * @param name - Name of the secret to verify against
3961
+ * @param password - Candidate password to test
3962
+ * @param argon2idProvider - Argon2id provider (must produce bit-identical output for identical inputs)
3963
+ * @param keyDerivation - The Argon2id key derivation parameters returned by `addSecretFromPasswordArgon2id`
3964
+ * @returns Success(true) if candidate matches stored key, Success(false) if not,
3965
+ * Failure if locked, secret missing, wrong type, or derivation fails
3966
+ * @public
3967
+ */
3968
+ verifySecretFromPasswordArgon2id(name: string, password: string, argon2idProvider: IArgon2idProvider, keyDerivation: IArgon2idKeyDerivationParams): Promise<Result<boolean>>;
3580
3969
  /**
3581
3970
  * Removes a secret by name. Vault-first: the in-memory vault entry is dropped
3582
3971
  * before any storage cleanup runs. For asymmetric-keypair entries, best-effort
@@ -3933,12 +4322,30 @@ declare namespace Mustache {
3933
4322
  IMissingVariableDetail,
3934
4323
  IMustacheTemplateOptions,
3935
4324
  IVariableRef,
4325
+ MustacheEscapeStrategy,
3936
4326
  MustacheTokenType,
3937
4327
  MustacheTemplate
3938
4328
  }
3939
4329
  }
3940
4330
  export { Mustache }
3941
4331
 
4332
+ /**
4333
+ * Strategy applied to double-brace `{{name}}` tokens at render time.
4334
+ *
4335
+ * - `'html'`: the standard mustache.js HTML escape (back-compat default).
4336
+ * - `'none'`: verbatim passthrough — values are interpolated as-is
4337
+ * (coerced to `String`). Suitable for LLM-prompt rendering and other
4338
+ * non-HTML targets where `& → &amp;` corrupts the output.
4339
+ * - `(value) => string`: caller-supplied escape function.
4340
+ *
4341
+ * Note: triple-brace `{{{name}}}` (and `{{&name}}`) tokens are always
4342
+ * rendered unescaped regardless of this strategy — that is the standard
4343
+ * mustache.js semantics and is not affected by this option.
4344
+ *
4345
+ * @public
4346
+ */
4347
+ declare type MustacheEscapeStrategy = 'html' | 'none' | ((value: string) => string);
4348
+
3942
4349
  /**
3943
4350
  * A helper class for working with Mustache templates that provides
3944
4351
  * validation, variable extraction, and context validation utilities.
@@ -3954,6 +4361,8 @@ declare class MustacheTemplate {
3954
4361
  */
3955
4362
  readonly options: Readonly<IRequiredMustacheTemplateOptions>;
3956
4363
  private readonly _tokens;
4364
+ private readonly _writer;
4365
+ private readonly _escapeFn;
3957
4366
  private _variables?;
3958
4367
  private constructor();
3959
4368
  /**
@@ -4129,6 +4538,45 @@ declare class NodeCryptoProvider implements ICryptoProvider {
4129
4538
  * @returns `Success` with the imported public `CryptoKey`, or `Failure` with error context.
4130
4539
  */
4131
4540
  importPublicKeySpki(spkiBytes: Uint8Array, algorithm: KeyPairAlgorithm): Promise<Result<CryptoKey>>;
4541
+ /**
4542
+ * Signs `data` with `privateKey` using the algorithm inferred from the key.
4543
+ * @param privateKey - A signing `CryptoKey` (`'ecdsa-p256'` or `'ed25519'`).
4544
+ * @param data - The bytes to sign.
4545
+ * @returns `Success` with the raw signature bytes, or `Failure` with error context.
4546
+ */
4547
+ sign(privateKey: CryptoKey, data: Uint8Array): Promise<Result<Uint8Array>>;
4548
+ /**
4549
+ * Verifies a signature produced by {@link NodeCryptoProvider.sign}.
4550
+ * @param publicKey - A verify `CryptoKey` (`'ecdsa-p256'` or `'ed25519'`).
4551
+ * @param signature - The raw signature bytes.
4552
+ * @param data - The original data that was signed.
4553
+ * @returns `Success` with `true` if valid, `false` if not, or `Failure` with error context.
4554
+ */
4555
+ verify(publicKey: CryptoKey, signature: Uint8Array, data: Uint8Array): Promise<Result<boolean>>;
4556
+ /**
4557
+ * Compares two byte arrays in constant time using Node's native
4558
+ * `crypto.timingSafeEqual`. Returns `false` for mismatched lengths
4559
+ * rather than throwing (Node's native throws on length mismatch).
4560
+ * @param a - First byte array.
4561
+ * @param b - Second byte array.
4562
+ * @returns `true` if lengths match and all bytes are equal, `false` otherwise.
4563
+ */
4564
+ timingSafeEqual(a: Uint8Array, b: Uint8Array): boolean;
4565
+ /**
4566
+ * Computes an HMAC-SHA256 MAC for `data` using `key`.
4567
+ * @param key - An HMAC `CryptoKey` with `'sign'` usage.
4568
+ * @param data - The bytes to authenticate.
4569
+ * @returns `Success` with the 32-byte MAC, or `Failure` with error context.
4570
+ */
4571
+ hmacSha256(key: CryptoKey, data: Uint8Array): Promise<Result<Uint8Array>>;
4572
+ /**
4573
+ * Verifies an HMAC-SHA256 MAC in constant time.
4574
+ * @param key - An HMAC `CryptoKey` with `'sign'` usage.
4575
+ * @param signature - The MAC bytes to verify.
4576
+ * @param data - The original data that was authenticated.
4577
+ * @returns `Success` with `true` if valid, `false` if not, or `Failure` with error context.
4578
+ */
4579
+ verifyHmacSha256(key: CryptoKey, signature: Uint8Array, data: Uint8Array): Promise<Result<boolean>>;
4132
4580
  /**
4133
4581
  * Wraps `plaintext` for the holder of `recipientPublicKey` using
4134
4582
  * ECIES (ECDH P-256 + HKDF-SHA256 + AES-GCM-256). See
@@ -4181,6 +4629,12 @@ declare function parseCsvString(body: string, options?: CsvOptions): Result<unkn
4181
4629
  */
4182
4630
  declare function parseRecordJarLines(lines: string[], options?: JarRecordParserOptions): Result<JarRecord[]>;
4183
4631
 
4632
+ /**
4633
+ * Converter for {@link CryptoUtils.IPbkdf2KeyDerivationParams | PBKDF2 key derivation parameters}.
4634
+ * @public
4635
+ */
4636
+ declare const pbkdf2KeyDerivationParams: Converter<IPbkdf2KeyDerivationParams>;
4637
+
4184
4638
  /**
4185
4639
  * Simple implementation of a possibly open-ended range of some comparable
4186
4640
  * type `<T>` with test and formatting.
@@ -5,7 +5,7 @@
5
5
  "toolPackages": [
6
6
  {
7
7
  "packageName": "@microsoft/api-extractor",
8
- "packageVersion": "7.57.7"
8
+ "packageVersion": "7.58.7"
9
9
  }
10
10
  ]
11
11
  }
@@ -5,7 +5,8 @@ import * as Experimental from './packlets/experimental';
5
5
  import * as Hash from './packlets/hash/index.browser';
6
6
  import * as Mustache from './packlets/mustache';
7
7
  import * as RecordJar from './packlets/record-jar/index.browser';
8
+ import * as Yaml from './packlets/yaml';
8
9
  import * as ZipFileTree from './packlets/zip-file-tree';
9
10
  import { Converters } from './packlets/conversion';
10
- export { AiAssist, Converters, CryptoUtils, CryptoUtils as Crypto, Csv, Experimental, Hash, Mustache, RecordJar, ZipFileTree };
11
+ export { AiAssist, Converters, CryptoUtils, CryptoUtils as Crypto, Csv, Experimental, Hash, Mustache, RecordJar, Yaml, ZipFileTree };
11
12
  //# sourceMappingURL=index.browser.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.browser.d.ts","sourceRoot":"","sources":["../src/index.browser.ts"],"names":[],"mappings":"AAuBA,OAAO,KAAK,QAAQ,MAAM,sBAAsB,CAAC;AAEjD,OAAO,KAAK,WAAW,MAAM,uCAAuC,CAAC;AAErE,OAAO,KAAK,GAAG,MAAM,8BAA8B,CAAC;AACpD,OAAO,KAAK,YAAY,MAAM,yBAAyB,CAAC;AAExD,OAAO,KAAK,IAAI,MAAM,+BAA+B,CAAC;AACtD,OAAO,KAAK,QAAQ,MAAM,qBAAqB,CAAC;AAEhD,OAAO,KAAK,SAAS,MAAM,qCAAqC,CAAC;AACjE,OAAO,KAAK,WAAW,MAAM,0BAA0B,CAAC;AAExD,OAAO,EAAE,UAAU,EAAE,MAAM,uBAAuB,CAAC;AAInD,OAAO,EACL,QAAQ,EACR,UAAU,EACV,WAAW,EACX,WAAW,IAAI,MAAM,EACrB,GAAG,EACH,YAAY,EACZ,IAAI,EACJ,QAAQ,EACR,SAAS,EACT,WAAW,EACZ,CAAC"}
1
+ {"version":3,"file":"index.browser.d.ts","sourceRoot":"","sources":["../src/index.browser.ts"],"names":[],"mappings":"AAuBA,OAAO,KAAK,QAAQ,MAAM,sBAAsB,CAAC;AAEjD,OAAO,KAAK,WAAW,MAAM,uCAAuC,CAAC;AAErE,OAAO,KAAK,GAAG,MAAM,8BAA8B,CAAC;AACpD,OAAO,KAAK,YAAY,MAAM,yBAAyB,CAAC;AAExD,OAAO,KAAK,IAAI,MAAM,+BAA+B,CAAC;AACtD,OAAO,KAAK,QAAQ,MAAM,qBAAqB,CAAC;AAEhD,OAAO,KAAK,SAAS,MAAM,qCAAqC,CAAC;AACjE,OAAO,KAAK,IAAI,MAAM,iBAAiB,CAAC;AACxC,OAAO,KAAK,WAAW,MAAM,0BAA0B,CAAC;AAExD,OAAO,EAAE,UAAU,EAAE,MAAM,uBAAuB,CAAC;AAInD,OAAO,EACL,QAAQ,EACR,UAAU,EACV,WAAW,EACX,WAAW,IAAI,MAAM,EACrB,GAAG,EACH,YAAY,EACZ,IAAI,EACJ,QAAQ,EACR,SAAS,EACT,IAAI,EACJ,WAAW,EACZ,CAAC"}