testudo/src/commitments.rs
src/commitments.rsRaw
1use crate::group::{CompressGroupElement, DecompressGroupElement};
2
3use super::group::{GroupElement, VartimeMultiscalarMul, GROUP_BASEPOINT, GroupElementAffine};
4use super::scalar::Scalar;
5use ark_ff::PrimeField;
6use digest::{ExtendableOutput, Input};
7use sha3::Shake256;
8use std::io::Read;
9use ark_serialize::{CanonicalDeserialize, CanonicalSerialize};
10use ark_ec::{ProjectiveCurve, AffineCurve};
11
12#[derive(Debug)]
13pub struct MultiCommitGens {
14 pub n: usize,
15 pub G: Vec<GroupElement>,
16 pub h: GroupElement,
17}
18
19impl MultiCommitGens {
20 pub fn new(n: usize, label: &[u8]) -> Self {
21 let mut shake = Shake256::default();
22 shake.input(label);
23 let mut generator_encoded = Vec::new();
24 GROUP_BASEPOINT.serialize(&mut generator_encoded).unwrap();
25 shake.input(generator_encoded);
26
27 let mut reader = shake.xof_result();
28 let mut gens: Vec<GroupElement> = Vec::new();
29 let mut uniform_bytes = [0u8; 64];
30 for _ in 0..n + 1 {
31 let mut el_aff: Option<GroupElementAffine> = None;
32 while el_aff.is_some() != true {
33 reader.read_exact(&mut uniform_bytes).unwrap();
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}
91
92impl Commitments for [Scalar] {
93 fn commit(&self, blind: &Scalar, gens_n: &MultiCommitGens) -> GroupElement {
94 assert_eq!(gens_n.n, self.len());
95 GroupElement::vartime_multiscalar_mul(self, &gens_n.G) + gens_n.h.mul(blind.into_repr())
96
97 }
98}