use ff::Field;
use crate::{
algebra::{
field::{FieldExtension, SubfieldElement},
BoxedUint,
},
correlated_randomness::pow::types::{OpenPowPair, PowPair},
errors::PrimitiveError,
izip_eq,
sharing::{Reconstructible, VerifiableWith},
types::PeerIndex,
};
impl<F: FieldExtension> Reconstructible for PowPair<F> {
type Opening = OpenPowPair<F>;
type Value = (SubfieldElement<F>, SubfieldElement<F>);
fn open_to(&self, peer_index: PeerIndex) -> Result<OpenPowPair<F>, PrimitiveError> {
Ok(OpenPowPair {
lambda: self.lambda.open_to(peer_index)?,
lambda_pow_neg_exp: self.lambda_pow_neg_exp.open_to(peer_index)?,
})
}
fn open_to_all_others(&self) -> impl ExactSizeIterator<Item = OpenPowPair<F>> {
let lambda = self.lambda.open_to_all_others();
let lambda_pow_neg_exp = self.lambda_pow_neg_exp.open_to_all_others();
izip_eq!(lambda, lambda_pow_neg_exp).map(|(lambda, lambda_pow_neg_exp)| OpenPowPair {
lambda,
lambda_pow_neg_exp,
})
}
fn reconstruct(&self, openings: Vec<OpenPowPair<F>>) -> Result<Self::Value, PrimitiveError> {
let (lambda_openings, lambda_pow_neg_exp_openings): (Vec<_>, Vec<_>) = openings
.into_iter()
.map(|o| (o.lambda, o.lambda_pow_neg_exp))
.unzip();
let lambda = self.lambda.reconstruct(lambda_openings)?;
let lambda_pow_neg_exp = self
.lambda_pow_neg_exp
.reconstruct(lambda_pow_neg_exp_openings)?;
Ok((lambda, lambda_pow_neg_exp))
}
}
impl<F: FieldExtension> VerifiableWith for PowPair<F> {
type VerificationData = BoxedUint;
fn verify_with(
&self,
openings: Vec<OpenPowPair<F>>,
exponent: BoxedUint,
) -> Result<(), PrimitiveError> {
let (lambda, lambda_pow_neg_exp) = self.reconstruct(openings)?;
let expected_lambda_pow_neg_exp = lambda.pow::<BoxedUint>(exponent).invert();
if expected_lambda_pow_neg_exp.is_none().into() {
return Err(PrimitiveError::WrongCorrelation(
"λ^(-exp) is not invertible".to_string(),
));
}
let expected_lambda_pow_neg_exp = expected_lambda_pow_neg_exp.unwrap();
if lambda_pow_neg_exp != expected_lambda_pow_neg_exp {
return Err(PrimitiveError::WrongCorrelation(
"Stored (λ^(-exp)) does not match reconstructed λ^(-exp)".to_string(),
));
}
Ok(())
}
}