hopr_crypto_sphinx/
derivation.rs1use hopr_types::crypto::prelude::*;
2
3const HASH_KEY_PACKET_TAG: &str = "HASH_KEY_PACKET_TAG";
5
6pub(crate) fn create_kdf_instance<S: AsRef<[u8]>>(
7 secret: &S,
8 context: &str,
9 salt: Option<&[u8]>,
10) -> hopr_types::crypto::errors::Result<Blake3Output> {
11 let key_material = secret.as_ref();
12 if key_material.len() < 16 {
13 return Err(CryptoError::InvalidInputValue("secret must have at least 128-bits"));
14 }
15
16 if let Some(salt) = salt {
17 Ok(Blake3::new_derive_key(context)
18 .update_reader(salt)
19 .map_err(|_| CryptoError::InvalidInputValue("salt"))?
20 .update_reader(key_material)
21 .map_err(|_| CryptoError::InvalidInputValue("key"))?
22 .finalize_xof())
23 } else {
24 Ok(Blake3::new_derive_key(context)
25 .update_reader(key_material)
26 .map_err(|_| CryptoError::InvalidInputValue("key"))?
27 .finalize_xof())
28 }
29}
30
31pub fn derive_packet_tag(secret: &SecretKey) -> hopr_types::crypto::errors::Result<PacketTag> {
33 let mut packet_tag: PacketTag = [0u8; PACKET_TAG_LENGTH];
34
35 let mut output = create_kdf_instance(secret, HASH_KEY_PACKET_TAG, None)?;
36 output.fill(&mut packet_tag);
37 Ok(packet_tag)
38}
39
40pub(crate) fn generate_key<T: crypto_traits::KeyInit, S: AsRef<[u8]>>(
52 secret: &S,
53 context: &str,
54 with_salt: Option<&[u8]>,
55) -> hopr_types::crypto::errors::Result<T> {
56 let mut out = crypto_traits::Key::<T>::default();
57
58 let mut output = create_kdf_instance(secret, context, with_salt)?;
59 output.fill(&mut out);
60
61 Ok(T::new(&out))
62}
63
64pub(crate) fn generate_key_iv<T: crypto_traits::KeyIvInit, S: AsRef<[u8]>>(
69 secret: &S,
70 context: &str,
71 with_salt: Option<&[u8]>,
72) -> hopr_types::crypto::errors::Result<T> {
73 let mut output = create_kdf_instance(secret, context, with_salt)?;
74
75 let mut key = crypto_traits::Key::<T>::default();
76 let mut iv = crypto_traits::Iv::<T>::default();
77
78 let mut out = vec![0u8; key.len() + iv.len()];
79 output.fill(&mut out);
80
81 let (v_iv, v_key) = out.split_at(iv.len());
82 iv.copy_from_slice(v_iv);
83 key.copy_from_slice(v_key);
84
85 Ok(T::new(&key, &iv))
86}