crypto_common/
generate.rs1use hybrid_array::{Array, ArraySize};
2use rand_core::{CryptoRng, TryCryptoRng};
3
4pub trait Generate: Sized {
6 fn try_generate_from_rng<R: TryCryptoRng + ?Sized>(rng: &mut R) -> Result<Self, R::Error>;
8
9 fn generate_from_rng<R: CryptoRng + ?Sized>(rng: &mut R) -> Self {
11 let Ok(ret) = Self::try_generate_from_rng(rng);
12 ret
13 }
14
15 #[cfg(feature = "getrandom")]
22 fn try_generate() -> Result<Self, getrandom::Error> {
23 Self::try_generate_from_rng(&mut getrandom::SysRng)
24 }
25
26 #[cfg(feature = "getrandom")]
35 fn generate() -> Self {
36 Self::try_generate().expect("RNG failure")
37 }
38}
39
40impl Generate for u32 {
41 #[inline]
42 fn try_generate_from_rng<R: TryCryptoRng + ?Sized>(rng: &mut R) -> Result<Self, R::Error> {
43 rng.try_next_u32()
44 }
45}
46
47impl Generate for u64 {
48 #[inline]
49 fn try_generate_from_rng<R: TryCryptoRng + ?Sized>(rng: &mut R) -> Result<Self, R::Error> {
50 rng.try_next_u64()
51 }
52}
53
54impl<const N: usize> Generate for [u8; N] {
55 #[inline]
56 fn try_generate_from_rng<R: TryCryptoRng + ?Sized>(rng: &mut R) -> Result<Self, R::Error> {
57 let mut ret = [0u8; N];
58 rng.try_fill_bytes(&mut ret)?;
59 Ok(ret)
60 }
61}
62
63impl<U: ArraySize> Generate for Array<u8, U> {
64 #[inline]
65 fn try_generate_from_rng<R: TryCryptoRng + ?Sized>(rng: &mut R) -> Result<Self, R::Error> {
66 let mut ret = Self::default();
67 rng.try_fill_bytes(&mut ret)?;
68 Ok(ret)
69 }
70}
71
72impl<U: ArraySize> Generate for Array<u32, U> {
73 #[inline]
74 fn try_generate_from_rng<R: TryCryptoRng + ?Sized>(rng: &mut R) -> Result<Self, R::Error> {
75 Self::try_from_fn(|_| rng.try_next_u32())
76 }
77}
78
79impl<U: ArraySize> Generate for Array<u64, U> {
80 #[inline]
81 fn try_generate_from_rng<R: TryCryptoRng + ?Sized>(rng: &mut R) -> Result<Self, R::Error> {
82 Self::try_from_fn(|_| rng.try_next_u64())
83 }
84}