mmr_crypto_primitives/commitment/pedersen/
mod.rs

1use crate::{CRHScheme, Error, Vec};
2use ark_ec::ProjectiveCurve;
3use ark_ff::{bytes::ToBytes, BitIteratorLE, Field, FpParameters, PrimeField, ToConstraintField};
4use ark_std::io::{Result as IoResult, Write};
5use ark_std::marker::PhantomData;
6use ark_std::rand::Rng;
7use ark_std::UniformRand;
8
9use super::CommitmentScheme;
10
11use crate::crh::pedersen;
12pub use crate::crh::pedersen::Window;
13
14#[cfg(feature = "r1cs")]
15pub mod constraints;
16
17#[derive(Clone)]
18pub struct Parameters<C: ProjectiveCurve> {
19    pub randomness_generator: Vec<C>,
20    pub generators: Vec<Vec<C>>,
21}
22
23pub struct Commitment<C: ProjectiveCurve, W: Window> {
24    group: PhantomData<C>,
25    window: PhantomData<W>,
26}
27
28#[derive(Derivative)]
29#[derivative(Clone, PartialEq, Debug, Eq, Default)]
30pub struct Randomness<C: ProjectiveCurve>(pub C::ScalarField);
31
32impl<C: ProjectiveCurve> UniformRand for Randomness<C> {
33    #[inline]
34    fn rand<R: Rng + ?Sized>(rng: &mut R) -> Self {
35        Randomness(UniformRand::rand(rng))
36    }
37}
38
39impl<C: ProjectiveCurve> ToBytes for Randomness<C> {
40    fn write<W: Write>(&self, writer: W) -> IoResult<()> {
41        self.0.write(writer)
42    }
43}
44
45impl<C: ProjectiveCurve, W: Window> CommitmentScheme for Commitment<C, W> {
46    type Parameters = Parameters<C>;
47    type Randomness = Randomness<C>;
48    type Output = C::Affine;
49
50    fn setup<R: Rng>(rng: &mut R) -> Result<Self::Parameters, Error> {
51        let time = start_timer!(|| format!(
52            "PedersenCOMM::Setup: {} {}-bit windows; {{0,1}}^{{{}}} -> C",
53            W::NUM_WINDOWS,
54            W::WINDOW_SIZE,
55            W::NUM_WINDOWS * W::WINDOW_SIZE
56        ));
57        let num_powers = <C::ScalarField as PrimeField>::Params::MODULUS_BITS as usize;
58        let randomness_generator = pedersen::CRH::<C, W>::generator_powers(num_powers, rng);
59        let generators = pedersen::CRH::<C, W>::create_generators(rng);
60        end_timer!(time);
61
62        Ok(Self::Parameters {
63            randomness_generator,
64            generators,
65        })
66    }
67
68    fn commit(
69        parameters: &Self::Parameters,
70        input: &[u8],
71        randomness: &Self::Randomness,
72    ) -> Result<Self::Output, Error> {
73        let commit_time = start_timer!(|| "PedersenCOMM::Commit");
74        // If the input is too long, return an error.
75        if input.len() > W::WINDOW_SIZE * W::NUM_WINDOWS {
76            panic!("incorrect input length: {:?}", input.len());
77        }
78        // Pad the input to the necessary length.
79        let mut padded_input = Vec::with_capacity(input.len());
80        let mut input = input;
81        if (input.len() * 8) < W::WINDOW_SIZE * W::NUM_WINDOWS {
82            padded_input.extend_from_slice(input);
83            let padded_length = (W::WINDOW_SIZE * W::NUM_WINDOWS) / 8;
84            padded_input.resize(padded_length, 0u8);
85            input = padded_input.as_slice();
86        }
87        assert_eq!(parameters.generators.len(), W::NUM_WINDOWS);
88        let input = input.to_vec();
89        // Invoke Pedersen CRH here, to prevent code duplication.
90
91        let crh_parameters = pedersen::Parameters {
92            generators: parameters.generators.clone(),
93        };
94        let mut result: C =
95            pedersen::CRH::<C, W>::evaluate(&crh_parameters, input.as_slice())?.into();
96        let randomize_time = start_timer!(|| "Randomize");
97
98        // Compute h^r.
99        for (bit, power) in BitIteratorLE::new(randomness.0.into_repr())
100            .into_iter()
101            .zip(&parameters.randomness_generator)
102        {
103            if bit {
104                result += power
105            }
106        }
107        end_timer!(randomize_time);
108        end_timer!(commit_time);
109
110        Ok(result.into())
111    }
112}
113
114impl<ConstraintF: Field, C: ProjectiveCurve + ToConstraintField<ConstraintF>>
115    ToConstraintField<ConstraintF> for Parameters<C>
116{
117    #[inline]
118    fn to_field_elements(&self) -> Option<Vec<ConstraintF>> {
119        Some(Vec::new())
120    }
121}