github.com/digdeepmining/go-atheios@v1.5.13-0.20180902133602-d5687a2e6f43/crypto/ecies/ecies_test.go (about) 1 // Copyright (c) 2013 Kyle Isom <kyle@tyrfingr.is> 2 // Copyright (c) 2012 The Go Authors. All rights reserved. 3 // 4 // Redistribution and use in source and binary forms, with or without 5 // modification, are permitted provided that the following conditions are 6 // met: 7 // 8 // * Redistributions of source code must retain the above copyright 9 // notice, this list of conditions and the following disclaimer. 10 // * Redistributions in binary form must reproduce the above 11 // copyright notice, this list of conditions and the following disclaimer 12 // in the documentation and/or other materials provided with the 13 // distribution. 14 // * Neither the name of Google Inc. nor the names of its 15 // contributors may be used to endorse or promote products derived from 16 // this software without specific prior written permission. 17 // 18 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 19 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 20 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 21 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 22 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 23 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 24 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 25 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 26 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 28 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 30 package ecies 31 32 import ( 33 "bytes" 34 "crypto/ecdsa" 35 "crypto/elliptic" 36 "crypto/rand" 37 "crypto/sha256" 38 "encoding/hex" 39 "flag" 40 "fmt" 41 "io/ioutil" 42 "math/big" 43 "testing" 44 45 "github.com/atheioschain/go-atheios/crypto/secp256k1" 46 ) 47 48 var dumpEnc bool 49 50 func init() { 51 flDump := flag.Bool("dump", false, "write encrypted test message to file") 52 flag.Parse() 53 dumpEnc = *flDump 54 } 55 56 // Ensure the KDF generates appropriately sized keys. 57 func TestKDF(t *testing.T) { 58 msg := []byte("Hello, world") 59 h := sha256.New() 60 61 k, err := concatKDF(h, msg, nil, 64) 62 if err != nil { 63 fmt.Println(err.Error()) 64 t.FailNow() 65 } 66 if len(k) != 64 { 67 fmt.Printf("KDF: generated key is the wrong size (%d instead of 64\n", 68 len(k)) 69 t.FailNow() 70 } 71 } 72 73 var ErrBadSharedKeys = fmt.Errorf("ecies: shared keys don't match") 74 75 // cmpParams compares a set of ECIES parameters. We assume, as per the 76 // docs, that AES is the only supported symmetric encryption algorithm. 77 func cmpParams(p1, p2 *ECIESParams) bool { 78 if p1.hashAlgo != p2.hashAlgo { 79 return false 80 } else if p1.KeyLen != p2.KeyLen { 81 return false 82 } else if p1.BlockSize != p2.BlockSize { 83 return false 84 } 85 return true 86 } 87 88 // cmpPublic returns true if the two public keys represent the same pojnt. 89 func cmpPublic(pub1, pub2 PublicKey) bool { 90 if pub1.X == nil || pub1.Y == nil { 91 fmt.Println(ErrInvalidPublicKey.Error()) 92 return false 93 } 94 if pub2.X == nil || pub2.Y == nil { 95 fmt.Println(ErrInvalidPublicKey.Error()) 96 return false 97 } 98 pub1Out := elliptic.Marshal(pub1.Curve, pub1.X, pub1.Y) 99 pub2Out := elliptic.Marshal(pub2.Curve, pub2.X, pub2.Y) 100 101 return bytes.Equal(pub1Out, pub2Out) 102 } 103 104 // cmpPrivate returns true if the two private keys are the same. 105 func cmpPrivate(prv1, prv2 *PrivateKey) bool { 106 if prv1 == nil || prv1.D == nil { 107 return false 108 } else if prv2 == nil || prv2.D == nil { 109 return false 110 } else if prv1.D.Cmp(prv2.D) != 0 { 111 return false 112 } else { 113 return cmpPublic(prv1.PublicKey, prv2.PublicKey) 114 } 115 } 116 117 // Validate the ECDH component. 118 func TestSharedKey(t *testing.T) { 119 prv1, err := GenerateKey(rand.Reader, DefaultCurve, nil) 120 if err != nil { 121 fmt.Println(err.Error()) 122 t.FailNow() 123 } 124 skLen := MaxSharedKeyLength(&prv1.PublicKey) / 2 125 126 prv2, err := GenerateKey(rand.Reader, DefaultCurve, nil) 127 if err != nil { 128 fmt.Println(err.Error()) 129 t.FailNow() 130 } 131 132 sk1, err := prv1.GenerateShared(&prv2.PublicKey, skLen, skLen) 133 if err != nil { 134 fmt.Println(err.Error()) 135 t.FailNow() 136 } 137 138 sk2, err := prv2.GenerateShared(&prv1.PublicKey, skLen, skLen) 139 if err != nil { 140 fmt.Println(err.Error()) 141 t.FailNow() 142 } 143 144 if !bytes.Equal(sk1, sk2) { 145 fmt.Println(ErrBadSharedKeys.Error()) 146 t.FailNow() 147 } 148 } 149 150 func TestSharedKeyPadding(t *testing.T) { 151 // sanity checks 152 prv0 := hexKey("1adf5c18167d96a1f9a0b1ef63be8aa27eaf6032c233b2b38f7850cf5b859fd9") 153 prv1 := hexKey("97a076fc7fcd9208240668e31c9abee952cbb6e375d1b8febc7499d6e16f1a") 154 x0, _ := new(big.Int).SetString("1a8ed022ff7aec59dc1b440446bdda5ff6bcb3509a8b109077282b361efffbd8", 16) 155 x1, _ := new(big.Int).SetString("6ab3ac374251f638d0abb3ef596d1dc67955b507c104e5f2009724812dc027b8", 16) 156 y0, _ := new(big.Int).SetString("e040bd480b1deccc3bc40bd5b1fdcb7bfd352500b477cb9471366dbd4493f923", 16) 157 y1, _ := new(big.Int).SetString("8ad915f2b503a8be6facab6588731fefeb584fd2dfa9a77a5e0bba1ec439e4fa", 16) 158 159 if prv0.PublicKey.X.Cmp(x0) != 0 { 160 t.Errorf("mismatched prv0.X:\nhave: %x\nwant: %x\n", prv0.PublicKey.X.Bytes(), x0.Bytes()) 161 } 162 if prv0.PublicKey.Y.Cmp(y0) != 0 { 163 t.Errorf("mismatched prv0.Y:\nhave: %x\nwant: %x\n", prv0.PublicKey.Y.Bytes(), y0.Bytes()) 164 } 165 if prv1.PublicKey.X.Cmp(x1) != 0 { 166 t.Errorf("mismatched prv1.X:\nhave: %x\nwant: %x\n", prv1.PublicKey.X.Bytes(), x1.Bytes()) 167 } 168 if prv1.PublicKey.Y.Cmp(y1) != 0 { 169 t.Errorf("mismatched prv1.Y:\nhave: %x\nwant: %x\n", prv1.PublicKey.Y.Bytes(), y1.Bytes()) 170 } 171 172 // test shared secret generation 173 sk1, err := prv0.GenerateShared(&prv1.PublicKey, 16, 16) 174 if err != nil { 175 fmt.Println(err.Error()) 176 } 177 178 sk2, err := prv1.GenerateShared(&prv0.PublicKey, 16, 16) 179 if err != nil { 180 t.Fatal(err.Error()) 181 } 182 183 if !bytes.Equal(sk1, sk2) { 184 t.Fatal(ErrBadSharedKeys.Error()) 185 } 186 } 187 188 // Verify that the key generation code fails when too much key data is 189 // requested. 190 func TestTooBigSharedKey(t *testing.T) { 191 prv1, err := GenerateKey(rand.Reader, DefaultCurve, nil) 192 if err != nil { 193 fmt.Println(err.Error()) 194 t.FailNow() 195 } 196 197 prv2, err := GenerateKey(rand.Reader, DefaultCurve, nil) 198 if err != nil { 199 fmt.Println(err.Error()) 200 t.FailNow() 201 } 202 203 _, err = prv1.GenerateShared(&prv2.PublicKey, 32, 32) 204 if err != ErrSharedKeyTooBig { 205 fmt.Println("ecdh: shared key should be too large for curve") 206 t.FailNow() 207 } 208 209 _, err = prv2.GenerateShared(&prv1.PublicKey, 32, 32) 210 if err != ErrSharedKeyTooBig { 211 fmt.Println("ecdh: shared key should be too large for curve") 212 t.FailNow() 213 } 214 } 215 216 // Ensure a public key can be successfully marshalled and unmarshalled, and 217 // that the decoded key is the same as the original. 218 func TestMarshalPublic(t *testing.T) { 219 prv, err := GenerateKey(rand.Reader, DefaultCurve, nil) 220 if err != nil { 221 t.Fatalf("GenerateKey error: %s", err) 222 } 223 224 out, err := MarshalPublic(&prv.PublicKey) 225 if err != nil { 226 t.Fatalf("MarshalPublic error: %s", err) 227 } 228 229 pub, err := UnmarshalPublic(out) 230 if err != nil { 231 t.Fatalf("UnmarshalPublic error: %s", err) 232 } 233 234 if !cmpPublic(prv.PublicKey, *pub) { 235 t.Fatal("ecies: failed to unmarshal public key") 236 } 237 } 238 239 // Ensure that a private key can be encoded into DER format, and that 240 // the resulting key is properly parsed back into a public key. 241 func TestMarshalPrivate(t *testing.T) { 242 prv, err := GenerateKey(rand.Reader, DefaultCurve, nil) 243 if err != nil { 244 fmt.Println(err.Error()) 245 t.FailNow() 246 } 247 248 out, err := MarshalPrivate(prv) 249 if err != nil { 250 fmt.Println(err.Error()) 251 t.FailNow() 252 } 253 254 if dumpEnc { 255 ioutil.WriteFile("test.out", out, 0644) 256 } 257 258 prv2, err := UnmarshalPrivate(out) 259 if err != nil { 260 fmt.Println(err.Error()) 261 t.FailNow() 262 } 263 264 if !cmpPrivate(prv, prv2) { 265 fmt.Println("ecdh: private key import failed") 266 t.FailNow() 267 } 268 } 269 270 // Ensure that a private key can be successfully encoded to PEM format, and 271 // the resulting key is properly parsed back in. 272 func TestPrivatePEM(t *testing.T) { 273 prv, err := GenerateKey(rand.Reader, DefaultCurve, nil) 274 if err != nil { 275 fmt.Println(err.Error()) 276 t.FailNow() 277 } 278 279 out, err := ExportPrivatePEM(prv) 280 if err != nil { 281 fmt.Println(err.Error()) 282 t.FailNow() 283 } 284 285 if dumpEnc { 286 ioutil.WriteFile("test.key", out, 0644) 287 } 288 289 prv2, err := ImportPrivatePEM(out) 290 if err != nil { 291 fmt.Println(err.Error()) 292 t.FailNow() 293 } else if !cmpPrivate(prv, prv2) { 294 fmt.Println("ecdh: import from PEM failed") 295 t.FailNow() 296 } 297 } 298 299 // Ensure that a public key can be successfully encoded to PEM format, and 300 // the resulting key is properly parsed back in. 301 func TestPublicPEM(t *testing.T) { 302 prv, err := GenerateKey(rand.Reader, DefaultCurve, nil) 303 if err != nil { 304 fmt.Println(err.Error()) 305 t.FailNow() 306 } 307 308 out, err := ExportPublicPEM(&prv.PublicKey) 309 if err != nil { 310 fmt.Println(err.Error()) 311 t.FailNow() 312 } 313 314 if dumpEnc { 315 ioutil.WriteFile("test.pem", out, 0644) 316 } 317 318 pub2, err := ImportPublicPEM(out) 319 if err != nil { 320 fmt.Println(err.Error()) 321 t.FailNow() 322 } else if !cmpPublic(prv.PublicKey, *pub2) { 323 fmt.Println("ecdh: import from PEM failed") 324 t.FailNow() 325 } 326 } 327 328 // Benchmark the generation of P256 keys. 329 func BenchmarkGenerateKeyP256(b *testing.B) { 330 for i := 0; i < b.N; i++ { 331 if _, err := GenerateKey(rand.Reader, elliptic.P256(), nil); err != nil { 332 fmt.Println(err.Error()) 333 b.FailNow() 334 } 335 } 336 } 337 338 // Benchmark the generation of P256 shared keys. 339 func BenchmarkGenSharedKeyP256(b *testing.B) { 340 prv, err := GenerateKey(rand.Reader, elliptic.P256(), nil) 341 if err != nil { 342 fmt.Println(err.Error()) 343 b.FailNow() 344 } 345 b.ResetTimer() 346 for i := 0; i < b.N; i++ { 347 _, err := prv.GenerateShared(&prv.PublicKey, 16, 16) 348 if err != nil { 349 fmt.Println(err.Error()) 350 b.FailNow() 351 } 352 } 353 } 354 355 // Benchmark the generation of S256 shared keys. 356 func BenchmarkGenSharedKeyS256(b *testing.B) { 357 prv, err := GenerateKey(rand.Reader, secp256k1.S256(), nil) 358 if err != nil { 359 fmt.Println(err.Error()) 360 b.FailNow() 361 } 362 b.ResetTimer() 363 for i := 0; i < b.N; i++ { 364 _, err := prv.GenerateShared(&prv.PublicKey, 16, 16) 365 if err != nil { 366 fmt.Println(err.Error()) 367 b.FailNow() 368 } 369 } 370 } 371 372 // Verify that an encrypted message can be successfully decrypted. 373 func TestEncryptDecrypt(t *testing.T) { 374 prv1, err := GenerateKey(rand.Reader, DefaultCurve, nil) 375 if err != nil { 376 fmt.Println(err.Error()) 377 t.FailNow() 378 } 379 380 prv2, err := GenerateKey(rand.Reader, DefaultCurve, nil) 381 if err != nil { 382 fmt.Println(err.Error()) 383 t.FailNow() 384 } 385 386 message := []byte("Hello, world.") 387 ct, err := Encrypt(rand.Reader, &prv2.PublicKey, message, nil, nil) 388 if err != nil { 389 fmt.Println(err.Error()) 390 t.FailNow() 391 } 392 393 pt, err := prv2.Decrypt(rand.Reader, ct, nil, nil) 394 if err != nil { 395 fmt.Println(err.Error()) 396 t.FailNow() 397 } 398 399 if !bytes.Equal(pt, message) { 400 fmt.Println("ecies: plaintext doesn't match message") 401 t.FailNow() 402 } 403 404 _, err = prv1.Decrypt(rand.Reader, ct, nil, nil) 405 if err == nil { 406 fmt.Println("ecies: encryption should not have succeeded") 407 t.FailNow() 408 } 409 } 410 411 func TestDecryptShared2(t *testing.T) { 412 prv, err := GenerateKey(rand.Reader, DefaultCurve, nil) 413 if err != nil { 414 t.Fatal(err) 415 } 416 message := []byte("Hello, world.") 417 shared2 := []byte("shared data 2") 418 ct, err := Encrypt(rand.Reader, &prv.PublicKey, message, nil, shared2) 419 if err != nil { 420 t.Fatal(err) 421 } 422 423 // Check that decrypting with correct shared data works. 424 pt, err := prv.Decrypt(rand.Reader, ct, nil, shared2) 425 if err != nil { 426 t.Fatal(err) 427 } 428 if !bytes.Equal(pt, message) { 429 t.Fatal("ecies: plaintext doesn't match message") 430 } 431 432 // Decrypting without shared data or incorrect shared data fails. 433 if _, err = prv.Decrypt(rand.Reader, ct, nil, nil); err == nil { 434 t.Fatal("ecies: decrypting without shared data didn't fail") 435 } 436 if _, err = prv.Decrypt(rand.Reader, ct, nil, []byte("garbage")); err == nil { 437 t.Fatal("ecies: decrypting with incorrect shared data didn't fail") 438 } 439 } 440 441 // TestMarshalEncryption validates the encode/decode produces a valid 442 // ECIES encryption key. 443 func TestMarshalEncryption(t *testing.T) { 444 prv1, err := GenerateKey(rand.Reader, DefaultCurve, nil) 445 if err != nil { 446 fmt.Println(err.Error()) 447 t.FailNow() 448 } 449 450 out, err := MarshalPrivate(prv1) 451 if err != nil { 452 fmt.Println(err.Error()) 453 t.FailNow() 454 } 455 456 prv2, err := UnmarshalPrivate(out) 457 if err != nil { 458 fmt.Println(err.Error()) 459 t.FailNow() 460 } 461 462 message := []byte("Hello, world.") 463 ct, err := Encrypt(rand.Reader, &prv2.PublicKey, message, nil, nil) 464 if err != nil { 465 fmt.Println(err.Error()) 466 t.FailNow() 467 } 468 469 pt, err := prv2.Decrypt(rand.Reader, ct, nil, nil) 470 if err != nil { 471 fmt.Println(err.Error()) 472 t.FailNow() 473 } 474 475 if !bytes.Equal(pt, message) { 476 fmt.Println("ecies: plaintext doesn't match message") 477 t.FailNow() 478 } 479 480 _, err = prv1.Decrypt(rand.Reader, ct, nil, nil) 481 if err != nil { 482 fmt.Println(err.Error()) 483 t.FailNow() 484 } 485 486 } 487 488 type testCase struct { 489 Curve elliptic.Curve 490 Name string 491 Expected bool 492 } 493 494 var testCases = []testCase{ 495 { 496 Curve: elliptic.P256(), 497 Name: "P256", 498 Expected: true, 499 }, 500 { 501 Curve: elliptic.P384(), 502 Name: "P384", 503 Expected: true, 504 }, 505 { 506 Curve: elliptic.P521(), 507 Name: "P521", 508 Expected: true, 509 }, 510 } 511 512 // Test parameter selection for each curve, and that P224 fails automatic 513 // parameter selection (see README for a discussion of P224). Ensures that 514 // selecting a set of parameters automatically for the given curve works. 515 func TestParamSelection(t *testing.T) { 516 for _, c := range testCases { 517 testParamSelection(t, c) 518 } 519 } 520 521 func testParamSelection(t *testing.T, c testCase) { 522 params := ParamsFromCurve(c.Curve) 523 if params == nil && c.Expected { 524 fmt.Printf("%s (%s)\n", ErrInvalidParams.Error(), c.Name) 525 t.FailNow() 526 } else if params != nil && !c.Expected { 527 fmt.Printf("ecies: parameters should be invalid (%s)\n", 528 c.Name) 529 t.FailNow() 530 } 531 532 prv1, err := GenerateKey(rand.Reader, DefaultCurve, nil) 533 if err != nil { 534 fmt.Printf("%s (%s)\n", err.Error(), c.Name) 535 t.FailNow() 536 } 537 538 prv2, err := GenerateKey(rand.Reader, DefaultCurve, nil) 539 if err != nil { 540 fmt.Printf("%s (%s)\n", err.Error(), c.Name) 541 t.FailNow() 542 } 543 544 message := []byte("Hello, world.") 545 ct, err := Encrypt(rand.Reader, &prv2.PublicKey, message, nil, nil) 546 if err != nil { 547 fmt.Printf("%s (%s)\n", err.Error(), c.Name) 548 t.FailNow() 549 } 550 551 pt, err := prv2.Decrypt(rand.Reader, ct, nil, nil) 552 if err != nil { 553 fmt.Printf("%s (%s)\n", err.Error(), c.Name) 554 t.FailNow() 555 } 556 557 if !bytes.Equal(pt, message) { 558 fmt.Printf("ecies: plaintext doesn't match message (%s)\n", 559 c.Name) 560 t.FailNow() 561 } 562 563 _, err = prv1.Decrypt(rand.Reader, ct, nil, nil) 564 if err == nil { 565 fmt.Printf("ecies: encryption should not have succeeded (%s)\n", 566 c.Name) 567 t.FailNow() 568 } 569 570 } 571 572 // Ensure that the basic public key validation in the decryption operation 573 // works. 574 func TestBasicKeyValidation(t *testing.T) { 575 badBytes := []byte{0, 1, 5, 6, 7, 8, 9} 576 577 prv, err := GenerateKey(rand.Reader, DefaultCurve, nil) 578 if err != nil { 579 fmt.Println(err.Error()) 580 t.FailNow() 581 } 582 583 message := []byte("Hello, world.") 584 ct, err := Encrypt(rand.Reader, &prv.PublicKey, message, nil, nil) 585 if err != nil { 586 fmt.Println(err.Error()) 587 t.FailNow() 588 } 589 590 for _, b := range badBytes { 591 ct[0] = b 592 _, err := prv.Decrypt(rand.Reader, ct, nil, nil) 593 if err != ErrInvalidPublicKey { 594 fmt.Println("ecies: validated an invalid key") 595 t.FailNow() 596 } 597 } 598 } 599 600 // Verify GenerateShared against static values - useful when 601 // debugging changes in underlying libs 602 func TestSharedKeyStatic(t *testing.T) { 603 prv1 := hexKey("7ebbc6a8358bc76dd73ebc557056702c8cfc34e5cfcd90eb83af0347575fd2ad") 604 prv2 := hexKey("6a3d6396903245bba5837752b9e0348874e72db0c4e11e9c485a81b4ea4353b9") 605 606 skLen := MaxSharedKeyLength(&prv1.PublicKey) / 2 607 608 sk1, err := prv1.GenerateShared(&prv2.PublicKey, skLen, skLen) 609 if err != nil { 610 fmt.Println(err.Error()) 611 t.FailNow() 612 } 613 614 sk2, err := prv2.GenerateShared(&prv1.PublicKey, skLen, skLen) 615 if err != nil { 616 fmt.Println(err.Error()) 617 t.FailNow() 618 } 619 620 if !bytes.Equal(sk1, sk2) { 621 fmt.Println(ErrBadSharedKeys.Error()) 622 t.FailNow() 623 } 624 625 sk, _ := hex.DecodeString("167ccc13ac5e8a26b131c3446030c60fbfac6aa8e31149d0869f93626a4cdf62") 626 if !bytes.Equal(sk1, sk) { 627 t.Fatalf("shared secret mismatch: want: %x have: %x", sk, sk1) 628 } 629 } 630 631 // TODO: remove after refactoring packages crypto and crypto/ecies 632 func hexKey(prv string) *PrivateKey { 633 priv := new(ecdsa.PrivateKey) 634 priv.PublicKey.Curve = secp256k1.S256() 635 priv.D, _ = new(big.Int).SetString(prv, 16) 636 priv.PublicKey.X, priv.PublicKey.Y = secp256k1.S256().ScalarBaseMult(priv.D.Bytes()) 637 return ImportECDSA(priv) 638 }