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