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}