Skip to content

Commit c2ce323

Browse files
committed
Allow specifying OPRF client seed
1 parent 8376c3a commit c2ce323

File tree

7 files changed

+118
-67
lines changed

7 files changed

+118
-67
lines changed

examples_test.go

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -108,7 +108,7 @@ func Example_serverSetup() {
108108
log.Fatalln(err)
109109
}
110110

111-
if err := server.SetKeyMaterial(serverID, serverPrivateKey, serverPublicKey, secretOprfSeed); err != nil {
111+
if err := server.SetKeyMaterial(serverID, serverPrivateKey, serverPublicKey, secretOprfSeed, nil); err != nil {
112112
log.Fatalln(err)
113113
}
114114

@@ -234,13 +234,16 @@ func Example_registration() {
234234
// The server creates a database entry for the client and creates a credential identifier that must absolutely
235235
// be unique among all clients.
236236
credID = opaque.RandomBytes(64)
237-
pks, err := server.Deserialize.DecodeAkePublicKey(serverPublicKey)
238-
if err != nil {
237+
238+
if err = server.SetKeyMaterial(serverID, serverPrivateKey, serverPublicKey, secretOprfSeed, nil); err != nil {
239239
log.Fatalln(err)
240240
}
241241

242242
// The server uses its public key and secret OPRF seed created at the setup.
243-
response := server.RegistrationResponse(request, pks, credID, secretOprfSeed)
243+
response, err := server.RegistrationResponse(request, credID)
244+
if err != nil {
245+
log.Fatalln(err)
246+
}
244247

245248
// The server responds with its serialized response.
246249
message2 = response.Serialize()
@@ -310,7 +313,7 @@ func Example_loginKeyExchange() {
310313
log.Fatalln(err)
311314
}
312315

313-
if err := server.SetKeyMaterial(serverID, serverPrivateKey, serverPublicKey, secretOprfSeed); err != nil {
316+
if err := server.SetKeyMaterial(serverID, serverPrivateKey, serverPublicKey, secretOprfSeed, nil); err != nil {
314317
log.Fatalln(err)
315318
}
316319

@@ -426,7 +429,7 @@ func Example_fakeResponse() {
426429
log.Fatalln(err)
427430
}
428431

429-
if err := server.SetKeyMaterial(serverID, serverPrivateKey, serverPublicKey, secretOprfSeed); err != nil {
432+
if err := server.SetKeyMaterial(serverID, serverPrivateKey, serverPublicKey, secretOprfSeed, nil); err != nil {
430433
log.Fatalln(err)
431434
}
432435

server.go

Lines changed: 57 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,11 @@ type keyMaterial struct {
5858
serverSecretKey *ecc.Scalar
5959
serverPublicKey []byte
6060
oprfSeed []byte
61+
oprfClientSeed []byte
62+
}
63+
64+
type OPRFSeedOptions struct {
65+
OPRFSeed []byte
6166
}
6267

6368
// NewServer returns a Server instantiation given the application Configuration.
@@ -84,49 +89,67 @@ func (s *Server) GetConf() *internal.Configuration {
8489
return s.conf
8590
}
8691

87-
func (s *Server) oprfResponse(element *ecc.Element, oprfSeed, credentialIdentifier []byte) *ecc.Element {
88-
seed := s.conf.KDF.Expand(
89-
oprfSeed,
90-
encoding.SuffixString(credentialIdentifier, tag.ExpandOPRF),
91-
internal.SeedLength,
92-
)
92+
func (s *Server) oprfResponse(element *ecc.Element, credentialIdentifier []byte) (*ecc.Element, error) {
93+
if s.keyMaterial == nil {
94+
return nil, fmt.Errorf("key material must be specified")
95+
}
96+
seed := s.keyMaterial.oprfClientSeed
97+
if seed == nil {
98+
if s.keyMaterial.oprfSeed == nil {
99+
return nil, fmt.Errorf("OPRF seed must be specified")
100+
}
101+
seed = s.conf.KDF.Expand(
102+
s.keyMaterial.oprfSeed,
103+
encoding.SuffixString(credentialIdentifier, tag.ExpandOPRF),
104+
internal.SeedLength,
105+
)
106+
}
93107
ku := s.conf.OPRF.DeriveKey(seed, []byte(tag.DeriveKeyPair))
94108

95-
return s.conf.OPRF.Evaluate(ku, element)
109+
return s.conf.OPRF.Evaluate(ku, element), nil
96110
}
97111

98112
// RegistrationResponse returns a RegistrationResponse message to the input RegistrationRequest message and given
99113
// identifiers.
100114
func (s *Server) RegistrationResponse(
101115
req *message.RegistrationRequest,
102-
serverPublicKey *ecc.Element,
103-
credentialIdentifier, oprfSeed []byte,
104-
) *message.RegistrationResponse {
105-
z := s.oprfResponse(req.BlindedMessage, oprfSeed, credentialIdentifier)
116+
credentialIdentifier []byte,
117+
) (*message.RegistrationResponse, error) {
118+
z, err := s.oprfResponse(req.BlindedMessage, credentialIdentifier)
119+
if err != nil {
120+
return nil, err
121+
}
122+
123+
serverPublicKey := s.conf.Group.NewElement()
124+
if err := serverPublicKey.Decode(s.keyMaterial.serverPublicKey); err != nil {
125+
return nil, fmt.Errorf("invalid server public key: %w", err)
126+
}
106127

107128
return &message.RegistrationResponse{
108129
EvaluatedMessage: z,
109130
Pks: serverPublicKey,
110-
}
131+
}, nil
111132
}
112133

113134
func (s *Server) credentialResponse(
114135
req *message.CredentialRequest,
115-
serverPublicKey []byte,
116136
record *message.RegistrationRecord,
117-
credentialIdentifier, oprfSeed, maskingNonce []byte,
118-
) *message.CredentialResponse {
119-
z := s.oprfResponse(req.BlindedMessage, oprfSeed, credentialIdentifier)
137+
credentialIdentifier, maskingNonce []byte,
138+
) (*message.CredentialResponse, error) {
139+
z, err := s.oprfResponse(req.BlindedMessage, credentialIdentifier)
140+
if err != nil {
141+
return nil, err
142+
}
120143

121144
maskingNonce, maskedResponse := masking.Mask(
122145
s.conf,
123146
maskingNonce,
124147
record.MaskingKey,
125-
serverPublicKey,
148+
s.keyMaterial.serverPublicKey,
126149
record.Envelope,
127150
)
128151

129-
return message.NewCredentialResponse(z, maskingNonce, maskedResponse)
152+
return message.NewCredentialResponse(z, maskingNonce, maskedResponse), nil
130153
}
131154

132155
// GenerateKE2Options enables setting optional values for the session, which default to secure random values if not
@@ -160,7 +183,7 @@ func getGenerateKE2Options(options []GenerateKE2Options) *ake.Options {
160183
// - serverSecretKey is the server's secret AKE key.
161184
// - serverPublicKey is the server's public AKE key to the serverSecretKey.
162185
// - oprfSeed is the long-term OPRF input seed.
163-
func (s *Server) SetKeyMaterial(serverIdentity, serverSecretKey, serverPublicKey, oprfSeed []byte) error {
186+
func (s *Server) SetKeyMaterial(serverIdentity, serverSecretKey, serverPublicKey, oprfSeed []byte, oprfClientSeed []byte) error {
164187
sks := s.conf.Group.NewScalar()
165188
if err := sks.Decode(serverSecretKey); err != nil {
166189
return fmt.Errorf("invalid server AKE secret key: %w", err)
@@ -170,7 +193,15 @@ func (s *Server) SetKeyMaterial(serverIdentity, serverSecretKey, serverPublicKey
170193
return ErrZeroSKS
171194
}
172195

173-
if len(oprfSeed) != s.conf.Hash.Size() {
196+
if oprfSeed != nil {
197+
if len(oprfSeed) != s.conf.Hash.Size() {
198+
return ErrInvalidOPRFSeedLength
199+
}
200+
} else if oprfClientSeed != nil {
201+
if len(oprfClientSeed) != internal.SeedLength {
202+
return ErrInvalidOPRFSeedLength
203+
}
204+
} else {
174205
return ErrInvalidOPRFSeedLength
175206
}
176207

@@ -187,6 +218,7 @@ func (s *Server) SetKeyMaterial(serverIdentity, serverSecretKey, serverPublicKey
187218
serverSecretKey: sks,
188219
serverPublicKey: serverPublicKey,
189220
oprfSeed: oprfSeed,
221+
oprfClientSeed: oprfClientSeed,
190222
}
191223

192224
return nil
@@ -211,8 +243,11 @@ func (s *Server) GenerateKE2(
211243

212244
op := getGenerateKE2Options(options)
213245

214-
response := s.credentialResponse(ke1.CredentialRequest, s.keyMaterial.serverPublicKey,
215-
record.RegistrationRecord, record.CredentialIdentifier, s.keyMaterial.oprfSeed, record.TestMaskNonce)
246+
response, err := s.credentialResponse(ke1.CredentialRequest,
247+
record.RegistrationRecord, record.CredentialIdentifier, record.TestMaskNonce)
248+
if err != nil {
249+
return nil, err
250+
}
216251

217252
identities := ake.Identities{
218253
ClientIdentity: record.ClientIdentity,

tests/client_test.go

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -40,15 +40,15 @@ func TestClientRegistrationFinalize_InvalidPks(t *testing.T) {
4040
t.Fatal(err)
4141
}
4242

43-
_, pks := conf.conf.KeyGen()
43+
sks, pks := conf.conf.KeyGen()
4444
oprfSeed := internal.RandomBytes(conf.conf.Hash.Size())
4545
r1 := client.RegistrationInit([]byte("yo"))
4646

47-
pk := server.GetConf().Group.NewElement()
48-
if err := pk.Decode(pks); err != nil {
49-
panic(err)
47+
server.SetKeyMaterial([]byte("server"), sks, pks, oprfSeed, nil)
48+
r2, err := server.RegistrationResponse(r1, credID)
49+
if err != nil {
50+
t.Fatalf("failed to generate registration response: %v", err)
5051
}
51-
r2 := server.RegistrationResponse(r1, pk, credID, oprfSeed)
5252

5353
// message length
5454
badr2 := internal.RandomBytes(15)
@@ -127,11 +127,11 @@ func TestClientFinish_BadMaskedResponse(t *testing.T) {
127127
sks, pks := conf.conf.KeyGen()
128128
oprfSeed := internal.RandomBytes(conf.conf.Hash.Size())
129129

130-
if err := server.SetKeyMaterial(nil, sks, pks, oprfSeed); err != nil {
130+
if err := server.SetKeyMaterial(nil, sks, pks, oprfSeed, nil); err != nil {
131131
t.Fatal(err)
132132
}
133133

134-
rec := buildRecord(credID, oprfSeed, []byte("yo"), pks, client, server)
134+
rec := buildRecord(credID, oprfSeed, []byte("yo"), sks, pks, client, server, false)
135135

136136
ke1 := client.GenerateKE1([]byte("yo"))
137137
ke2, _ := server.GenerateKE2(ke1, rec)
@@ -173,11 +173,11 @@ func TestClientFinish_InvalidEnvelopeTag(t *testing.T) {
173173
sks, pks := conf.conf.KeyGen()
174174
oprfSeed := internal.RandomBytes(conf.conf.Hash.Size())
175175

176-
if err := server.SetKeyMaterial(nil, sks, pks, oprfSeed); err != nil {
176+
if err := server.SetKeyMaterial(nil, sks, pks, oprfSeed, nil); err != nil {
177177
t.Fatal(err)
178178
}
179179

180-
rec := buildRecord(credID, oprfSeed, []byte("yo"), pks, client, server)
180+
rec := buildRecord(credID, oprfSeed, []byte("yo"), sks, pks, client, server, false)
181181

182182
ke1 := client.GenerateKE1([]byte("yo"))
183183
ke2, _ := server.GenerateKE2(ke1, rec)
@@ -231,11 +231,11 @@ func TestClientFinish_InvalidKE2KeyEncoding(t *testing.T) {
231231
sks, pks := conf.conf.KeyGen()
232232
oprfSeed := internal.RandomBytes(conf.conf.Hash.Size())
233233

234-
if err := server.SetKeyMaterial(nil, sks, pks, oprfSeed); err != nil {
234+
if err := server.SetKeyMaterial(nil, sks, pks, oprfSeed, nil); err != nil {
235235
t.Fatal(err)
236236
}
237237

238-
rec := buildRecord(credID, oprfSeed, []byte("yo"), pks, client, server)
238+
rec := buildRecord(credID, oprfSeed, []byte("yo"), sks, pks, client, server, false)
239239

240240
ke1 := client.GenerateKE1([]byte("yo"))
241241
ke2, _ := server.GenerateKE2(ke1, rec)
@@ -314,11 +314,11 @@ func TestClientFinish_InvalidKE2Mac(t *testing.T) {
314314
sks, pks := conf.conf.KeyGen()
315315
oprfSeed := internal.RandomBytes(conf.conf.Hash.Size())
316316

317-
if err := server.SetKeyMaterial(nil, sks, pks, oprfSeed); err != nil {
317+
if err := server.SetKeyMaterial(nil, sks, pks, oprfSeed, nil); err != nil {
318318
log.Fatal(err)
319319
}
320320

321-
rec := buildRecord(credID, oprfSeed, []byte("yo"), pks, client, server)
321+
rec := buildRecord(credID, oprfSeed, []byte("yo"), sks, pks, client, server, false)
322322

323323
ke1 := client.GenerateKE1([]byte("yo"))
324324
ke2, _ := server.GenerateKE2(ke1, rec)

tests/helper_test.go

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -173,9 +173,10 @@ func getBadScalar(t *testing.T, c *configuration) []byte {
173173
}
174174

175175
func buildRecord(
176-
credID, oprfSeed, password, pks []byte,
176+
credID, oprfSeed, password, sks, pks []byte,
177177
client *opaque.Client,
178178
server *opaque.Server,
179+
noServerID bool,
179180
) *opaque.ClientRecord {
180181
conf := server.GetConf()
181182
r1 := client.RegistrationInit(password)
@@ -184,8 +185,18 @@ func buildRecord(
184185
if err := pk.Decode(pks); err != nil {
185186
panic(err)
186187
}
188+
var serverID []byte
189+
if !noServerID {
190+
serverID = []byte("server")
191+
}
187192

188-
r2 := server.RegistrationResponse(r1, pk, credID, oprfSeed)
193+
if err := server.SetKeyMaterial(serverID, sks, pks, oprfSeed, nil); err != nil {
194+
panic(err)
195+
}
196+
r2, err := server.RegistrationResponse(r1, credID)
197+
if err != nil {
198+
panic(err)
199+
}
189200
r3, _ := client.RegistrationFinalize(r2)
190201

191202
return &opaque.ClientRecord{

tests/opaque_test.go

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -89,13 +89,15 @@ func testRegistration(t *testing.T, p *testParams) (*opaque.Client, *opaque.Serv
8989
}
9090

9191
credID = internal.RandomBytes(32)
92-
pks, err := server.Deserialize.DecodeAkePublicKey(p.serverPublicKey)
92+
93+
if err := server.SetKeyMaterial(p.serverID, p.serverSecretKey, p.serverPublicKey, p.oprfSeed, nil); err != nil {
94+
t.Fatalf(dbgErr, err)
95+
}
96+
respReg, err := server.RegistrationResponse(m1, credID)
9397
if err != nil {
9498
t.Fatalf(dbgErr, err)
9599
}
96100

97-
respReg := server.RegistrationResponse(m1, pks, credID, p.oprfSeed)
98-
99101
m2s = respReg.Serialize()
100102
}
101103

@@ -152,7 +154,7 @@ func testAuthentication(
152154
var state []byte
153155
server, _ := p.Server()
154156
{
155-
if err := server.SetKeyMaterial(p.serverID, p.serverSecretKey, p.serverPublicKey, p.oprfSeed); err != nil {
157+
if err := server.SetKeyMaterial(p.serverID, p.serverSecretKey, p.serverPublicKey, p.oprfSeed, nil); err != nil {
156158
t.Fatal(err)
157159
}
158160

0 commit comments

Comments
 (0)