hopr_crypto_types/
primitives.rs

1use std::fmt::Formatter;
2use std::marker::PhantomData;
3use typenum::Unsigned;
4
5use crate::crypto_traits::{Iv, IvSizeUser, Key, KeyIvInit, KeySizeUser};
6use crate::utils::SecretValue;
7
8/// AES with 128-bit key in counter-mode (with big-endian counter).
9pub type Aes128Ctr = ctr::Ctr64BE<aes::Aes128>;
10
11// Re-exports of used cryptographic primitives
12pub use blake3::{hash as blake3_hash, Hasher as Blake3, OutputReader as Blake3Output};
13pub use chacha20::ChaCha20;
14pub use poly1305::Poly1305;
15pub use sha3::Keccak256;
16pub use sha3::Sha3_256;
17
18/// Represents a 256-bit secret key of fixed length.
19/// The value is auto-zeroized on drop.
20pub type SecretKey = SecretValue<typenum::U32>;
21
22/// Represents a 128-bit secret key of fixed length.
23/// The value is auto-zeroized on drop.
24pub type SecretKey16 = SecretValue<typenum::U16>;
25
26/// Convenience container for IV and key of a given primitive `T`.
27#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
28#[derive(zeroize::ZeroizeOnDrop)]
29pub struct IvKey<T>(Box<[u8]>, PhantomData<T>);
30
31impl<T: KeyIvInit> KeySizeUser for IvKey<T> {
32    type KeySize = T::KeySize;
33}
34
35impl<T: KeyIvInit> IvSizeUser for IvKey<T> {
36    type IvSize = T::IvSize;
37}
38
39impl<T: KeyIvInit> KeyIvInit for IvKey<T> {
40    fn new(key: &Key<Self>, iv: &Iv<Self>) -> Self {
41        let mut out = Vec::with_capacity(Self::SIZE);
42        out.extend_from_slice(iv.as_ref());
43        out.extend_from_slice(key.as_ref());
44        Self(out.into_boxed_slice(), PhantomData)
45    }
46}
47
48impl<T: KeyIvInit> Default for IvKey<T> {
49    fn default() -> Self {
50        Self(vec![0u8; Self::SIZE].into_boxed_slice(), PhantomData)
51    }
52}
53
54impl<T> Clone for IvKey<T> {
55    fn clone(&self) -> Self {
56        Self(self.0.clone(), PhantomData)
57    }
58}
59
60impl<T> PartialEq for IvKey<T> {
61    fn eq(&self, other: &Self) -> bool {
62        self.0 == other.0
63    }
64}
65
66impl<T> Eq for IvKey<T> {}
67
68impl<T: KeyIvInit> std::fmt::Debug for IvKey<T> {
69    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
70        f.debug_struct("IvKey")
71            .field("key", &"<redacted>")
72            .field("iv", self.iv())
73            .finish()
74    }
75}
76
77impl<T: KeyIvInit> IvKey<T> {
78    /// Total size of the key and IV in bytes.
79    pub const SIZE: usize = T::KeySize::USIZE + T::IvSize::USIZE;
80
81    /// Returns the IV part.
82    #[inline]
83    pub fn iv(&self) -> &Iv<T> {
84        Iv::<T>::from_slice(&self.0[0..T::IvSize::USIZE])
85    }
86
87    /// Returns IV as a mutable slice.
88    #[inline]
89    pub fn iv_mut(&mut self) -> &mut [u8] {
90        &mut self.0[0..T::IvSize::USIZE]
91    }
92
93    /// Returns the key part.
94    #[inline]
95    pub fn key(&self) -> &Key<T> {
96        Key::<T>::from_slice(&self.0[T::IvSize::USIZE..])
97    }
98
99    /// Returns the key as a mutable slice.
100    #[inline]
101    pub fn key_mut(&mut self) -> &mut [u8] {
102        &mut self.0[T::IvSize::USIZE..]
103    }
104
105    /// Turn this instance into another [`KeyIvInit`] with the same IV and key sizes.
106    #[inline]
107    pub fn into_init<V>(self) -> V
108    where
109        V: KeyIvInit<KeySize = T::KeySize, IvSize = T::IvSize>,
110    {
111        V::new(self.key(), self.iv())
112    }
113}