Pedersen Commitment

Pedersen commitment:

\(Gen(1^\lambda) \rightarrow ck\)

\[\begin{split}g \leftarrow \mathbb{G}\\ h = g^x\\ ck:=(\mathbb{G}, p, g, h)\end{split}\]

\(Com_{ck}(m) \rightarrow c\)

\[c:=(g^r, g^mh^r)\]
[18]:
from klefki.types.algebra.concrete import EllipticCurveGroupSecp256k1 as Curve
from klefki.types.algebra.concrete import FiniteFieldCyclicSecp256k1 as CF
from klefki.types.algebra.concrete import FiniteFieldSecp256k1 as F
from klefki.types.algebra.utils import randfield
from klefki.utils import to_sha256int
import hashlib

G = Curve.G
s = bytes.fromhex("0479be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8")
x = int(hashlib.sha256(s).hexdigest(),16)
H = Curve.lift_x(F(x))

\(\Sigma\)-protocol

Consider a commitment \(A\) opening to m to be part of the statement. The prover computes a random commitment \(B = Com_{ck}(m; s)\) and sends it to the verifier, which answer with a random challenge \(x\). The prover then sends opening information \(z\) to the verifier, which checks the commitment \(A^x B\) opens to m using randomness \(z\).

\(s \leftarrow \mathbb{Z}_p\) \(B=Com_{ck}(m;s)\)

\[P \rightarrow V: B\]
[6]:
m = randfield(CF)
r = randfield(CF)

A = G ** m + H ** r
[7]:
s = randfield(CF)


B = G ** s * H ** r

\(x \leftarrow \mathbb{Z}_p\)

\[P \leftarrow V: x\]
[8]:
e = randfield(CF)

\(z = me + s; x = re + r\)

\[P \rightarrow V: z, x\]
[9]:
z = m*e + s
x = r*e + r

Accept \(\iff\) \(B \in \mathbf{G}, z \in \mathbb{Z}_p\)

\[Com_{ck}(z;x) = A^eB\]
[10]:
G ** z * H ** x == A ** e * B
[10]:
True

Implementation

[19]:
from klefki.zkp.pedersen import PedersonCommitment
[20]:
#priv = randfield(CF)
secret = CF(73570390403507240989674623545632060650466613362119649500108200592951986722161)

r = randfield(CF)
P = PedersonCommitment(G, G@x, secret, r)
[21]:
m = randfield(CF)
s = randfield(CF)


P.commit(m, s)
[21]:
EllipticCurveGroupSecp256k1::(FiniteFieldSecp256k1::76201704871179190780475307638115978518301654908825034157386315651276262400510, FiniteFieldSecp256k1::77268800855390143539124184346541682025370673032906278995802703732885034967010)
[22]:
e = randfield(CF)
P.challenge(e)
[22]:
(FiniteFieldCyclicSecp256k1::89447814369209904756588252129833606768839036881297533466290775855388358949321,
 FiniteFieldCyclicSecp256k1::44683317883183669291202167938139287483071112847656724484292910426096615830465)
[23]:
P.proof()
[23]:
True
[16]:
m1 = randfield(CF)


P.trapdoor(m1, x)
[17]:
P.challenge(e)
P.proof()
[17]:
True

NIZK

[1]:
from klefki.zkp.schnorr import NIZKSchnoor
[2]:
NIZKSchnoor.verify(*NIZKSchnoor.proof(42))
[2]:
True

Ref: