1use crate::Unspecified;
2use std::cell::RefCell;
3use vitaminc_random::{Generatable, SafeRand, SeedableRng};
4
5pub struct Nonce<const N: usize>([u8; N]);
7
8impl<const N: usize> AsRef<[u8]> for Nonce<N> {
9 fn as_ref(&self) -> &[u8] {
10 &self.0
11 }
12}
13
14impl<const N: usize> Nonce<N> {
15 pub(crate) fn new(inner: [u8; N]) -> Self {
16 Self(inner)
17 }
18
19 pub fn into_inner(self) -> [u8; N] {
20 self.0
21 }
22}
23
24pub trait NonceGenerator<const N: usize> {
27 fn init() -> Self;
28 fn generate(&self) -> Result<Nonce<N>, Unspecified>;
29}
30
31pub struct RandomNonceGenerator<const N: usize>(RefCell<SafeRand>);
32
33impl<const N: usize> NonceGenerator<N> for RandomNonceGenerator<N> {
34 fn init() -> Self {
35 let rng = SafeRand::from_entropy();
36 Self(RefCell::new(rng))
37 }
38
39 fn generate(&self) -> Result<Nonce<N>, Unspecified> {
40 let mut rng = self.0.borrow_mut();
41 Generatable::random(&mut rng)
42 .map_err(|_| Unspecified)
43 .map(Nonce::new)
44 }
45}