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; 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}