1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package dl
18
19 import (
20 "encoding/binary"
21 "io"
22
23 "github.com/cloudflare/circl/group"
24 )
25
26 type Proof struct {
27 V group.Element
28 R group.Scalar
29 }
30
31 func calcChallenge(myGroup group.Group, G, V, A group.Element, userID, otherInfo []byte) group.Scalar {
32
33 GByte, errByte := G.MarshalBinary()
34 if errByte != nil {
35 panic(errByte)
36 }
37 VByte, errByte := V.MarshalBinary()
38 if errByte != nil {
39 panic(errByte)
40 }
41 AByte, errByte := A.MarshalBinary()
42 if errByte != nil {
43 panic(errByte)
44 }
45
46 uPrefix := [4]byte{}
47 binary.BigEndian.PutUint32(uPrefix[:], uint32(len(userID)))
48 oPrefix := [4]byte{}
49 binary.BigEndian.PutUint32(oPrefix[:], uint32(len(otherInfo)))
50
51 hashByte := append(append(append(append(append(append(
52 GByte, VByte...), AByte...),
53 uPrefix[:]...), userID...),
54 oPrefix[:]...), otherInfo...)
55
56 return myGroup.HashToScalar(hashByte, otherInfo)
57 }
58
59
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)
64
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 }
72
73
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)
76
77 rG := myGroup.NewElement()
78 rG.Mul(G, p.R)
79
80 ckG := myGroup.NewElement()
81 ckG.Mul(kG, c)
82
83 rG.Add(rG, ckG)
84
85 return p.V.IsEqual(rG)
86 }
87
View as plain text