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.
- package/QuickCrypto.podspec +143 -7
- package/README.md +12 -6
- package/android/CMakeLists.txt +82 -21
- package/android/build.gradle +47 -4
- package/android/src/main/cpp/cpp-adapter.cpp +3 -10
- package/android/src/main/java/com/margelo/nitro/quickcrypto/QuickCryptoPackage.java +13 -10
- package/app.plugin.js +3 -0
- package/cpp/blake3/HybridBlake3.cpp +118 -0
- package/cpp/blake3/HybridBlake3.hpp +35 -0
- package/cpp/cipher/CCMCipher.cpp +199 -0
- package/cpp/cipher/CCMCipher.hpp +26 -0
- package/cpp/cipher/ChaCha20Cipher.cpp +97 -0
- package/cpp/cipher/ChaCha20Cipher.hpp +25 -0
- package/cpp/cipher/ChaCha20Poly1305Cipher.cpp +170 -0
- package/cpp/cipher/ChaCha20Poly1305Cipher.hpp +30 -0
- package/cpp/cipher/HybridCipher.cpp +322 -0
- package/cpp/cipher/HybridCipher.hpp +68 -0
- package/cpp/cipher/HybridCipherFactory.hpp +97 -0
- package/cpp/cipher/OCBCipher.cpp +55 -0
- package/cpp/cipher/OCBCipher.hpp +19 -0
- package/cpp/cipher/XSalsa20Cipher.cpp +61 -0
- package/cpp/cipher/XSalsa20Cipher.hpp +33 -0
- package/cpp/ec/HybridEcKeyPair.cpp +428 -0
- package/cpp/ec/HybridEcKeyPair.hpp +48 -0
- package/cpp/ed25519/HybridEdKeyPair.cpp +300 -0
- package/cpp/ed25519/HybridEdKeyPair.hpp +63 -0
- package/cpp/hash/HybridHash.cpp +185 -0
- package/cpp/hash/HybridHash.hpp +43 -0
- package/cpp/hmac/HybridHmac.cpp +95 -0
- package/cpp/hmac/HybridHmac.hpp +31 -0
- package/cpp/keys/HybridKeyObjectHandle.cpp +243 -0
- package/cpp/keys/HybridKeyObjectHandle.hpp +42 -0
- package/cpp/keys/KeyObjectData.cpp +226 -0
- package/cpp/keys/KeyObjectData.hpp +71 -0
- package/cpp/keys/node.h +5 -0
- package/cpp/pbkdf2/HybridPbkdf2.cpp +51 -0
- package/cpp/pbkdf2/HybridPbkdf2.hpp +24 -0
- package/cpp/random/HybridRandom.cpp +32 -18
- package/cpp/random/HybridRandom.hpp +18 -30
- package/cpp/rsa/HybridRsaKeyPair.cpp +154 -0
- package/cpp/rsa/HybridRsaKeyPair.hpp +43 -0
- package/cpp/utils/Macros.hpp +68 -0
- package/cpp/utils/Utils.hpp +53 -1
- package/deps/blake3/.cargo/config.toml +2 -0
- package/deps/blake3/.git-blame-ignore-revs +2 -0
- package/deps/blake3/.github/workflows/build_b3sum.py +38 -0
- package/deps/blake3/.github/workflows/ci.yml +491 -0
- package/deps/blake3/.github/workflows/tag.yml +43 -0
- package/deps/blake3/.github/workflows/upload_github_release_asset.py +73 -0
- package/deps/blake3/CONTRIBUTING.md +31 -0
- package/deps/blake3/Cargo.toml +135 -0
- package/deps/blake3/LICENSE_A2 +202 -0
- package/deps/blake3/LICENSE_A2LLVM +219 -0
- package/deps/blake3/LICENSE_CC0 +121 -0
- package/deps/blake3/README.md +229 -0
- package/deps/blake3/b3sum/Cargo.lock +513 -0
- package/deps/blake3/b3sum/Cargo.toml +26 -0
- package/deps/blake3/b3sum/README.md +72 -0
- package/deps/blake3/b3sum/src/main.rs +564 -0
- package/deps/blake3/b3sum/src/unit_tests.rs +235 -0
- package/deps/blake3/b3sum/tests/cli_tests.rs +680 -0
- package/deps/blake3/b3sum/what_does_check_do.md +176 -0
- package/deps/blake3/benches/bench.rs +623 -0
- package/deps/blake3/build.rs +389 -0
- package/deps/blake3/c/CMakeLists.txt +383 -0
- package/deps/blake3/c/CMakePresets.json +73 -0
- package/deps/blake3/c/Makefile.testing +82 -0
- package/deps/blake3/c/README.md +403 -0
- package/deps/blake3/c/blake3-config.cmake.in +14 -0
- package/deps/blake3/c/blake3.c +650 -0
- package/deps/blake3/c/blake3.h +86 -0
- package/deps/blake3/c/blake3_avx2.c +326 -0
- package/deps/blake3/c/blake3_avx2_x86-64_unix.S +1815 -0
- package/deps/blake3/c/blake3_avx2_x86-64_windows_gnu.S +1817 -0
- package/deps/blake3/c/blake3_avx2_x86-64_windows_msvc.asm +1828 -0
- package/deps/blake3/c/blake3_avx512.c +1388 -0
- package/deps/blake3/c/blake3_avx512_x86-64_unix.S +4824 -0
- package/deps/blake3/c/blake3_avx512_x86-64_windows_gnu.S +2615 -0
- package/deps/blake3/c/blake3_avx512_x86-64_windows_msvc.asm +2634 -0
- package/deps/blake3/c/blake3_c_rust_bindings/Cargo.toml +32 -0
- package/deps/blake3/c/blake3_c_rust_bindings/README.md +4 -0
- package/deps/blake3/c/blake3_c_rust_bindings/benches/bench.rs +477 -0
- package/deps/blake3/c/blake3_c_rust_bindings/build.rs +253 -0
- package/deps/blake3/c/blake3_c_rust_bindings/cross_test.sh +31 -0
- package/deps/blake3/c/blake3_c_rust_bindings/src/lib.rs +333 -0
- package/deps/blake3/c/blake3_c_rust_bindings/src/test.rs +696 -0
- package/deps/blake3/c/blake3_dispatch.c +332 -0
- package/deps/blake3/c/blake3_impl.h +333 -0
- package/deps/blake3/c/blake3_neon.c +366 -0
- package/deps/blake3/c/blake3_portable.c +160 -0
- package/deps/blake3/c/blake3_sse2.c +566 -0
- package/deps/blake3/c/blake3_sse2_x86-64_unix.S +2291 -0
- package/deps/blake3/c/blake3_sse2_x86-64_windows_gnu.S +2332 -0
- package/deps/blake3/c/blake3_sse2_x86-64_windows_msvc.asm +2350 -0
- package/deps/blake3/c/blake3_sse41.c +560 -0
- package/deps/blake3/c/blake3_sse41_x86-64_unix.S +2028 -0
- package/deps/blake3/c/blake3_sse41_x86-64_windows_gnu.S +2069 -0
- package/deps/blake3/c/blake3_sse41_x86-64_windows_msvc.asm +2089 -0
- package/deps/blake3/c/blake3_tbb.cpp +37 -0
- package/deps/blake3/c/dependencies/CMakeLists.txt +3 -0
- package/deps/blake3/c/dependencies/tbb/CMakeLists.txt +28 -0
- package/deps/blake3/c/example.c +36 -0
- package/deps/blake3/c/example_tbb.c +57 -0
- package/deps/blake3/c/libblake3.pc.in +12 -0
- package/deps/blake3/c/main.c +166 -0
- package/deps/blake3/c/test.py +97 -0
- package/deps/blake3/media/B3.svg +70 -0
- package/deps/blake3/media/BLAKE3.svg +85 -0
- package/deps/blake3/media/speed.svg +1474 -0
- package/deps/blake3/reference_impl/Cargo.toml +8 -0
- package/deps/blake3/reference_impl/README.md +14 -0
- package/deps/blake3/reference_impl/reference_impl.rs +374 -0
- package/deps/blake3/src/ffi_avx2.rs +65 -0
- package/deps/blake3/src/ffi_avx512.rs +169 -0
- package/deps/blake3/src/ffi_neon.rs +82 -0
- package/deps/blake3/src/ffi_sse2.rs +126 -0
- package/deps/blake3/src/ffi_sse41.rs +126 -0
- package/deps/blake3/src/guts.rs +60 -0
- package/deps/blake3/src/hazmat.rs +704 -0
- package/deps/blake3/src/io.rs +64 -0
- package/deps/blake3/src/join.rs +92 -0
- package/deps/blake3/src/lib.rs +1835 -0
- package/deps/blake3/src/platform.rs +587 -0
- package/deps/blake3/src/portable.rs +198 -0
- package/deps/blake3/src/rust_avx2.rs +474 -0
- package/deps/blake3/src/rust_sse2.rs +775 -0
- package/deps/blake3/src/rust_sse41.rs +766 -0
- package/deps/blake3/src/test.rs +1049 -0
- package/deps/blake3/src/traits.rs +227 -0
- package/deps/blake3/src/wasm32_simd.rs +794 -0
- package/deps/blake3/test_vectors/Cargo.toml +19 -0
- package/deps/blake3/test_vectors/cross_test.sh +25 -0
- package/deps/blake3/test_vectors/src/bin/generate.rs +4 -0
- package/deps/blake3/test_vectors/src/lib.rs +350 -0
- package/deps/blake3/test_vectors/test_vectors.json +217 -0
- package/deps/blake3/tools/compiler_version/Cargo.toml +7 -0
- package/deps/blake3/tools/compiler_version/build.rs +6 -0
- package/deps/blake3/tools/compiler_version/src/main.rs +27 -0
- package/deps/blake3/tools/instruction_set_support/Cargo.toml +6 -0
- package/deps/blake3/tools/instruction_set_support/src/main.rs +10 -0
- package/deps/blake3/tools/release.md +16 -0
- package/deps/fastpbkdf2/fastpbkdf2.c +356 -0
- package/deps/fastpbkdf2/fastpbkdf2.h +68 -0
- package/deps/ncrypto/ncrypto.cc +4679 -0
- package/deps/ncrypto/ncrypto.h +1625 -0
- package/lib/commonjs/blake3.js +98 -0
- package/lib/commonjs/blake3.js.map +1 -0
- package/lib/commonjs/cipher.js +180 -0
- package/lib/commonjs/cipher.js.map +1 -0
- package/lib/commonjs/ec.js +344 -0
- package/lib/commonjs/ec.js.map +1 -0
- package/lib/commonjs/ed.js +185 -0
- package/lib/commonjs/ed.js.map +1 -0
- package/lib/commonjs/expo-plugin/@types.js +2 -0
- package/lib/commonjs/expo-plugin/@types.js.map +1 -0
- package/lib/commonjs/expo-plugin/withRNQC.js +25 -0
- package/lib/commonjs/expo-plugin/withRNQC.js.map +1 -0
- package/lib/commonjs/expo-plugin/withSodiumAndroid.js +25 -0
- package/lib/commonjs/expo-plugin/withSodiumAndroid.js.map +1 -0
- package/lib/commonjs/expo-plugin/withSodiumIos.js +26 -0
- package/lib/commonjs/expo-plugin/withSodiumIos.js.map +1 -0
- package/lib/commonjs/expo-plugin/withXCode.js +51 -0
- package/lib/commonjs/expo-plugin/withXCode.js.map +1 -0
- package/lib/commonjs/hash.js +215 -0
- package/lib/commonjs/hash.js.map +1 -0
- package/lib/commonjs/hmac.js +109 -0
- package/lib/commonjs/hmac.js.map +1 -0
- package/lib/commonjs/index.js +152 -32
- package/lib/commonjs/index.js.map +1 -1
- package/lib/commonjs/keys/classes.js +250 -0
- package/lib/commonjs/keys/classes.js.map +1 -0
- package/lib/commonjs/keys/generateKeyPair.js +102 -0
- package/lib/commonjs/keys/generateKeyPair.js.map +1 -0
- package/lib/commonjs/keys/index.js +89 -0
- package/lib/commonjs/keys/index.js.map +1 -0
- package/lib/commonjs/keys/signVerify.js +41 -0
- package/lib/commonjs/keys/signVerify.js.map +1 -0
- package/lib/commonjs/keys/utils.js +123 -0
- package/lib/commonjs/keys/utils.js.map +1 -0
- package/lib/commonjs/pbkdf2.js +89 -0
- package/lib/commonjs/pbkdf2.js.map +1 -0
- package/lib/commonjs/random.js +9 -3
- package/lib/commonjs/random.js.map +1 -1
- package/lib/commonjs/rsa.js +129 -0
- package/lib/commonjs/rsa.js.map +1 -0
- package/lib/commonjs/specs/blake3.nitro.js +6 -0
- package/lib/commonjs/specs/blake3.nitro.js.map +1 -0
- package/lib/commonjs/specs/cipher.nitro.js +6 -0
- package/lib/commonjs/specs/cipher.nitro.js.map +1 -0
- package/lib/commonjs/specs/ecKeyPair.nitro.js +6 -0
- package/lib/commonjs/specs/ecKeyPair.nitro.js.map +1 -0
- package/lib/commonjs/specs/edKeyPair.nitro.js +6 -0
- package/lib/commonjs/specs/edKeyPair.nitro.js.map +1 -0
- package/lib/commonjs/specs/hash.nitro.js +6 -0
- package/lib/commonjs/specs/hash.nitro.js.map +1 -0
- package/lib/commonjs/specs/hmac.nitro.js +6 -0
- package/lib/commonjs/specs/hmac.nitro.js.map +1 -0
- package/lib/commonjs/specs/keyObjectHandle.nitro.js +6 -0
- package/lib/commonjs/specs/keyObjectHandle.nitro.js.map +1 -0
- package/lib/commonjs/specs/pbkdf2.nitro.js +6 -0
- package/lib/commonjs/specs/pbkdf2.nitro.js.map +1 -0
- package/lib/commonjs/specs/rsaKeyPair.nitro.js +6 -0
- package/lib/commonjs/specs/rsaKeyPair.nitro.js.map +1 -0
- package/lib/commonjs/subtle.js +365 -0
- package/lib/commonjs/subtle.js.map +1 -0
- package/lib/commonjs/utils/cipher.js +64 -0
- package/lib/commonjs/utils/cipher.js.map +1 -0
- package/lib/commonjs/utils/conversion.js +140 -6
- package/lib/commonjs/utils/conversion.js.map +1 -1
- package/lib/commonjs/utils/errors.js +14 -0
- package/lib/commonjs/utils/errors.js.map +1 -0
- package/lib/commonjs/utils/hashnames.js +91 -0
- package/lib/commonjs/utils/hashnames.js.map +1 -0
- package/lib/commonjs/utils/index.js +65 -5
- package/lib/commonjs/utils/index.js.map +1 -1
- package/lib/commonjs/utils/noble.js +82 -0
- package/lib/commonjs/utils/noble.js.map +1 -0
- package/lib/commonjs/utils/types.js +52 -0
- package/lib/commonjs/utils/types.js.map +1 -1
- package/lib/commonjs/utils/validation.js +98 -0
- package/lib/commonjs/utils/validation.js.map +1 -0
- package/lib/module/blake3.js +90 -0
- package/lib/module/blake3.js.map +1 -0
- package/lib/module/cipher.js +173 -0
- package/lib/module/cipher.js.map +1 -0
- package/lib/module/ec.js +336 -0
- package/lib/module/ec.js.map +1 -0
- package/lib/module/ed.js +178 -0
- package/lib/module/ed.js.map +1 -0
- package/lib/module/expo-plugin/@types.js +2 -0
- package/lib/module/expo-plugin/@types.js.map +1 -0
- package/lib/module/expo-plugin/withRNQC.js +21 -0
- package/lib/module/expo-plugin/withRNQC.js.map +1 -0
- package/lib/module/expo-plugin/withSodiumAndroid.js +20 -0
- package/lib/module/expo-plugin/withSodiumAndroid.js.map +1 -0
- package/lib/module/expo-plugin/withSodiumIos.js +20 -0
- package/lib/module/expo-plugin/withSodiumIos.js.map +1 -0
- package/lib/module/expo-plugin/withXCode.js +46 -0
- package/lib/module/expo-plugin/withXCode.js.map +1 -0
- package/lib/module/hash.js +207 -0
- package/lib/module/hash.js.map +1 -0
- package/lib/module/hmac.js +104 -0
- package/lib/module/hmac.js.map +1 -0
- package/lib/module/index.js +33 -29
- package/lib/module/index.js.map +1 -1
- package/lib/module/keys/classes.js +241 -0
- package/lib/module/keys/classes.js.map +1 -0
- package/lib/module/keys/generateKeyPair.js +96 -0
- package/lib/module/keys/generateKeyPair.js.map +1 -0
- package/lib/module/keys/index.js +32 -0
- package/lib/module/keys/index.js.map +1 -0
- package/lib/module/keys/signVerify.js +41 -0
- package/lib/module/keys/signVerify.js.map +1 -0
- package/lib/module/keys/utils.js +114 -0
- package/lib/module/keys/utils.js.map +1 -0
- package/lib/module/pbkdf2.js +83 -0
- package/lib/module/pbkdf2.js.map +1 -0
- package/lib/module/random.js +7 -1
- package/lib/module/random.js.map +1 -1
- package/lib/module/rsa.js +123 -0
- package/lib/module/rsa.js.map +1 -0
- package/lib/module/specs/blake3.nitro.js +4 -0
- package/lib/module/specs/blake3.nitro.js.map +1 -0
- package/lib/module/specs/cipher.nitro.js +4 -0
- package/lib/module/specs/cipher.nitro.js.map +1 -0
- package/lib/module/specs/ecKeyPair.nitro.js +4 -0
- package/lib/module/specs/ecKeyPair.nitro.js.map +1 -0
- package/lib/module/specs/edKeyPair.nitro.js +4 -0
- package/lib/module/specs/edKeyPair.nitro.js.map +1 -0
- package/lib/module/specs/hash.nitro.js +4 -0
- package/lib/module/specs/hash.nitro.js.map +1 -0
- package/lib/module/specs/hmac.nitro.js +4 -0
- package/lib/module/specs/hmac.nitro.js.map +1 -0
- package/lib/module/specs/keyObjectHandle.nitro.js +4 -0
- package/lib/module/specs/keyObjectHandle.nitro.js.map +1 -0
- package/lib/module/specs/pbkdf2.nitro.js +4 -0
- package/lib/module/specs/pbkdf2.nitro.js.map +1 -0
- package/lib/module/specs/rsaKeyPair.nitro.js +4 -0
- package/lib/module/specs/rsaKeyPair.nitro.js.map +1 -0
- package/lib/module/subtle.js +360 -0
- package/lib/module/subtle.js.map +1 -0
- package/lib/module/utils/cipher.js +56 -0
- package/lib/module/utils/cipher.js.map +1 -0
- package/lib/module/utils/conversion.js +120 -8
- package/lib/module/utils/conversion.js.map +1 -1
- package/lib/module/utils/errors.js +10 -0
- package/lib/module/utils/errors.js.map +1 -0
- package/lib/module/utils/hashnames.js +89 -0
- package/lib/module/utils/hashnames.js.map +1 -0
- package/lib/module/utils/index.js +6 -5
- package/lib/module/utils/index.js.map +1 -1
- package/lib/module/utils/noble.js +76 -0
- package/lib/module/utils/noble.js.map +1 -0
- package/lib/module/utils/types.js +53 -0
- package/lib/module/utils/types.js.map +1 -1
- package/lib/module/utils/validation.js +87 -0
- package/lib/module/utils/validation.js.map +1 -0
- package/lib/tsconfig.tsbuildinfo +1 -1
- package/lib/typescript/blake3.d.ts +33 -0
- package/lib/typescript/blake3.d.ts.map +1 -0
- package/lib/typescript/cipher.d.ts +60 -0
- package/lib/typescript/cipher.d.ts.map +1 -0
- package/lib/typescript/ec.d.ts +13 -0
- package/lib/typescript/ec.d.ts.map +1 -0
- package/lib/typescript/ed.d.ts +43 -0
- package/lib/typescript/ed.d.ts.map +1 -0
- package/lib/typescript/expo-plugin/@types.d.ts +8 -0
- package/lib/typescript/expo-plugin/@types.d.ts.map +1 -0
- package/lib/typescript/expo-plugin/withRNQC.d.ts +4 -0
- package/lib/typescript/expo-plugin/withRNQC.d.ts.map +1 -0
- package/lib/typescript/expo-plugin/withSodiumAndroid.d.ts +4 -0
- package/lib/typescript/expo-plugin/withSodiumAndroid.d.ts.map +1 -0
- package/lib/typescript/expo-plugin/withSodiumIos.d.ts +4 -0
- package/lib/typescript/expo-plugin/withSodiumIos.d.ts.map +1 -0
- package/lib/typescript/expo-plugin/withXCode.d.ts +9 -0
- package/lib/typescript/expo-plugin/withXCode.d.ts.map +1 -0
- package/lib/typescript/hash.d.ts +122 -0
- package/lib/typescript/hash.d.ts.map +1 -0
- package/lib/typescript/hmac.d.ts +66 -0
- package/lib/typescript/hmac.d.ts.map +1 -0
- package/lib/typescript/index.d.ts +110 -9
- package/lib/typescript/index.d.ts.map +1 -1
- package/lib/typescript/keys/classes.d.ts +79 -0
- package/lib/typescript/keys/classes.d.ts.map +1 -0
- package/lib/typescript/keys/generateKeyPair.d.ts +6 -0
- package/lib/typescript/keys/generateKeyPair.d.ts.map +1 -0
- package/lib/typescript/keys/index.d.ts +7 -0
- package/lib/typescript/keys/index.d.ts.map +1 -0
- package/lib/typescript/keys/signVerify.d.ts +1 -0
- package/lib/typescript/keys/signVerify.d.ts.map +1 -0
- package/lib/typescript/keys/utils.d.ts +34 -0
- package/lib/typescript/keys/utils.d.ts.map +1 -0
- package/lib/typescript/pbkdf2.d.ts +12 -0
- package/lib/typescript/pbkdf2.d.ts.map +1 -0
- package/lib/typescript/random.d.ts +11 -5
- package/lib/typescript/random.d.ts.map +1 -1
- package/lib/typescript/rsa.d.ts +10 -0
- package/lib/typescript/rsa.d.ts.map +1 -0
- package/lib/typescript/specs/blake3.nitro.d.ts +15 -0
- package/lib/typescript/specs/blake3.nitro.d.ts.map +1 -0
- package/lib/typescript/specs/cipher.nitro.d.ts +29 -0
- package/lib/typescript/specs/cipher.nitro.d.ts.map +1 -0
- package/lib/typescript/specs/ecKeyPair.nitro.d.ts +20 -0
- package/lib/typescript/specs/ecKeyPair.nitro.d.ts.map +1 -0
- package/lib/typescript/specs/edKeyPair.nitro.d.ts +17 -0
- package/lib/typescript/specs/edKeyPair.nitro.d.ts.map +1 -0
- package/lib/typescript/specs/hash.nitro.d.ts +13 -0
- package/lib/typescript/specs/hash.nitro.d.ts.map +1 -0
- package/lib/typescript/specs/hmac.nitro.d.ts +10 -0
- package/lib/typescript/specs/hmac.nitro.d.ts.map +1 -0
- package/lib/typescript/specs/keyObjectHandle.nitro.d.ts +14 -0
- package/lib/typescript/specs/keyObjectHandle.nitro.d.ts.map +1 -0
- package/lib/typescript/specs/pbkdf2.nitro.d.ts +9 -0
- package/lib/typescript/specs/pbkdf2.nitro.d.ts.map +1 -0
- package/lib/typescript/specs/rsaKeyPair.nitro.d.ts +20 -0
- package/lib/typescript/specs/rsaKeyPair.nitro.d.ts.map +1 -0
- package/lib/typescript/subtle.d.ts +17 -0
- package/lib/typescript/subtle.d.ts.map +1 -0
- package/lib/typescript/utils/cipher.d.ts +7 -0
- package/lib/typescript/utils/cipher.d.ts.map +1 -0
- package/lib/typescript/utils/conversion.d.ts +24 -2
- package/lib/typescript/utils/conversion.d.ts.map +1 -1
- package/lib/typescript/utils/errors.d.ts +7 -0
- package/lib/typescript/utils/errors.d.ts.map +1 -0
- package/lib/typescript/utils/hashnames.d.ts +13 -0
- package/lib/typescript/utils/hashnames.d.ts.map +1 -0
- package/lib/typescript/utils/index.d.ts +6 -5
- package/lib/typescript/utils/index.d.ts.map +1 -1
- package/lib/typescript/utils/noble.d.ts +19 -0
- package/lib/typescript/utils/noble.d.ts.map +1 -0
- package/lib/typescript/utils/types.d.ts +252 -2
- package/lib/typescript/utils/types.d.ts.map +1 -1
- package/lib/typescript/utils/validation.d.ts +13 -0
- package/lib/typescript/utils/validation.d.ts.map +1 -0
- package/nitrogen/generated/.gitattributes +1 -0
- package/nitrogen/generated/android/QuickCrypto+autolinking.cmake +47 -4
- package/nitrogen/generated/android/QuickCrypto+autolinking.gradle +4 -3
- package/nitrogen/generated/android/QuickCryptoOnLoad.cpp +144 -0
- package/nitrogen/generated/android/QuickCryptoOnLoad.hpp +25 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/crypto/QuickCryptoOnLoad.kt +35 -0
- package/nitrogen/generated/ios/QuickCrypto+autolinking.rb +11 -8
- package/nitrogen/generated/ios/QuickCrypto-Swift-Cxx-Bridge.cpp +11 -3
- package/nitrogen/generated/ios/QuickCrypto-Swift-Cxx-Bridge.hpp +5 -3
- package/nitrogen/generated/ios/QuickCrypto-Swift-Cxx-Umbrella.hpp +16 -7
- package/nitrogen/generated/ios/QuickCryptoAutolinking.mm +135 -0
- package/nitrogen/generated/ios/QuickCryptoAutolinking.swift +12 -0
- package/nitrogen/generated/shared/c++/CFRGKeyPairType.hpp +84 -0
- package/nitrogen/generated/shared/c++/CipherArgs.hpp +86 -0
- package/nitrogen/generated/shared/c++/HybridBlake3Spec.cpp +28 -0
- package/nitrogen/generated/shared/c++/HybridBlake3Spec.hpp +76 -0
- package/nitrogen/generated/shared/c++/HybridCipherFactorySpec.cpp +21 -0
- package/nitrogen/generated/shared/c++/HybridCipherFactorySpec.hpp +67 -0
- package/nitrogen/generated/shared/c++/HybridCipherSpec.cpp +28 -0
- package/nitrogen/generated/shared/c++/HybridCipherSpec.hpp +76 -0
- package/nitrogen/generated/shared/c++/HybridEcKeyPairSpec.cpp +29 -0
- package/nitrogen/generated/shared/c++/HybridEcKeyPairSpec.hpp +77 -0
- package/nitrogen/generated/shared/c++/HybridEdKeyPairSpec.cpp +30 -0
- package/nitrogen/generated/shared/c++/HybridEdKeyPairSpec.hpp +75 -0
- package/nitrogen/generated/shared/c++/HybridHashSpec.cpp +26 -0
- package/nitrogen/generated/shared/c++/HybridHashSpec.hpp +75 -0
- package/nitrogen/generated/shared/c++/HybridHmacSpec.cpp +23 -0
- package/nitrogen/generated/shared/c++/HybridHmacSpec.hpp +66 -0
- package/nitrogen/generated/shared/c++/HybridKeyObjectHandleSpec.cpp +26 -0
- package/nitrogen/generated/shared/c++/HybridKeyObjectHandleSpec.hpp +92 -0
- package/nitrogen/generated/shared/c++/HybridPbkdf2Spec.cpp +22 -0
- package/nitrogen/generated/shared/c++/HybridPbkdf2Spec.hpp +66 -0
- package/nitrogen/generated/shared/c++/HybridRandomSpec.cpp +2 -3
- package/nitrogen/generated/shared/c++/HybridRandomSpec.hpp +9 -6
- package/nitrogen/generated/shared/c++/HybridRsaKeyPairSpec.cpp +29 -0
- package/nitrogen/generated/shared/c++/HybridRsaKeyPairSpec.hpp +77 -0
- package/nitrogen/generated/shared/c++/JWK.hpp +161 -0
- package/nitrogen/generated/shared/c++/JWKkty.hpp +84 -0
- package/nitrogen/generated/shared/c++/JWKuse.hpp +76 -0
- package/nitrogen/generated/shared/c++/KFormatType.hpp +63 -0
- package/nitrogen/generated/shared/c++/KeyDetail.hpp +92 -0
- package/nitrogen/generated/shared/c++/KeyEncoding.hpp +64 -0
- package/nitrogen/generated/shared/c++/KeyObject.hpp +67 -0
- package/nitrogen/generated/shared/c++/KeyType.hpp +63 -0
- package/nitrogen/generated/shared/c++/KeyUsage.hpp +116 -0
- package/nitrogen/generated/shared/c++/NamedCurve.hpp +80 -0
- package/package.json +66 -39
- package/src/blake3.ts +123 -0
- package/src/cipher.ts +335 -0
- package/src/ec.ts +432 -0
- package/src/ed.ts +256 -0
- package/src/expo-plugin/@types.ts +7 -0
- package/src/expo-plugin/withRNQC.ts +23 -0
- package/src/expo-plugin/withSodiumAndroid.ts +24 -0
- package/src/expo-plugin/withSodiumIos.ts +30 -0
- package/src/expo-plugin/withXCode.ts +55 -0
- package/src/hash.ts +274 -0
- package/src/hmac.ts +135 -0
- package/src/index.ts +32 -29
- package/src/keys/classes.ts +317 -0
- package/src/keys/generateKeyPair.ts +145 -0
- package/src/keys/index.ts +52 -0
- package/src/keys/signVerify.ts +39 -0
- package/src/keys/utils.ts +190 -0
- package/src/pbkdf2.ts +154 -0
- package/src/random.ts +26 -23
- package/src/rsa.ts +176 -0
- package/src/specs/blake3.nitro.ts +12 -0
- package/src/specs/cipher.nitro.ts +25 -0
- package/src/specs/ecKeyPair.nitro.ts +38 -0
- package/src/specs/edKeyPair.nitro.ts +43 -0
- package/src/specs/hash.nitro.ts +10 -0
- package/src/specs/hmac.nitro.ts +7 -0
- package/src/specs/keyObjectHandle.nitro.ts +31 -0
- package/src/specs/pbkdf2.nitro.ts +18 -0
- package/src/specs/random.nitro.ts +2 -2
- package/src/specs/rsaKeyPair.nitro.ts +33 -0
- package/src/subtle.ts +614 -0
- package/src/utils/cipher.ts +60 -0
- package/src/utils/conversion.ts +143 -9
- package/src/utils/errors.ts +15 -0
- package/src/utils/hashnames.ts +98 -0
- package/src/utils/index.ts +6 -6
- package/src/utils/noble.ts +85 -0
- package/src/utils/types.ts +423 -3
- package/src/utils/validation.ts +130 -0
- package/ios/QuickCryptoOnLoad.mm +0 -19
- 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
|
+
}
|