...
1 package oprf
2
3 import (
4 "encoding/binary"
5 "io"
6
7 "github.com/cloudflare/circl/group"
8 )
9
10 type PrivateKey struct {
11 p params
12 k group.Scalar
13 pub *PublicKey
14 }
15
16 type PublicKey struct {
17 p params
18 e group.Element
19 }
20
21 func (k *PrivateKey) MarshalBinary() ([]byte, error) { return k.k.MarshalBinary() }
22 func (k *PublicKey) MarshalBinary() ([]byte, error) { return k.e.MarshalBinaryCompress() }
23
24 func (k *PrivateKey) UnmarshalBinary(s Suite, data []byte) error {
25 p, ok := s.(params)
26 if !ok {
27 return ErrInvalidSuite
28 }
29 k.p = p
30 k.k = k.p.group.NewScalar()
31
32 return k.k.UnmarshalBinary(data)
33 }
34
35 func (k *PublicKey) UnmarshalBinary(s Suite, data []byte) error {
36 p, ok := s.(params)
37 if !ok {
38 return ErrInvalidSuite
39 }
40 k.p = p
41 k.e = k.p.group.NewElement()
42
43 return k.e.UnmarshalBinary(data)
44 }
45
46 func (k *PrivateKey) Public() *PublicKey {
47 if k.pub == nil {
48 k.pub = &PublicKey{k.p, k.p.group.NewElement().MulGen(k.k)}
49 }
50
51 return k.pub
52 }
53
54
55 func GenerateKey(s Suite, rnd io.Reader) (*PrivateKey, error) {
56 if rnd == nil {
57 return nil, io.ErrNoProgress
58 }
59
60 p, ok := s.(params)
61 if !ok {
62 return nil, ErrInvalidSuite
63 }
64 privateKey := p.group.RandomScalar(rnd)
65
66 return &PrivateKey{p, privateKey, nil}, nil
67 }
68
69
70 func DeriveKey(s Suite, mode Mode, seed, info []byte) (*PrivateKey, error) {
71 const maxTries = 255
72 p, ok := s.(params)
73 if !ok {
74 return nil, ErrInvalidSuite
75 }
76 if !isValidMode(mode) {
77 return nil, ErrInvalidMode
78 }
79 p.m = mode
80
81 lenInfo := []byte{0, 0}
82 binary.BigEndian.PutUint16(lenInfo, uint16(len(info)))
83 deriveInput := append(append(append([]byte{}, seed...), lenInfo...), info...)
84
85 dst := p.getDST(deriveKeyPairDST)
86 zero := p.group.NewScalar()
87 privateKey := p.group.NewScalar()
88 for counter := byte(0); privateKey.IsEqual(zero); counter++ {
89 if counter > maxTries {
90 return nil, ErrDeriveKeyPairError
91 }
92 privateKey = p.group.HashToScalar(append(deriveInput, counter), dst)
93 }
94
95 return &PrivateKey{p, privateKey, nil}, nil
96 }
97
View as plain text