react-native-quick-crypto 1.0.11 → 1.0.13

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 (197) hide show
  1. package/android/CMakeLists.txt +7 -0
  2. package/cpp/cipher/CCMCipher.cpp +4 -1
  3. package/cpp/cipher/ChaCha20Cipher.cpp +3 -1
  4. package/cpp/cipher/ChaCha20Poly1305Cipher.cpp +5 -5
  5. package/cpp/cipher/ChaCha20Poly1305Cipher.hpp +1 -2
  6. package/cpp/cipher/HybridCipher.cpp +10 -1
  7. package/cpp/cipher/HybridCipher.hpp +2 -0
  8. package/cpp/cipher/HybridRsaCipher.cpp +0 -13
  9. package/cpp/cipher/XChaCha20Poly1305Cipher.cpp +7 -5
  10. package/cpp/cipher/XChaCha20Poly1305Cipher.hpp +1 -2
  11. package/cpp/cipher/XSalsa20Cipher.cpp +4 -0
  12. package/cpp/cipher/XSalsa20Poly1305Cipher.cpp +7 -5
  13. package/cpp/cipher/XSalsa20Poly1305Cipher.hpp +1 -2
  14. package/cpp/ecdh/HybridECDH.cpp +20 -133
  15. package/cpp/keys/HybridKeyObjectHandle.cpp +144 -141
  16. package/cpp/keys/HybridKeyObjectHandle.hpp +6 -3
  17. package/cpp/keys/KeyObjectData.hpp +2 -0
  18. package/cpp/kmac/HybridKmac.cpp +83 -0
  19. package/cpp/kmac/HybridKmac.hpp +31 -0
  20. package/cpp/mldsa/HybridMlDsaKeyPair.cpp +11 -20
  21. package/cpp/mldsa/HybridMlDsaKeyPair.hpp +4 -2
  22. package/cpp/mlkem/HybridMlKemKeyPair.cpp +319 -0
  23. package/cpp/mlkem/HybridMlKemKeyPair.hpp +48 -0
  24. package/cpp/sign/SignUtils.hpp +9 -26
  25. package/cpp/utils/QuickCryptoUtils.cpp +44 -0
  26. package/cpp/utils/QuickCryptoUtils.hpp +39 -0
  27. package/cpp/x509/HybridX509Certificate.cpp +174 -0
  28. package/cpp/x509/HybridX509Certificate.hpp +51 -0
  29. package/lib/commonjs/cipher.js +15 -2
  30. package/lib/commonjs/cipher.js.map +1 -1
  31. package/lib/commonjs/dhKeyPair.js +3 -3
  32. package/lib/commonjs/dhKeyPair.js.map +1 -1
  33. package/lib/commonjs/dsa.js +3 -3
  34. package/lib/commonjs/dsa.js.map +1 -1
  35. package/lib/commonjs/ec.js +18 -18
  36. package/lib/commonjs/ec.js.map +1 -1
  37. package/lib/commonjs/ed.js +9 -9
  38. package/lib/commonjs/ed.js.map +1 -1
  39. package/lib/commonjs/hash.js +17 -12
  40. package/lib/commonjs/hash.js.map +1 -1
  41. package/lib/commonjs/hkdf.js.map +1 -1
  42. package/lib/commonjs/index.js +22 -0
  43. package/lib/commonjs/index.js.map +1 -1
  44. package/lib/commonjs/keys/classes.js +2 -2
  45. package/lib/commonjs/keys/classes.js.map +1 -1
  46. package/lib/commonjs/keys/index.js +24 -0
  47. package/lib/commonjs/keys/index.js.map +1 -1
  48. package/lib/commonjs/keys/publicCipher.js +2 -2
  49. package/lib/commonjs/keys/publicCipher.js.map +1 -1
  50. package/lib/commonjs/keys/signVerify.js +0 -2
  51. package/lib/commonjs/keys/signVerify.js.map +1 -1
  52. package/lib/commonjs/mlkem.js +219 -0
  53. package/lib/commonjs/mlkem.js.map +1 -0
  54. package/lib/commonjs/pbkdf2.js +18 -1
  55. package/lib/commonjs/pbkdf2.js.map +1 -1
  56. package/lib/commonjs/rsa.js +7 -7
  57. package/lib/commonjs/rsa.js.map +1 -1
  58. package/lib/commonjs/specs/kmac.nitro.js +6 -0
  59. package/lib/commonjs/specs/kmac.nitro.js.map +1 -0
  60. package/lib/commonjs/specs/mlKemKeyPair.nitro.js +6 -0
  61. package/lib/commonjs/specs/mlKemKeyPair.nitro.js.map +1 -0
  62. package/lib/commonjs/specs/x509certificate.nitro.js +6 -0
  63. package/lib/commonjs/specs/x509certificate.nitro.js.map +1 -0
  64. package/lib/commonjs/subtle.js +292 -112
  65. package/lib/commonjs/subtle.js.map +1 -1
  66. package/lib/commonjs/utils/conversion.js +3 -3
  67. package/lib/commonjs/utils/conversion.js.map +1 -1
  68. package/lib/commonjs/utils/hashnames.js +31 -0
  69. package/lib/commonjs/utils/hashnames.js.map +1 -1
  70. package/lib/commonjs/utils/types.js.map +1 -1
  71. package/lib/commonjs/x509certificate.js +189 -0
  72. package/lib/commonjs/x509certificate.js.map +1 -0
  73. package/lib/module/cipher.js +16 -3
  74. package/lib/module/cipher.js.map +1 -1
  75. package/lib/module/dhKeyPair.js +1 -1
  76. package/lib/module/dhKeyPair.js.map +1 -1
  77. package/lib/module/dsa.js +1 -1
  78. package/lib/module/dsa.js.map +1 -1
  79. package/lib/module/ec.js +6 -6
  80. package/lib/module/ec.js.map +1 -1
  81. package/lib/module/ed.js +1 -1
  82. package/lib/module/ed.js.map +1 -1
  83. package/lib/module/hash.js +17 -12
  84. package/lib/module/hash.js.map +1 -1
  85. package/lib/module/hkdf.js.map +1 -1
  86. package/lib/module/index.js +6 -0
  87. package/lib/module/index.js.map +1 -1
  88. package/lib/module/keys/classes.js +2 -2
  89. package/lib/module/keys/classes.js.map +1 -1
  90. package/lib/module/keys/index.js +25 -1
  91. package/lib/module/keys/index.js.map +1 -1
  92. package/lib/module/keys/publicCipher.js +2 -2
  93. package/lib/module/keys/publicCipher.js.map +1 -1
  94. package/lib/module/keys/signVerify.js +0 -2
  95. package/lib/module/keys/signVerify.js.map +1 -1
  96. package/lib/module/mlkem.js +211 -0
  97. package/lib/module/mlkem.js.map +1 -0
  98. package/lib/module/pbkdf2.js +18 -1
  99. package/lib/module/pbkdf2.js.map +1 -1
  100. package/lib/module/rsa.js +1 -1
  101. package/lib/module/rsa.js.map +1 -1
  102. package/lib/module/specs/kmac.nitro.js +4 -0
  103. package/lib/module/specs/kmac.nitro.js.map +1 -0
  104. package/lib/module/specs/mlKemKeyPair.nitro.js +4 -0
  105. package/lib/module/specs/mlKemKeyPair.nitro.js.map +1 -0
  106. package/lib/module/specs/x509certificate.nitro.js +4 -0
  107. package/lib/module/specs/x509certificate.nitro.js.map +1 -0
  108. package/lib/module/subtle.js +292 -112
  109. package/lib/module/subtle.js.map +1 -1
  110. package/lib/module/utils/conversion.js +3 -4
  111. package/lib/module/utils/conversion.js.map +1 -1
  112. package/lib/module/utils/hashnames.js +31 -0
  113. package/lib/module/utils/hashnames.js.map +1 -1
  114. package/lib/module/utils/types.js.map +1 -1
  115. package/lib/module/x509certificate.js +184 -0
  116. package/lib/module/x509certificate.js.map +1 -0
  117. package/lib/tsconfig.tsbuildinfo +1 -1
  118. package/lib/typescript/cipher.d.ts +3 -0
  119. package/lib/typescript/cipher.d.ts.map +1 -1
  120. package/lib/typescript/dhKeyPair.d.ts +1 -1
  121. package/lib/typescript/dhKeyPair.d.ts.map +1 -1
  122. package/lib/typescript/dsa.d.ts +1 -1
  123. package/lib/typescript/dsa.d.ts.map +1 -1
  124. package/lib/typescript/ec.d.ts +1 -1
  125. package/lib/typescript/ec.d.ts.map +1 -1
  126. package/lib/typescript/ed.d.ts +1 -1
  127. package/lib/typescript/ed.d.ts.map +1 -1
  128. package/lib/typescript/hash.d.ts.map +1 -1
  129. package/lib/typescript/hkdf.d.ts +2 -6
  130. package/lib/typescript/hkdf.d.ts.map +1 -1
  131. package/lib/typescript/index.d.ts +15 -4
  132. package/lib/typescript/index.d.ts.map +1 -1
  133. package/lib/typescript/keys/classes.d.ts +5 -5
  134. package/lib/typescript/keys/classes.d.ts.map +1 -1
  135. package/lib/typescript/keys/index.d.ts +2 -2
  136. package/lib/typescript/keys/index.d.ts.map +1 -1
  137. package/lib/typescript/keys/signVerify.d.ts.map +1 -1
  138. package/lib/typescript/mlkem.d.ts +30 -0
  139. package/lib/typescript/mlkem.d.ts.map +1 -0
  140. package/lib/typescript/pbkdf2.d.ts +2 -2
  141. package/lib/typescript/pbkdf2.d.ts.map +1 -1
  142. package/lib/typescript/rsa.d.ts +1 -1
  143. package/lib/typescript/rsa.d.ts.map +1 -1
  144. package/lib/typescript/specs/keyObjectHandle.nitro.d.ts +1 -0
  145. package/lib/typescript/specs/keyObjectHandle.nitro.d.ts.map +1 -1
  146. package/lib/typescript/specs/kmac.nitro.d.ts +10 -0
  147. package/lib/typescript/specs/kmac.nitro.d.ts.map +1 -0
  148. package/lib/typescript/specs/mlKemKeyPair.nitro.d.ts +18 -0
  149. package/lib/typescript/specs/mlKemKeyPair.nitro.d.ts.map +1 -0
  150. package/lib/typescript/specs/x509certificate.nitro.d.ts +34 -0
  151. package/lib/typescript/specs/x509certificate.nitro.d.ts.map +1 -0
  152. package/lib/typescript/subtle.d.ts +10 -0
  153. package/lib/typescript/subtle.d.ts.map +1 -1
  154. package/lib/typescript/utils/conversion.d.ts.map +1 -1
  155. package/lib/typescript/utils/hashnames.d.ts +1 -1
  156. package/lib/typescript/utils/hashnames.d.ts.map +1 -1
  157. package/lib/typescript/utils/types.d.ts +13 -7
  158. package/lib/typescript/utils/types.d.ts.map +1 -1
  159. package/lib/typescript/x509certificate.d.ts +64 -0
  160. package/lib/typescript/x509certificate.d.ts.map +1 -0
  161. package/nitrogen/generated/android/QuickCrypto+autolinking.cmake +3 -0
  162. package/nitrogen/generated/android/QuickCryptoOnLoad.cpp +30 -0
  163. package/nitrogen/generated/ios/QuickCryptoAutolinking.mm +30 -0
  164. package/nitrogen/generated/shared/c++/AsymmetricKeyType.hpp +12 -0
  165. package/nitrogen/generated/shared/c++/HybridKeyObjectHandleSpec.cpp +1 -0
  166. package/nitrogen/generated/shared/c++/HybridKeyObjectHandleSpec.hpp +1 -0
  167. package/nitrogen/generated/shared/c++/HybridKmacSpec.cpp +23 -0
  168. package/nitrogen/generated/shared/c++/HybridKmacSpec.hpp +66 -0
  169. package/nitrogen/generated/shared/c++/HybridMlKemKeyPairSpec.cpp +31 -0
  170. package/nitrogen/generated/shared/c++/HybridMlKemKeyPairSpec.hpp +74 -0
  171. package/nitrogen/generated/shared/c++/HybridX509CertificateHandleSpec.cpp +46 -0
  172. package/nitrogen/generated/shared/c++/HybridX509CertificateHandleSpec.hpp +96 -0
  173. package/package.json +4 -1
  174. package/src/cipher.ts +17 -3
  175. package/src/dhKeyPair.ts +1 -1
  176. package/src/dsa.ts +1 -1
  177. package/src/ec.ts +9 -9
  178. package/src/ed.ts +2 -2
  179. package/src/hash.ts +34 -11
  180. package/src/hkdf.ts +2 -7
  181. package/src/index.ts +7 -0
  182. package/src/keys/classes.ts +10 -9
  183. package/src/keys/index.ts +37 -2
  184. package/src/keys/publicCipher.ts +2 -2
  185. package/src/keys/signVerify.ts +0 -5
  186. package/src/mlkem.ts +350 -0
  187. package/src/pbkdf2.ts +34 -5
  188. package/src/rsa.ts +1 -1
  189. package/src/specs/keyObjectHandle.nitro.ts +5 -0
  190. package/src/specs/kmac.nitro.ts +12 -0
  191. package/src/specs/mlKemKeyPair.nitro.ts +32 -0
  192. package/src/specs/x509certificate.nitro.ts +38 -0
  193. package/src/subtle.ts +551 -125
  194. package/src/utils/conversion.ts +10 -4
  195. package/src/utils/hashnames.ts +33 -2
  196. package/src/utils/types.ts +42 -5
  197. package/src/x509certificate.ts +277 -0
@@ -0,0 +1,96 @@
1
+ ///
2
+ /// HybridX509CertificateHandleSpec.hpp
3
+ /// This file was generated by nitrogen. DO NOT MODIFY THIS FILE.
4
+ /// https://github.com/mrousavy/nitro
5
+ /// Copyright © Marc Rousavy @ Margelo
6
+ ///
7
+
8
+ #pragma once
9
+
10
+ #if __has_include(<NitroModules/HybridObject.hpp>)
11
+ #include <NitroModules/HybridObject.hpp>
12
+ #else
13
+ #error NitroModules cannot be found! Are you sure you installed NitroModules properly?
14
+ #endif
15
+
16
+ // Forward declaration of `HybridKeyObjectHandleSpec` to properly resolve imports.
17
+ namespace margelo::nitro::crypto { class HybridKeyObjectHandleSpec; }
18
+ // Forward declaration of `HybridX509CertificateHandleSpec` to properly resolve imports.
19
+ namespace margelo::nitro::crypto { class HybridX509CertificateHandleSpec; }
20
+
21
+ #include <NitroModules/ArrayBuffer.hpp>
22
+ #include <string>
23
+ #include <memory>
24
+ #include "HybridKeyObjectHandleSpec.hpp"
25
+ #include <vector>
26
+ #include "HybridX509CertificateHandleSpec.hpp"
27
+ #include <optional>
28
+
29
+ namespace margelo::nitro::crypto {
30
+
31
+ using namespace margelo::nitro;
32
+
33
+ /**
34
+ * An abstract base class for `X509CertificateHandle`
35
+ * Inherit this class to create instances of `HybridX509CertificateHandleSpec` in C++.
36
+ * You must explicitly call `HybridObject`'s constructor yourself, because it is virtual.
37
+ * @example
38
+ * ```cpp
39
+ * class HybridX509CertificateHandle: public HybridX509CertificateHandleSpec {
40
+ * public:
41
+ * HybridX509CertificateHandle(...): HybridObject(TAG) { ... }
42
+ * // ...
43
+ * };
44
+ * ```
45
+ */
46
+ class HybridX509CertificateHandleSpec: public virtual HybridObject {
47
+ public:
48
+ // Constructor
49
+ explicit HybridX509CertificateHandleSpec(): HybridObject(TAG) { }
50
+
51
+ // Destructor
52
+ ~HybridX509CertificateHandleSpec() override = default;
53
+
54
+ public:
55
+ // Properties
56
+
57
+
58
+ public:
59
+ // Methods
60
+ virtual void init(const std::shared_ptr<ArrayBuffer>& buffer) = 0;
61
+ virtual std::string subject() = 0;
62
+ virtual std::string subjectAltName() = 0;
63
+ virtual std::string issuer() = 0;
64
+ virtual std::string infoAccess() = 0;
65
+ virtual std::string validFrom() = 0;
66
+ virtual std::string validTo() = 0;
67
+ virtual double validFromDate() = 0;
68
+ virtual double validToDate() = 0;
69
+ virtual std::string signatureAlgorithm() = 0;
70
+ virtual std::string signatureAlgorithmOid() = 0;
71
+ virtual std::string serialNumber() = 0;
72
+ virtual std::string fingerprint() = 0;
73
+ virtual std::string fingerprint256() = 0;
74
+ virtual std::string fingerprint512() = 0;
75
+ virtual std::shared_ptr<ArrayBuffer> raw() = 0;
76
+ virtual std::string pem() = 0;
77
+ virtual std::shared_ptr<HybridKeyObjectHandleSpec> publicKey() = 0;
78
+ virtual std::vector<std::string> keyUsage() = 0;
79
+ virtual bool ca() = 0;
80
+ virtual bool checkIssued(const std::shared_ptr<HybridX509CertificateHandleSpec>& other) = 0;
81
+ virtual bool checkPrivateKey(const std::shared_ptr<HybridKeyObjectHandleSpec>& key) = 0;
82
+ virtual bool verify(const std::shared_ptr<HybridKeyObjectHandleSpec>& key) = 0;
83
+ virtual std::optional<std::string> checkHost(const std::string& name, double flags) = 0;
84
+ virtual std::optional<std::string> checkEmail(const std::string& email, double flags) = 0;
85
+ virtual std::optional<std::string> checkIP(const std::string& ip) = 0;
86
+
87
+ protected:
88
+ // Hybrid Setup
89
+ void loadHybridMethods() override;
90
+
91
+ protected:
92
+ // Tag for logging
93
+ static constexpr auto TAG = "X509CertificateHandle";
94
+ };
95
+
96
+ } // namespace margelo::nitro::crypto
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "react-native-quick-crypto",
3
- "version": "1.0.11",
3
+ "version": "1.0.13",
4
4
  "description": "A fast implementation of Node's `crypto` module written in C/C++ JSI",
5
5
  "main": "lib/commonjs/index",
6
6
  "module": "lib/module/index",
@@ -19,6 +19,7 @@
19
19
  "prepare": "bun clean && bun tsc && bob build",
20
20
  "release": "release-it",
21
21
  "specs": "nitrogen",
22
+ "circular": "dpdm --circular --no-tree --no-warning --exit-code circular:1 --transform src/index.ts",
22
23
  "test": "jest"
23
24
  },
24
25
  "files": [
@@ -77,6 +78,7 @@
77
78
  "events": "3.3.0",
78
79
  "readable-stream": "4.5.2",
79
80
  "safe-buffer": "^5.2.1",
81
+ "string_decoder": "^1.3.0",
80
82
  "util": "0.12.5"
81
83
  },
82
84
  "devDependencies": {
@@ -85,6 +87,7 @@
85
87
  "@types/react": "18.3.3",
86
88
  "@types/readable-stream": "4.0.18",
87
89
  "del-cli": "7.0.0",
90
+ "dpdm": "^4.0.1",
88
91
  "expo": "^54.0.25",
89
92
  "expo-build-properties": "^1.0.0",
90
93
  "jest": "29.7.0",
package/src/cipher.ts CHANGED
@@ -1,5 +1,6 @@
1
1
  import { NitroModules } from 'react-native-nitro-modules';
2
2
  import Stream, { type TransformOptions } from 'readable-stream';
3
+ import { StringDecoder } from 'string_decoder';
3
4
  import { Buffer } from '@craftzdog/react-native-buffer';
4
5
  import type { BinaryLike, BinaryLikeNode, Encoding } from './utils';
5
6
  import type {
@@ -14,7 +15,7 @@ import type {
14
15
  Cipher as NativeCipher,
15
16
  CipherFactory,
16
17
  } from './specs/cipher.nitro';
17
- import { ab2str, binaryLikeToArrayBuffer } from './utils';
18
+ import { binaryLikeToArrayBuffer } from './utils';
18
19
  import {
19
20
  getDefaultEncoding,
20
21
  getUIntOption,
@@ -74,6 +75,8 @@ interface CipherArgs {
74
75
 
75
76
  class CipherCommon extends Stream.Transform {
76
77
  private native: NativeCipher;
78
+ private _decoder: StringDecoder | null = null;
79
+ private _decoderEncoding: string | undefined = undefined;
77
80
 
78
81
  constructor({ isCipher, cipherType, cipherKey, iv, options }: CipherArgs) {
79
82
  // Explicitly create TransformOptions for super()
@@ -120,6 +123,17 @@ class CipherCommon extends Stream.Transform {
120
123
  });
121
124
  }
122
125
 
126
+ private getDecoder(encoding: string): StringDecoder {
127
+ const normalized = normalizeEncoding(encoding);
128
+ if (!this._decoder) {
129
+ this._decoder = new StringDecoder(encoding as BufferEncoding);
130
+ this._decoderEncoding = normalized;
131
+ } else if (this._decoderEncoding !== normalized) {
132
+ throw new Error('Cannot change encoding');
133
+ }
134
+ return this._decoder;
135
+ }
136
+
123
137
  update(data: Buffer): Buffer;
124
138
  update(data: BinaryLike, inputEncoding?: Encoding): Buffer;
125
139
  update(
@@ -147,7 +161,7 @@ class CipherCommon extends Stream.Transform {
147
161
  );
148
162
 
149
163
  if (outputEncoding && outputEncoding !== 'buffer') {
150
- return ab2str(ret, outputEncoding);
164
+ return this.getDecoder(outputEncoding).write(Buffer.from(ret));
151
165
  }
152
166
 
153
167
  return Buffer.from(ret);
@@ -159,7 +173,7 @@ class CipherCommon extends Stream.Transform {
159
173
  const ret = this.native.final();
160
174
 
161
175
  if (outputEncoding && outputEncoding !== 'buffer') {
162
- return ab2str(ret, outputEncoding);
176
+ return this.getDecoder(outputEncoding).end(Buffer.from(ret));
163
177
  }
164
178
 
165
179
  return Buffer.from(ret);
package/src/dhKeyPair.ts CHANGED
@@ -1,6 +1,6 @@
1
1
  import { NitroModules } from 'react-native-nitro-modules';
2
2
  import { Buffer } from '@craftzdog/react-native-buffer';
3
- import { KeyObject, PublicKeyObject, PrivateKeyObject } from './keys';
3
+ import { KeyObject, PublicKeyObject, PrivateKeyObject } from './keys/classes';
4
4
  import type { DhKeyPair } from './specs/dhKeyPair.nitro';
5
5
  import type { GenerateKeyPairOptions, KeyPairGenConfig } from './utils/types';
6
6
  import { KFormatType, KeyEncoding } from './utils';
package/src/dsa.ts CHANGED
@@ -1,6 +1,6 @@
1
1
  import { NitroModules } from 'react-native-nitro-modules';
2
2
  import { Buffer } from '@craftzdog/react-native-buffer';
3
- import { KeyObject, PublicKeyObject, PrivateKeyObject } from './keys';
3
+ import { KeyObject, PublicKeyObject, PrivateKeyObject } from './keys/classes';
4
4
  import type { DsaKeyPair } from './specs/dsaKeyPair.nitro';
5
5
  import type { GenerateKeyPairOptions, KeyPairGenConfig } from './utils/types';
6
6
  import { KFormatType, KeyEncoding } from './utils';
package/src/ec.ts CHANGED
@@ -6,7 +6,7 @@ import {
6
6
  KeyObject,
7
7
  PublicKeyObject,
8
8
  PrivateKeyObject,
9
- } from './keys';
9
+ } from './keys/classes';
10
10
  import type {
11
11
  CryptoKeyPair,
12
12
  KeyPairOptions,
@@ -76,7 +76,7 @@ export class Ec {
76
76
  }
77
77
  }
78
78
 
79
- // Node API
79
+ // WebCrypto API - only P-256, P-384, P-521 allowed per spec
80
80
  export function ecImportKey(
81
81
  format: ImportFormat,
82
82
  keyData: BufferLike | BinaryLike | JWK,
@@ -289,7 +289,7 @@ export const ecdsaSignVerify = (
289
289
  }
290
290
  };
291
291
 
292
- // Node API
292
+ // WebCrypto API - only P-256, P-384, P-521 allowed per spec
293
293
 
294
294
  export async function ec_generateKeyPair(
295
295
  name: string,
@@ -388,11 +388,8 @@ function ec_prepareKeyGenParams(
388
388
 
389
389
  const { namedCurve } = options as { namedCurve?: string };
390
390
 
391
- if (
392
- !namedCurve ||
393
- !kNamedCurveAliases[namedCurve as keyof typeof kNamedCurveAliases]
394
- ) {
395
- throw new Error(`Invalid or unsupported named curve: ${namedCurve}`);
391
+ if (!namedCurve) {
392
+ throw new Error('namedCurve is required for EC key generation');
396
393
  }
397
394
 
398
395
  return new Ec(namedCurve);
@@ -550,7 +547,10 @@ export function ecDeriveBits(
550
547
  // If length is specified, truncate
551
548
  const byteLength = Math.ceil(length / 8);
552
549
  if (secretBuf.byteLength >= byteLength) {
553
- return secretBuf.subarray(0, byteLength).buffer as ArrayBuffer;
550
+ return secretBuf.buffer.slice(
551
+ secretBuf.byteOffset,
552
+ secretBuf.byteOffset + byteLength,
553
+ ) as ArrayBuffer;
554
554
  }
555
555
 
556
556
  throw new Error('Derived key is shorter than requested length');
package/src/ed.ts CHANGED
@@ -1,12 +1,12 @@
1
1
  import { NitroModules } from 'react-native-nitro-modules';
2
2
  import { Buffer } from '@craftzdog/react-native-buffer';
3
- import type { AsymmetricKeyObject, PrivateKeyObject } from './keys';
3
+ import type { AsymmetricKeyObject, PrivateKeyObject } from './keys/classes';
4
4
  import {
5
5
  CryptoKey,
6
6
  KeyObject,
7
7
  PublicKeyObject,
8
8
  PrivateKeyObject as PrivateKeyObjectClass,
9
- } from './keys';
9
+ } from './keys/classes';
10
10
  import type { EdKeyPair } from './specs/edKeyPair.nitro';
11
11
  import type {
12
12
  BinaryLike,
package/src/hash.ts CHANGED
@@ -241,19 +241,38 @@ export const asyncDigest = async (
241
241
  ): Promise<ArrayBuffer> => {
242
242
  validateMaxBufferLength(data, 'data');
243
243
 
244
- switch (algorithm.name) {
245
- case 'SHA-1':
246
- // Fall through
247
- case 'SHA-256':
248
- // Fall through
249
- case 'SHA-384':
250
- // Fall through
251
- case 'SHA-512':
252
- return internalDigest(algorithm, data);
244
+ const name = algorithm.name;
245
+
246
+ if (
247
+ name === 'SHA-1' ||
248
+ name === 'SHA-256' ||
249
+ name === 'SHA-384' ||
250
+ name === 'SHA-512' ||
251
+ name === 'SHA3-256' ||
252
+ name === 'SHA3-384' ||
253
+ name === 'SHA3-512'
254
+ ) {
255
+ return internalDigest(algorithm, data);
256
+ }
257
+
258
+ if (name === 'cSHAKE128' || name === 'cSHAKE256') {
259
+ if (typeof algorithm.length !== 'number' || algorithm.length <= 0) {
260
+ throw lazyDOMException(
261
+ 'cSHAKE requires a length parameter',
262
+ 'OperationError',
263
+ );
264
+ }
265
+ if (algorithm.length % 8) {
266
+ throw lazyDOMException(
267
+ 'Unsupported CShakeParams length',
268
+ 'NotSupportedError',
269
+ );
270
+ }
271
+ return internalDigest(algorithm, data, algorithm.length);
253
272
  }
254
273
 
255
274
  throw lazyDOMException(
256
- `Unrecognized algorithm name: ${algorithm.name}`,
275
+ `Unrecognized algorithm name: ${name}`,
257
276
  'NotSupportedError',
258
277
  );
259
278
  };
@@ -261,9 +280,13 @@ export const asyncDigest = async (
261
280
  const internalDigest = (
262
281
  algorithm: SubtleAlgorithm,
263
282
  data: BufferLike,
283
+ outputLength?: number,
264
284
  ): ArrayBuffer => {
265
285
  const normalizedHashName = normalizeHashName(algorithm.name);
266
- const hash = createHash(normalizedHashName);
286
+ const hash = createHash(
287
+ normalizedHashName,
288
+ outputLength ? { outputLength } : undefined,
289
+ );
267
290
  hash.update(bufferLikeToArrayBuffer(data));
268
291
  const result = hash.digest();
269
292
  const arrayBuffer = new ArrayBuffer(result.length);
package/src/hkdf.ts CHANGED
@@ -3,6 +3,7 @@ import { NitroModules } from 'react-native-nitro-modules';
3
3
  import type { Hkdf as HkdfNative } from './specs/hkdf.nitro';
4
4
  import { binaryLikeToArrayBuffer, normalizeHashName } from './utils';
5
5
  import type { BinaryLike } from './utils';
6
+ import type { CryptoKey } from './keys';
6
7
 
7
8
  type KeyMaterial = BinaryLike;
8
9
  type Salt = BinaryLike;
@@ -15,12 +16,6 @@ export interface HkdfAlgorithm {
15
16
  info: BinaryLike;
16
17
  }
17
18
 
18
- export interface CryptoKeyInternal {
19
- keyObject: {
20
- export: () => Buffer;
21
- };
22
- }
23
-
24
19
  export interface HkdfCallback {
25
20
  (err: Error | null, derivedKey?: Buffer): void;
26
21
  }
@@ -122,7 +117,7 @@ export function hkdfSync(
122
117
 
123
118
  export function hkdfDeriveBits(
124
119
  algorithm: HkdfAlgorithm,
125
- baseKey: CryptoKeyInternal,
120
+ baseKey: CryptoKey,
126
121
  length: number,
127
122
  ): ArrayBuffer {
128
123
  const hash = algorithm.hash;
package/src/index.ts CHANGED
@@ -16,7 +16,9 @@ import * as scrypt from './scrypt';
16
16
  import * as random from './random';
17
17
  import * as ecdh from './ecdh';
18
18
  import * as dh from './diffie-hellman';
19
+ import * as mlkem from './mlkem';
19
20
  import { Certificate } from './certificate';
21
+ import { X509Certificate } from './x509certificate';
20
22
  import { getCurves } from './ec';
21
23
  import { constants } from './constants';
22
24
 
@@ -43,9 +45,11 @@ const QuickCrypto = {
43
45
  ...random,
44
46
  ...ecdh,
45
47
  ...dh,
48
+ ...mlkem,
46
49
  ...utils,
47
50
  ...subtle,
48
51
  Certificate,
52
+ X509Certificate,
49
53
  getCurves,
50
54
  constants,
51
55
  Buffer,
@@ -81,6 +85,8 @@ export default QuickCrypto;
81
85
  export * from './argon2';
82
86
  export * from './blake3';
83
87
  export { Certificate } from './certificate';
88
+ export { X509Certificate } from './x509certificate';
89
+ export type { CheckOptions, X509LegacyObject } from './x509certificate';
84
90
  export * from './cipher';
85
91
  export * from './ed';
86
92
  export * from './keys';
@@ -94,6 +100,7 @@ export * from './random';
94
100
  export * from './ecdh';
95
101
  export { getCurves } from './ec';
96
102
  export * from './diffie-hellman';
103
+ export * from './mlkem';
97
104
  export * from './utils';
98
105
  export * from './subtle';
99
106
  export { subtle, isCryptoKeyPair } from './subtle';
@@ -3,6 +3,7 @@ import { NitroModules } from 'react-native-nitro-modules';
3
3
  import type {
4
4
  AsymmetricKeyType,
5
5
  EncodingOptions,
6
+ JWK,
6
7
  KeyDetail,
7
8
  KeyObjectHandle,
8
9
  KeyUsage,
@@ -81,10 +82,10 @@ export class KeyObject {
81
82
 
82
83
  export(options: { format: 'pem' } & EncodingOptions): string | Buffer;
83
84
  export(options?: { format: 'der' } & EncodingOptions): Buffer;
84
- export(options?: { format: 'jwk' } & EncodingOptions): never;
85
- export(options?: EncodingOptions): string | Buffer;
85
+ export(options?: { format: 'jwk' } & EncodingOptions): JWK;
86
+ export(options?: EncodingOptions): string | Buffer | JWK;
86
87
  // eslint-disable-next-line @typescript-eslint/no-unused-vars
87
- export(_options?: EncodingOptions): string | Buffer {
88
+ export(_options?: EncodingOptions): string | Buffer | JWK {
88
89
  // This is a placeholder and should be overridden by subclasses.
89
90
  throw new Error('export() must be implemented by subclasses');
90
91
  }
@@ -284,10 +285,10 @@ export class PublicKeyObject extends AsymmetricKeyObject {
284
285
 
285
286
  export(options: { format: 'pem' } & EncodingOptions): string;
286
287
  export(options: { format: 'der' } & EncodingOptions): Buffer;
287
- export(options: { format: 'jwk' } & EncodingOptions): never;
288
- export(options: EncodingOptions): string | Buffer {
288
+ export(options: { format: 'jwk' } & EncodingOptions): JWK;
289
+ export(options: EncodingOptions): string | Buffer | JWK {
289
290
  if (options?.format === 'jwk') {
290
- throw new Error('PublicKey export for jwk is not implemented');
291
+ return this.handle.exportJwk({}, false);
291
292
  }
292
293
  const { format, type } = parsePublicKeyEncoding(
293
294
  options,
@@ -309,13 +310,13 @@ export class PrivateKeyObject extends AsymmetricKeyObject {
309
310
 
310
311
  export(options: { format: 'pem' } & EncodingOptions): string;
311
312
  export(options: { format: 'der' } & EncodingOptions): Buffer;
312
- export(options: { format: 'jwk' } & EncodingOptions): never;
313
- export(options: EncodingOptions): string | Buffer {
313
+ export(options: { format: 'jwk' } & EncodingOptions): JWK;
314
+ export(options: EncodingOptions): string | Buffer | JWK {
314
315
  if (options?.format === 'jwk') {
315
316
  if (options.passphrase !== undefined) {
316
317
  throw new Error('jwk does not support encryption');
317
318
  }
318
- throw new Error('PrivateKey export for jwk is not implemented');
319
+ return this.handle.exportJwk({}, false);
319
320
  }
320
321
  const { format, type, cipher, passphrase } = parsePrivateKeyEncoding(
321
322
  options,
package/src/keys/index.ts CHANGED
@@ -27,17 +27,19 @@ import {
27
27
  parsePrivateKeyEncoding,
28
28
  parsePublicKeyEncoding,
29
29
  } from './utils';
30
- import type { BinaryLike } from '../utils';
30
+ import { NitroModules } from 'react-native-nitro-modules';
31
+ import type { BinaryLike, JWK, KeyObjectHandle } from '../utils';
31
32
  import {
32
33
  binaryLikeToArrayBuffer as toAB,
33
34
  isStringOrBuffer,
34
35
  KFormatType,
35
36
  KeyEncoding,
37
+ KeyType,
36
38
  } from '../utils';
37
39
  import { randomBytes } from '../random';
38
40
 
39
41
  interface KeyInputObject {
40
- key: BinaryLike | KeyObject | CryptoKey;
42
+ key: BinaryLike | KeyObject | CryptoKey | JWK;
41
43
  format?: 'pem' | 'der' | 'jwk';
42
44
  type?: 'pkcs1' | 'pkcs8' | 'spki' | 'sec1';
43
45
  passphrase?: BinaryLike;
@@ -123,6 +125,29 @@ function prepareAsymmetricKey(
123
125
  }
124
126
 
125
127
  function createPublicKey(key: KeyInput): PublicKeyObject {
128
+ if (typeof key === 'object' && 'key' in key && key.format === 'jwk') {
129
+ const handle =
130
+ NitroModules.createHybridObject<KeyObjectHandle>('KeyObjectHandle');
131
+ const keyType = handle.initJwk(key.key as JWK);
132
+ if (keyType === undefined) {
133
+ throw new Error('Failed to import JWK');
134
+ }
135
+ if (keyType === KeyType.PRIVATE) {
136
+ // Extract public from private
137
+ const exported = handle.exportKey(KFormatType.DER, KeyEncoding.SPKI);
138
+ const pubHandle =
139
+ NitroModules.createHybridObject<KeyObjectHandle>('KeyObjectHandle');
140
+ pubHandle.init(
141
+ KeyType.PUBLIC,
142
+ exported,
143
+ KFormatType.DER,
144
+ KeyEncoding.SPKI,
145
+ );
146
+ return new PublicKeyObject(pubHandle);
147
+ }
148
+ return new PublicKeyObject(handle);
149
+ }
150
+
126
151
  const { data, format, type } = prepareAsymmetricKey(key, true);
127
152
 
128
153
  // Map format string to KFormatType enum
@@ -144,6 +169,16 @@ function createPublicKey(key: KeyInput): PublicKeyObject {
144
169
  }
145
170
 
146
171
  function createPrivateKey(key: KeyInput): PrivateKeyObject {
172
+ if (typeof key === 'object' && 'key' in key && key.format === 'jwk') {
173
+ const handle =
174
+ NitroModules.createHybridObject<KeyObjectHandle>('KeyObjectHandle');
175
+ const keyType = handle.initJwk(key.key as JWK);
176
+ if (keyType === undefined || keyType !== KeyType.PRIVATE) {
177
+ throw new Error('Failed to import private key from JWK');
178
+ }
179
+ return new PrivateKeyObject(handle);
180
+ }
181
+
147
182
  const { data, format, type } = prepareAsymmetricKey(key, false);
148
183
 
149
184
  // Map format string to KFormatType enum
@@ -110,7 +110,7 @@ export function publicEncrypt(
110
110
  const rsaCipher: RsaCipher = NitroModules.createHybridObject('RsaCipher');
111
111
  const data = toAB(buffer);
112
112
  const paddingMode = padding ?? constants.RSA_PKCS1_OAEP_PADDING;
113
- const hashAlgorithm = oaepHash || 'SHA-256';
113
+ const hashAlgorithm = oaepHash || 'sha1';
114
114
 
115
115
  try {
116
116
  const encrypted = rsaCipher.encrypt(
@@ -232,7 +232,7 @@ export function privateDecrypt(
232
232
  const rsaCipher: RsaCipher = NitroModules.createHybridObject('RsaCipher');
233
233
  const data = toAB(buffer);
234
234
  const paddingMode = padding ?? constants.RSA_PKCS1_OAEP_PADDING;
235
- const hashAlgorithm = oaepHash || 'SHA-256';
235
+ const hashAlgorithm = oaepHash || 'sha1';
236
236
 
237
237
  try {
238
238
  const decrypted = rsaCipher.privateDecrypt(
@@ -119,12 +119,7 @@ function prepareKey(key: KeyInput, isPublic: boolean): PreparedKey {
119
119
 
120
120
  const keyType = isPublic ? 'public' : 'private';
121
121
  // Always convert to ArrayBuffer to avoid Nitro bridge string truncation bug
122
- const originalLength =
123
- typeof data === 'string' ? data.length : data.byteLength;
124
122
  const keyData = toAB(data);
125
- console.log(
126
- `[prepareKey KeyInputObject] ${keyType} key, original length: ${originalLength}, ArrayBuffer size: ${keyData.byteLength}`,
127
- );
128
123
  const keyObject = KeyObject.createKeyObject(
129
124
  keyType,
130
125
  keyData,