arnaucube
arnaucube/testudoPublic Self-hosted repository
testudo/src/commitments.rs
src/commitments.rsRaw
 1use super::group::{GroupElement, VartimeMultiscalarMul, GROUP_BASEPOINT};
 2use super::scalar::Scalar;
 3use digest::{ExtendableOutput, Input};
 4use sha3::Shake256;
 5use std::io::Read;
 6use ark_ff::fields::{Field};
 7use ark_ec::{ProjectiveCurve};
 8
 9#[derive(Debug)]
10pub struct MultiCommitGens {
11  pub n: usize,
12  pub G: Vec<GroupElement>,
13  pub h: GroupElement,
14}
15
16impl MultiCommitGens {
17  pub fn new(n: usize, label: &[u8]) -> Self {
18    let mut shake = Shake256::default();
19    shake.input(label);
20    shake.input(GROUP_BASEPOINT.as_bytes());
21
22    let mut reader = shake.xof_result();
23    let mut gens: Vec<GroupElement> = Vec::new();
24    let mut uniform_bytes = [0u8; 64];
25    for _ in 0..n + 1 {
26      reader.read_exact(&mut uniform_bytes).unwrap();
27      gens.push(GroupElement::from_random_bytes(&uniform_bytes));
28    }
29
30    MultiCommitGens {
31      n,
32      G: gens[..n].to_vec(),
33      h: gens[n],
34    }
35  }
36
37  pub fn clone(&self) -> MultiCommitGens {
38    MultiCommitGens {
39      n: self.n,
40      h: self.h,
41      G: self.G.clone(),
42    }
43  }
44
45  pub fn split_at(&self, mid: usize) -> (MultiCommitGens, MultiCommitGens) {
46    let (G1, G2) = self.G.split_at(mid);
47
48    (
49      MultiCommitGens {
50        n: G1.len(),
51        G: G1.to_vec(),
52        h: self.h,
53      },
54      MultiCommitGens {
55        n: G2.len(),
56        G: G2.to_vec(),
57        h: self.h,
58      },
59    )
60  }
61}
62
63pub trait Commitments {
64  fn commit(&self, blind: &Scalar, gens_n: &MultiCommitGens) -> GroupElement;
65}
66
67impl Commitments for Scalar {
68  fn commit(&self, blind: &Scalar, gens_n: &MultiCommitGens) -> GroupElement {
69    assert_eq!(gens_n.n, 1);
70    GroupElement::vartime_multiscalar_mul(&[*self, *blind], &[gens_n.G[0], gens_n.h])
71  }
72}
73
74impl Commitments for Vec<Scalar> {
75  fn commit(&self, blind: &Scalar, gens_n: &MultiCommitGens) -> GroupElement {
76    assert_eq!(gens_n.n, self.len());
77    GroupElement::vartime_multiscalar_mul(self, &gens_n.G) + blind * gens_n.h
78  }
79}
80
81impl Commitments for [Scalar] {
82  fn commit(&self, blind: &Scalar, gens_n: &MultiCommitGens) -> GroupElement {
83    assert_eq!(gens_n.n, self.len());
84    GroupElement::vartime_multiscalar_mul(self, &gens_n.G) + blind * gens_n.h
85  }
86}