Skip to main content

primitives/correlated_randomness/pow/
sharing.rs

1use ff::Field;
2
3use crate::{
4    algebra::{
5        field::{FieldExtension, SubfieldElement},
6        BoxedUint,
7    },
8    correlated_randomness::pow::types::{OpenPowPair, PowPair},
9    errors::PrimitiveError,
10    izip_eq,
11    sharing::{Reconstructible, VerifiableWith},
12    types::PeerIndex,
13};
14// ---------------
15// |   Opening   |
16// ---------------
17
18impl<F: FieldExtension> Reconstructible for PowPair<F> {
19    type Opening = OpenPowPair<F>;
20    type Value = (SubfieldElement<F>, SubfieldElement<F>);
21
22    fn open_to(&self, peer_index: PeerIndex) -> Result<OpenPowPair<F>, PrimitiveError> {
23        Ok(OpenPowPair {
24            lambda: self.lambda.open_to(peer_index)?,
25            lambda_pow_neg_exp: self.lambda_pow_neg_exp.open_to(peer_index)?,
26        })
27    }
28
29    fn open_to_all_others(&self) -> impl ExactSizeIterator<Item = OpenPowPair<F>> {
30        let lambda = self.lambda.open_to_all_others();
31        let lambda_pow_neg_exp = self.lambda_pow_neg_exp.open_to_all_others();
32        izip_eq!(lambda, lambda_pow_neg_exp).map(|(lambda, lambda_pow_neg_exp)| OpenPowPair {
33            lambda,
34            lambda_pow_neg_exp,
35        })
36    }
37
38    fn reconstruct(&self, openings: Vec<OpenPowPair<F>>) -> Result<Self::Value, PrimitiveError> {
39        let (lambda_openings, lambda_pow_neg_exp_openings): (Vec<_>, Vec<_>) = openings
40            .into_iter()
41            .map(|o| (o.lambda, o.lambda_pow_neg_exp))
42            .unzip();
43        let lambda = self.lambda.reconstruct(lambda_openings)?;
44        let lambda_pow_neg_exp = self
45            .lambda_pow_neg_exp
46            .reconstruct(lambda_pow_neg_exp_openings)?;
47        Ok((lambda, lambda_pow_neg_exp))
48    }
49}
50
51impl<F: FieldExtension> VerifiableWith for PowPair<F> {
52    type VerificationData = BoxedUint;
53    fn verify_with(
54        &self,
55        openings: Vec<OpenPowPair<F>>,
56        exponent: BoxedUint,
57    ) -> Result<(), PrimitiveError> {
58        let (lambda, lambda_pow_neg_exp) = self.reconstruct(openings)?;
59        let expected_lambda_pow_neg_exp = lambda.pow::<BoxedUint>(exponent).invert();
60        if expected_lambda_pow_neg_exp.is_none().into() {
61            return Err(PrimitiveError::WrongCorrelation(
62                "λ^(-exp) is not invertible".to_string(),
63            ));
64        }
65        let expected_lambda_pow_neg_exp = expected_lambda_pow_neg_exp.unwrap();
66        if lambda_pow_neg_exp != expected_lambda_pow_neg_exp {
67            return Err(PrimitiveError::WrongCorrelation(
68                "Stored (λ^(-exp)) does not match reconstructed λ^(-exp)".to_string(),
69            ));
70        }
71        Ok(())
72    }
73}