react-native-quick-crypto 1.0.0-beta.9 → 1.0.1

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 (526) hide show
  1. package/QuickCrypto.podspec +156 -8
  2. package/README.md +14 -27
  3. package/android/CMakeLists.txt +64 -7
  4. package/android/build.gradle +12 -2
  5. package/android/src/main/java/com/margelo/nitro/quickcrypto/QuickCryptoPackage.java +0 -2
  6. package/app.plugin.js +3 -0
  7. package/cpp/blake3/HybridBlake3.cpp +118 -0
  8. package/cpp/blake3/HybridBlake3.hpp +35 -0
  9. package/cpp/cipher/CCMCipher.cpp +199 -0
  10. package/cpp/cipher/CCMCipher.hpp +26 -0
  11. package/cpp/cipher/ChaCha20Cipher.cpp +97 -0
  12. package/cpp/cipher/ChaCha20Cipher.hpp +25 -0
  13. package/cpp/cipher/ChaCha20Poly1305Cipher.cpp +170 -0
  14. package/cpp/cipher/ChaCha20Poly1305Cipher.hpp +30 -0
  15. package/cpp/cipher/GCMCipher.cpp +68 -0
  16. package/cpp/cipher/GCMCipher.hpp +14 -0
  17. package/cpp/cipher/HybridCipher.cpp +323 -0
  18. package/cpp/cipher/HybridCipher.hpp +68 -0
  19. package/cpp/cipher/HybridCipherFactory.hpp +105 -0
  20. package/cpp/cipher/HybridRsaCipher.cpp +367 -0
  21. package/cpp/cipher/HybridRsaCipher.hpp +29 -0
  22. package/cpp/cipher/OCBCipher.cpp +55 -0
  23. package/cpp/cipher/OCBCipher.hpp +19 -0
  24. package/cpp/cipher/XSalsa20Cipher.cpp +61 -0
  25. package/cpp/cipher/XSalsa20Cipher.hpp +33 -0
  26. package/cpp/ec/HybridEcKeyPair.cpp +428 -0
  27. package/cpp/ec/HybridEcKeyPair.hpp +48 -0
  28. package/cpp/ed25519/HybridEdKeyPair.cpp +228 -98
  29. package/cpp/ed25519/HybridEdKeyPair.hpp +42 -56
  30. package/cpp/hash/HybridHash.cpp +185 -0
  31. package/cpp/hash/HybridHash.hpp +43 -0
  32. package/cpp/hmac/HybridHmac.cpp +95 -0
  33. package/cpp/hmac/HybridHmac.hpp +31 -0
  34. package/cpp/keys/HybridKeyObjectHandle.cpp +757 -0
  35. package/cpp/keys/HybridKeyObjectHandle.hpp +51 -0
  36. package/cpp/keys/KeyObjectData.cpp +268 -0
  37. package/cpp/keys/KeyObjectData.hpp +71 -0
  38. package/cpp/keys/node.h +5 -0
  39. package/cpp/mldsa/HybridMlDsaKeyPair.cpp +264 -0
  40. package/cpp/mldsa/HybridMlDsaKeyPair.hpp +47 -0
  41. package/cpp/pbkdf2/HybridPbkdf2.cpp +34 -55
  42. package/cpp/pbkdf2/HybridPbkdf2.hpp +5 -16
  43. package/cpp/random/HybridRandom.cpp +6 -17
  44. package/cpp/random/HybridRandom.hpp +5 -6
  45. package/cpp/rsa/HybridRsaKeyPair.cpp +154 -0
  46. package/cpp/rsa/HybridRsaKeyPair.hpp +43 -0
  47. package/cpp/sign/HybridSignHandle.cpp +266 -0
  48. package/cpp/sign/HybridSignHandle.hpp +36 -0
  49. package/cpp/sign/HybridVerifyHandle.cpp +227 -0
  50. package/cpp/sign/HybridVerifyHandle.hpp +36 -0
  51. package/cpp/sign/SignUtils.hpp +108 -0
  52. package/cpp/utils/Macros.hpp +68 -0
  53. package/cpp/utils/Utils.hpp +43 -2
  54. package/cpp/utils/base64.h +309 -0
  55. package/deps/blake3/.cargo/config.toml +2 -0
  56. package/deps/blake3/.git-blame-ignore-revs +2 -0
  57. package/deps/blake3/.github/workflows/build_b3sum.py +38 -0
  58. package/deps/blake3/.github/workflows/ci.yml +491 -0
  59. package/deps/blake3/.github/workflows/tag.yml +43 -0
  60. package/deps/blake3/.github/workflows/upload_github_release_asset.py +73 -0
  61. package/deps/blake3/CONTRIBUTING.md +31 -0
  62. package/deps/blake3/Cargo.toml +135 -0
  63. package/deps/blake3/LICENSE_A2 +202 -0
  64. package/deps/blake3/LICENSE_A2LLVM +219 -0
  65. package/deps/blake3/LICENSE_CC0 +121 -0
  66. package/deps/blake3/README.md +229 -0
  67. package/deps/blake3/b3sum/Cargo.lock +513 -0
  68. package/deps/blake3/b3sum/Cargo.toml +26 -0
  69. package/deps/blake3/b3sum/README.md +72 -0
  70. package/deps/blake3/b3sum/src/main.rs +564 -0
  71. package/deps/blake3/b3sum/src/unit_tests.rs +235 -0
  72. package/deps/blake3/b3sum/tests/cli_tests.rs +680 -0
  73. package/deps/blake3/b3sum/what_does_check_do.md +176 -0
  74. package/deps/blake3/benches/bench.rs +623 -0
  75. package/deps/blake3/build.rs +389 -0
  76. package/deps/blake3/c/CMakeLists.txt +383 -0
  77. package/deps/blake3/c/CMakePresets.json +73 -0
  78. package/deps/blake3/c/Makefile.testing +82 -0
  79. package/deps/blake3/c/README.md +403 -0
  80. package/deps/blake3/c/blake3-config.cmake.in +14 -0
  81. package/deps/blake3/c/blake3.c +650 -0
  82. package/deps/blake3/c/blake3.h +86 -0
  83. package/deps/blake3/c/blake3_avx2.c +326 -0
  84. package/deps/blake3/c/blake3_avx2_x86-64_unix.S +1815 -0
  85. package/deps/blake3/c/blake3_avx2_x86-64_windows_gnu.S +1817 -0
  86. package/deps/blake3/c/blake3_avx2_x86-64_windows_msvc.asm +1828 -0
  87. package/deps/blake3/c/blake3_avx512.c +1388 -0
  88. package/deps/blake3/c/blake3_avx512_x86-64_unix.S +4824 -0
  89. package/deps/blake3/c/blake3_avx512_x86-64_windows_gnu.S +2615 -0
  90. package/deps/blake3/c/blake3_avx512_x86-64_windows_msvc.asm +2634 -0
  91. package/deps/blake3/c/blake3_c_rust_bindings/Cargo.toml +32 -0
  92. package/deps/blake3/c/blake3_c_rust_bindings/README.md +4 -0
  93. package/deps/blake3/c/blake3_c_rust_bindings/benches/bench.rs +477 -0
  94. package/deps/blake3/c/blake3_c_rust_bindings/build.rs +253 -0
  95. package/deps/blake3/c/blake3_c_rust_bindings/cross_test.sh +31 -0
  96. package/deps/blake3/c/blake3_c_rust_bindings/src/lib.rs +333 -0
  97. package/deps/blake3/c/blake3_c_rust_bindings/src/test.rs +696 -0
  98. package/deps/blake3/c/blake3_dispatch.c +332 -0
  99. package/deps/blake3/c/blake3_impl.h +333 -0
  100. package/deps/blake3/c/blake3_neon.c +366 -0
  101. package/deps/blake3/c/blake3_portable.c +160 -0
  102. package/deps/blake3/c/blake3_sse2.c +566 -0
  103. package/deps/blake3/c/blake3_sse2_x86-64_unix.S +2291 -0
  104. package/deps/blake3/c/blake3_sse2_x86-64_windows_gnu.S +2332 -0
  105. package/deps/blake3/c/blake3_sse2_x86-64_windows_msvc.asm +2350 -0
  106. package/deps/blake3/c/blake3_sse41.c +560 -0
  107. package/deps/blake3/c/blake3_sse41_x86-64_unix.S +2028 -0
  108. package/deps/blake3/c/blake3_sse41_x86-64_windows_gnu.S +2069 -0
  109. package/deps/blake3/c/blake3_sse41_x86-64_windows_msvc.asm +2089 -0
  110. package/deps/blake3/c/blake3_tbb.cpp +37 -0
  111. package/deps/blake3/c/dependencies/CMakeLists.txt +3 -0
  112. package/deps/blake3/c/dependencies/tbb/CMakeLists.txt +28 -0
  113. package/deps/blake3/c/example.c +36 -0
  114. package/deps/blake3/c/example_tbb.c +57 -0
  115. package/deps/blake3/c/libblake3.pc.in +12 -0
  116. package/deps/blake3/c/main.c +166 -0
  117. package/deps/blake3/c/test.py +97 -0
  118. package/deps/blake3/media/B3.svg +70 -0
  119. package/deps/blake3/media/BLAKE3.svg +85 -0
  120. package/deps/blake3/media/speed.svg +1474 -0
  121. package/deps/blake3/reference_impl/Cargo.toml +8 -0
  122. package/deps/blake3/reference_impl/README.md +14 -0
  123. package/deps/blake3/reference_impl/reference_impl.rs +374 -0
  124. package/deps/blake3/src/ffi_avx2.rs +65 -0
  125. package/deps/blake3/src/ffi_avx512.rs +169 -0
  126. package/deps/blake3/src/ffi_neon.rs +82 -0
  127. package/deps/blake3/src/ffi_sse2.rs +126 -0
  128. package/deps/blake3/src/ffi_sse41.rs +126 -0
  129. package/deps/blake3/src/guts.rs +60 -0
  130. package/deps/blake3/src/hazmat.rs +704 -0
  131. package/deps/blake3/src/io.rs +64 -0
  132. package/deps/blake3/src/join.rs +92 -0
  133. package/deps/blake3/src/lib.rs +1835 -0
  134. package/deps/blake3/src/platform.rs +587 -0
  135. package/deps/blake3/src/portable.rs +198 -0
  136. package/deps/blake3/src/rust_avx2.rs +474 -0
  137. package/deps/blake3/src/rust_sse2.rs +775 -0
  138. package/deps/blake3/src/rust_sse41.rs +766 -0
  139. package/deps/blake3/src/test.rs +1049 -0
  140. package/deps/blake3/src/traits.rs +227 -0
  141. package/deps/blake3/src/wasm32_simd.rs +794 -0
  142. package/deps/blake3/test_vectors/Cargo.toml +19 -0
  143. package/deps/blake3/test_vectors/cross_test.sh +25 -0
  144. package/deps/blake3/test_vectors/src/bin/generate.rs +4 -0
  145. package/deps/blake3/test_vectors/src/lib.rs +350 -0
  146. package/deps/blake3/test_vectors/test_vectors.json +217 -0
  147. package/deps/blake3/tools/compiler_version/Cargo.toml +7 -0
  148. package/deps/blake3/tools/compiler_version/build.rs +6 -0
  149. package/deps/blake3/tools/compiler_version/src/main.rs +27 -0
  150. package/deps/blake3/tools/instruction_set_support/Cargo.toml +6 -0
  151. package/deps/blake3/tools/instruction_set_support/src/main.rs +10 -0
  152. package/deps/blake3/tools/release.md +16 -0
  153. package/deps/fastpbkdf2/fastpbkdf2.c +5 -1
  154. package/deps/ncrypto/.bazelignore +4 -0
  155. package/deps/ncrypto/.bazelrc +2 -0
  156. package/deps/ncrypto/.bazelversion +1 -0
  157. package/deps/ncrypto/.clang-format +111 -0
  158. package/deps/ncrypto/.github/workflows/bazel.yml +58 -0
  159. package/deps/ncrypto/.github/workflows/linter.yml +38 -0
  160. package/deps/ncrypto/.github/workflows/macos.yml +43 -0
  161. package/deps/ncrypto/.github/workflows/ubuntu.yml +46 -0
  162. package/deps/ncrypto/.github/workflows/visual-studio.yml +49 -0
  163. package/deps/ncrypto/.python-version +1 -0
  164. package/deps/ncrypto/BUILD.bazel +36 -0
  165. package/deps/ncrypto/CMakeLists.txt +55 -0
  166. package/deps/ncrypto/LICENSE +21 -0
  167. package/deps/ncrypto/MODULE.bazel +1 -0
  168. package/deps/ncrypto/MODULE.bazel.lock +280 -0
  169. package/deps/ncrypto/README.md +18 -0
  170. package/deps/ncrypto/WORKSPACE +15 -0
  171. package/deps/ncrypto/cmake/CPM.cmake +1225 -0
  172. package/deps/ncrypto/cmake/ncrypto-flags.cmake +16 -0
  173. package/deps/ncrypto/include/dh-primes.h +67 -0
  174. package/deps/ncrypto/include/ncrypto.h +1897 -0
  175. package/deps/ncrypto/patches/0001-Expose-libdecrepit-so-NodeJS-can-use-it-for-ncrypto.patch +28 -0
  176. package/deps/ncrypto/pyproject.toml +38 -0
  177. package/deps/ncrypto/src/CMakeLists.txt +15 -0
  178. package/deps/ncrypto/src/engine.cpp +93 -0
  179. package/deps/ncrypto/src/ncrypto.cpp +5613 -0
  180. package/deps/ncrypto/tests/BUILD.bazel +9 -0
  181. package/deps/ncrypto/tests/CMakeLists.txt +7 -0
  182. package/deps/ncrypto/tests/basic.cpp +86 -0
  183. package/deps/ncrypto/tools/run-clang-format.sh +42 -0
  184. package/lib/commonjs/blake3.js +98 -0
  185. package/lib/commonjs/blake3.js.map +1 -0
  186. package/lib/commonjs/cipher.js +180 -0
  187. package/lib/commonjs/cipher.js.map +1 -0
  188. package/lib/commonjs/constants.js +32 -0
  189. package/lib/commonjs/constants.js.map +1 -0
  190. package/lib/commonjs/ec.js +480 -0
  191. package/lib/commonjs/ec.js.map +1 -0
  192. package/lib/commonjs/ed.js +214 -2
  193. package/lib/commonjs/ed.js.map +1 -1
  194. package/lib/commonjs/expo-plugin/@types.js +2 -0
  195. package/lib/commonjs/expo-plugin/@types.js.map +1 -0
  196. package/lib/commonjs/expo-plugin/withRNQC.js +25 -0
  197. package/lib/commonjs/expo-plugin/withRNQC.js.map +1 -0
  198. package/lib/commonjs/expo-plugin/withSodiumAndroid.js +25 -0
  199. package/lib/commonjs/expo-plugin/withSodiumAndroid.js.map +1 -0
  200. package/lib/commonjs/expo-plugin/withSodiumIos.js +26 -0
  201. package/lib/commonjs/expo-plugin/withSodiumIos.js.map +1 -0
  202. package/lib/commonjs/expo-plugin/withXCode.js +51 -0
  203. package/lib/commonjs/expo-plugin/withXCode.js.map +1 -0
  204. package/lib/commonjs/hash.js +215 -0
  205. package/lib/commonjs/hash.js.map +1 -0
  206. package/lib/commonjs/hmac.js +109 -0
  207. package/lib/commonjs/hmac.js.map +1 -0
  208. package/lib/commonjs/index.js +102 -24
  209. package/lib/commonjs/index.js.map +1 -1
  210. package/lib/commonjs/keys/classes.js +115 -52
  211. package/lib/commonjs/keys/classes.js.map +1 -1
  212. package/lib/commonjs/keys/generateKeyPair.js +141 -144
  213. package/lib/commonjs/keys/generateKeyPair.js.map +1 -1
  214. package/lib/commonjs/keys/index.js +229 -0
  215. package/lib/commonjs/keys/index.js.map +1 -1
  216. package/lib/commonjs/keys/publicCipher.js +152 -0
  217. package/lib/commonjs/keys/publicCipher.js.map +1 -0
  218. package/lib/commonjs/keys/signVerify.js +178 -39
  219. package/lib/commonjs/keys/signVerify.js.map +1 -1
  220. package/lib/commonjs/keys/utils.js +18 -13
  221. package/lib/commonjs/keys/utils.js.map +1 -1
  222. package/lib/commonjs/mldsa.js +69 -0
  223. package/lib/commonjs/mldsa.js.map +1 -0
  224. package/lib/commonjs/pbkdf2.js.map +1 -1
  225. package/lib/commonjs/random.js +6 -0
  226. package/lib/commonjs/random.js.map +1 -1
  227. package/lib/commonjs/rsa.js +202 -0
  228. package/lib/commonjs/rsa.js.map +1 -0
  229. package/lib/commonjs/specs/blake3.nitro.js +6 -0
  230. package/lib/commonjs/specs/blake3.nitro.js.map +1 -0
  231. package/lib/commonjs/specs/cipher.nitro.js +6 -0
  232. package/lib/commonjs/specs/cipher.nitro.js.map +1 -0
  233. package/lib/commonjs/specs/ecKeyPair.nitro.js +6 -0
  234. package/lib/commonjs/specs/ecKeyPair.nitro.js.map +1 -0
  235. package/lib/commonjs/specs/hash.nitro.js +6 -0
  236. package/lib/commonjs/specs/hash.nitro.js.map +1 -0
  237. package/lib/commonjs/specs/hmac.nitro.js +6 -0
  238. package/lib/commonjs/specs/hmac.nitro.js.map +1 -0
  239. package/lib/commonjs/specs/mlDsaKeyPair.nitro.js +6 -0
  240. package/lib/commonjs/specs/mlDsaKeyPair.nitro.js.map +1 -0
  241. package/lib/commonjs/specs/rsaCipher.nitro.js +6 -0
  242. package/lib/commonjs/specs/rsaCipher.nitro.js.map +1 -0
  243. package/lib/commonjs/specs/rsaKeyPair.nitro.js +6 -0
  244. package/lib/commonjs/specs/rsaKeyPair.nitro.js.map +1 -0
  245. package/lib/commonjs/specs/sign.nitro.js +6 -0
  246. package/lib/commonjs/specs/sign.nitro.js.map +1 -0
  247. package/lib/commonjs/subtle.js +1092 -0
  248. package/lib/commonjs/subtle.js.map +1 -0
  249. package/lib/commonjs/utils/cipher.js +64 -0
  250. package/lib/commonjs/utils/cipher.js.map +1 -0
  251. package/lib/commonjs/utils/conversion.js +44 -5
  252. package/lib/commonjs/utils/conversion.js.map +1 -1
  253. package/lib/commonjs/utils/hashnames.js +2 -1
  254. package/lib/commonjs/utils/hashnames.js.map +1 -1
  255. package/lib/commonjs/utils/index.js +11 -0
  256. package/lib/commonjs/utils/index.js.map +1 -1
  257. package/lib/commonjs/utils/noble.js +82 -0
  258. package/lib/commonjs/utils/noble.js.map +1 -0
  259. package/lib/commonjs/utils/types.js +32 -17
  260. package/lib/commonjs/utils/types.js.map +1 -1
  261. package/lib/commonjs/utils/validation.js +74 -1
  262. package/lib/commonjs/utils/validation.js.map +1 -1
  263. package/lib/module/blake3.js +90 -0
  264. package/lib/module/blake3.js.map +1 -0
  265. package/lib/module/cipher.js +173 -0
  266. package/lib/module/cipher.js.map +1 -0
  267. package/lib/module/constants.js +28 -0
  268. package/lib/module/constants.js.map +1 -0
  269. package/lib/module/ec.js +470 -0
  270. package/lib/module/ec.js.map +1 -0
  271. package/lib/module/ed.js +212 -3
  272. package/lib/module/ed.js.map +1 -1
  273. package/lib/module/expo-plugin/@types.js +2 -0
  274. package/lib/module/expo-plugin/@types.js.map +1 -0
  275. package/lib/module/expo-plugin/withRNQC.js +21 -0
  276. package/lib/module/expo-plugin/withRNQC.js.map +1 -0
  277. package/lib/module/expo-plugin/withSodiumAndroid.js +20 -0
  278. package/lib/module/expo-plugin/withSodiumAndroid.js.map +1 -0
  279. package/lib/module/expo-plugin/withSodiumIos.js +20 -0
  280. package/lib/module/expo-plugin/withSodiumIos.js.map +1 -0
  281. package/lib/module/expo-plugin/withXCode.js +46 -0
  282. package/lib/module/expo-plugin/withXCode.js.map +1 -0
  283. package/lib/module/hash.js +207 -0
  284. package/lib/module/hash.js.map +1 -0
  285. package/lib/module/hmac.js +104 -0
  286. package/lib/module/hmac.js.map +1 -0
  287. package/lib/module/index.js +21 -21
  288. package/lib/module/index.js.map +1 -1
  289. package/lib/module/keys/classes.js +112 -49
  290. package/lib/module/keys/classes.js.map +1 -1
  291. package/lib/module/keys/generateKeyPair.js +134 -143
  292. package/lib/module/keys/generateKeyPair.js.map +1 -1
  293. package/lib/module/keys/index.js +161 -22
  294. package/lib/module/keys/index.js.map +1 -1
  295. package/lib/module/keys/publicCipher.js +145 -0
  296. package/lib/module/keys/publicCipher.js.map +1 -0
  297. package/lib/module/keys/signVerify.js +170 -39
  298. package/lib/module/keys/signVerify.js.map +1 -1
  299. package/lib/module/keys/utils.js +16 -12
  300. package/lib/module/keys/utils.js.map +1 -1
  301. package/lib/module/mldsa.js +63 -0
  302. package/lib/module/mldsa.js.map +1 -0
  303. package/lib/module/pbkdf2.js.map +1 -1
  304. package/lib/module/random.js +6 -0
  305. package/lib/module/random.js.map +1 -1
  306. package/lib/module/rsa.js +194 -0
  307. package/lib/module/rsa.js.map +1 -0
  308. package/lib/module/specs/blake3.nitro.js +4 -0
  309. package/lib/module/specs/blake3.nitro.js.map +1 -0
  310. package/lib/module/specs/cipher.nitro.js +4 -0
  311. package/lib/module/specs/cipher.nitro.js.map +1 -0
  312. package/lib/module/specs/ecKeyPair.nitro.js +4 -0
  313. package/lib/module/specs/ecKeyPair.nitro.js.map +1 -0
  314. package/lib/module/specs/hash.nitro.js +4 -0
  315. package/lib/module/specs/hash.nitro.js.map +1 -0
  316. package/lib/module/specs/hmac.nitro.js +4 -0
  317. package/lib/module/specs/hmac.nitro.js.map +1 -0
  318. package/lib/module/specs/mlDsaKeyPair.nitro.js +4 -0
  319. package/lib/module/specs/mlDsaKeyPair.nitro.js.map +1 -0
  320. package/lib/module/specs/rsaCipher.nitro.js +4 -0
  321. package/lib/module/specs/rsaCipher.nitro.js.map +1 -0
  322. package/lib/module/specs/rsaKeyPair.nitro.js +4 -0
  323. package/lib/module/specs/rsaKeyPair.nitro.js.map +1 -0
  324. package/lib/module/specs/sign.nitro.js +4 -0
  325. package/lib/module/specs/sign.nitro.js.map +1 -0
  326. package/lib/module/subtle.js +1087 -0
  327. package/lib/module/subtle.js.map +1 -0
  328. package/lib/module/utils/cipher.js +56 -0
  329. package/lib/module/utils/cipher.js.map +1 -0
  330. package/lib/module/utils/conversion.js +26 -5
  331. package/lib/module/utils/conversion.js.map +1 -1
  332. package/lib/module/utils/hashnames.js +2 -1
  333. package/lib/module/utils/hashnames.js.map +1 -1
  334. package/lib/module/utils/index.js +1 -0
  335. package/lib/module/utils/index.js.map +1 -1
  336. package/lib/module/utils/noble.js +76 -0
  337. package/lib/module/utils/noble.js.map +1 -0
  338. package/lib/module/utils/types.js +32 -17
  339. package/lib/module/utils/types.js.map +1 -1
  340. package/lib/module/utils/validation.js +69 -1
  341. package/lib/module/utils/validation.js.map +1 -1
  342. package/lib/tsconfig.tsbuildinfo +1 -1
  343. package/lib/typescript/blake3.d.ts +33 -0
  344. package/lib/typescript/blake3.d.ts.map +1 -0
  345. package/lib/typescript/cipher.d.ts +60 -0
  346. package/lib/typescript/cipher.d.ts.map +1 -0
  347. package/lib/typescript/constants.d.ts +21 -0
  348. package/lib/typescript/constants.d.ts.map +1 -0
  349. package/lib/typescript/ec.d.ts +22 -0
  350. package/lib/typescript/ec.d.ts.map +1 -0
  351. package/lib/typescript/ed.d.ts +28 -1
  352. package/lib/typescript/ed.d.ts.map +1 -1
  353. package/lib/typescript/expo-plugin/@types.d.ts +8 -0
  354. package/lib/typescript/expo-plugin/@types.d.ts.map +1 -0
  355. package/lib/typescript/expo-plugin/withRNQC.d.ts +4 -0
  356. package/lib/typescript/expo-plugin/withRNQC.d.ts.map +1 -0
  357. package/lib/typescript/expo-plugin/withSodiumAndroid.d.ts +4 -0
  358. package/lib/typescript/expo-plugin/withSodiumAndroid.d.ts.map +1 -0
  359. package/lib/typescript/expo-plugin/withSodiumIos.d.ts +4 -0
  360. package/lib/typescript/expo-plugin/withSodiumIos.d.ts.map +1 -0
  361. package/lib/typescript/expo-plugin/withXCode.d.ts +9 -0
  362. package/lib/typescript/expo-plugin/withXCode.d.ts.map +1 -0
  363. package/lib/typescript/hash.d.ts +122 -0
  364. package/lib/typescript/hash.d.ts.map +1 -0
  365. package/lib/typescript/hmac.d.ts +66 -0
  366. package/lib/typescript/hmac.d.ts.map +1 -0
  367. package/lib/typescript/index.d.ts +102 -10
  368. package/lib/typescript/index.d.ts.map +1 -1
  369. package/lib/typescript/keys/classes.d.ts +52 -8
  370. package/lib/typescript/keys/classes.d.ts.map +1 -1
  371. package/lib/typescript/keys/generateKeyPair.d.ts +5 -0
  372. package/lib/typescript/keys/generateKeyPair.d.ts.map +1 -1
  373. package/lib/typescript/keys/index.d.ts +22 -2
  374. package/lib/typescript/keys/index.d.ts.map +1 -1
  375. package/lib/typescript/keys/publicCipher.d.ts +20 -0
  376. package/lib/typescript/keys/publicCipher.d.ts.map +1 -0
  377. package/lib/typescript/keys/signVerify.d.ts +28 -0
  378. package/lib/typescript/keys/signVerify.d.ts.map +1 -1
  379. package/lib/typescript/keys/utils.d.ts +3 -1
  380. package/lib/typescript/keys/utils.d.ts.map +1 -1
  381. package/lib/typescript/mldsa.d.ts +18 -0
  382. package/lib/typescript/mldsa.d.ts.map +1 -0
  383. package/lib/typescript/pbkdf2.d.ts +1 -1
  384. package/lib/typescript/pbkdf2.d.ts.map +1 -1
  385. package/lib/typescript/random.d.ts +6 -0
  386. package/lib/typescript/random.d.ts.map +1 -1
  387. package/lib/typescript/rsa.d.ts +19 -0
  388. package/lib/typescript/rsa.d.ts.map +1 -0
  389. package/lib/typescript/specs/blake3.nitro.d.ts +15 -0
  390. package/lib/typescript/specs/blake3.nitro.d.ts.map +1 -0
  391. package/lib/typescript/specs/cipher.nitro.d.ts +29 -0
  392. package/lib/typescript/specs/cipher.nitro.d.ts.map +1 -0
  393. package/lib/typescript/specs/ecKeyPair.nitro.d.ts +20 -0
  394. package/lib/typescript/specs/ecKeyPair.nitro.d.ts.map +1 -0
  395. package/lib/typescript/specs/edKeyPair.nitro.d.ts +1 -0
  396. package/lib/typescript/specs/edKeyPair.nitro.d.ts.map +1 -1
  397. package/lib/typescript/specs/hash.nitro.d.ts +13 -0
  398. package/lib/typescript/specs/hash.nitro.d.ts.map +1 -0
  399. package/lib/typescript/specs/hmac.nitro.d.ts +10 -0
  400. package/lib/typescript/specs/hmac.nitro.d.ts.map +1 -0
  401. package/lib/typescript/specs/keyObjectHandle.nitro.d.ts +1 -1
  402. package/lib/typescript/specs/keyObjectHandle.nitro.d.ts.map +1 -1
  403. package/lib/typescript/specs/mlDsaKeyPair.nitro.d.ts +16 -0
  404. package/lib/typescript/specs/mlDsaKeyPair.nitro.d.ts.map +1 -0
  405. package/lib/typescript/specs/rsaCipher.nitro.d.ts +44 -0
  406. package/lib/typescript/specs/rsaCipher.nitro.d.ts.map +1 -0
  407. package/lib/typescript/specs/rsaKeyPair.nitro.d.ts +20 -0
  408. package/lib/typescript/specs/rsaKeyPair.nitro.d.ts.map +1 -0
  409. package/lib/typescript/specs/sign.nitro.d.ts +19 -0
  410. package/lib/typescript/specs/sign.nitro.d.ts.map +1 -0
  411. package/lib/typescript/subtle.d.ts +17 -0
  412. package/lib/typescript/subtle.d.ts.map +1 -0
  413. package/lib/typescript/utils/cipher.d.ts +7 -0
  414. package/lib/typescript/utils/cipher.d.ts.map +1 -0
  415. package/lib/typescript/utils/conversion.d.ts +1 -0
  416. package/lib/typescript/utils/conversion.d.ts.map +1 -1
  417. package/lib/typescript/utils/hashnames.d.ts +3 -1
  418. package/lib/typescript/utils/hashnames.d.ts.map +1 -1
  419. package/lib/typescript/utils/index.d.ts +1 -0
  420. package/lib/typescript/utils/index.d.ts.map +1 -1
  421. package/lib/typescript/utils/noble.d.ts +19 -0
  422. package/lib/typescript/utils/noble.d.ts.map +1 -0
  423. package/lib/typescript/utils/types.d.ts +129 -25
  424. package/lib/typescript/utils/types.d.ts.map +1 -1
  425. package/lib/typescript/utils/validation.d.ts +5 -0
  426. package/lib/typescript/utils/validation.d.ts.map +1 -1
  427. package/nitrogen/generated/.gitattributes +1 -0
  428. package/nitrogen/generated/android/QuickCrypto+autolinking.cmake +31 -1
  429. package/nitrogen/generated/android/QuickCrypto+autolinking.gradle +1 -1
  430. package/nitrogen/generated/android/QuickCryptoOnLoad.cpp +125 -1
  431. package/nitrogen/generated/android/QuickCryptoOnLoad.hpp +1 -1
  432. package/nitrogen/generated/android/kotlin/com/margelo/nitro/crypto/QuickCryptoOnLoad.kt +35 -0
  433. package/nitrogen/generated/ios/QuickCrypto+autolinking.rb +3 -1
  434. package/nitrogen/generated/ios/QuickCrypto-Swift-Cxx-Bridge.cpp +1 -1
  435. package/nitrogen/generated/ios/QuickCrypto-Swift-Cxx-Bridge.hpp +1 -1
  436. package/nitrogen/generated/ios/QuickCrypto-Swift-Cxx-Umbrella.hpp +3 -3
  437. package/nitrogen/generated/ios/QuickCryptoAutolinking.mm +121 -1
  438. package/nitrogen/generated/ios/QuickCryptoAutolinking.swift +1 -1
  439. package/nitrogen/generated/shared/c++/AsymmetricKeyType.hpp +116 -0
  440. package/nitrogen/generated/shared/c++/CipherArgs.hpp +86 -0
  441. package/nitrogen/generated/shared/c++/HybridBlake3Spec.cpp +28 -0
  442. package/nitrogen/generated/shared/c++/HybridBlake3Spec.hpp +76 -0
  443. package/nitrogen/generated/shared/c++/HybridCipherFactorySpec.cpp +21 -0
  444. package/nitrogen/generated/shared/c++/HybridCipherFactorySpec.hpp +67 -0
  445. package/nitrogen/generated/shared/c++/HybridCipherSpec.cpp +28 -0
  446. package/nitrogen/generated/shared/c++/HybridCipherSpec.hpp +76 -0
  447. package/nitrogen/generated/shared/c++/HybridEcKeyPairSpec.cpp +29 -0
  448. package/nitrogen/generated/shared/c++/HybridEcKeyPairSpec.hpp +77 -0
  449. package/nitrogen/generated/shared/c++/HybridEdKeyPairSpec.cpp +2 -1
  450. package/nitrogen/generated/shared/c++/HybridEdKeyPairSpec.hpp +5 -4
  451. package/nitrogen/generated/shared/c++/HybridHashSpec.cpp +26 -0
  452. package/nitrogen/generated/shared/c++/HybridHashSpec.hpp +75 -0
  453. package/nitrogen/generated/shared/c++/HybridHmacSpec.cpp +23 -0
  454. package/nitrogen/generated/shared/c++/HybridHmacSpec.hpp +66 -0
  455. package/nitrogen/generated/shared/c++/HybridKeyObjectHandleSpec.cpp +1 -1
  456. package/nitrogen/generated/shared/c++/HybridKeyObjectHandleSpec.hpp +8 -8
  457. package/nitrogen/generated/shared/c++/HybridMlDsaKeyPairSpec.cpp +29 -0
  458. package/nitrogen/generated/shared/c++/HybridMlDsaKeyPairSpec.hpp +73 -0
  459. package/nitrogen/generated/shared/c++/HybridPbkdf2Spec.cpp +1 -1
  460. package/nitrogen/generated/shared/c++/HybridPbkdf2Spec.hpp +3 -3
  461. package/nitrogen/generated/shared/c++/HybridRandomSpec.cpp +1 -1
  462. package/nitrogen/generated/shared/c++/HybridRandomSpec.hpp +3 -3
  463. package/nitrogen/generated/shared/c++/HybridRsaCipherSpec.cpp +24 -0
  464. package/nitrogen/generated/shared/c++/HybridRsaCipherSpec.hpp +72 -0
  465. package/nitrogen/generated/shared/c++/HybridRsaKeyPairSpec.cpp +29 -0
  466. package/nitrogen/generated/shared/c++/HybridRsaKeyPairSpec.hpp +77 -0
  467. package/nitrogen/generated/shared/c++/HybridSignHandleSpec.cpp +23 -0
  468. package/nitrogen/generated/shared/c++/HybridSignHandleSpec.hpp +71 -0
  469. package/nitrogen/generated/shared/c++/HybridVerifyHandleSpec.cpp +23 -0
  470. package/nitrogen/generated/shared/c++/HybridVerifyHandleSpec.hpp +71 -0
  471. package/nitrogen/generated/shared/c++/JWK.hpp +17 -18
  472. package/nitrogen/generated/shared/c++/JWKkty.hpp +12 -14
  473. package/nitrogen/generated/shared/c++/JWKuse.hpp +8 -10
  474. package/nitrogen/generated/shared/c++/KFormatType.hpp +14 -16
  475. package/nitrogen/generated/shared/c++/KeyDetail.hpp +6 -7
  476. package/nitrogen/generated/shared/c++/KeyEncoding.hpp +15 -17
  477. package/nitrogen/generated/shared/c++/KeyObject.hpp +67 -0
  478. package/nitrogen/generated/shared/c++/KeyType.hpp +11 -13
  479. package/nitrogen/generated/shared/c++/KeyUsage.hpp +38 -24
  480. package/nitrogen/generated/shared/c++/NamedCurve.hpp +10 -12
  481. package/package.json +31 -23
  482. package/src/blake3.ts +123 -0
  483. package/src/cipher.ts +335 -0
  484. package/src/constants.ts +32 -0
  485. package/src/ec.ts +657 -0
  486. package/src/ed.ts +297 -13
  487. package/src/expo-plugin/@types.ts +7 -0
  488. package/src/expo-plugin/withRNQC.ts +23 -0
  489. package/src/expo-plugin/withSodiumAndroid.ts +24 -0
  490. package/src/expo-plugin/withSodiumIos.ts +30 -0
  491. package/src/expo-plugin/withXCode.ts +55 -0
  492. package/src/hash.ts +274 -0
  493. package/src/hmac.ts +135 -0
  494. package/src/index.ts +20 -20
  495. package/src/keys/classes.ts +157 -55
  496. package/src/keys/generateKeyPair.ts +177 -134
  497. package/src/keys/index.ts +226 -14
  498. package/src/keys/publicCipher.ts +229 -0
  499. package/src/keys/signVerify.ts +239 -39
  500. package/src/keys/utils.ts +24 -18
  501. package/src/mldsa.ts +125 -0
  502. package/src/pbkdf2.ts +1 -1
  503. package/src/random.ts +7 -0
  504. package/src/rsa.ts +310 -0
  505. package/src/specs/blake3.nitro.ts +12 -0
  506. package/src/specs/cipher.nitro.ts +25 -0
  507. package/src/specs/ecKeyPair.nitro.ts +38 -0
  508. package/src/specs/edKeyPair.nitro.ts +2 -0
  509. package/src/specs/hash.nitro.ts +10 -0
  510. package/src/specs/hmac.nitro.ts +7 -0
  511. package/src/specs/keyObjectHandle.nitro.ts +1 -1
  512. package/src/specs/mlDsaKeyPair.nitro.ts +29 -0
  513. package/src/specs/rsaCipher.nitro.ts +65 -0
  514. package/src/specs/rsaKeyPair.nitro.ts +33 -0
  515. package/src/specs/sign.nitro.ts +31 -0
  516. package/src/subtle.ts +1576 -0
  517. package/src/utils/cipher.ts +60 -0
  518. package/src/utils/conversion.ts +33 -4
  519. package/src/utils/hashnames.ts +4 -2
  520. package/src/utils/index.ts +1 -0
  521. package/src/utils/noble.ts +85 -0
  522. package/src/utils/types.ts +219 -31
  523. package/src/utils/validation.ts +96 -1
  524. package/lib/module/package.json +0 -1
  525. package/nitrogen/generated/android/QuickCryptoOnLoad.kt +0 -1
  526. package/nitrogen/generated/shared/c++/CFRGKeyPairType.hpp +0 -86
package/src/subtle.ts ADDED
@@ -0,0 +1,1576 @@
1
+ /* eslint-disable @typescript-eslint/no-unused-vars */
2
+ import { Buffer as SBuffer } from 'safe-buffer';
3
+ import type {
4
+ SubtleAlgorithm,
5
+ KeyUsage,
6
+ BinaryLike,
7
+ BufferLike,
8
+ JWK,
9
+ AnyAlgorithm,
10
+ ImportFormat,
11
+ AesKeyGenParams,
12
+ EncryptDecryptParams,
13
+ Operation,
14
+ AesCtrParams,
15
+ AesCbcParams,
16
+ AesGcmParams,
17
+ RsaOaepParams,
18
+ } from './utils';
19
+ import { KFormatType, KeyEncoding } from './utils';
20
+ import {
21
+ CryptoKey,
22
+ KeyObject,
23
+ PublicKeyObject,
24
+ PrivateKeyObject,
25
+ SecretKeyObject,
26
+ } from './keys';
27
+ import type { CryptoKeyPair } from './utils/types';
28
+ import { bufferLikeToArrayBuffer } from './utils/conversion';
29
+ import { lazyDOMException } from './utils/errors';
30
+ import { normalizeHashName, HashContext } from './utils/hashnames';
31
+ import { validateMaxBufferLength } from './utils/validation';
32
+ import { asyncDigest } from './hash';
33
+ import { createSecretKey } from './keys';
34
+ import { NitroModules } from 'react-native-nitro-modules';
35
+ import type { KeyObjectHandle } from './specs/keyObjectHandle.nitro';
36
+ import type { RsaCipher } from './specs/rsaCipher.nitro';
37
+ import type { CipherFactory } from './specs/cipher.nitro';
38
+ import { pbkdf2DeriveBits } from './pbkdf2';
39
+ import { ecImportKey, ecdsaSignVerify, ec_generateKeyPair } from './ec';
40
+ import { rsa_generateKeyPair } from './rsa';
41
+ import { getRandomValues } from './random';
42
+ import { createHmac } from './hmac';
43
+ import { createSign, createVerify } from './keys/signVerify';
44
+ import { ed_generateKeyPairWebCrypto, Ed } from './ed';
45
+ import { mldsa_generateKeyPairWebCrypto, type MlDsaVariant } from './mldsa';
46
+ // import { pbkdf2DeriveBits } from './pbkdf2';
47
+ // import { aesCipher, aesGenerateKey, aesImportKey, getAlgorithmName } from './aes';
48
+ // import { rsaCipher, rsaExportKey, rsaImportKey, rsaKeyGenerate } from './rsa';
49
+ // import { normalizeAlgorithm, type Operation } from './algorithms';
50
+ // import { hmacImportKey } from './mac';
51
+
52
+ // Temporary enums that need to be defined
53
+
54
+ enum KWebCryptoKeyFormat {
55
+ kWebCryptoKeyFormatRaw,
56
+ kWebCryptoKeyFormatSPKI,
57
+ kWebCryptoKeyFormatPKCS8,
58
+ }
59
+
60
+ enum CipherOrWrapMode {
61
+ kWebCryptoCipherEncrypt,
62
+ kWebCryptoCipherDecrypt,
63
+ }
64
+
65
+ // Placeholder functions that need to be implemented
66
+ function hasAnyNotIn(usages: KeyUsage[], allowed: KeyUsage[]): boolean {
67
+ return usages.some(usage => !allowed.includes(usage));
68
+ }
69
+
70
+ function normalizeAlgorithm(
71
+ algorithm: SubtleAlgorithm | AnyAlgorithm,
72
+ _operation: Operation,
73
+ ): SubtleAlgorithm {
74
+ if (typeof algorithm === 'string') {
75
+ return { name: algorithm };
76
+ }
77
+ return algorithm as SubtleAlgorithm;
78
+ }
79
+
80
+ function getAlgorithmName(name: string, length: number): string {
81
+ return `${name}${length}`;
82
+ }
83
+
84
+ // Placeholder implementations for missing functions
85
+ function ecExportKey(key: CryptoKey, format: KWebCryptoKeyFormat): ArrayBuffer {
86
+ const keyObject = key.keyObject;
87
+
88
+ if (format === KWebCryptoKeyFormat.kWebCryptoKeyFormatSPKI) {
89
+ // Export public key in SPKI format
90
+ const exported = keyObject.export({ format: 'der', type: 'spki' });
91
+ return bufferLikeToArrayBuffer(exported);
92
+ } else if (format === KWebCryptoKeyFormat.kWebCryptoKeyFormatPKCS8) {
93
+ // Export private key in PKCS8 format
94
+ const exported = keyObject.export({ format: 'der', type: 'pkcs8' });
95
+ return bufferLikeToArrayBuffer(exported);
96
+ } else {
97
+ throw new Error(`Unsupported EC export format: ${format}`);
98
+ }
99
+ }
100
+
101
+ function rsaExportKey(
102
+ key: CryptoKey,
103
+ format: KWebCryptoKeyFormat,
104
+ ): ArrayBuffer {
105
+ const keyObject = key.keyObject;
106
+
107
+ if (format === KWebCryptoKeyFormat.kWebCryptoKeyFormatSPKI) {
108
+ // Export public key in SPKI format
109
+ const exported = keyObject.export({ format: 'der', type: 'spki' });
110
+ return bufferLikeToArrayBuffer(exported);
111
+ } else if (format === KWebCryptoKeyFormat.kWebCryptoKeyFormatPKCS8) {
112
+ // Export private key in PKCS8 format
113
+ const exported = keyObject.export({ format: 'der', type: 'pkcs8' });
114
+ return bufferLikeToArrayBuffer(exported);
115
+ } else {
116
+ throw new Error(`Unsupported RSA export format: ${format}`);
117
+ }
118
+ }
119
+
120
+ async function rsaCipher(
121
+ mode: CipherOrWrapMode,
122
+ key: CryptoKey,
123
+ data: ArrayBuffer,
124
+ algorithm: EncryptDecryptParams,
125
+ ): Promise<ArrayBuffer> {
126
+ const rsaParams = algorithm as RsaOaepParams;
127
+
128
+ // Validate key type matches operation
129
+ const expectedType =
130
+ mode === CipherOrWrapMode.kWebCryptoCipherEncrypt ? 'public' : 'private';
131
+ if (key.type !== expectedType) {
132
+ throw lazyDOMException(
133
+ 'The requested operation is not valid for the provided key',
134
+ 'InvalidAccessError',
135
+ );
136
+ }
137
+
138
+ // Get hash algorithm from key
139
+ const hashAlgorithm = normalizeHashName(key.algorithm.hash);
140
+
141
+ // Prepare label (optional)
142
+ const label = rsaParams.label
143
+ ? bufferLikeToArrayBuffer(rsaParams.label)
144
+ : undefined;
145
+
146
+ // Create RSA cipher instance
147
+ const rsaCipherModule =
148
+ NitroModules.createHybridObject<RsaCipher>('RsaCipher');
149
+
150
+ // RSA-OAEP padding constant = 4
151
+ const RSA_PKCS1_OAEP_PADDING = 4;
152
+
153
+ if (mode === CipherOrWrapMode.kWebCryptoCipherEncrypt) {
154
+ // Encrypt with public key
155
+ return rsaCipherModule.encrypt(
156
+ key.keyObject.handle,
157
+ data,
158
+ RSA_PKCS1_OAEP_PADDING,
159
+ hashAlgorithm,
160
+ label,
161
+ );
162
+ } else {
163
+ // Decrypt with private key
164
+ return rsaCipherModule.decrypt(
165
+ key.keyObject.handle,
166
+ data,
167
+ RSA_PKCS1_OAEP_PADDING,
168
+ hashAlgorithm,
169
+ label,
170
+ );
171
+ }
172
+ }
173
+
174
+ async function aesCipher(
175
+ mode: CipherOrWrapMode,
176
+ key: CryptoKey,
177
+ data: ArrayBuffer,
178
+ algorithm: EncryptDecryptParams,
179
+ ): Promise<ArrayBuffer> {
180
+ const { name } = algorithm;
181
+
182
+ switch (name) {
183
+ case 'AES-CTR':
184
+ return aesCtrCipher(mode, key, data, algorithm as AesCtrParams);
185
+ case 'AES-CBC':
186
+ return aesCbcCipher(mode, key, data, algorithm as AesCbcParams);
187
+ case 'AES-GCM':
188
+ return aesGcmCipher(mode, key, data, algorithm as AesGcmParams);
189
+ default:
190
+ throw lazyDOMException(
191
+ `Unsupported AES algorithm: ${name}`,
192
+ 'NotSupportedError',
193
+ );
194
+ }
195
+ }
196
+
197
+ async function aesCtrCipher(
198
+ mode: CipherOrWrapMode,
199
+ key: CryptoKey,
200
+ data: ArrayBuffer,
201
+ algorithm: AesCtrParams,
202
+ ): Promise<ArrayBuffer> {
203
+ // Validate counter and length
204
+ if (!algorithm.counter || algorithm.counter.byteLength !== 16) {
205
+ throw lazyDOMException(
206
+ 'AES-CTR algorithm.counter must be 16 bytes',
207
+ 'OperationError',
208
+ );
209
+ }
210
+
211
+ if (algorithm.length < 1 || algorithm.length > 128) {
212
+ throw lazyDOMException(
213
+ 'AES-CTR algorithm.length must be between 1 and 128',
214
+ 'OperationError',
215
+ );
216
+ }
217
+
218
+ // Get cipher type based on key length
219
+ const keyLength = (key.algorithm as { length: number }).length;
220
+ const cipherType = `aes-${keyLength}-ctr`;
221
+
222
+ // Create cipher
223
+ const factory =
224
+ NitroModules.createHybridObject<CipherFactory>('CipherFactory');
225
+ const cipher = factory.createCipher({
226
+ isCipher: mode === CipherOrWrapMode.kWebCryptoCipherEncrypt,
227
+ cipherType,
228
+ cipherKey: bufferLikeToArrayBuffer(key.keyObject.export()),
229
+ iv: bufferLikeToArrayBuffer(algorithm.counter),
230
+ });
231
+
232
+ // Process data
233
+ const updated = cipher.update(data);
234
+ const final = cipher.final();
235
+
236
+ // Concatenate results
237
+ const result = new Uint8Array(updated.byteLength + final.byteLength);
238
+ result.set(new Uint8Array(updated), 0);
239
+ result.set(new Uint8Array(final), updated.byteLength);
240
+
241
+ return result.buffer;
242
+ }
243
+
244
+ async function aesCbcCipher(
245
+ mode: CipherOrWrapMode,
246
+ key: CryptoKey,
247
+ data: ArrayBuffer,
248
+ algorithm: AesCbcParams,
249
+ ): Promise<ArrayBuffer> {
250
+ // Validate IV
251
+ const iv = bufferLikeToArrayBuffer(algorithm.iv);
252
+ if (iv.byteLength !== 16) {
253
+ throw lazyDOMException(
254
+ 'algorithm.iv must contain exactly 16 bytes',
255
+ 'OperationError',
256
+ );
257
+ }
258
+
259
+ // Get cipher type based on key length
260
+ const keyLength = (key.algorithm as { length: number }).length;
261
+ const cipherType = `aes-${keyLength}-cbc`;
262
+
263
+ // Create cipher
264
+ const factory =
265
+ NitroModules.createHybridObject<CipherFactory>('CipherFactory');
266
+ const cipher = factory.createCipher({
267
+ isCipher: mode === CipherOrWrapMode.kWebCryptoCipherEncrypt,
268
+ cipherType,
269
+ cipherKey: bufferLikeToArrayBuffer(key.keyObject.export()),
270
+ iv,
271
+ });
272
+
273
+ // Process data
274
+ const updated = cipher.update(data);
275
+ const final = cipher.final();
276
+
277
+ // Concatenate results
278
+ const result = new Uint8Array(updated.byteLength + final.byteLength);
279
+ result.set(new Uint8Array(updated), 0);
280
+ result.set(new Uint8Array(final), updated.byteLength);
281
+
282
+ return result.buffer;
283
+ }
284
+
285
+ async function aesGcmCipher(
286
+ mode: CipherOrWrapMode,
287
+ key: CryptoKey,
288
+ data: ArrayBuffer,
289
+ algorithm: AesGcmParams,
290
+ ): Promise<ArrayBuffer> {
291
+ const { tagLength = 128 } = algorithm;
292
+
293
+ // Validate tag length
294
+ const validTagLengths = [32, 64, 96, 104, 112, 120, 128];
295
+ if (!validTagLengths.includes(tagLength)) {
296
+ throw lazyDOMException(
297
+ `${tagLength} is not a valid AES-GCM tag length`,
298
+ 'OperationError',
299
+ );
300
+ }
301
+
302
+ const tagByteLength = tagLength / 8;
303
+
304
+ // Get cipher type based on key length
305
+ const keyLength = (key.algorithm as { length: number }).length;
306
+ const cipherType = `aes-${keyLength}-gcm`;
307
+
308
+ // Create cipher
309
+ const factory =
310
+ NitroModules.createHybridObject<CipherFactory>('CipherFactory');
311
+ const cipher = factory.createCipher({
312
+ isCipher: mode === CipherOrWrapMode.kWebCryptoCipherEncrypt,
313
+ cipherType,
314
+ cipherKey: bufferLikeToArrayBuffer(key.keyObject.export()),
315
+ iv: bufferLikeToArrayBuffer(algorithm.iv),
316
+ authTagLen: tagByteLength,
317
+ });
318
+
319
+ let processData: ArrayBuffer;
320
+ let authTag: ArrayBuffer | undefined;
321
+
322
+ if (mode === CipherOrWrapMode.kWebCryptoCipherDecrypt) {
323
+ // For decryption, extract auth tag from end of data
324
+ const dataView = new Uint8Array(data);
325
+
326
+ if (dataView.byteLength < tagByteLength) {
327
+ throw lazyDOMException(
328
+ 'The provided data is too small.',
329
+ 'OperationError',
330
+ );
331
+ }
332
+
333
+ // Split data and tag
334
+ const ciphertextLength = dataView.byteLength - tagByteLength;
335
+ processData = dataView.slice(0, ciphertextLength).buffer;
336
+ authTag = dataView.slice(ciphertextLength).buffer;
337
+
338
+ // Set auth tag for verification
339
+ cipher.setAuthTag(authTag);
340
+ } else {
341
+ processData = data;
342
+ }
343
+
344
+ // Set additional authenticated data if provided
345
+ if (algorithm.additionalData) {
346
+ cipher.setAAD(bufferLikeToArrayBuffer(algorithm.additionalData));
347
+ }
348
+
349
+ // Process data
350
+ const updated = cipher.update(processData);
351
+ const final = cipher.final();
352
+
353
+ if (mode === CipherOrWrapMode.kWebCryptoCipherEncrypt) {
354
+ // For encryption, append auth tag to result
355
+ const tag = cipher.getAuthTag();
356
+ const result = new Uint8Array(
357
+ updated.byteLength + final.byteLength + tag.byteLength,
358
+ );
359
+ result.set(new Uint8Array(updated), 0);
360
+ result.set(new Uint8Array(final), updated.byteLength);
361
+ result.set(new Uint8Array(tag), updated.byteLength + final.byteLength);
362
+ return result.buffer;
363
+ } else {
364
+ // For decryption, just concatenate plaintext
365
+ const result = new Uint8Array(updated.byteLength + final.byteLength);
366
+ result.set(new Uint8Array(updated), 0);
367
+ result.set(new Uint8Array(final), updated.byteLength);
368
+ return result.buffer;
369
+ }
370
+ }
371
+
372
+ async function aesGenerateKey(
373
+ algorithm: AesKeyGenParams,
374
+ extractable: boolean,
375
+ keyUsages: KeyUsage[],
376
+ ): Promise<CryptoKey> {
377
+ const { length } = algorithm;
378
+ const name = algorithm.name;
379
+
380
+ if (!name) {
381
+ throw lazyDOMException('Algorithm name is required', 'OperationError');
382
+ }
383
+
384
+ // Validate key length
385
+ if (![128, 192, 256].includes(length)) {
386
+ throw lazyDOMException(
387
+ `Invalid AES key length: ${length}. Must be 128, 192, or 256.`,
388
+ 'OperationError',
389
+ );
390
+ }
391
+
392
+ // Validate usages
393
+ const validUsages: KeyUsage[] = [
394
+ 'encrypt',
395
+ 'decrypt',
396
+ 'wrapKey',
397
+ 'unwrapKey',
398
+ ];
399
+ if (hasAnyNotIn(keyUsages, validUsages)) {
400
+ throw lazyDOMException(`Unsupported key usage for ${name}`, 'SyntaxError');
401
+ }
402
+
403
+ // Generate random key bytes
404
+ const keyBytes = new Uint8Array(length / 8);
405
+ getRandomValues(keyBytes);
406
+
407
+ // Create secret key
408
+ const keyObject = createSecretKey(keyBytes);
409
+
410
+ // Construct algorithm object with guaranteed name
411
+ const keyAlgorithm: SubtleAlgorithm = { name, length };
412
+
413
+ return new CryptoKey(keyObject, keyAlgorithm, keyUsages, extractable);
414
+ }
415
+
416
+ async function hmacGenerateKey(
417
+ algorithm: SubtleAlgorithm,
418
+ extractable: boolean,
419
+ keyUsages: KeyUsage[],
420
+ ): Promise<CryptoKey> {
421
+ // Validate usages
422
+ if (hasAnyNotIn(keyUsages, ['sign', 'verify'])) {
423
+ throw lazyDOMException('Unsupported key usage for HMAC key', 'SyntaxError');
424
+ }
425
+
426
+ // Get hash algorithm
427
+ const hash = algorithm.hash;
428
+ if (!hash) {
429
+ throw lazyDOMException(
430
+ 'HMAC algorithm requires a hash parameter',
431
+ 'TypeError',
432
+ );
433
+ }
434
+
435
+ const hashName = normalizeHashName(hash);
436
+
437
+ // Determine key length
438
+ let length = algorithm.length;
439
+ if (length === undefined) {
440
+ // Use hash output length as default key length
441
+ switch (hashName) {
442
+ case 'SHA-1':
443
+ length = 160;
444
+ break;
445
+ case 'SHA-256':
446
+ length = 256;
447
+ break;
448
+ case 'SHA-384':
449
+ length = 384;
450
+ break;
451
+ case 'SHA-512':
452
+ length = 512;
453
+ break;
454
+ default:
455
+ length = 256; // Default to 256 bits
456
+ }
457
+ }
458
+
459
+ if (length === 0) {
460
+ throw lazyDOMException(
461
+ 'Zero-length key is not supported',
462
+ 'OperationError',
463
+ );
464
+ }
465
+
466
+ // Generate random key bytes
467
+ const keyBytes = new Uint8Array(Math.ceil(length / 8));
468
+ getRandomValues(keyBytes);
469
+
470
+ // Create secret key
471
+ const keyObject = createSecretKey(keyBytes);
472
+
473
+ // Construct algorithm object with hash normalized to { name: string } format per WebCrypto spec
474
+ const webCryptoHashName = normalizeHashName(hash, HashContext.WebCrypto);
475
+ const keyAlgorithm: SubtleAlgorithm = {
476
+ name: 'HMAC',
477
+ hash: { name: webCryptoHashName },
478
+ length,
479
+ };
480
+
481
+ return new CryptoKey(keyObject, keyAlgorithm, keyUsages, extractable);
482
+ }
483
+
484
+ function rsaImportKey(
485
+ format: ImportFormat,
486
+ data: BufferLike | JWK,
487
+ algorithm: SubtleAlgorithm,
488
+ extractable: boolean,
489
+ keyUsages: KeyUsage[],
490
+ ): CryptoKey {
491
+ const { name } = algorithm;
492
+
493
+ // Validate usages
494
+ let checkSet: KeyUsage[];
495
+ switch (name) {
496
+ case 'RSASSA-PKCS1-v1_5':
497
+ case 'RSA-PSS':
498
+ checkSet = ['sign', 'verify'];
499
+ break;
500
+ case 'RSA-OAEP':
501
+ checkSet = ['encrypt', 'decrypt', 'wrapKey', 'unwrapKey'];
502
+ break;
503
+ default:
504
+ throw new Error(`Unsupported RSA algorithm: ${name}`);
505
+ }
506
+
507
+ if (hasAnyNotIn(keyUsages, checkSet)) {
508
+ throw new Error(`Unsupported key usage for ${name}`);
509
+ }
510
+
511
+ let keyObject: KeyObject;
512
+
513
+ if (format === 'jwk') {
514
+ const jwk = data as JWK;
515
+
516
+ // Validate JWK
517
+ if (jwk.kty !== 'RSA') {
518
+ throw new Error('Invalid JWK format for RSA key');
519
+ }
520
+
521
+ const handle =
522
+ NitroModules.createHybridObject<KeyObjectHandle>('KeyObjectHandle');
523
+ const keyType = handle.initJwk(jwk, undefined);
524
+
525
+ if (keyType === undefined) {
526
+ throw new Error('Failed to import RSA JWK');
527
+ }
528
+
529
+ // Create the appropriate KeyObject based on type
530
+ if (keyType === 1) {
531
+ keyObject = new PublicKeyObject(handle);
532
+ } else if (keyType === 2) {
533
+ keyObject = new PrivateKeyObject(handle);
534
+ } else {
535
+ throw new Error('Unexpected key type from RSA JWK import');
536
+ }
537
+ } else if (format === 'spki') {
538
+ const keyData = bufferLikeToArrayBuffer(data as BufferLike);
539
+ keyObject = KeyObject.createKeyObject(
540
+ 'public',
541
+ keyData,
542
+ KFormatType.DER,
543
+ KeyEncoding.SPKI,
544
+ );
545
+ } else if (format === 'pkcs8') {
546
+ const keyData = bufferLikeToArrayBuffer(data as BufferLike);
547
+ keyObject = KeyObject.createKeyObject(
548
+ 'private',
549
+ keyData,
550
+ KFormatType.DER,
551
+ KeyEncoding.PKCS8,
552
+ );
553
+ } else {
554
+ throw new Error(`Unsupported format for RSA import: ${format}`);
555
+ }
556
+
557
+ // Get the modulus length from the key and add it to the algorithm
558
+ const keyDetails = (keyObject as PublicKeyObject | PrivateKeyObject)
559
+ .asymmetricKeyDetails;
560
+
561
+ // Convert publicExponent number to big-endian byte array
562
+ let publicExponentBytes: Uint8Array | undefined;
563
+ if (keyDetails?.publicExponent) {
564
+ const exp = keyDetails.publicExponent;
565
+ // Convert number to big-endian bytes
566
+ const bytes: number[] = [];
567
+ let value = exp;
568
+ while (value > 0) {
569
+ bytes.unshift(value & 0xff);
570
+ value = Math.floor(value / 256);
571
+ }
572
+ publicExponentBytes = new Uint8Array(bytes.length > 0 ? bytes : [0]);
573
+ }
574
+
575
+ // Normalize hash to { name: string } format per WebCrypto spec
576
+ const hashName = normalizeHashName(algorithm.hash, HashContext.WebCrypto);
577
+ const normalizedHash = { name: hashName };
578
+
579
+ const algorithmWithDetails = {
580
+ ...algorithm,
581
+ modulusLength: keyDetails?.modulusLength,
582
+ publicExponent: publicExponentBytes,
583
+ hash: normalizedHash,
584
+ };
585
+
586
+ return new CryptoKey(keyObject, algorithmWithDetails, keyUsages, extractable);
587
+ }
588
+
589
+ async function hmacImportKey(
590
+ algorithm: SubtleAlgorithm,
591
+ format: ImportFormat,
592
+ data: BufferLike | JWK,
593
+ extractable: boolean,
594
+ keyUsages: KeyUsage[],
595
+ ): Promise<CryptoKey> {
596
+ // Validate usages
597
+ if (hasAnyNotIn(keyUsages, ['sign', 'verify'])) {
598
+ throw new Error('Unsupported key usage for an HMAC key');
599
+ }
600
+
601
+ let keyObject: KeyObject;
602
+
603
+ if (format === 'jwk') {
604
+ const jwk = data as JWK;
605
+
606
+ // Validate JWK
607
+ if (!jwk || typeof jwk !== 'object') {
608
+ throw new Error('Invalid keyData');
609
+ }
610
+
611
+ if (jwk.kty !== 'oct') {
612
+ throw new Error('Invalid JWK format for HMAC key');
613
+ }
614
+
615
+ // Validate key length if specified
616
+ if (algorithm.length !== undefined) {
617
+ if (!jwk.k) {
618
+ throw new Error('JWK missing key data');
619
+ }
620
+ // Decode to check length
621
+ const decoded = SBuffer.from(jwk.k, 'base64');
622
+ const keyBitLength = decoded.length * 8;
623
+ if (algorithm.length === 0) {
624
+ throw new Error('Zero-length key is not supported');
625
+ }
626
+ if (algorithm.length !== keyBitLength) {
627
+ throw new Error('Invalid key length');
628
+ }
629
+ }
630
+
631
+ const handle =
632
+ NitroModules.createHybridObject<KeyObjectHandle>('KeyObjectHandle');
633
+ const keyType = handle.initJwk(jwk, undefined);
634
+
635
+ if (keyType === undefined || keyType !== 0) {
636
+ throw new Error('Failed to import HMAC JWK');
637
+ }
638
+
639
+ keyObject = new SecretKeyObject(handle);
640
+ } else if (format === 'raw') {
641
+ keyObject = createSecretKey(data as BinaryLike);
642
+ } else {
643
+ throw new Error(`Unable to import HMAC key with format ${format}`);
644
+ }
645
+
646
+ // Normalize hash to { name: string } format per WebCrypto spec
647
+ const hashName = normalizeHashName(algorithm.hash, HashContext.WebCrypto);
648
+ const normalizedAlgorithm: SubtleAlgorithm = {
649
+ ...algorithm,
650
+ name: 'HMAC',
651
+ hash: { name: hashName },
652
+ };
653
+
654
+ return new CryptoKey(keyObject, normalizedAlgorithm, keyUsages, extractable);
655
+ }
656
+
657
+ async function aesImportKey(
658
+ algorithm: SubtleAlgorithm,
659
+ format: ImportFormat,
660
+ data: BufferLike | JWK,
661
+ extractable: boolean,
662
+ keyUsages: KeyUsage[],
663
+ ): Promise<CryptoKey> {
664
+ const { name, length } = algorithm;
665
+
666
+ // Validate usages
667
+ const validUsages: KeyUsage[] = [
668
+ 'encrypt',
669
+ 'decrypt',
670
+ 'wrapKey',
671
+ 'unwrapKey',
672
+ ];
673
+ if (hasAnyNotIn(keyUsages, validUsages)) {
674
+ throw new Error(`Unsupported key usage for ${name}`);
675
+ }
676
+
677
+ let keyObject: KeyObject;
678
+ let actualLength: number;
679
+
680
+ if (format === 'jwk') {
681
+ const jwk = data as JWK;
682
+
683
+ // Validate JWK
684
+ if (jwk.kty !== 'oct') {
685
+ throw new Error('Invalid JWK format for AES key');
686
+ }
687
+
688
+ const handle =
689
+ NitroModules.createHybridObject<KeyObjectHandle>('KeyObjectHandle');
690
+ const keyType = handle.initJwk(jwk, undefined);
691
+
692
+ if (keyType === undefined || keyType !== 0) {
693
+ throw new Error('Failed to import AES JWK');
694
+ }
695
+
696
+ keyObject = new SecretKeyObject(handle);
697
+
698
+ // Get actual key length from imported key
699
+ const exported = keyObject.export();
700
+ actualLength = exported.byteLength * 8;
701
+ } else if (format === 'raw') {
702
+ const keyData = bufferLikeToArrayBuffer(data as BufferLike);
703
+ actualLength = keyData.byteLength * 8;
704
+
705
+ // Validate key length
706
+ if (![128, 192, 256].includes(actualLength)) {
707
+ throw new Error('Invalid AES key length');
708
+ }
709
+
710
+ keyObject = createSecretKey(keyData);
711
+ } else {
712
+ throw new Error(`Unsupported format for AES import: ${format}`);
713
+ }
714
+
715
+ // Validate length if specified
716
+ if (length !== undefined && length !== actualLength) {
717
+ throw new Error(
718
+ `Key length mismatch: expected ${length}, got ${actualLength}`,
719
+ );
720
+ }
721
+
722
+ return new CryptoKey(
723
+ keyObject,
724
+ { name, length: actualLength },
725
+ keyUsages,
726
+ extractable,
727
+ );
728
+ }
729
+
730
+ function edImportKey(
731
+ format: ImportFormat,
732
+ data: BufferLike,
733
+ algorithm: SubtleAlgorithm,
734
+ extractable: boolean,
735
+ keyUsages: KeyUsage[],
736
+ ): CryptoKey {
737
+ const { name } = algorithm;
738
+
739
+ // Validate usages
740
+ if (hasAnyNotIn(keyUsages, ['sign', 'verify'])) {
741
+ throw lazyDOMException(
742
+ `Unsupported key usage for ${name} key`,
743
+ 'SyntaxError',
744
+ );
745
+ }
746
+
747
+ let keyObject: KeyObject;
748
+
749
+ if (format === 'spki') {
750
+ // Import public key
751
+ const keyData = bufferLikeToArrayBuffer(data);
752
+ keyObject = KeyObject.createKeyObject(
753
+ 'public',
754
+ keyData,
755
+ KFormatType.DER,
756
+ KeyEncoding.SPKI,
757
+ );
758
+ } else if (format === 'pkcs8') {
759
+ // Import private key
760
+ const keyData = bufferLikeToArrayBuffer(data);
761
+ keyObject = KeyObject.createKeyObject(
762
+ 'private',
763
+ keyData,
764
+ KFormatType.DER,
765
+ KeyEncoding.PKCS8,
766
+ );
767
+ } else if (format === 'raw') {
768
+ // Raw format - public key only for Ed keys
769
+ const keyData = bufferLikeToArrayBuffer(data);
770
+ const handle =
771
+ NitroModules.createHybridObject<KeyObjectHandle>('KeyObjectHandle');
772
+ // For raw Ed keys, we need to create them differently
773
+ // Raw public keys are just the key bytes
774
+ handle.init(1, keyData); // 1 = public key type
775
+ keyObject = new PublicKeyObject(handle);
776
+ } else {
777
+ throw lazyDOMException(
778
+ `Unsupported format for ${name} import: ${format}`,
779
+ 'NotSupportedError',
780
+ );
781
+ }
782
+
783
+ return new CryptoKey(keyObject, { name }, keyUsages, extractable);
784
+ }
785
+
786
+ function mldsaImportKey(
787
+ format: ImportFormat,
788
+ data: BufferLike,
789
+ algorithm: SubtleAlgorithm,
790
+ extractable: boolean,
791
+ keyUsages: KeyUsage[],
792
+ ): CryptoKey {
793
+ const { name } = algorithm;
794
+
795
+ // Validate usages
796
+ if (hasAnyNotIn(keyUsages, ['sign', 'verify'])) {
797
+ throw lazyDOMException(
798
+ `Unsupported key usage for ${name} key`,
799
+ 'SyntaxError',
800
+ );
801
+ }
802
+
803
+ let keyObject: KeyObject;
804
+
805
+ if (format === 'spki') {
806
+ // Import public key
807
+ const keyData = bufferLikeToArrayBuffer(data);
808
+ keyObject = KeyObject.createKeyObject(
809
+ 'public',
810
+ keyData,
811
+ KFormatType.DER,
812
+ KeyEncoding.SPKI,
813
+ );
814
+ } else if (format === 'pkcs8') {
815
+ // Import private key
816
+ const keyData = bufferLikeToArrayBuffer(data);
817
+ keyObject = KeyObject.createKeyObject(
818
+ 'private',
819
+ keyData,
820
+ KFormatType.DER,
821
+ KeyEncoding.PKCS8,
822
+ );
823
+ } else {
824
+ throw lazyDOMException(
825
+ `Unsupported format for ${name} import: ${format}`,
826
+ 'NotSupportedError',
827
+ );
828
+ }
829
+
830
+ return new CryptoKey(keyObject, { name }, keyUsages, extractable);
831
+ }
832
+
833
+ const exportKeySpki = async (
834
+ key: CryptoKey,
835
+ ): Promise<ArrayBuffer | unknown> => {
836
+ switch (key.algorithm.name) {
837
+ case 'RSASSA-PKCS1-v1_5':
838
+ // Fall through
839
+ case 'RSA-PSS':
840
+ // Fall through
841
+ case 'RSA-OAEP':
842
+ if (key.type === 'public') {
843
+ return rsaExportKey(key, KWebCryptoKeyFormat.kWebCryptoKeyFormatSPKI);
844
+ }
845
+ break;
846
+ case 'ECDSA':
847
+ // Fall through
848
+ case 'ECDH':
849
+ if (key.type === 'public') {
850
+ return ecExportKey(key, KWebCryptoKeyFormat.kWebCryptoKeyFormatSPKI);
851
+ }
852
+ break;
853
+ case 'Ed25519':
854
+ // Fall through
855
+ case 'Ed448':
856
+ if (key.type === 'public') {
857
+ // Export Ed key in SPKI DER format
858
+ return bufferLikeToArrayBuffer(
859
+ key.keyObject.handle.exportKey(KFormatType.DER, KeyEncoding.SPKI),
860
+ );
861
+ }
862
+ break;
863
+ case 'ML-DSA-44':
864
+ // Fall through
865
+ case 'ML-DSA-65':
866
+ // Fall through
867
+ case 'ML-DSA-87':
868
+ if (key.type === 'public') {
869
+ // Export ML-DSA key in SPKI DER format
870
+ return bufferLikeToArrayBuffer(
871
+ key.keyObject.handle.exportKey(KFormatType.DER, KeyEncoding.SPKI),
872
+ );
873
+ }
874
+ break;
875
+ }
876
+
877
+ throw new Error(
878
+ `Unable to export a spki ${key.algorithm.name} ${key.type} key`,
879
+ );
880
+ };
881
+
882
+ const exportKeyPkcs8 = async (
883
+ key: CryptoKey,
884
+ ): Promise<ArrayBuffer | unknown> => {
885
+ switch (key.algorithm.name) {
886
+ case 'RSASSA-PKCS1-v1_5':
887
+ // Fall through
888
+ case 'RSA-PSS':
889
+ // Fall through
890
+ case 'RSA-OAEP':
891
+ if (key.type === 'private') {
892
+ return rsaExportKey(key, KWebCryptoKeyFormat.kWebCryptoKeyFormatPKCS8);
893
+ }
894
+ break;
895
+ case 'ECDSA':
896
+ // Fall through
897
+ case 'ECDH':
898
+ if (key.type === 'private') {
899
+ return ecExportKey(key, KWebCryptoKeyFormat.kWebCryptoKeyFormatPKCS8);
900
+ }
901
+ break;
902
+ case 'Ed25519':
903
+ // Fall through
904
+ case 'Ed448':
905
+ if (key.type === 'private') {
906
+ // Export Ed key in PKCS8 DER format
907
+ return bufferLikeToArrayBuffer(
908
+ key.keyObject.handle.exportKey(KFormatType.DER, KeyEncoding.PKCS8),
909
+ );
910
+ }
911
+ break;
912
+ case 'ML-DSA-44':
913
+ // Fall through
914
+ case 'ML-DSA-65':
915
+ // Fall through
916
+ case 'ML-DSA-87':
917
+ if (key.type === 'private') {
918
+ // Export ML-DSA key in PKCS8 DER format
919
+ return bufferLikeToArrayBuffer(
920
+ key.keyObject.handle.exportKey(KFormatType.DER, KeyEncoding.PKCS8),
921
+ );
922
+ }
923
+ break;
924
+ }
925
+
926
+ throw new Error(
927
+ `Unable to export a pkcs8 ${key.algorithm.name} ${key.type} key`,
928
+ );
929
+ };
930
+
931
+ const exportKeyRaw = (key: CryptoKey): ArrayBuffer | unknown => {
932
+ switch (key.algorithm.name) {
933
+ case 'ECDSA':
934
+ // Fall through
935
+ case 'ECDH':
936
+ if (key.type === 'public') {
937
+ return ecExportKey(key, KWebCryptoKeyFormat.kWebCryptoKeyFormatRaw);
938
+ }
939
+ break;
940
+ case 'AES-CTR':
941
+ // Fall through
942
+ case 'AES-CBC':
943
+ // Fall through
944
+ case 'AES-GCM':
945
+ // Fall through
946
+ case 'AES-KW':
947
+ // Fall through
948
+ case 'HMAC': {
949
+ const exported = key.keyObject.export();
950
+ // Convert Buffer to ArrayBuffer
951
+ return exported.buffer.slice(
952
+ exported.byteOffset,
953
+ exported.byteOffset + exported.byteLength,
954
+ );
955
+ }
956
+ }
957
+
958
+ throw lazyDOMException(
959
+ `Unable to export a raw ${key.algorithm.name} ${key.type} key`,
960
+ 'InvalidAccessError',
961
+ );
962
+ };
963
+
964
+ const exportKeyJWK = (key: CryptoKey): ArrayBuffer | unknown => {
965
+ const jwk = key.keyObject.handle.exportJwk(
966
+ {
967
+ key_ops: key.usages,
968
+ ext: key.extractable,
969
+ },
970
+ true,
971
+ );
972
+ switch (key.algorithm.name) {
973
+ case 'RSASSA-PKCS1-v1_5':
974
+ jwk.alg = normalizeHashName(key.algorithm.hash, HashContext.JwkRsa);
975
+ return jwk;
976
+ case 'RSA-PSS':
977
+ jwk.alg = normalizeHashName(key.algorithm.hash, HashContext.JwkRsaPss);
978
+ return jwk;
979
+ case 'RSA-OAEP':
980
+ jwk.alg = normalizeHashName(key.algorithm.hash, HashContext.JwkRsaOaep);
981
+ return jwk;
982
+ case 'HMAC':
983
+ jwk.alg = normalizeHashName(key.algorithm.hash, HashContext.JwkHmac);
984
+ return jwk;
985
+ case 'ECDSA':
986
+ // Fall through
987
+ case 'ECDH':
988
+ jwk.crv ||= key.algorithm.namedCurve;
989
+ return jwk;
990
+ case 'AES-CTR':
991
+ // Fall through
992
+ case 'AES-CBC':
993
+ // Fall through
994
+ case 'AES-GCM':
995
+ // Fall through
996
+ case 'AES-KW':
997
+ if (key.algorithm.length === undefined) {
998
+ throw lazyDOMException(
999
+ `Algorithm ${key.algorithm.name} missing required length property`,
1000
+ 'InvalidAccessError',
1001
+ );
1002
+ }
1003
+ jwk.alg = getAlgorithmName(key.algorithm.name, key.algorithm.length);
1004
+ return jwk;
1005
+ default:
1006
+ // Fall through
1007
+ }
1008
+
1009
+ throw lazyDOMException(
1010
+ `JWK export not yet supported: ${key.algorithm.name}`,
1011
+ 'NotSupportedError',
1012
+ );
1013
+ };
1014
+
1015
+ const importGenericSecretKey = async (
1016
+ { name, length }: SubtleAlgorithm,
1017
+ format: ImportFormat,
1018
+ keyData: BufferLike | BinaryLike,
1019
+ extractable: boolean,
1020
+ keyUsages: KeyUsage[],
1021
+ ): Promise<CryptoKey> => {
1022
+ if (extractable) {
1023
+ throw new Error(`${name} keys are not extractable`);
1024
+ }
1025
+ if (hasAnyNotIn(keyUsages, ['deriveKey', 'deriveBits'])) {
1026
+ throw new Error(`Unsupported key usage for a ${name} key`);
1027
+ }
1028
+
1029
+ switch (format) {
1030
+ case 'raw': {
1031
+ if (hasAnyNotIn(keyUsages, ['deriveKey', 'deriveBits'])) {
1032
+ throw new Error(`Unsupported key usage for a ${name} key`);
1033
+ }
1034
+
1035
+ const checkLength =
1036
+ typeof keyData === 'string' || SBuffer.isBuffer(keyData)
1037
+ ? keyData.length * 8
1038
+ : keyData.byteLength * 8;
1039
+
1040
+ if (length !== undefined && length !== checkLength) {
1041
+ throw new Error('Invalid key length');
1042
+ }
1043
+
1044
+ const keyObject = createSecretKey(keyData as BinaryLike);
1045
+ return new CryptoKey(keyObject, { name }, keyUsages, false);
1046
+ }
1047
+ }
1048
+
1049
+ throw new Error(`Unable to import ${name} key with format ${format}`);
1050
+ };
1051
+
1052
+ const checkCryptoKeyPairUsages = (pair: CryptoKeyPair) => {
1053
+ if (
1054
+ pair.privateKey &&
1055
+ pair.privateKey instanceof CryptoKey &&
1056
+ pair.privateKey.keyUsages &&
1057
+ pair.privateKey.keyUsages.length > 0
1058
+ ) {
1059
+ return;
1060
+ }
1061
+ throw lazyDOMException(
1062
+ 'Usages cannot be empty when creating a key.',
1063
+ 'SyntaxError',
1064
+ );
1065
+ };
1066
+
1067
+ // Type guard to check if result is CryptoKeyPair
1068
+ export function isCryptoKeyPair(
1069
+ result: CryptoKey | CryptoKeyPair,
1070
+ ): result is CryptoKeyPair {
1071
+ return 'publicKey' in result && 'privateKey' in result;
1072
+ }
1073
+
1074
+ function hmacSignVerify(
1075
+ key: CryptoKey,
1076
+ data: BufferLike,
1077
+ signature?: BufferLike,
1078
+ ): ArrayBuffer | boolean {
1079
+ // Get hash algorithm from key
1080
+ const hashName = normalizeHashName(key.algorithm.hash);
1081
+
1082
+ // Export the secret key material
1083
+ const keyData = key.keyObject.export();
1084
+
1085
+ // Create HMAC and compute digest
1086
+ const hmac = createHmac(hashName, keyData);
1087
+ hmac.update(bufferLikeToArrayBuffer(data));
1088
+ const computed = hmac.digest();
1089
+
1090
+ if (signature === undefined) {
1091
+ // Sign operation - return the HMAC as ArrayBuffer
1092
+ return computed.buffer.slice(
1093
+ computed.byteOffset,
1094
+ computed.byteOffset + computed.byteLength,
1095
+ );
1096
+ }
1097
+
1098
+ // Verify operation - compare computed HMAC with provided signature
1099
+ const sigBytes = new Uint8Array(bufferLikeToArrayBuffer(signature));
1100
+ const computedBytes = new Uint8Array(
1101
+ computed.buffer,
1102
+ computed.byteOffset,
1103
+ computed.byteLength,
1104
+ );
1105
+
1106
+ if (computedBytes.length !== sigBytes.length) {
1107
+ return false;
1108
+ }
1109
+
1110
+ // Constant-time comparison to prevent timing attacks
1111
+ let result = 0;
1112
+ for (let i = 0; i < computedBytes.length; i++) {
1113
+ result |= computedBytes[i]! ^ sigBytes[i]!;
1114
+ }
1115
+ return result === 0;
1116
+ }
1117
+
1118
+ function rsaSignVerify(
1119
+ key: CryptoKey,
1120
+ data: BufferLike,
1121
+ padding: 'pkcs1' | 'pss',
1122
+ signature?: BufferLike,
1123
+ saltLength?: number,
1124
+ ): ArrayBuffer | boolean {
1125
+ // Get hash algorithm from key
1126
+ const hashName = normalizeHashName(key.algorithm.hash);
1127
+
1128
+ // Determine RSA padding constant
1129
+ const RSA_PKCS1_PADDING = 1;
1130
+ const RSA_PKCS1_PSS_PADDING = 6;
1131
+ const paddingValue =
1132
+ padding === 'pss' ? RSA_PKCS1_PSS_PADDING : RSA_PKCS1_PADDING;
1133
+
1134
+ if (signature === undefined) {
1135
+ // Sign operation
1136
+ const signer = createSign(hashName);
1137
+ signer.update(data);
1138
+ const sig = signer.sign({
1139
+ key: key,
1140
+ padding: paddingValue,
1141
+ saltLength,
1142
+ });
1143
+ return sig.buffer.slice(sig.byteOffset, sig.byteOffset + sig.byteLength);
1144
+ }
1145
+
1146
+ // Verify operation
1147
+ const verifier = createVerify(hashName);
1148
+ verifier.update(data);
1149
+ return verifier.verify(
1150
+ {
1151
+ key: key,
1152
+ padding: paddingValue,
1153
+ saltLength,
1154
+ },
1155
+ signature,
1156
+ );
1157
+ }
1158
+
1159
+ function edSignVerify(
1160
+ key: CryptoKey,
1161
+ data: BufferLike,
1162
+ signature?: BufferLike,
1163
+ ): ArrayBuffer | boolean {
1164
+ const isSign = signature === undefined;
1165
+ const expectedKeyType = isSign ? 'private' : 'public';
1166
+
1167
+ if (key.type !== expectedKeyType) {
1168
+ throw lazyDOMException(
1169
+ `Key must be a ${expectedKeyType} key`,
1170
+ 'InvalidAccessError',
1171
+ );
1172
+ }
1173
+
1174
+ // Get curve type from algorithm name (Ed25519 or Ed448)
1175
+ const algorithmName = key.algorithm.name;
1176
+ const curveType = algorithmName.toLowerCase() as 'ed25519' | 'ed448';
1177
+
1178
+ // Create Ed instance with the curve
1179
+ const ed = new Ed(curveType, {});
1180
+
1181
+ // Export raw key bytes (exportKey with no format returns raw for Ed keys)
1182
+ const rawKey = key.keyObject.handle.exportKey();
1183
+ const dataBuffer = bufferLikeToArrayBuffer(data);
1184
+
1185
+ if (isSign) {
1186
+ // Sign operation - use raw private key
1187
+ const sig = ed.signSync(dataBuffer, rawKey);
1188
+ return sig;
1189
+ } else {
1190
+ // Verify operation - use raw public key
1191
+ const signatureBuffer = bufferLikeToArrayBuffer(signature!);
1192
+ return ed.verifySync(signatureBuffer, dataBuffer, rawKey);
1193
+ }
1194
+ }
1195
+
1196
+ function mldsaSignVerify(
1197
+ key: CryptoKey,
1198
+ data: BufferLike,
1199
+ signature?: BufferLike,
1200
+ ): ArrayBuffer | boolean {
1201
+ const isSign = signature === undefined;
1202
+ const expectedKeyType = isSign ? 'private' : 'public';
1203
+
1204
+ if (key.type !== expectedKeyType) {
1205
+ throw lazyDOMException(
1206
+ `Key must be a ${expectedKeyType} key`,
1207
+ 'InvalidAccessError',
1208
+ );
1209
+ }
1210
+
1211
+ const dataBuffer = bufferLikeToArrayBuffer(data);
1212
+
1213
+ if (isSign) {
1214
+ const signer = createSign('');
1215
+ signer.update(dataBuffer);
1216
+ const sig = signer.sign({ key: key });
1217
+ return sig.buffer.slice(sig.byteOffset, sig.byteOffset + sig.byteLength);
1218
+ } else {
1219
+ const signatureBuffer = bufferLikeToArrayBuffer(signature!);
1220
+ const verifier = createVerify('');
1221
+ verifier.update(dataBuffer);
1222
+ return verifier.verify({ key: key }, signatureBuffer);
1223
+ }
1224
+ }
1225
+
1226
+ const signVerify = (
1227
+ algorithm: SubtleAlgorithm,
1228
+ key: CryptoKey,
1229
+ data: BufferLike,
1230
+ signature?: BufferLike,
1231
+ ): ArrayBuffer | boolean => {
1232
+ const usage: Operation = signature === undefined ? 'sign' : 'verify';
1233
+ algorithm = normalizeAlgorithm(algorithm, usage);
1234
+
1235
+ if (!key.usages.includes(usage) || algorithm.name !== key.algorithm.name) {
1236
+ throw lazyDOMException(
1237
+ `Unable to use this key to ${usage}`,
1238
+ 'InvalidAccessError',
1239
+ );
1240
+ }
1241
+
1242
+ switch (algorithm.name) {
1243
+ case 'ECDSA':
1244
+ return ecdsaSignVerify(key, data, algorithm, signature);
1245
+ case 'HMAC':
1246
+ return hmacSignVerify(key, data, signature);
1247
+ case 'RSASSA-PKCS1-v1_5':
1248
+ return rsaSignVerify(key, data, 'pkcs1', signature);
1249
+ case 'RSA-PSS':
1250
+ return rsaSignVerify(key, data, 'pss', signature, algorithm.saltLength);
1251
+ case 'Ed25519':
1252
+ case 'Ed448':
1253
+ return edSignVerify(key, data, signature);
1254
+ case 'ML-DSA-44':
1255
+ case 'ML-DSA-65':
1256
+ case 'ML-DSA-87':
1257
+ return mldsaSignVerify(key, data, signature);
1258
+ }
1259
+ throw lazyDOMException(
1260
+ `Unrecognized algorithm name '${algorithm.name}' for '${usage}'`,
1261
+ 'NotSupportedError',
1262
+ );
1263
+ };
1264
+
1265
+ const cipherOrWrap = async (
1266
+ mode: CipherOrWrapMode,
1267
+ algorithm: EncryptDecryptParams,
1268
+ key: CryptoKey,
1269
+ data: ArrayBuffer,
1270
+ op: Operation,
1271
+ ): Promise<ArrayBuffer> => {
1272
+ if (
1273
+ key.algorithm.name !== algorithm.name ||
1274
+ !key.usages.includes(op as KeyUsage)
1275
+ ) {
1276
+ throw lazyDOMException(
1277
+ 'The requested operation is not valid for the provided key',
1278
+ 'InvalidAccessError',
1279
+ );
1280
+ }
1281
+
1282
+ validateMaxBufferLength(data, 'data');
1283
+
1284
+ switch (algorithm.name) {
1285
+ case 'RSA-OAEP':
1286
+ return rsaCipher(mode, key, data, algorithm);
1287
+ case 'AES-CTR':
1288
+ // Fall through
1289
+ case 'AES-CBC':
1290
+ // Fall through
1291
+ case 'AES-GCM':
1292
+ return aesCipher(mode, key, data, algorithm);
1293
+ }
1294
+ };
1295
+
1296
+ export class Subtle {
1297
+ async decrypt(
1298
+ algorithm: EncryptDecryptParams,
1299
+ key: CryptoKey,
1300
+ data: BufferLike,
1301
+ ): Promise<ArrayBuffer> {
1302
+ const normalizedAlgorithm = normalizeAlgorithm(algorithm, 'decrypt');
1303
+ return cipherOrWrap(
1304
+ CipherOrWrapMode.kWebCryptoCipherDecrypt,
1305
+ normalizedAlgorithm as EncryptDecryptParams,
1306
+ key,
1307
+ bufferLikeToArrayBuffer(data),
1308
+ 'decrypt',
1309
+ );
1310
+ }
1311
+
1312
+ async digest(
1313
+ algorithm: SubtleAlgorithm | AnyAlgorithm,
1314
+ data: BufferLike,
1315
+ ): Promise<ArrayBuffer> {
1316
+ const normalizedAlgorithm = normalizeAlgorithm(
1317
+ algorithm,
1318
+ 'digest' as Operation,
1319
+ );
1320
+ return asyncDigest(normalizedAlgorithm, data);
1321
+ }
1322
+
1323
+ async deriveBits(
1324
+ algorithm: SubtleAlgorithm,
1325
+ baseKey: CryptoKey,
1326
+ length: number,
1327
+ ): Promise<ArrayBuffer> {
1328
+ if (!baseKey.keyUsages.includes('deriveBits')) {
1329
+ throw new Error('baseKey does not have deriveBits usage');
1330
+ }
1331
+ if (baseKey.algorithm.name !== algorithm.name)
1332
+ throw new Error('Key algorithm mismatch');
1333
+ switch (algorithm.name) {
1334
+ case 'PBKDF2':
1335
+ return pbkdf2DeriveBits(algorithm, baseKey, length);
1336
+ }
1337
+ throw new Error(
1338
+ `'subtle.deriveBits()' for ${algorithm.name} is not implemented.`,
1339
+ );
1340
+ }
1341
+
1342
+ async encrypt(
1343
+ algorithm: EncryptDecryptParams,
1344
+ key: CryptoKey,
1345
+ data: BufferLike,
1346
+ ): Promise<ArrayBuffer> {
1347
+ const normalizedAlgorithm = normalizeAlgorithm(algorithm, 'encrypt');
1348
+ return cipherOrWrap(
1349
+ CipherOrWrapMode.kWebCryptoCipherEncrypt,
1350
+ normalizedAlgorithm as EncryptDecryptParams,
1351
+ key,
1352
+ bufferLikeToArrayBuffer(data),
1353
+ 'encrypt',
1354
+ );
1355
+ }
1356
+
1357
+ async exportKey(
1358
+ format: ImportFormat,
1359
+ key: CryptoKey,
1360
+ ): Promise<ArrayBuffer | JWK> {
1361
+ if (!key.extractable) throw new Error('key is not extractable');
1362
+
1363
+ switch (format) {
1364
+ case 'spki':
1365
+ return (await exportKeySpki(key)) as ArrayBuffer;
1366
+ case 'pkcs8':
1367
+ return (await exportKeyPkcs8(key)) as ArrayBuffer;
1368
+ case 'jwk':
1369
+ return exportKeyJWK(key) as JWK;
1370
+ case 'raw':
1371
+ return exportKeyRaw(key) as ArrayBuffer;
1372
+ }
1373
+ }
1374
+
1375
+ async generateKey(
1376
+ algorithm: SubtleAlgorithm,
1377
+ extractable: boolean,
1378
+ keyUsages: KeyUsage[],
1379
+ ): Promise<CryptoKey | CryptoKeyPair> {
1380
+ algorithm = normalizeAlgorithm(algorithm, 'generateKey');
1381
+ let result: CryptoKey | CryptoKeyPair;
1382
+ switch (algorithm.name) {
1383
+ case 'RSASSA-PKCS1-v1_5':
1384
+ // Fall through
1385
+ case 'RSA-PSS':
1386
+ // Fall through
1387
+ case 'RSA-OAEP':
1388
+ result = await rsa_generateKeyPair(algorithm, extractable, keyUsages);
1389
+ break;
1390
+ case 'ECDSA':
1391
+ // Fall through
1392
+ case 'ECDH':
1393
+ result = await ec_generateKeyPair(
1394
+ algorithm.name,
1395
+ algorithm.namedCurve!,
1396
+ extractable,
1397
+ keyUsages,
1398
+ );
1399
+ checkCryptoKeyPairUsages(result as CryptoKeyPair);
1400
+ break;
1401
+ case 'AES-CTR':
1402
+ // Fall through
1403
+ case 'AES-CBC':
1404
+ // Fall through
1405
+ case 'AES-GCM':
1406
+ // Fall through
1407
+ case 'AES-KW':
1408
+ result = await aesGenerateKey(
1409
+ algorithm as AesKeyGenParams,
1410
+ extractable,
1411
+ keyUsages,
1412
+ );
1413
+ break;
1414
+ case 'HMAC':
1415
+ result = await hmacGenerateKey(algorithm, extractable, keyUsages);
1416
+ break;
1417
+ case 'Ed25519':
1418
+ // Fall through
1419
+ case 'Ed448':
1420
+ result = await ed_generateKeyPairWebCrypto(
1421
+ algorithm.name.toLowerCase() as 'ed25519' | 'ed448',
1422
+ extractable,
1423
+ keyUsages,
1424
+ );
1425
+ checkCryptoKeyPairUsages(result as CryptoKeyPair);
1426
+ break;
1427
+ case 'ML-DSA-44':
1428
+ // Fall through
1429
+ case 'ML-DSA-65':
1430
+ // Fall through
1431
+ case 'ML-DSA-87':
1432
+ result = await mldsa_generateKeyPairWebCrypto(
1433
+ algorithm.name as MlDsaVariant,
1434
+ extractable,
1435
+ keyUsages,
1436
+ );
1437
+ checkCryptoKeyPairUsages(result as CryptoKeyPair);
1438
+ break;
1439
+ default:
1440
+ throw new Error(
1441
+ `'subtle.generateKey()' is not implemented for ${algorithm.name}.
1442
+ Unrecognized algorithm name`,
1443
+ );
1444
+ }
1445
+
1446
+ return result;
1447
+ }
1448
+
1449
+ async importKey(
1450
+ format: ImportFormat,
1451
+ data: BufferLike | BinaryLike | JWK,
1452
+ algorithm: SubtleAlgorithm | AnyAlgorithm,
1453
+ extractable: boolean,
1454
+ keyUsages: KeyUsage[],
1455
+ ): Promise<CryptoKey> {
1456
+ const normalizedAlgorithm = normalizeAlgorithm(algorithm, 'importKey');
1457
+ let result: CryptoKey;
1458
+ switch (normalizedAlgorithm.name) {
1459
+ case 'RSASSA-PKCS1-v1_5':
1460
+ // Fall through
1461
+ case 'RSA-PSS':
1462
+ // Fall through
1463
+ case 'RSA-OAEP':
1464
+ result = rsaImportKey(
1465
+ format,
1466
+ data as BufferLike | JWK,
1467
+ normalizedAlgorithm,
1468
+ extractable,
1469
+ keyUsages,
1470
+ );
1471
+ break;
1472
+ case 'ECDSA':
1473
+ // Fall through
1474
+ case 'ECDH':
1475
+ result = ecImportKey(
1476
+ format,
1477
+ data,
1478
+ normalizedAlgorithm,
1479
+ extractable,
1480
+ keyUsages,
1481
+ );
1482
+ break;
1483
+ case 'HMAC':
1484
+ result = await hmacImportKey(
1485
+ normalizedAlgorithm,
1486
+ format,
1487
+ data as BufferLike | JWK,
1488
+ extractable,
1489
+ keyUsages,
1490
+ );
1491
+ break;
1492
+ case 'AES-CTR':
1493
+ // Fall through
1494
+ case 'AES-CBC':
1495
+ // Fall through
1496
+ case 'AES-GCM':
1497
+ // Fall through
1498
+ case 'AES-KW':
1499
+ result = await aesImportKey(
1500
+ normalizedAlgorithm,
1501
+ format,
1502
+ data as BufferLike | JWK,
1503
+ extractable,
1504
+ keyUsages,
1505
+ );
1506
+ break;
1507
+ case 'PBKDF2':
1508
+ result = await importGenericSecretKey(
1509
+ normalizedAlgorithm,
1510
+ format,
1511
+ data as BufferLike | BinaryLike,
1512
+ extractable,
1513
+ keyUsages,
1514
+ );
1515
+ break;
1516
+ case 'Ed25519':
1517
+ // Fall through
1518
+ case 'Ed448':
1519
+ result = edImportKey(
1520
+ format,
1521
+ data as BufferLike,
1522
+ normalizedAlgorithm,
1523
+ extractable,
1524
+ keyUsages,
1525
+ );
1526
+ break;
1527
+ case 'ML-DSA-44':
1528
+ // Fall through
1529
+ case 'ML-DSA-65':
1530
+ // Fall through
1531
+ case 'ML-DSA-87':
1532
+ result = mldsaImportKey(
1533
+ format,
1534
+ data as BufferLike,
1535
+ normalizedAlgorithm,
1536
+ extractable,
1537
+ keyUsages,
1538
+ );
1539
+ break;
1540
+ default:
1541
+ throw new Error(
1542
+ `"subtle.importKey()" is not implemented for ${normalizedAlgorithm.name}`,
1543
+ );
1544
+ }
1545
+
1546
+ if (
1547
+ (result.type === 'secret' || result.type === 'private') &&
1548
+ result.usages.length === 0
1549
+ ) {
1550
+ throw new Error(
1551
+ `Usages cannot be empty when importing a ${result.type} key.`,
1552
+ );
1553
+ }
1554
+
1555
+ return result;
1556
+ }
1557
+
1558
+ async sign(
1559
+ algorithm: SubtleAlgorithm,
1560
+ key: CryptoKey,
1561
+ data: BufferLike,
1562
+ ): Promise<ArrayBuffer> {
1563
+ return signVerify(algorithm, key, data) as ArrayBuffer;
1564
+ }
1565
+
1566
+ async verify(
1567
+ algorithm: SubtleAlgorithm,
1568
+ key: CryptoKey,
1569
+ signature: BufferLike,
1570
+ data: BufferLike,
1571
+ ): Promise<ArrayBuffer> {
1572
+ return signVerify(algorithm, key, data, signature) as ArrayBuffer;
1573
+ }
1574
+ }
1575
+
1576
+ export const subtle = new Subtle();