vru_noise/
config.rs

1use {
2    aead::{KeyInit, AeadCore, AeadInPlace, Nonce},
3    generic_array::typenum::{Bit, Unsigned},
4    digest::OutputSizeUser,
5    hkdf::HmacImpl,
6};
7
8use super::hash::{MixHash, HkdfSplitExt};
9
10pub trait Config {
11    type BigEndianness: Bit; // LittleEndian for chacha20poly1305 and BigEndian for Aes256Gcm
12    type Aead: KeyInit + AeadInPlace;
13    type MixHash: MixHash;
14    type HkdfSplit: HkdfSplitExt<Self::Aead, L = <Self::MixHash as MixHash>::L>;
15}
16
17impl<I, D, E, A> Config for (I, D, E, A)
18where
19    I: HmacImpl<D>,
20    (D, I): HkdfSplitExt<A, L = <D as MixHash>::L>,
21    D: OutputSizeUser + MixHash,
22    E: Bit,
23    A: KeyInit + AeadInPlace,
24{
25    type BigEndianness = E;
26    type Aead = A;
27    type MixHash = D;
28    type HkdfSplit = (D, I);
29}
30
31pub trait ConfigExt
32where
33    Self: Config,
34{
35    fn prepare_nonce(n: u64) -> Nonce<Self::Aead>;
36}
37
38impl<C> ConfigExt for C
39where
40    C: Config,
41{
42    fn prepare_nonce(n: u64) -> Nonce<Self::Aead> {
43        let len = <<Self::Aead as AeadCore>::NonceSize as Unsigned>::USIZE;
44        let n = if <Self::BigEndianness as Bit>::BOOL {
45            n.to_be_bytes()
46        } else {
47            n.to_le_bytes()
48        };
49        let min = n.len().min(len);
50        let mut nonce = Nonce::<Self::Aead>::default();
51        nonce[(len - min)..].clone_from_slice(&n[(n.len() - min)..]);
52        nonce
53    }
54}