blob: 2e146bc781cc9f06dc38b200082efd4ef7d78ad6 [file] [log] [blame]
Pete Bentley0c61efe2019-08-13 09:32:23 +01001// Copyright (c) 2019, Cloudflare Inc.
2//
3// Permission to use, copy, modify, and/or distribute this software for any
4// purpose with or without fee is hereby granted, provided that the above
5// copyright notice and this permission notice appear in all copies.
6//
7// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
8// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
9// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
10// SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
11// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
12// OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
13// CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
14
15package sike
16
17import (
18 "bufio"
19 "bytes"
20 "crypto/rand"
21 "encoding/hex"
22 "math/big"
23 "strings"
24 "testing"
25)
26
27var tdata = struct {
28 name string
29 PrB_sidh string
30 PkB_sidh string
31 PrA_sidh string
32 PkA_sidh string
33 PkB_sike string
34 PrB_sike string
35}{
36 name: "P-434",
37 PrA_sidh: "3A727E04EA9B7E2A766A6F846489E7E7B915263BCEED308BB10FC9",
38 PkA_sidh: "9E668D1E6750ED4B91EE052C32839CA9DD2E56D52BC24DECC950AA" +
39 "AD24CEED3F9049C77FE80F0B9B01E7F8DAD7833EEC2286544D6380" +
40 "009C379CDD3E7517CEF5E20EB01F8231D52FC30DC61D2F63FB357F" +
41 "85DC6396E8A95DB9740BD3A972C8DB7901B31F074CD3E45345CA78" +
42 "F900817130E688A29A7CF0073B5C00FF2C65FBE776918EF9BD8E75" +
43 "B29EF7FAB791969B60B0C5B37A8992EDEF95FA7BAC40A95DAFE02E" +
44 "237301FEE9A7A43FD0B73477E8035DD12B73FAFEF18D39904DDE36" +
45 "53A754F36BE1888F6607C6A7951349A414352CF31A29F2C40302DB" +
46 "406C48018C905EB9DC46AFBF42A9187A9BB9E51B587622A2862DC7" +
47 "D5CC598BF38ED6320FB51D8697AD3D7A72ABCC32A393F0133DA8DF" +
48 "5E253D9E00B760B2DF342FCE974DCFE946CFE4727783531882800F" +
49 "9E5DD594D6D5A6275EEFEF9713ED838F4A06BB34D7B8D46E0B385A" +
50 "AEA1C7963601",
51 PrB_sidh: "E37BFE55B43B32448F375903D8D226EC94ADBFEA1D2B3536EB987001",
52 PkB_sidh: "C9F73E4497AAA3FDF9EB688135866A8A83934BA10E273B8CC3808C" +
53 "F0C1F5FAB3E9BB295885881B73DEBC875670C0F51C4BB40DF5FEDE" +
54 "01B8AF32D1BF10508B8C17B2734EB93B2B7F5D84A4A0F2F816E9E2" +
55 "C32AC253C0B6025B124D05A87A9E2A8567930F44BAA14219B941B6" +
56 "B400B4AED1D796DA12A5A9F0B8F3F5EE9DD43F64CB24A3B1719DF2" +
57 "78ADF56B5F3395187829DA2319DEABF6BBD6EDA244DE2B62CC5AC2" +
58 "50C1009DD1CD4712B0B37406612AD002B5E51A62B51AC9C0374D14" +
59 "3ABBBD58275FAFC4A5E959C54838C2D6D9FB43B7B2609061267B6A" +
60 "2E6C6D01D295C4223E0D3D7A4CDCFB28A7818A737935279751A6DD" +
61 "8290FD498D1F6AD5F4FFF6BDFA536713F509DCE8047252F1E7D0DD" +
62 "9FCC414C0070B5DCCE3665A21A032D7FBE749181032183AFAD240B" +
63 "7E671E87FBBEC3A8CA4C11AA7A9A23AC69AE2ACF54B664DECD2775" +
64 "3D63508F1B02",
65 PrB_sike: "4B622DE1350119C45A9F2E2EF3DC5DF56A27FCDFCDDAF58CD69B90" +
66 "3752D68C200934E160B234E49EDE247601",
67 PkB_sike: "1BD0A2E81307B6F96461317DDF535ACC0E59C742627BAE60D27605" +
68 "E10FAF722D22A73E184CB572A12E79DCD58C6B54FB01442114CBE9" +
69 "010B6CAEC25D04C16C5E42540C1524C545B8C67614ED4183C9FA5B" +
70 "D0BE45A7F89FBC770EE8E7E5E391C7EE6F35F74C29E6D9E35B1663" +
71 "DA01E48E9DEB2347512D366FDE505161677055E3EF23054D276E81" +
72 "7E2C57025DA1C10D2461F68617F2D11256EEE4E2D7DBDF6C8E34F3" +
73 "A0FD00C625428CB41857002159DAB94267ABE42D630C6AAA91AF83" +
74 "7C7A6740754EA6634C45454C51B0BB4D44C3CCCCE4B32C00901CF6" +
75 "9C008D013348379B2F9837F428A01B6173584691F2A6F3A3C4CF48" +
76 "7D20D261B36C8CDB1BC158E2A5162A9DA4F7A97AA0879B9897E2B6" +
77 "891B672201F9AEFBF799C27B2587120AC586A511360926FB7DA8EB" +
78 "F5CB5272F396AE06608422BE9792E2CE9BEF21BF55B7EFF8DC7EC8" +
79 "C99910D3F800",
80}
81
82/* -------------------------------------------------------------------------
83 Helpers
84 -------------------------------------------------------------------------*/
85// Fail if err !=nil. Display msg as an error message
86func checkErr(t testing.TB, err error, msg string) {
87 t.Helper()
88 if err != nil {
89 t.Error(msg)
90 }
91}
92
93// Utility used for running same test with all registered prime fields
94type MultiIdTestingFunc func(testing.TB)
95
96// Converts string to private key
97func convToPrv(s string, v KeyVariant) *PrivateKey {
98 key := NewPrivateKey(v)
99 hex, e := hex.DecodeString(s)
100 if e != nil {
101 panic("non-hex number provided")
102 }
103 e = key.Import(hex)
104 if e != nil {
105 panic("Can't import private key")
106 }
107 return key
108}
109
110// Converts string to public key
111func convToPub(s string, v KeyVariant) *PublicKey {
112 key := NewPublicKey(v)
113 hex, e := hex.DecodeString(s)
114 if e != nil {
115 panic("non-hex number provided")
116 }
117 e = key.Import(hex)
118 if e != nil {
119 panic("Can't import public key")
120 }
121 return key
122}
123
124/* -------------------------------------------------------------------------
125 Unit tests
126 -------------------------------------------------------------------------*/
127func TestKeygen(t *testing.T) {
128 alicePrivate := convToPrv(tdata.PrA_sidh, KeyVariant_SIDH_A)
129 bobPrivate := convToPrv(tdata.PrB_sidh, KeyVariant_SIDH_B)
130 expPubA := convToPub(tdata.PkA_sidh, KeyVariant_SIDH_A)
131 expPubB := convToPub(tdata.PkB_sidh, KeyVariant_SIDH_B)
132
133 pubA := alicePrivate.GeneratePublicKey()
134 pubB := bobPrivate.GeneratePublicKey()
135
136 if !bytes.Equal(pubA.Export(), expPubA.Export()) {
137 t.Fatalf("unexpected value of public key A")
138 }
139 if !bytes.Equal(pubB.Export(), expPubB.Export()) {
140 t.Fatalf("unexpected value of public key B")
141 }
142}
143
144func TestImportExport(t *testing.T) {
145 var err error
146 a := NewPublicKey(KeyVariant_SIDH_A)
147 b := NewPublicKey(KeyVariant_SIDH_B)
148
149 // Import keys
150 a_hex, err := hex.DecodeString(tdata.PkA_sidh)
151 checkErr(t, err, "invalid hex-number provided")
152
153 err = a.Import(a_hex)
154 checkErr(t, err, "import failed")
155
156 b_hex, err := hex.DecodeString(tdata.PkB_sike)
157 checkErr(t, err, "invalid hex-number provided")
158
159 err = b.Import(b_hex)
160 checkErr(t, err, "import failed")
161
162 // Export and check if same
163 if !bytes.Equal(b.Export(), b_hex) || !bytes.Equal(a.Export(), a_hex) {
164 t.Fatalf("export/import failed")
165 }
166
167 if (len(b.Export()) != b.Size()) || (len(a.Export()) != a.Size()) {
168 t.Fatalf("wrong size of exported keys")
169 }
170}
171
172func testPrivateKeyBelowMax(t testing.TB) {
173 for variant, keySz := range map[KeyVariant]*DomainParams{
174 KeyVariant_SIDH_A: &Params.A,
175 KeyVariant_SIDH_B: &Params.B} {
176
177 func(v KeyVariant, dp *DomainParams) {
178 var blen = int(dp.SecretByteLen)
179 var prv = NewPrivateKey(v)
180
181 // Calculate either (2^e2 - 1) or (2^s - 1); where s=ceil(log_2(3^e3)))
182 maxSecertVal := big.NewInt(int64(dp.SecretBitLen))
183 maxSecertVal.Exp(big.NewInt(int64(2)), maxSecertVal, nil)
184 maxSecertVal.Sub(maxSecertVal, big.NewInt(1))
185
186 // Do same test 1000 times
187 for i := 0; i < 1000; i++ {
188 err := prv.Generate(rand.Reader)
189 checkErr(t, err, "Private key generation")
190
191 // Convert to big-endian, as that's what expected by (*Int)SetBytes()
192 secretBytes := prv.Export()
193 for i := 0; i < int(blen/2); i++ {
194 tmp := secretBytes[i] ^ secretBytes[blen-i-1]
195 secretBytes[i] = tmp ^ secretBytes[i]
196 secretBytes[blen-i-1] = tmp ^ secretBytes[blen-i-1]
197 }
198 prvBig := new(big.Int).SetBytes(secretBytes)
199 // Check if generated key is bigger than acceptable
200 if prvBig.Cmp(maxSecertVal) == 1 {
201 t.Error("Generated private key is wrong")
202 }
203 }
204 }(variant, keySz)
205 }
206}
207
208func testKeyAgreement(t *testing.T, pkA, prA, pkB, prB string) {
209 var e error
210
211 // KeyPairs
212 alicePublic := convToPub(pkA, KeyVariant_SIDH_A)
213 bobPublic := convToPub(pkB, KeyVariant_SIDH_B)
214 alicePrivate := convToPrv(prA, KeyVariant_SIDH_A)
215 bobPrivate := convToPrv(prB, KeyVariant_SIDH_B)
216
217 // Do actual test
218 s1, e := DeriveSecret(bobPrivate, alicePublic)
219 checkErr(t, e, "derivation s1")
220 s2, e := DeriveSecret(alicePrivate, bobPublic)
221 checkErr(t, e, "derivation s1")
222
223 if !bytes.Equal(s1[:], s2[:]) {
224 t.Fatalf("two shared keys: %d, %d do not match", s1, s2)
225 }
226
227 // Negative case
228 dec, e := hex.DecodeString(tdata.PkA_sidh)
229 if e != nil {
230 t.FailNow()
231 }
232 dec[0] = ^dec[0]
233 e = alicePublic.Import(dec)
234 if e != nil {
235 t.FailNow()
236 }
237
238 s1, e = DeriveSecret(bobPrivate, alicePublic)
239 checkErr(t, e, "derivation of s1 failed")
240 s2, e = DeriveSecret(alicePrivate, bobPublic)
241 checkErr(t, e, "derivation of s2 failed")
242
243 if bytes.Equal(s1[:], s2[:]) {
244 t.Fatalf("The two shared keys: %d, %d match", s1, s2)
245 }
246}
247
248func TestDerivationRoundTrip(t *testing.T) {
249 var err error
250
251 prvA := NewPrivateKey(KeyVariant_SIDH_A)
252 prvB := NewPrivateKey(KeyVariant_SIDH_B)
253
254 // Generate private keys
255 err = prvA.Generate(rand.Reader)
256 checkErr(t, err, "key generation failed")
257 err = prvB.Generate(rand.Reader)
258 checkErr(t, err, "key generation failed")
259
260 // Generate public keys
261 pubA := prvA.GeneratePublicKey()
262 pubB := prvB.GeneratePublicKey()
263
264 // Derive shared secret
265 s1, err := DeriveSecret(prvB, pubA)
266 checkErr(t, err, "")
267
268 s2, err := DeriveSecret(prvA, pubB)
269 checkErr(t, err, "")
270
271 if !bytes.Equal(s1[:], s2[:]) {
272 t.Fatalf("Two shared keys: \n%X, \n%X do not match", s1, s2)
273 }
274}
275
276// Encrypt, Decrypt, check if input/output plaintext is the same
277func testPKERoundTrip(t testing.TB, id uint8) {
278 // Message to be encrypted
279 var msg = make([]byte, Params.MsgLen)
280 for i, _ := range msg {
281 msg[i] = byte(i)
282 }
283
284 // Import keys
285 pkB := NewPublicKey(KeyVariant_SIKE)
286 skB := NewPrivateKey(KeyVariant_SIKE)
287 pk_hex, err := hex.DecodeString(tdata.PkB_sike)
288 if err != nil {
289 t.Fatal(err)
290 }
291 sk_hex, err := hex.DecodeString(tdata.PrB_sike)
292 if err != nil {
293 t.Fatal(err)
294 }
295 if pkB.Import(pk_hex) != nil || skB.Import(sk_hex) != nil {
296 t.Error("Import")
297 }
298
299 ct, err := Encrypt(rand.Reader, pkB, msg[:])
300 if err != nil {
301 t.Fatal(err)
302 }
303 pt, err := Decrypt(skB, ct)
304 if err != nil {
305 t.Fatal(err)
306 }
307 if !bytes.Equal(pt[:], msg[:]) {
308 t.Errorf("Decryption failed \n got : %X\n exp : %X", pt, msg)
309 }
310}
311
312// Generate key and check if can encrypt
313func TestPKEKeyGeneration(t *testing.T) {
314 // Message to be encrypted
315 var msg = make([]byte, Params.MsgLen)
316 var err error
317 for i, _ := range msg {
318 msg[i] = byte(i)
319 }
320
321 sk := NewPrivateKey(KeyVariant_SIKE)
322 err = sk.Generate(rand.Reader)
323 checkErr(t, err, "PEK key generation")
324 pk := sk.GeneratePublicKey()
325
326 // Try to encrypt
327 ct, err := Encrypt(rand.Reader, pk, msg[:])
328 checkErr(t, err, "PEK encryption")
329 pt, err := Decrypt(sk, ct)
330 checkErr(t, err, "PEK key decryption")
331
332 if !bytes.Equal(pt[:], msg[:]) {
333 t.Fatalf("Decryption failed \n got : %X\n exp : %X", pt, msg)
334 }
335}
336
337func TestNegativePKE(t *testing.T) {
338 var msg [40]byte
339 var err error
340
341 // Generate key
342 sk := NewPrivateKey(KeyVariant_SIKE)
343 err = sk.Generate(rand.Reader)
344 checkErr(t, err, "key generation")
345
346 pk := sk.GeneratePublicKey()
347
348 // bytelen(msg) - 1
349 ct, err := Encrypt(rand.Reader, pk, msg[:Params.KemSize+8-1])
350 if err == nil {
351 t.Fatal("Error hasn't been returned")
352 }
353 if ct != nil {
354 t.Fatal("Ciphertext must be nil")
355 }
356
357 // KemSize - 1
358 pt, err := Decrypt(sk, msg[:Params.KemSize+8-1])
359 if err == nil {
360 t.Fatal("Error hasn't been returned")
361 }
362 if pt != nil {
363 t.Fatal("Ciphertext must be nil")
364 }
365}
366
367func testKEMRoundTrip(t *testing.T, pkB, skB []byte) {
368 // Import keys
369 pk := NewPublicKey(KeyVariant_SIKE)
370 sk := NewPrivateKey(KeyVariant_SIKE)
371 if pk.Import(pkB) != nil || sk.Import(skB) != nil {
372 t.Error("Import failed")
373 }
374
375 ct, ss_e, err := Encapsulate(rand.Reader, pk)
376 if err != nil {
377 t.Error("Encapsulate failed")
378 }
379
380 ss_d, err := Decapsulate(sk, pk, ct)
381 if err != nil {
382 t.Error("Decapsulate failed")
383 }
384 if !bytes.Equal(ss_e, ss_d) {
385 t.Error("Shared secrets from decapsulation and encapsulation differ")
386 }
387}
388
389func TestKEMRoundTrip(t *testing.T) {
390 pk, err := hex.DecodeString(tdata.PkB_sike)
391 checkErr(t, err, "public key B not a number")
392 sk, err := hex.DecodeString(tdata.PrB_sike)
393 checkErr(t, err, "private key B not a number")
394 testKEMRoundTrip(t, pk, sk)
395}
396
397func TestKEMKeyGeneration(t *testing.T) {
398 // Generate key
399 sk := NewPrivateKey(KeyVariant_SIKE)
400 checkErr(t, sk.Generate(rand.Reader), "error: key generation")
401 pk := sk.GeneratePublicKey()
402
403 // calculated shared secret
404 ct, ss_e, err := Encapsulate(rand.Reader, pk)
405
406 checkErr(t, err, "encapsulation failed")
407 ss_d, err := Decapsulate(sk, pk, ct)
408 checkErr(t, err, "decapsulation failed")
409
410 if !bytes.Equal(ss_e, ss_d) {
411 t.Fatalf("KEM failed \n encapsulated: %X\n decapsulated: %X", ss_d, ss_e)
412 }
413}
414
415func TestNegativeKEM(t *testing.T) {
416 sk := NewPrivateKey(KeyVariant_SIKE)
417 checkErr(t, sk.Generate(rand.Reader), "error: key generation")
418 pk := sk.GeneratePublicKey()
419
420 ct, ss_e, err := Encapsulate(rand.Reader, pk)
421 checkErr(t, err, "pre-requisite for a test failed")
422
423 ct[0] = ct[0] - 1
424 ss_d, err := Decapsulate(sk, pk, ct)
425 checkErr(t, err, "decapsulation returns error when invalid ciphertext provided")
426
427 if bytes.Equal(ss_e, ss_d) {
428 // no idea how this could ever happen, but it would be very bad
429 t.Error("critical error")
430 }
431
432 // Try encapsulating with SIDH key
433 pkSidh := NewPublicKey(KeyVariant_SIDH_B)
434 prSidh := NewPrivateKey(KeyVariant_SIDH_B)
435 _, _, err = Encapsulate(rand.Reader, pkSidh)
436 if err == nil {
437 t.Error("encapsulation accepts SIDH public key")
438 }
439 // Try decapsulating with SIDH key
440 _, err = Decapsulate(prSidh, pk, ct)
441 if err == nil {
442 t.Error("decapsulation accepts SIDH private key key")
443 }
444}
445
446// In case invalid ciphertext is provided, SIKE's decapsulation must
447// return same (but unpredictable) result for a given key.
448func TestNegativeKEMSameWrongResult(t *testing.T) {
449 sk := NewPrivateKey(KeyVariant_SIKE)
450 checkErr(t, sk.Generate(rand.Reader), "error: key generation")
451 pk := sk.GeneratePublicKey()
452
453 ct, encSs, err := Encapsulate(rand.Reader, pk)
454 checkErr(t, err, "pre-requisite for a test failed")
455
456 // make ciphertext wrong
457 ct[0] = ct[0] - 1
458 decSs1, err := Decapsulate(sk, pk, ct)
459 checkErr(t, err, "pre-requisite for a test failed")
460
461 // second decapsulation must be done with same, but imported private key
462 expSk := sk.Export()
463
464 // creat new private key
465 sk = NewPrivateKey(KeyVariant_SIKE)
466 err = sk.Import(expSk)
467 checkErr(t, err, "import failed")
468
469 // try decapsulating again. ss2 must be same as ss1 and different than
470 // original plaintext
471 decSs2, err := Decapsulate(sk, pk, ct)
472 checkErr(t, err, "pre-requisite for a test failed")
473
474 if !bytes.Equal(decSs1, decSs2) {
475 t.Error("decapsulation is insecure")
476 }
477
478 if bytes.Equal(encSs, decSs1) || bytes.Equal(encSs, decSs2) {
479 // this test requires that decapsulation returns wrong result
480 t.Errorf("test implementation error")
481 }
482}
483
484func readAndCheckLine(r *bufio.Reader) []byte {
485 // Read next line from buffer
486 line, isPrefix, err := r.ReadLine()
487 if err != nil || isPrefix {
488 panic("Wrong format of input file")
489 }
490
491 // Function expects that line is in format "KEY = HEX_VALUE". Get
492 // value, which should be a hex string
493 hexst := strings.Split(string(line), "=")[1]
494 hexst = strings.TrimSpace(hexst)
495 // Convert value to byte string
496 ret, err := hex.DecodeString(hexst)
497 if err != nil {
498 panic("Wrong format of input file")
499 }
500 return ret
501}
502
503func testKeygenSIKE(pk, sk []byte, id uint8) bool {
504 // Import provided private key
505 var prvKey = NewPrivateKey(KeyVariant_SIKE)
506 if prvKey.Import(sk) != nil {
507 panic("sike test: can't load KAT")
508 }
509
510 // Generate public key
511 pubKey := prvKey.GeneratePublicKey()
512 return bytes.Equal(pubKey.Export(), pk)
513}
514
515func testDecapsulation(pk, sk, ct, ssExpected []byte, id uint8) bool {
516 var pubKey = NewPublicKey(KeyVariant_SIKE)
517 var prvKey = NewPrivateKey(KeyVariant_SIKE)
518 if pubKey.Import(pk) != nil || prvKey.Import(sk) != nil {
519 panic("sike test: can't load KAT")
520 }
521
522 ssGot, err := Decapsulate(prvKey, pubKey, ct)
523 if err != nil {
524 panic("sike test: can't perform degcapsulation KAT")
525 }
526
527 return bytes.Equal(ssGot, ssExpected)
528}
529
530func TestKeyAgreement(t *testing.T) {
531 testKeyAgreement(t, tdata.PkA_sidh, tdata.PrA_sidh, tdata.PkB_sidh, tdata.PrB_sidh)
532}
533
534// Same values as in sike_test.cc
535func TestDecapsulation(t *testing.T) {
536 var sk = [16 + 28]byte{
537 0x04, 0x5E, 0x01, 0x42, 0xB8, 0x2F, 0xE1, 0x9A, 0x38, 0x25,
538 0x92, 0xE7, 0xDC, 0xBA, 0xF7, 0x1B, 0xB1, 0xFD, 0x34, 0x42,
539 0xDB, 0x02, 0xBC, 0x9D, 0x4C, 0xD0, 0x72, 0x34, 0x4D, 0xBD,
540 0x06, 0xDF, 0x1C, 0x7D, 0x0A, 0x88, 0xB2, 0x50, 0xC4, 0xF6,
541 0xAE, 0xE8, 0x25, 0x01,
542 }
543
544 var pk = [330]byte{
545 0x6D, 0x8D, 0xF5, 0x7B, 0xCD, 0x47, 0xCA, 0xCB, 0x7A, 0x38,
546 0xB7, 0xA6, 0x90, 0xB7, 0x37, 0x03, 0xD4, 0x6F, 0x27, 0x73,
547 0x74, 0x17, 0x5A, 0xA4, 0x0D, 0xC6, 0x81, 0xAD, 0xDB, 0xF7,
548 0x18, 0xB2, 0x3C, 0x30, 0xCF, 0xAA, 0x08, 0x11, 0x91, 0xCC,
549 0x27, 0x4E, 0xF1, 0xA6, 0xB7, 0xDA, 0xD2, 0xCF, 0x99, 0x7F,
550 0xF7, 0xE1, 0xD0, 0xCE, 0x00, 0xD2, 0x4B, 0xA4, 0x33, 0xB4,
551 0x87, 0x01, 0x3F, 0x02, 0xF7, 0xF9, 0xDE, 0xC3, 0x60, 0x62,
552 0xDA, 0x3F, 0x74, 0xA9, 0x44, 0xBE, 0x19, 0xD5, 0x03, 0x2A,
553 0x79, 0x8C, 0xA7, 0xFF, 0xEA, 0xB3, 0xBB, 0xB5, 0xD4, 0x1D,
554 0x8F, 0x92, 0xCE, 0x62, 0x6E, 0x99, 0x24, 0xD7, 0x57, 0xFA,
555 0xCD, 0xB6, 0xE2, 0x8E, 0xFD, 0x22, 0x0E, 0x31, 0x21, 0x01,
556 0x8D, 0x79, 0xF8, 0x3E, 0x27, 0xEC, 0x43, 0x40, 0xDB, 0x82,
557 0xE5, 0xEB, 0x6C, 0x97, 0x66, 0x29, 0x15, 0x68, 0xB7, 0x4D,
558 0x84, 0xD1, 0x8A, 0x0B, 0x12, 0x36, 0x2C, 0x0C, 0x0A, 0x6E,
559 0x4E, 0xDE, 0xA5, 0x8A, 0xDE, 0x77, 0xDD, 0x70, 0x49, 0x73,
560 0xAC, 0x27, 0x6D, 0x8D, 0x25, 0x9A, 0xE4, 0x25, 0xE8, 0x95,
561 0x8F, 0xFE, 0x90, 0x3B, 0x00, 0x69, 0x20, 0xE8, 0x7C, 0xA5,
562 0xF5, 0x79, 0xC0, 0x61, 0x51, 0x91, 0x35, 0x25, 0x3F, 0x17,
563 0x2F, 0x70, 0x73, 0xF0, 0x89, 0xB5, 0xC8, 0x25, 0xB8, 0xE5,
564 0x7E, 0x34, 0xDD, 0x11, 0xE5, 0xD6, 0xC3, 0xD5, 0x29, 0x89,
565 0xC6, 0x2C, 0x99, 0x53, 0x1D, 0x2C, 0x77, 0xB0, 0xB6, 0xA1,
566 0xBD, 0x79, 0xFB, 0x4A, 0xC2, 0x48, 0x4C, 0x62, 0x51, 0x00,
567 0xE3, 0x91, 0x2A, 0xCB, 0x84, 0x03, 0x5D, 0x2D, 0xC8, 0x33,
568 0xE9, 0x14, 0xBF, 0x74, 0x21, 0xBC, 0xF4, 0x76, 0xE5, 0x42,
569 0xB8, 0xBD, 0xE2, 0xE7, 0x20, 0x95, 0x54, 0xF2, 0xED, 0xC0,
570 0x79, 0x38, 0x1E, 0xD2, 0xEA, 0x1A, 0x63, 0x85, 0xE7, 0x3A,
571 0xDA, 0xAD, 0xAB, 0x1B, 0x1E, 0x19, 0x9E, 0x73, 0xD0, 0x10,
572 0x2E, 0x38, 0xAC, 0x8B, 0x00, 0x6A, 0x30, 0x2C, 0x3D, 0x70,
573 0x8E, 0x39, 0x6D, 0xC0, 0x12, 0x61, 0x7D, 0x2A, 0x0A, 0x04,
574 0x95, 0x8E, 0x09, 0x3C, 0x7B, 0xEC, 0x2E, 0xBC, 0xE8, 0xE8,
575 0xE8, 0x37, 0x29, 0xC4, 0x7E, 0x76, 0x48, 0xB9, 0x3B, 0x72,
576 0xE5, 0x99, 0x9B, 0xF9, 0xE3, 0x99, 0x72, 0x3F, 0x35, 0x29,
577 0x85, 0xE0, 0xC8, 0xBF, 0xB1, 0x6B, 0xB1, 0x6E, 0x72, 0x00,
578 }
579
580 var ct = [330 + 16]byte{
581 0xFF, 0xEB, 0xEF, 0x4A, 0xC0, 0x57, 0x0F, 0x26, 0xAC, 0x76,
582 0xA8, 0xB0, 0xA3, 0x5D, 0x9C, 0xD9, 0x25, 0xD1, 0x7F, 0x92,
583 0x5D, 0xF4, 0x23, 0x34, 0xC3, 0x03, 0x10, 0xE1, 0xB0, 0x24,
584 0x9B, 0x44, 0x58, 0x26, 0x13, 0x56, 0x83, 0x43, 0x72, 0x69,
585 0x28, 0x0D, 0x55, 0x07, 0x1F, 0xDB, 0xC0, 0x23, 0x34, 0x83,
586 0x1A, 0x09, 0x9B, 0x80, 0x00, 0x64, 0x56, 0xDC, 0x79, 0x7A,
587 0xD2, 0xCE, 0x23, 0xC9, 0x72, 0x27, 0xFC, 0x8D, 0xAB, 0xBF,
588 0xD3, 0x17, 0xF6, 0x91, 0x7B, 0x15, 0x93, 0x83, 0x8A, 0x4F,
589 0x6C, 0xCA, 0x4A, 0x94, 0xDA, 0xC7, 0x9D, 0xB6, 0xD6, 0xBA,
590 0xBD, 0x81, 0x9A, 0x78, 0xE5, 0xE5, 0xBE, 0x17, 0xBC, 0xCB,
591 0xC8, 0x23, 0x80, 0x5F, 0x75, 0xF8, 0xDB, 0x51, 0x55, 0x00,
592 0x25, 0x33, 0x52, 0x64, 0xB2, 0xD6, 0xD8, 0x9A, 0x2A, 0x9E,
593 0x29, 0x99, 0x13, 0x33, 0xE2, 0xA7, 0x98, 0xAC, 0xD7, 0x79,
594 0x5C, 0x2F, 0xBA, 0x07, 0xC3, 0x03, 0x37, 0xD6, 0xE6, 0xB5,
595 0xA1, 0xF5, 0x29, 0xB6, 0xF6, 0xC0, 0x5C, 0x44, 0x68, 0x2B,
596 0x0B, 0xF5, 0x00, 0x01, 0x44, 0xD5, 0xCC, 0x23, 0xB5, 0x27,
597 0x4F, 0xCA, 0xB4, 0x05, 0x01, 0xF9, 0xD4, 0x41, 0xE0, 0xE1,
598 0x1E, 0xCF, 0xA9, 0xBC, 0x79, 0xD7, 0xD5, 0xF5, 0x3C, 0xE6,
599 0x93, 0xF4, 0x6C, 0x84, 0x5A, 0x2C, 0x4B, 0xE4, 0x91, 0xB2,
600 0xB2, 0xB8, 0xAD, 0x74, 0x9A, 0x69, 0x79, 0x4C, 0x84, 0xB7,
601 0xBF, 0xF1, 0x68, 0x4B, 0xAE, 0x0F, 0x7F, 0x45, 0x3B, 0x18,
602 0x3F, 0xFA, 0x00, 0x48, 0xE0, 0x3A, 0xE2, 0xC0, 0xAE, 0x00,
603 0xCE, 0x90, 0x28, 0xA4, 0x1B, 0xBE, 0xCA, 0x0C, 0x21, 0x29,
604 0x64, 0x30, 0x5E, 0x35, 0xAD, 0xFD, 0x83, 0x47, 0x40, 0x6D,
605 0x15, 0x56, 0xFC, 0xF8, 0x5F, 0xAB, 0x81, 0xFE, 0x6B, 0xE9,
606 0x6B, 0xED, 0x27, 0x35, 0x7C, 0xD8, 0x2C, 0xD4, 0xF2, 0x11,
607 0xE6, 0xAF, 0xDF, 0xB8, 0x91, 0x96, 0xEB, 0xF7, 0x4C, 0x8D,
608 0x70, 0x77, 0x90, 0x81, 0x00, 0x09, 0x19, 0x27, 0x8A, 0x9E,
609 0xB6, 0x1A, 0xE9, 0xAC, 0x6C, 0xC9, 0xF8, 0xEA, 0xA2, 0x34,
610 0xB8, 0xAC, 0xB3, 0xB3, 0x68, 0xA1, 0xB7, 0x29, 0x55, 0xCA,
611 0x40, 0x23, 0x92, 0x5C, 0x0C, 0x79, 0x6B, 0xD6, 0x9F, 0x5B,
612 0xD2, 0xE6, 0xAE, 0x04, 0xCB, 0xEC, 0xC7, 0x88, 0x18, 0xDB,
613 0x7A, 0xE6, 0xD6, 0xC9, 0x39, 0xFD, 0x93, 0x9B, 0xC8, 0x01,
614 0x6F, 0x3E, 0x6C, 0x90, 0x3E, 0x73, 0x76, 0x99, 0x7C, 0x48,
615 0xDA, 0x68, 0x48, 0x80, 0x2B, 0x63,
616 }
617 var ssExp = [16]byte{
618 0xA1, 0xF9, 0x5A, 0x67, 0xB9, 0x3D, 0x1E, 0x72, 0xE8, 0xC5,
619 0x71, 0xF1, 0x4C, 0xB2, 0xAA, 0x6D,
620 }
621
622 var prvObj = NewPrivateKey(KeyVariant_SIKE)
623 var pubObj = NewPublicKey(KeyVariant_SIKE)
624
625 if pubObj.Import(pk[:]) != nil || prvObj.Import(sk[:]) != nil {
626 t.Error("Can't import one of the keys")
627 }
628
629 res, _ := Decapsulate(prvObj, pubObj, ct[:])
630 if !bytes.Equal(ssExp[:], res) {
631 t.Error("Wrong decapsulation result")
632 }
633}
634
635/* -------------------------------------------------------------------------
636 Benchmarking
637 -------------------------------------------------------------------------*/
638
639func BenchmarkSidhKeyAgreement(b *testing.B) {
640 // KeyPairs
641 alicePublic := convToPub(tdata.PkA_sidh, KeyVariant_SIDH_A)
642 alicePrivate := convToPrv(tdata.PrA_sidh, KeyVariant_SIDH_A)
643 bobPublic := convToPub(tdata.PkB_sidh, KeyVariant_SIDH_B)
644 bobPrivate := convToPrv(tdata.PrB_sidh, KeyVariant_SIDH_B)
645
646 for i := 0; i < b.N; i++ {
647 // Derive shared secret
648 DeriveSecret(bobPrivate, alicePublic)
649 DeriveSecret(alicePrivate, bobPublic)
650 }
651}
652
653func BenchmarkAliceKeyGenPrv(b *testing.B) {
654 prv := NewPrivateKey(KeyVariant_SIDH_A)
655 for n := 0; n < b.N; n++ {
656 prv.Generate(rand.Reader)
657 }
658}
659
660func BenchmarkBobKeyGenPrv(b *testing.B) {
661 prv := NewPrivateKey(KeyVariant_SIDH_B)
662 for n := 0; n < b.N; n++ {
663 prv.Generate(rand.Reader)
664 }
665}
666
667func BenchmarkAliceKeyGenPub(b *testing.B) {
668 prv := NewPrivateKey(KeyVariant_SIDH_A)
669 prv.Generate(rand.Reader)
670 for n := 0; n < b.N; n++ {
671 prv.GeneratePublicKey()
672 }
673}
674
675func BenchmarkBobKeyGenPub(b *testing.B) {
676 prv := NewPrivateKey(KeyVariant_SIDH_B)
677 prv.Generate(rand.Reader)
678 for n := 0; n < b.N; n++ {
679 prv.GeneratePublicKey()
680 }
681}
682
683func BenchmarkSharedSecretAlice(b *testing.B) {
684 aPr := convToPrv(tdata.PrA_sidh, KeyVariant_SIDH_A)
685 bPk := convToPub(tdata.PkB_sike, KeyVariant_SIDH_B)
686 for n := 0; n < b.N; n++ {
687 DeriveSecret(aPr, bPk)
688 }
689}
690
691func BenchmarkSharedSecretBob(b *testing.B) {
692 // m_B = 3*randint(0,3^238)
693 aPk := convToPub(tdata.PkA_sidh, KeyVariant_SIDH_A)
694 bPr := convToPrv(tdata.PrB_sidh, KeyVariant_SIDH_B)
695 for n := 0; n < b.N; n++ {
696 DeriveSecret(bPr, aPk)
697 }
698}