penumbra_sdk_tct/
random.rs1use 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 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 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 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 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 pub fn random(mut rng: impl Rng) -> Self {
88 rng.sample(UniformFq)
89 }
90}