Skip to main content

primitives/correlated_randomness/triples/
random.rs

1use crate::{
2    algebra::field::{FieldExtension, SubfieldElement},
3    correlated_randomness::triples::{
4        CorrelatedUnauthenticatedTriples,
5        Triple,
6        Triples,
7        UnauthenticatedTriple,
8        UnauthenticatedTriples,
9    },
10    izip_eq,
11    random::{CryptoRngCore, Random, RandomWith},
12    sharing::{unauthenticated::AdditiveShares, FieldShare, FieldShares, GlobalFieldKey},
13    types::{heap_array::SubfieldElements, Positive},
14    utils::IntoExactSizeIterator,
15};
16// -------------------------
17// |   Random Generation   |
18// -------------------------
19
20impl<F: FieldExtension> Random for UnauthenticatedTriple<F> {
21    fn random(_rng: impl CryptoRngCore) -> Self {
22        unimplemented!("UnauthenticatedTriple is correlated randomness. Use `random_n` to establish correlation for n_parties")
23    }
24
25    /// Generates random triples for all the parties requested.
26    fn random_n<Container: FromIterator<Self>>(
27        mut rng: impl CryptoRngCore,
28        n_parties: usize,
29    ) -> Container {
30        let a = SubfieldElement::random(&mut rng);
31        let b = SubfieldElement::random(&mut rng);
32        let c = a * b;
33
34        let a_shares = a.to_additive_shares(n_parties, &mut rng);
35        let b_shares = b.to_additive_shares(n_parties, &mut rng);
36        let c_shares = c.to_additive_shares(n_parties, &mut rng);
37
38        izip_eq!(a_shares, b_shares, c_shares)
39            .map(|(a, b, c)| UnauthenticatedTriple { a, b, c })
40            .collect()
41    }
42}
43
44impl<F: FieldExtension, M: Positive> Random for UnauthenticatedTriples<F, M> {
45    fn random(_rng: impl CryptoRngCore) -> Self {
46        unimplemented!("UnauthenticatedTriples are correlated randomness. Use `random_n` to establish correlation for n_parties")
47    }
48
49    /// Generates random triples for all the parties requested.
50    fn random_n<Container: FromIterator<Self>>(
51        mut rng: impl CryptoRngCore,
52        n_parties: usize,
53    ) -> Container {
54        let a = SubfieldElements::random(&mut rng);
55        let b = SubfieldElements::random(&mut rng);
56        let c = &a * &b;
57
58        let a_shares = a.to_additive_shares(n_parties, &mut rng);
59        let b_shares = b.to_additive_shares(n_parties, &mut rng);
60        let c_shares = c.to_additive_shares(n_parties, &mut rng);
61
62        izip_eq!(a_shares, b_shares, c_shares)
63            .map(|(a, b, c)| UnauthenticatedTriples { a, b, c })
64            .collect()
65    }
66}
67
68impl<F: FieldExtension, M: Positive> Random for CorrelatedUnauthenticatedTriples<F, M> {
69    fn random(_rng: impl CryptoRngCore) -> Self {
70        unimplemented!("CorrelatedUnauthenticatedTriples are correlated randomness. Use `random_n` to establish correlation for n_parties")
71    }
72
73    /// Generates random correlated triples for all the parties requested.
74    fn random_n<Container: FromIterator<Self>>(
75        mut rng: impl CryptoRngCore,
76        n_parties: usize,
77    ) -> Container {
78        let a = SubfieldElements::random(&mut rng);
79        let b = SubfieldElements::random(&mut rng);
80        let c = &a * &b;
81        let d = SubfieldElements::random(&mut rng);
82        let f = &b * &d;
83
84        let a_shares = a.to_additive_shares(n_parties, &mut rng);
85        let b_shares = b.to_additive_shares(n_parties, &mut rng);
86        let c_shares = c.to_additive_shares(n_parties, &mut rng);
87        let d_shares = d.to_additive_shares(n_parties, &mut rng);
88        let f_shares = f.to_additive_shares(n_parties, &mut rng);
89
90        izip_eq!(a_shares, b_shares, c_shares, d_shares, f_shares)
91            .map(|(a, b, c, d, f)| CorrelatedUnauthenticatedTriples { a, b, c, d, f })
92            .collect()
93    }
94}
95
96impl<F: FieldExtension, M: Positive> Random for Triples<F, M> {
97    fn random(_rng: impl CryptoRngCore) -> Self {
98        unimplemented!("Triples are correlated randomness. Use `random_n` to establish correlation for n_parties")
99    }
100
101    /// Generates random triples for all the parties requested.
102    fn random_n<Container: FromIterator<Self>>(
103        mut rng: impl CryptoRngCore,
104        n_parties: usize,
105    ) -> Container {
106        let a = SubfieldElements::random(&mut rng);
107        let b = SubfieldElements::random(&mut rng);
108        let c = &a * &b;
109
110        let a_shares: Vec<_> = FieldShares::random_n_with(&mut rng, n_parties, a);
111        let b_shares: Vec<_> = FieldShares::random_n_with(&mut rng, n_parties, b);
112        let c_shares: Vec<_> = FieldShares::random_n_with(&mut rng, n_parties, c);
113
114        izip_eq!(a_shares, b_shares, c_shares)
115            .map(|(a, b, c)| Triples { a, b, c })
116            .collect()
117    }
118}
119
120impl<F: FieldExtension, M: Positive> RandomWith<Vec<GlobalFieldKey<F>>> for Triples<F, M> {
121    /// Generate a single random triple share for the global keys of a single party.
122    ///
123    /// WARNING: This does not establish correlation with other parties! Use only to mock a single
124    /// party's triple.
125    #[allow(unused_mut)]
126    fn random_with(mut rng: impl CryptoRngCore, alphas: Vec<GlobalFieldKey<F>>) -> Self {
127        #[cfg(any(test, feature = "dev"))]
128        {
129            Triples {
130                a: FieldShares::<F, M>::random_with(&mut rng, alphas.clone()),
131                b: FieldShares::<F, M>::random_with(&mut rng, alphas.clone()),
132                c: FieldShares::<F, M>::random_with(&mut rng, alphas),
133            }
134        }
135
136        #[cfg(not(any(test, feature = "dev")))]
137        unimplemented!(
138            "Triples are correlated randomness. Use `random_n_with_each({}, Vec<{}>)` to establish correlation for n_parties", std::any::type_name_of_val(&rng),
139            std::any::type_name_of_val(&alphas)
140        );
141    }
142
143    /// Generate random triples given the global keys (alphas) for all parties.
144    fn random_n_with_each<Container: FromIterator<Self>>(
145        mut rng: impl CryptoRngCore,
146        all_alphas: impl IntoExactSizeIterator<Item = Vec<GlobalFieldKey<F>>>,
147    ) -> Container {
148        let all_alphas = all_alphas.into_iter().collect::<Vec<_>>();
149        let a = SubfieldElements::random(&mut rng);
150        let b = SubfieldElements::random(&mut rng);
151        let c = &a * &b;
152
153        let n_parties = all_alphas.len();
154        let a_shares: Vec<_> =
155            FieldShares::random_n_with(&mut rng, n_parties, (a, all_alphas.clone()));
156        let b_shares: Vec<_> =
157            FieldShares::random_n_with(&mut rng, n_parties, (b, all_alphas.clone()));
158        let c_shares: Vec<_> = FieldShares::random_n_with(&mut rng, n_parties, (c, all_alphas));
159
160        izip_eq!(a_shares, b_shares, c_shares)
161            .map(|(a, b, c)| Triples { a, b, c })
162            .collect()
163    }
164}
165
166impl<F: FieldExtension> Random for Triple<F> {
167    fn random(_rng: impl CryptoRngCore) -> Self {
168        unimplemented!("Triples are correlated randomness. Use `random_n`/`random_n_with`` to establish correlation for n_parties")
169    }
170
171    /// Generates random triples for all the parties requested.
172    fn random_n<Container: FromIterator<Self>>(
173        mut rng: impl CryptoRngCore,
174        n_parties: usize,
175    ) -> Container {
176        let a = SubfieldElement::random(&mut rng);
177        let b = SubfieldElement::random(&mut rng);
178        let c = a * b;
179
180        let a_shares: Vec<_> = FieldShare::random_n_with(&mut rng, n_parties, a);
181        let b_shares: Vec<_> = FieldShare::random_n_with(&mut rng, n_parties, b);
182        let c_shares: Vec<_> = FieldShare::random_n_with(&mut rng, n_parties, c);
183
184        izip_eq!(a_shares, b_shares, c_shares)
185            .map(|(a, b, c)| Triple { a, b, c })
186            .collect()
187    }
188}
189
190impl<F: FieldExtension> RandomWith<Vec<GlobalFieldKey<F>>> for Triple<F> {
191    /// Generate a single random triple share for the global keys of a single party.
192    #[allow(unused_mut)]
193    fn random_with(mut rng: impl CryptoRngCore, alphas: Vec<GlobalFieldKey<F>>) -> Self {
194        #[cfg(any(test, feature = "dev"))]
195        {
196            Triple {
197                a: FieldShare::random_with(&mut rng, alphas.clone()),
198                b: FieldShare::random_with(&mut rng, alphas.clone()),
199                c: FieldShare::random_with(&mut rng, alphas),
200            }
201        }
202
203        #[cfg(not(any(test, feature = "dev")))]
204        unimplemented!(
205            "Triples are correlated randomness. Use `random_n_with_each({}, Vec<{}>)` to establish correlation for n_parties", std::any::type_name_of_val(&rng),
206            std::any::type_name_of_val(&alphas)
207        );
208    }
209
210    /// Generate random triples given the global keys (alphas) for all parties.
211    fn random_n_with_each<Container: FromIterator<Self>>(
212        mut rng: impl CryptoRngCore,
213        all_alphas: impl IntoExactSizeIterator<Item = Vec<GlobalFieldKey<F>>>,
214    ) -> Container {
215        let all_alphas = all_alphas.into_iter().collect::<Vec<_>>();
216        let a = SubfieldElement::random(&mut rng);
217        let b = SubfieldElement::random(&mut rng);
218        let c = a * b;
219
220        let n_parties = all_alphas.len();
221        let a_shares: Vec<_> =
222            FieldShare::random_n_with(&mut rng, n_parties, (a, all_alphas.clone()));
223        let b_shares: Vec<_> =
224            FieldShare::random_n_with(&mut rng, n_parties, (b, all_alphas.clone()));
225        let c_shares: Vec<_> = FieldShare::random_n_with(&mut rng, n_parties, (c, all_alphas));
226
227        izip_eq!(a_shares, b_shares, c_shares)
228            .map(|(a, b, c)| Triple { a, b, c })
229            .collect()
230    }
231}