use super::group::{GroupElement, GroupElementAffine, VartimeMultiscalarMul, GROUP_BASEPOINT}; use super::scalar::Scalar; use crate::group::CompressGroupElement; use crate::parameters::*; use ark_ec::{AffineCurve, ProjectiveCurve}; use ark_ff::PrimeField; use ark_sponge::poseidon::PoseidonSponge; use ark_sponge::CryptographicSponge; #[derive(Debug, Clone)] pub struct MultiCommitGens { pub n: usize, pub G: Vec, pub h: GroupElement, } impl MultiCommitGens { pub fn new(n: usize, label: &[u8]) -> Self { let params = poseidon_params(); let mut sponge = PoseidonSponge::new(¶ms); sponge.absorb(&label); sponge.absorb(&GROUP_BASEPOINT.compress().0); let mut gens: Vec = Vec::new(); for _ in 0..n + 1 { let mut el_aff: Option = None; while el_aff.is_none() { let uniform_bytes = sponge.squeeze_bytes(64); el_aff = GroupElementAffine::from_random_bytes(&uniform_bytes); } let el = el_aff.unwrap().mul_by_cofactor_to_projective(); gens.push(el); } MultiCommitGens { n, G: gens[..n].to_vec(), h: gens[n], } } pub fn clone(&self) -> MultiCommitGens { MultiCommitGens { n: self.n, h: self.h, G: self.G.clone(), } } pub fn split_at(&self, mid: usize) -> (MultiCommitGens, MultiCommitGens) { let (G1, G2) = self.G.split_at(mid); ( MultiCommitGens { n: G1.len(), G: G1.to_vec(), h: self.h, }, MultiCommitGens { n: G2.len(), G: G2.to_vec(), h: self.h, }, ) } } pub trait Commitments { fn commit(&self, blind: &Scalar, gens_n: &MultiCommitGens) -> GroupElement; } impl Commitments for Scalar { fn commit(&self, blind: &Scalar, gens_n: &MultiCommitGens) -> GroupElement { assert_eq!(gens_n.n, 1); GroupElement::vartime_multiscalar_mul(&[*self, *blind], &[gens_n.G[0], gens_n.h]) } } impl Commitments for Vec { fn commit(&self, blind: &Scalar, gens_n: &MultiCommitGens) -> GroupElement { assert_eq!(gens_n.n, self.len()); GroupElement::vartime_multiscalar_mul(self, &gens_n.G) + gens_n.h.mul(blind.into_repr()) } } impl Commitments for [Scalar] { fn commit(&self, blind: &Scalar, gens_n: &MultiCommitGens) -> GroupElement { assert_eq!(gens_n.n, self.len()); GroupElement::vartime_multiscalar_mul(self, &gens_n.G) + gens_n.h.mul(blind.into_repr()) } }