arcium-primitives 0.4.2

Arcium primitives
Documentation
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,
};
// ---------------
// |   Opening   |
// ---------------

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(())
    }
}