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}