react-native-quick-crypto 1.0.0-beta.2 → 1.0.0-beta.21

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 (462) hide show
  1. package/QuickCrypto.podspec +143 -7
  2. package/README.md +12 -6
  3. package/android/CMakeLists.txt +82 -21
  4. package/android/build.gradle +47 -4
  5. package/android/src/main/cpp/cpp-adapter.cpp +3 -10
  6. package/android/src/main/java/com/margelo/nitro/quickcrypto/QuickCryptoPackage.java +13 -10
  7. package/app.plugin.js +3 -0
  8. package/cpp/blake3/HybridBlake3.cpp +118 -0
  9. package/cpp/blake3/HybridBlake3.hpp +35 -0
  10. package/cpp/cipher/CCMCipher.cpp +199 -0
  11. package/cpp/cipher/CCMCipher.hpp +26 -0
  12. package/cpp/cipher/ChaCha20Cipher.cpp +97 -0
  13. package/cpp/cipher/ChaCha20Cipher.hpp +25 -0
  14. package/cpp/cipher/ChaCha20Poly1305Cipher.cpp +170 -0
  15. package/cpp/cipher/ChaCha20Poly1305Cipher.hpp +30 -0
  16. package/cpp/cipher/HybridCipher.cpp +322 -0
  17. package/cpp/cipher/HybridCipher.hpp +68 -0
  18. package/cpp/cipher/HybridCipherFactory.hpp +97 -0
  19. package/cpp/cipher/OCBCipher.cpp +55 -0
  20. package/cpp/cipher/OCBCipher.hpp +19 -0
  21. package/cpp/cipher/XSalsa20Cipher.cpp +61 -0
  22. package/cpp/cipher/XSalsa20Cipher.hpp +33 -0
  23. package/cpp/ec/HybridEcKeyPair.cpp +428 -0
  24. package/cpp/ec/HybridEcKeyPair.hpp +48 -0
  25. package/cpp/ed25519/HybridEdKeyPair.cpp +300 -0
  26. package/cpp/ed25519/HybridEdKeyPair.hpp +63 -0
  27. package/cpp/hash/HybridHash.cpp +185 -0
  28. package/cpp/hash/HybridHash.hpp +43 -0
  29. package/cpp/hmac/HybridHmac.cpp +95 -0
  30. package/cpp/hmac/HybridHmac.hpp +31 -0
  31. package/cpp/keys/HybridKeyObjectHandle.cpp +243 -0
  32. package/cpp/keys/HybridKeyObjectHandle.hpp +42 -0
  33. package/cpp/keys/KeyObjectData.cpp +226 -0
  34. package/cpp/keys/KeyObjectData.hpp +71 -0
  35. package/cpp/keys/node.h +5 -0
  36. package/cpp/pbkdf2/HybridPbkdf2.cpp +51 -0
  37. package/cpp/pbkdf2/HybridPbkdf2.hpp +24 -0
  38. package/cpp/random/HybridRandom.cpp +32 -18
  39. package/cpp/random/HybridRandom.hpp +18 -30
  40. package/cpp/rsa/HybridRsaKeyPair.cpp +154 -0
  41. package/cpp/rsa/HybridRsaKeyPair.hpp +43 -0
  42. package/cpp/utils/Macros.hpp +68 -0
  43. package/cpp/utils/Utils.hpp +53 -1
  44. package/deps/blake3/.cargo/config.toml +2 -0
  45. package/deps/blake3/.git-blame-ignore-revs +2 -0
  46. package/deps/blake3/.github/workflows/build_b3sum.py +38 -0
  47. package/deps/blake3/.github/workflows/ci.yml +491 -0
  48. package/deps/blake3/.github/workflows/tag.yml +43 -0
  49. package/deps/blake3/.github/workflows/upload_github_release_asset.py +73 -0
  50. package/deps/blake3/CONTRIBUTING.md +31 -0
  51. package/deps/blake3/Cargo.toml +135 -0
  52. package/deps/blake3/LICENSE_A2 +202 -0
  53. package/deps/blake3/LICENSE_A2LLVM +219 -0
  54. package/deps/blake3/LICENSE_CC0 +121 -0
  55. package/deps/blake3/README.md +229 -0
  56. package/deps/blake3/b3sum/Cargo.lock +513 -0
  57. package/deps/blake3/b3sum/Cargo.toml +26 -0
  58. package/deps/blake3/b3sum/README.md +72 -0
  59. package/deps/blake3/b3sum/src/main.rs +564 -0
  60. package/deps/blake3/b3sum/src/unit_tests.rs +235 -0
  61. package/deps/blake3/b3sum/tests/cli_tests.rs +680 -0
  62. package/deps/blake3/b3sum/what_does_check_do.md +176 -0
  63. package/deps/blake3/benches/bench.rs +623 -0
  64. package/deps/blake3/build.rs +389 -0
  65. package/deps/blake3/c/CMakeLists.txt +383 -0
  66. package/deps/blake3/c/CMakePresets.json +73 -0
  67. package/deps/blake3/c/Makefile.testing +82 -0
  68. package/deps/blake3/c/README.md +403 -0
  69. package/deps/blake3/c/blake3-config.cmake.in +14 -0
  70. package/deps/blake3/c/blake3.c +650 -0
  71. package/deps/blake3/c/blake3.h +86 -0
  72. package/deps/blake3/c/blake3_avx2.c +326 -0
  73. package/deps/blake3/c/blake3_avx2_x86-64_unix.S +1815 -0
  74. package/deps/blake3/c/blake3_avx2_x86-64_windows_gnu.S +1817 -0
  75. package/deps/blake3/c/blake3_avx2_x86-64_windows_msvc.asm +1828 -0
  76. package/deps/blake3/c/blake3_avx512.c +1388 -0
  77. package/deps/blake3/c/blake3_avx512_x86-64_unix.S +4824 -0
  78. package/deps/blake3/c/blake3_avx512_x86-64_windows_gnu.S +2615 -0
  79. package/deps/blake3/c/blake3_avx512_x86-64_windows_msvc.asm +2634 -0
  80. package/deps/blake3/c/blake3_c_rust_bindings/Cargo.toml +32 -0
  81. package/deps/blake3/c/blake3_c_rust_bindings/README.md +4 -0
  82. package/deps/blake3/c/blake3_c_rust_bindings/benches/bench.rs +477 -0
  83. package/deps/blake3/c/blake3_c_rust_bindings/build.rs +253 -0
  84. package/deps/blake3/c/blake3_c_rust_bindings/cross_test.sh +31 -0
  85. package/deps/blake3/c/blake3_c_rust_bindings/src/lib.rs +333 -0
  86. package/deps/blake3/c/blake3_c_rust_bindings/src/test.rs +696 -0
  87. package/deps/blake3/c/blake3_dispatch.c +332 -0
  88. package/deps/blake3/c/blake3_impl.h +333 -0
  89. package/deps/blake3/c/blake3_neon.c +366 -0
  90. package/deps/blake3/c/blake3_portable.c +160 -0
  91. package/deps/blake3/c/blake3_sse2.c +566 -0
  92. package/deps/blake3/c/blake3_sse2_x86-64_unix.S +2291 -0
  93. package/deps/blake3/c/blake3_sse2_x86-64_windows_gnu.S +2332 -0
  94. package/deps/blake3/c/blake3_sse2_x86-64_windows_msvc.asm +2350 -0
  95. package/deps/blake3/c/blake3_sse41.c +560 -0
  96. package/deps/blake3/c/blake3_sse41_x86-64_unix.S +2028 -0
  97. package/deps/blake3/c/blake3_sse41_x86-64_windows_gnu.S +2069 -0
  98. package/deps/blake3/c/blake3_sse41_x86-64_windows_msvc.asm +2089 -0
  99. package/deps/blake3/c/blake3_tbb.cpp +37 -0
  100. package/deps/blake3/c/dependencies/CMakeLists.txt +3 -0
  101. package/deps/blake3/c/dependencies/tbb/CMakeLists.txt +28 -0
  102. package/deps/blake3/c/example.c +36 -0
  103. package/deps/blake3/c/example_tbb.c +57 -0
  104. package/deps/blake3/c/libblake3.pc.in +12 -0
  105. package/deps/blake3/c/main.c +166 -0
  106. package/deps/blake3/c/test.py +97 -0
  107. package/deps/blake3/media/B3.svg +70 -0
  108. package/deps/blake3/media/BLAKE3.svg +85 -0
  109. package/deps/blake3/media/speed.svg +1474 -0
  110. package/deps/blake3/reference_impl/Cargo.toml +8 -0
  111. package/deps/blake3/reference_impl/README.md +14 -0
  112. package/deps/blake3/reference_impl/reference_impl.rs +374 -0
  113. package/deps/blake3/src/ffi_avx2.rs +65 -0
  114. package/deps/blake3/src/ffi_avx512.rs +169 -0
  115. package/deps/blake3/src/ffi_neon.rs +82 -0
  116. package/deps/blake3/src/ffi_sse2.rs +126 -0
  117. package/deps/blake3/src/ffi_sse41.rs +126 -0
  118. package/deps/blake3/src/guts.rs +60 -0
  119. package/deps/blake3/src/hazmat.rs +704 -0
  120. package/deps/blake3/src/io.rs +64 -0
  121. package/deps/blake3/src/join.rs +92 -0
  122. package/deps/blake3/src/lib.rs +1835 -0
  123. package/deps/blake3/src/platform.rs +587 -0
  124. package/deps/blake3/src/portable.rs +198 -0
  125. package/deps/blake3/src/rust_avx2.rs +474 -0
  126. package/deps/blake3/src/rust_sse2.rs +775 -0
  127. package/deps/blake3/src/rust_sse41.rs +766 -0
  128. package/deps/blake3/src/test.rs +1049 -0
  129. package/deps/blake3/src/traits.rs +227 -0
  130. package/deps/blake3/src/wasm32_simd.rs +794 -0
  131. package/deps/blake3/test_vectors/Cargo.toml +19 -0
  132. package/deps/blake3/test_vectors/cross_test.sh +25 -0
  133. package/deps/blake3/test_vectors/src/bin/generate.rs +4 -0
  134. package/deps/blake3/test_vectors/src/lib.rs +350 -0
  135. package/deps/blake3/test_vectors/test_vectors.json +217 -0
  136. package/deps/blake3/tools/compiler_version/Cargo.toml +7 -0
  137. package/deps/blake3/tools/compiler_version/build.rs +6 -0
  138. package/deps/blake3/tools/compiler_version/src/main.rs +27 -0
  139. package/deps/blake3/tools/instruction_set_support/Cargo.toml +6 -0
  140. package/deps/blake3/tools/instruction_set_support/src/main.rs +10 -0
  141. package/deps/blake3/tools/release.md +16 -0
  142. package/deps/fastpbkdf2/fastpbkdf2.c +356 -0
  143. package/deps/fastpbkdf2/fastpbkdf2.h +68 -0
  144. package/deps/ncrypto/ncrypto.cc +4679 -0
  145. package/deps/ncrypto/ncrypto.h +1625 -0
  146. package/lib/commonjs/blake3.js +98 -0
  147. package/lib/commonjs/blake3.js.map +1 -0
  148. package/lib/commonjs/cipher.js +180 -0
  149. package/lib/commonjs/cipher.js.map +1 -0
  150. package/lib/commonjs/ec.js +344 -0
  151. package/lib/commonjs/ec.js.map +1 -0
  152. package/lib/commonjs/ed.js +185 -0
  153. package/lib/commonjs/ed.js.map +1 -0
  154. package/lib/commonjs/expo-plugin/@types.js +2 -0
  155. package/lib/commonjs/expo-plugin/@types.js.map +1 -0
  156. package/lib/commonjs/expo-plugin/withRNQC.js +25 -0
  157. package/lib/commonjs/expo-plugin/withRNQC.js.map +1 -0
  158. package/lib/commonjs/expo-plugin/withSodiumAndroid.js +25 -0
  159. package/lib/commonjs/expo-plugin/withSodiumAndroid.js.map +1 -0
  160. package/lib/commonjs/expo-plugin/withSodiumIos.js +26 -0
  161. package/lib/commonjs/expo-plugin/withSodiumIos.js.map +1 -0
  162. package/lib/commonjs/expo-plugin/withXCode.js +51 -0
  163. package/lib/commonjs/expo-plugin/withXCode.js.map +1 -0
  164. package/lib/commonjs/hash.js +215 -0
  165. package/lib/commonjs/hash.js.map +1 -0
  166. package/lib/commonjs/hmac.js +109 -0
  167. package/lib/commonjs/hmac.js.map +1 -0
  168. package/lib/commonjs/index.js +152 -32
  169. package/lib/commonjs/index.js.map +1 -1
  170. package/lib/commonjs/keys/classes.js +250 -0
  171. package/lib/commonjs/keys/classes.js.map +1 -0
  172. package/lib/commonjs/keys/generateKeyPair.js +102 -0
  173. package/lib/commonjs/keys/generateKeyPair.js.map +1 -0
  174. package/lib/commonjs/keys/index.js +89 -0
  175. package/lib/commonjs/keys/index.js.map +1 -0
  176. package/lib/commonjs/keys/signVerify.js +41 -0
  177. package/lib/commonjs/keys/signVerify.js.map +1 -0
  178. package/lib/commonjs/keys/utils.js +123 -0
  179. package/lib/commonjs/keys/utils.js.map +1 -0
  180. package/lib/commonjs/pbkdf2.js +89 -0
  181. package/lib/commonjs/pbkdf2.js.map +1 -0
  182. package/lib/commonjs/random.js +9 -3
  183. package/lib/commonjs/random.js.map +1 -1
  184. package/lib/commonjs/rsa.js +129 -0
  185. package/lib/commonjs/rsa.js.map +1 -0
  186. package/lib/commonjs/specs/blake3.nitro.js +6 -0
  187. package/lib/commonjs/specs/blake3.nitro.js.map +1 -0
  188. package/lib/commonjs/specs/cipher.nitro.js +6 -0
  189. package/lib/commonjs/specs/cipher.nitro.js.map +1 -0
  190. package/lib/commonjs/specs/ecKeyPair.nitro.js +6 -0
  191. package/lib/commonjs/specs/ecKeyPair.nitro.js.map +1 -0
  192. package/lib/commonjs/specs/edKeyPair.nitro.js +6 -0
  193. package/lib/commonjs/specs/edKeyPair.nitro.js.map +1 -0
  194. package/lib/commonjs/specs/hash.nitro.js +6 -0
  195. package/lib/commonjs/specs/hash.nitro.js.map +1 -0
  196. package/lib/commonjs/specs/hmac.nitro.js +6 -0
  197. package/lib/commonjs/specs/hmac.nitro.js.map +1 -0
  198. package/lib/commonjs/specs/keyObjectHandle.nitro.js +6 -0
  199. package/lib/commonjs/specs/keyObjectHandle.nitro.js.map +1 -0
  200. package/lib/commonjs/specs/pbkdf2.nitro.js +6 -0
  201. package/lib/commonjs/specs/pbkdf2.nitro.js.map +1 -0
  202. package/lib/commonjs/specs/rsaKeyPair.nitro.js +6 -0
  203. package/lib/commonjs/specs/rsaKeyPair.nitro.js.map +1 -0
  204. package/lib/commonjs/subtle.js +365 -0
  205. package/lib/commonjs/subtle.js.map +1 -0
  206. package/lib/commonjs/utils/cipher.js +64 -0
  207. package/lib/commonjs/utils/cipher.js.map +1 -0
  208. package/lib/commonjs/utils/conversion.js +140 -6
  209. package/lib/commonjs/utils/conversion.js.map +1 -1
  210. package/lib/commonjs/utils/errors.js +14 -0
  211. package/lib/commonjs/utils/errors.js.map +1 -0
  212. package/lib/commonjs/utils/hashnames.js +91 -0
  213. package/lib/commonjs/utils/hashnames.js.map +1 -0
  214. package/lib/commonjs/utils/index.js +65 -5
  215. package/lib/commonjs/utils/index.js.map +1 -1
  216. package/lib/commonjs/utils/noble.js +82 -0
  217. package/lib/commonjs/utils/noble.js.map +1 -0
  218. package/lib/commonjs/utils/types.js +52 -0
  219. package/lib/commonjs/utils/types.js.map +1 -1
  220. package/lib/commonjs/utils/validation.js +98 -0
  221. package/lib/commonjs/utils/validation.js.map +1 -0
  222. package/lib/module/blake3.js +90 -0
  223. package/lib/module/blake3.js.map +1 -0
  224. package/lib/module/cipher.js +173 -0
  225. package/lib/module/cipher.js.map +1 -0
  226. package/lib/module/ec.js +336 -0
  227. package/lib/module/ec.js.map +1 -0
  228. package/lib/module/ed.js +178 -0
  229. package/lib/module/ed.js.map +1 -0
  230. package/lib/module/expo-plugin/@types.js +2 -0
  231. package/lib/module/expo-plugin/@types.js.map +1 -0
  232. package/lib/module/expo-plugin/withRNQC.js +21 -0
  233. package/lib/module/expo-plugin/withRNQC.js.map +1 -0
  234. package/lib/module/expo-plugin/withSodiumAndroid.js +20 -0
  235. package/lib/module/expo-plugin/withSodiumAndroid.js.map +1 -0
  236. package/lib/module/expo-plugin/withSodiumIos.js +20 -0
  237. package/lib/module/expo-plugin/withSodiumIos.js.map +1 -0
  238. package/lib/module/expo-plugin/withXCode.js +46 -0
  239. package/lib/module/expo-plugin/withXCode.js.map +1 -0
  240. package/lib/module/hash.js +207 -0
  241. package/lib/module/hash.js.map +1 -0
  242. package/lib/module/hmac.js +104 -0
  243. package/lib/module/hmac.js.map +1 -0
  244. package/lib/module/index.js +33 -29
  245. package/lib/module/index.js.map +1 -1
  246. package/lib/module/keys/classes.js +241 -0
  247. package/lib/module/keys/classes.js.map +1 -0
  248. package/lib/module/keys/generateKeyPair.js +96 -0
  249. package/lib/module/keys/generateKeyPair.js.map +1 -0
  250. package/lib/module/keys/index.js +32 -0
  251. package/lib/module/keys/index.js.map +1 -0
  252. package/lib/module/keys/signVerify.js +41 -0
  253. package/lib/module/keys/signVerify.js.map +1 -0
  254. package/lib/module/keys/utils.js +114 -0
  255. package/lib/module/keys/utils.js.map +1 -0
  256. package/lib/module/pbkdf2.js +83 -0
  257. package/lib/module/pbkdf2.js.map +1 -0
  258. package/lib/module/random.js +7 -1
  259. package/lib/module/random.js.map +1 -1
  260. package/lib/module/rsa.js +123 -0
  261. package/lib/module/rsa.js.map +1 -0
  262. package/lib/module/specs/blake3.nitro.js +4 -0
  263. package/lib/module/specs/blake3.nitro.js.map +1 -0
  264. package/lib/module/specs/cipher.nitro.js +4 -0
  265. package/lib/module/specs/cipher.nitro.js.map +1 -0
  266. package/lib/module/specs/ecKeyPair.nitro.js +4 -0
  267. package/lib/module/specs/ecKeyPair.nitro.js.map +1 -0
  268. package/lib/module/specs/edKeyPair.nitro.js +4 -0
  269. package/lib/module/specs/edKeyPair.nitro.js.map +1 -0
  270. package/lib/module/specs/hash.nitro.js +4 -0
  271. package/lib/module/specs/hash.nitro.js.map +1 -0
  272. package/lib/module/specs/hmac.nitro.js +4 -0
  273. package/lib/module/specs/hmac.nitro.js.map +1 -0
  274. package/lib/module/specs/keyObjectHandle.nitro.js +4 -0
  275. package/lib/module/specs/keyObjectHandle.nitro.js.map +1 -0
  276. package/lib/module/specs/pbkdf2.nitro.js +4 -0
  277. package/lib/module/specs/pbkdf2.nitro.js.map +1 -0
  278. package/lib/module/specs/rsaKeyPair.nitro.js +4 -0
  279. package/lib/module/specs/rsaKeyPair.nitro.js.map +1 -0
  280. package/lib/module/subtle.js +360 -0
  281. package/lib/module/subtle.js.map +1 -0
  282. package/lib/module/utils/cipher.js +56 -0
  283. package/lib/module/utils/cipher.js.map +1 -0
  284. package/lib/module/utils/conversion.js +120 -8
  285. package/lib/module/utils/conversion.js.map +1 -1
  286. package/lib/module/utils/errors.js +10 -0
  287. package/lib/module/utils/errors.js.map +1 -0
  288. package/lib/module/utils/hashnames.js +89 -0
  289. package/lib/module/utils/hashnames.js.map +1 -0
  290. package/lib/module/utils/index.js +6 -5
  291. package/lib/module/utils/index.js.map +1 -1
  292. package/lib/module/utils/noble.js +76 -0
  293. package/lib/module/utils/noble.js.map +1 -0
  294. package/lib/module/utils/types.js +53 -0
  295. package/lib/module/utils/types.js.map +1 -1
  296. package/lib/module/utils/validation.js +87 -0
  297. package/lib/module/utils/validation.js.map +1 -0
  298. package/lib/tsconfig.tsbuildinfo +1 -1
  299. package/lib/typescript/blake3.d.ts +33 -0
  300. package/lib/typescript/blake3.d.ts.map +1 -0
  301. package/lib/typescript/cipher.d.ts +60 -0
  302. package/lib/typescript/cipher.d.ts.map +1 -0
  303. package/lib/typescript/ec.d.ts +13 -0
  304. package/lib/typescript/ec.d.ts.map +1 -0
  305. package/lib/typescript/ed.d.ts +43 -0
  306. package/lib/typescript/ed.d.ts.map +1 -0
  307. package/lib/typescript/expo-plugin/@types.d.ts +8 -0
  308. package/lib/typescript/expo-plugin/@types.d.ts.map +1 -0
  309. package/lib/typescript/expo-plugin/withRNQC.d.ts +4 -0
  310. package/lib/typescript/expo-plugin/withRNQC.d.ts.map +1 -0
  311. package/lib/typescript/expo-plugin/withSodiumAndroid.d.ts +4 -0
  312. package/lib/typescript/expo-plugin/withSodiumAndroid.d.ts.map +1 -0
  313. package/lib/typescript/expo-plugin/withSodiumIos.d.ts +4 -0
  314. package/lib/typescript/expo-plugin/withSodiumIos.d.ts.map +1 -0
  315. package/lib/typescript/expo-plugin/withXCode.d.ts +9 -0
  316. package/lib/typescript/expo-plugin/withXCode.d.ts.map +1 -0
  317. package/lib/typescript/hash.d.ts +122 -0
  318. package/lib/typescript/hash.d.ts.map +1 -0
  319. package/lib/typescript/hmac.d.ts +66 -0
  320. package/lib/typescript/hmac.d.ts.map +1 -0
  321. package/lib/typescript/index.d.ts +110 -9
  322. package/lib/typescript/index.d.ts.map +1 -1
  323. package/lib/typescript/keys/classes.d.ts +79 -0
  324. package/lib/typescript/keys/classes.d.ts.map +1 -0
  325. package/lib/typescript/keys/generateKeyPair.d.ts +6 -0
  326. package/lib/typescript/keys/generateKeyPair.d.ts.map +1 -0
  327. package/lib/typescript/keys/index.d.ts +7 -0
  328. package/lib/typescript/keys/index.d.ts.map +1 -0
  329. package/lib/typescript/keys/signVerify.d.ts +1 -0
  330. package/lib/typescript/keys/signVerify.d.ts.map +1 -0
  331. package/lib/typescript/keys/utils.d.ts +34 -0
  332. package/lib/typescript/keys/utils.d.ts.map +1 -0
  333. package/lib/typescript/pbkdf2.d.ts +12 -0
  334. package/lib/typescript/pbkdf2.d.ts.map +1 -0
  335. package/lib/typescript/random.d.ts +11 -5
  336. package/lib/typescript/random.d.ts.map +1 -1
  337. package/lib/typescript/rsa.d.ts +10 -0
  338. package/lib/typescript/rsa.d.ts.map +1 -0
  339. package/lib/typescript/specs/blake3.nitro.d.ts +15 -0
  340. package/lib/typescript/specs/blake3.nitro.d.ts.map +1 -0
  341. package/lib/typescript/specs/cipher.nitro.d.ts +29 -0
  342. package/lib/typescript/specs/cipher.nitro.d.ts.map +1 -0
  343. package/lib/typescript/specs/ecKeyPair.nitro.d.ts +20 -0
  344. package/lib/typescript/specs/ecKeyPair.nitro.d.ts.map +1 -0
  345. package/lib/typescript/specs/edKeyPair.nitro.d.ts +17 -0
  346. package/lib/typescript/specs/edKeyPair.nitro.d.ts.map +1 -0
  347. package/lib/typescript/specs/hash.nitro.d.ts +13 -0
  348. package/lib/typescript/specs/hash.nitro.d.ts.map +1 -0
  349. package/lib/typescript/specs/hmac.nitro.d.ts +10 -0
  350. package/lib/typescript/specs/hmac.nitro.d.ts.map +1 -0
  351. package/lib/typescript/specs/keyObjectHandle.nitro.d.ts +14 -0
  352. package/lib/typescript/specs/keyObjectHandle.nitro.d.ts.map +1 -0
  353. package/lib/typescript/specs/pbkdf2.nitro.d.ts +9 -0
  354. package/lib/typescript/specs/pbkdf2.nitro.d.ts.map +1 -0
  355. package/lib/typescript/specs/rsaKeyPair.nitro.d.ts +20 -0
  356. package/lib/typescript/specs/rsaKeyPair.nitro.d.ts.map +1 -0
  357. package/lib/typescript/subtle.d.ts +17 -0
  358. package/lib/typescript/subtle.d.ts.map +1 -0
  359. package/lib/typescript/utils/cipher.d.ts +7 -0
  360. package/lib/typescript/utils/cipher.d.ts.map +1 -0
  361. package/lib/typescript/utils/conversion.d.ts +24 -2
  362. package/lib/typescript/utils/conversion.d.ts.map +1 -1
  363. package/lib/typescript/utils/errors.d.ts +7 -0
  364. package/lib/typescript/utils/errors.d.ts.map +1 -0
  365. package/lib/typescript/utils/hashnames.d.ts +13 -0
  366. package/lib/typescript/utils/hashnames.d.ts.map +1 -0
  367. package/lib/typescript/utils/index.d.ts +6 -5
  368. package/lib/typescript/utils/index.d.ts.map +1 -1
  369. package/lib/typescript/utils/noble.d.ts +19 -0
  370. package/lib/typescript/utils/noble.d.ts.map +1 -0
  371. package/lib/typescript/utils/types.d.ts +252 -2
  372. package/lib/typescript/utils/types.d.ts.map +1 -1
  373. package/lib/typescript/utils/validation.d.ts +13 -0
  374. package/lib/typescript/utils/validation.d.ts.map +1 -0
  375. package/nitrogen/generated/.gitattributes +1 -0
  376. package/nitrogen/generated/android/QuickCrypto+autolinking.cmake +47 -4
  377. package/nitrogen/generated/android/QuickCrypto+autolinking.gradle +4 -3
  378. package/nitrogen/generated/android/QuickCryptoOnLoad.cpp +144 -0
  379. package/nitrogen/generated/android/QuickCryptoOnLoad.hpp +25 -0
  380. package/nitrogen/generated/android/kotlin/com/margelo/nitro/crypto/QuickCryptoOnLoad.kt +35 -0
  381. package/nitrogen/generated/ios/QuickCrypto+autolinking.rb +11 -8
  382. package/nitrogen/generated/ios/QuickCrypto-Swift-Cxx-Bridge.cpp +11 -3
  383. package/nitrogen/generated/ios/QuickCrypto-Swift-Cxx-Bridge.hpp +5 -3
  384. package/nitrogen/generated/ios/QuickCrypto-Swift-Cxx-Umbrella.hpp +16 -7
  385. package/nitrogen/generated/ios/QuickCryptoAutolinking.mm +135 -0
  386. package/nitrogen/generated/ios/QuickCryptoAutolinking.swift +12 -0
  387. package/nitrogen/generated/shared/c++/CFRGKeyPairType.hpp +84 -0
  388. package/nitrogen/generated/shared/c++/CipherArgs.hpp +86 -0
  389. package/nitrogen/generated/shared/c++/HybridBlake3Spec.cpp +28 -0
  390. package/nitrogen/generated/shared/c++/HybridBlake3Spec.hpp +76 -0
  391. package/nitrogen/generated/shared/c++/HybridCipherFactorySpec.cpp +21 -0
  392. package/nitrogen/generated/shared/c++/HybridCipherFactorySpec.hpp +67 -0
  393. package/nitrogen/generated/shared/c++/HybridCipherSpec.cpp +28 -0
  394. package/nitrogen/generated/shared/c++/HybridCipherSpec.hpp +76 -0
  395. package/nitrogen/generated/shared/c++/HybridEcKeyPairSpec.cpp +29 -0
  396. package/nitrogen/generated/shared/c++/HybridEcKeyPairSpec.hpp +77 -0
  397. package/nitrogen/generated/shared/c++/HybridEdKeyPairSpec.cpp +30 -0
  398. package/nitrogen/generated/shared/c++/HybridEdKeyPairSpec.hpp +75 -0
  399. package/nitrogen/generated/shared/c++/HybridHashSpec.cpp +26 -0
  400. package/nitrogen/generated/shared/c++/HybridHashSpec.hpp +75 -0
  401. package/nitrogen/generated/shared/c++/HybridHmacSpec.cpp +23 -0
  402. package/nitrogen/generated/shared/c++/HybridHmacSpec.hpp +66 -0
  403. package/nitrogen/generated/shared/c++/HybridKeyObjectHandleSpec.cpp +26 -0
  404. package/nitrogen/generated/shared/c++/HybridKeyObjectHandleSpec.hpp +92 -0
  405. package/nitrogen/generated/shared/c++/HybridPbkdf2Spec.cpp +22 -0
  406. package/nitrogen/generated/shared/c++/HybridPbkdf2Spec.hpp +66 -0
  407. package/nitrogen/generated/shared/c++/HybridRandomSpec.cpp +2 -3
  408. package/nitrogen/generated/shared/c++/HybridRandomSpec.hpp +9 -6
  409. package/nitrogen/generated/shared/c++/HybridRsaKeyPairSpec.cpp +29 -0
  410. package/nitrogen/generated/shared/c++/HybridRsaKeyPairSpec.hpp +77 -0
  411. package/nitrogen/generated/shared/c++/JWK.hpp +161 -0
  412. package/nitrogen/generated/shared/c++/JWKkty.hpp +84 -0
  413. package/nitrogen/generated/shared/c++/JWKuse.hpp +76 -0
  414. package/nitrogen/generated/shared/c++/KFormatType.hpp +63 -0
  415. package/nitrogen/generated/shared/c++/KeyDetail.hpp +92 -0
  416. package/nitrogen/generated/shared/c++/KeyEncoding.hpp +64 -0
  417. package/nitrogen/generated/shared/c++/KeyObject.hpp +67 -0
  418. package/nitrogen/generated/shared/c++/KeyType.hpp +63 -0
  419. package/nitrogen/generated/shared/c++/KeyUsage.hpp +116 -0
  420. package/nitrogen/generated/shared/c++/NamedCurve.hpp +80 -0
  421. package/package.json +66 -39
  422. package/src/blake3.ts +123 -0
  423. package/src/cipher.ts +335 -0
  424. package/src/ec.ts +432 -0
  425. package/src/ed.ts +256 -0
  426. package/src/expo-plugin/@types.ts +7 -0
  427. package/src/expo-plugin/withRNQC.ts +23 -0
  428. package/src/expo-plugin/withSodiumAndroid.ts +24 -0
  429. package/src/expo-plugin/withSodiumIos.ts +30 -0
  430. package/src/expo-plugin/withXCode.ts +55 -0
  431. package/src/hash.ts +274 -0
  432. package/src/hmac.ts +135 -0
  433. package/src/index.ts +32 -29
  434. package/src/keys/classes.ts +317 -0
  435. package/src/keys/generateKeyPair.ts +145 -0
  436. package/src/keys/index.ts +52 -0
  437. package/src/keys/signVerify.ts +39 -0
  438. package/src/keys/utils.ts +190 -0
  439. package/src/pbkdf2.ts +154 -0
  440. package/src/random.ts +26 -23
  441. package/src/rsa.ts +176 -0
  442. package/src/specs/blake3.nitro.ts +12 -0
  443. package/src/specs/cipher.nitro.ts +25 -0
  444. package/src/specs/ecKeyPair.nitro.ts +38 -0
  445. package/src/specs/edKeyPair.nitro.ts +43 -0
  446. package/src/specs/hash.nitro.ts +10 -0
  447. package/src/specs/hmac.nitro.ts +7 -0
  448. package/src/specs/keyObjectHandle.nitro.ts +31 -0
  449. package/src/specs/pbkdf2.nitro.ts +18 -0
  450. package/src/specs/random.nitro.ts +2 -2
  451. package/src/specs/rsaKeyPair.nitro.ts +33 -0
  452. package/src/subtle.ts +614 -0
  453. package/src/utils/cipher.ts +60 -0
  454. package/src/utils/conversion.ts +143 -9
  455. package/src/utils/errors.ts +15 -0
  456. package/src/utils/hashnames.ts +98 -0
  457. package/src/utils/index.ts +6 -6
  458. package/src/utils/noble.ts +85 -0
  459. package/src/utils/types.ts +423 -3
  460. package/src/utils/validation.ts +130 -0
  461. package/ios/QuickCryptoOnLoad.mm +0 -19
  462. package/lib/module/package.json +0 -1
@@ -0,0 +1,704 @@
1
+ //! Low-level tree manipulations and other sharp tools
2
+ //!
3
+ //! The target audience for this module is projects like [Bao](https://github.com/oconnor663/bao),
4
+ //! which work directly with the interior hashes ("chaining values") of BLAKE3 chunks and subtrees.
5
+ //! For example, you could use these functions to implement a BitTorrent-like protocol using the
6
+ //! BLAKE3 tree structure, or to hash an input that's distributed across different machines. These
7
+ //! use cases are advanced, and most applications don't need this module. Also:
8
+ //!
9
+ //! <div class="warning">
10
+ //!
11
+ //! **Warning:** This module is *hazardous material*. If you've heard folks say *don't roll your
12
+ //! own crypto,* this is the sort of thing they're talking about. These functions have complicated
13
+ //! requirements, and any mistakes will give you garbage output and/or break the security
14
+ //! properties that BLAKE3 is supposed to have. Read section 2.1 of [the BLAKE3
15
+ //! paper](https://github.com/BLAKE3-team/BLAKE3-specs/blob/master/blake3.pdf) to understand the
16
+ //! tree structure you need to maintain. Test your code against [`blake3::hash`](../fn.hash.html)
17
+ //! and make sure you can get the same outputs for [lots of different
18
+ //! inputs](https://github.com/BLAKE3-team/BLAKE3/blob/master/test_vectors/test_vectors.json).
19
+ //!
20
+ //! </div>
21
+ //!
22
+ //! On the other hand:
23
+ //!
24
+ //! <div class="warning">
25
+ //!
26
+ //! **Encouragement:** Playing with these functions is a great way to learn how BLAKE3 works on the
27
+ //! inside. Have fun!
28
+ //!
29
+ //! </div>
30
+ //!
31
+ //! The main entrypoint for this module is the [`HasherExt`] trait, particularly the
32
+ //! [`set_input_offset`](HasherExt::set_input_offset) and
33
+ //! [`finalize_non_root`](HasherExt::finalize_non_root) methods. These let you compute the chaining
34
+ //! values of individual chunks or subtrees. You then combine these chaining values into larger
35
+ //! subtrees using [`merge_subtrees_non_root`] and finally (once at the very top)
36
+ //! [`merge_subtrees_root`] or [`merge_subtrees_root_xof`].
37
+ //!
38
+ //! # Examples
39
+ //!
40
+ //! Here's an example of computing all the interior hashes in a 3-chunk tree:
41
+ //!
42
+ //! ```text
43
+ //! root
44
+ //! / \
45
+ //! parent \
46
+ //! / \ \
47
+ //! chunk0 chunk1 chunk2
48
+ //! ```
49
+ //!
50
+ //! ```
51
+ //! # fn main() {
52
+ //! use blake3::{Hasher, CHUNK_LEN};
53
+ //! use blake3::hazmat::{merge_subtrees_non_root, merge_subtrees_root, Mode};
54
+ //! use blake3::hazmat::HasherExt; // an extension trait for Hasher
55
+ //!
56
+ //! let chunk0 = [b'a'; CHUNK_LEN];
57
+ //! let chunk1 = [b'b'; CHUNK_LEN];
58
+ //! let chunk2 = [b'c'; 42]; // The final chunk can be short.
59
+ //!
60
+ //! // Compute the non-root hashes ("chaining values") of all three chunks. Chunks or subtrees
61
+ //! // that don't begin at the start of the input use `set_input_offset` to say where they begin.
62
+ //! let chunk0_cv = Hasher::new()
63
+ //! // .set_input_offset(0) is the default.
64
+ //! .update(&chunk0)
65
+ //! .finalize_non_root();
66
+ //! let chunk1_cv = Hasher::new()
67
+ //! .set_input_offset(CHUNK_LEN as u64)
68
+ //! .update(&chunk1)
69
+ //! .finalize_non_root();
70
+ //! let chunk2_cv = Hasher::new()
71
+ //! .set_input_offset(2 * CHUNK_LEN as u64)
72
+ //! .update(&chunk2)
73
+ //! .finalize_non_root();
74
+ //!
75
+ //! // Join the first two chunks with a non-root parent node and compute its chaining value.
76
+ //! let parent_cv = merge_subtrees_non_root(&chunk0_cv, &chunk1_cv, Mode::Hash);
77
+ //!
78
+ //! // Join that parent node and the third chunk with a root parent node and compute the hash.
79
+ //! let root_hash = merge_subtrees_root(&parent_cv, &chunk2_cv, Mode::Hash);
80
+ //!
81
+ //! // Double check that we got the right answer.
82
+ //! let mut combined_input = Vec::new();
83
+ //! combined_input.extend_from_slice(&chunk0);
84
+ //! combined_input.extend_from_slice(&chunk1);
85
+ //! combined_input.extend_from_slice(&chunk2);
86
+ //! assert_eq!(root_hash, blake3::hash(&combined_input));
87
+ //! # }
88
+ //! ```
89
+ //!
90
+ //! Hashing many chunks together is important for performance, because it allows the implementation
91
+ //! to use SIMD parallelism internally. ([AVX-512](https://en.wikipedia.org/wiki/AVX-512) for
92
+ //! example needs 16 chunks to really get going.) We can reproduce `parent_cv` by hashing `chunk0`
93
+ //! and `chunk1` at the same time:
94
+ //!
95
+ //! ```
96
+ //! # fn main() {
97
+ //! # use blake3::{Hasher, CHUNK_LEN};
98
+ //! # use blake3::hazmat::{Mode, HasherExt, merge_subtrees_non_root, merge_subtrees_root};
99
+ //! # let chunk0 = [b'a'; CHUNK_LEN];
100
+ //! # let chunk1 = [b'b'; CHUNK_LEN];
101
+ //! # let chunk0_cv = Hasher::new().update(&chunk0).finalize_non_root();
102
+ //! # let chunk1_cv = Hasher::new().set_input_offset(CHUNK_LEN as u64).update(&chunk1).finalize_non_root();
103
+ //! # let parent_cv = merge_subtrees_non_root(&chunk0_cv, &chunk1_cv, Mode::Hash);
104
+ //! # let mut combined_input = Vec::new();
105
+ //! # combined_input.extend_from_slice(&chunk0);
106
+ //! # combined_input.extend_from_slice(&chunk1);
107
+ //! let left_subtree_cv = Hasher::new()
108
+ //! // .set_input_offset(0) is the default.
109
+ //! .update(&combined_input[..2 * CHUNK_LEN])
110
+ //! .finalize_non_root();
111
+ //! assert_eq!(left_subtree_cv, parent_cv);
112
+ //!
113
+ //! // Using multiple updates gives the same answer, though it's not as efficient.
114
+ //! let mut subtree_hasher = Hasher::new();
115
+ //! // Again, .set_input_offset(0) is the default.
116
+ //! subtree_hasher.update(&chunk0);
117
+ //! subtree_hasher.update(&chunk1);
118
+ //! assert_eq!(left_subtree_cv, subtree_hasher.finalize_non_root());
119
+ //! # }
120
+ //! ```
121
+ //!
122
+ //! However, hashing multiple chunks together **must** respect the overall tree structure. Hashing
123
+ //! `chunk0` and `chunk1` together is valid, but hashing `chunk1` and `chunk2` together is
124
+ //! incorrect and gives a garbage result that will never match a standard BLAKE3 hash. The
125
+ //! implementation includes a few best-effort asserts to catch some of these mistakes, but these
126
+ //! checks aren't guaranteed. For example, this second call to `update` currently panics:
127
+ //!
128
+ //! ```should_panic
129
+ //! # fn main() {
130
+ //! # use blake3::{Hasher, CHUNK_LEN};
131
+ //! # use blake3::hazmat::HasherExt;
132
+ //! # let chunk0 = [b'a'; CHUNK_LEN];
133
+ //! # let chunk1 = [b'b'; CHUNK_LEN];
134
+ //! # let chunk2 = [b'c'; 42];
135
+ //! let oops = Hasher::new()
136
+ //! .set_input_offset(CHUNK_LEN as u64)
137
+ //! .update(&chunk1)
138
+ //! // PANIC: "the subtree starting at 1024 contains at most 1024 bytes"
139
+ //! .update(&chunk2)
140
+ //! .finalize_non_root();
141
+ //! # }
142
+ //! ```
143
+ //!
144
+ //! For more on valid tree structures, see the docs for and [`left_subtree_len`] and
145
+ //! [`max_subtree_len`], and see section 2.1 of [the BLAKE3
146
+ //! paper](https://github.com/BLAKE3-team/BLAKE3-specs/blob/master/blake3.pdf). Note that the
147
+ //! merging functions ([`merge_subtrees_root`] and friends) don't know the shape of the left and
148
+ //! right subtrees you're giving them, and they can't help you catch mistakes. The best way to
149
+ //! catch mistakes with these is to compare your root output to the [`blake3::hash`](crate::hash)
150
+ //! of the same input.
151
+
152
+ use crate::platform::Platform;
153
+ use crate::{CVWords, Hasher, CHUNK_LEN, IV, KEY_LEN, OUT_LEN};
154
+
155
+ /// Extension methods for [`Hasher`]. This is the main entrypoint to the `hazmat` module.
156
+ pub trait HasherExt {
157
+ /// Similar to [`Hasher::new_derive_key`] but using a pre-hashed [`ContextKey`] from
158
+ /// [`hash_derive_key_context`].
159
+ ///
160
+ /// The [`hash_derive_key_context`] function is _only_ valid source of the [`ContextKey`]
161
+ ///
162
+ /// # Example
163
+ ///
164
+ /// ```
165
+ /// use blake3::Hasher;
166
+ /// use blake3::hazmat::HasherExt;
167
+ ///
168
+ /// let context_key = blake3::hazmat::hash_derive_key_context("foo");
169
+ /// let mut hasher = Hasher::new_from_context_key(&context_key);
170
+ /// hasher.update(b"bar");
171
+ /// let derived_key = *hasher.finalize().as_bytes();
172
+ ///
173
+ /// assert_eq!(derived_key, blake3::derive_key("foo", b"bar"));
174
+ /// ```
175
+ fn new_from_context_key(context_key: &ContextKey) -> Self;
176
+
177
+ /// Configure the `Hasher` to process a chunk or subtree starting at `offset` bytes into the
178
+ /// whole input.
179
+ ///
180
+ /// You must call this function before processing any input with [`update`](Hasher::update) or
181
+ /// similar. This step isn't required for the first chunk, or for a subtree that includes the
182
+ /// first chunk (i.e. when the `offset` is zero), but it's required for all other chunks and
183
+ /// subtrees.
184
+ ///
185
+ /// The starting input offset of a subtree implies a maximum possible length for that subtree.
186
+ /// See [`max_subtree_len`] and section 2.1 of [the BLAKE3
187
+ /// paper](https://github.com/BLAKE3-team/BLAKE3-specs/blob/master/blake3.pdf). Note that only
188
+ /// subtrees along the right edge of the whole tree can have a length less than their maximum
189
+ /// possible length.
190
+ ///
191
+ /// See the [module level examples](index.html#examples).
192
+ ///
193
+ /// # Panics
194
+ ///
195
+ /// This function panics if the `Hasher` has already accepted any input with
196
+ /// [`update`](Hasher::update) or similar.
197
+ ///
198
+ /// This should always be paired with [`finalize_non_root`](HasherExt::finalize_non_root). It's
199
+ /// never correct to use a non-zero input offset with [`finalize`](Hasher::finalize) or
200
+ /// [`finalize_xof`](Hasher::finalize_xof). The `offset` must also be a multiple of
201
+ /// `CHUNK_LEN`. Violating either of these rules will currently fail an assertion and panic,
202
+ /// but this is not guaranteed.
203
+ fn set_input_offset(&mut self, offset: u64) -> &mut Self;
204
+
205
+ /// Finalize the non-root hash ("chaining value") of the current chunk or subtree.
206
+ ///
207
+ /// Afterwards you can merge subtree chaining values into parent nodes using
208
+ /// [`merge_subtrees_non_root`] and ultimately into the root node with either
209
+ /// [`merge_subtrees_root`] (similar to [`Hasher::finalize`]) or [`merge_subtrees_root_xof`]
210
+ /// (similar to [`Hasher::finalize_xof`]).
211
+ ///
212
+ /// See the [module level examples](index.html#examples), particularly the discussion of valid
213
+ /// tree structures.
214
+ fn finalize_non_root(&self) -> ChainingValue;
215
+ }
216
+
217
+ impl HasherExt for Hasher {
218
+ fn new_from_context_key(context_key: &[u8; KEY_LEN]) -> Hasher {
219
+ let context_key_words = crate::platform::words_from_le_bytes_32(context_key);
220
+ Hasher::new_internal(&context_key_words, crate::DERIVE_KEY_MATERIAL)
221
+ }
222
+
223
+ fn set_input_offset(&mut self, offset: u64) -> &mut Hasher {
224
+ assert_eq!(self.count(), 0, "hasher has already accepted input");
225
+ assert_eq!(
226
+ offset % CHUNK_LEN as u64,
227
+ 0,
228
+ "offset ({offset}) must be a chunk boundary (divisible by {CHUNK_LEN})",
229
+ );
230
+ let counter = offset / CHUNK_LEN as u64;
231
+ self.chunk_state.chunk_counter = counter;
232
+ self.initial_chunk_counter = counter;
233
+ self
234
+ }
235
+
236
+ fn finalize_non_root(&self) -> ChainingValue {
237
+ assert_ne!(self.count(), 0, "empty subtrees are never valid");
238
+ self.final_output().chaining_value()
239
+ }
240
+ }
241
+
242
+ /// The maximum length of a subtree in bytes, given its starting offset in bytes
243
+ ///
244
+ /// If you try to hash more than this many bytes as one subtree, you'll end up merging parent nodes
245
+ /// that shouldn't be merged, and your output will be garbage. [`Hasher::update`] will currently
246
+ /// panic in this case, but this is not guaranteed.
247
+ ///
248
+ /// For input offset zero (the default), there is no maximum length, and this function returns
249
+ /// `None`. For all other offsets it returns `Some`. Note that valid offsets must be a multiple of
250
+ /// [`CHUNK_LEN`] (1024); it's not possible to start hashing a chunk in the middle.
251
+ ///
252
+ /// In the example tree below, chunks are numbered by their _0-based index_. The subtree that
253
+ /// _starts_ with chunk 3, i.e. `input_offset = 3 * CHUNK_LEN`, includes only that one chunk, so
254
+ /// its max length is `Some(CHUNK_LEN)`. The subtree that starts with chunk 6 includes chunk 7 but
255
+ /// not chunk 8, so its max length is `Some(2 * CHUNK_LEN)`. The subtree that starts with chunk 12
256
+ /// includes chunks 13, 14, and 15, but if the tree were bigger it would not include chunk 16, so
257
+ /// its max length is `Some(4 * CHUNK_LEN)`. One way to think about the rule here is that, if you
258
+ /// go beyond the max subtree length from a given starting offset, you start dealing with subtrees
259
+ /// that include chunks _to the left_ of where you started.
260
+ ///
261
+ /// ```text
262
+ /// root
263
+ /// / \
264
+ /// . .
265
+ /// / \ / \
266
+ /// . . . .
267
+ /// / \ / \ / \ / \
268
+ /// . . . . . . . .
269
+ /// / \ / \ / \ / \ / \ / \ / \ / \
270
+ /// 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
271
+ /// ```
272
+ ///
273
+ /// The general rule turns out to be that for a subtree starting at a 0-based chunk index N greater
274
+ /// than zero, the maximum number of chunks in that subtree is the largest power-of-two that
275
+ /// divides N, which is given by `1 << N.trailing_zeros()`.
276
+ ///
277
+ /// This function can be useful for writing tests or debug assertions, but it's actually rare to
278
+ /// use this for real control flow. Callers who split their input recursively using
279
+ /// [`left_subtree_len`] will automatically satisfy the `max_subtree_len` bound and don't
280
+ /// necessarily need to check. It's also common to choose some fixed power-of-two subtree size, say
281
+ /// 64 chunks, and divide your input up into slices of that fixed length (with the final slice
282
+ /// possibly short). This approach also automatically satisfies the `max_subtree_len` bound and
283
+ /// doesn't need to check. Proving that this is true can be an interesting exercise. Note that
284
+ /// chunks 0, 4, 8, and 12 all begin subtrees of at least 4 chunks in the example tree above.
285
+ ///
286
+ /// # Panics
287
+ ///
288
+ /// This function currently panics if `input_offset` is not a multiple of `CHUNK_LEN`. This is not
289
+ /// guaranteed.
290
+ #[inline(always)]
291
+ pub fn max_subtree_len(input_offset: u64) -> Option<u64> {
292
+ if input_offset == 0 {
293
+ return None;
294
+ }
295
+ assert_eq!(input_offset % CHUNK_LEN as u64, 0);
296
+ let counter = input_offset / CHUNK_LEN as u64;
297
+ let max_chunks = 1 << counter.trailing_zeros();
298
+ Some(max_chunks * CHUNK_LEN as u64)
299
+ }
300
+
301
+ #[test]
302
+ fn test_max_subtree_len() {
303
+ assert_eq!(max_subtree_len(0), None);
304
+ // (chunk index, max chunks)
305
+ let cases = [
306
+ (1, 1),
307
+ (2, 2),
308
+ (3, 1),
309
+ (4, 4),
310
+ (5, 1),
311
+ (6, 2),
312
+ (7, 1),
313
+ (8, 8),
314
+ ];
315
+ for (chunk_index, max_chunks) in cases {
316
+ let input_offset = chunk_index * CHUNK_LEN as u64;
317
+ assert_eq!(
318
+ max_subtree_len(input_offset),
319
+ Some(max_chunks * CHUNK_LEN as u64),
320
+ );
321
+ }
322
+ }
323
+
324
+ /// Given the length in bytes of either a complete input or a subtree input, return the number of
325
+ /// bytes that belong to its left child subtree. The rest belong to its right child subtree.
326
+ ///
327
+ /// Concretely, this function returns the largest power-of-two number of bytes that's strictly less
328
+ /// than `input_len`. This leads to a tree where all left subtrees are "complete" and at least as
329
+ /// large as their sibling right subtrees, as specified in section 2.1 of [the BLAKE3
330
+ /// paper](https://github.com/BLAKE3-team/BLAKE3-specs/blob/master/blake3.pdf). For example, if an
331
+ /// input is exactly two chunks, its left and right subtrees both get one chunk. But if an input is
332
+ /// two chunks plus one more byte, then its left subtree gets two chunks, and its right subtree
333
+ /// only gets one byte.
334
+ ///
335
+ /// This function isn't meaningful for one chunk of input, because chunks don't have children. It
336
+ /// currently panics in debug mode if `input_len <= CHUNK_LEN`.
337
+ ///
338
+ /// # Example
339
+ ///
340
+ /// Hash a input of random length as two subtrees:
341
+ ///
342
+ /// ```
343
+ /// # #[cfg(feature = "std")] {
344
+ /// use blake3::hazmat::{left_subtree_len, merge_subtrees_root, HasherExt, Mode};
345
+ /// use blake3::{Hasher, CHUNK_LEN};
346
+ ///
347
+ /// // Generate a random-length input. Note that to be split into two subtrees, the input length
348
+ /// // must be greater than CHUNK_LEN.
349
+ /// let input_len = rand::random_range(CHUNK_LEN + 1..1_000_000);
350
+ /// let mut input = vec![0; input_len];
351
+ /// rand::fill(&mut input[..]);
352
+ ///
353
+ /// // Compute the left and right subtree hashes and then the root hash. left_subtree_len() tells
354
+ /// // us exactly where to split the input. Any other split would either panic (if we're lucky) or
355
+ /// // lead to an incorrect root hash.
356
+ /// let left_len = left_subtree_len(input_len as u64) as usize;
357
+ /// let left_subtree_cv = Hasher::new()
358
+ /// .update(&input[..left_len])
359
+ /// .finalize_non_root();
360
+ /// let right_subtree_cv = Hasher::new()
361
+ /// .set_input_offset(left_len as u64)
362
+ /// .update(&input[left_len..])
363
+ /// .finalize_non_root();
364
+ /// let root_hash = merge_subtrees_root(&left_subtree_cv, &right_subtree_cv, Mode::Hash);
365
+ ///
366
+ /// // Double check the answer.
367
+ /// assert_eq!(root_hash, blake3::hash(&input));
368
+ /// # }
369
+ /// ```
370
+ #[inline(always)]
371
+ pub fn left_subtree_len(input_len: u64) -> u64 {
372
+ debug_assert!(input_len > CHUNK_LEN as u64);
373
+ // Note that .next_power_of_two() is greater than *or equal*.
374
+ ((input_len + 1) / 2).next_power_of_two()
375
+ }
376
+
377
+ #[test]
378
+ fn test_left_subtree_len() {
379
+ assert_eq!(left_subtree_len(1025), 1024);
380
+ for boundary_case in [2, 4, 8, 16, 32, 64] {
381
+ let input_len = boundary_case * CHUNK_LEN as u64;
382
+ assert_eq!(left_subtree_len(input_len - 1), input_len / 2);
383
+ assert_eq!(left_subtree_len(input_len), input_len / 2);
384
+ assert_eq!(left_subtree_len(input_len + 1), input_len);
385
+ }
386
+ }
387
+
388
+ /// The `mode` argument to [`merge_subtrees_root`] and friends
389
+ ///
390
+ /// See the [module level examples](index.html#examples).
391
+ #[derive(Copy, Clone, Debug)]
392
+ pub enum Mode<'a> {
393
+ /// Corresponding to [`hash`](crate::hash)
394
+ Hash,
395
+
396
+ /// Corresponding to [`keyed_hash`](crate::hash)
397
+ KeyedHash(&'a [u8; KEY_LEN]),
398
+
399
+ /// Corresponding to [`derive_key`](crate::hash)
400
+ ///
401
+ /// The [`ContextKey`] comes from [`hash_derive_key_context`].
402
+ DeriveKeyMaterial(&'a ContextKey),
403
+ }
404
+
405
+ impl<'a> Mode<'a> {
406
+ fn key_words(&self) -> CVWords {
407
+ match self {
408
+ Mode::Hash => *IV,
409
+ Mode::KeyedHash(key) => crate::platform::words_from_le_bytes_32(key),
410
+ Mode::DeriveKeyMaterial(cx_key) => crate::platform::words_from_le_bytes_32(cx_key),
411
+ }
412
+ }
413
+
414
+ fn flags_byte(&self) -> u8 {
415
+ match self {
416
+ Mode::Hash => 0,
417
+ Mode::KeyedHash(_) => crate::KEYED_HASH,
418
+ Mode::DeriveKeyMaterial(_) => crate::DERIVE_KEY_MATERIAL,
419
+ }
420
+ }
421
+ }
422
+
423
+ /// "Chaining value" is the academic term for a non-root or non-final hash.
424
+ ///
425
+ /// Besides just sounding fancy, it turns out there are [security
426
+ /// reasons](https://jacko.io/tree_hashing.html) to be careful about the difference between
427
+ /// (root/final) hashes and (non-root/non-final) chaining values.
428
+ pub type ChainingValue = [u8; OUT_LEN];
429
+
430
+ fn merge_subtrees_inner(
431
+ left_child: &ChainingValue,
432
+ right_child: &ChainingValue,
433
+ mode: Mode,
434
+ ) -> crate::Output {
435
+ crate::parent_node_output(
436
+ &left_child,
437
+ &right_child,
438
+ &mode.key_words(),
439
+ mode.flags_byte(),
440
+ Platform::detect(),
441
+ )
442
+ }
443
+
444
+ /// Compute a non-root parent node chaining value from two child chaining values.
445
+ ///
446
+ /// See the [module level examples](index.html#examples), particularly the discussion of valid tree
447
+ /// structures. The left and right child chaining values can come from either
448
+ /// [`Hasher::finalize_non_root`](HasherExt::finalize_non_root) or other calls to
449
+ /// `merge_subtrees_non_root`. "Chaining value" is the academic term for a non-root or non-final
450
+ /// hash.
451
+ pub fn merge_subtrees_non_root(
452
+ left_child: &ChainingValue,
453
+ right_child: &ChainingValue,
454
+ mode: Mode,
455
+ ) -> ChainingValue {
456
+ merge_subtrees_inner(left_child, right_child, mode).chaining_value()
457
+ }
458
+
459
+ /// Compute a root hash from two child chaining values.
460
+ ///
461
+ /// See the [module level examples](index.html#examples), particularly the discussion of valid tree
462
+ /// structures. The left and right child chaining values can come from either
463
+ /// [`Hasher::finalize_non_root`](HasherExt::finalize_non_root) or [`merge_subtrees_non_root`].
464
+ /// "Chaining value" is the academic term for a non-root or non-final hash.
465
+ ///
466
+ /// Note that inputs of [`CHUNK_LEN`] or less don't produce any parent nodes and can't be hashed
467
+ /// using this function. In that case you must get the root hash from [`Hasher::finalize`] (or just
468
+ /// [`blake3::hash`](crate::hash)).
469
+ pub fn merge_subtrees_root(
470
+ left_child: &ChainingValue,
471
+ right_child: &ChainingValue,
472
+ mode: Mode,
473
+ ) -> crate::Hash {
474
+ merge_subtrees_inner(left_child, right_child, mode).root_hash()
475
+ }
476
+
477
+ /// Build a root [`OutputReader`](crate::OutputReader) from two child chaining values.
478
+ ///
479
+ /// See also the [module level examples](index.html#examples), particularly the discussion of valid
480
+ /// tree structures. The left and right child chaining values can come from either
481
+ /// [`Hasher::finalize_non_root`](HasherExt::finalize_non_root) or [`merge_subtrees_non_root`].
482
+ /// "Chaining value" is the academic term for a non-root or non-final hash.
483
+ ///
484
+ /// Note that inputs of [`CHUNK_LEN`] or less don't produce any parent nodes and can't be hashed
485
+ /// using this function. In that case you must get the `OutputReader` from
486
+ /// [`Hasher::finalize_xof`].
487
+ ///
488
+ /// # Example
489
+ ///
490
+ /// ```
491
+ /// use blake3::hazmat::{merge_subtrees_root_xof, HasherExt, Mode};
492
+ /// use blake3::{Hasher, CHUNK_LEN};
493
+ ///
494
+ /// // Hash a 2-chunk subtree in steps. Note that only
495
+ /// // the final chunk can be shorter than CHUNK_LEN.
496
+ /// let chunk0 = &[42; CHUNK_LEN];
497
+ /// let chunk1 = b"hello world";
498
+ /// let chunk0_cv = Hasher::new()
499
+ /// .update(chunk0)
500
+ /// .finalize_non_root();
501
+ /// let chunk1_cv = Hasher::new()
502
+ /// .set_input_offset(CHUNK_LEN as u64)
503
+ /// .update(chunk1)
504
+ /// .finalize_non_root();
505
+ ///
506
+ /// // Obtain a blake3::OutputReader at the root and extract 1000 bytes.
507
+ /// let mut output_reader = merge_subtrees_root_xof(&chunk0_cv, &chunk1_cv, Mode::Hash);
508
+ /// let mut output_bytes = [0; 1_000];
509
+ /// output_reader.fill(&mut output_bytes);
510
+ ///
511
+ /// // Double check the answer.
512
+ /// let mut hasher = Hasher::new();
513
+ /// hasher.update(chunk0);
514
+ /// hasher.update(chunk1);
515
+ /// let mut expected = [0; 1_000];
516
+ /// hasher.finalize_xof().fill(&mut expected);
517
+ /// assert_eq!(output_bytes, expected);
518
+ /// ```
519
+ pub fn merge_subtrees_root_xof(
520
+ left_child: &ChainingValue,
521
+ right_child: &ChainingValue,
522
+ mode: Mode,
523
+ ) -> crate::OutputReader {
524
+ crate::OutputReader::new(merge_subtrees_inner(left_child, right_child, mode))
525
+ }
526
+
527
+ /// An alias to distinguish [`hash_derive_key_context`] outputs from other keys.
528
+ pub type ContextKey = [u8; KEY_LEN];
529
+
530
+ /// Hash a [`derive_key`](crate::derive_key) context string and return a [`ContextKey`].
531
+ ///
532
+ /// The _only_ valid uses for the returned [`ContextKey`] are [`Hasher::new_from_context_key`] and
533
+ /// [`Mode::DeriveKeyMaterial`] (together with the merge subtree functions).
534
+ ///
535
+ /// # Example
536
+ ///
537
+ /// ```
538
+ /// use blake3::Hasher;
539
+ /// use blake3::hazmat::HasherExt;
540
+ ///
541
+ /// let context_key = blake3::hazmat::hash_derive_key_context("foo");
542
+ /// let mut hasher = Hasher::new_from_context_key(&context_key);
543
+ /// hasher.update(b"bar");
544
+ /// let derived_key = *hasher.finalize().as_bytes();
545
+ ///
546
+ /// assert_eq!(derived_key, blake3::derive_key("foo", b"bar"));
547
+ /// ```
548
+ pub fn hash_derive_key_context(context: &str) -> ContextKey {
549
+ crate::hash_all_at_once::<crate::join::SerialJoin>(
550
+ context.as_bytes(),
551
+ IV,
552
+ crate::DERIVE_KEY_CONTEXT,
553
+ )
554
+ .root_hash()
555
+ .0
556
+ }
557
+
558
+ #[cfg(test)]
559
+ mod test {
560
+ use super::*;
561
+
562
+ #[test]
563
+ #[should_panic]
564
+ fn test_empty_subtree_should_panic() {
565
+ Hasher::new().finalize_non_root();
566
+ }
567
+
568
+ #[test]
569
+ #[should_panic]
570
+ fn test_unaligned_offset_should_panic() {
571
+ Hasher::new().set_input_offset(1);
572
+ }
573
+
574
+ #[test]
575
+ #[should_panic]
576
+ fn test_hasher_already_accepted_input_should_panic() {
577
+ Hasher::new().update(b"x").set_input_offset(0);
578
+ }
579
+
580
+ #[test]
581
+ #[should_panic]
582
+ fn test_too_much_input_should_panic() {
583
+ Hasher::new()
584
+ .set_input_offset(CHUNK_LEN as u64)
585
+ .update(&[0; CHUNK_LEN + 1]);
586
+ }
587
+
588
+ #[test]
589
+ #[should_panic]
590
+ fn test_set_input_offset_cant_finalize() {
591
+ Hasher::new().set_input_offset(CHUNK_LEN as u64).finalize();
592
+ }
593
+
594
+ #[test]
595
+ #[should_panic]
596
+ fn test_set_input_offset_cant_finalize_xof() {
597
+ Hasher::new()
598
+ .set_input_offset(CHUNK_LEN as u64)
599
+ .finalize_xof();
600
+ }
601
+
602
+ #[test]
603
+ fn test_grouped_hash() {
604
+ const MAX_CHUNKS: usize = (crate::test::TEST_CASES_MAX + 1) / CHUNK_LEN;
605
+ let mut input_buf = [0; crate::test::TEST_CASES_MAX];
606
+ crate::test::paint_test_input(&mut input_buf);
607
+ for subtree_chunks in [1, 2, 4, 8, 16, 32] {
608
+ #[cfg(feature = "std")]
609
+ dbg!(subtree_chunks);
610
+ let subtree_len = subtree_chunks * CHUNK_LEN;
611
+ for &case in crate::test::TEST_CASES {
612
+ if case <= subtree_len {
613
+ continue;
614
+ }
615
+ #[cfg(feature = "std")]
616
+ dbg!(case);
617
+ let input = &input_buf[..case];
618
+ let expected_hash = crate::hash(input);
619
+
620
+ // Collect all the group chaining values.
621
+ let mut chaining_values = arrayvec::ArrayVec::<ChainingValue, MAX_CHUNKS>::new();
622
+ let mut subtree_offset = 0;
623
+ while subtree_offset < input.len() {
624
+ let take = core::cmp::min(subtree_len, input.len() - subtree_offset);
625
+ let subtree_input = &input[subtree_offset..][..take];
626
+ let subtree_cv = Hasher::new()
627
+ .set_input_offset(subtree_offset as u64)
628
+ .update(subtree_input)
629
+ .finalize_non_root();
630
+ chaining_values.push(subtree_cv);
631
+ subtree_offset += take;
632
+ }
633
+
634
+ // Compress all the chaining_values together, layer by layer.
635
+ assert!(chaining_values.len() >= 2);
636
+ while chaining_values.len() > 2 {
637
+ let n = chaining_values.len();
638
+ // Merge each side-by-side pair in place, overwriting the front half of the
639
+ // array with the merged results. This moves us "up one level" in the tree.
640
+ for i in 0..(n / 2) {
641
+ chaining_values[i] = merge_subtrees_non_root(
642
+ &chaining_values[2 * i],
643
+ &chaining_values[2 * i + 1],
644
+ Mode::Hash,
645
+ );
646
+ }
647
+ // If there's an odd CV out, it moves up.
648
+ if n % 2 == 1 {
649
+ chaining_values[n / 2] = chaining_values[n - 1];
650
+ }
651
+ chaining_values.truncate(n / 2 + n % 2);
652
+ }
653
+ assert_eq!(chaining_values.len(), 2);
654
+ let root_hash =
655
+ merge_subtrees_root(&chaining_values[0], &chaining_values[1], Mode::Hash);
656
+ assert_eq!(expected_hash, root_hash);
657
+ }
658
+ }
659
+ }
660
+
661
+ #[test]
662
+ fn test_keyed_hash_xof() {
663
+ let group0 = &[42; 4096];
664
+ let group1 = &[43; 4095];
665
+ let mut input = [0; 8191];
666
+ input[..4096].copy_from_slice(group0);
667
+ input[4096..].copy_from_slice(group1);
668
+ let key = &[44; 32];
669
+
670
+ let mut expected_output = [0; 100];
671
+ Hasher::new_keyed(&key)
672
+ .update(&input)
673
+ .finalize_xof()
674
+ .fill(&mut expected_output);
675
+
676
+ let mut hazmat_output = [0; 100];
677
+ let left = Hasher::new_keyed(key).update(group0).finalize_non_root();
678
+ let right = Hasher::new_keyed(key)
679
+ .set_input_offset(group0.len() as u64)
680
+ .update(group1)
681
+ .finalize_non_root();
682
+ merge_subtrees_root_xof(&left, &right, Mode::KeyedHash(&key)).fill(&mut hazmat_output);
683
+ assert_eq!(expected_output, hazmat_output);
684
+ }
685
+
686
+ #[test]
687
+ fn test_derive_key() {
688
+ let context = "foo";
689
+ let mut input = [0; 1025];
690
+ crate::test::paint_test_input(&mut input);
691
+ let expected = crate::derive_key(context, &input);
692
+
693
+ let cx_key = hash_derive_key_context(context);
694
+ let left = Hasher::new_from_context_key(&cx_key)
695
+ .update(&input[..1024])
696
+ .finalize_non_root();
697
+ let right = Hasher::new_from_context_key(&cx_key)
698
+ .set_input_offset(1024)
699
+ .update(&input[1024..])
700
+ .finalize_non_root();
701
+ let derived_key = merge_subtrees_root(&left, &right, Mode::DeriveKeyMaterial(&cx_key)).0;
702
+ assert_eq!(expected, derived_key);
703
+ }
704
+ }