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