arnaucube
arnaucube/testudoPublic Self-hosted repository
testudo/src/commitments.rs
src/commitments.rsRaw
 1use crate::ark_std::UniformRand;
 2use crate::parameters::*;
 3use ark_crypto_primitives::sponge::poseidon::PoseidonSponge;
 4use ark_crypto_primitives::sponge::CryptographicSponge;
 5use ark_ec::{CurveGroup, VariableBaseMSM};
 6use rand::SeedableRng;
 7use std::ops::Mul;
 8
 9#[derive(Debug, Clone)]
10pub struct MultiCommitGens<G: CurveGroup> {
11  pub n: usize,
12  pub G: Vec<G::Affine>,
13  pub h: G::Affine,
14}
15
16impl<G: CurveGroup> MultiCommitGens<G> {
17  pub fn new(n: usize, label: &[u8]) -> Self {
18    let params = poseidon_params();
19    let mut sponge = PoseidonSponge::new(&params);
20    sponge.absorb(&label);
21    let mut b = Vec::new();
22    G::generator().serialize_compressed(&mut b).unwrap();
23    sponge.absorb(&b);
24
25    let gens = (0..=n)
26      .map(|_| {
27        let mut uniform_bytes = [0u8; 32];
28        uniform_bytes.copy_from_slice(&sponge.squeeze_bytes(32)[..]);
29        let mut prng = rand::rngs::StdRng::from_seed(uniform_bytes);
30        G::Affine::rand(&mut prng)
31      })
32      .collect::<Vec<_>>();
33
34    MultiCommitGens {
35      n,
36      G: gens[..n].to_vec(),
37      h: gens[n],
38    }
39  }
40
41  pub fn clone(&self) -> Self {
42    MultiCommitGens {
43      n: self.n,
44      h: self.h,
45      G: self.G.clone(),
46    }
47  }
48
49  pub fn split_at(&self, mid: usize) -> (Self, Self) {
50    let (G1, G2) = self.G.split_at(mid);
51
52    (
53      MultiCommitGens {
54        n: G1.len(),
55        G: G1.to_vec(),
56        h: self.h,
57      },
58      MultiCommitGens {
59        n: G2.len(),
60        G: G2.to_vec(),
61        h: self.h,
62      },
63    )
64  }
65}
66
67pub struct PedersenCommit;
68
69impl PedersenCommit {
70  pub fn commit_scalar<G: CurveGroup>(
71    scalar: &G::ScalarField,
72    blind: &G::ScalarField,
73    gens_n: &MultiCommitGens<G>,
74  ) -> G {
75    assert_eq!(gens_n.n, 1);
76    <G as VariableBaseMSM>::msm_unchecked(&[gens_n.G[0], gens_n.h], &[*scalar, *blind])
77  }
78
79  pub fn commit_slice<G: CurveGroup>(
80    scalars: &[G::ScalarField],
81    blind: &G::ScalarField,
82    gens_n: &MultiCommitGens<G>,
83  ) -> G {
84    assert_eq!(scalars.len(), gens_n.n);
85    <G as VariableBaseMSM>::msm_unchecked(&gens_n.G, scalars) + gens_n.h.mul(blind)
86  }
87}