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