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