use itertools::izip;
use num_traits::identities::{One, Zero};
use crate::{
algebra::{
field::{binary::Gf2_128, FieldExtension, SubfieldElement},
ops::transpose,
},
correlated_randomness::dabits::{DaBit, DaBits},
random::{CryptoRngCore, Random, RandomWith},
sharing::{BitShare, FieldShare, GlobalFieldKey},
types::Positive,
};
impl<F: FieldExtension>
RandomWith<(
Vec<Vec<GlobalFieldKey<F>>>,
Vec<Vec<GlobalFieldKey<Gf2_128>>>,
)> for DaBit<F>
{
fn random_with(
_rng: impl CryptoRngCore,
_data: (
Vec<Vec<GlobalFieldKey<F>>>,
Vec<Vec<GlobalFieldKey<Gf2_128>>>,
),
) -> Self {
unimplemented!("DaBits are correlated randomness. Use `random_n_with` to establish correlation for n_parties")
}
fn random_n_with<Container: FromIterator<Self>>(
mut rng: impl CryptoRngCore,
n_parties: usize,
(alphas_f, alphas_gf2): (
Vec<Vec<GlobalFieldKey<F>>>,
Vec<Vec<GlobalFieldKey<Gf2_128>>>,
),
) -> Container {
let bit = SubfieldElement::<Gf2_128>::random(&mut rng);
let bit_shares: Vec<_> = BitShare::random_n_with(&mut rng, n_parties, (bit, alphas_gf2));
let field_value = if SubfieldElement::<Gf2_128>::one() == bit {
SubfieldElement::<F>::one()
} else {
SubfieldElement::<F>::zero()
};
let field_shares: Vec<_> =
FieldShare::random_n_with(&mut rng, n_parties, (field_value, alphas_f));
izip!(bit_shares, field_shares)
.map(|(bit, field_share)| DaBit::new(bit, field_share))
.collect()
}
}
impl<F: FieldExtension, M: Positive>
RandomWith<(
Vec<Vec<GlobalFieldKey<F>>>,
Vec<Vec<GlobalFieldKey<Gf2_128>>>,
)> for DaBits<F, M>
{
fn random_with(
_rng: impl CryptoRngCore,
_data: (
Vec<Vec<GlobalFieldKey<F>>>,
Vec<Vec<GlobalFieldKey<Gf2_128>>>,
),
) -> Self {
unimplemented!("DaBits are correlated randomness. Use `random_n_with` to establish correlation for n_parties")
}
fn random_n_with<Container: FromIterator<Self>>(
mut rng: impl CryptoRngCore,
n_parties: usize,
(alphas_f, alphas_gf2): (
Vec<Vec<GlobalFieldKey<F>>>,
Vec<Vec<GlobalFieldKey<Gf2_128>>>,
),
) -> Container {
transpose(
(0..M::USIZE)
.map(|_| {
DaBit::<F>::random_n_with::<Vec<_>>(
&mut rng,
n_parties,
(alphas_f.clone(), alphas_gf2.clone()),
)
})
.collect::<Vec<_>>(),
)
.into_iter()
.map(|dabits| {
let (bits, field_shares) = dabits
.into_iter()
.map(|dabit| {
let DaBit { bit, field } = dabit;
(bit, field)
})
.unzip::<_, _, Vec<_>, Vec<_>>();
let bits = bits.into_iter().collect();
let field_shares = field_shares.into_iter().collect();
DaBits::new(bits, field_shares)
})
.collect()
}
}