Skip to content

Commit 3af71e2

Browse files
author
zhdllwyc
committed
zero knowledge for discrete log
1 parent 10a0004 commit 3af71e2

File tree

2 files changed

+148
-0
lines changed

2 files changed

+148
-0
lines changed

zk/dl/zkRDL.go

+89
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
// Reference: https://datatracker.ietf.org/doc/html/rfc8235#page-6
2+
// Prove the knowledge of [k] given [k]G, G and the curve where the points reside
3+
package zkRDL
4+
5+
import (
6+
"crypto/rand"
7+
8+
"github.com/cloudflare/circl/group"
9+
)
10+
11+
// Input: myGroup, the group we operate in
12+
// Input: R = [kA]DB
13+
// Input: proverLabel, verifierLabel labels of prover and verifier
14+
// Ouptput: (V,r), the prove such that we know kA without revealing kA
15+
func ProveGen(myGroup group.Group, DB, R group.Element, kA group.Scalar, proverLabel, verifierLabel []byte) (group.Element, group.Scalar) {
16+
17+
v := myGroup.RandomNonZeroScalar(rand.Reader)
18+
V := myGroup.NewElement()
19+
V.Mul(DB, v)
20+
21+
// Hash transcript (D_B | V | R | proverLabel | verifierLabel) to get the random coin
22+
DBByte, errByte := DB.MarshalBinary()
23+
if errByte != nil {
24+
panic(errByte)
25+
}
26+
VByte, errByte := V.MarshalBinary()
27+
if errByte != nil {
28+
panic(errByte)
29+
}
30+
31+
RByte, errByte := R.MarshalBinary()
32+
if errByte != nil {
33+
panic(errByte)
34+
}
35+
36+
hashByte := append(DBByte, VByte...)
37+
hashByte = append(hashByte, RByte...)
38+
hashByte = append(hashByte, proverLabel...)
39+
hashByte = append(hashByte, verifierLabel...)
40+
41+
dst := "zeroknowledge"
42+
c := myGroup.HashToScalar(hashByte, []byte(dst))
43+
44+
kAc := myGroup.NewScalar()
45+
kAc.Mul(c, kA)
46+
r := v.Copy()
47+
r.Sub(r, kAc)
48+
49+
return V, r
50+
}
51+
52+
// Input: myGroup, the group we operate in
53+
// Input: R = [kA]DB
54+
// Input: (V,r), the prove such that the prover knows kA
55+
// Input: proverLabel, verifierLabel labels of prover and verifier
56+
// Output: V ?= [r]D_B +[c]R
57+
func Verify(myGroup group.Group, DB, R group.Element, V group.Element, r group.Scalar, proverLabel, verifierLabel []byte) bool {
58+
// Hash the transcript (D_B | V | R | proverLabel | verifierLabel) to get the random coin
59+
DBByte, errByte := DB.MarshalBinary()
60+
if errByte != nil {
61+
panic(errByte)
62+
}
63+
VByte, errByte := V.MarshalBinary()
64+
if errByte != nil {
65+
panic(errByte)
66+
}
67+
68+
RByte, errByte := R.MarshalBinary()
69+
if errByte != nil {
70+
panic(errByte)
71+
}
72+
hashByte := append(DBByte, VByte...)
73+
hashByte = append(hashByte, RByte...)
74+
hashByte = append(hashByte, proverLabel...)
75+
hashByte = append(hashByte, verifierLabel...)
76+
77+
dst := "zeroknowledge"
78+
c := myGroup.HashToScalar(hashByte, []byte(dst))
79+
80+
rDB := myGroup.NewElement()
81+
rDB.Mul(DB, r)
82+
83+
cR := myGroup.NewElement()
84+
cR.Mul(R, c)
85+
86+
rDB.Add(rDB, cR)
87+
88+
return V.IsEqual(rDB)
89+
}

zk/dl/zkRDL_test.go

+59
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
package zkRDL
2+
3+
import (
4+
"crypto/rand"
5+
"testing"
6+
7+
"github.com/cloudflare/circl/group"
8+
)
9+
10+
const TestzkRDLCount = 10
11+
12+
func testzkRDL(t *testing.T, myGroup group.Group) {
13+
kA := myGroup.RandomNonZeroScalar(rand.Reader)
14+
DB := myGroup.RandomElement(rand.Reader)
15+
16+
R := myGroup.NewElement()
17+
R.Mul(DB, kA)
18+
19+
V, r := ProveGen(myGroup, DB, R, kA, []byte("Prover"), []byte("Verifier"))
20+
21+
verify := Verify(myGroup, DB, R, V, r, []byte("Prover"), []byte("Verifier"))
22+
if verify == false {
23+
t.Error("zkRDL verification failed")
24+
}
25+
26+
}
27+
28+
func testzkRDLNegative(t *testing.T, myGroup group.Group) {
29+
kA := myGroup.RandomNonZeroScalar(rand.Reader)
30+
DB := myGroup.RandomElement(rand.Reader)
31+
32+
R := myGroup.RandomElement(rand.Reader)
33+
34+
V, r := ProveGen(myGroup, DB, R, kA, []byte("Prover"), []byte("Verifier"))
35+
36+
verify := Verify(myGroup, DB, R, V, r, []byte("Prover"), []byte("Verifier"))
37+
if verify == true {
38+
t.Error("zkRDL verification should fail")
39+
}
40+
41+
}
42+
43+
func TestZKRDL(t *testing.T) {
44+
45+
t.Run("zkRDL", func(t *testing.T) {
46+
for i := 0; i < TestzkRDLCount; i++ {
47+
currGroup := group.P256
48+
testzkRDL(t, currGroup)
49+
}
50+
})
51+
52+
t.Run("zkRDLNegative", func(t *testing.T) {
53+
for i := 0; i < TestzkRDLCount; i++ {
54+
currGroup := group.P256
55+
testzkRDLNegative(t, currGroup)
56+
}
57+
})
58+
59+
}

0 commit comments

Comments
 (0)