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