Skip to content

Commit 2481411

Browse files
committed
Adds prefixed labels and updates nomenclature.
1 parent 7a181da commit 2481411

File tree

2 files changed

+64
-63
lines changed

2 files changed

+64
-63
lines changed

zk/dl/dl.go

Lines changed: 55 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -1,86 +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
1+
// Package dl provides a Schnorr NIZK discrete-log proof.
2+
//
3+
// This package implements a Schnorr NIZK discrete-log proof obtained from the
4+
// interactive Schnorr identification scheme through a Fiat-Shamir transformation.
5+
//
6+
// Given (k,G,kG) the Prove function returns a Proof struct attesting that
7+
// kG = [k]G, which can be validated using the Verify function.
8+
//
9+
// The userID label is a unique identifier for the prover.
10+
//
11+
// The otherInfo label is defined to allow flexible inclusion of contextual
12+
// information in the Schnorr NIZK proof.
13+
// The otherInfo is also used as a domain separation tag (dst) for the hash
14+
// to scalar function.
15+
//
16+
// Reference: https://datatracker.ietf.org/doc/html/rfc8235
317
package dl
418

519
import (
20+
"encoding/binary"
621
"io"
722

823
"github.com/cloudflare/circl/group"
924
)
1025

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)
26+
type Proof struct {
27+
V group.Element
28+
R group.Scalar
29+
}
1930

20-
// Hash transcript (D_B | V | R | proverLabel | verifierLabel) to get the random coin
21-
DBByte, errByte := DB.MarshalBinary()
31+
func calcChallenge(myGroup group.Group, G, V, A group.Element, userID, otherInfo []byte) group.Scalar {
32+
// Hash transcript (G | V | A | UserID | OtherInfo) to get the random coin.
33+
GByte, errByte := G.MarshalBinary()
2234
if errByte != nil {
2335
panic(errByte)
2436
}
2537
VByte, errByte := V.MarshalBinary()
2638
if errByte != nil {
2739
panic(errByte)
2840
}
29-
30-
RByte, errByte := R.MarshalBinary()
41+
AByte, errByte := A.MarshalBinary()
3142
if errByte != nil {
3243
panic(errByte)
3344
}
3445

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)
46+
uPrefix := [4]byte{}
47+
binary.BigEndian.PutUint32(uPrefix[:], uint32(len(userID)))
48+
oPrefix := [4]byte{}
49+
binary.BigEndian.PutUint32(oPrefix[:], uint32(len(otherInfo)))
4150

42-
kAc := myGroup.NewScalar()
43-
kAc.Mul(c, kA)
44-
r := v.Copy()
45-
r.Sub(r, kAc)
51+
hashByte := append(append(append(append(append(append(
52+
GByte, VByte...), AByte...),
53+
uPrefix[:]...), userID...),
54+
oPrefix[:]...), otherInfo...)
4655

47-
return V, r
56+
return myGroup.HashToScalar(hashByte, otherInfo)
4857
}
4958

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-
}
59+
// Prove returns a proof attesting that kG = [k]G.
60+
func Prove(myGroup group.Group, G, kG group.Element, k group.Scalar, userID, otherInfo []byte, rnd io.Reader) Proof {
61+
v := myGroup.RandomNonZeroScalar(rnd)
62+
V := myGroup.NewElement()
63+
V.Mul(G, v)
6564

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...)
65+
c := calcChallenge(myGroup, G, V, kG, userID, otherInfo)
66+
67+
r := myGroup.NewScalar()
68+
r.Sub(v, myGroup.NewScalar().Mul(k, c))
69+
70+
return Proof{V, r}
71+
}
7472

75-
c := myGroup.HashToScalar(hashByte, dst)
73+
// Verify checks whether the proof attests that kG = [k]G.
74+
func Verify(myGroup group.Group, G, kG group.Element, p Proof, userID, otherInfo []byte) bool {
75+
c := calcChallenge(myGroup, G, p.V, kG, userID, otherInfo)
7676

77-
rDB := myGroup.NewElement()
78-
rDB.Mul(DB, r)
77+
rG := myGroup.NewElement()
78+
rG.Mul(G, p.R)
7979

80-
cR := myGroup.NewElement()
81-
cR.Mul(R, c)
80+
ckG := myGroup.NewElement()
81+
ckG.Mul(kG, c)
8282

83-
rDB.Add(rDB, cR)
83+
rG.Add(rG, ckG)
8484

85-
return V.IsEqual(rDB)
85+
return p.V.IsEqual(rG)
8686
}

zk/dl/dl_test.go

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,14 @@
1-
package dl
1+
package dl_test
22

33
import (
44
"crypto/rand"
55
"testing"
66

77
"github.com/cloudflare/circl/group"
8+
"github.com/cloudflare/circl/zk/dl"
89
)
910

10-
const testzkDLCount = 10
11+
const testzkDLCount = 1 << 8
1112

1213
func testzkDL(t *testing.T, myGroup group.Group) {
1314
kA := myGroup.RandomNonZeroScalar(rand.Reader)
@@ -18,11 +19,11 @@ func testzkDL(t *testing.T, myGroup group.Group) {
1819

1920
dst := "zeroknowledge"
2021
rnd := rand.Reader
21-
V, r := ProveGen(myGroup, DB, R, kA, []byte("Prover"), []byte("Verifier"), []byte(dst), rnd)
22+
proof := dl.Prove(myGroup, DB, R, kA, []byte("Prover"), []byte(dst), rnd)
2223

23-
verify := Verify(myGroup, DB, R, V, r, []byte("Prover"), []byte("Verifier"), []byte(dst))
24+
verify := dl.Verify(myGroup, DB, R, proof, []byte("Prover"), []byte(dst))
2425
if verify == false {
25-
t.Error("zkRDL verification failed")
26+
t.Error("zk/dl verification failed")
2627
}
2728
}
2829

@@ -34,11 +35,11 @@ func testzkDLNegative(t *testing.T, myGroup group.Group) {
3435

3536
dst := "zeroknowledge"
3637
rnd := rand.Reader
37-
V, r := ProveGen(myGroup, DB, R, kA, []byte("Prover"), []byte("Verifier"), []byte(dst), rnd)
38+
proof := dl.Prove(myGroup, DB, R, kA, []byte("Prover"), []byte(dst), rnd)
3839

39-
verify := Verify(myGroup, DB, R, V, r, []byte("Prover"), []byte("Verifier"), []byte(dst))
40+
verify := dl.Verify(myGroup, DB, R, proof, []byte("Prover"), []byte(dst))
4041
if verify == true {
41-
t.Error("zkRDL verification should fail")
42+
t.Error("zk/dl verification should fail")
4243
}
4344
}
4445

0 commit comments

Comments
 (0)