penumbra_sdk_tct/
random.rs

1//! Generating random values of various types.
2
3use decaf377::Fq;
4use rand::{distributions::Distribution, Rng};
5
6use super::StateCommitment;
7use crate::{
8    builder::{block, epoch},
9    structure::Hash,
10    Root,
11};
12
13struct UniformFq;
14
15impl Distribution<Fq> for UniformFq {
16    fn sample<R: Rng + ?Sized>(&self, rng: &mut R) -> Fq {
17        let mut bytes = [0u8; 32];
18        loop {
19            rng.fill_bytes(&mut bytes);
20            if let Ok(fq) = Fq::from_bytes_checked(&bytes) {
21                return fq;
22            }
23        }
24    }
25}
26
27impl Distribution<StateCommitment> for UniformFq {
28    fn sample<R: Rng + ?Sized>(&self, rng: &mut R) -> StateCommitment {
29        StateCommitment(self.sample(rng))
30    }
31}
32
33impl StateCommitment {
34    /// Generate a random [`Commitment`].
35    pub fn random(mut rng: impl Rng) -> Self {
36        rng.sample(UniformFq)
37    }
38}
39
40impl Distribution<Hash> for UniformFq {
41    fn sample<R: Rng + ?Sized>(&self, rng: &mut R) -> Hash {
42        Hash::new(self.sample(rng))
43    }
44}
45
46impl Hash {
47    /// Generate a random [`struct@Hash`].
48    pub fn random(mut rng: impl Rng) -> Self {
49        rng.sample(UniformFq)
50    }
51}
52
53impl Distribution<Root> for UniformFq {
54    fn sample<R: Rng + ?Sized>(&self, rng: &mut R) -> Root {
55        Root(self.sample(rng))
56    }
57}
58
59impl Root {
60    /// Generate a random [`Root`].
61    pub fn random(mut rng: impl Rng) -> Self {
62        rng.sample(UniformFq)
63    }
64}
65
66impl Distribution<epoch::Root> for UniformFq {
67    fn sample<R: Rng + ?Sized>(&self, rng: &mut R) -> epoch::Root {
68        epoch::Root(self.sample(rng))
69    }
70}
71
72impl epoch::Root {
73    /// Generate a random [`epoch::Root`].
74    pub fn random(mut rng: impl Rng) -> Self {
75        rng.sample(UniformFq)
76    }
77}
78
79impl Distribution<block::Root> for UniformFq {
80    fn sample<R: Rng + ?Sized>(&self, rng: &mut R) -> block::Root {
81        block::Root(self.sample(rng))
82    }
83}
84
85impl block::Root {
86    /// Generate a random [`block::Root`].
87    pub fn random(mut rng: impl Rng) -> Self {
88        rng.sample(UniformFq)
89    }
90}