crypto_common/
generate.rs1use hybrid_array::{Array, ArraySize};
2use rand_core::{CryptoRng, TryCryptoRng};
3
4#[cfg(feature = "getrandom")]
5use getrandom::{SysRng, rand_core::UnwrapErr};
6
7pub trait Generate: Sized {
9 fn try_generate_from_rng<R: TryCryptoRng + ?Sized>(rng: &mut R) -> Result<Self, R::Error>;
14
15 #[must_use]
17 fn generate_from_rng<R: CryptoRng + ?Sized>(rng: &mut R) -> Self {
18 let Ok(ret) = Self::try_generate_from_rng(rng);
19 ret
20 }
21
22 #[cfg(feature = "getrandom")]
29 fn try_generate() -> Result<Self, getrandom::Error> {
30 Self::try_generate_from_rng(&mut SysRng)
31 }
32
33 #[cfg(feature = "getrandom")]
42 #[must_use]
43 fn generate() -> Self {
44 Self::generate_from_rng(&mut UnwrapErr(SysRng))
45 }
46}
47
48impl Generate for u32 {
49 #[inline]
50 fn try_generate_from_rng<R: TryCryptoRng + ?Sized>(rng: &mut R) -> Result<Self, R::Error> {
51 rng.try_next_u32()
52 }
53}
54
55impl Generate for u64 {
56 #[inline]
57 fn try_generate_from_rng<R: TryCryptoRng + ?Sized>(rng: &mut R) -> Result<Self, R::Error> {
58 rng.try_next_u64()
59 }
60}
61
62impl<const N: usize> Generate for [u8; N] {
63 #[inline]
64 fn try_generate_from_rng<R: TryCryptoRng + ?Sized>(rng: &mut R) -> Result<Self, R::Error> {
65 let mut ret = [0u8; N];
66 rng.try_fill_bytes(&mut ret)?;
67 Ok(ret)
68 }
69}
70
71impl<U: ArraySize> Generate for Array<u8, U> {
72 #[inline]
73 fn try_generate_from_rng<R: TryCryptoRng + ?Sized>(rng: &mut R) -> Result<Self, R::Error> {
74 let mut ret = Self::default();
75 rng.try_fill_bytes(&mut ret)?;
76 Ok(ret)
77 }
78}
79
80impl<U: ArraySize> Generate for Array<u32, U> {
81 #[inline]
82 fn try_generate_from_rng<R: TryCryptoRng + ?Sized>(rng: &mut R) -> Result<Self, R::Error> {
83 Self::try_from_fn(|_| rng.try_next_u32())
84 }
85}
86
87impl<U: ArraySize> Generate for Array<u64, U> {
88 #[inline]
89 fn try_generate_from_rng<R: TryCryptoRng + ?Sized>(rng: &mut R) -> Result<Self, R::Error> {
90 Self::try_from_fn(|_| rng.try_next_u64())
91 }
92}