Skip to content

Commit 971442f

Browse files
committed
Export some missing OPRF pieces. Clean up unit tests.
1 parent f1ee9a6 commit 971442f

File tree

2 files changed

+73
-137
lines changed

2 files changed

+73
-137
lines changed

oprf/oprf.go

+55-47
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
1-
//
21
// Package oprf provides an implementation of Oblivious Pseudorandom Functions
3-
// (OPRFs), as defined on draft-irtf-cfrg-voprf.
2+
// (OPRFs), as defined on draft-irtf-cfrg-voprf: https://datatracker.ietf.org/doc/draft-irtf-cfrg-voprf/
43
// It implements:
54
// For a Client:
65
// - Blind
@@ -11,8 +10,6 @@
1110
// - Setup
1211
// - Evaluate
1312
// - VerifyFinalize
14-
// References
15-
// - OPRF draft: https://datatracker.ietf.org/doc/draft-irtf-cfrg-voprf/
1613
package oprf
1714

1815
import (
@@ -22,6 +19,7 @@ import (
2219
"encoding/binary"
2320
"errors"
2421
"hash"
22+
"io"
2523

2624
"github.com/cloudflare/circl/oprf/group"
2725
)
@@ -45,7 +43,7 @@ var (
4543

4644
var (
4745
// ErrUnsupportedGroup is an error stating that the ciphersuite chosen is not supported
48-
ErrUnsupportedGroup = errors.New("the chosen group is not supported")
46+
ErrUnsupportedGroup = errors.New("unsupported group")
4947
)
5048

5149
// BlindToken corresponds to a token that has been blinded.
@@ -75,21 +73,21 @@ type KeyPair struct {
7573

7674
// Client is a representation of a Client during protocol execution.
7775
type Client struct {
78-
suite *group.Ciphersuite
79-
ctx []byte
76+
suite *group.Ciphersuite
77+
context []byte
8078
}
8179

8280
// Server is a representation of a Server during protocol execution.
8381
type Server struct {
84-
suite *group.Ciphersuite
85-
ctx []byte
86-
Kp *KeyPair
82+
suite *group.Ciphersuite
83+
context []byte
84+
Kp *KeyPair
8785
}
8886

8987
func generateContext(id SuiteID) []byte {
90-
ctx := [3]byte{OPRFMode, 0, byte(id)}
88+
context := [3]byte{OPRFMode, 0, byte(id)}
9189

92-
return ctx[:]
90+
return context[:]
9391
}
9492

9593
// Serialize serializes a KeyPair elements into byte arrays.
@@ -132,11 +130,11 @@ func assignKeyPair(suite *group.Ciphersuite, privK, pubK []byte) (*KeyPair, erro
132130
return kp, nil
133131
}
134132

135-
func suiteFromID(id SuiteID, ctx []byte) (*group.Ciphersuite, error) {
133+
func suiteFromID(id SuiteID, context []byte) (*group.Ciphersuite, error) {
136134
var err error
137135
var suite *group.Ciphersuite
138136

139-
suite, err = group.NewSuite(uint16(id), ctx)
137+
suite, err = group.NewSuite(uint16(id), context)
140138
if err != nil {
141139
return nil, err
142140
}
@@ -146,26 +144,26 @@ func suiteFromID(id SuiteID, ctx []byte) (*group.Ciphersuite, error) {
146144

147145
// NewServer creates a new instantiation of a Server.
148146
func NewServer(id SuiteID) (*Server, error) {
149-
ctx := generateContext(id)
147+
context := generateContext(id)
150148

151-
suite, err := suiteFromID(id, ctx)
149+
suite, err := suiteFromID(id, context)
152150
if err != nil {
153151
return nil, err
154152
}
155153
keyPair := GenerateKeyPair(suite)
156154

157155
return &Server{
158-
suite: suite,
159-
ctx: ctx,
160-
Kp: keyPair}, nil
156+
suite: suite,
157+
context: context,
158+
Kp: keyPair}, nil
161159
}
162160

163161
// NewServerWithKeyPair creates a new instantiation of a Server. It can create
164162
// a server with existing keys or use pre-generated keys.
165163
func NewServerWithKeyPair(id SuiteID, privK, pubK []byte) (*Server, error) {
166-
ctx := generateContext(id)
164+
context := generateContext(id)
167165

168-
suite, err := suiteFromID(id, ctx)
166+
suite, err := suiteFromID(id, context)
169167
if err != nil {
170168
return nil, err
171169
}
@@ -176,9 +174,9 @@ func NewServerWithKeyPair(id SuiteID, privK, pubK []byte) (*Server, error) {
176174
}
177175

178176
return &Server{
179-
suite: suite,
180-
ctx: ctx,
181-
Kp: keyPair}, nil
177+
suite: suite,
178+
context: context,
179+
Kp: keyPair}, nil
182180
}
183181

184182
// Evaluate blindly signs a client token.
@@ -195,8 +193,18 @@ func (s *Server) Evaluate(b BlindToken) (*Evaluation, error) {
195193
return &Evaluation{ser}, nil
196194
}
197195

196+
func mustWrite(h io.Writer, data []byte) {
197+
dataLen, err := h.Write(data)
198+
if err != nil {
199+
panic(err)
200+
}
201+
if len(data) != dataLen {
202+
panic("failed to write")
203+
}
204+
}
205+
198206
// FinalizeHash computes the final hash for the suite.
199-
func finalizeHash(c *group.Ciphersuite, data, iToken, info, ctx []byte) []byte {
207+
func finalizeHash(c *group.Ciphersuite, data, iToken, info, context []byte) []byte {
200208
var h hash.Hash
201209
if c.Hash == "sha256" {
202210
h = sha256.New()
@@ -207,23 +215,23 @@ func finalizeHash(c *group.Ciphersuite, data, iToken, info, ctx []byte) []byte {
207215
lenBuf := make([]byte, 2)
208216

209217
binary.BigEndian.PutUint16(lenBuf, uint16(len(data)))
210-
_, _ = h.Write(lenBuf)
211-
_, _ = h.Write(data)
218+
mustWrite(h, lenBuf)
219+
mustWrite(h, data)
212220

213221
binary.BigEndian.PutUint16(lenBuf, uint16(len(iToken)))
214-
_, _ = h.Write(lenBuf)
215-
_, _ = h.Write(iToken)
222+
mustWrite(h, lenBuf)
223+
mustWrite(h, iToken)
216224

217225
binary.BigEndian.PutUint16(lenBuf, uint16(len(info)))
218-
_, _ = h.Write(lenBuf)
219-
_, _ = h.Write(info)
226+
mustWrite(h, lenBuf)
227+
mustWrite(h, info)
220228

221229
dst := []byte("VOPRF05-Finalize-")
222-
dst = append(dst, ctx...)
230+
dst = append(dst, context...)
223231

224232
binary.BigEndian.PutUint16(lenBuf, uint16(len(dst)))
225-
_, _ = h.Write(lenBuf)
226-
_, _ = h.Write(dst)
233+
mustWrite(h, lenBuf)
234+
mustWrite(h, dst)
227235

228236
return h.Sum(nil)
229237
}
@@ -238,7 +246,7 @@ func (s *Server) FullEvaluate(in, info []byte) ([]byte, error) {
238246
t := p.ScalarMult(s.Kp.PrivK)
239247
iToken := t.Serialize()
240248

241-
h := finalizeHash(s.suite, in, iToken, info, s.ctx)
249+
h := finalizeHash(s.suite, in, iToken, info, s.context)
242250

243251
return h, nil
244252
}
@@ -257,30 +265,30 @@ func (s *Server) VerifyFinalize(in, info, out []byte) bool {
257265
return false
258266
}
259267

260-
h := finalizeHash(s.suite, in, e.element, info, s.ctx)
268+
h := finalizeHash(s.suite, in, e.element, info, s.context)
261269
return subtle.ConstantTimeCompare(h, out) == 1
262270
}
263271

264272
// NewClient creates a new instantiation of a Client.
265273
func NewClient(id SuiteID) (*Client, error) {
266-
ctx := generateContext(id)
274+
context := generateContext(id)
267275

268-
suite, err := suiteFromID(id, ctx)
276+
suite, err := suiteFromID(id, context)
269277
if err != nil {
270278
return nil, err
271279
}
272280

273281
return &Client{
274-
suite: suite,
275-
ctx: ctx}, nil
282+
suite: suite,
283+
context: context}, nil
276284
}
277285

278286
// ClientRequest is a structure to encapsulate the output of a Request call.
279287
type ClientRequest struct {
280-
suite *group.Ciphersuite
281-
ctx []byte
282-
token *Token
283-
bToken BlindToken
288+
suite *group.Ciphersuite
289+
context []byte
290+
token *Token
291+
BlindedToken BlindToken
284292
}
285293

286294
// Request generates a token and its blinded version.
@@ -293,10 +301,10 @@ func (c *Client) Request(in []byte) (*ClientRequest, error) {
293301
}
294302

295303
t := p.ScalarMult(r)
296-
bToken := t.Serialize()
304+
BlindedToken := t.Serialize()
297305

298306
tk := &Token{in, r}
299-
return &ClientRequest{c.suite, c.ctx, tk, bToken}, nil
307+
return &ClientRequest{c.suite, c.context, tk, BlindedToken}, nil
300308
}
301309

302310
// Finalize computes the signed token from the server Evaluation and returns
@@ -314,6 +322,6 @@ func (cr *ClientRequest) Finalize(e *Evaluation, info []byte) ([]byte, error) {
314322
tt := p.ScalarMult(rInv)
315323
iToken := tt.Serialize()
316324

317-
h := finalizeHash(cr.suite, cr.token.data, iToken, info, cr.ctx)
325+
h := finalizeHash(cr.suite, cr.token.data, iToken, info, cr.context)
318326
return h, nil
319327
}

0 commit comments

Comments
 (0)