diff --git a/script/research/pvss/README.md b/script/research/pvss/README.md index 7eaacf453..a6b1feaa5 100644 --- a/script/research/pvss/README.md +++ b/script/research/pvss/README.md @@ -1,6 +1,13 @@ Publicly Verifiable Secret Sharing ================================== +## `dleq.sage` + +A quick overview of the DLEQ sigma protocol, both interactive and +non-interactive. + +## `pvss.sage` + This is an implementation of the paper found at . diff --git a/script/research/pvss/dleq.sage b/script/research/pvss/dleq.sage new file mode 100644 index 000000000..75ac3ed17 --- /dev/null +++ b/script/research/pvss/dleq.sage @@ -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