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}
 84
 85impl Commitments for Vec<bool> {
 86  fn commit(&self, blind: &Scalar, gens_n: &MultiCommitGens) -> GroupElement {
 87    assert!(gens_n.n == self.len());
 88    let mut comm = blind * &gens_n.h;
 89    for i in 0..self.len() {
 90      if self[i] {
 91        comm = comm + gens_n.G[i];
 92      }
 93    }
 94    comm
 95  }
 96}
 97
 98impl Commitments for [bool] {
 99  fn commit(&self, blind: &Scalar, gens_n: &MultiCommitGens) -> GroupElement {
100    assert!(gens_n.n == self.len());
101    let mut comm = blind * &gens_n.h;
102    for i in 0..self.len() {
103      if self[i] {
104        comm = comm + gens_n.G[i];
105      }
106    }
107    comm
108  }
109}