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 package hybrid
32
33 import (
34 "errors"
35
36 "github.com/cloudflare/circl/internal/sha3"
37 "github.com/cloudflare/circl/kem"
38 "github.com/cloudflare/circl/kem/kyber/kyber1024"
39 "github.com/cloudflare/circl/kem/kyber/kyber512"
40 "github.com/cloudflare/circl/kem/kyber/kyber768"
41 )
42
43 var ErrUninitialized = errors.New("public or private key not initialized")
44
45
46 func Kyber512X25519() kem.Scheme { return kyber512X }
47
48
49 func Kyber768X25519() kem.Scheme { return kyber768X }
50
51
52 func Kyber768X448() kem.Scheme { return kyber768X4 }
53
54
55 func Kyber1024X448() kem.Scheme { return kyber1024X }
56
57
58 func P256Kyber768Draft00() kem.Scheme { return p256Kyber768Draft00 }
59
60 var p256Kyber768Draft00 kem.Scheme = &scheme{
61 "P256Kyber768Draft00",
62 p256Kem,
63 kyber768.Scheme(),
64 }
65
66 var kyber512X kem.Scheme = &scheme{
67 "Kyber512-X25519",
68 x25519Kem,
69 kyber512.Scheme(),
70 }
71
72 var kyber768X kem.Scheme = &scheme{
73 "Kyber768-X25519",
74 x25519Kem,
75 kyber768.Scheme(),
76 }
77
78 var kyber768X4 kem.Scheme = &scheme{
79 "Kyber768-X448",
80 x448Kem,
81 kyber768.Scheme(),
82 }
83
84 var kyber1024X kem.Scheme = &scheme{
85 "Kyber1024-X448",
86 x448Kem,
87 kyber1024.Scheme(),
88 }
89
90
91 type publicKey struct {
92 scheme *scheme
93 first kem.PublicKey
94 second kem.PublicKey
95 }
96
97
98 type privateKey struct {
99 scheme *scheme
100 first kem.PrivateKey
101 second kem.PrivateKey
102 }
103
104
105 type scheme struct {
106 name string
107 first kem.Scheme
108 second kem.Scheme
109 }
110
111 func (sch *scheme) Name() string { return sch.name }
112 func (sch *scheme) PublicKeySize() int {
113 return sch.first.PublicKeySize() + sch.second.PublicKeySize()
114 }
115
116 func (sch *scheme) PrivateKeySize() int {
117 return sch.first.PrivateKeySize() + sch.second.PrivateKeySize()
118 }
119
120 func (sch *scheme) SeedSize() int {
121 first := sch.first.SeedSize()
122 second := sch.second.SeedSize()
123 ret := second
124 if first > second {
125 ret = first
126 }
127 return ret
128 }
129
130 func (sch *scheme) SharedKeySize() int {
131 return sch.first.SharedKeySize() + sch.second.SharedKeySize()
132 }
133
134 func (sch *scheme) CiphertextSize() int {
135 return sch.first.CiphertextSize() + sch.second.CiphertextSize()
136 }
137
138 func (sch *scheme) EncapsulationSeedSize() int {
139 first := sch.first.EncapsulationSeedSize()
140 second := sch.second.EncapsulationSeedSize()
141 ret := second
142 if first > second {
143 ret = first
144 }
145 return ret
146 }
147
148 func (sk *privateKey) Scheme() kem.Scheme { return sk.scheme }
149 func (pk *publicKey) Scheme() kem.Scheme { return pk.scheme }
150
151 func (sk *privateKey) MarshalBinary() ([]byte, error) {
152 if sk.first == nil || sk.second == nil {
153 return nil, ErrUninitialized
154 }
155 first, err := sk.first.MarshalBinary()
156 if err != nil {
157 return nil, err
158 }
159 second, err := sk.second.MarshalBinary()
160 if err != nil {
161 return nil, err
162 }
163 return append(first, second...), nil
164 }
165
166 func (sk *privateKey) Equal(other kem.PrivateKey) bool {
167 oth, ok := other.(*privateKey)
168 if !ok {
169 return false
170 }
171 if sk.first == nil && sk.second == nil && oth.first == nil && oth.second == nil {
172 return true
173 }
174 if sk.first == nil || sk.second == nil || oth.first == nil || oth.second == nil {
175 return false
176 }
177 return sk.first.Equal(oth.first) && sk.second.Equal(oth.second)
178 }
179
180 func (sk *privateKey) Public() kem.PublicKey {
181 return &publicKey{sk.scheme, sk.first.Public(), sk.second.Public()}
182 }
183
184 func (pk *publicKey) Equal(other kem.PublicKey) bool {
185 oth, ok := other.(*publicKey)
186 if !ok {
187 return false
188 }
189 if pk.first == nil && pk.second == nil && oth.first == nil && oth.second == nil {
190 return true
191 }
192 if pk.first == nil || pk.second == nil || oth.first == nil || oth.second == nil {
193 return false
194 }
195 return pk.first.Equal(oth.first) && pk.second.Equal(oth.second)
196 }
197
198 func (pk *publicKey) MarshalBinary() ([]byte, error) {
199 if pk.first == nil || pk.second == nil {
200 return nil, ErrUninitialized
201 }
202 first, err := pk.first.MarshalBinary()
203 if err != nil {
204 return nil, err
205 }
206 second, err := pk.second.MarshalBinary()
207 if err != nil {
208 return nil, err
209 }
210 return append(first, second...), nil
211 }
212
213 func (sch *scheme) GenerateKeyPair() (kem.PublicKey, kem.PrivateKey, error) {
214 pk1, sk1, err := sch.first.GenerateKeyPair()
215 if err != nil {
216 return nil, nil, err
217 }
218 pk2, sk2, err := sch.second.GenerateKeyPair()
219 if err != nil {
220 return nil, nil, err
221 }
222
223 return &publicKey{sch, pk1, pk2}, &privateKey{sch, sk1, sk2}, nil
224 }
225
226 func (sch *scheme) DeriveKeyPair(seed []byte) (kem.PublicKey, kem.PrivateKey) {
227 if len(seed) != sch.SeedSize() {
228 panic(kem.ErrSeedSize)
229 }
230 h := sha3.NewShake256()
231 _, _ = h.Write(seed)
232 first := make([]byte, sch.first.SeedSize())
233 second := make([]byte, sch.second.SeedSize())
234 _, _ = h.Read(first)
235 _, _ = h.Read(second)
236
237 pk1, sk1 := sch.first.DeriveKeyPair(first)
238 pk2, sk2 := sch.second.DeriveKeyPair(second)
239
240 return &publicKey{sch, pk1, pk2}, &privateKey{sch, sk1, sk2}
241 }
242
243 func (sch *scheme) Encapsulate(pk kem.PublicKey) (ct, ss []byte, err error) {
244 pub, ok := pk.(*publicKey)
245 if !ok {
246 return nil, nil, kem.ErrTypeMismatch
247 }
248
249 ct1, ss1, err := sch.first.Encapsulate(pub.first)
250 if err != nil {
251 return nil, nil, err
252 }
253
254 ct2, ss2, err := sch.second.Encapsulate(pub.second)
255 if err != nil {
256 return nil, nil, err
257 }
258
259 return append(ct1, ct2...), append(ss1, ss2...), nil
260 }
261
262 func (sch *scheme) EncapsulateDeterministically(
263 pk kem.PublicKey, seed []byte,
264 ) (ct, ss []byte, err error) {
265 if len(seed) != sch.EncapsulationSeedSize() {
266 return nil, nil, kem.ErrSeedSize
267 }
268
269 h := sha3.NewShake256()
270 _, _ = h.Write(seed)
271 first := make([]byte, sch.first.EncapsulationSeedSize())
272 second := make([]byte, sch.second.EncapsulationSeedSize())
273 _, _ = h.Read(first)
274 _, _ = h.Read(second)
275
276 pub, ok := pk.(*publicKey)
277 if !ok {
278 return nil, nil, kem.ErrTypeMismatch
279 }
280
281 ct1, ss1, err := sch.first.EncapsulateDeterministically(pub.first, first)
282 if err != nil {
283 return nil, nil, err
284 }
285 ct2, ss2, err := sch.second.EncapsulateDeterministically(pub.second, second)
286 if err != nil {
287 return nil, nil, err
288 }
289 return append(ct1, ct2...), append(ss1, ss2...), nil
290 }
291
292 func (sch *scheme) Decapsulate(sk kem.PrivateKey, ct []byte) ([]byte, error) {
293 if len(ct) != sch.CiphertextSize() {
294 return nil, kem.ErrCiphertextSize
295 }
296
297 priv, ok := sk.(*privateKey)
298 if !ok {
299 return nil, kem.ErrTypeMismatch
300 }
301
302 firstSize := sch.first.CiphertextSize()
303 ss1, err := sch.first.Decapsulate(priv.first, ct[:firstSize])
304 if err != nil {
305 return nil, err
306 }
307 ss2, err := sch.second.Decapsulate(priv.second, ct[firstSize:])
308 if err != nil {
309 return nil, err
310 }
311 return append(ss1, ss2...), nil
312 }
313
314 func (sch *scheme) UnmarshalBinaryPublicKey(buf []byte) (kem.PublicKey, error) {
315 if len(buf) != sch.PublicKeySize() {
316 return nil, kem.ErrPubKeySize
317 }
318 firstSize := sch.first.PublicKeySize()
319 pk1, err := sch.first.UnmarshalBinaryPublicKey(buf[:firstSize])
320 if err != nil {
321 return nil, err
322 }
323 pk2, err := sch.second.UnmarshalBinaryPublicKey(buf[firstSize:])
324 if err != nil {
325 return nil, err
326 }
327 return &publicKey{sch, pk1, pk2}, nil
328 }
329
330 func (sch *scheme) UnmarshalBinaryPrivateKey(buf []byte) (kem.PrivateKey, error) {
331 if len(buf) != sch.PrivateKeySize() {
332 return nil, kem.ErrPrivKeySize
333 }
334 firstSize := sch.first.PrivateKeySize()
335 sk1, err := sch.first.UnmarshalBinaryPrivateKey(buf[:firstSize])
336 if err != nil {
337 return nil, err
338 }
339 sk2, err := sch.second.UnmarshalBinaryPrivateKey(buf[firstSize:])
340 if err != nil {
341 return nil, err
342 }
343 return &privateKey{sch, sk1, sk2}, nil
344 }
345
View as plain text