gitlab.com/aquachain/aquachain@v1.17.16-rc3.0.20221018032414-e3ddf1e1c055/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 "math/big" 41 "testing" 42 43 "gitlab.com/aquachain/aquachain/crypto" 44 ) 45 46 var dumpEnc bool 47 48 func Init() { 49 flDump := flag.Bool("dump", false, "write encrypted test message to file") 50 flag.Parse() 51 dumpEnc = *flDump 52 } 53 54 func TestA_Init(t *testing.T) { 55 Init() 56 } 57 58 // Ensure the KDF generates appropriately sized keys. 59 func TestKDF(t *testing.T) { 60 msg := []byte("Hello, world") 61 h := sha256.New() 62 63 k, err := concatKDF(h, msg, nil, 64) 64 if err != nil { 65 fmt.Println(err.Error()) 66 t.FailNow() 67 } 68 if len(k) != 64 { 69 fmt.Printf("KDF: generated key is the wrong size (%d instead of 64\n", len(k)) 70 t.FailNow() 71 } 72 } 73 74 var ErrBadSharedKeys = fmt.Errorf("ecies: shared keys don't match") 75 76 // cmpParams compares a set of ECIES parameters. We assume, as per the 77 // docs, that AES is the only supported symmetric encryption algorithm. 78 func cmpParams(p1, p2 *ECIESParams) bool { 79 return p1.hashAlgo == p2.hashAlgo && 80 p1.KeyLen == p2.KeyLen && 81 p1.BlockSize == p2.BlockSize 82 } 83 84 // Validate the ECDH component. 85 func TestSharedKey(t *testing.T) { 86 prv1, err := GenerateKey(rand.Reader, DefaultCurve, nil) 87 if err != nil { 88 fmt.Println(err.Error()) 89 t.FailNow() 90 } 91 skLen := MaxSharedKeyLength(&prv1.PublicKey) / 2 92 93 prv2, err := GenerateKey(rand.Reader, DefaultCurve, nil) 94 if err != nil { 95 fmt.Println(err.Error()) 96 t.FailNow() 97 } 98 99 sk1, err := prv1.GenerateShared(&prv2.PublicKey, skLen, skLen) 100 if err != nil { 101 fmt.Println(err.Error()) 102 t.FailNow() 103 } 104 105 sk2, err := prv2.GenerateShared(&prv1.PublicKey, skLen, skLen) 106 if err != nil { 107 fmt.Println(err.Error()) 108 t.FailNow() 109 } 110 111 if !bytes.Equal(sk1, sk2) { 112 fmt.Println(ErrBadSharedKeys.Error()) 113 t.FailNow() 114 } 115 } 116 117 func TestSharedKeyPadding(t *testing.T) { 118 // sanity checks 119 prv0 := hexKey("1adf5c18167d96a1f9a0b1ef63be8aa27eaf6032c233b2b38f7850cf5b859fd9") 120 prv1 := hexKey("0097a076fc7fcd9208240668e31c9abee952cbb6e375d1b8febc7499d6e16f1a") 121 x0, _ := new(big.Int).SetString("1a8ed022ff7aec59dc1b440446bdda5ff6bcb3509a8b109077282b361efffbd8", 16) 122 x1, _ := new(big.Int).SetString("6ab3ac374251f638d0abb3ef596d1dc67955b507c104e5f2009724812dc027b8", 16) 123 y0, _ := new(big.Int).SetString("e040bd480b1deccc3bc40bd5b1fdcb7bfd352500b477cb9471366dbd4493f923", 16) 124 y1, _ := new(big.Int).SetString("8ad915f2b503a8be6facab6588731fefeb584fd2dfa9a77a5e0bba1ec439e4fa", 16) 125 126 if prv0.PublicKey.X.Cmp(x0) != 0 { 127 t.Errorf("mismatched prv0.X:\nhave: %x\nwant: %x\n", prv0.PublicKey.X.Bytes(), x0.Bytes()) 128 } 129 if prv0.PublicKey.Y.Cmp(y0) != 0 { 130 t.Errorf("mismatched prv0.Y:\nhave: %x\nwant: %x\n", prv0.PublicKey.Y.Bytes(), y0.Bytes()) 131 } 132 if prv1.PublicKey.X.Cmp(x1) != 0 { 133 t.Errorf("mismatched prv1.X:\nhave: %x\nwant: %x\n", prv1.PublicKey.X.Bytes(), x1.Bytes()) 134 } 135 if prv1.PublicKey.Y.Cmp(y1) != 0 { 136 t.Errorf("mismatched prv1.Y:\nhave: %x\nwant: %x\n", prv1.PublicKey.Y.Bytes(), y1.Bytes()) 137 } 138 139 // test shared secret generation 140 sk1, err := prv0.GenerateShared(&prv1.PublicKey, 16, 16) 141 if err != nil { 142 fmt.Println(err.Error()) 143 } 144 145 sk2, err := prv1.GenerateShared(&prv0.PublicKey, 16, 16) 146 if err != nil { 147 t.Fatal(err.Error()) 148 } 149 150 if !bytes.Equal(sk1, sk2) { 151 t.Fatal(ErrBadSharedKeys.Error()) 152 } 153 } 154 155 // Verify that the key generation code fails when too much key data is 156 // requested. 157 func TestTooBigSharedKey(t *testing.T) { 158 prv1, err := GenerateKey(rand.Reader, DefaultCurve, nil) 159 if err != nil { 160 fmt.Println(err.Error()) 161 t.FailNow() 162 } 163 164 prv2, err := GenerateKey(rand.Reader, DefaultCurve, nil) 165 if err != nil { 166 fmt.Println(err.Error()) 167 t.FailNow() 168 } 169 170 _, err = prv1.GenerateShared(&prv2.PublicKey, 32, 32) 171 if err != ErrSharedKeyTooBig { 172 fmt.Println("ecdh: shared key should be too large for curve") 173 t.FailNow() 174 } 175 176 _, err = prv2.GenerateShared(&prv1.PublicKey, 32, 32) 177 if err != ErrSharedKeyTooBig { 178 fmt.Println("ecdh: shared key should be too large for curve") 179 t.FailNow() 180 } 181 } 182 183 // Benchmark the generation of P256 keys. 184 func BenchmarkGenerateKeyP256(b *testing.B) { 185 for i := 0; i < b.N; i++ { 186 if _, err := GenerateKey(rand.Reader, elliptic.P256(), nil); err != nil { 187 fmt.Println(err.Error()) 188 b.FailNow() 189 } 190 } 191 } 192 193 // Benchmark the generation of P256 shared keys. 194 func BenchmarkGenSharedKeyP256(b *testing.B) { 195 prv, err := GenerateKey(rand.Reader, elliptic.P256(), nil) 196 if err != nil { 197 fmt.Println(err.Error()) 198 b.FailNow() 199 } 200 b.ResetTimer() 201 for i := 0; i < b.N; i++ { 202 _, err := prv.GenerateShared(&prv.PublicKey, 16, 16) 203 if err != nil { 204 fmt.Println(err.Error()) 205 b.FailNow() 206 } 207 } 208 } 209 210 // Benchmark the generation of S256 shared keys. 211 func BenchmarkGenSharedKeyS256(b *testing.B) { 212 prv, err := GenerateKey(rand.Reader, crypto.S256(), nil) 213 if err != nil { 214 fmt.Println(err.Error()) 215 b.FailNow() 216 } 217 b.ResetTimer() 218 for i := 0; i < b.N; i++ { 219 _, err := prv.GenerateShared(&prv.PublicKey, 16, 16) 220 if err != nil { 221 fmt.Println(err.Error()) 222 b.FailNow() 223 } 224 } 225 } 226 227 // Verify that an encrypted message can be successfully decrypted. 228 func TestEncryptDecrypt(t *testing.T) { 229 prv1, err := GenerateKey(rand.Reader, DefaultCurve, nil) 230 if err != nil { 231 fmt.Println(err.Error()) 232 t.FailNow() 233 } 234 235 prv2, err := GenerateKey(rand.Reader, DefaultCurve, nil) 236 if err != nil { 237 fmt.Println(err.Error()) 238 t.FailNow() 239 } 240 241 message := []byte("Hello, world.") 242 ct, err := Encrypt(rand.Reader, &prv2.PublicKey, message, nil, nil) 243 if err != nil { 244 fmt.Println(err.Error()) 245 t.FailNow() 246 } 247 248 pt, err := prv2.Decrypt(ct, nil, nil) 249 if err != nil { 250 fmt.Println(err.Error()) 251 t.FailNow() 252 } 253 254 if !bytes.Equal(pt, message) { 255 fmt.Println("ecies: plaintext doesn't match message") 256 t.FailNow() 257 } 258 259 _, err = prv1.Decrypt(ct, nil, nil) 260 if err == nil { 261 fmt.Println("ecies: encryption should not have succeeded") 262 t.FailNow() 263 } 264 } 265 266 func TestDecryptShared2(t *testing.T) { 267 prv, err := GenerateKey(rand.Reader, DefaultCurve, nil) 268 if err != nil { 269 t.Fatal(err) 270 } 271 message := []byte("Hello, world.") 272 shared2 := []byte("shared data 2") 273 ct, err := Encrypt(rand.Reader, &prv.PublicKey, message, nil, shared2) 274 if err != nil { 275 t.Fatal(err) 276 } 277 278 // Check that decrypting with correct shared data works. 279 pt, err := prv.Decrypt(ct, nil, shared2) 280 if err != nil { 281 t.Fatal(err) 282 } 283 if !bytes.Equal(pt, message) { 284 t.Fatal("ecies: plaintext doesn't match message") 285 } 286 287 // Decrypting without shared data or incorrect shared data fails. 288 if _, err = prv.Decrypt(ct, nil, nil); err == nil { 289 t.Fatal("ecies: decrypting without shared data didn't fail") 290 } 291 if _, err = prv.Decrypt(ct, nil, []byte("garbage")); err == nil { 292 t.Fatal("ecies: decrypting with incorrect shared data didn't fail") 293 } 294 } 295 296 type testCase struct { 297 Curve elliptic.Curve 298 Name string 299 Expected *ECIESParams 300 } 301 302 var testCases = []testCase{ 303 { 304 Curve: elliptic.P256(), 305 Name: "P256", 306 Expected: ECIES_AES128_SHA256, 307 }, 308 { 309 Curve: elliptic.P384(), 310 Name: "P384", 311 Expected: ECIES_AES256_SHA384, 312 }, 313 { 314 Curve: elliptic.P521(), 315 Name: "P521", 316 Expected: ECIES_AES256_SHA512, 317 }, 318 } 319 320 // Test parameter selection for each curve, and that P224 fails automatic 321 // parameter selection (see README for a discussion of P224). Ensures that 322 // selecting a set of parameters automatically for the given curve works. 323 func TestParamSelection(t *testing.T) { 324 for _, c := range testCases { 325 testParamSelection(t, c) 326 } 327 } 328 329 func testParamSelection(t *testing.T, c testCase) { 330 params := ParamsFromCurve(c.Curve) 331 if params == nil && c.Expected != nil { 332 fmt.Printf("%s (%s)\n", ErrInvalidParams.Error(), c.Name) 333 t.FailNow() 334 } else if params != nil && !cmpParams(params, c.Expected) { 335 fmt.Printf("ecies: parameters should be invalid (%s)\n", 336 c.Name) 337 t.FailNow() 338 } 339 340 prv1, err := GenerateKey(rand.Reader, DefaultCurve, nil) 341 if err != nil { 342 fmt.Printf("%s (%s)\n", err.Error(), c.Name) 343 t.FailNow() 344 } 345 346 prv2, err := GenerateKey(rand.Reader, DefaultCurve, nil) 347 if err != nil { 348 fmt.Printf("%s (%s)\n", err.Error(), c.Name) 349 t.FailNow() 350 } 351 352 message := []byte("Hello, world.") 353 ct, err := Encrypt(rand.Reader, &prv2.PublicKey, message, nil, nil) 354 if err != nil { 355 fmt.Printf("%s (%s)\n", err.Error(), c.Name) 356 t.FailNow() 357 } 358 359 pt, err := prv2.Decrypt(ct, nil, nil) 360 if err != nil { 361 fmt.Printf("%s (%s)\n", err.Error(), c.Name) 362 t.FailNow() 363 } 364 365 if !bytes.Equal(pt, message) { 366 fmt.Printf("ecies: plaintext doesn't match message (%s)\n", 367 c.Name) 368 t.FailNow() 369 } 370 371 _, err = prv1.Decrypt(ct, nil, nil) 372 if err == nil { 373 fmt.Printf("ecies: encryption should not have succeeded (%s)\n", 374 c.Name) 375 t.FailNow() 376 } 377 378 } 379 380 // Ensure that the basic public key validation in the decryption operation 381 // works. 382 func TestBasicKeyValidation(t *testing.T) { 383 badBytes := []byte{0, 1, 5, 6, 7, 8, 9} 384 385 prv, err := GenerateKey(rand.Reader, DefaultCurve, nil) 386 if err != nil { 387 fmt.Println(err.Error()) 388 t.FailNow() 389 } 390 391 message := []byte("Hello, world.") 392 ct, err := Encrypt(rand.Reader, &prv.PublicKey, message, nil, nil) 393 if err != nil { 394 fmt.Println(err.Error()) 395 t.FailNow() 396 } 397 398 for _, b := range badBytes { 399 ct[0] = b 400 _, err := prv.Decrypt(ct, nil, nil) 401 if err != ErrInvalidPublicKey { 402 fmt.Println("ecies: validated an invalid key") 403 t.FailNow() 404 } 405 } 406 } 407 408 func TestBox(t *testing.T) { 409 prv1 := hexKey("4b50fa71f5c3eeb8fdc452224b2395af2fcc3d125e06c32c82e048c0559db03f") 410 prv2 := hexKey("d0b043b4c5d657670778242d82d68a29d25d7d711127d17b8e299f156dad361a") 411 pub2 := &prv2.PublicKey 412 413 message := []byte("Hello, world.") 414 ct, err := Encrypt(rand.Reader, pub2, message, nil, nil) 415 if err != nil { 416 t.Fatal(err) 417 } 418 419 pt, err := prv2.Decrypt(ct, nil, nil) 420 if err != nil { 421 t.Fatal(err) 422 } 423 if !bytes.Equal(pt, message) { 424 t.Fatal("ecies: plaintext doesn't match message") 425 } 426 if _, err = prv1.Decrypt(ct, nil, nil); err == nil { 427 t.Fatal("ecies: encryption should not have succeeded") 428 } 429 } 430 431 // Verify GenerateShared against static values - useful when 432 // debugging changes in underlying libs 433 func TestSharedKeyStatic(t *testing.T) { 434 prv1 := hexKey("7ebbc6a8358bc76dd73ebc557056702c8cfc34e5cfcd90eb83af0347575fd2ad") 435 prv2 := hexKey("6a3d6396903245bba5837752b9e0348874e72db0c4e11e9c485a81b4ea4353b9") 436 437 skLen := MaxSharedKeyLength(&prv1.PublicKey) / 2 438 439 sk1, err := prv1.GenerateShared(&prv2.PublicKey, skLen, skLen) 440 if err != nil { 441 fmt.Println(err.Error()) 442 t.FailNow() 443 } 444 445 sk2, err := prv2.GenerateShared(&prv1.PublicKey, skLen, skLen) 446 if err != nil { 447 fmt.Println(err.Error()) 448 t.FailNow() 449 } 450 451 if !bytes.Equal(sk1, sk2) { 452 fmt.Println(ErrBadSharedKeys.Error()) 453 t.FailNow() 454 } 455 456 sk, _ := hex.DecodeString("167ccc13ac5e8a26b131c3446030c60fbfac6aa8e31149d0869f93626a4cdf62") 457 if !bytes.Equal(sk1, sk) { 458 t.Fatalf("shared secret mismatch: want: %x have: %x", sk, sk1) 459 } 460 } 461 462 func hexKey(prv string) *PrivateKey { 463 key, err := crypto.HexToECDSA(prv) 464 if err != nil { 465 panic(err) 466 } 467 return ImportECDSA(key) 468 }