vsss_rs_std/verifier/
feldman.rs

1/*
2    Copyright Michael Lodder. All Rights Reserved.
3    SPDX-License-Identifier: Apache-2.0
4*/
5
6use crate::*;
7use core::marker::PhantomData;
8use elliptic_curve::{
9    ff::PrimeField,
10    group::{Group, GroupEncoding, ScalarMul},
11};
12use serde::{Deserialize, Serialize};
13
14/// A Feldman verifier is used to provide integrity checking of shamir shares
15/// `T` commitments are made to be used for verification.
16#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
17pub struct FeldmanVerifier<F: PrimeField, G: Group + GroupEncoding + ScalarMul<F>> {
18    /// The generator for the share polynomial coefficients
19    #[serde(
20        serialize_with = "serialize_group",
21        deserialize_with = "deserialize_group"
22    )]
23    pub generator: G,
24    /// The commitments to the polynomial
25    #[serde(
26        serialize_with = "serialize_group_vec",
27        deserialize_with = "deserialize_group_vec"
28    )]
29    pub commitments: Vec<G>,
30    /// Marker
31    #[serde(skip)]
32    pub marker: PhantomData<F>,
33}
34
35impl<F: PrimeField, G: Group + GroupEncoding + ScalarMul<F>> FeldmanVerifier<F, G> {
36    /// Check whether the share is valid according this verifier set
37    pub fn verify(&self, share: &Share) -> VsssResult<()> {
38        let s = share.as_field_element::<F>()?;
39
40        let x = F::from(share.identifier() as u64);
41        let mut i = F::ONE;
42
43        // FUTURE: execute this sum of products
44        // c_0 * c_1^i * c_2^{i^2} ... c_t^{i^t}
45        // as a constant time operation using <https://cr.yp.to/papers/pippenger.pdf>
46        // or Guide to Elliptic Curve Cryptography book,
47        // "Algorithm 3.48 Simultaneous multiple point multiplication"
48        // without precomputing the addition but still reduces doublings
49
50        // c_0
51        let mut rhs = self.commitments[0];
52        for v in &self.commitments[1..] {
53            i *= x;
54
55            // c_0 * c_1^i * c_2^{i^2} ... c_t^{i^t}
56            rhs += *v * i;
57        }
58
59        let lhs: G = -self.generator * s;
60
61        let res: G = lhs + rhs;
62
63        if res.is_identity().into() {
64            Ok(())
65        } else {
66            Err(Error::InvalidShare)
67        }
68    }
69}