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(¶ms);
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}