1pub mod prf;
2pub mod prg;
3pub mod rng;
4
5use std::sync::Arc;
6
7pub use rand_chacha::rand_core::CryptoRngCore;
8#[cfg(any(test, feature = "dev"))]
9pub use rng::test_rng;
10pub use rng::{BaseRng, Seed, SeedableRng};
11use subtle::Choice;
12use typenum::Unsigned;
13
14use crate::{
15 algebra::field::FieldExtension,
16 constants::Lambda,
17 errors::PrimitiveError,
18 types::{HeapArray, Positive},
19 utils::IntoExactSizeIterator,
20};
21
22pub trait Random: Sized {
25 fn random(rng: impl CryptoRngCore) -> Self;
27
28 fn random_n<Container: FromIterator<Self>>(
30 mut rng: impl CryptoRngCore,
31 size: usize,
32 ) -> Container {
33 (0..size).map(|_| Self::random(&mut rng)).collect()
34 }
35
36 fn random_array<M: Positive>(rng: impl CryptoRngCore) -> HeapArray<Self, M> {
38 HeapArray::random(rng)
39 }
40}
41
42impl Random for Seed {
43 #[inline]
44 fn random(mut rng: impl CryptoRngCore) -> Self {
45 let mut seed = [0u8; 32];
46 rng.fill_bytes(&mut seed);
47 seed
48 }
49}
50
51impl<T: Random> Random for Arc<T> {
52 #[inline]
53 fn random(mut source: impl CryptoRngCore) -> Self {
54 Arc::new(T::random(&mut source))
55 }
56}
57
58impl<T: Random> RandomWith<usize> for Vec<T> {
59 #[inline]
60 fn random_with(mut source: impl CryptoRngCore, n_elements: usize) -> Self {
61 (0..n_elements).map(|_| T::random(&mut source)).collect()
62 }
63}
64
65pub trait RandomWith<D: Clone>: Sized {
67 fn random_with(rng: impl CryptoRngCore, data: D) -> Self;
69
70 fn random_n_with<Container: FromIterator<Self>>(
72 mut rng: impl CryptoRngCore,
73 size: usize,
74 data: D,
75 ) -> Container {
76 (0..size)
77 .map(|_| Self::random_with(&mut rng, data.clone()))
78 .collect()
79 }
80
81 fn random_n_with_each<Container: FromIterator<Self>>(
83 mut rng: impl CryptoRngCore,
84 all_data: impl IntoExactSizeIterator<Item = D>,
85 ) -> Container {
86 all_data
87 .into_iter()
88 .map(|data| Self::random_with(&mut rng, data))
89 .collect()
90 }
91}
92
93pub trait RandomNonZero: Sized {
95 fn random_non_zero(rng: impl CryptoRngCore) -> Result<Self, PrimitiveError>;
97
98 fn random_n_non_zero<Container: FromIterator<Self>>(
100 rng: impl CryptoRngCore,
101 size: usize,
102 ) -> Result<Container, PrimitiveError>;
103}
104
105impl<T: FieldExtension> RandomNonZero for T {
106 #[inline]
121 fn random_non_zero(mut rng: impl CryptoRngCore) -> Result<Self, PrimitiveError> {
122 let n_tries = (Lambda::USIZE).div_ceil(std::mem::size_of::<Self>());
123 for _ in 0..n_tries {
124 let value = <Self as ff::Field>::random(&mut rng);
125 if !<Choice as Into<bool>>::into(value.is_zero()) {
126 return Ok(value);
127 }
128 }
129 Err(PrimitiveError::ZeroValueSampled(
130 std::any::type_name::<Self>().into(),
131 ))
132 }
133
134 fn random_n_non_zero<Container: FromIterator<Self>>(
136 mut rng: impl CryptoRngCore,
137 size: usize,
138 ) -> Result<Container, PrimitiveError> {
139 (0..size).map(|_| Self::random_non_zero(&mut rng)).collect()
140 }
141}
142
143impl Random for u8 {
144 #[inline]
145 fn random(mut rng: impl CryptoRngCore) -> Self {
146 let mut buf = [0u8; 1];
147 rng.fill_bytes(&mut buf);
148 buf[0]
149 }
150
151 fn random_n<Container: FromIterator<Self>>(
152 mut rng: impl CryptoRngCore,
153 size: usize,
154 ) -> Container {
155 let mut buf = vec![0u8; size];
156 rng.fill_bytes(&mut buf);
157 buf.into_iter().collect()
158 }
159}