-
Notifications
You must be signed in to change notification settings - Fork 1
/
cpace_example_test.go
194 lines (161 loc) · 5.11 KB
/
cpace_example_test.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
package cpace
import (
"bytes"
"fmt"
"github.com/bytemare/cryptotools/group/ciphersuite"
"github.com/bytemare/cryptotools/hash"
)
var (
testResponder, testInitiator *CPace
testResponderSK []byte
)
func receiveFromResponder(epkc, sid []byte) []byte {
clientID := []byte("client")
serverID := []byte("server")
password := []byte("password")
params := &Parameters{
Group: ciphersuite.Ristretto255Sha512,
Hash: hash.SHA512,
}
testResponder = params.Init(clientID, serverID, nil).Responder()
epks, _, err := testResponder.Start(password, sid)
if err != nil {
panic(err)
}
testResponderSK, err = testResponder.Finish(epkc)
if err != nil {
panic(err)
}
return epks
}
func receiveFromClient() (epku, sid []byte) {
clientID := []byte("client")
serverID := []byte("server")
password := []byte("password")
params := &Parameters{
Group: ciphersuite.Ristretto255Sha512,
Hash: hash.SHA512,
}
testInitiator = params.Init(clientID, serverID, nil).Initiator()
epku, sid, err := testInitiator.Start(password, nil)
if err != nil {
panic(err)
}
return epku, sid
}
func clientSecretKey(epks []byte) []byte {
sk, err := testInitiator.Finish(epks)
if err != nil {
panic(err)
}
return sk
}
func ExampleInitiator() {
clientID := []byte("client")
serverID := []byte("server")
password := []byte("password")
var sid []byte = nil // if nil, sid will be set randomly in Start()
var ad []byte = nil
// Set cryptographic parameters
params := &Parameters{
Group: ciphersuite.Ristretto255Sha512,
Hash: hash.SHA512,
}
// Prepare common communication info, and directly derive the client
client := params.Init(clientID, serverID, ad).Initiator()
// Client starts. If no sid is given for the client, the function returns a new sid.
epku, sid, err := client.Start(password, sid)
if err != nil {
panic(err)
}
// The client receives the server epks, and can derive the session key.
epks := receiveFromResponder(epku, sid)
clientSK, err := client.Finish(epks)
if err != nil {
panic(err)
}
// The client has not access to the server's result, but if everything went fine, the session keys are the same.
if bytes.Equal(clientSK, testResponderSK) {
fmt.Println("Success ! Both parties share the same secret session key !")
} else {
fmt.Println("Failed. Client and server keys are different.")
}
// Output: Success ! Both parties share the same secret session key !
}
func ExampleResponder() {
clientID := []byte("client")
serverID := []byte("server")
password := []byte("password")
var ad []byte = nil
// Set cryptographic parameters
params := &Parameters{
Group: ciphersuite.Ristretto255Sha512,
Hash: hash.SHA512,
}
// Prepare common communication info, and directly derive the responder
responder := params.Init(clientID, serverID, ad).Responder()
// The responder either already knows the sid, or receives it from the initiator, along with epku
epku, sid := receiveFromClient()
// The responder computes its epks given the password and sid, and sends epks to the client
epks, sid, err := responder.Start(password, sid)
if err != nil {
panic(err)
}
// The responder can now derive the session key.
responderSK, err := responder.Finish(epku)
if err != nil {
panic(err)
}
// The responder has not access to the initiator's result, but if everything went fine, the session keys are the same.
if bytes.Equal(responderSK, clientSecretKey(epks)) {
fmt.Println("Success ! Both parties share the same secret session key !")
} else {
fmt.Println("Failed. Client and server keys are different.")
}
// Output: Success ! Both parties share the same secret session key !
}
func ExampleCPace() {
clientID := []byte("client")
serverID := []byte("server")
password := []byte("password")
var ad []byte = nil // this can securely be nil
// Set cryptographic parameters
params := &Parameters{
Group: ciphersuite.Ristretto255Sha512,
Hash: hash.SHA512,
}
// Prepare common communication info
info := params.Init(clientID, serverID, ad)
// Get a client and a server
client := info.Initiator()
server := info.Responder()
// Client starts. If no sid is given for the client, the function returns a new sid.
epku, sid, err := client.Start(password, nil)
if err != nil {
panic(err)
}
// The server receives sends back its own epks.
// The sid should be the same as from the client, and can even be the one the client sent.
epks, _, err := server.Start(password, sid)
if err != nil {
panic(err)
}
// The session key can already be derived by the server using the client's epku.
// If they differ, one of the peers used the wrong password.
serverSK, err := server.Finish(epku)
if err != nil {
panic(err)
}
// The client receives the server epks, and can derive the session key.
clientSK, err := client.Finish(epks)
if err != nil {
panic(err)
}
// The protocol is finished, and both parties now share the same secret session key
if bytes.Equal(serverSK, clientSK) {
fmt.Println("Success ! Both parties share the same secret session key !")
} else {
fmt.Println("Failed. Client and server keys are different.")
}
// Output: Success ! Both parties share the same secret session key !
}