|
|
@@ -0,0 +1,71 @@
|
|
|
+# What is defined as DLEQ(g,x,h,y) for proving knowledge of some α
|
|
|
+# in zero-knowledge is what follows:
|
|
|
+# We want to prove knowledge of a value α ∈ Fq, such that x=g*α and y=h*a,
|
|
|
+# given g,x,h,y.
|
|
|
+
|
|
|
+# ================
|
|
|
+# Parameters setup
|
|
|
+# ================
|
|
|
+# Pallas curve
|
|
|
+p = 0x40000000000000000000000000000000224698fc094cf91b992d30ed00000001
|
|
|
+q = 0x40000000000000000000000000000000224698fc0994a8dd8c46eb2100000001
|
|
|
+Fp = GF(p)
|
|
|
+Fq = GF(q)
|
|
|
+Ep = EllipticCurve(Fp, (0, 5))
|
|
|
+Ep.set_order(q)
|
|
|
+
|
|
|
+g = Ep.random_point()
|
|
|
+h = Ep.random_point()
|
|
|
+
|
|
|
+# Value alpha
|
|
|
+α = Fq.random_element()
|
|
|
+
|
|
|
+# =================
|
|
|
+# Interactive proof
|
|
|
+# =================
|
|
|
+# The public data is
|
|
|
+x = g*α
|
|
|
+y = h*α
|
|
|
+
|
|
|
+# 1. The prover computes a_1 = g*w and a_2 = h*w, where w is a random element
|
|
|
+# of Fq, and sends a_1 and a_2 to the verifier.
|
|
|
+w = Fq.random_element()
|
|
|
+a_1 = g * w
|
|
|
+a_2 = h * w
|
|
|
+
|
|
|
+# 2. The verifier sends a challenge e from Fq to the prover
|
|
|
+e = Fq.random_element()
|
|
|
+
|
|
|
+# 3. The prover sends a response z = w - αe to the verifier.
|
|
|
+z = w - α * e
|
|
|
+
|
|
|
+# 4. The verifier checks the following and accepts the proof if it holds:
|
|
|
+assert a_1 == g*z + x*e
|
|
|
+assert a_2 == h*z + y*e
|
|
|
+
|
|
|
+# =====================
|
|
|
+# Non-interactive proof
|
|
|
+# =====================
|
|
|
+# This sigma proof can be transformed into a non-interactive ZK proof
|
|
|
+# through the Fiat-Shamir heuristic:
|
|
|
+from hashlib import sha256
|
|
|
+
|
|
|
+# Prover:
|
|
|
+e = sha256()
|
|
|
+e.update(str(x).encode())
|
|
|
+e.update(str(y).encode())
|
|
|
+e.update(str(a_1).encode())
|
|
|
+e.update(str(a_2).encode())
|
|
|
+e_prover = Fq(int(e.hexdigest(), 16))
|
|
|
+z = w - α * e_prover
|
|
|
+
|
|
|
+# Verifier
|
|
|
+e = sha256()
|
|
|
+e.update(str(x).encode())
|
|
|
+e.update(str(y).encode())
|
|
|
+e.update(str(a_1).encode())
|
|
|
+e.update(str(a_2).encode())
|
|
|
+e_verifier = Fq(int(e.hexdigest(), 16))
|
|
|
+assert a_1 == g*z + x*e_verifier
|
|
|
+assert a_2 == h*z + y*e_verifier
|
|
|
+assert e_prover == e_verifier
|