From 498a18bdc6160ecdc42a9a33e37ee0fa2ca22b87 Mon Sep 17 00:00:00 2001 From: Jason Cooper Date: Wed, 28 Aug 2024 13:30:09 -0400 Subject: [PATCH] derive_key: Add default-off, unstable `derive_key_u8ref` API call This can be enabled with the unstable feature flag, `i_know_what_i_am_doing`. Developers attempting to deploy blake3 via the Rust crate often encounter `derive_key(&str, ...)` which forces the INFO parameter to be a valid UTF-8 string. Please see the discussion in issue [13](https://github.com/BLAKE3-team/BLAKE3/issues/13), in particular, this [comment](https://github.com/BLAKE3-team/BLAKE3/issues/13#issuecomment-573219903). The recommended course of action for those with non-UTF-8 INFO is to use `hash` and `keyed_hash` and open code their own `derive_key` which takes an `&[u8]`. This is not good for two reasons: First, it is quickly seen that this forces deviation from the Blake3 paper for how `derive_key` should be performed, as `hash` doesn't let you set the `flags` field. Attempting to use the underlying `hash_all_at_once` fails because it's not exported. Second, the developer is now forced into the position of maintaining their own patches on top of the blake3 repo. This is a burden on the developer, and makes following blake3 upstream releases *much* less likely. This patch proposes a reasonable compromise. For developers who require `&[u8]` INFO field, they can enable the rust feature flag `i_know_what_i_am_doing` to expose the API `derive_key_u8ref`. This enables developers to use upstream blake3 directly, while still discouraging sloppy behavior in the default case. Signed-off-by: Jason Cooper --- Cargo.toml | 11 +++++++++++ src/lib.rs | 10 ++++++++++ 2 files changed, 21 insertions(+) diff --git a/Cargo.toml b/Cargo.toml index c5f8c99db..3214054e9 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -90,6 +90,17 @@ no_avx2 = [] no_avx512 = [] no_neon = [] +# For developers who encountered `derive_key(&str)`, read the Blake3 paper, +# and read and fully comprehended this comment: +# +# https://github.com/BLAKE3-team/BLAKE3/issues/13#issuecomment-573219903 +# +# and are willing to own both halves when their design breaks. +# +# Note: The *only* reason to add this is so that developers don't need to +# maintain out-of-tree hacked up patches. +i_know_what_i_am_doing = [] + [package.metadata.docs.rs] # Document the rayon/mmap methods and the Serialize/Deserialize/Zeroize impls on docs.rs. features = ["mmap", "rayon", "serde", "zeroize"] diff --git a/src/lib.rs b/src/lib.rs index 37c2c0b31..b391f2ea9 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -990,6 +990,16 @@ pub fn derive_key(context: &str, key_material: &[u8]) -> [u8; OUT_LEN] { .0 } +#[cfg(i_know_what_im_doing)] +pub fn derive_key_u8ref(context: &[u8], key_material: &[u8]) -> [u8; OUT_LEN] { + let context_key = + hash_all_at_once::(context, IV, DERIVE_KEY_CONTEXT).root_hash(); + let context_key_words = platform::words_from_le_bytes_32(context_key.as_bytes()); + hash_all_at_once::(key_material, &context_key_words, DERIVE_KEY_MATERIAL) + .root_hash() + .0 +} + fn parent_node_output( left_child: &CVBytes, right_child: &CVBytes,