hopr_crypto_types/
primitives.rs

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