use crate::{
algebra::field::{FieldExtension, SubfieldElement},
correlated_randomness::triples::{
Triple,
Triples,
UnauthenticatedTriple,
UnauthenticatedTriples,
},
izip_eq,
random::{CryptoRngCore, Random, RandomWith},
sharing::{unauthenticated::AdditiveShares, FieldShare, FieldShares, GlobalFieldKey},
types::{heap_array::SubfieldElements, Positive},
utils::IntoExactSizeIterator,
};
impl<F: FieldExtension> Random for UnauthenticatedTriple<F> {
fn random(_rng: impl CryptoRngCore) -> Self {
unimplemented!("UnauthenticatedTriple is correlated randomness. Use `random_n` to establish correlation for n_parties")
}
fn random_n<Container: FromIterator<Self>>(
mut rng: impl CryptoRngCore,
n_parties: usize,
) -> Container {
let a = SubfieldElement::random(&mut rng);
let b = SubfieldElement::random(&mut rng);
let c = a * b;
let a_shares = a.to_additive_shares(n_parties, &mut rng);
let b_shares = b.to_additive_shares(n_parties, &mut rng);
let c_shares = c.to_additive_shares(n_parties, &mut rng);
izip_eq!(a_shares, b_shares, c_shares)
.map(|(a, b, c)| UnauthenticatedTriple { a, b, c })
.collect()
}
}
impl<F: FieldExtension, M: Positive> Random for UnauthenticatedTriples<F, M> {
fn random(_rng: impl CryptoRngCore) -> Self {
unimplemented!("UnauthenticatedTriples are correlated randomness. Use `random_n` to establish correlation for n_parties")
}
fn random_n<Container: FromIterator<Self>>(
mut rng: impl CryptoRngCore,
n_parties: usize,
) -> Container {
let a = SubfieldElements::random(&mut rng);
let b = SubfieldElements::random(&mut rng);
let c = &a * &b;
let a_shares = a.to_additive_shares(n_parties, &mut rng);
let b_shares = b.to_additive_shares(n_parties, &mut rng);
let c_shares = c.to_additive_shares(n_parties, &mut rng);
izip_eq!(a_shares, b_shares, c_shares)
.map(|(a, b, c)| UnauthenticatedTriples { a, b, c })
.collect()
}
}
impl<F: FieldExtension, M: Positive> Random for Triples<F, M> {
fn random(_rng: impl CryptoRngCore) -> Self {
unimplemented!("Triples are correlated randomness. Use `random_n` to establish correlation for n_parties")
}
fn random_n<Container: FromIterator<Self>>(
mut rng: impl CryptoRngCore,
n_parties: usize,
) -> Container {
let a = SubfieldElements::random(&mut rng);
let b = SubfieldElements::random(&mut rng);
let c = &a * &b;
let a_shares: Vec<_> = FieldShares::random_n_with(&mut rng, n_parties, a);
let b_shares: Vec<_> = FieldShares::random_n_with(&mut rng, n_parties, b);
let c_shares: Vec<_> = FieldShares::random_n_with(&mut rng, n_parties, c);
izip_eq!(a_shares, b_shares, c_shares)
.map(|(a, b, c)| Triples { a, b, c })
.collect()
}
}
impl<F: FieldExtension, M: Positive> RandomWith<Vec<GlobalFieldKey<F>>> for Triples<F, M> {
#[allow(unused_mut)]
fn random_with(mut rng: impl CryptoRngCore, alphas: Vec<GlobalFieldKey<F>>) -> Self {
#[cfg(any(test, feature = "dev"))]
{
Triples {
a: FieldShares::<F, M>::random_with(&mut rng, alphas.clone()),
b: FieldShares::<F, M>::random_with(&mut rng, alphas.clone()),
c: FieldShares::<F, M>::random_with(&mut rng, alphas),
}
}
#[cfg(not(any(test, feature = "dev")))]
unimplemented!(
"Triples are correlated randomness. Use `random_n_with_each({}, Vec<{}>)` to establish correlation for n_parties", std::any::type_name_of_val(&rng),
std::any::type_name_of_val(&alphas)
);
}
fn random_n_with_each<Container: FromIterator<Self>>(
mut rng: impl CryptoRngCore,
all_alphas: impl IntoExactSizeIterator<Item = Vec<GlobalFieldKey<F>>>,
) -> Container {
let all_alphas = all_alphas.into_iter().collect::<Vec<_>>();
let a = SubfieldElements::random(&mut rng);
let b = SubfieldElements::random(&mut rng);
let c = &a * &b;
let n_parties = all_alphas.len();
let a_shares: Vec<_> =
FieldShares::random_n_with(&mut rng, n_parties, (a, all_alphas.clone()));
let b_shares: Vec<_> =
FieldShares::random_n_with(&mut rng, n_parties, (b, all_alphas.clone()));
let c_shares: Vec<_> = FieldShares::random_n_with(&mut rng, n_parties, (c, all_alphas));
izip_eq!(a_shares, b_shares, c_shares)
.map(|(a, b, c)| Triples { a, b, c })
.collect()
}
}
impl<F: FieldExtension> Random for Triple<F> {
fn random(_rng: impl CryptoRngCore) -> Self {
unimplemented!("Triples are correlated randomness. Use `random_n`/`random_n_with`` to establish correlation for n_parties")
}
fn random_n<Container: FromIterator<Self>>(
mut rng: impl CryptoRngCore,
n_parties: usize,
) -> Container {
let a = SubfieldElement::random(&mut rng);
let b = SubfieldElement::random(&mut rng);
let c = a * b;
let a_shares: Vec<_> = FieldShare::random_n_with(&mut rng, n_parties, a);
let b_shares: Vec<_> = FieldShare::random_n_with(&mut rng, n_parties, b);
let c_shares: Vec<_> = FieldShare::random_n_with(&mut rng, n_parties, c);
izip_eq!(a_shares, b_shares, c_shares)
.map(|(a, b, c)| Triple { a, b, c })
.collect()
}
}
impl<F: FieldExtension> RandomWith<Vec<GlobalFieldKey<F>>> for Triple<F> {
#[allow(unused_mut)]
fn random_with(mut rng: impl CryptoRngCore, alphas: Vec<GlobalFieldKey<F>>) -> Self {
#[cfg(any(test, feature = "dev"))]
{
Triple {
a: FieldShare::random_with(&mut rng, alphas.clone()),
b: FieldShare::random_with(&mut rng, alphas.clone()),
c: FieldShare::random_with(&mut rng, alphas),
}
}
#[cfg(not(any(test, feature = "dev")))]
unimplemented!(
"Triples are correlated randomness. Use `random_n_with_each({}, Vec<{}>)` to establish correlation for n_parties", std::any::type_name_of_val(&rng),
std::any::type_name_of_val(&alphas)
);
}
fn random_n_with_each<Container: FromIterator<Self>>(
mut rng: impl CryptoRngCore,
all_alphas: impl IntoExactSizeIterator<Item = Vec<GlobalFieldKey<F>>>,
) -> Container {
let all_alphas = all_alphas.into_iter().collect::<Vec<_>>();
let a = SubfieldElement::random(&mut rng);
let b = SubfieldElement::random(&mut rng);
let c = a * b;
let n_parties = all_alphas.len();
let a_shares: Vec<_> =
FieldShare::random_n_with(&mut rng, n_parties, (a, all_alphas.clone()));
let b_shares: Vec<_> =
FieldShare::random_n_with(&mut rng, n_parties, (b, all_alphas.clone()));
let c_shares: Vec<_> = FieldShare::random_n_with(&mut rng, n_parties, (c, all_alphas));
izip_eq!(a_shares, b_shares, c_shares)
.map(|(a, b, c)| Triple { a, b, c })
.collect()
}
}