Skip to content

Commit 3a03536

Browse files
zhdllwycarmfazh
zhdllwyc
authored andcommitted
zk dl
1 parent 6580354 commit 3a03536

File tree

2 files changed

+145
-0
lines changed

2 files changed

+145
-0
lines changed

zk/dl/dl.go

+86
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
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 dl
4+
5+
import (
6+
"io"
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, dst []byte, rnd io.Reader) (group.Element, group.Scalar) {
16+
v := myGroup.RandomNonZeroScalar(rnd)
17+
V := myGroup.NewElement()
18+
V.Mul(DB, v)
19+
20+
// Hash transcript (D_B | V | R | proverLabel | verifierLabel) to get the random coin
21+
DBByte, errByte := DB.MarshalBinary()
22+
if errByte != nil {
23+
panic(errByte)
24+
}
25+
VByte, errByte := V.MarshalBinary()
26+
if errByte != nil {
27+
panic(errByte)
28+
}
29+
30+
RByte, errByte := R.MarshalBinary()
31+
if errByte != nil {
32+
panic(errByte)
33+
}
34+
35+
hashByte := append(DBByte, VByte...)
36+
hashByte = append(hashByte, RByte...)
37+
hashByte = append(hashByte, proverLabel...)
38+
hashByte = append(hashByte, verifierLabel...)
39+
40+
c := myGroup.HashToScalar(hashByte, dst)
41+
42+
kAc := myGroup.NewScalar()
43+
kAc.Mul(c, kA)
44+
r := v.Copy()
45+
r.Sub(r, kAc)
46+
47+
return V, r
48+
}
49+
50+
// Input: myGroup, the group we operate in
51+
// Input: R = [kA]DB
52+
// Input: (V,r), the prove such that the prover knows kA
53+
// Input: proverLabel, verifierLabel labels of prover and verifier
54+
// Output: V ?= [r]D_B +[c]R
55+
func Verify(myGroup group.Group, DB, R group.Element, V group.Element, r group.Scalar, proverLabel, verifierLabel, dst []byte) bool {
56+
// Hash the transcript (D_B | V | R | proverLabel | verifierLabel) to get the random coin
57+
DBByte, errByte := DB.MarshalBinary()
58+
if errByte != nil {
59+
panic(errByte)
60+
}
61+
VByte, errByte := V.MarshalBinary()
62+
if errByte != nil {
63+
panic(errByte)
64+
}
65+
66+
RByte, errByte := R.MarshalBinary()
67+
if errByte != nil {
68+
panic(errByte)
69+
}
70+
hashByte := append(DBByte, VByte...)
71+
hashByte = append(hashByte, RByte...)
72+
hashByte = append(hashByte, proverLabel...)
73+
hashByte = append(hashByte, verifierLabel...)
74+
75+
c := myGroup.HashToScalar(hashByte, dst)
76+
77+
rDB := myGroup.NewElement()
78+
rDB.Mul(DB, r)
79+
80+
cR := myGroup.NewElement()
81+
cR.Mul(R, c)
82+
83+
rDB.Add(rDB, cR)
84+
85+
return V.IsEqual(rDB)
86+
}

zk/dl/dl_test.go

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

0 commit comments

Comments
 (0)