primitives/correlated_randomness/triples/
random.rs1use crate::{
2 algebra::field::{FieldExtension, SubfieldElement},
3 correlated_randomness::triples::{
4 Triple,
5 Triples,
6 UnauthenticatedTriple,
7 UnauthenticatedTriples,
8 },
9 izip_eq,
10 random::{CryptoRngCore, Random, RandomWith},
11 sharing::{unauthenticated::AdditiveShares, FieldShare, FieldShares, GlobalFieldKey},
12 types::{heap_array::SubfieldElements, Positive},
13 utils::IntoExactSizeIterator,
14};
15impl<F: FieldExtension> Random for UnauthenticatedTriple<F> {
20 fn random(_rng: impl CryptoRngCore) -> Self {
21 unimplemented!("UnauthenticatedTriple is correlated randomness. Use `random_n` to establish correlation for n_parties")
22 }
23
24 fn random_n<Container: FromIterator<Self>>(
26 mut rng: impl CryptoRngCore,
27 n_parties: usize,
28 ) -> Container {
29 let a = SubfieldElement::random(&mut rng);
30 let b = SubfieldElement::random(&mut rng);
31 let c = a * b;
32
33 let a_shares = a.to_additive_shares(n_parties, &mut rng);
34 let b_shares = b.to_additive_shares(n_parties, &mut rng);
35 let c_shares = c.to_additive_shares(n_parties, &mut rng);
36
37 izip_eq!(a_shares, b_shares, c_shares)
38 .map(|(a, b, c)| UnauthenticatedTriple { a, b, c })
39 .collect()
40 }
41}
42
43impl<F: FieldExtension, M: Positive> Random for UnauthenticatedTriples<F, M> {
44 fn random(_rng: impl CryptoRngCore) -> Self {
45 unimplemented!("UnauthenticatedTriples are correlated randomness. Use `random_n` to establish correlation for n_parties")
46 }
47
48 fn random_n<Container: FromIterator<Self>>(
50 mut rng: impl CryptoRngCore,
51 n_parties: usize,
52 ) -> Container {
53 let a = SubfieldElements::random(&mut rng);
54 let b = SubfieldElements::random(&mut rng);
55 let c = &a * &b;
56
57 let a_shares = a.to_additive_shares(n_parties, &mut rng);
58 let b_shares = b.to_additive_shares(n_parties, &mut rng);
59 let c_shares = c.to_additive_shares(n_parties, &mut rng);
60
61 izip_eq!(a_shares, b_shares, c_shares)
62 .map(|(a, b, c)| UnauthenticatedTriples { a, b, c })
63 .collect()
64 }
65}
66
67impl<F: FieldExtension, M: Positive> Random for Triples<F, M> {
68 fn random(_rng: impl CryptoRngCore) -> Self {
69 unimplemented!("Triples are correlated randomness. Use `random_n` to establish correlation for n_parties")
70 }
71
72 fn random_n<Container: FromIterator<Self>>(
74 mut rng: impl CryptoRngCore,
75 n_parties: usize,
76 ) -> Container {
77 let a = SubfieldElements::random(&mut rng);
78 let b = SubfieldElements::random(&mut rng);
79 let c = &a * &b;
80
81 let a_shares: Vec<_> = FieldShares::random_n_with(&mut rng, n_parties, a);
82 let b_shares: Vec<_> = FieldShares::random_n_with(&mut rng, n_parties, b);
83 let c_shares: Vec<_> = FieldShares::random_n_with(&mut rng, n_parties, c);
84
85 izip_eq!(a_shares, b_shares, c_shares)
86 .map(|(a, b, c)| Triples { a, b, c })
87 .collect()
88 }
89}
90
91impl<F: FieldExtension, M: Positive> RandomWith<Vec<GlobalFieldKey<F>>> for Triples<F, M> {
92 #[allow(unused_mut)]
97 fn random_with(mut rng: impl CryptoRngCore, alphas: Vec<GlobalFieldKey<F>>) -> Self {
98 #[cfg(any(test, feature = "dev"))]
99 {
100 Triples {
101 a: FieldShares::<F, M>::random_with(&mut rng, alphas.clone()),
102 b: FieldShares::<F, M>::random_with(&mut rng, alphas.clone()),
103 c: FieldShares::<F, M>::random_with(&mut rng, alphas),
104 }
105 }
106
107 #[cfg(not(any(test, feature = "dev")))]
108 unimplemented!(
109 "Triples are correlated randomness. Use `random_n_with_each({}, Vec<{}>)` to establish correlation for n_parties", std::any::type_name_of_val(&rng),
110 std::any::type_name_of_val(&alphas)
111 );
112 }
113
114 fn random_n_with_each<Container: FromIterator<Self>>(
116 mut rng: impl CryptoRngCore,
117 all_alphas: impl IntoExactSizeIterator<Item = Vec<GlobalFieldKey<F>>>,
118 ) -> Container {
119 let all_alphas = all_alphas.into_iter().collect::<Vec<_>>();
120 let a = SubfieldElements::random(&mut rng);
121 let b = SubfieldElements::random(&mut rng);
122 let c = &a * &b;
123
124 let n_parties = all_alphas.len();
125 let a_shares: Vec<_> =
126 FieldShares::random_n_with(&mut rng, n_parties, (a, all_alphas.clone()));
127 let b_shares: Vec<_> =
128 FieldShares::random_n_with(&mut rng, n_parties, (b, all_alphas.clone()));
129 let c_shares: Vec<_> = FieldShares::random_n_with(&mut rng, n_parties, (c, all_alphas));
130
131 izip_eq!(a_shares, b_shares, c_shares)
132 .map(|(a, b, c)| Triples { a, b, c })
133 .collect()
134 }
135}
136
137impl<F: FieldExtension> Random for Triple<F> {
138 fn random(_rng: impl CryptoRngCore) -> Self {
139 unimplemented!("Triples are correlated randomness. Use `random_n`/`random_n_with`` to establish correlation for n_parties")
140 }
141
142 fn random_n<Container: FromIterator<Self>>(
144 mut rng: impl CryptoRngCore,
145 n_parties: usize,
146 ) -> Container {
147 let a = SubfieldElement::random(&mut rng);
148 let b = SubfieldElement::random(&mut rng);
149 let c = a * b;
150
151 let a_shares: Vec<_> = FieldShare::random_n_with(&mut rng, n_parties, a);
152 let b_shares: Vec<_> = FieldShare::random_n_with(&mut rng, n_parties, b);
153 let c_shares: Vec<_> = FieldShare::random_n_with(&mut rng, n_parties, c);
154
155 izip_eq!(a_shares, b_shares, c_shares)
156 .map(|(a, b, c)| Triple { a, b, c })
157 .collect()
158 }
159}
160
161impl<F: FieldExtension> RandomWith<Vec<GlobalFieldKey<F>>> for Triple<F> {
162 #[allow(unused_mut)]
164 fn random_with(mut rng: impl CryptoRngCore, alphas: Vec<GlobalFieldKey<F>>) -> Self {
165 #[cfg(any(test, feature = "dev"))]
166 {
167 Triple {
168 a: FieldShare::random_with(&mut rng, alphas.clone()),
169 b: FieldShare::random_with(&mut rng, alphas.clone()),
170 c: FieldShare::random_with(&mut rng, alphas),
171 }
172 }
173
174 #[cfg(not(any(test, feature = "dev")))]
175 unimplemented!(
176 "Triples are correlated randomness. Use `random_n_with_each({}, Vec<{}>)` to establish correlation for n_parties", std::any::type_name_of_val(&rng),
177 std::any::type_name_of_val(&alphas)
178 );
179 }
180
181 fn random_n_with_each<Container: FromIterator<Self>>(
183 mut rng: impl CryptoRngCore,
184 all_alphas: impl IntoExactSizeIterator<Item = Vec<GlobalFieldKey<F>>>,
185 ) -> Container {
186 let all_alphas = all_alphas.into_iter().collect::<Vec<_>>();
187 let a = SubfieldElement::random(&mut rng);
188 let b = SubfieldElement::random(&mut rng);
189 let c = a * b;
190
191 let n_parties = all_alphas.len();
192 let a_shares: Vec<_> =
193 FieldShare::random_n_with(&mut rng, n_parties, (a, all_alphas.clone()));
194 let b_shares: Vec<_> =
195 FieldShare::random_n_with(&mut rng, n_parties, (b, all_alphas.clone()));
196 let c_shares: Vec<_> = FieldShare::random_n_with(&mut rng, n_parties, (c, all_alphas));
197
198 izip_eq!(a_shares, b_shares, c_shares)
199 .map(|(a, b, c)| Triple { a, b, c })
200 .collect()
201 }
202}