mmr_crypto_primitives/commitment/pedersen/
mod.rs1use 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 input.len() > W::WINDOW_SIZE * W::NUM_WINDOWS {
76 panic!("incorrect input length: {:?}", input.len());
77 }
78 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 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 for (bit, power) in BitIteratorLE::new(randomness.0.into_repr())
100 .into_iter()
101 .zip(¶meters.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}