@enbox/crypto 0.0.2 → 0.0.4

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 (226) hide show
  1. package/README.md +34 -102
  2. package/dist/browser.mjs +6 -10
  3. package/dist/browser.mjs.map +4 -4
  4. package/dist/esm/algorithms/aes-ctr.js +1 -1
  5. package/dist/esm/algorithms/aes-gcm.js +35 -2
  6. package/dist/esm/algorithms/aes-gcm.js.map +1 -1
  7. package/dist/esm/algorithms/aes-kw.js +154 -0
  8. package/dist/esm/algorithms/aes-kw.js.map +1 -0
  9. package/dist/esm/algorithms/ecdsa.js +119 -6
  10. package/dist/esm/algorithms/ecdsa.js.map +1 -1
  11. package/dist/esm/algorithms/eddsa.js +99 -6
  12. package/dist/esm/algorithms/eddsa.js.map +1 -1
  13. package/dist/esm/algorithms/hkdf.js +53 -0
  14. package/dist/esm/algorithms/hkdf.js.map +1 -0
  15. package/dist/esm/algorithms/pbkdf2.js +55 -0
  16. package/dist/esm/algorithms/pbkdf2.js.map +1 -0
  17. package/dist/esm/algorithms/sha-2.js +2 -2
  18. package/dist/esm/algorithms/sha-2.js.map +1 -1
  19. package/dist/esm/algorithms/x25519.js +125 -0
  20. package/dist/esm/algorithms/x25519.js.map +1 -0
  21. package/dist/esm/crypto-error.js +41 -0
  22. package/dist/esm/crypto-error.js.map +1 -0
  23. package/dist/esm/index.js +8 -0
  24. package/dist/esm/index.js.map +1 -1
  25. package/dist/esm/jose/jwk.js +52 -26
  26. package/dist/esm/jose/jwk.js.map +1 -1
  27. package/dist/esm/local-key-manager.js +9 -3
  28. package/dist/esm/local-key-manager.js.map +1 -1
  29. package/dist/esm/primitives/aes-ctr.js.map +1 -1
  30. package/dist/esm/primitives/aes-gcm.js.map +1 -1
  31. package/dist/esm/primitives/aes-kw.js +246 -0
  32. package/dist/esm/primitives/aes-kw.js.map +1 -0
  33. package/dist/esm/primitives/concat-kdf.js +1 -1
  34. package/dist/esm/primitives/concat-kdf.js.map +1 -1
  35. package/dist/esm/primitives/ecies-secp256k1.js +79 -0
  36. package/dist/esm/primitives/ecies-secp256k1.js.map +1 -0
  37. package/dist/esm/primitives/ed25519.js +3 -3
  38. package/dist/esm/primitives/ed25519.js.map +1 -1
  39. package/dist/esm/primitives/hkdf.js +79 -0
  40. package/dist/esm/primitives/hkdf.js.map +1 -0
  41. package/dist/esm/primitives/pbkdf2.js +49 -0
  42. package/dist/esm/primitives/pbkdf2.js.map +1 -1
  43. package/dist/esm/primitives/secp256k1.js +4 -4
  44. package/dist/esm/primitives/secp256k1.js.map +1 -1
  45. package/dist/esm/primitives/secp256r1.js +4 -4
  46. package/dist/esm/primitives/secp256r1.js.map +1 -1
  47. package/dist/esm/primitives/x25519.js +10 -17
  48. package/dist/esm/primitives/x25519.js.map +1 -1
  49. package/dist/esm/primitives/xchacha20-poly1305.js +48 -3
  50. package/dist/esm/primitives/xchacha20-poly1305.js.map +1 -1
  51. package/dist/esm/primitives/xchacha20.js +1 -1
  52. package/dist/esm/primitives/xchacha20.js.map +1 -1
  53. package/dist/esm/utils.js +30 -0
  54. package/dist/esm/utils.js.map +1 -1
  55. package/dist/types/algorithms/aes-ctr.d.ts +2 -2
  56. package/dist/types/algorithms/aes-ctr.d.ts.map +1 -1
  57. package/dist/types/algorithms/aes-gcm.d.ts +25 -5
  58. package/dist/types/algorithms/aes-gcm.d.ts.map +1 -1
  59. package/dist/types/algorithms/aes-kw.d.ts +129 -0
  60. package/dist/types/algorithms/aes-kw.d.ts.map +1 -0
  61. package/dist/types/algorithms/ecdsa.d.ts +49 -4
  62. package/dist/types/algorithms/ecdsa.d.ts.map +1 -1
  63. package/dist/types/algorithms/eddsa.d.ts +49 -4
  64. package/dist/types/algorithms/eddsa.d.ts.map +1 -1
  65. package/dist/types/algorithms/hkdf.d.ts +35 -0
  66. package/dist/types/algorithms/hkdf.d.ts.map +1 -0
  67. package/dist/types/algorithms/pbkdf2.d.ts +35 -0
  68. package/dist/types/algorithms/pbkdf2.d.ts.map +1 -0
  69. package/dist/types/algorithms/sha-2.d.ts +2 -2
  70. package/dist/types/algorithms/sha-2.d.ts.map +1 -1
  71. package/dist/types/algorithms/x25519.d.ts +76 -0
  72. package/dist/types/algorithms/x25519.d.ts.map +1 -0
  73. package/dist/types/crypto-error.d.ts +29 -0
  74. package/dist/types/crypto-error.d.ts.map +1 -0
  75. package/dist/types/index.d.ts +8 -0
  76. package/dist/types/index.d.ts.map +1 -1
  77. package/dist/types/jose/jwk.d.ts.map +1 -1
  78. package/dist/types/local-key-manager.d.ts +6 -6
  79. package/dist/types/local-key-manager.d.ts.map +1 -1
  80. package/dist/types/primitives/aes-kw.d.ts +103 -0
  81. package/dist/types/primitives/aes-kw.d.ts.map +1 -0
  82. package/dist/types/primitives/concat-kdf.d.ts +1 -1
  83. package/dist/types/primitives/concat-kdf.d.ts.map +1 -1
  84. package/dist/types/primitives/ecies-secp256k1.d.ts +53 -0
  85. package/dist/types/primitives/ecies-secp256k1.d.ts.map +1 -0
  86. package/dist/types/primitives/hkdf.d.ts +90 -0
  87. package/dist/types/primitives/hkdf.d.ts.map +1 -0
  88. package/dist/types/primitives/pbkdf2.d.ts +58 -0
  89. package/dist/types/primitives/pbkdf2.d.ts.map +1 -1
  90. package/dist/types/primitives/x25519.d.ts +9 -16
  91. package/dist/types/primitives/x25519.d.ts.map +1 -1
  92. package/dist/types/primitives/xchacha20-poly1305.d.ts +47 -0
  93. package/dist/types/primitives/xchacha20-poly1305.d.ts.map +1 -1
  94. package/dist/types/types/cipher.d.ts +1 -1
  95. package/dist/types/types/crypto-api.d.ts +54 -6
  96. package/dist/types/types/crypto-api.d.ts.map +1 -1
  97. package/dist/types/types/key-converter.d.ts +37 -15
  98. package/dist/types/types/key-converter.d.ts.map +1 -1
  99. package/dist/types/types/key-deriver.d.ts +41 -0
  100. package/dist/types/types/key-deriver.d.ts.map +1 -1
  101. package/dist/types/types/key-io.d.ts +37 -0
  102. package/dist/types/types/key-io.d.ts.map +1 -1
  103. package/dist/types/types/params-direct.d.ts +96 -1
  104. package/dist/types/types/params-direct.d.ts.map +1 -1
  105. package/dist/types/types/params-kms.d.ts +55 -0
  106. package/dist/types/types/params-kms.d.ts.map +1 -1
  107. package/dist/types/utils.d.ts +19 -0
  108. package/dist/types/utils.d.ts.map +1 -1
  109. package/dist/utils.js +1 -1
  110. package/dist/utils.js.map +4 -4
  111. package/package.json +29 -45
  112. package/src/algorithms/aes-ctr.ts +2 -2
  113. package/src/algorithms/aes-gcm.ts +41 -4
  114. package/src/algorithms/aes-kw.ts +182 -0
  115. package/src/algorithms/ecdsa.ts +145 -8
  116. package/src/algorithms/eddsa.ts +117 -10
  117. package/src/algorithms/hkdf.ts +54 -0
  118. package/src/algorithms/pbkdf2.ts +57 -0
  119. package/src/algorithms/sha-2.ts +3 -3
  120. package/src/algorithms/x25519.ts +153 -0
  121. package/src/crypto-error.ts +45 -0
  122. package/src/index.ts +8 -0
  123. package/src/jose/jwk.ts +32 -32
  124. package/src/local-key-manager.ts +22 -16
  125. package/src/primitives/aes-ctr.ts +1 -1
  126. package/src/primitives/aes-gcm.ts +5 -5
  127. package/src/primitives/aes-kw.ts +269 -0
  128. package/src/primitives/concat-kdf.ts +4 -2
  129. package/src/primitives/ecies-secp256k1.ts +113 -0
  130. package/src/primitives/ed25519.ts +6 -6
  131. package/src/primitives/hkdf.ts +121 -0
  132. package/src/primitives/pbkdf2.ts +91 -0
  133. package/src/primitives/secp256k1.ts +6 -6
  134. package/src/primitives/secp256r1.ts +6 -6
  135. package/src/primitives/x25519.ts +12 -19
  136. package/src/primitives/xchacha20-poly1305.ts +57 -4
  137. package/src/primitives/xchacha20.ts +1 -1
  138. package/src/types/cipher.ts +1 -1
  139. package/src/types/crypto-api.ts +129 -11
  140. package/src/types/key-converter.ts +33 -7
  141. package/src/types/key-deriver.ts +49 -0
  142. package/src/types/key-io.ts +40 -0
  143. package/src/types/params-direct.ts +118 -1
  144. package/src/types/params-kms.ts +67 -0
  145. package/src/utils.ts +55 -2
  146. package/dist/browser.js +0 -64
  147. package/dist/browser.js.map +0 -7
  148. package/dist/cjs/algorithms/aes-ctr.js +0 -188
  149. package/dist/cjs/algorithms/aes-ctr.js.map +0 -1
  150. package/dist/cjs/algorithms/aes-gcm.js +0 -196
  151. package/dist/cjs/algorithms/aes-gcm.js.map +0 -1
  152. package/dist/cjs/algorithms/crypto-algorithm.js +0 -13
  153. package/dist/cjs/algorithms/crypto-algorithm.js.map +0 -1
  154. package/dist/cjs/algorithms/ecdsa.js +0 -352
  155. package/dist/cjs/algorithms/ecdsa.js.map +0 -1
  156. package/dist/cjs/algorithms/eddsa.js +0 -325
  157. package/dist/cjs/algorithms/eddsa.js.map +0 -1
  158. package/dist/cjs/algorithms/sha-2.js +0 -119
  159. package/dist/cjs/algorithms/sha-2.js.map +0 -1
  160. package/dist/cjs/index.js +0 -41
  161. package/dist/cjs/index.js.map +0 -1
  162. package/dist/cjs/jose/jwe.js +0 -3
  163. package/dist/cjs/jose/jwe.js.map +0 -1
  164. package/dist/cjs/jose/jwk.js +0 -278
  165. package/dist/cjs/jose/jwk.js.map +0 -1
  166. package/dist/cjs/jose/jws.js +0 -3
  167. package/dist/cjs/jose/jws.js.map +0 -1
  168. package/dist/cjs/jose/jwt.js +0 -3
  169. package/dist/cjs/jose/jwt.js.map +0 -1
  170. package/dist/cjs/jose/utils.js +0 -60
  171. package/dist/cjs/jose/utils.js.map +0 -1
  172. package/dist/cjs/local-key-manager.js +0 -521
  173. package/dist/cjs/local-key-manager.js.map +0 -1
  174. package/dist/cjs/package.json +0 -1
  175. package/dist/cjs/primitives/aes-ctr.js +0 -398
  176. package/dist/cjs/primitives/aes-ctr.js.map +0 -1
  177. package/dist/cjs/primitives/aes-gcm.js +0 -425
  178. package/dist/cjs/primitives/aes-gcm.js.map +0 -1
  179. package/dist/cjs/primitives/concat-kdf.js +0 -215
  180. package/dist/cjs/primitives/concat-kdf.js.map +0 -1
  181. package/dist/cjs/primitives/ed25519.js +0 -651
  182. package/dist/cjs/primitives/ed25519.js.map +0 -1
  183. package/dist/cjs/primitives/pbkdf2.js +0 -120
  184. package/dist/cjs/primitives/pbkdf2.js.map +0 -1
  185. package/dist/cjs/primitives/secp256k1.js +0 -958
  186. package/dist/cjs/primitives/secp256k1.js.map +0 -1
  187. package/dist/cjs/primitives/secp256r1.js +0 -959
  188. package/dist/cjs/primitives/secp256r1.js.map +0 -1
  189. package/dist/cjs/primitives/sha256.js +0 -93
  190. package/dist/cjs/primitives/sha256.js.map +0 -1
  191. package/dist/cjs/primitives/x25519.js +0 -498
  192. package/dist/cjs/primitives/x25519.js.map +0 -1
  193. package/dist/cjs/primitives/xchacha20-poly1305.js +0 -340
  194. package/dist/cjs/primitives/xchacha20-poly1305.js.map +0 -1
  195. package/dist/cjs/primitives/xchacha20.js +0 -316
  196. package/dist/cjs/primitives/xchacha20.js.map +0 -1
  197. package/dist/cjs/types/cipher.js +0 -3
  198. package/dist/cjs/types/cipher.js.map +0 -1
  199. package/dist/cjs/types/crypto-api.js +0 -3
  200. package/dist/cjs/types/crypto-api.js.map +0 -1
  201. package/dist/cjs/types/hasher.js +0 -3
  202. package/dist/cjs/types/hasher.js.map +0 -1
  203. package/dist/cjs/types/identifier.js +0 -3
  204. package/dist/cjs/types/identifier.js.map +0 -1
  205. package/dist/cjs/types/key-compressor.js +0 -3
  206. package/dist/cjs/types/key-compressor.js.map +0 -1
  207. package/dist/cjs/types/key-converter.js +0 -3
  208. package/dist/cjs/types/key-converter.js.map +0 -1
  209. package/dist/cjs/types/key-deriver.js +0 -3
  210. package/dist/cjs/types/key-deriver.js.map +0 -1
  211. package/dist/cjs/types/key-generator.js +0 -3
  212. package/dist/cjs/types/key-generator.js.map +0 -1
  213. package/dist/cjs/types/key-io.js +0 -3
  214. package/dist/cjs/types/key-io.js.map +0 -1
  215. package/dist/cjs/types/key-wrapper.js +0 -3
  216. package/dist/cjs/types/key-wrapper.js.map +0 -1
  217. package/dist/cjs/types/params-direct.js +0 -3
  218. package/dist/cjs/types/params-direct.js.map +0 -1
  219. package/dist/cjs/types/params-enclosed.js +0 -3
  220. package/dist/cjs/types/params-enclosed.js.map +0 -1
  221. package/dist/cjs/types/params-kms.js +0 -3
  222. package/dist/cjs/types/params-kms.js.map +0 -1
  223. package/dist/cjs/types/signer.js +0 -3
  224. package/dist/cjs/types/signer.js.map +0 -1
  225. package/dist/cjs/utils.js +0 -173
  226. package/dist/cjs/utils.js.map +0 -1
@@ -0,0 +1,182 @@
1
+ import type { Jwk } from '../jose/jwk.js';
2
+ import type { KeyConverter } from '../types/key-converter.js';
3
+ import type { KeyGenerator } from '../types/key-generator.js';
4
+ import type { KeyWrapper } from '../types/key-wrapper.js';
5
+ import type { RequireOnly } from '@enbox/common';
6
+ import type { BytesToPrivateKeyParams, GenerateKeyParams, PrivateKeyToBytesParams, UnwrapKeyParams, WrapKeyParams } from '../types/params-direct.js';
7
+
8
+ import { AesKw } from '../primitives/aes-kw.js';
9
+ import { CryptoAlgorithm } from './crypto-algorithm.js';
10
+
11
+ /**
12
+ * The `AesKwGenerateKeyParams` interface defines the algorithm-specific parameters that should be
13
+ * passed into the `generateKey()` method when using the AES-KW algorithm.
14
+ */
15
+ export interface AesKwGenerateKeyParams extends GenerateKeyParams {
16
+ /** Specifies the algorithm variant for key generation in AES-KW mode.
17
+ * The value determines the length of the key to be generated and must be one of the following:
18
+ * - `"A128KW"`: AES Key Wrap using a 128-bit key.
19
+ * - `"A192KW"`: AES Key Wrap using a 192-bit key.
20
+ * - `"A256KW"`: AES Key Wrap using a 256-bit key.
21
+ */
22
+ algorithm: 'A128KW' | 'A192KW' | 'A256KW';
23
+ }
24
+
25
+ /**
26
+ * The `AesKwAlgorithm` class provides a concrete implementation for cryptographic operations using
27
+ * the AES algorithm for key wrapping. This class implements both
28
+ * {@link KeyGenerator | `KeyGenerator`} and {@link KeyWrapper | `KeyWrapper`} interfaces, providing
29
+ * key generation, key wrapping, and key unwrapping features.
30
+ *
31
+ * This class is typically accessed through implementations that extend the
32
+ * {@link DsaApi | `DsaApi`} interface.
33
+ */
34
+ export class AesKwAlgorithm extends CryptoAlgorithm
35
+ implements KeyConverter,
36
+ KeyGenerator<AesKwGenerateKeyParams, Jwk>,
37
+ KeyWrapper<WrapKeyParams, UnwrapKeyParams> {
38
+
39
+ /**
40
+ * Converts a private key from a byte array to JWK format, setting the `alg` property based on
41
+ * the key length.
42
+ *
43
+ * @param params - The parameters for the private key conversion.
44
+ * @param params.privateKeyBytes - The raw private key as a Uint8Array.
45
+ *
46
+ * @returns A Promise that resolves to the private key in JWK format.
47
+ */
48
+ public async bytesToPrivateKey({ privateKeyBytes }:
49
+ RequireOnly<BytesToPrivateKeyParams, 'privateKeyBytes'>
50
+ ): Promise<Jwk> {
51
+ // Convert the byte array to a JWK.
52
+ const privateKey = await AesKw.bytesToPrivateKey({ privateKeyBytes });
53
+
54
+ // Set the `alg` property based on the key length.
55
+ privateKey.alg = { 16: 'A128KW', 24: 'A192KW', 32: 'A256KW' }[privateKeyBytes.length];
56
+
57
+ return privateKey;
58
+ }
59
+
60
+ /**
61
+ * Generates a symmetric key for AES for key wrapping in JSON Web Key (JWK) format.
62
+ *
63
+ * @remarks
64
+ * This method generates a symmetric AES key for use in key wrapping mode, based on the specified
65
+ * `algorithm` parameter which determines the key length. It uses cryptographically secure random
66
+ * number generation to ensure the uniqueness and security of the key. The key is returned in JWK
67
+ * format.
68
+ *
69
+ * The generated key includes the following components:
70
+ * - `kty`: Key Type, set to 'oct' for Octet Sequence.
71
+ * - `k`: The symmetric key component, base64url-encoded.
72
+ * - `kid`: Key ID, generated based on the JWK thumbprint.
73
+ * - `alg`: Algorithm, set to 'A128KW', 'A192KW', or 'A256KW' for AES Key Wrap with the
74
+ * specified key length.
75
+ *
76
+ * @example
77
+ * ```ts
78
+ * const aesKw = new AesKwAlgorithm();
79
+ * const privateKey = await aesKw.generateKey({ algorithm: 'A256KW' });
80
+ * ```
81
+ *
82
+ * @param params - The parameters for the key generation.
83
+ *
84
+ * @returns A Promise that resolves to the generated symmetric key in JWK format.
85
+ */
86
+ public async generateKey({ algorithm }:
87
+ AesKwGenerateKeyParams
88
+ ): Promise<Jwk> {
89
+ // Map algorithm name to key length.
90
+ const length = { A128KW: 128, A192KW: 192, A256KW: 256 }[algorithm] as 128 | 192 | 256;
91
+
92
+ // Generate a random private key.
93
+ const privateKey = await AesKw.generateKey({ length });
94
+
95
+ // Set the `alg` property based on the specified algorithm.
96
+ privateKey.alg = algorithm;
97
+
98
+ return privateKey;
99
+ }
100
+
101
+ /**
102
+ * Converts a private key from JWK format to a byte array.
103
+ *
104
+ * @param params - The parameters for the private key conversion.
105
+ * @param params.privateKey - The private key in JWK format.
106
+ *
107
+ * @returns A Promise that resolves to the private key as a Uint8Array.
108
+ */
109
+ public async privateKeyToBytes({ privateKey }:
110
+ PrivateKeyToBytesParams
111
+ ): Promise<Uint8Array> {
112
+ // Convert the JWK to a byte array.
113
+ const privateKeyBytes = await AesKw.privateKeyToBytes({ privateKey });
114
+
115
+ return privateKeyBytes;
116
+ }
117
+
118
+ /**
119
+ * Decrypts a wrapped key using the AES Key Wrap algorithm.
120
+ *
121
+ * @remarks
122
+ * This method unwraps a previously wrapped cryptographic key using the AES Key Wrap algorithm.
123
+ * The wrapped key, provided as a byte array, is unwrapped using the decryption key specified in
124
+ * the parameters.
125
+ *
126
+ * This operation is useful for securely receiving keys transmitted over untrusted mediums. The
127
+ * method returns the unwrapped key as a JSON Web Key (JWK).
128
+ *
129
+ * @example
130
+ * ```ts
131
+ * const aesKw = new AesKwAlgorithm();
132
+ * const wrappedKeyBytes = new Uint8Array([...]); // Byte array of a wrapped AES-256 GCM key
133
+ * const decryptionKey = { ... }; // A Jwk object representing the AES unwrapping key
134
+ * const unwrappedKey = await aesKw.unwrapKey({
135
+ * wrappedKeyBytes,
136
+ * wrappedKeyAlgorithm: 'A256GCM',
137
+ * decryptionKey
138
+ * });
139
+ * ```
140
+ *
141
+ * @param params - The parameters for the key unwrapping operation.
142
+ *
143
+ * @returns A Promise that resolves to the unwrapped key in JWK format.
144
+ */
145
+ public async unwrapKey(params:
146
+ UnwrapKeyParams
147
+ ): Promise<Jwk> {
148
+ const unwrappedKey = await AesKw.unwrapKey(params);
149
+
150
+ return unwrappedKey;
151
+ }
152
+
153
+ /**
154
+ * Encrypts a given key using the AES Key Wrap algorithm.
155
+ *
156
+ * @remarks
157
+ * This method wraps a given cryptographic key using the AES Key Wrap algorithm. The private key
158
+ * to be wrapped is provided in the form of a JSON Web Key (JWK).
159
+ *
160
+ * This operation is useful for securely transmitting keys over untrusted mediums. The method
161
+ * returns the wrapped key as a byte array.
162
+ *
163
+ * @example
164
+ * ```ts
165
+ * const aesKw = new AesKwAlgorithm();
166
+ * const unwrappedKey = { ... }; // A Jwk object representing the key to be wrapped
167
+ * const encryptionKey = { ... }; // A Jwk object representing the AES wrapping key
168
+ * const wrappedKeyBytes = await aesKw.wrapKey({ unwrappedKey, encryptionKey });
169
+ * ```
170
+ *
171
+ * @param params - The parameters for the key wrapping operation.
172
+ *
173
+ * @returns A Promise that resolves to the wrapped key as a Uint8Array.
174
+ */
175
+ public async wrapKey(params:
176
+ WrapKeyParams
177
+ ): Promise<Uint8Array> {
178
+ const wrappedKeyBytes = AesKw.wrapKey(params);
179
+
180
+ return wrappedKeyBytes;
181
+ }
182
+ }
@@ -1,11 +1,23 @@
1
+ import type { AsymmetricKeyGenerator } from '../types/key-generator.js';
1
2
  import type { Jwk } from '../jose/jwk.js';
2
3
  import type { Signer } from '../types/signer.js';
3
- import type { AsymmetricKeyGenerator } from '../types/key-generator.js';
4
- import type { ComputePublicKeyParams, GenerateKeyParams, GetPublicKeyParams, SignParams, VerifyParams } from '../types/params-direct.js';
4
+ import type { AsymmetricKeyConverter, KeyConverter } from '../types/key-converter.js';
5
+ import type {
6
+ BytesToPrivateKeyParams,
7
+ BytesToPublicKeyParams,
8
+ ComputePublicKeyParams,
9
+ GenerateKeyParams,
10
+ GetPublicKeyParams,
11
+ PrivateKeyToBytesParams,
12
+ PublicKeyToBytesParams,
13
+ SignParams,
14
+ VerifyParams,
15
+ } from '../types/params-direct.js';
5
16
 
17
+ import { CryptoAlgorithm } from './crypto-algorithm.js';
6
18
  import { Secp256k1 } from '../primitives/secp256k1.js';
7
19
  import { Secp256r1 } from '../primitives/secp256r1.js';
8
- import { CryptoAlgorithm } from './crypto-algorithm.js';
20
+ import { CryptoError, CryptoErrorCode } from '../crypto-error.js';
9
21
  import { isEcPrivateJwk, isEcPublicJwk } from '../jose/jwk.js';
10
22
 
11
23
  /**
@@ -31,12 +43,83 @@ export interface EcdsaGenerateKeyParams extends GenerateKeyParams {
31
43
  * of signatures.
32
44
  *
33
45
  * This class is typically accessed through implementations that extend the
34
- * {@link CryptoApi | `CryptoApi`} interface.
46
+ * {@link DsaApi | `DsaApi`} interface.
35
47
  */
36
48
  export class EcdsaAlgorithm extends CryptoAlgorithm
37
49
  implements AsymmetricKeyGenerator<EcdsaGenerateKeyParams, Jwk, GetPublicKeyParams>,
50
+ KeyConverter, AsymmetricKeyConverter,
38
51
  Signer<SignParams, VerifyParams> {
39
52
 
53
+ /**
54
+ * Converts a private key from a byte array to JWK format, setting the `alg` property based on
55
+ * the algorithm.
56
+ *
57
+ * @param params - The parameters for the private key conversion.
58
+ * @param params.algorithm - The ECDSA algorithm identifier.
59
+ * @param params.privateKeyBytes - The raw private key as a Uint8Array.
60
+ *
61
+ * @returns A Promise that resolves to the private key in JWK format.
62
+ */
63
+ public async bytesToPrivateKey({ algorithm, privateKeyBytes }:
64
+ BytesToPrivateKeyParams & { algorithm: 'ES256' | 'ES256K' | 'secp256k1' | 'secp256r1' }
65
+ ): Promise<Jwk> {
66
+ switch (algorithm) {
67
+
68
+ case 'ES256K':
69
+ case 'secp256k1': {
70
+ const privateKey = await Secp256k1.bytesToPrivateKey({ privateKeyBytes });
71
+ privateKey.alg = 'ES256K';
72
+ return privateKey;
73
+ }
74
+
75
+ case 'ES256':
76
+ case 'secp256r1': {
77
+ const privateKey = await Secp256r1.bytesToPrivateKey({ privateKeyBytes });
78
+ privateKey.alg = 'ES256';
79
+ return privateKey;
80
+ }
81
+
82
+ default: {
83
+ throw new CryptoError(CryptoErrorCode.AlgorithmNotSupported, `Algorithm not supported: ${algorithm}`);
84
+ }
85
+ }
86
+ }
87
+
88
+ /**
89
+ * Converts a public key from a byte array to JWK format, setting the `alg` property based on
90
+ * the algorithm.
91
+ *
92
+ * @param params - The parameters for the public key conversion.
93
+ * @param params.algorithm - The ECDSA algorithm identifier.
94
+ * @param params.publicKeyBytes - The raw public key as a Uint8Array.
95
+ *
96
+ * @returns A Promise that resolves to the public key in JWK format.
97
+ */
98
+ public async bytesToPublicKey({ algorithm, publicKeyBytes }:
99
+ BytesToPublicKeyParams & { algorithm: 'ES256' | 'ES256K' | 'secp256k1' | 'secp256r1' }
100
+ ): Promise<Jwk> {
101
+ switch (algorithm) {
102
+
103
+ case 'ES256K':
104
+ case 'secp256k1': {
105
+ const publicKey = await Secp256k1.bytesToPublicKey({ publicKeyBytes });
106
+ publicKey.alg = 'ES256K';
107
+ return publicKey;
108
+ }
109
+
110
+ case 'ES256':
111
+ case 'secp256r1': {
112
+ const publicKey = await Secp256r1.bytesToPublicKey({ publicKeyBytes });
113
+ publicKey.alg = 'ES256';
114
+ return publicKey;
115
+ }
116
+
117
+ default: {
118
+ throw new CryptoError(CryptoErrorCode.AlgorithmNotSupported, `Algorithm not supported: ${algorithm}`);
119
+ }
120
+ }
121
+ }
122
+
40
123
  /**
41
124
  * Derives the public key in JWK format from a given private key.
42
125
  *
@@ -60,7 +143,7 @@ export class EcdsaAlgorithm extends CryptoAlgorithm
60
143
  public async computePublicKey({ key }:
61
144
  ComputePublicKeyParams
62
145
  ): Promise<Jwk> {
63
- if (!isEcPrivateJwk(key)) throw new TypeError('Invalid key provided. Must be an elliptic curve (EC) private key.');
146
+ if (!isEcPrivateJwk(key)) {throw new TypeError('Invalid key provided. Must be an elliptic curve (EC) private key.');}
64
147
 
65
148
  switch (key.crv) {
66
149
 
@@ -146,7 +229,7 @@ export class EcdsaAlgorithm extends CryptoAlgorithm
146
229
  public async getPublicKey({ key }:
147
230
  GetPublicKeyParams
148
231
  ): Promise<Jwk> {
149
- if (!isEcPrivateJwk(key)) throw new TypeError('Invalid key provided. Must be an elliptic curve (EC) private key.');
232
+ if (!isEcPrivateJwk(key)) {throw new TypeError('Invalid key provided. Must be an elliptic curve (EC) private key.');}
150
233
 
151
234
  switch (key.crv) {
152
235
 
@@ -199,7 +282,7 @@ export class EcdsaAlgorithm extends CryptoAlgorithm
199
282
  public async sign({ key, data }:
200
283
  SignParams
201
284
  ): Promise<Uint8Array> {
202
- if (!isEcPrivateJwk(key)) throw new TypeError('Invalid key provided. Must be an elliptic curve (EC) private key.');
285
+ if (!isEcPrivateJwk(key)) {throw new TypeError('Invalid key provided. Must be an elliptic curve (EC) private key.');}
203
286
 
204
287
  switch (key.crv) {
205
288
 
@@ -249,7 +332,7 @@ export class EcdsaAlgorithm extends CryptoAlgorithm
249
332
  public async verify({ key, signature, data }:
250
333
  VerifyParams
251
334
  ): Promise<boolean> {
252
- if (!isEcPublicJwk(key)) throw new TypeError('Invalid key provided. Must be an elliptic curve (EC) public key.');
335
+ if (!isEcPublicJwk(key)) {throw new TypeError('Invalid key provided. Must be an elliptic curve (EC) public key.');}
253
336
 
254
337
  switch (key.crv) {
255
338
 
@@ -266,4 +349,58 @@ export class EcdsaAlgorithm extends CryptoAlgorithm
266
349
  }
267
350
  }
268
351
  }
352
+
353
+ /**
354
+ * Converts a private key from JWK format to a byte array.
355
+ *
356
+ * @param params - The parameters for the private key conversion.
357
+ * @param params.privateKey - The private key in JWK format.
358
+ *
359
+ * @returns A Promise that resolves to the private key as a Uint8Array.
360
+ */
361
+ public async privateKeyToBytes({ privateKey }:
362
+ PrivateKeyToBytesParams
363
+ ): Promise<Uint8Array> {
364
+ switch (privateKey.crv) {
365
+
366
+ case 'secp256k1': {
367
+ return await Secp256k1.privateKeyToBytes({ privateKey });
368
+ }
369
+
370
+ case 'P-256': {
371
+ return await Secp256r1.privateKeyToBytes({ privateKey });
372
+ }
373
+
374
+ default: {
375
+ throw new CryptoError(CryptoErrorCode.AlgorithmNotSupported, `Curve not supported: ${privateKey.crv}`);
376
+ }
377
+ }
378
+ }
379
+
380
+ /**
381
+ * Converts a public key from JWK format to a byte array.
382
+ *
383
+ * @param params - The parameters for the public key conversion.
384
+ * @param params.publicKey - The public key in JWK format.
385
+ *
386
+ * @returns A Promise that resolves to the public key as a Uint8Array.
387
+ */
388
+ public async publicKeyToBytes({ publicKey }:
389
+ PublicKeyToBytesParams
390
+ ): Promise<Uint8Array> {
391
+ switch (publicKey.crv) {
392
+
393
+ case 'secp256k1': {
394
+ return await Secp256k1.publicKeyToBytes({ publicKey });
395
+ }
396
+
397
+ case 'P-256': {
398
+ return await Secp256r1.publicKeyToBytes({ publicKey });
399
+ }
400
+
401
+ default: {
402
+ throw new CryptoError(CryptoErrorCode.AlgorithmNotSupported, `Curve not supported: ${publicKey.crv}`);
403
+ }
404
+ }
405
+ }
269
406
  }
@@ -1,16 +1,22 @@
1
+ import type { AsymmetricKeyGenerator } from '../types/key-generator.js';
1
2
  import type { Jwk } from '../jose/jwk.js';
2
3
  import type { Signer } from '../types/signer.js';
3
- import type { AsymmetricKeyGenerator } from '../types/key-generator.js';
4
+ import type { AsymmetricKeyConverter, KeyConverter } from '../types/key-converter.js';
4
5
  import type {
5
- SignParams,
6
- VerifyParams,
6
+ BytesToPrivateKeyParams,
7
+ BytesToPublicKeyParams,
8
+ ComputePublicKeyParams,
7
9
  GenerateKeyParams,
8
10
  GetPublicKeyParams,
9
- ComputePublicKeyParams,
11
+ PrivateKeyToBytesParams,
12
+ PublicKeyToBytesParams,
13
+ SignParams,
14
+ VerifyParams,
10
15
  } from '../types/params-direct.js';
11
16
 
12
- import { Ed25519 } from '../primitives/ed25519.js';
13
17
  import { CryptoAlgorithm } from './crypto-algorithm.js';
18
+ import { Ed25519 } from '../primitives/ed25519.js';
19
+ import { CryptoError, CryptoErrorCode } from '../crypto-error.js';
14
20
  import { isOkpPrivateJwk, isOkpPublicJwk } from '../jose/jwk.js';
15
21
 
16
22
  /**
@@ -33,12 +39,67 @@ export interface EdDsaGenerateKeyParams extends GenerateKeyParams {
33
39
  * of signatures.
34
40
  *
35
41
  * This class is typically accessed through implementations that extend the
36
- * {@link CryptoApi | `CryptoApi`} interface.
42
+ * {@link DsaApi | `DsaApi`} interface.
37
43
  */
38
44
  export class EdDsaAlgorithm extends CryptoAlgorithm
39
45
  implements AsymmetricKeyGenerator<EdDsaGenerateKeyParams, Jwk, GetPublicKeyParams>,
46
+ KeyConverter, AsymmetricKeyConverter,
40
47
  Signer<SignParams, VerifyParams> {
41
48
 
49
+ /**
50
+ * Converts a private key from a byte array to JWK format, setting the `alg` property to
51
+ * `'EdDSA'`.
52
+ *
53
+ * @param params - The parameters for the private key conversion.
54
+ * @param params.algorithm - The EdDSA algorithm identifier (`'Ed25519'`).
55
+ * @param params.privateKeyBytes - The raw private key as a Uint8Array.
56
+ *
57
+ * @returns A Promise that resolves to the private key in JWK format.
58
+ */
59
+ public async bytesToPrivateKey({ algorithm, privateKeyBytes }:
60
+ BytesToPrivateKeyParams & { algorithm: 'Ed25519' }
61
+ ): Promise<Jwk> {
62
+ switch (algorithm) {
63
+
64
+ case 'Ed25519': {
65
+ const privateKey = await Ed25519.bytesToPrivateKey({ privateKeyBytes });
66
+ privateKey.alg = 'EdDSA';
67
+ return privateKey;
68
+ }
69
+
70
+ default: {
71
+ throw new CryptoError(CryptoErrorCode.AlgorithmNotSupported, `Algorithm not supported: ${algorithm}`);
72
+ }
73
+ }
74
+ }
75
+
76
+ /**
77
+ * Converts a public key from a byte array to JWK format, setting the `alg` property to
78
+ * `'EdDSA'`.
79
+ *
80
+ * @param params - The parameters for the public key conversion.
81
+ * @param params.algorithm - The EdDSA algorithm identifier (`'Ed25519'`).
82
+ * @param params.publicKeyBytes - The raw public key as a Uint8Array.
83
+ *
84
+ * @returns A Promise that resolves to the public key in JWK format.
85
+ */
86
+ public async bytesToPublicKey({ algorithm, publicKeyBytes }:
87
+ BytesToPublicKeyParams & { algorithm: 'Ed25519' }
88
+ ): Promise<Jwk> {
89
+ switch (algorithm) {
90
+
91
+ case 'Ed25519': {
92
+ const publicKey = await Ed25519.bytesToPublicKey({ publicKeyBytes });
93
+ publicKey.alg = 'EdDSA';
94
+ return publicKey;
95
+ }
96
+
97
+ default: {
98
+ throw new CryptoError(CryptoErrorCode.AlgorithmNotSupported, `Algorithm not supported: ${algorithm}`);
99
+ }
100
+ }
101
+ }
102
+
42
103
  /**
43
104
  * Derives the public key in JWK format from a given private key.
44
105
  *
@@ -62,7 +123,7 @@ export class EdDsaAlgorithm extends CryptoAlgorithm
62
123
  public async computePublicKey({ key }:
63
124
  ComputePublicKeyParams
64
125
  ): Promise<Jwk> {
65
- if (!isOkpPrivateJwk(key)) throw new TypeError('Invalid key provided. Must be an octet key pair (OKP) private key.');
126
+ if (!isOkpPrivateJwk(key)) {throw new TypeError('Invalid key provided. Must be an octet key pair (OKP) private key.');}
66
127
 
67
128
  switch (key.crv) {
68
129
 
@@ -134,7 +195,7 @@ export class EdDsaAlgorithm extends CryptoAlgorithm
134
195
  public async getPublicKey({ key }:
135
196
  GetPublicKeyParams
136
197
  ): Promise<Jwk> {
137
- if (!isOkpPrivateJwk(key)) throw new TypeError('Invalid key provided. Must be an octet key pair (OKP) private key.');
198
+ if (!isOkpPrivateJwk(key)) {throw new TypeError('Invalid key provided. Must be an octet key pair (OKP) private key.');}
138
199
 
139
200
  switch (key.crv) {
140
201
 
@@ -181,7 +242,7 @@ export class EdDsaAlgorithm extends CryptoAlgorithm
181
242
  public async sign({ key, data }:
182
243
  SignParams
183
244
  ): Promise<Uint8Array> {
184
- if (!isOkpPrivateJwk(key)) throw new TypeError('Invalid key provided. Must be an octet key pair (OKP) private key.');
245
+ if (!isOkpPrivateJwk(key)) {throw new TypeError('Invalid key provided. Must be an octet key pair (OKP) private key.');}
185
246
 
186
247
  switch (key.crv) {
187
248
 
@@ -227,7 +288,7 @@ export class EdDsaAlgorithm extends CryptoAlgorithm
227
288
  public async verify({ key, signature, data }:
228
289
  VerifyParams
229
290
  ): Promise<boolean> {
230
- if (!isOkpPublicJwk(key)) throw new TypeError('Invalid key provided. Must be an octet key pair (OKP) public key.');
291
+ if (!isOkpPublicJwk(key)) {throw new TypeError('Invalid key provided. Must be an octet key pair (OKP) public key.');}
231
292
 
232
293
  switch (key.crv) {
233
294
 
@@ -240,4 +301,50 @@ export class EdDsaAlgorithm extends CryptoAlgorithm
240
301
  }
241
302
  }
242
303
  }
304
+
305
+ /**
306
+ * Converts a private key from JWK format to a byte array.
307
+ *
308
+ * @param params - The parameters for the private key conversion.
309
+ * @param params.privateKey - The private key in JWK format.
310
+ *
311
+ * @returns A Promise that resolves to the private key as a Uint8Array.
312
+ */
313
+ public async privateKeyToBytes({ privateKey }:
314
+ PrivateKeyToBytesParams
315
+ ): Promise<Uint8Array> {
316
+ switch (privateKey.crv) {
317
+
318
+ case 'Ed25519': {
319
+ return await Ed25519.privateKeyToBytes({ privateKey });
320
+ }
321
+
322
+ default: {
323
+ throw new CryptoError(CryptoErrorCode.AlgorithmNotSupported, `Curve not supported: ${privateKey.crv}`);
324
+ }
325
+ }
326
+ }
327
+
328
+ /**
329
+ * Converts a public key from JWK format to a byte array.
330
+ *
331
+ * @param params - The parameters for the public key conversion.
332
+ * @param params.publicKey - The public key in JWK format.
333
+ *
334
+ * @returns A Promise that resolves to the public key as a Uint8Array.
335
+ */
336
+ public async publicKeyToBytes({ publicKey }:
337
+ PublicKeyToBytesParams
338
+ ): Promise<Uint8Array> {
339
+ switch (publicKey.crv) {
340
+
341
+ case 'Ed25519': {
342
+ return await Ed25519.publicKeyToBytes({ publicKey });
343
+ }
344
+
345
+ default: {
346
+ throw new CryptoError(CryptoErrorCode.AlgorithmNotSupported, `Curve not supported: ${publicKey.crv}`);
347
+ }
348
+ }
349
+ }
243
350
  }
@@ -0,0 +1,54 @@
1
+ import type { DeriveKeyBytesParams } from '../types/params-direct.js';
2
+ import type { HkdfParams } from '../primitives/hkdf.js';
3
+ import type { KeyBytesDeriver } from '../types/key-deriver.js';
4
+
5
+ import { CryptoAlgorithm } from './crypto-algorithm.js';
6
+ import { Hkdf } from '../primitives/hkdf.js';
7
+
8
+ /**
9
+ * The `HkdfDeriveKeyBytesParams` interface defines the algorithm-specific parameters that should be
10
+ * passed into the `deriveKeyBytes()` method when using the HKDF algorithm.
11
+ */
12
+ export interface HkdfDeriveKeyBytesParams extends DeriveKeyBytesParams {
13
+ /** Specifies the algorithm variant for HKDF key derivation.
14
+ * The value determines the hash function that will be used and must be one of the following:
15
+ * - `"HKDF-256"`: HKDF with SHA-256.
16
+ * - `"HKDF-384"`: HKDF with SHA-384.
17
+ * - `"HKDF-512"`: HKDF with SHA-512.
18
+ */
19
+ algorithm: 'HKDF-256' | 'HKDF-384' | 'HKDF-512';
20
+ }
21
+
22
+ /**
23
+ * The `HkdfAlgorithm` class provides a concrete implementation for HKDF key derivation. It wraps
24
+ * the {@link Hkdf} primitive and maps JOSE algorithm names to hash functions.
25
+ */
26
+ export class HkdfAlgorithm extends CryptoAlgorithm
27
+ implements KeyBytesDeriver<HkdfDeriveKeyBytesParams, Uint8Array> {
28
+
29
+ /**
30
+ * Derives a cryptographic byte array using HKDF.
31
+ *
32
+ * @param params - The parameters for the key derivation operation.
33
+ * @param params.algorithm - The HKDF algorithm variant (e.g., `'HKDF-256'`).
34
+ * @param params.baseKeyBytes - The input key material.
35
+ * @param params.length - The desired length of the output in bits.
36
+ *
37
+ * @returns A Promise that resolves to the derived key bytes.
38
+ */
39
+ public async deriveKeyBytes({ algorithm, ...params }:
40
+ HkdfDeriveKeyBytesParams & Omit<HkdfParams, 'hash'>
41
+ ): Promise<Uint8Array> {
42
+ // Map algorithm name to hash function.
43
+ const hash = {
44
+ 'HKDF-256' : 'SHA-256' as const,
45
+ 'HKDF-384' : 'SHA-384' as const,
46
+ 'HKDF-512' : 'SHA-512' as const
47
+ }[algorithm];
48
+
49
+ // Derive a cryptographic byte array using HKDF.
50
+ const derivedKeyBytes = await Hkdf.deriveKeyBytes({ ...params, hash });
51
+
52
+ return derivedKeyBytes;
53
+ }
54
+ }
@@ -0,0 +1,57 @@
1
+ import type { DeriveKeyBytesParams } from '../types/params-direct.js';
2
+ import type { KeyBytesDeriver } from '../types/key-deriver.js';
3
+ import type { Pbkdf2Params } from '../primitives/pbkdf2.js';
4
+
5
+ import { CryptoAlgorithm } from './crypto-algorithm.js';
6
+ import { Pbkdf2 } from '../primitives/pbkdf2.js';
7
+
8
+ /**
9
+ * The `Pbkdf2DeriveKeyBytesParams` interface defines the algorithm-specific parameters that
10
+ * should be passed into the `deriveKeyBytes()` method when using the PBKDF2 algorithm.
11
+ */
12
+ export interface Pbkdf2DeriveKeyBytesParams extends DeriveKeyBytesParams {
13
+ /** Specifies the algorithm variant for PBKDF2 key derivation.
14
+ * The value determines the hash function that will be used and must be one of the following:
15
+ * - `"PBES2-HS256+A128KW"`: PBKDF2 with HMAC SHA-256 and A128KW key wrapping.
16
+ * - `"PBES2-HS384+A192KW"`: PBKDF2 with HMAC SHA-384 and A192KW key wrapping.
17
+ * - `"PBES2-HS512+A256KW"`: PBKDF2 with HMAC SHA-512 and A256KW key wrapping.
18
+ */
19
+ algorithm: 'PBES2-HS256+A128KW' | 'PBES2-HS384+A192KW' | 'PBES2-HS512+A256KW';
20
+ }
21
+
22
+ /**
23
+ * The `Pbkdf2Algorithm` class provides a concrete implementation for PBKDF2 key derivation. It
24
+ * wraps the {@link Pbkdf2} primitive and maps PBES2 JOSE algorithm names to hash functions.
25
+ */
26
+ export class Pbkdf2Algorithm extends CryptoAlgorithm
27
+ implements KeyBytesDeriver<Pbkdf2DeriveKeyBytesParams, Uint8Array> {
28
+
29
+ /**
30
+ * Derives a cryptographic byte array using PBKDF2.
31
+ *
32
+ * @param params - The parameters for the key derivation operation.
33
+ * @param params.algorithm - The PBES2 algorithm variant (e.g., `'PBES2-HS512+A256KW'`).
34
+ * @param params.baseKeyBytes - The password or passphrase as bytes.
35
+ * @param params.length - The desired length of the output in bits.
36
+ *
37
+ * @returns A Promise that resolves to the derived key bytes.
38
+ */
39
+ public async deriveKeyBytes({ algorithm, ...params }:
40
+ Pbkdf2DeriveKeyBytesParams & Omit<Pbkdf2Params, 'hash'>
41
+ ): Promise<Uint8Array> {
42
+ // Extract the hash function component of the `algorithm` parameter.
43
+ const [, hashFunction] = algorithm.split(/[-+]/);
44
+
45
+ // Map from JOSE algorithm name to "SHA" hash function identifier.
46
+ const hash = {
47
+ 'HS256' : 'SHA-256' as const,
48
+ 'HS384' : 'SHA-384' as const,
49
+ 'HS512' : 'SHA-512' as const
50
+ }[hashFunction]!;
51
+
52
+ // Derive a cryptographic byte array using PBKDF2.
53
+ const derivedKeyBytes = await Pbkdf2.deriveKeyBytes({ ...params, hash });
54
+
55
+ return derivedKeyBytes;
56
+ }
57
+ }