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