arnaucube
arnaucube/testudoPublic Self-hosted repository
testudo/src/commitments.rs
src/commitments.rsRaw
 1use super::group::{GroupElement, GroupElementAffine, VartimeMultiscalarMul, GROUP_BASEPOINT};
 2use super::scalar::Scalar;
 3use crate::group::CompressGroupElement;
 4use crate::parameters::*;
 5use ark_ec::{AffineCurve, ProjectiveCurve};
 6use ark_ff::PrimeField;
 7
 8use ark_sponge::poseidon::PoseidonSponge;
 9use ark_sponge::CryptographicSponge;
10
11#[derive(Debug, Clone)]
12pub struct MultiCommitGens {
13  pub n: usize,
14  pub G: Vec<GroupElement>,
15  pub h: GroupElement,
16}
17
18impl MultiCommitGens {
19  pub fn new(n: usize, label: &[u8]) -> Self {
20    let params = poseidon_params();
21    let mut sponge = PoseidonSponge::new(&params);
22    sponge.absorb(&label);
23    sponge.absorb(&GROUP_BASEPOINT.compress().0);
24
25    let mut gens: Vec<GroupElement> = Vec::new();
26    for _ in 0..n + 1 {
27      let mut el_aff: Option<GroupElementAffine> = None;
28      while el_aff.is_some() != true {
29        let uniform_bytes = sponge.squeeze_bytes(64);
30        el_aff = GroupElementAffine::from_random_bytes(&uniform_bytes);
31      }
32      let el = el_aff.unwrap().mul_by_cofactor_to_projective();
33      gens.push(el);
34    }
35
36    MultiCommitGens {
37      n,
38      G: gens[..n].to_vec(),
39      h: gens[n],
40    }
41  }
42
43  pub fn clone(&self) -> MultiCommitGens {
44    MultiCommitGens {
45      n: self.n,
46      h: self.h,
47      G: self.G.clone(),
48    }
49  }
50
51  pub fn split_at(&self, mid: usize) -> (MultiCommitGens, MultiCommitGens) {
52    let (G1, G2) = self.G.split_at(mid);
53
54    (
55      MultiCommitGens {
56        n: G1.len(),
57        G: G1.to_vec(),
58        h: self.h,
59      },
60      MultiCommitGens {
61        n: G2.len(),
62        G: G2.to_vec(),
63        h: self.h,
64      },
65    )
66  }
67}
68
69pub trait Commitments {
70  fn commit(&self, blind: &Scalar, gens_n: &MultiCommitGens) -> GroupElement;
71}
72
73impl Commitments for Scalar {
74  fn commit(&self, blind: &Scalar, gens_n: &MultiCommitGens) -> GroupElement {
75    assert_eq!(gens_n.n, 1);
76    GroupElement::vartime_multiscalar_mul(&[*self, *blind], &[gens_n.G[0], gens_n.h])
77  }
78}
79
80impl Commitments for Vec<Scalar> {
81  fn commit(&self, blind: &Scalar, gens_n: &MultiCommitGens) -> GroupElement {
82    assert_eq!(gens_n.n, self.len());
83    GroupElement::vartime_multiscalar_mul(self, &gens_n.G) + gens_n.h.mul(blind.into_repr())
84  }
85}
86
87impl Commitments for [Scalar] {
88  fn commit(&self, blind: &Scalar, gens_n: &MultiCommitGens) -> GroupElement {
89    assert_eq!(gens_n.n, self.len());
90    GroupElement::vartime_multiscalar_mul(self, &gens_n.G) + gens_n.h.mul(blind.into_repr())
91  }
92}