Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Pedersen Commitments


Pedersen commitments [TPP91] let a committer bind to a value while keeping it hidden, and later open it for verification. The scheme has two core properties:

  • Perfect hiding: the commitment leaks no information about the message.
  • Computational binding: after committing, it is infeasible to open to a different message assuming the hardness of discrete logarithm in the chosen group.

Mathematical setting

Let be a cyclic group of prime order with two independent generators in . For binding, no party should know . Messages and randomness are scalars in .

To commit to with randomness , compute

The pair is an opening of . Verification checks

Multi-message variant. For generators and message vector with randomness , define

Correctness is immediate from group laws.

Properties

  • Perfect hiding. For fixed , the distribution of is uniform in (because is uniform and independent of ). Hence reveals nothing about .

  • Computational binding. If an adversary finds two distinct openings for the same commitment: then . If , this reveals , contradicting the assumption that is unknown. If , then follows immediately. Thus binding reduces to the discrete logarithm hardness in together with the unknown-log relationship between and .

  • Additive homomorphism. For commitments and , . The multi-message variant is likewise additively homomorphic.

These algebraic properties make Pedersen commitments ideal for zero-knowledge proofs about sums, equalities, and linear relations among hidden values.

Applications

  • Sealed values: commit now, reveal later (e.g., bids, choices, randomness beacons).
  • Consistency checks: prove equality of hidden values across systems or that sums match.
  • Privacy-preserving protocols: a standard building block for NIZKs, voting, mix-nets, and confidential transactions.

Example


use dlog_sigma_primitives::pedersen::commitment::{ExtendedPedersen, Parameters};
use dlog_sigma_primitives::prelude::*;
use core_rng::OsRng;

fn main() {
let mut rng = OsRng;
// Choose a maximum supported message vector length and derive generators.
let list_len = 50;
let params = Parameters::<Curve>::new(list_len, &mut rng);

// Sample 40 messages (scalars) to commit.
let messages: Vec<<Curve as GroupScalar>::Scalar> =
  (0..40u64).map(|_| Curve::scalar_random(&mut rng)).collect();

// Variable-time, parallelized commitment (use const_commit for constant-time needs).
let (com, r) = ExtendedPedersen::var_commit(&params, &messages, &mut rng).unwrap().open();

// Verify with the provided opening (messages and randomness).
assert!(com
    .verify(&params, &messages, &r)
    .is_ok());
}

Notes:

  • Parameters should be sampled so that the generators have unknown discrete-log relation.
  • ExtendedPedersen retains the randomness r, which is useful when composing zero-knowledge proofs. The bare Pedersen type contains only the commitment element Com.
  • If constant-time behavior is required, prefer constant-time scalar multiplications (const_commit).