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