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}