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>;
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")]
25 fn try_generate() -> Result<Self, getrandom::Error> {
26 Self::try_generate_from_rng(&mut SysRng)
27 }
28
29 #[cfg(feature = "getrandom")]
38 fn generate() -> Self {
39 Self::generate_from_rng(&mut UnwrapErr(SysRng))
40 }
41}
42
43impl Generate for u32 {
44 #[inline]
45 fn try_generate_from_rng<R: TryCryptoRng + ?Sized>(rng: &mut R) -> Result<Self, R::Error> {
46 rng.try_next_u32()
47 }
48}
49
50impl Generate for u64 {
51 #[inline]
52 fn try_generate_from_rng<R: TryCryptoRng + ?Sized>(rng: &mut R) -> Result<Self, R::Error> {
53 rng.try_next_u64()
54 }
55}
56
57impl<const N: usize> Generate for [u8; N] {
58 #[inline]
59 fn try_generate_from_rng<R: TryCryptoRng + ?Sized>(rng: &mut R) -> Result<Self, R::Error> {
60 let mut ret = [0u8; N];
61 rng.try_fill_bytes(&mut ret)?;
62 Ok(ret)
63 }
64}
65
66impl<U: ArraySize> Generate for Array<u8, U> {
67 #[inline]
68 fn try_generate_from_rng<R: TryCryptoRng + ?Sized>(rng: &mut R) -> Result<Self, R::Error> {
69 let mut ret = Self::default();
70 rng.try_fill_bytes(&mut ret)?;
71 Ok(ret)
72 }
73}
74
75impl<U: ArraySize> Generate for Array<u32, U> {
76 #[inline]
77 fn try_generate_from_rng<R: TryCryptoRng + ?Sized>(rng: &mut R) -> Result<Self, R::Error> {
78 Self::try_from_fn(|_| rng.try_next_u32())
79 }
80}
81
82impl<U: ArraySize> Generate for Array<u64, U> {
83 #[inline]
84 fn try_generate_from_rng<R: TryCryptoRng + ?Sized>(rng: &mut R) -> Result<Self, R::Error> {
85 Self::try_from_fn(|_| rng.try_next_u64())
86 }
87}