github.com/cloudflare/circl@v1.5.0/dh/sidh/sike_test.go (about) 1 package sidh 2 3 import ( 4 "bufio" 5 "bytes" 6 "crypto/rand" 7 "encoding/hex" 8 "fmt" 9 "io" 10 "os" 11 "strings" 12 "testing" 13 14 "github.com/cloudflare/circl/dh/sidh/internal/common" 15 . "github.com/cloudflare/circl/internal/test" 16 ) 17 18 type sikeVec struct { 19 id uint8 20 name string 21 kem *KEM 22 KatFile string 23 PkB string 24 PrB string 25 } 26 27 var tdataSike = map[uint8]sikeVec{ 28 Fp434: { 29 Fp434, "P-434", NewSike434(rand.Reader), 30 "testdata/PQCkemKAT_374.rsp", 31 "1BD0A2E81307B6F96461317DDF535ACC0E59C742627BAE60D27605E10FAF722D" + 32 "22A73E184CB572A12E79DCD58C6B54FB01442114CBE9010B6CAEC25D04C16C5E" + 33 "42540C1524C545B8C67614ED4183C9FA5BD0BE45A7F89FBC770EE8E7E5E391C7" + 34 "EE6F35F74C29E6D9E35B1663DA01E48E9DEB2347512D366FDE505161677055E3" + 35 "EF23054D276E817E2C57025DA1C10D2461F68617F2D11256EEE4E2D7DBDF6C8E" + 36 "34F3A0FD00C625428CB41857002159DAB94267ABE42D630C6AAA91AF837C7A67" + 37 "40754EA6634C45454C51B0BB4D44C3CCCCE4B32C00901CF69C008D013348379B" + 38 "2F9837F428A01B6173584691F2A6F3A3C4CF487D20D261B36C8CDB1BC158E2A5" + 39 "162A9DA4F7A97AA0879B9897E2B6891B672201F9AEFBF799C27B2587120AC586" + 40 "A511360926FB7DA8EBF5CB5272F396AE06608422BE9792E2CE9BEF21BF55B7EF" + 41 "F8DC7EC8C99910D3F800", 42 "4B622DE1350119C45A9F2E2EF3DC5DF56A27FCDFCDDAF58CD69B903752D68C20" + 43 "0934E160B234E49EDE247601", 44 }, 45 Fp503: { 46 Fp503, "P-503", NewSike503(rand.Reader), 47 "testdata/PQCkemKAT_434.rsp", 48 "4032A90B6C036B7D2A83878AD116641AD319E420235A505F3F5C3DEC27C87A6C" + 49 "BA0792201D6E7B196C582D43CAF86CB2C7DEFA6598B543C946CDDF62EF9A328C" + 50 "8719B66BA5052231DAE13AF7D9CDEBB4ED327773C7AE0818F41AF1D28CD78B16" + 51 "C996232528235C8392B8FCFD925CB311B2A801B0402A90E527261EA32F2BEF67" + 52 "7C544908D5509B8AB7D7BF20456727AD358AD585306A0B28F6B2AA583CE8A3E0" + 53 "BB92D8CD55347D39D4E3C30D3D0F96EABB721A6968CDD143FE9227643CF697FB" + 54 "2DF0B71322B5EA1505D0DDBF70A2FD1193011F3BC18AA1E127C614B76969DCDA" + 55 "45A2072B519A1074FDA49F5C828450C6A007BF8D7CDDD5D2FC112119C679CA3A" + 56 "B16C6960B25F6C681A7DCED0F0E3901740D3DBF3A33011EB7DA460E8ADA80EE3" + 57 "45B2B71420950A9A803E4F11330EB91CCABB1EEE4D875A109D7724ABD201272C" + 58 "0B4981BDCDFA70F3430A89D2A88EEED474CF0CFAC65CE883F44B4722FA280C6F" + 59 "A9C4724D414B35AF69D6ECB21BFDA23BFF6B66C22C2451DC8E1C", 60 "7BF6938C975658AEB8B4D37CFFBDE25D97E561F36C219A0E8FE645816DBBC7ED7B57" + 61 "7700AE8DC3138E97A0C3F6F002065C92A0B1B8180208", 62 }, 63 Fp751: { 64 Fp751, "P-751", NewSike751(rand.Reader), 65 "testdata/PQCkemKAT_644.rsp", 66 "E1A758EC0D418BFE86D8077B5BB169133C06C1F2A067D8B202D9D058FFC51F63" + 67 "FD26155A6577C74BA7F1A27E7BA51982517B923615DEB00BE408920A07831DF5" + 68 "978CFDDD0BF690A264353A4A16B666F90586D7F89A193CE09375D389C1379A7A" + 69 "528581C3ACB002CD2DC4F0FD672568FF9050BA8365C7FEFC5E6ED089B921DE68" + 70 "04091A0744DE3EB14D426A3F7DA215C50312617C1C2697243980D06056F2CCE8" + 71 "8AE7AE73C7343C0B7104C9F2870A94FED744CF6E94630514B6CEAB0E64733BB6" + 72 "FA67B931E5D8206010475CBE8BC587248D65D89D8CD9C8BBFA93E8B5F9EB9130" + 73 "773DED665D52ABBD91C4C8C255F73C0FC82501AE33330E9F308DE7177CBF83E4" + 74 "E26E334D7CB09019E638147FC58ED372AF660F14C194BC80E9666325C98E0F80" + 75 "877271D4A6BF514F603703D8A697874CD50A34D92F5AAEA84633CCF96801BD51" + 76 "7BF425DEE4A32AAF06684052473EA14643C3D535440FB2240A988D09F297C5A3" + 77 "88CB3DE60ED943F124034B90EFF611221F80F78EC124956338A105F6636B063D" + 78 "7E48BFBD5D614310FB97D86F122E4AE6F9DDF4977A93ED7D0CE2A94E346A1A03" + 79 "D3219CF21907B85A5BCDC713F93A4406A22E03B1655A66E1F6741A2F953E6FE0" + 80 "868B2614BABEF1943BBBCB1B66D3E7017E533EA84F291240B56AB33EF1DC3F3D" + 81 "E99DBF9E8BE51A0076E462BCDD825EA96D7F63C99177C305C257B31461F4C23D" + 82 "43115F0220409E8880BBB2468586D03461E807BE824B693874911B2B52AF06FD" + 83 "BDC47F5A0159729641A7C950AB9E03F2DC045135", 84 "0001020304050607080900010203040506070809000102030405060708090102" + 85 "8626ED79D451140800E03B59B956F8210E556067407D13DC90FA9E8B872BFB8F" + 86 "AB0A7289852106E40538D3575C500201", 87 }, 88 } 89 90 // Encrypt, Decrypt, check if input/output plaintext is the same. 91 func testPKERoundTrip(t *testing.T, v sikeVec) { 92 // Message to be encrypted 93 var pt [common.MaxMsgBsz]byte 94 params := common.Params(v.id) 95 ct := make([]byte, v.kem.CiphertextSize()) 96 msg := make([]byte, params.MsgLen) 97 for i := range msg { 98 msg[i] = byte(i) 99 } 100 101 // Import keys 102 pkB := NewPublicKey(params.ID, KeyVariantSike) 103 skB := NewPrivateKey(params.ID, KeyVariantSike) 104 pkHex, err := hex.DecodeString(v.PkB) 105 CheckNoErr(t, err, "Test vector wrong") 106 skHex, err := hex.DecodeString(v.PrB) 107 CheckNoErr(t, err, "Test vector wrong") 108 err = pkB.Import(pkHex) 109 CheckNoErr(t, err, "Public key import failed") 110 err = skB.Import(skHex) 111 CheckNoErr(t, err, "Private key import failed") 112 err = v.kem.encrypt(ct, rand.Reader, pkB, msg[:]) 113 CheckNoErr(t, err, "PKE roundtrip - encryption failed") 114 ptLen, err := v.kem.decrypt(pt[:], skB, ct) 115 CheckNoErr(t, err, "PKE roundtrip - description failed") 116 117 if !bytes.Equal(pt[:ptLen], msg[:]) { 118 t.Errorf("Decryption failed \n got : %X\n exp : %X", pt[:ptLen], msg) 119 } 120 } 121 122 // Generate key and check if can encrypt. 123 func testPKEKeyGeneration(t *testing.T, v sikeVec) { 124 var err error 125 params := common.Params(v.id) 126 var pt [common.MaxMsgBsz]byte 127 msg := make([]byte, params.MsgLen) 128 ct := make([]byte, v.kem.CiphertextSize()) 129 // static buffer to ensure no overrides 130 pk := NewPublicKey(v.id, KeyVariantSike) 131 sk := NewPrivateKey(v.id, KeyVariantSike) 132 133 for i := range msg { 134 msg[i] = byte(i) 135 } 136 137 err = sk.Generate(rand.Reader) 138 CheckNoErr(t, err, "PKE key generation") 139 sk.GeneratePublicKey(pk) 140 141 err = v.kem.encrypt(ct, rand.Reader, pk, msg[:]) 142 CheckNoErr(t, err, "PKE encryption") 143 ptLen, err := v.kem.decrypt(pt[:], sk, ct) 144 CheckNoErr(t, err, "PKE key decryption") 145 146 if !bytes.Equal(pt[:ptLen], msg[:]) { 147 t.Fatalf("Decryption failed \n got : %X\n exp : %X", pt, msg) 148 } 149 } 150 151 func testNegativePKE(t *testing.T, v sikeVec) { 152 var err error 153 var msg [common.MaxMsgBsz]byte 154 ct := make([]byte, v.kem.CiphertextSize()) 155 pk := NewPublicKey(v.id, KeyVariantSike) 156 sk := NewPrivateKey(v.id, KeyVariantSike) 157 158 // Generate key 159 err = sk.Generate(rand.Reader) 160 CheckNoErr(t, err, "key generation") 161 sk.GeneratePublicKey(pk) 162 163 // bytelen(msg) - 1 164 err = v.kem.encrypt(ct, rand.Reader, pk, msg[:v.kem.params.KemSize+8-1]) 165 CheckIsErr(t, err, "PKE encryption doesn't fail") 166 for _, v := range ct { 167 if v != 0 { 168 t.Fatal("Returned ciphertext must be not changed") 169 } 170 } 171 } 172 173 func testKEMRoundTrip(t *testing.T, pkB, skB []byte, v sikeVec) { 174 // Import keys 175 var err error 176 var ssE [common.MaxSharedSecretBsz]byte 177 var ssD [common.MaxSharedSecretBsz]byte 178 pk := NewPublicKey(v.id, KeyVariantSike) 179 sk := NewPrivateKey(v.id, KeyVariantSike) 180 ct := make([]byte, v.kem.CiphertextSize()) 181 ssBsz := v.kem.SharedSecretSize() 182 183 err = pk.Import(pkB) 184 CheckNoErr(t, err, "Public key import failed") 185 err = sk.Import(skB) 186 CheckNoErr(t, err, "Private key import failed") 187 188 v.kem.Reset() 189 err = v.kem.Encapsulate(ct, ssE[:], pk) 190 CheckNoErr(t, err, "Encapsulation failed") 191 v.kem.Reset() 192 err = v.kem.Decapsulate(ssD[:ssBsz], sk, pk, ct) 193 CheckNoErr(t, err, "Decapsulation failed") 194 195 if !bytes.Equal(ssE[:v.kem.SharedSecretSize()], ssD[:v.kem.SharedSecretSize()]) { 196 t.Errorf("Shared secrets from decapsulation and encapsulation differ [%s]", v.name) 197 } 198 } 199 200 func testKEMKeyGeneration(t *testing.T, v sikeVec) { 201 var ssE [common.MaxSharedSecretBsz]byte 202 var ssD [common.MaxSharedSecretBsz]byte 203 ct := make([]byte, v.kem.CiphertextSize()) 204 205 sk := NewPrivateKey(v.id, KeyVariantSike) 206 pk := NewPublicKey(v.id, KeyVariantSike) 207 CheckNoErr(t, sk.Generate(rand.Reader), "error: key generation") 208 sk.GeneratePublicKey(pk) 209 210 // calculated shared secret 211 v.kem.Reset() 212 err := v.kem.Encapsulate(ct, ssE[:], pk) 213 CheckNoErr(t, err, "encapsulation failed") 214 v.kem.Reset() 215 err = v.kem.Decapsulate(ssD[:v.kem.SharedSecretSize()], sk, pk, ct) 216 CheckNoErr(t, err, "decapsulation failed") 217 218 if !bytes.Equal(ssE[:], ssD[:]) { 219 t.Fatalf("KEM failed \n encapsulated: %X\n decapsulated: %X", ssD[:], ssE[:]) 220 } 221 } 222 223 func testNegativeKEM(t *testing.T, v sikeVec) { 224 var ssE [common.MaxSharedSecretBsz]byte 225 var ssD [common.MaxSharedSecretBsz]byte 226 var ssTmp [common.MaxSharedSecretBsz]byte 227 ct := make([]byte, v.kem.CiphertextSize()) 228 ssBsz := v.kem.SharedSecretSize() 229 230 sk := NewPrivateKey(v.id, KeyVariantSike) 231 pk := NewPublicKey(v.id, KeyVariantSike) 232 CheckNoErr(t, sk.Generate(rand.Reader), "error: key generation") 233 sk.GeneratePublicKey(pk) 234 235 v.kem.Reset() 236 err := v.kem.Encapsulate(ct, ssE[:], pk) 237 CheckNoErr(t, err, "pre-requisite for a test failed") 238 239 // Try decapsulate too small ciphertext 240 v.kem.Reset() 241 CheckNoErr( 242 t, 243 CheckPanic(func() { _ = v.kem.Decapsulate(ssTmp[:ssBsz], sk, pk, ct[:len(ct)-2]) }), 244 "Decapsulation must panic if ciphertext is too small") 245 246 ctTmp := make([]byte, len(ct)+1) 247 // Try decapsulate too big ciphertext 248 v.kem.Reset() 249 CheckNoErr( 250 t, 251 CheckPanic(func() { _ = v.kem.Decapsulate(ssTmp[:ssBsz], sk, pk, ctTmp) }), 252 "Decapsulation must panic if ciphertext is too big") 253 254 // Change ciphertext 255 ct[0] = ct[0] - 1 256 v.kem.Reset() 257 err = v.kem.Decapsulate(ssD[:ssBsz], sk, pk, ct) 258 CheckNoErr(t, err, "decapsulation returns error when invalid ciphertext provided") 259 260 if bytes.Equal(ssE[:], ssD[:]) { 261 // no idea how this could ever happen, but it would be very bad 262 t.Error("critical error") 263 } 264 265 // Try encapsulating with SIDH key 266 pkSidh := NewPublicKey(v.id, KeyVariantSidhB) 267 prSidh := NewPrivateKey(v.id, KeyVariantSidhB) 268 v.kem.Reset() 269 CheckNoErr( 270 t, 271 CheckPanic(func() { _ = v.kem.Encapsulate(ct, ssE[:], pkSidh) }), 272 "encapsulation accepts SIDH public key") 273 274 // Try decapsulating with SIDH key 275 v.kem.Reset() 276 CheckNoErr( 277 t, 278 CheckPanic(func() { _ = v.kem.Decapsulate(ssD[:ssBsz], prSidh, pk, ct) }), 279 "encapsulation accepts SIDH public key") 280 } 281 282 // In case invalid ciphertext is provided, SIKE's decapsulation must 283 // return same (but unpredictable) result for a given key. 284 func testNegativeKEMSameWrongResult(t *testing.T, v sikeVec) { 285 var ssE [common.MaxSharedSecretBsz]byte 286 var ssD1 [common.MaxSharedSecretBsz]byte 287 var ssD2 [common.MaxSharedSecretBsz]byte 288 ct := make([]byte, v.kem.CiphertextSize()) 289 ssBsz := v.kem.SharedSecretSize() 290 291 sk := NewPrivateKey(v.id, KeyVariantSike) 292 pk := NewPublicKey(v.id, KeyVariantSike) 293 CheckNoErr(t, sk.Generate(rand.Reader), "error: key generation") 294 sk.GeneratePublicKey(pk) 295 296 v.kem.Reset() 297 err := v.kem.Encapsulate(ct, ssE[:], pk) 298 CheckNoErr(t, err, "pre-requisite for a test failed") 299 300 // make ciphertext wrong 301 ct[0] = ct[0] - 1 302 v.kem.Reset() 303 err = v.kem.Decapsulate(ssD1[:ssBsz], sk, pk, ct) 304 CheckNoErr(t, err, "pre-requisite for a test failed") 305 306 // change secret keysecond decapsulation must be done with same, but imported private key 307 var expSk [common.MaxSikePrivateKeyBsz]byte 308 sk.Export(expSk[:]) 309 310 // create new private key 311 sk = NewPrivateKey(v.id, KeyVariantSike) 312 CheckNoErr(t, sk.Import(expSk[:sk.Size()]), "import failed") 313 314 // try decapsulating again. 315 v.kem.Reset() 316 err = v.kem.Decapsulate(ssD2[:ssBsz], sk, pk, ct) 317 CheckNoErr(t, err, "pre-requisite for a test failed") 318 319 // ssD1 must be same as ssD2 320 if !bytes.Equal(ssD1[:], ssD2[:]) { 321 t.Error("decapsulation is insecure") 322 } 323 324 // ssD1 and ssD2 must be different than ssE 325 if bytes.Equal(ssE[:], ssD1[:]) || bytes.Equal(ssE[:], ssD2[:]) { 326 // this test requires that decapsulation returns wrong result 327 t.Errorf("test implementation error") 328 } 329 } 330 331 func testKAT(t *testing.T, v sikeVec) { 332 ssGot := make([]byte, v.kem.SharedSecretSize()) 333 testDecapsulation := func(pk, sk, ct, ssExpected []byte) { 334 pubKey := NewPublicKey(v.id, KeyVariantSike) 335 prvKey := NewPrivateKey(v.id, KeyVariantSike) 336 if pubKey.Import(pk) != nil || prvKey.Import(sk) != nil { 337 panic("sike test: can't load KAT") 338 } 339 340 err := v.kem.Decapsulate(ssGot, prvKey, pubKey, ct) 341 CheckNoErr(t, err, "sike test: can't perform decapsulation KAT") 342 if !bytes.Equal(ssGot, ssExpected) { 343 t.Fatalf("KAT decapsulation failed\n") 344 } 345 } 346 347 readAndCheckLine := func(r *bufio.Reader) []byte { 348 // Read next line from buffer 349 line, isPrefix, err := r.ReadLine() 350 if err != nil || isPrefix { 351 panic("Wrong format of input file") 352 } 353 354 // Function expects that line is in format "KEY = HEX_VALUE". Get 355 // value, which should be a hex string 356 hexst := strings.Split(string(line), "=")[1] 357 hexst = strings.TrimSpace(hexst) 358 // Convert value to byte string 359 ret, err := hex.DecodeString(hexst) 360 if err != nil { 361 panic("Wrong format of input file") 362 } 363 return ret 364 } 365 366 testKeygen := func(pk, sk []byte) { 367 // Import provided private key 368 prvKey := NewPrivateKey(v.id, KeyVariantSike) 369 pubKey := NewPublicKey(v.id, KeyVariantSike) 370 pubKeyBytes := make([]byte, pubKey.Size()) 371 CheckNoErr(t, prvKey.Import(sk), "Can't load KAT") 372 373 // Generate public key 374 prvKey.GeneratePublicKey(pubKey) 375 pubKey.Export(pubKeyBytes) 376 if !bytes.Equal(pubKeyBytes, pk) { 377 t.Errorf("Public key differ [%s]", v.name) 378 } 379 } 380 381 f, err := os.Open(v.KatFile) 382 if err != nil { 383 t.Fatal(err) 384 } 385 386 r := bufio.NewReader(f) 387 for { 388 line, isPrefix, err := r.ReadLine() 389 if err != nil || isPrefix { 390 if err == io.EOF { 391 break 392 } else { 393 t.Fatal(err) 394 } 395 } 396 if len(strings.TrimSpace(string(line))) == 0 || line[0] == '#' { 397 continue 398 } 399 400 // count 401 _ = strings.Split(string(line), "=")[1] 402 // seed 403 _ = readAndCheckLine(r) 404 // pk 405 pk := readAndCheckLine(r) 406 // sk (secret key in test vector is concatenation of 407 // MSG + SECRET_BOB_KEY + PUBLIC_BOB_KEY. We use only MSG+SECRET_BOB_KEY 408 sk := readAndCheckLine(r) 409 sk = sk[:v.kem.params.MsgLen+int(v.kem.params.B.SecretByteLen)] 410 // ct 411 ct := readAndCheckLine(r) 412 // ss 413 ss := readAndCheckLine(r) 414 415 testKeygen(pk, sk) 416 testDecapsulation(pk, sk, ct, ss) 417 testKEMRoundTrip(t, pk, sk, v) 418 } 419 } 420 421 // Interface to "testing" 422 423 /* ------------------------------------------------------------------------- 424 Wrappers for 'testing' SIDH 425 -------------------------------------------------------------------------*/ 426 427 func testSike(t *testing.T, m *map[uint8]sikeVec, f func(*testing.T, sikeVec)) { 428 for i := range *m { 429 v := (*m)[i] 430 t.Run(v.name, func(t *testing.T) { f(t, v) }) 431 } 432 } 433 434 func TestPKERoundTrip(t *testing.T) { testSike(t, &tdataSike, testPKERoundTrip) } 435 func TestPKEKeyGeneration(t *testing.T) { testSike(t, &tdataSike, testPKEKeyGeneration) } 436 func TestNegativePKE(t *testing.T) { testSike(t, &tdataSike, testNegativePKE) } 437 func TestKEMKeyGeneration(t *testing.T) { testSike(t, &tdataSike, testKEMKeyGeneration) } 438 func TestNegativeKEM(t *testing.T) { testSike(t, &tdataSike, testNegativeKEM) } 439 func TestKAT(t *testing.T) { testSike(t, &tdataSike, testKAT) } 440 func TestNegativeKEMSameWrongResult(t *testing.T) { 441 testSike(t, &tdataSike, testNegativeKEMSameWrongResult) 442 } 443 444 func TestKEMRoundTrip(t *testing.T) { 445 for _, val := range tdataSike { 446 // fmt.Printf("\tTesting: %s\n", val.name) 447 pk, err := hex.DecodeString(val.PkB) 448 CheckNoErr(t, err, "public key B not a number") 449 sk, err := hex.DecodeString(val.PrB) 450 CheckNoErr(t, err, "private key B not a number") 451 testKEMRoundTrip(t, pk, sk, val) 452 } 453 } 454 455 /* ------------------------------------------------------------------------- 456 Benchmarking 457 -------------------------------------------------------------------------*/ 458 459 func benchSike(t *testing.B, m *map[uint8]sikeVec, f func(*testing.B, sikeVec)) { 460 for i := range *m { 461 v := (*m)[i] 462 t.Run(v.name, func(t *testing.B) { f(t, v) }) 463 } 464 } 465 466 func benchKeygen(b *testing.B, v sikeVec) { 467 pub := NewPublicKey(v.id, KeyVariantSike) 468 prv := NewPrivateKey(v.id, KeyVariantSike) 469 _ = prv.Generate(rand.Reader) 470 471 b.ResetTimer() 472 for n := 0; n < b.N; n++ { 473 prv.GeneratePublicKey(pub) 474 } 475 } 476 477 func benchmarkEncaps(b *testing.B, v sikeVec) { 478 pub := NewPublicKey(v.id, KeyVariantSike) 479 prv := NewPrivateKey(v.id, KeyVariantSike) 480 481 if prv.Generate(rand.Reader) != nil { 482 b.FailNow() 483 } 484 prv.GeneratePublicKey(pub) 485 486 var ct [common.MaxCiphertextBsz]byte 487 var ss [common.MaxSharedSecretBsz]byte 488 489 b.ResetTimer() 490 for n := 0; n < b.N; n++ { 491 v.kem.Reset() 492 _ = v.kem.Encapsulate(ct[:], ss[:], pub) 493 } 494 } 495 496 func benchmarkDecaps(b *testing.B, v sikeVec) { 497 var ct [common.MaxCiphertextBsz]byte 498 var ss [common.MaxSharedSecretBsz]byte 499 ssBsz := v.kem.SharedSecretSize() 500 501 pkA := NewPublicKey(v.id, KeyVariantSike) 502 prvA := NewPrivateKey(v.id, KeyVariantSike) 503 pkB := NewPublicKey(v.id, KeyVariantSike) 504 prvB := NewPrivateKey(v.id, KeyVariantSike) 505 506 if prvA.Generate(rand.Reader) != nil || prvB.Generate(rand.Reader) != nil { 507 b.FailNow() 508 } 509 510 prvA.GeneratePublicKey(pkA) 511 prvB.GeneratePublicKey(pkB) 512 513 v.kem.Reset() 514 err := v.kem.Encapsulate(ct[:], ss[:], pkA) 515 if err != nil { 516 b.FailNow() 517 } 518 519 ctSlc := ct[:v.kem.CiphertextSize()] 520 521 b.ResetTimer() 522 for n := 0; n < b.N; n++ { 523 v.kem.Reset() 524 _ = v.kem.Decapsulate(ss[:ssBsz], prvA, pkB, ctSlc) 525 } 526 } 527 528 func BenchmarkKeygen(b *testing.B) { benchSike(b, &tdataSike, benchKeygen) } 529 func BenchmarkEncaps(b *testing.B) { benchSike(b, &tdataSike, benchmarkEncaps) } 530 func BenchmarkDecaps(b *testing.B) { benchSike(b, &tdataSike, benchmarkDecaps) } 531 532 func ExampleKEM() { 533 // Alice's key pair 534 prvA := NewPrivateKey(Fp503, KeyVariantSike) 535 pubA := NewPublicKey(Fp503, KeyVariantSike) 536 // Bob's key pair 537 prvB := NewPrivateKey(Fp503, KeyVariantSike) 538 pubB := NewPublicKey(Fp503, KeyVariantSike) 539 // Generate keypair for Alice 540 err := prvA.Generate(rand.Reader) 541 if err != nil { 542 panic(err) 543 } 544 prvA.GeneratePublicKey(pubA) 545 // Generate keypair for Bob 546 err = prvB.Generate(rand.Reader) 547 if err != nil { 548 panic(err) 549 } 550 prvB.GeneratePublicKey(pubB) 551 // Initialize internal KEM structures 552 kem := NewSike503(rand.Reader) 553 // Create buffers for ciphertext, shared secret received 554 // from encapsulation and shared secret from decapsulation 555 ct := make([]byte, kem.CiphertextSize()) 556 ssE := make([]byte, kem.SharedSecretSize()) 557 ssD := make([]byte, kem.SharedSecretSize()) 558 // Alice performs encapsulation with Bob's public key 559 err = kem.Encapsulate(ct, ssE, pubB) 560 if err != nil { 561 panic(err) 562 } 563 // Bob performs decapsulation with his key pair 564 err = kem.Decapsulate(ssD, prvB, pubB, ct) 565 if err != nil { 566 panic(err) 567 } 568 fmt.Printf("%t\n", bytes.Equal(ssE, ssD)) 569 570 // Bob performs encapsulation with Alice's public key 571 err = kem.Encapsulate(ct, ssE, pubA) 572 if err != nil { 573 panic(err) 574 } 575 // Alice performs decapsulation with hers key pair 576 err = kem.Decapsulate(ssD, prvA, pubA, ct) 577 if err != nil { 578 panic(err) 579 } 580 fmt.Printf("%t\n", bytes.Equal(ssE, ssD)) 581 582 // Output: 583 // true 584 // true 585 }