Pick a depth. Each prompt opens in your AI pre-loaded with the lesson. Click a row to preview the prompt.
Pedersen commitments are the foundational algebraic commitment used across ZK: in Bulletproofs, Confidential Transactions, KZG (which is Pedersen-flavoured), and most -protocol-based ZK arguments. The form in a prime-order group is a single group element but achieves perfect hiding (any corresponds to every possible for some ) and computational binding (under DLP). The reason this matters more than the hash version: Pedersen commitments are homomorphic — — which lets you prove sums, ranges, and inner products of committed values without ever opening them. That single property is the engine behind Confidential Transactions and most efficient ZK range proofs. Internalise the construction now; you'll meet it in every protocol that follows.
Let be a cyclic group of prime order with generators such that is unknown to the committer. For , pick and set . Pedersen is hiding (the distribution of over uniform is uniform on , regardless of ) and binding under DLP — finding two openings would yield .
// main.go — run: go run main.go
package main
import (
"fmt"
"math/big"
"math/rand"
)
// Pedersen commitments in a small prime-order subgroup of (Z/p)*.
// For real use, pick a 256-bit safe-prime group or an elliptic curve.
const p = 2027 // prime
const q = 1013 // (p-1)/2, prime; subgroup order
func powmod(base, exp, mod int64) int64 {
return new(big.Int).Exp(big.NewInt(base), big.NewInt(exp), big.NewInt(mod)).Int64()
}
func inSubgroup(x int64) bool { return powmod(x, q, p) == 1 }
func main() {
// Pick generators g, h with unknown discrete log relation.
var g int64 = 2
for !inSubgroup(g) {
g++
}
var h int64 = 5
for !(inSubgroup(h) && h != g) {
h++
}
fmt.Printf("g = %d h = %d subgroup order q = %d\n", g, h, q)
rng := rand.New(rand.NewSource(0))
commit := func(m, r int64) int64 {
return (powmod(g, m, p) * powmod(h, r, p)) % p
}
open := func(c, m, r int64) bool { return commit(m, r) == c }
m := int64(42)
r := rng.Int63n(q)
c := commit(m, r)
fmt.Printf("c = %d open? %v\n", c, open(c, m, r))
// Homomorphism: Commit(m1)*Commit(m2) == Commit(m1+m2)
m1, r1 := int64(7), rng.Int63n(q)
m2, r2 := int64(9), rng.Int63n(q)
lhs := (commit(m1, r1) * commit(m2, r2)) % p
rhs := commit((m1+m2)%q, (r1+r2)%q)
fmt.Printf("homomorphism holds: %v\n", lhs == rhs)
}go run main.go