pub mod random;
pub mod sharing;
pub mod types;
pub use types::*;
#[cfg(test)]
mod tests {
use crypto_bigint::{Random as _, U256};
use ff::Field;
use super::*;
use crate::{
algebra::{
elliptic_curve::{Curve25519Ristretto, ScalarField},
BoxedUint,
},
random::RandomWith,
sharing::{GlobalFieldKey, Reconstructible},
};
pub type Fq = ScalarField<Curve25519Ristretto>;
pub type BatchSize = typenum::U8;
#[test]
fn test_random_with_boxed_uint_generates_valid_pow_pairs() {
let mut rng = crate::random::test_rng();
let n_parties = 3;
let exp = BoxedUint::from(U256::random(&mut rng));
for _ in 0..10 {
let pow_pairs: Vec<PowPair<Fq>> =
PowPair::random_n_with(&mut rng, n_parties, exp.clone());
assert_eq!(pow_pairs.len(), n_parties);
let (lambda, lambda_pow_neg_exp) = PowPair::<Fq>::reconstruct_all(pow_pairs).unwrap();
let expected_lambda_pow_neg_exp = lambda.pow(exp.clone()).invert().unwrap();
assert_eq!(lambda_pow_neg_exp, expected_lambda_pow_neg_exp);
}
}
#[test]
fn test_random_with_alphas_generates_valid_pow_pairs() {
let mut rng = crate::random::test_rng();
let n_parties = 4;
let exp = BoxedUint::from(U256::random(&mut rng));
let all_alphas: Vec<Vec<GlobalFieldKey<Fq>>> =
Vec::random_n_with(&mut rng, n_parties, n_parties - 1);
for _ in 0..10 {
let pow_pairs: Vec<PowPair<Fq>> =
PowPair::random_n_with(&mut rng, n_parties, (exp.clone(), all_alphas.clone()));
assert_eq!(pow_pairs.len(), n_parties);
let (lambda, lambda_pow_neg_exp) = PowPair::<Fq>::reconstruct_all(pow_pairs).unwrap();
let expected_lambda_pow_neg_exp = lambda.pow(exp.clone()).invert().unwrap();
assert_eq!(lambda_pow_neg_exp, expected_lambda_pow_neg_exp);
}
}
#[test]
fn test_pow_pairs_random_with_boxed_uint() {
let mut rng = crate::random::test_rng();
let n_parties = 3;
let exp = BoxedUint::from(U256::random(&mut rng));
let pow_pairs_batch: Vec<PowPairs<Fq, BatchSize>> =
PowPairs::random_n_with(&mut rng, n_parties, exp.clone());
assert_eq!(pow_pairs_batch.len(), n_parties);
for pow_pairs in &pow_pairs_batch {
assert_eq!(pow_pairs.lambdas.n_parties(), n_parties);
assert_eq!(pow_pairs.lambdas_pow_neg_exp.n_parties(), n_parties);
}
let mut pow_pairs_iters: Vec<_> = pow_pairs_batch
.into_iter()
.map(|pow_pairs| pow_pairs.into_iter())
.collect();
for i in 0..8 {
let pow_pair: Vec<PowPair<Fq>> = pow_pairs_iters
.iter_mut()
.map(|batch| batch.next().unwrap())
.collect();
let (lambda, lambda_pow_neg_exp) = PowPair::<Fq>::reconstruct_all(pow_pair).unwrap();
let expected_lambda_pow_neg_exp = lambda.pow(exp.clone()).invert().unwrap();
assert_eq!(
lambda_pow_neg_exp, expected_lambda_pow_neg_exp,
"PowPair {i} in batch does not satisfy λ^(-exp) relationship"
);
}
}
#[test]
fn test_pow_pairs_random_with_alphas() {
let mut rng = crate::random::test_rng();
let n_parties = 4;
let exp = BoxedUint::from(U256::random(&mut rng));
let all_alphas: Vec<Vec<GlobalFieldKey<Fq>>> =
Vec::random_n_with(&mut rng, n_parties, n_parties - 1);
let pow_pairs_batch: Vec<PowPairs<Fq, BatchSize>> =
PowPairs::random_n_with(&mut rng, n_parties, (exp.clone(), all_alphas));
assert_eq!(pow_pairs_batch.len(), n_parties);
for pow_pairs in &pow_pairs_batch {
assert_eq!(pow_pairs.lambdas.n_parties(), n_parties);
assert_eq!(pow_pairs.lambdas_pow_neg_exp.n_parties(), n_parties);
}
let mut pow_pairs_iters: Vec<_> = pow_pairs_batch
.into_iter()
.map(|pow_pairs| pow_pairs.into_iter())
.collect();
for i in 0..5 {
let individual_pow_pairs: Vec<PowPair<Fq>> = pow_pairs_iters
.iter_mut()
.map(|batch| batch.next().unwrap())
.collect();
let (lambda, lambda_pow_neg_exp) =
PowPair::<Fq>::reconstruct_all(individual_pow_pairs).unwrap();
let expected_lambda_pow_neg_exp = lambda.pow(exp.clone()).invert().unwrap();
assert_eq!(
lambda_pow_neg_exp, expected_lambda_pow_neg_exp,
"Authenticated PowPair {i} in batch does not satisfy λ^(-exp) relationship"
);
}
}
}