primitives/correlated_randomness/pow/
random.rs1use ff::Field;
2
3use crate::{
4 algebra::{
5 field::{FieldExtension, SubfieldElement},
6 BoxedUint,
7 },
8 correlated_randomness::pow::types::{PowPair, PowPairs},
9 izip_eq,
10 random::{CryptoRngCore, Random, RandomWith},
11 sharing::{FieldShare, FieldShares, GlobalFieldKey},
12 types::{heap_array::SubfieldElements, Positive},
13};
14impl<F: FieldExtension> RandomWith<BoxedUint> for PowPair<F> {
19 fn random_with(_rng: impl CryptoRngCore, _exp: BoxedUint) -> Self {
20 unimplemented!("PowPairs are correlated randomness. Use `random_n_with` to establish correlation for n_parties")
21 }
22
23 fn random_n_with<Container: FromIterator<Self>>(
24 mut rng: impl CryptoRngCore,
25 n_parties: usize,
26 exp: BoxedUint,
27 ) -> Container {
28 let alphas = Vec::<GlobalFieldKey<F>>::random_n_with(&mut rng, n_parties, n_parties - 1);
29 PowPair::random_n_with(&mut rng, n_parties, (exp, alphas))
30 }
31}
32
33impl<F: FieldExtension> RandomWith<(BoxedUint, Vec<Vec<GlobalFieldKey<F>>>)> for PowPair<F> {
34 fn random_with(
35 _rng: impl CryptoRngCore,
36 _data: (BoxedUint, Vec<Vec<GlobalFieldKey<F>>>),
37 ) -> Self {
38 unimplemented!("PowPairs are correlated randomness. Use `random_n_with` to establish correlation for n_parties")
39 }
40
41 fn random_n_with<Container: FromIterator<Self>>(
44 mut rng: impl CryptoRngCore,
45 n_parties: usize,
46 (exp, all_alphas): (BoxedUint, Vec<Vec<GlobalFieldKey<F>>>),
47 ) -> Container {
48 assert_eq!(n_parties, all_alphas.len());
49
50 let mut lambda = <SubfieldElement<F> as Random>::random(&mut rng);
51 let mut lambda_pow_neg_exp = lambda.pow(&exp).invert().into_option();
52 while lambda_pow_neg_exp.is_none() {
53 let lambda_new = <SubfieldElement<F> as Random>::random(&mut rng);
55 let lambda_new_pow_neg_exp = lambda_new.pow(&exp).invert().into_option();
56 if let Some(lambda_new_pow_neg_exp) = lambda_new_pow_neg_exp {
57 lambda = lambda_new;
58 lambda_pow_neg_exp = Some(lambda_new_pow_neg_exp);
59 break;
60 }
61 }
62
63 let lambda_shares: Vec<_> =
64 FieldShare::<F>::random_n_with(&mut rng, n_parties, (lambda, all_alphas.clone()));
65 let lambda_pow_neg_exp_shares: Vec<_> = FieldShare::<F>::random_n_with(
66 &mut rng,
67 n_parties,
68 (
69 lambda_pow_neg_exp.expect("We sampled λ so that it was invertible"),
70 all_alphas,
71 ),
72 );
73
74 izip_eq!(lambda_shares, lambda_pow_neg_exp_shares)
75 .map(PowPair::new)
76 .collect()
77 }
78}
79
80impl<F: FieldExtension, N: Positive> RandomWith<BoxedUint> for PowPairs<F, N> {
81 fn random_with(_rng: impl CryptoRngCore, _exp: BoxedUint) -> Self {
82 unimplemented!("PowPairs are correlated randomness. Use `random_n_with` to establish correlation for n_parties")
83 }
84
85 fn random_n_with<Container: FromIterator<Self>>(
86 mut rng: impl CryptoRngCore,
87 n_parties: usize,
88 exp: BoxedUint,
89 ) -> Container {
90 let alphas = Vec::<GlobalFieldKey<F>>::random_n_with(&mut rng, n_parties, n_parties - 1);
91 PowPairs::random_n_with(&mut rng, n_parties, (exp, alphas))
92 }
93}
94
95impl<F: FieldExtension, M: Positive> RandomWith<(BoxedUint, Vec<Vec<GlobalFieldKey<F>>>)>
96 for PowPairs<F, M>
97{
98 fn random_with(
99 _rng: impl CryptoRngCore,
100 _data: (BoxedUint, Vec<Vec<GlobalFieldKey<F>>>),
101 ) -> Self {
102 unimplemented!("PowPairs are correlated randomness. Use `random_n_with` to establish correlation for n_parties")
103 }
104
105 fn random_n_with<Container: FromIterator<Self>>(
106 mut rng: impl CryptoRngCore,
107 n_parties: usize,
108 (exp, all_alphas): (BoxedUint, Vec<Vec<GlobalFieldKey<F>>>),
109 ) -> Container {
110 assert_eq!(n_parties, all_alphas.len());
111
112 let lambdas = <SubfieldElements<F, M> as Random>::random(&mut rng);
114 let lambdas_pow_neg_exp = lambdas.pow(exp).invert().expect("λ^exp is not invertible");
115
116 let lambda_shares: Vec<_> =
117 FieldShares::<F, M>::random_n_with(&mut rng, n_parties, (lambdas, all_alphas.clone()));
118 let lambda_pow_neg_exp_shares: Vec<_> = FieldShares::<F, M>::random_n_with(
119 &mut rng,
120 n_parties,
121 (lambdas_pow_neg_exp, all_alphas),
122 );
123
124 izip_eq!(lambda_shares, lambda_pow_neg_exp_shares)
125 .map(PowPairs::new)
126 .collect()
127 }
128}