Skip to main content

primitives/correlated_randomness/dabits/
random.rs

1use itertools::izip;
2use num_traits::identities::{One, Zero};
3
4use crate::{
5    algebra::{
6        field::{binary::Gf2_128, FieldExtension, SubfieldElement},
7        ops::transpose,
8    },
9    correlated_randomness::dabits::{DaBit, DaBits},
10    random::{CryptoRngCore, Random, RandomWith},
11    sharing::{BitShare, FieldShare, GlobalFieldKey},
12    types::Positive,
13};
14// -------------------------
15// |   Random Generation   |
16// -------------------------
17
18impl<F: FieldExtension>
19    RandomWith<(
20        Vec<Vec<GlobalFieldKey<F>>>,
21        Vec<Vec<GlobalFieldKey<Gf2_128>>>,
22    )> for DaBit<F>
23{
24    fn random_with(
25        _rng: impl CryptoRngCore,
26        _data: (
27            Vec<Vec<GlobalFieldKey<F>>>,
28            Vec<Vec<GlobalFieldKey<Gf2_128>>>,
29        ),
30    ) -> Self {
31        unimplemented!("DaBits are correlated randomness. Use `random_n_with` to establish correlation for n_parties")
32    }
33
34    fn random_n_with<Container: FromIterator<Self>>(
35        mut rng: impl CryptoRngCore,
36        n_parties: usize,
37        (alphas_f, alphas_gf2): (
38            Vec<Vec<GlobalFieldKey<F>>>,
39            Vec<Vec<GlobalFieldKey<Gf2_128>>>,
40        ),
41    ) -> Container {
42        let bit = SubfieldElement::<Gf2_128>::random(&mut rng);
43        let bit_shares: Vec<_> = BitShare::random_n_with(&mut rng, n_parties, (bit, alphas_gf2));
44
45        let field_value = if SubfieldElement::<Gf2_128>::one() == bit {
46            SubfieldElement::<F>::one()
47        } else {
48            SubfieldElement::<F>::zero()
49        };
50        let field_shares: Vec<_> =
51            FieldShare::random_n_with(&mut rng, n_parties, (field_value, alphas_f));
52
53        izip!(bit_shares, field_shares)
54            .map(|(bit, field_share)| DaBit::new(bit, field_share))
55            .collect()
56    }
57}
58
59impl<F: FieldExtension, M: Positive>
60    RandomWith<(
61        Vec<Vec<GlobalFieldKey<F>>>,
62        Vec<Vec<GlobalFieldKey<Gf2_128>>>,
63    )> for DaBits<F, M>
64{
65    fn random_with(
66        _rng: impl CryptoRngCore,
67        _data: (
68            Vec<Vec<GlobalFieldKey<F>>>,
69            Vec<Vec<GlobalFieldKey<Gf2_128>>>,
70        ),
71    ) -> Self {
72        unimplemented!("DaBits are correlated randomness. Use `random_n_with` to establish correlation for n_parties")
73    }
74
75    fn random_n_with<Container: FromIterator<Self>>(
76        mut rng: impl CryptoRngCore,
77        n_parties: usize,
78        (alphas_f, alphas_gf2): (
79            Vec<Vec<GlobalFieldKey<F>>>,
80            Vec<Vec<GlobalFieldKey<Gf2_128>>>,
81        ),
82    ) -> Container {
83        transpose(
84            (0..M::USIZE)
85                .map(|_| {
86                    DaBit::<F>::random_n_with::<Vec<_>>(
87                        &mut rng,
88                        n_parties,
89                        (alphas_f.clone(), alphas_gf2.clone()),
90                    )
91                })
92                .collect::<Vec<_>>(),
93        )
94        .into_iter()
95        .map(|dabits| {
96            let (bits, field_shares) = dabits
97                .into_iter()
98                .map(|dabit| {
99                    let DaBit { bit, field } = dabit;
100                    (bit, field)
101                })
102                .unzip::<_, _, Vec<_>, Vec<_>>();
103
104            let bits = bits.into_iter().collect();
105            let field_shares = field_shares.into_iter().collect();
106
107            DaBits::new(bits, field_shares)
108        })
109        .collect()
110    }
111}