react-native-quick-crypto 1.0.19 → 1.1.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 (561) hide show
  1. package/QuickCrypto.podspec +12 -38
  2. package/README.md +2 -0
  3. package/android/CMakeLists.txt +3 -0
  4. package/android/build.gradle +5 -1
  5. package/cpp/argon2/HybridArgon2.cpp +10 -3
  6. package/cpp/blake3/HybridBlake3.cpp +5 -3
  7. package/cpp/cipher/CCMCipher.cpp +29 -16
  8. package/cpp/cipher/CCMCipher.hpp +2 -4
  9. package/cpp/cipher/ChaCha20Cipher.cpp +14 -18
  10. package/cpp/cipher/ChaCha20Cipher.hpp +2 -4
  11. package/cpp/cipher/ChaCha20Poly1305Cipher.cpp +34 -23
  12. package/cpp/cipher/ChaCha20Poly1305Cipher.hpp +2 -4
  13. package/cpp/cipher/GCMCipher.cpp +14 -15
  14. package/cpp/cipher/HybridCipher.cpp +39 -36
  15. package/cpp/cipher/HybridCipher.hpp +17 -1
  16. package/cpp/cipher/HybridRsaCipher.cpp +74 -29
  17. package/cpp/cipher/OCBCipher.cpp +4 -3
  18. package/cpp/cipher/XChaCha20Poly1305Cipher.cpp +14 -13
  19. package/cpp/cipher/XSalsa20Cipher.cpp +72 -6
  20. package/cpp/cipher/XSalsa20Cipher.hpp +25 -3
  21. package/cpp/cipher/XSalsa20Poly1305Cipher.cpp +21 -25
  22. package/cpp/dh/HybridDiffieHellman.cpp +29 -0
  23. package/cpp/ec/HybridEcKeyPair.cpp +35 -33
  24. package/cpp/ec/HybridEcKeyPair.hpp +3 -7
  25. package/cpp/ecdh/HybridECDH.cpp +23 -0
  26. package/cpp/ed25519/HybridEdKeyPair.cpp +73 -117
  27. package/cpp/ed25519/HybridEdKeyPair.hpp +5 -9
  28. package/cpp/hash/HybridHash.cpp +5 -7
  29. package/cpp/hkdf/HybridHkdf.cpp +6 -4
  30. package/cpp/hmac/HybridHmac.cpp +4 -6
  31. package/cpp/kmac/HybridKmac.cpp +4 -4
  32. package/cpp/mldsa/HybridMlDsaKeyPair.cpp +37 -49
  33. package/cpp/mlkem/HybridMlKemKeyPair.cpp +39 -43
  34. package/cpp/pbkdf2/HybridPbkdf2.cpp +7 -8
  35. package/cpp/rsa/HybridRsaKeyPair.cpp +5 -8
  36. package/cpp/rsa/HybridRsaKeyPair.hpp +4 -7
  37. package/cpp/scrypt/HybridScrypt.cpp +6 -4
  38. package/cpp/sign/HybridSignHandle.cpp +25 -68
  39. package/cpp/sign/HybridVerifyHandle.cpp +23 -60
  40. package/cpp/utils/HybridUtils.cpp +213 -111
  41. package/cpp/utils/HybridUtils.hpp +9 -2
  42. package/cpp/utils/QuickCryptoUtils.hpp +72 -0
  43. package/deps/simdutf/LICENSE-APACHE +201 -0
  44. package/deps/simdutf/LICENSE-MIT +18 -0
  45. package/deps/simdutf/README.md +2782 -0
  46. package/deps/simdutf/include/simdutf/avx512.h +79 -0
  47. package/deps/simdutf/include/simdutf/base64_implementation.h +158 -0
  48. package/deps/simdutf/include/simdutf/base64_tables.h +887 -0
  49. package/deps/simdutf/include/simdutf/common_defs.h +186 -0
  50. package/deps/simdutf/include/simdutf/compiler_check.h +50 -0
  51. package/deps/simdutf/include/simdutf/constexpr_ptr.h +138 -0
  52. package/deps/simdutf/include/simdutf/encoding_types.h +189 -0
  53. package/deps/simdutf/include/simdutf/error.h +126 -0
  54. package/deps/simdutf/include/simdutf/implementation.h +7081 -0
  55. package/deps/simdutf/include/simdutf/internal/isadetection.h +325 -0
  56. package/deps/simdutf/include/simdutf/portability.h +285 -0
  57. package/deps/simdutf/include/simdutf/scalar/ascii.h +86 -0
  58. package/deps/simdutf/include/simdutf/scalar/atomic_util.h +105 -0
  59. package/deps/simdutf/include/simdutf/scalar/base64.h +911 -0
  60. package/deps/simdutf/include/simdutf/scalar/latin1.h +26 -0
  61. package/deps/simdutf/include/simdutf/scalar/latin1_to_utf16/latin1_to_utf16.h +52 -0
  62. package/deps/simdutf/include/simdutf/scalar/latin1_to_utf32/latin1_to_utf32.h +27 -0
  63. package/deps/simdutf/include/simdutf/scalar/latin1_to_utf8/latin1_to_utf8.h +191 -0
  64. package/deps/simdutf/include/simdutf/scalar/swap_bytes.h +35 -0
  65. package/deps/simdutf/include/simdutf/scalar/utf16.h +226 -0
  66. package/deps/simdutf/include/simdutf/scalar/utf16_to_latin1/utf16_to_latin1.h +108 -0
  67. package/deps/simdutf/include/simdutf/scalar/utf16_to_latin1/valid_utf16_to_latin1.h +40 -0
  68. package/deps/simdutf/include/simdutf/scalar/utf16_to_utf32/utf16_to_utf32.h +86 -0
  69. package/deps/simdutf/include/simdutf/scalar/utf16_to_utf32/valid_utf16_to_utf32.h +44 -0
  70. package/deps/simdutf/include/simdutf/scalar/utf16_to_utf8/utf16_to_utf8.h +295 -0
  71. package/deps/simdutf/include/simdutf/scalar/utf16_to_utf8/valid_utf16_to_utf8.h +91 -0
  72. package/deps/simdutf/include/simdutf/scalar/utf32.h +82 -0
  73. package/deps/simdutf/include/simdutf/scalar/utf32_to_latin1/utf32_to_latin1.h +68 -0
  74. package/deps/simdutf/include/simdutf/scalar/utf32_to_latin1/valid_utf32_to_latin1.h +67 -0
  75. package/deps/simdutf/include/simdutf/scalar/utf32_to_utf16/utf32_to_utf16.h +84 -0
  76. package/deps/simdutf/include/simdutf/scalar/utf32_to_utf16/valid_utf32_to_utf16.h +44 -0
  77. package/deps/simdutf/include/simdutf/scalar/utf32_to_utf8/utf32_to_utf8.h +142 -0
  78. package/deps/simdutf/include/simdutf/scalar/utf32_to_utf8/valid_utf32_to_utf8.h +72 -0
  79. package/deps/simdutf/include/simdutf/scalar/utf8.h +326 -0
  80. package/deps/simdutf/include/simdutf/scalar/utf8_to_latin1/utf8_to_latin1.h +225 -0
  81. package/deps/simdutf/include/simdutf/scalar/utf8_to_latin1/valid_utf8_to_latin1.h +87 -0
  82. package/deps/simdutf/include/simdutf/scalar/utf8_to_utf16/utf8_to_utf16.h +342 -0
  83. package/deps/simdutf/include/simdutf/scalar/utf8_to_utf16/valid_utf8_to_utf16.h +106 -0
  84. package/deps/simdutf/include/simdutf/scalar/utf8_to_utf32/utf8_to_utf32.h +299 -0
  85. package/deps/simdutf/include/simdutf/scalar/utf8_to_utf32/valid_utf8_to_utf32.h +83 -0
  86. package/deps/simdutf/include/simdutf/simdutf_version.h +26 -0
  87. package/deps/simdutf/include/simdutf.h +26 -0
  88. package/deps/simdutf/include/simdutf_c.h +342 -0
  89. package/deps/simdutf/src/arm64/arm_base64.cpp +791 -0
  90. package/deps/simdutf/src/arm64/arm_convert_latin1_to_utf16.cpp +24 -0
  91. package/deps/simdutf/src/arm64/arm_convert_latin1_to_utf32.cpp +24 -0
  92. package/deps/simdutf/src/arm64/arm_convert_latin1_to_utf8.cpp +70 -0
  93. package/deps/simdutf/src/arm64/arm_convert_utf16_to_latin1.cpp +61 -0
  94. package/deps/simdutf/src/arm64/arm_convert_utf16_to_utf32.cpp +185 -0
  95. package/deps/simdutf/src/arm64/arm_convert_utf16_to_utf8.cpp +780 -0
  96. package/deps/simdutf/src/arm64/arm_convert_utf32_to_latin1.cpp +60 -0
  97. package/deps/simdutf/src/arm64/arm_convert_utf32_to_utf16.cpp +208 -0
  98. package/deps/simdutf/src/arm64/arm_convert_utf32_to_utf8.cpp +505 -0
  99. package/deps/simdutf/src/arm64/arm_convert_utf8_to_latin1.cpp +69 -0
  100. package/deps/simdutf/src/arm64/arm_convert_utf8_to_utf16.cpp +313 -0
  101. package/deps/simdutf/src/arm64/arm_convert_utf8_to_utf32.cpp +179 -0
  102. package/deps/simdutf/src/arm64/arm_find.cpp +199 -0
  103. package/deps/simdutf/src/arm64/arm_utf16fix.cpp +185 -0
  104. package/deps/simdutf/src/arm64/arm_validate_utf16.cpp +165 -0
  105. package/deps/simdutf/src/arm64/arm_validate_utf32le.cpp +65 -0
  106. package/deps/simdutf/src/arm64/implementation.cpp +1442 -0
  107. package/deps/simdutf/src/encoding_types.cpp +67 -0
  108. package/deps/simdutf/src/error.cpp +3 -0
  109. package/deps/simdutf/src/fallback/implementation.cpp +589 -0
  110. package/deps/simdutf/src/generic/ascii_validation.h +50 -0
  111. package/deps/simdutf/src/generic/base64.h +233 -0
  112. package/deps/simdutf/src/generic/base64lengths.h +63 -0
  113. package/deps/simdutf/src/generic/buf_block_reader.h +109 -0
  114. package/deps/simdutf/src/generic/find.h +75 -0
  115. package/deps/simdutf/src/generic/utf16/change_endianness.h +24 -0
  116. package/deps/simdutf/src/generic/utf16/count_code_points_bytemask.h +58 -0
  117. package/deps/simdutf/src/generic/utf16/to_well_formed.h +93 -0
  118. package/deps/simdutf/src/generic/utf16/utf32_length_from_utf16.h +15 -0
  119. package/deps/simdutf/src/generic/utf16/utf8_length_from_utf16.h +35 -0
  120. package/deps/simdutf/src/generic/utf16/utf8_length_from_utf16_bytemask.h +199 -0
  121. package/deps/simdutf/src/generic/utf16.h +73 -0
  122. package/deps/simdutf/src/generic/utf32.h +136 -0
  123. package/deps/simdutf/src/generic/utf8/utf16_length_from_utf8_bytemask.h +53 -0
  124. package/deps/simdutf/src/generic/utf8.h +92 -0
  125. package/deps/simdutf/src/generic/utf8_to_latin1/utf8_to_latin1.h +316 -0
  126. package/deps/simdutf/src/generic/utf8_to_latin1/valid_utf8_to_latin1.h +78 -0
  127. package/deps/simdutf/src/generic/utf8_to_utf16/utf8_to_utf16.h +332 -0
  128. package/deps/simdutf/src/generic/utf8_to_utf16/valid_utf8_to_utf16.h +74 -0
  129. package/deps/simdutf/src/generic/utf8_to_utf32/utf8_to_utf32.h +318 -0
  130. package/deps/simdutf/src/generic/utf8_to_utf32/valid_utf8_to_utf32.h +42 -0
  131. package/deps/simdutf/src/generic/utf8_validation/utf8_lookup4_algorithm.h +223 -0
  132. package/deps/simdutf/src/generic/utf8_validation/utf8_validator.h +84 -0
  133. package/deps/simdutf/src/generic/validate_utf16.h +164 -0
  134. package/deps/simdutf/src/generic/validate_utf32.h +99 -0
  135. package/deps/simdutf/src/haswell/avx2_base64.cpp +837 -0
  136. package/deps/simdutf/src/haswell/avx2_convert_latin1_to_utf16.cpp +28 -0
  137. package/deps/simdutf/src/haswell/avx2_convert_latin1_to_utf32.cpp +20 -0
  138. package/deps/simdutf/src/haswell/avx2_convert_latin1_to_utf8.cpp +83 -0
  139. package/deps/simdutf/src/haswell/avx2_convert_utf16_to_latin1.cpp +83 -0
  140. package/deps/simdutf/src/haswell/avx2_convert_utf16_to_utf32.cpp +210 -0
  141. package/deps/simdutf/src/haswell/avx2_convert_utf16_to_utf8.cpp +602 -0
  142. package/deps/simdutf/src/haswell/avx2_convert_utf32_to_latin1.cpp +116 -0
  143. package/deps/simdutf/src/haswell/avx2_convert_utf32_to_utf16.cpp +164 -0
  144. package/deps/simdutf/src/haswell/avx2_convert_utf32_to_utf8.cpp +569 -0
  145. package/deps/simdutf/src/haswell/avx2_convert_utf8_to_latin1.cpp +60 -0
  146. package/deps/simdutf/src/haswell/avx2_convert_utf8_to_utf16.cpp +195 -0
  147. package/deps/simdutf/src/haswell/avx2_convert_utf8_to_utf32.cpp +135 -0
  148. package/deps/simdutf/src/haswell/avx2_utf16fix.cpp +173 -0
  149. package/deps/simdutf/src/haswell/avx2_validate_utf16.cpp +17 -0
  150. package/deps/simdutf/src/haswell/implementation.cpp +1447 -0
  151. package/deps/simdutf/src/icelake/icelake_ascii_validation.inl.cpp +19 -0
  152. package/deps/simdutf/src/icelake/icelake_base64.inl.cpp +630 -0
  153. package/deps/simdutf/src/icelake/icelake_common.inl.cpp +37 -0
  154. package/deps/simdutf/src/icelake/icelake_convert_latin1_to_utf16.inl.cpp +36 -0
  155. package/deps/simdutf/src/icelake/icelake_convert_latin1_to_utf32.inl.cpp +23 -0
  156. package/deps/simdutf/src/icelake/icelake_convert_latin1_to_utf8.inl.cpp +107 -0
  157. package/deps/simdutf/src/icelake/icelake_convert_utf16_to_latin1.inl.cpp +103 -0
  158. package/deps/simdutf/src/icelake/icelake_convert_utf16_to_utf32.inl.cpp +136 -0
  159. package/deps/simdutf/src/icelake/icelake_convert_utf16_to_utf8.inl.cpp +206 -0
  160. package/deps/simdutf/src/icelake/icelake_convert_utf32_to_latin1.inl.cpp +74 -0
  161. package/deps/simdutf/src/icelake/icelake_convert_utf32_to_utf16.inl.cpp +338 -0
  162. package/deps/simdutf/src/icelake/icelake_convert_utf32_to_utf8.inl.cpp +574 -0
  163. package/deps/simdutf/src/icelake/icelake_convert_utf8_to_latin1.inl.cpp +104 -0
  164. package/deps/simdutf/src/icelake/icelake_convert_utf8_to_utf16.inl.cpp +75 -0
  165. package/deps/simdutf/src/icelake/icelake_convert_valid_utf8_to_latin1.inl.cpp +69 -0
  166. package/deps/simdutf/src/icelake/icelake_find.inl.cpp +146 -0
  167. package/deps/simdutf/src/icelake/icelake_from_utf8.inl.cpp +266 -0
  168. package/deps/simdutf/src/icelake/icelake_from_valid_utf8.inl.cpp +136 -0
  169. package/deps/simdutf/src/icelake/icelake_macros.inl.cpp +143 -0
  170. package/deps/simdutf/src/icelake/icelake_utf16fix.cpp +138 -0
  171. package/deps/simdutf/src/icelake/icelake_utf32_validation.inl.cpp +63 -0
  172. package/deps/simdutf/src/icelake/icelake_utf8_common.inl.cpp +753 -0
  173. package/deps/simdutf/src/icelake/icelake_utf8_length_from_utf16.inl.cpp +269 -0
  174. package/deps/simdutf/src/icelake/icelake_utf8_validation.inl.cpp +116 -0
  175. package/deps/simdutf/src/icelake/implementation.cpp +1903 -0
  176. package/deps/simdutf/src/implementation.cpp +2526 -0
  177. package/deps/simdutf/src/lasx/implementation.cpp +1531 -0
  178. package/deps/simdutf/src/lasx/lasx_base64.cpp +695 -0
  179. package/deps/simdutf/src/lasx/lasx_convert_latin1_to_utf16.cpp +76 -0
  180. package/deps/simdutf/src/lasx/lasx_convert_latin1_to_utf32.cpp +55 -0
  181. package/deps/simdutf/src/lasx/lasx_convert_latin1_to_utf8.cpp +65 -0
  182. package/deps/simdutf/src/lasx/lasx_convert_utf16_to_latin1.cpp +64 -0
  183. package/deps/simdutf/src/lasx/lasx_convert_utf16_to_utf32.cpp +183 -0
  184. package/deps/simdutf/src/lasx/lasx_convert_utf16_to_utf8.cpp +550 -0
  185. package/deps/simdutf/src/lasx/lasx_convert_utf32_to_latin1.cpp +73 -0
  186. package/deps/simdutf/src/lasx/lasx_convert_utf32_to_utf16.cpp +218 -0
  187. package/deps/simdutf/src/lasx/lasx_convert_utf32_to_utf8.cpp +589 -0
  188. package/deps/simdutf/src/lasx/lasx_convert_utf8_to_latin1.cpp +72 -0
  189. package/deps/simdutf/src/lasx/lasx_convert_utf8_to_utf16.cpp +296 -0
  190. package/deps/simdutf/src/lasx/lasx_convert_utf8_to_utf32.cpp +190 -0
  191. package/deps/simdutf/src/lasx/lasx_find.cpp +64 -0
  192. package/deps/simdutf/src/lasx/lasx_validate_utf16.cpp +13 -0
  193. package/deps/simdutf/src/lasx/lasx_validate_utf32le.cpp +84 -0
  194. package/deps/simdutf/src/lsx/implementation.cpp +1417 -0
  195. package/deps/simdutf/src/lsx/lsx_base64.cpp +675 -0
  196. package/deps/simdutf/src/lsx/lsx_convert_latin1_to_utf16.cpp +39 -0
  197. package/deps/simdutf/src/lsx/lsx_convert_latin1_to_utf32.cpp +27 -0
  198. package/deps/simdutf/src/lsx/lsx_convert_latin1_to_utf8.cpp +56 -0
  199. package/deps/simdutf/src/lsx/lsx_convert_utf16_to_latin1.cpp +64 -0
  200. package/deps/simdutf/src/lsx/lsx_convert_utf16_to_utf32.cpp +133 -0
  201. package/deps/simdutf/src/lsx/lsx_convert_utf16_to_utf8.cpp +518 -0
  202. package/deps/simdutf/src/lsx/lsx_convert_utf32_to_latin1.cpp +66 -0
  203. package/deps/simdutf/src/lsx/lsx_convert_utf32_to_utf16.cpp +155 -0
  204. package/deps/simdutf/src/lsx/lsx_convert_utf32_to_utf8.cpp +459 -0
  205. package/deps/simdutf/src/lsx/lsx_convert_utf8_to_latin1.cpp +75 -0
  206. package/deps/simdutf/src/lsx/lsx_convert_utf8_to_utf16.cpp +291 -0
  207. package/deps/simdutf/src/lsx/lsx_convert_utf8_to_utf32.cpp +179 -0
  208. package/deps/simdutf/src/lsx/lsx_find.cpp +60 -0
  209. package/deps/simdutf/src/lsx/lsx_validate_utf16.cpp +13 -0
  210. package/deps/simdutf/src/lsx/lsx_validate_utf32le.cpp +68 -0
  211. package/deps/simdutf/src/ppc64/implementation.cpp +992 -0
  212. package/deps/simdutf/src/ppc64/ppc64_base64.cpp +480 -0
  213. package/deps/simdutf/src/ppc64/ppc64_base64_internal_tests.cpp +401 -0
  214. package/deps/simdutf/src/ppc64/ppc64_convert_latin1_to_utf16.cpp +12 -0
  215. package/deps/simdutf/src/ppc64/ppc64_convert_latin1_to_utf32.cpp +12 -0
  216. package/deps/simdutf/src/ppc64/ppc64_convert_latin1_to_utf8.cpp +149 -0
  217. package/deps/simdutf/src/ppc64/ppc64_convert_utf16_to_latin1.cpp +67 -0
  218. package/deps/simdutf/src/ppc64/ppc64_convert_utf16_to_utf32.cpp +87 -0
  219. package/deps/simdutf/src/ppc64/ppc64_convert_utf16_to_utf8.cpp +296 -0
  220. package/deps/simdutf/src/ppc64/ppc64_convert_utf32_to_latin1.cpp +57 -0
  221. package/deps/simdutf/src/ppc64/ppc64_convert_utf32_to_utf16.cpp +117 -0
  222. package/deps/simdutf/src/ppc64/ppc64_convert_utf32_to_utf8.cpp +166 -0
  223. package/deps/simdutf/src/ppc64/ppc64_convert_utf8_to_latin1.cpp +69 -0
  224. package/deps/simdutf/src/ppc64/ppc64_convert_utf8_to_utf16.cpp +211 -0
  225. package/deps/simdutf/src/ppc64/ppc64_convert_utf8_to_utf32.cpp +153 -0
  226. package/deps/simdutf/src/ppc64/ppc64_utf16_to_utf8_tables.h +1011 -0
  227. package/deps/simdutf/src/ppc64/ppc64_utf8_length_from_latin1.cpp +37 -0
  228. package/deps/simdutf/src/ppc64/ppc64_validate_utf16.cpp +19 -0
  229. package/deps/simdutf/src/ppc64/templates.cpp +91 -0
  230. package/deps/simdutf/src/rvv/implementation.cpp +138 -0
  231. package/deps/simdutf/src/rvv/rvv_find.cpp +27 -0
  232. package/deps/simdutf/src/rvv/rvv_helpers.inl.cpp +23 -0
  233. package/deps/simdutf/src/rvv/rvv_latin1_to.inl.cpp +71 -0
  234. package/deps/simdutf/src/rvv/rvv_length_from.inl.cpp +164 -0
  235. package/deps/simdutf/src/rvv/rvv_utf16_to.inl.cpp +399 -0
  236. package/deps/simdutf/src/rvv/rvv_utf16fix.cpp +110 -0
  237. package/deps/simdutf/src/rvv/rvv_utf32_to.inl.cpp +307 -0
  238. package/deps/simdutf/src/rvv/rvv_utf8_to.inl.cpp +435 -0
  239. package/deps/simdutf/src/rvv/rvv_validate.inl.cpp +275 -0
  240. package/deps/simdutf/src/simdutf/arm64/begin.h +2 -0
  241. package/deps/simdutf/src/simdutf/arm64/bitmanipulation.h +34 -0
  242. package/deps/simdutf/src/simdutf/arm64/end.h +2 -0
  243. package/deps/simdutf/src/simdutf/arm64/implementation.h +307 -0
  244. package/deps/simdutf/src/simdutf/arm64/intrinsics.h +10 -0
  245. package/deps/simdutf/src/simdutf/arm64/simd.h +547 -0
  246. package/deps/simdutf/src/simdutf/arm64/simd16-inl.h +403 -0
  247. package/deps/simdutf/src/simdutf/arm64/simd32-inl.h +129 -0
  248. package/deps/simdutf/src/simdutf/arm64/simd64-inl.h +28 -0
  249. package/deps/simdutf/src/simdutf/arm64.h +43 -0
  250. package/deps/simdutf/src/simdutf/fallback/begin.h +1 -0
  251. package/deps/simdutf/src/simdutf/fallback/bitmanipulation.h +13 -0
  252. package/deps/simdutf/src/simdutf/fallback/end.h +1 -0
  253. package/deps/simdutf/src/simdutf/fallback/implementation.h +331 -0
  254. package/deps/simdutf/src/simdutf/fallback.h +42 -0
  255. package/deps/simdutf/src/simdutf/haswell/begin.h +15 -0
  256. package/deps/simdutf/src/simdutf/haswell/bitmanipulation.h +35 -0
  257. package/deps/simdutf/src/simdutf/haswell/end.h +13 -0
  258. package/deps/simdutf/src/simdutf/haswell/implementation.h +338 -0
  259. package/deps/simdutf/src/simdutf/haswell/intrinsics.h +67 -0
  260. package/deps/simdutf/src/simdutf/haswell/simd.h +363 -0
  261. package/deps/simdutf/src/simdutf/haswell/simd16-inl.h +261 -0
  262. package/deps/simdutf/src/simdutf/haswell/simd32-inl.h +111 -0
  263. package/deps/simdutf/src/simdutf/haswell/simd64-inl.h +34 -0
  264. package/deps/simdutf/src/simdutf/haswell.h +63 -0
  265. package/deps/simdutf/src/simdutf/icelake/begin.h +14 -0
  266. package/deps/simdutf/src/simdutf/icelake/bitmanipulation.h +44 -0
  267. package/deps/simdutf/src/simdutf/icelake/end.h +12 -0
  268. package/deps/simdutf/src/simdutf/icelake/implementation.h +346 -0
  269. package/deps/simdutf/src/simdutf/icelake/intrinsics.h +138 -0
  270. package/deps/simdutf/src/simdutf/icelake/simd.h +17 -0
  271. package/deps/simdutf/src/simdutf/icelake/simd16-inl.h +90 -0
  272. package/deps/simdutf/src/simdutf/icelake/simd32-inl.h +47 -0
  273. package/deps/simdutf/src/simdutf/icelake.h +81 -0
  274. package/deps/simdutf/src/simdutf/lasx/begin.h +8 -0
  275. package/deps/simdutf/src/simdutf/lasx/bitmanipulation.h +25 -0
  276. package/deps/simdutf/src/simdutf/lasx/end.h +8 -0
  277. package/deps/simdutf/src/simdutf/lasx/implementation.h +310 -0
  278. package/deps/simdutf/src/simdutf/lasx/intrinsics.h +319 -0
  279. package/deps/simdutf/src/simdutf/lasx/simd.h +551 -0
  280. package/deps/simdutf/src/simdutf/lasx/simd16-inl.h +234 -0
  281. package/deps/simdutf/src/simdutf/lasx/simd32-inl.h +74 -0
  282. package/deps/simdutf/src/simdutf/lasx/simd64-inl.h +52 -0
  283. package/deps/simdutf/src/simdutf/lasx.h +49 -0
  284. package/deps/simdutf/src/simdutf/lsx/begin.h +2 -0
  285. package/deps/simdutf/src/simdutf/lsx/bitmanipulation.h +25 -0
  286. package/deps/simdutf/src/simdutf/lsx/end.h +2 -0
  287. package/deps/simdutf/src/simdutf/lsx/implementation.h +309 -0
  288. package/deps/simdutf/src/simdutf/lsx/intrinsics.h +196 -0
  289. package/deps/simdutf/src/simdutf/lsx/simd.h +421 -0
  290. package/deps/simdutf/src/simdutf/lsx/simd16-inl.h +242 -0
  291. package/deps/simdutf/src/simdutf/lsx/simd32-inl.h +69 -0
  292. package/deps/simdutf/src/simdutf/lsx/simd64-inl.h +50 -0
  293. package/deps/simdutf/src/simdutf/lsx.h +52 -0
  294. package/deps/simdutf/src/simdutf/ppc64/begin.h +1 -0
  295. package/deps/simdutf/src/simdutf/ppc64/bitmanipulation.h +29 -0
  296. package/deps/simdutf/src/simdutf/ppc64/end.h +1 -0
  297. package/deps/simdutf/src/simdutf/ppc64/implementation.h +348 -0
  298. package/deps/simdutf/src/simdutf/ppc64/intrinsics.h +19 -0
  299. package/deps/simdutf/src/simdutf/ppc64/simd.h +177 -0
  300. package/deps/simdutf/src/simdutf/ppc64/simd16-inl.h +327 -0
  301. package/deps/simdutf/src/simdutf/ppc64/simd32-inl.h +247 -0
  302. package/deps/simdutf/src/simdutf/ppc64/simd8-inl.h +618 -0
  303. package/deps/simdutf/src/simdutf/ppc64.h +40 -0
  304. package/deps/simdutf/src/simdutf/rvv/begin.h +7 -0
  305. package/deps/simdutf/src/simdutf/rvv/end.h +7 -0
  306. package/deps/simdutf/src/simdutf/rvv/implementation.h +321 -0
  307. package/deps/simdutf/src/simdutf/rvv/intrinsics.h +131 -0
  308. package/deps/simdutf/src/simdutf/rvv.h +41 -0
  309. package/deps/simdutf/src/simdutf/westmere/begin.h +8 -0
  310. package/deps/simdutf/src/simdutf/westmere/bitmanipulation.h +37 -0
  311. package/deps/simdutf/src/simdutf/westmere/end.h +8 -0
  312. package/deps/simdutf/src/simdutf/westmere/implementation.h +338 -0
  313. package/deps/simdutf/src/simdutf/westmere/intrinsics.h +38 -0
  314. package/deps/simdutf/src/simdutf/westmere/simd.h +379 -0
  315. package/deps/simdutf/src/simdutf/westmere/simd16-inl.h +242 -0
  316. package/deps/simdutf/src/simdutf/westmere/simd32-inl.h +151 -0
  317. package/deps/simdutf/src/simdutf/westmere/simd64-inl.h +33 -0
  318. package/deps/simdutf/src/simdutf/westmere.h +59 -0
  319. package/deps/simdutf/src/simdutf.cpp +152 -0
  320. package/deps/simdutf/src/simdutf_c.cpp +525 -0
  321. package/deps/simdutf/src/tables/utf16_to_utf8_tables.h +768 -0
  322. package/deps/simdutf/src/tables/utf32_to_utf16_tables.h +53 -0
  323. package/deps/simdutf/src/tables/utf8_to_utf16_tables.h +826 -0
  324. package/deps/simdutf/src/westmere/implementation.cpp +1479 -0
  325. package/deps/simdutf/src/westmere/internal/loader.cpp +7 -0
  326. package/deps/simdutf/src/westmere/internal/write_v_u16_11bits_to_utf8.cpp +66 -0
  327. package/deps/simdutf/src/westmere/sse_base64.cpp +672 -0
  328. package/deps/simdutf/src/westmere/sse_convert_latin1_to_utf16.cpp +21 -0
  329. package/deps/simdutf/src/westmere/sse_convert_latin1_to_utf32.cpp +31 -0
  330. package/deps/simdutf/src/westmere/sse_convert_latin1_to_utf8.cpp +71 -0
  331. package/deps/simdutf/src/westmere/sse_convert_utf16_to_latin1.cpp +70 -0
  332. package/deps/simdutf/src/westmere/sse_convert_utf16_to_utf32.cpp +206 -0
  333. package/deps/simdutf/src/westmere/sse_convert_utf16_to_utf8.cpp +504 -0
  334. package/deps/simdutf/src/westmere/sse_convert_utf32_to_latin1.cpp +82 -0
  335. package/deps/simdutf/src/westmere/sse_convert_utf32_to_utf16.cpp +209 -0
  336. package/deps/simdutf/src/westmere/sse_convert_utf32_to_utf8.cpp +589 -0
  337. package/deps/simdutf/src/westmere/sse_convert_utf8_to_latin1.cpp +58 -0
  338. package/deps/simdutf/src/westmere/sse_convert_utf8_to_utf16.cpp +197 -0
  339. package/deps/simdutf/src/westmere/sse_convert_utf8_to_utf32.cpp +141 -0
  340. package/deps/simdutf/src/westmere/sse_utf16fix.cpp +82 -0
  341. package/deps/simdutf/src/westmere/sse_validate_utf16.cpp +17 -0
  342. package/lib/commonjs/argon2.js +51 -2
  343. package/lib/commonjs/argon2.js.map +1 -1
  344. package/lib/commonjs/cipher.js +109 -11
  345. package/lib/commonjs/cipher.js.map +1 -1
  346. package/lib/commonjs/dsa.js +8 -2
  347. package/lib/commonjs/dsa.js.map +1 -1
  348. package/lib/commonjs/hash.js +15 -5
  349. package/lib/commonjs/hash.js.map +1 -1
  350. package/lib/commonjs/hkdf.js +33 -6
  351. package/lib/commonjs/hkdf.js.map +1 -1
  352. package/lib/commonjs/hmac.js +15 -5
  353. package/lib/commonjs/hmac.js.map +1 -1
  354. package/lib/commonjs/keys/publicCipher.js +10 -4
  355. package/lib/commonjs/keys/publicCipher.js.map +1 -1
  356. package/lib/commonjs/random.js +11 -2
  357. package/lib/commonjs/random.js.map +1 -1
  358. package/lib/commonjs/rsa.js +12 -5
  359. package/lib/commonjs/rsa.js.map +1 -1
  360. package/lib/commonjs/scrypt.js +47 -6
  361. package/lib/commonjs/scrypt.js.map +1 -1
  362. package/lib/commonjs/subtle.js +76 -5
  363. package/lib/commonjs/subtle.js.map +1 -1
  364. package/lib/commonjs/utils/cipher.js +18 -7
  365. package/lib/commonjs/utils/cipher.js.map +1 -1
  366. package/lib/commonjs/utils/conversion.js +33 -9
  367. package/lib/commonjs/utils/conversion.js.map +1 -1
  368. package/lib/commonjs/utils/timingSafeEqual.js +7 -2
  369. package/lib/commonjs/utils/timingSafeEqual.js.map +1 -1
  370. package/lib/commonjs/x509certificate.js +6 -6
  371. package/lib/commonjs/x509certificate.js.map +1 -1
  372. package/lib/module/argon2.js +51 -2
  373. package/lib/module/argon2.js.map +1 -1
  374. package/lib/module/cipher.js +109 -11
  375. package/lib/module/cipher.js.map +1 -1
  376. package/lib/module/dsa.js +8 -2
  377. package/lib/module/dsa.js.map +1 -1
  378. package/lib/module/hash.js +15 -5
  379. package/lib/module/hash.js.map +1 -1
  380. package/lib/module/hkdf.js +33 -6
  381. package/lib/module/hkdf.js.map +1 -1
  382. package/lib/module/hmac.js +15 -5
  383. package/lib/module/hmac.js.map +1 -1
  384. package/lib/module/keys/publicCipher.js +10 -4
  385. package/lib/module/keys/publicCipher.js.map +1 -1
  386. package/lib/module/random.js +11 -2
  387. package/lib/module/random.js.map +1 -1
  388. package/lib/module/rsa.js +11 -4
  389. package/lib/module/rsa.js.map +1 -1
  390. package/lib/module/scrypt.js +47 -6
  391. package/lib/module/scrypt.js.map +1 -1
  392. package/lib/module/subtle.js +76 -5
  393. package/lib/module/subtle.js.map +1 -1
  394. package/lib/module/utils/cipher.js +18 -7
  395. package/lib/module/utils/cipher.js.map +1 -1
  396. package/lib/module/utils/conversion.js +33 -9
  397. package/lib/module/utils/conversion.js.map +1 -1
  398. package/lib/module/utils/timingSafeEqual.js +8 -3
  399. package/lib/module/utils/timingSafeEqual.js.map +1 -1
  400. package/lib/module/x509certificate.js +6 -6
  401. package/lib/module/x509certificate.js.map +1 -1
  402. package/lib/typescript/argon2.d.ts.map +1 -1
  403. package/lib/typescript/cipher.d.ts +2 -2
  404. package/lib/typescript/cipher.d.ts.map +1 -1
  405. package/lib/typescript/dsa.d.ts.map +1 -1
  406. package/lib/typescript/hash.d.ts +2 -2
  407. package/lib/typescript/hash.d.ts.map +1 -1
  408. package/lib/typescript/hkdf.d.ts.map +1 -1
  409. package/lib/typescript/hmac.d.ts +2 -2
  410. package/lib/typescript/hmac.d.ts.map +1 -1
  411. package/lib/typescript/index.d.ts +1 -1
  412. package/lib/typescript/index.d.ts.map +1 -1
  413. package/lib/typescript/keys/publicCipher.d.ts.map +1 -1
  414. package/lib/typescript/random.d.ts.map +1 -1
  415. package/lib/typescript/rsa.d.ts.map +1 -1
  416. package/lib/typescript/scrypt.d.ts.map +1 -1
  417. package/lib/typescript/specs/utils.nitro.d.ts +0 -2
  418. package/lib/typescript/specs/utils.nitro.d.ts.map +1 -1
  419. package/lib/typescript/subtle.d.ts.map +1 -1
  420. package/lib/typescript/utils/cipher.d.ts +13 -1
  421. package/lib/typescript/utils/cipher.d.ts.map +1 -1
  422. package/lib/typescript/utils/conversion.d.ts +9 -6
  423. package/lib/typescript/utils/conversion.d.ts.map +1 -1
  424. package/lib/typescript/utils/timingSafeEqual.d.ts.map +1 -1
  425. package/lib/typescript/x509certificate.d.ts.map +1 -1
  426. package/nitrogen/generated/shared/c++/HybridUtilsSpec.cpp +0 -2
  427. package/nitrogen/generated/shared/c++/HybridUtilsSpec.hpp +0 -3
  428. package/package.json +38 -6
  429. package/src/argon2.ts +80 -2
  430. package/src/cipher.ts +139 -15
  431. package/src/dsa.ts +11 -2
  432. package/src/hash.ts +17 -7
  433. package/src/hkdf.ts +44 -6
  434. package/src/hmac.ts +17 -7
  435. package/src/keys/publicCipher.ts +10 -4
  436. package/src/random.ts +11 -2
  437. package/src/rsa.ts +18 -4
  438. package/src/scrypt.ts +73 -6
  439. package/src/specs/utils.nitro.ts +0 -2
  440. package/src/subtle.ts +90 -8
  441. package/src/utils/cipher.ts +30 -8
  442. package/src/utils/conversion.ts +58 -20
  443. package/src/utils/timingSafeEqual.ts +8 -3
  444. package/src/x509certificate.ts +5 -6
  445. package/deps/blake3/.cargo/config.toml +0 -2
  446. package/deps/blake3/.git-blame-ignore-revs +0 -2
  447. package/deps/blake3/.github/workflows/build_b3sum.py +0 -38
  448. package/deps/blake3/.github/workflows/ci.yml +0 -491
  449. package/deps/blake3/.github/workflows/tag.yml +0 -43
  450. package/deps/blake3/.github/workflows/upload_github_release_asset.py +0 -73
  451. package/deps/blake3/CONTRIBUTING.md +0 -31
  452. package/deps/blake3/Cargo.toml +0 -135
  453. package/deps/blake3/b3sum/Cargo.lock +0 -513
  454. package/deps/blake3/b3sum/Cargo.toml +0 -26
  455. package/deps/blake3/b3sum/README.md +0 -72
  456. package/deps/blake3/b3sum/src/main.rs +0 -564
  457. package/deps/blake3/b3sum/src/unit_tests.rs +0 -235
  458. package/deps/blake3/b3sum/tests/cli_tests.rs +0 -680
  459. package/deps/blake3/b3sum/what_does_check_do.md +0 -176
  460. package/deps/blake3/benches/bench.rs +0 -623
  461. package/deps/blake3/build.rs +0 -389
  462. package/deps/blake3/c/CMakeLists.txt +0 -383
  463. package/deps/blake3/c/CMakePresets.json +0 -73
  464. package/deps/blake3/c/Makefile.testing +0 -82
  465. package/deps/blake3/c/blake3-config.cmake.in +0 -14
  466. package/deps/blake3/c/blake3_avx2.c +0 -326
  467. package/deps/blake3/c/blake3_avx2_x86-64_unix.S +0 -1815
  468. package/deps/blake3/c/blake3_avx2_x86-64_windows_gnu.S +0 -1817
  469. package/deps/blake3/c/blake3_avx2_x86-64_windows_msvc.asm +0 -1828
  470. package/deps/blake3/c/blake3_avx512.c +0 -1388
  471. package/deps/blake3/c/blake3_avx512_x86-64_unix.S +0 -4824
  472. package/deps/blake3/c/blake3_avx512_x86-64_windows_gnu.S +0 -2615
  473. package/deps/blake3/c/blake3_avx512_x86-64_windows_msvc.asm +0 -2634
  474. package/deps/blake3/c/blake3_c_rust_bindings/Cargo.toml +0 -32
  475. package/deps/blake3/c/blake3_c_rust_bindings/README.md +0 -4
  476. package/deps/blake3/c/blake3_c_rust_bindings/benches/bench.rs +0 -477
  477. package/deps/blake3/c/blake3_c_rust_bindings/build.rs +0 -253
  478. package/deps/blake3/c/blake3_c_rust_bindings/cross_test.sh +0 -31
  479. package/deps/blake3/c/blake3_c_rust_bindings/src/lib.rs +0 -333
  480. package/deps/blake3/c/blake3_c_rust_bindings/src/test.rs +0 -696
  481. package/deps/blake3/c/blake3_sse2.c +0 -566
  482. package/deps/blake3/c/blake3_sse2_x86-64_unix.S +0 -2291
  483. package/deps/blake3/c/blake3_sse2_x86-64_windows_gnu.S +0 -2332
  484. package/deps/blake3/c/blake3_sse2_x86-64_windows_msvc.asm +0 -2350
  485. package/deps/blake3/c/blake3_sse41.c +0 -560
  486. package/deps/blake3/c/blake3_sse41_x86-64_unix.S +0 -2028
  487. package/deps/blake3/c/blake3_sse41_x86-64_windows_gnu.S +0 -2069
  488. package/deps/blake3/c/blake3_sse41_x86-64_windows_msvc.asm +0 -2089
  489. package/deps/blake3/c/blake3_tbb.cpp +0 -37
  490. package/deps/blake3/c/dependencies/CMakeLists.txt +0 -3
  491. package/deps/blake3/c/dependencies/tbb/CMakeLists.txt +0 -28
  492. package/deps/blake3/c/example.c +0 -36
  493. package/deps/blake3/c/example_tbb.c +0 -57
  494. package/deps/blake3/c/libblake3.pc.in +0 -12
  495. package/deps/blake3/c/main.c +0 -166
  496. package/deps/blake3/c/test.py +0 -97
  497. package/deps/blake3/media/B3.svg +0 -70
  498. package/deps/blake3/media/BLAKE3.svg +0 -85
  499. package/deps/blake3/media/speed.svg +0 -1474
  500. package/deps/blake3/reference_impl/Cargo.toml +0 -8
  501. package/deps/blake3/reference_impl/README.md +0 -14
  502. package/deps/blake3/reference_impl/reference_impl.rs +0 -374
  503. package/deps/blake3/src/ffi_avx2.rs +0 -65
  504. package/deps/blake3/src/ffi_avx512.rs +0 -169
  505. package/deps/blake3/src/ffi_neon.rs +0 -82
  506. package/deps/blake3/src/ffi_sse2.rs +0 -126
  507. package/deps/blake3/src/ffi_sse41.rs +0 -126
  508. package/deps/blake3/src/guts.rs +0 -60
  509. package/deps/blake3/src/hazmat.rs +0 -704
  510. package/deps/blake3/src/io.rs +0 -64
  511. package/deps/blake3/src/join.rs +0 -92
  512. package/deps/blake3/src/lib.rs +0 -1835
  513. package/deps/blake3/src/platform.rs +0 -587
  514. package/deps/blake3/src/portable.rs +0 -198
  515. package/deps/blake3/src/rust_avx2.rs +0 -474
  516. package/deps/blake3/src/rust_sse2.rs +0 -775
  517. package/deps/blake3/src/rust_sse41.rs +0 -766
  518. package/deps/blake3/src/test.rs +0 -1049
  519. package/deps/blake3/src/traits.rs +0 -227
  520. package/deps/blake3/src/wasm32_simd.rs +0 -794
  521. package/deps/blake3/test_vectors/Cargo.toml +0 -19
  522. package/deps/blake3/test_vectors/cross_test.sh +0 -25
  523. package/deps/blake3/test_vectors/src/bin/generate.rs +0 -4
  524. package/deps/blake3/test_vectors/src/lib.rs +0 -350
  525. package/deps/blake3/test_vectors/test_vectors.json +0 -217
  526. package/deps/blake3/tools/compiler_version/Cargo.toml +0 -7
  527. package/deps/blake3/tools/compiler_version/build.rs +0 -6
  528. package/deps/blake3/tools/compiler_version/src/main.rs +0 -27
  529. package/deps/blake3/tools/instruction_set_support/Cargo.toml +0 -6
  530. package/deps/blake3/tools/instruction_set_support/src/main.rs +0 -10
  531. package/deps/blake3/tools/release.md +0 -16
  532. package/deps/ncrypto/.bazelignore +0 -4
  533. package/deps/ncrypto/.bazelrc +0 -1
  534. package/deps/ncrypto/.bazelversion +0 -1
  535. package/deps/ncrypto/.clang-format +0 -111
  536. package/deps/ncrypto/.github/workflows/bazel.yml +0 -58
  537. package/deps/ncrypto/.github/workflows/commitlint.yml +0 -16
  538. package/deps/ncrypto/.github/workflows/linter.yml +0 -38
  539. package/deps/ncrypto/.github/workflows/macos.yml +0 -43
  540. package/deps/ncrypto/.github/workflows/release-please.yml +0 -16
  541. package/deps/ncrypto/.github/workflows/ubuntu.yml +0 -128
  542. package/deps/ncrypto/.github/workflows/visual-studio.yml +0 -49
  543. package/deps/ncrypto/.python-version +0 -1
  544. package/deps/ncrypto/.release-please-manifest.json +0 -3
  545. package/deps/ncrypto/BUILD.bazel +0 -44
  546. package/deps/ncrypto/CHANGELOG.md +0 -37
  547. package/deps/ncrypto/CMakeLists.txt +0 -79
  548. package/deps/ncrypto/MODULE.bazel +0 -16
  549. package/deps/ncrypto/MODULE.bazel.lock +0 -461
  550. package/deps/ncrypto/cmake/CPM.cmake +0 -1225
  551. package/deps/ncrypto/cmake/ncrypto-flags.cmake +0 -17
  552. package/deps/ncrypto/ncrypto.pc.in +0 -10
  553. package/deps/ncrypto/patches/0001-Expose-libdecrepit-so-NodeJS-can-use-it-for-ncrypto.patch +0 -28
  554. package/deps/ncrypto/pyproject.toml +0 -38
  555. package/deps/ncrypto/release-please-config.json +0 -11
  556. package/deps/ncrypto/src/CMakeLists.txt +0 -40
  557. package/deps/ncrypto/tests/BUILD.bazel +0 -11
  558. package/deps/ncrypto/tests/CMakeLists.txt +0 -7
  559. package/deps/ncrypto/tests/basic.cpp +0 -856
  560. package/deps/ncrypto/tools/run-clang-format.sh +0 -42
  561. package/lib/tsconfig.tsbuildinfo +0 -1
@@ -1,4 +1,6 @@
1
+ #include <algorithm>
1
2
  #include <cstring> // For std::memcpy
3
+ #include <memory> // For std::unique_ptr
2
4
  #include <stdexcept> // For std::runtime_error
3
5
 
4
6
  #include "NitroModules/ArrayBuffer.hpp"
@@ -28,11 +30,27 @@ void XSalsa20Cipher::init(const std::shared_ptr<ArrayBuffer> cipher_key, const s
28
30
  // Copy key and nonce data
29
31
  std::memcpy(key, native_key->data(), crypto_stream_KEYBYTES);
30
32
  std::memcpy(nonce, native_iv->data(), crypto_stream_NONCEBYTES);
33
+
34
+ // Reset streaming state so a re-init'd cipher does not accidentally reuse
35
+ // keystream bytes from a previous session.
36
+ block_counter = 0;
37
+ leftover_offset = kSalsa20BlockBytes;
38
+
31
39
  is_finalized = false;
32
40
  }
33
41
 
34
42
  /**
35
- * xsalsa20 call to sodium implementation
43
+ * xsalsa20 update encrypts/decrypts `data` while keeping the keystream
44
+ * advancing across successive update() calls.
45
+ *
46
+ * Implementation notes:
47
+ * 1. First, drain any unused keystream bytes left over from the previous
48
+ * chunk's trailing partial block.
49
+ * 2. Then process as many aligned whole 64-byte blocks as possible by
50
+ * jumping the keystream to `block_counter` via crypto_stream_xsalsa20_xor_ic.
51
+ * 3. For the remaining tail (< 64 bytes), generate one full keystream
52
+ * block, XOR the requested prefix, and stash the unused suffix for the
53
+ * next update() call.
36
54
  */
37
55
  std::shared_ptr<ArrayBuffer> XSalsa20Cipher::update(const std::shared_ptr<ArrayBuffer>& data) {
38
56
  checkNotFinalized();
@@ -40,12 +58,60 @@ std::shared_ptr<ArrayBuffer> XSalsa20Cipher::update(const std::shared_ptr<ArrayB
40
58
  throw std::runtime_error("XSalsa20Cipher: libsodium must be enabled to use this cipher (BLSALLOC_SODIUM is not defined).");
41
59
  #else
42
60
  auto native_data = ToNativeArrayBuffer(data);
43
- auto output = new uint8_t[native_data->size()];
44
- int result = crypto_stream_xor(output, native_data->data(), native_data->size(), nonce, key);
45
- if (result != 0) {
46
- throw std::runtime_error("XSalsa20Cipher: Failed to update");
61
+ const std::size_t data_size = native_data->size();
62
+
63
+ if (data_size == 0) {
64
+ return std::make_shared<NativeArrayBuffer>(nullptr, 0, nullptr);
65
+ }
66
+
67
+ // Owning buffer: prevents leaking `output` if we throw on the way out.
68
+ auto output = std::make_unique<uint8_t[]>(data_size);
69
+ const uint8_t* input = native_data->data();
70
+ std::size_t pos = 0;
71
+
72
+ // (1) Drain any unused keystream from the previous update()'s tail block.
73
+ if (leftover_offset < kSalsa20BlockBytes) {
74
+ const std::size_t avail = kSalsa20BlockBytes - leftover_offset;
75
+ const std::size_t take = std::min(avail, data_size);
76
+ for (std::size_t i = 0; i < take; ++i) {
77
+ output[i] = input[i] ^ leftover_keystream[leftover_offset + i];
78
+ }
79
+ leftover_offset += take;
80
+ pos = take;
47
81
  }
48
- return std::make_shared<NativeArrayBuffer>(output, native_data->size(), [=]() { delete[] output; });
82
+
83
+ // (2) Encrypt the aligned whole blocks at the current block counter.
84
+ const std::size_t remaining = data_size - pos;
85
+ const std::size_t whole_blocks = remaining / kSalsa20BlockBytes;
86
+ const std::size_t whole_bytes = whole_blocks * kSalsa20BlockBytes;
87
+ if (whole_bytes > 0) {
88
+ int rc = crypto_stream_xsalsa20_xor_ic(output.get() + pos, input + pos, whole_bytes, nonce, block_counter, key);
89
+ if (rc != 0) {
90
+ throw std::runtime_error("XSalsa20Cipher: crypto_stream_xsalsa20_xor_ic failed");
91
+ }
92
+ block_counter += whole_blocks;
93
+ pos += whole_bytes;
94
+ }
95
+
96
+ // (3) For any trailing partial block, generate one full keystream block,
97
+ // XOR the requested prefix, and stash the unused keystream bytes for
98
+ // the next update() call.
99
+ const std::size_t tail = data_size - pos;
100
+ if (tail > 0) {
101
+ uint8_t zeros[kSalsa20BlockBytes] = {};
102
+ int rc = crypto_stream_xsalsa20_xor_ic(leftover_keystream, zeros, kSalsa20BlockBytes, nonce, block_counter, key);
103
+ if (rc != 0) {
104
+ throw std::runtime_error("XSalsa20Cipher: crypto_stream_xsalsa20_xor_ic failed");
105
+ }
106
+ for (std::size_t i = 0; i < tail; ++i) {
107
+ output[pos + i] = input[pos + i] ^ leftover_keystream[i];
108
+ }
109
+ leftover_offset = tail;
110
+ block_counter += 1;
111
+ }
112
+
113
+ uint8_t* raw = output.release();
114
+ return std::make_shared<NativeArrayBuffer>(raw, data_size, [=]() { delete[] raw; });
49
115
  #endif
50
116
  }
51
117
 
@@ -8,17 +8,26 @@
8
8
  #define crypto_stream_NONCEBYTES 24 // XSalsa20 nonce size (24 bytes)
9
9
  #endif
10
10
 
11
+ #include <cstddef>
12
+ #include <cstdint>
13
+
11
14
  #include "HybridCipher.hpp"
12
15
  #include "NitroModules/ArrayBuffer.hpp"
16
+ #include "QuickCryptoUtils.hpp"
13
17
 
14
18
  namespace margelo::nitro::crypto {
15
19
 
16
20
  class XSalsa20Cipher : public HybridCipher {
17
21
  public:
18
22
  XSalsa20Cipher() : HybridObject(TAG) {}
19
- ~XSalsa20Cipher() {
20
- // Let parent destructor free the context
21
- ctx = nullptr;
23
+ ~XSalsa20Cipher() override {
24
+ // Wipe key material and any cached keystream bytes before the heap is
25
+ // returned. Without this the secret-bearing bytes persist on the heap
26
+ // until overwritten — see audit HIGH finding (XSalsa20Cipher.hpp:19-22).
27
+ // The base-class unique_ptr ctx frees itself; we don't touch it here.
28
+ secureZero(key);
29
+ secureZero(nonce);
30
+ secureZero(leftover_keystream);
22
31
  }
23
32
 
24
33
  void init(const std::shared_ptr<ArrayBuffer> cipher_key, const std::shared_ptr<ArrayBuffer> iv) override;
@@ -26,8 +35,21 @@ class XSalsa20Cipher : public HybridCipher {
26
35
  std::shared_ptr<ArrayBuffer> final() override;
27
36
 
28
37
  private:
38
+ // Salsa20 (and therefore XSalsa20) processes the keystream in 64-byte blocks.
39
+ static constexpr std::size_t kSalsa20BlockBytes = 64;
40
+
29
41
  uint8_t key[crypto_stream_KEYBYTES];
30
42
  uint8_t nonce[crypto_stream_NONCEBYTES];
43
+
44
+ // Streaming state — keeps the keystream advancing across multiple update()
45
+ // calls. Without this, every update() would restart at block 0, producing
46
+ // identical keystream for each chunk (a two-time-pad break).
47
+ uint8_t leftover_keystream[kSalsa20BlockBytes] = {};
48
+ // 0..kSalsa20BlockBytes; the sentinel value kSalsa20BlockBytes means "no
49
+ // leftover keystream available — start the next chunk on a block boundary".
50
+ std::size_t leftover_offset = kSalsa20BlockBytes;
51
+ // Index of the next 64-byte keystream block to consume.
52
+ uint64_t block_counter = 0;
31
53
  };
32
54
 
33
55
  } // namespace margelo::nitro::crypto
@@ -9,18 +9,13 @@
9
9
  namespace margelo::nitro::crypto {
10
10
 
11
11
  XSalsa20Poly1305Cipher::~XSalsa20Poly1305Cipher() {
12
- #ifdef BLSALLOC_SODIUM
13
- sodium_memzero(key_, kKeySize);
14
- sodium_memzero(nonce_, kNonceSize);
15
- sodium_memzero(auth_tag_, kTagSize);
16
- if (!data_buffer_.empty()) {
17
- sodium_memzero(data_buffer_.data(), data_buffer_.size());
18
- }
19
- #else
20
- std::memset(key_, 0, kKeySize);
21
- std::memset(nonce_, 0, kNonceSize);
22
- std::memset(auth_tag_, 0, kTagSize);
23
- #endif
12
+ // Always wipe via OPENSSL_cleanse (even when libsodium is enabled) so the
13
+ // non-sodium `std::memset` fallback can't be optimized away by the
14
+ // compiler. Audit MEDIUM finding (XSalsa20Poly1305Cipher.cpp:20-22).
15
+ secureZero(key_);
16
+ secureZero(nonce_);
17
+ secureZero(auth_tag_);
18
+ secureZero(data_buffer_);
24
19
  data_buffer_.clear();
25
20
  }
26
21
 
@@ -65,38 +60,38 @@ std::shared_ptr<ArrayBuffer> XSalsa20Poly1305Cipher::final() {
65
60
  throw std::runtime_error("XSalsa20Poly1305Cipher: libsodium must be enabled (BLSALLOC_SODIUM)");
66
61
  #else
67
62
  if (is_cipher) {
68
- uint8_t* ciphertext = new uint8_t[data_buffer_.size()];
63
+ auto ciphertext = std::make_unique<uint8_t[]>(data_buffer_.size());
69
64
 
70
- int result = crypto_secretbox_detached(ciphertext, auth_tag_, data_buffer_.data(), data_buffer_.size(), nonce_, key_);
65
+ int result = crypto_secretbox_detached(ciphertext.get(), auth_tag_, data_buffer_.data(), data_buffer_.size(), nonce_, key_);
71
66
 
72
67
  if (result != 0) {
73
- sodium_memzero(ciphertext, data_buffer_.size());
74
- delete[] ciphertext;
68
+ sodium_memzero(ciphertext.get(), data_buffer_.size());
75
69
  throw std::runtime_error("XSalsa20Poly1305Cipher: encryption failed");
76
70
  }
77
71
 
78
72
  is_finalized = true;
79
73
  size_t ct_len = data_buffer_.size();
80
- return std::make_shared<NativeArrayBuffer>(ciphertext, ct_len, [=]() { delete[] ciphertext; });
74
+ uint8_t* raw_ptr = ciphertext.get();
75
+ return std::make_shared<NativeArrayBuffer>(ciphertext.release(), ct_len, [raw_ptr]() { delete[] raw_ptr; });
81
76
  } else {
82
77
  if (data_buffer_.empty()) {
83
78
  is_finalized = true;
84
79
  return std::make_shared<NativeArrayBuffer>(nullptr, 0, nullptr);
85
80
  }
86
81
 
87
- uint8_t* plaintext = new uint8_t[data_buffer_.size()];
82
+ auto plaintext = std::make_unique<uint8_t[]>(data_buffer_.size());
88
83
 
89
- int result = crypto_secretbox_open_detached(plaintext, data_buffer_.data(), auth_tag_, data_buffer_.size(), nonce_, key_);
84
+ int result = crypto_secretbox_open_detached(plaintext.get(), data_buffer_.data(), auth_tag_, data_buffer_.size(), nonce_, key_);
90
85
 
91
86
  if (result != 0) {
92
- sodium_memzero(plaintext, data_buffer_.size());
93
- delete[] plaintext;
87
+ sodium_memzero(plaintext.get(), data_buffer_.size());
94
88
  throw std::runtime_error("XSalsa20Poly1305Cipher: decryption failed - authentication tag mismatch");
95
89
  }
96
90
 
97
91
  is_finalized = true;
98
92
  size_t pt_len = data_buffer_.size();
99
- return std::make_shared<NativeArrayBuffer>(plaintext, pt_len, [=]() { delete[] plaintext; });
93
+ uint8_t* raw_ptr = plaintext.get();
94
+ return std::make_shared<NativeArrayBuffer>(plaintext.release(), pt_len, [raw_ptr]() { delete[] raw_ptr; });
100
95
  }
101
96
  #endif
102
97
  }
@@ -116,9 +111,10 @@ std::shared_ptr<ArrayBuffer> XSalsa20Poly1305Cipher::getAuthTag() {
116
111
  throw std::runtime_error("getAuthTag must be called after final()");
117
112
  }
118
113
 
119
- uint8_t* tag_copy = new uint8_t[kTagSize];
120
- std::memcpy(tag_copy, auth_tag_, kTagSize);
121
- return std::make_shared<NativeArrayBuffer>(tag_copy, kTagSize, [=]() { delete[] tag_copy; });
114
+ auto tag_copy = std::make_unique<uint8_t[]>(kTagSize);
115
+ std::memcpy(tag_copy.get(), auth_tag_, kTagSize);
116
+ uint8_t* raw_ptr = tag_copy.get();
117
+ return std::make_shared<NativeArrayBuffer>(tag_copy.release(), kTagSize, [raw_ptr]() { delete[] raw_ptr; });
122
118
  #endif
123
119
  }
124
120
 
@@ -133,6 +133,35 @@ std::shared_ptr<ArrayBuffer> HybridDiffieHellman::computeSecret(const std::share
133
133
  const BIGNUM *p, *q, *g;
134
134
  DH_get0_pqg(ourDh, &p, &q, &g);
135
135
 
136
+ // Validate the peer's public key against our DH parameters BEFORE doing
137
+ // anything else. EVP_PKEY_derive_set_peer() does NOT call DH_check_pub_key,
138
+ // so without this check a peer key of 0, 1, or p-1 silently produces a
139
+ // degenerate "shared secret" (0, 1, or ±1) — the small-subgroup attack.
140
+ // Match the ncrypto pattern (DHPointer::checkPublicKey) and Node.js error
141
+ // surface so callers see why the key was rejected.
142
+ {
143
+ BN_ptr peerPubCheck(BN_bin2bn(otherPublicKey->data(), static_cast<int>(otherPublicKey->size()), nullptr), BN_free);
144
+ if (!peerPubCheck) {
145
+ throw std::runtime_error("DiffieHellman: failed to parse peer public key");
146
+ }
147
+ int codes = 0;
148
+ if (DH_check_pub_key(ourDh, peerPubCheck.get(), &codes) != 1) {
149
+ throw std::runtime_error("DiffieHellman: failed to check peer public key");
150
+ }
151
+ if (codes & DH_CHECK_PUBKEY_TOO_SMALL) {
152
+ throw std::runtime_error("DiffieHellman: peer public key is too small (<= 1)");
153
+ }
154
+ if (codes & DH_CHECK_PUBKEY_TOO_LARGE) {
155
+ throw std::runtime_error("DiffieHellman: peer public key is too large (>= p-1)");
156
+ }
157
+ if (codes & DH_CHECK_PUBKEY_INVALID) {
158
+ throw std::runtime_error("DiffieHellman: peer public key is invalid (not in subgroup)");
159
+ }
160
+ if (codes != 0) {
161
+ throw std::runtime_error("DiffieHellman: peer public key is invalid");
162
+ }
163
+ }
164
+
136
165
  // Create peer DH with same parameters but peer's public key
137
166
  DH_ptr peerDh(DH_new(), DH_free);
138
167
  if (!peerDh) {
@@ -40,10 +40,7 @@ void HybridEcKeyPair::generateKeyPairSync() {
40
40
  }
41
41
 
42
42
  // Clean up existing key if any
43
- if (this->pkey != nullptr) {
44
- EVP_PKEY_free(this->pkey);
45
- this->pkey = nullptr;
46
- }
43
+ this->pkey_.reset();
47
44
 
48
45
  // Get curve NID from curve name
49
46
  int curve_nid = GetCurveFromName(this->curve.c_str());
@@ -105,17 +102,14 @@ void HybridEcKeyPair::generateKeyPairSync() {
105
102
  throw std::runtime_error("Failed to generate EC key pair");
106
103
  }
107
104
 
108
- this->pkey = raw_pkey;
105
+ this->pkey_.reset(raw_pkey);
109
106
  }
110
107
 
111
108
  KeyObject HybridEcKeyPair::importKey(const std::string& format, const std::shared_ptr<ArrayBuffer>& keyData,
112
109
  const std::string& /* algorithm */, bool /* extractable */,
113
110
  const std::vector<std::string>& /* keyUsages */) {
114
111
  // Clean up any existing key
115
- if (this->pkey != nullptr) {
116
- EVP_PKEY_free(this->pkey);
117
- this->pkey = nullptr;
118
- }
112
+ this->pkey_.reset();
119
113
  // Reset curve state to avoid interference between different uses
120
114
  this->curve.clear();
121
115
 
@@ -143,7 +137,7 @@ KeyObject HybridEcKeyPair::importKey(const std::string& format, const std::share
143
137
  PKCS8_PRIV_KEY_INFO_free(p8inf);
144
138
  BIO_free(pkcs8_bio);
145
139
  if (pkcs8_pkey != nullptr) {
146
- this->pkey = pkcs8_pkey;
140
+ this->pkey_.reset(pkcs8_pkey);
147
141
  KeyObject keyObj;
148
142
  return keyObj;
149
143
  }
@@ -157,7 +151,7 @@ KeyObject HybridEcKeyPair::importKey(const std::string& format, const std::share
157
151
  EVP_PKEY* spki_pkey = d2i_PUBKEY_bio(spki_bio, nullptr);
158
152
  BIO_free(spki_bio);
159
153
  if (spki_pkey != nullptr) {
160
- this->pkey = spki_pkey;
154
+ this->pkey_.reset(spki_pkey);
161
155
  KeyObject keyObj;
162
156
  return keyObj;
163
157
  }
@@ -166,7 +160,7 @@ KeyObject HybridEcKeyPair::importKey(const std::string& format, const std::share
166
160
  throw std::runtime_error("Failed to import EC key from DER data");
167
161
  }
168
162
 
169
- this->pkey = pkey;
163
+ this->pkey_.reset(pkey);
170
164
 
171
165
  // Return a placeholder KeyObject - this would need proper implementation
172
166
  // For now, we just need the key imported into this->pkey for sign/verify
@@ -178,20 +172,20 @@ std::shared_ptr<ArrayBuffer> HybridEcKeyPair::exportKey(const KeyObject& key, co
178
172
  // Suppress unused parameter warning
179
173
  (void)key;
180
174
 
181
- if (!this->pkey) {
175
+ if (!this->pkey_) {
182
176
  throw std::runtime_error("No key pair generated");
183
177
  }
184
178
 
185
179
  if (format == "der-spki") {
186
180
  // Export public key in DER SPKI format
187
- int len = i2d_PUBKEY(this->pkey, nullptr);
181
+ int len = i2d_PUBKEY(this->pkey_.get(), nullptr);
188
182
  if (len <= 0) {
189
183
  throw std::runtime_error("Failed to get public key DER length");
190
184
  }
191
185
 
192
186
  std::vector<unsigned char> derData(len);
193
187
  unsigned char* ptr = derData.data();
194
- i2d_PUBKEY(this->pkey, &ptr);
188
+ i2d_PUBKEY(this->pkey_.get(), &ptr);
195
189
  return ToNativeArrayBuffer(std::string(derData.begin(), derData.end()));
196
190
  } else if (format == "der-pkcs8") {
197
191
  // Export private key in DER PKCS8 format
@@ -200,7 +194,7 @@ std::shared_ptr<ArrayBuffer> HybridEcKeyPair::exportKey(const KeyObject& key, co
200
194
  throw std::runtime_error("Failed to create BIO for private key export");
201
195
  }
202
196
 
203
- if (i2d_PKCS8PrivateKey_bio(bio, this->pkey, nullptr, nullptr, 0, nullptr, nullptr) != 1) {
197
+ if (i2d_PKCS8PrivateKey_bio(bio, this->pkey_.get(), nullptr, nullptr, 0, nullptr, nullptr) != 1) {
204
198
  BIO_free(bio);
205
199
  throw std::runtime_error("Failed to export private key to DER PKCS8 format");
206
200
  }
@@ -218,7 +212,7 @@ std::shared_ptr<ArrayBuffer> HybridEcKeyPair::exportKey(const KeyObject& key, co
218
212
  throw std::runtime_error("Failed to create BIO for public key export");
219
213
  }
220
214
 
221
- if (PEM_write_bio_PUBKEY(bio, this->pkey) != 1) {
215
+ if (PEM_write_bio_PUBKEY(bio, this->pkey_.get()) != 1) {
222
216
  BIO_free(bio);
223
217
  throw std::runtime_error("Failed to export public key to PEM SPKI format");
224
218
  }
@@ -236,7 +230,7 @@ std::shared_ptr<ArrayBuffer> HybridEcKeyPair::exportKey(const KeyObject& key, co
236
230
  throw std::runtime_error("Failed to create BIO for private key export");
237
231
  }
238
232
 
239
- if (PEM_write_bio_PKCS8PrivateKey(bio, this->pkey, nullptr, nullptr, 0, nullptr, nullptr) != 1) {
233
+ if (PEM_write_bio_PKCS8PrivateKey(bio, this->pkey_.get(), nullptr, nullptr, 0, nullptr, nullptr) != 1) {
240
234
  BIO_free(bio);
241
235
  throw std::runtime_error("Failed to export private key to PEM PKCS8 format");
242
236
  }
@@ -261,7 +255,7 @@ std::shared_ptr<ArrayBuffer> HybridEcKeyPair::getPublicKey() {
261
255
  throw std::runtime_error("Failed to create BIO for public key export");
262
256
  }
263
257
 
264
- if (i2d_PUBKEY_bio(bio, this->pkey) != 1) {
258
+ if (i2d_PUBKEY_bio(bio, this->pkey_.get()) != 1) {
265
259
  BIO_free(bio);
266
260
  throw std::runtime_error("Failed to export public key to DER format");
267
261
  }
@@ -277,13 +271,13 @@ std::shared_ptr<ArrayBuffer> HybridEcKeyPair::getPublicKey() {
277
271
  }
278
272
 
279
273
  std::shared_ptr<ArrayBuffer> HybridEcKeyPair::getPrivateKey() {
280
- if (this->pkey == nullptr) {
274
+ if (!this->pkey_) {
281
275
  throw std::runtime_error("No private key available");
282
276
  }
283
277
 
284
278
  // Export private key in PKCS8 DER format
285
279
  BIO* bio = BIO_new(BIO_s_mem());
286
- if (i2d_PKCS8PrivateKey_bio(bio, this->pkey, nullptr, nullptr, 0, nullptr, nullptr) != 1) {
280
+ if (i2d_PKCS8PrivateKey_bio(bio, this->pkey_.get(), nullptr, nullptr, 0, nullptr, nullptr) != 1) {
287
281
  BIO_free(bio);
288
282
  throw std::runtime_error("Failed to export private key");
289
283
  }
@@ -350,7 +344,7 @@ std::shared_ptr<ArrayBuffer> HybridEcKeyPair::sign(const std::shared_ptr<ArrayBu
350
344
  }
351
345
 
352
346
  // Initialize signing
353
- if (EVP_DigestSignInit(md_ctx.get(), nullptr, md, nullptr, this->pkey) <= 0) {
347
+ if (EVP_DigestSignInit(md_ctx.get(), nullptr, md, nullptr, this->pkey_.get()) <= 0) {
354
348
  throw std::runtime_error("Failed to initialize ECDSA signing");
355
349
  }
356
350
 
@@ -377,7 +371,7 @@ std::shared_ptr<ArrayBuffer> HybridEcKeyPair::sign(const std::shared_ptr<ArrayBu
377
371
  signature.resize(sig_len);
378
372
 
379
373
  // Web Crypto API requires IEEE P1363 format for ECDSA signatures
380
- unsigned int n = getBytesOfRS(this->pkey);
374
+ unsigned int n = getBytesOfRS(this->pkey_.get());
381
375
  if (n == 0) {
382
376
  throw std::runtime_error("Failed to determine EC key order size for P1363 conversion");
383
377
  }
@@ -415,7 +409,7 @@ bool HybridEcKeyPair::verify(const std::shared_ptr<ArrayBuffer>& data, const std
415
409
  }
416
410
 
417
411
  // Initialize verification
418
- if (EVP_DigestVerifyInit(md_ctx.get(), nullptr, md, nullptr, this->pkey) <= 0) {
412
+ if (EVP_DigestVerifyInit(md_ctx.get(), nullptr, md, nullptr, this->pkey_.get()) <= 0) {
419
413
  throw std::runtime_error("Failed to initialize ECDSA verification");
420
414
  }
421
415
 
@@ -424,22 +418,30 @@ bool HybridEcKeyPair::verify(const std::shared_ptr<ArrayBuffer>& data, const std
424
418
  throw std::runtime_error("Failed to update ECDSA verification with data");
425
419
  }
426
420
 
427
- // Web Crypto API passes IEEE P1363 format, OpenSSL expects DER
421
+ // Web Crypto API typically passes IEEE P1363 (raw r||s, exactly 2*n bytes);
422
+ // the Node-API path with `dsaEncoding: 'der'` passes ASN.1 DER instead.
423
+ // Discriminate by length — anything other than 2*n is treated as DER and
424
+ // passed through unchanged. This matches what every other ECDSA verify
425
+ // wrapper (Node's, ncrypto's) does and is robust because well-formed DER
426
+ // ECDSA signatures are never exactly 2*n bytes for the curves we support.
428
427
  const unsigned char* sig_data = static_cast<const unsigned char*>(signature->data());
429
428
  size_t sig_len = signature->size();
430
429
  std::unique_ptr<uint8_t[]> der_sig_buf;
431
430
 
432
- unsigned int n = getBytesOfRS(this->pkey);
431
+ unsigned int n = getBytesOfRS(this->pkey_.get());
433
432
  if (n == 0) {
434
433
  throw std::runtime_error("Failed to determine EC key order size for DER conversion");
435
434
  }
436
- size_t der_len = 0;
437
- der_sig_buf = convertSignatureToDER(sig_data, sig_len, n, &der_len);
438
- if (!der_sig_buf) {
439
- throw std::runtime_error("Failed to convert ECDSA signature from P1363 to DER format");
435
+
436
+ if (sig_len == 2 * n) {
437
+ size_t der_len = 0;
438
+ der_sig_buf = convertSignatureToDER(sig_data, sig_len, n, &der_len);
439
+ if (!der_sig_buf) {
440
+ throw std::runtime_error("Failed to convert ECDSA signature from P1363 to DER format");
441
+ }
442
+ sig_data = der_sig_buf.get();
443
+ sig_len = der_len;
440
444
  }
441
- sig_data = der_sig_buf.get();
442
- sig_len = der_len;
443
445
 
444
446
  int result = EVP_DigestVerifyFinal(md_ctx.get(), sig_data, sig_len);
445
447
 
@@ -451,7 +453,7 @@ bool HybridEcKeyPair::verify(const std::shared_ptr<ArrayBuffer>& data, const std
451
453
  }
452
454
 
453
455
  void HybridEcKeyPair::checkKeyPair() {
454
- if (this->pkey == nullptr) {
456
+ if (!this->pkey_) {
455
457
  throw std::runtime_error("EC KeyPair not initialized");
456
458
  }
457
459
  }
@@ -13,12 +13,7 @@ namespace margelo::nitro::crypto {
13
13
  class HybridEcKeyPair : public HybridEcKeyPairSpec {
14
14
  public:
15
15
  HybridEcKeyPair() : HybridObject(TAG) {}
16
- ~HybridEcKeyPair() {
17
- if (pkey != nullptr) {
18
- EVP_PKEY_free(pkey);
19
- pkey = nullptr;
20
- }
21
- }
16
+ ~HybridEcKeyPair() override = default;
22
17
 
23
18
  public:
24
19
  // Methods
@@ -41,7 +36,8 @@ class HybridEcKeyPair : public HybridEcKeyPairSpec {
41
36
 
42
37
  private:
43
38
  std::string curve;
44
- EVP_PKEY* pkey = nullptr;
39
+ using EVP_PKEY_ptr = std::unique_ptr<EVP_PKEY, decltype(&EVP_PKEY_free)>;
40
+ EVP_PKEY_ptr pkey_{nullptr, EVP_PKEY_free};
45
41
 
46
42
  static int GetCurveFromName(const char* name);
47
43
  };
@@ -65,6 +65,29 @@ std::shared_ptr<ArrayBuffer> HybridECDH::computeSecret(const std::shared_ptr<Arr
65
65
  throw std::runtime_error("ECDH: private key not set");
66
66
  }
67
67
 
68
+ // Validate the peer's public key BEFORE building an EVP_PKEY from it.
69
+ // EVP_PKEY_fromdata() does NOT verify that the supplied public-key octets
70
+ // decode to a point on the configured curve, so an attacker can mount an
71
+ // invalid-curve attack: send a point on a related, weaker curve (or a
72
+ // small-order point) and recover bits of our private key from the
73
+ // resulting "shared secret". Reject malformed encodings, the identity
74
+ // point, and any point that is not on _group up front.
75
+ {
76
+ EC_POINT_ptr peerPoint(EC_POINT_new(_group.get()), EC_POINT_free);
77
+ if (!peerPoint) {
78
+ throw std::runtime_error("ECDH: failed to allocate EC_POINT for peer key validation");
79
+ }
80
+ if (EC_POINT_oct2point(_group.get(), peerPoint.get(), otherPublicKey->data(), otherPublicKey->size(), nullptr) != 1) {
81
+ throw std::runtime_error("ECDH: peer public key is malformed");
82
+ }
83
+ if (EC_POINT_is_at_infinity(_group.get(), peerPoint.get())) {
84
+ throw std::runtime_error("ECDH: peer public key is the identity point");
85
+ }
86
+ if (EC_POINT_is_on_curve(_group.get(), peerPoint.get(), nullptr) != 1) {
87
+ throw std::runtime_error("ECDH: peer public key is not on the configured curve");
88
+ }
89
+ }
90
+
68
91
  // Build peer EVP_PKEY from raw public key octets
69
92
  EVP_PKEY_ptr peerPkey(createEcEvpPkey(_curveName.c_str(), otherPublicKey->data(), otherPublicKey->size()), EVP_PKEY_free);
70
93