Skip to main content

zc_rlnc/
commit.rs

1//! This module implements non-hiding Pedersen commitments.
2use blstrs::{G1Projective, Scalar};
3use rayon::iter::{IntoParallelIterator, ParallelIterator};
4
5/// The domain separation tag for the Pedersen commitment scheme.
6const DST: &[u8] = b"RLNC_PEDERSEN_GEN";
7
8/// A committer that uses the non-hiding Pedersen commitment scheme.
9///
10/// # Idea
11/// Pedersen commitments work with a number of generators, which are pre-computed and stored in the
12/// committer. The commitment is computed as the sum of the generators multiplied by the symbols.
13///
14/// Since we don't want to transmit the generators to the verifier, we use deterministic
15/// generators, which can be derived from a seed (like a sender's public key).
16///
17/// # Security
18/// The security of the Pedersen commitment scheme relies on the discrete logarithm assumption.
19/// The generators are chosen such that the discrete logarithm of the commitment to a symbol is
20/// hard to compute.
21#[derive(Debug)]
22pub struct PedersenCommitter {
23    generators: Vec<G1Projective>,
24}
25
26impl PedersenCommitter {
27    /// Creates a new deterministic committer with the given seed and number of generators.
28    pub fn new(seed: [u8; 32], n: usize) -> Self {
29        #[cfg(feature = "parallel")]
30        let generators = (0..n)
31            .into_par_iter()
32            .map(|i| {
33                let mut msg = [0u8; 40];
34                msg[..32].copy_from_slice(&seed);
35                msg[32..].copy_from_slice(&i.to_le_bytes());
36
37                G1Projective::hash_to_curve(&msg, DST, &[])
38            })
39            .collect();
40
41        #[cfg(not(feature = "parallel"))]
42        let generators = (0..n)
43            .map(|i| {
44                let mut msg = [0u8; 40];
45                msg[..32].copy_from_slice(&seed);
46                msg[32..].copy_from_slice(&i.to_le_bytes());
47
48                G1Projective::hash_to_curve(&msg, DST, &[])
49            })
50            .collect();
51
52        Self { generators }
53    }
54
55    /// Commits to the symbols using the committer's generators.
56    pub fn commit(&self, symbols: &[Scalar]) -> G1Projective {
57        assert_eq!(symbols.len(), self.generators.len());
58
59        G1Projective::multi_exp(&self.generators, symbols)
60    }
61}