github.com/linapex/ethereum-go-chinese@v0.0.0-20190316121929-f8b7a73c3fa1/crypto/ecies/ecies_test.go (about) 1 2 //<developer> 3 // <name>linapex 曹一峰</name> 4 // <email>linapex@163.com</email> 5 // <wx>superexc</wx> 6 // <qqgroup>128148617</qqgroup> 7 // <url>https://jsq.ink</url> 8 // <role>pku engineer</role> 9 // <date>2019-03-16 19:16:36</date> 10 //</624450085027057664> 11 12 //版权所有(c)2013 Kyle Isom<kyle@tyrfingr.is> 13 //版权所有(c)2012 The Go作者。版权所有。 14 // 15 //以源和二进制形式重新分配和使用,有或无 16 //允许修改,前提是以下条件 17 //遇见: 18 // 19 //*源代码的再分配必须保留上述版权。 20 //注意,此条件列表和以下免责声明。 21 //*二进制形式的再分配必须复制上述内容 22 //版权声明、此条件列表和以下免责声明 23 //在提供的文件和/或其他材料中, 24 //分布。 25 //*无论是谷歌公司的名称还是其 26 //贡献者可用于支持或推广源自 27 //本软件未经事先明确书面许可。 28 // 29 //本软件由版权所有者和贡献者提供。 30 //“原样”和任何明示或暗示的保证,包括但不包括 31 //仅限于对适销性和适用性的暗示保证 32 //不承认特定目的。在任何情况下,版权 33 //所有人或出资人对任何直接、间接、附带的, 34 //特殊、惩戒性或后果性损害(包括但不包括 35 //仅限于采购替代货物或服务;使用损失, 36 //数据或利润;或业务中断),无论如何引起的 37 //责任理论,无论是合同责任、严格责任还是侵权责任。 38 //(包括疏忽或其他)因使用不当而引起的 39 //即使已告知此类损坏的可能性。 40 41 package ecies 42 43 import ( 44 "bytes" 45 "crypto/elliptic" 46 "crypto/rand" 47 "crypto/sha256" 48 "encoding/hex" 49 "flag" 50 "fmt" 51 "math/big" 52 "testing" 53 54 "github.com/ethereum/go-ethereum/crypto" 55 ) 56 57 var dumpEnc bool 58 59 func init() { 60 flDump := flag.Bool("dump", false, "write encrypted test message to file") 61 flag.Parse() 62 dumpEnc = *flDump 63 } 64 65 //确保KDF生成大小适当的密钥。 66 func TestKDF(t *testing.T) { 67 msg := []byte("Hello, world") 68 h := sha256.New() 69 70 k, err := concatKDF(h, msg, nil, 64) 71 if err != nil { 72 fmt.Println(err.Error()) 73 t.FailNow() 74 } 75 if len(k) != 64 { 76 fmt.Printf("KDF: generated key is the wrong size (%d instead of 64\n", len(k)) 77 t.FailNow() 78 } 79 } 80 81 var ErrBadSharedKeys = fmt.Errorf("ecies: shared keys don't match") 82 83 //cmpfarams比较一组ecies参数。我们假设,根据 84 //文档,认为AES是唯一支持的对称加密算法。 85 func cmpParams(p1, p2 *ECIESParams) bool { 86 return p1.hashAlgo == p2.hashAlgo && 87 p1.KeyLen == p2.KeyLen && 88 p1.BlockSize == p2.BlockSize 89 } 90 91 //如果两个公钥表示相同的pojnt,则cmppublic返回true。 92 func cmpPublic(pub1, pub2 PublicKey) bool { 93 if pub1.X == nil || pub1.Y == nil { 94 fmt.Println(ErrInvalidPublicKey.Error()) 95 return false 96 } 97 if pub2.X == nil || pub2.Y == nil { 98 fmt.Println(ErrInvalidPublicKey.Error()) 99 return false 100 } 101 pub1Out := elliptic.Marshal(pub1.Curve, pub1.X, pub1.Y) 102 pub2Out := elliptic.Marshal(pub2.Curve, pub2.X, pub2.Y) 103 104 return bytes.Equal(pub1Out, pub2Out) 105 } 106 107 //如果两个私钥相同,则cmprivate返回true。 108 func cmpPrivate(prv1, prv2 *PrivateKey) bool { 109 if prv1 == nil || prv1.D == nil { 110 return false 111 } else if prv2 == nil || prv2.D == nil { 112 return false 113 } else if prv1.D.Cmp(prv2.D) != 0 { 114 return false 115 } else { 116 return cmpPublic(prv1.PublicKey, prv2.PublicKey) 117 } 118 } 119 120 //验证ECDH组件。 121 func TestSharedKey(t *testing.T) { 122 prv1, err := GenerateKey(rand.Reader, DefaultCurve, nil) 123 if err != nil { 124 fmt.Println(err.Error()) 125 t.FailNow() 126 } 127 skLen := MaxSharedKeyLength(&prv1.PublicKey) / 2 128 129 prv2, err := GenerateKey(rand.Reader, DefaultCurve, nil) 130 if err != nil { 131 fmt.Println(err.Error()) 132 t.FailNow() 133 } 134 135 sk1, err := prv1.GenerateShared(&prv2.PublicKey, skLen, skLen) 136 if err != nil { 137 fmt.Println(err.Error()) 138 t.FailNow() 139 } 140 141 sk2, err := prv2.GenerateShared(&prv1.PublicKey, skLen, skLen) 142 if err != nil { 143 fmt.Println(err.Error()) 144 t.FailNow() 145 } 146 147 if !bytes.Equal(sk1, sk2) { 148 fmt.Println(ErrBadSharedKeys.Error()) 149 t.FailNow() 150 } 151 } 152 153 func TestSharedKeyPadding(t *testing.T) { 154 //清醒检查 155 prv0 := hexKey("1adf5c18167d96a1f9a0b1ef63be8aa27eaf6032c233b2b38f7850cf5b859fd9") 156 prv1 := hexKey("0097a076fc7fcd9208240668e31c9abee952cbb6e375d1b8febc7499d6e16f1a") 157 x0, _ := new(big.Int).SetString("1a8ed022ff7aec59dc1b440446bdda5ff6bcb3509a8b109077282b361efffbd8", 16) 158 x1, _ := new(big.Int).SetString("6ab3ac374251f638d0abb3ef596d1dc67955b507c104e5f2009724812dc027b8", 16) 159 y0, _ := new(big.Int).SetString("e040bd480b1deccc3bc40bd5b1fdcb7bfd352500b477cb9471366dbd4493f923", 16) 160 y1, _ := new(big.Int).SetString("8ad915f2b503a8be6facab6588731fefeb584fd2dfa9a77a5e0bba1ec439e4fa", 16) 161 162 if prv0.PublicKey.X.Cmp(x0) != 0 { 163 t.Errorf("mismatched prv0.X:\nhave: %x\nwant: %x\n", prv0.PublicKey.X.Bytes(), x0.Bytes()) 164 } 165 if prv0.PublicKey.Y.Cmp(y0) != 0 { 166 t.Errorf("mismatched prv0.Y:\nhave: %x\nwant: %x\n", prv0.PublicKey.Y.Bytes(), y0.Bytes()) 167 } 168 if prv1.PublicKey.X.Cmp(x1) != 0 { 169 t.Errorf("mismatched prv1.X:\nhave: %x\nwant: %x\n", prv1.PublicKey.X.Bytes(), x1.Bytes()) 170 } 171 if prv1.PublicKey.Y.Cmp(y1) != 0 { 172 t.Errorf("mismatched prv1.Y:\nhave: %x\nwant: %x\n", prv1.PublicKey.Y.Bytes(), y1.Bytes()) 173 } 174 175 //测试共享秘密生成 176 sk1, err := prv0.GenerateShared(&prv1.PublicKey, 16, 16) 177 if err != nil { 178 fmt.Println(err.Error()) 179 } 180 181 sk2, err := prv1.GenerateShared(&prv0.PublicKey, 16, 16) 182 if err != nil { 183 t.Fatal(err.Error()) 184 } 185 186 if !bytes.Equal(sk1, sk2) { 187 t.Fatal(ErrBadSharedKeys.Error()) 188 } 189 } 190 191 //验证当密钥数据太多时密钥生成代码是否失败 192 //请求。 193 func TestTooBigSharedKey(t *testing.T) { 194 prv1, err := GenerateKey(rand.Reader, DefaultCurve, nil) 195 if err != nil { 196 fmt.Println(err.Error()) 197 t.FailNow() 198 } 199 200 prv2, err := GenerateKey(rand.Reader, DefaultCurve, nil) 201 if err != nil { 202 fmt.Println(err.Error()) 203 t.FailNow() 204 } 205 206 _, err = prv1.GenerateShared(&prv2.PublicKey, 32, 32) 207 if err != ErrSharedKeyTooBig { 208 fmt.Println("ecdh: shared key should be too large for curve") 209 t.FailNow() 210 } 211 212 _, err = prv2.GenerateShared(&prv1.PublicKey, 32, 32) 213 if err != ErrSharedKeyTooBig { 214 fmt.Println("ecdh: shared key should be too large for curve") 215 t.FailNow() 216 } 217 } 218 219 //对p256密钥的生成进行基准测试。 220 func BenchmarkGenerateKeyP256(b *testing.B) { 221 for i := 0; i < b.N; i++ { 222 if _, err := GenerateKey(rand.Reader, elliptic.P256(), nil); err != nil { 223 fmt.Println(err.Error()) 224 b.FailNow() 225 } 226 } 227 } 228 229 //基准测试p256共享密钥的生成。 230 func BenchmarkGenSharedKeyP256(b *testing.B) { 231 prv, err := GenerateKey(rand.Reader, elliptic.P256(), nil) 232 if err != nil { 233 fmt.Println(err.Error()) 234 b.FailNow() 235 } 236 b.ResetTimer() 237 for i := 0; i < b.N; i++ { 238 _, err := prv.GenerateShared(&prv.PublicKey, 16, 16) 239 if err != nil { 240 fmt.Println(err.Error()) 241 b.FailNow() 242 } 243 } 244 } 245 246 //对S256共享密钥的生成进行基准测试。 247 func BenchmarkGenSharedKeyS256(b *testing.B) { 248 prv, err := GenerateKey(rand.Reader, crypto.S256(), nil) 249 if err != nil { 250 fmt.Println(err.Error()) 251 b.FailNow() 252 } 253 b.ResetTimer() 254 for i := 0; i < b.N; i++ { 255 _, err := prv.GenerateShared(&prv.PublicKey, 16, 16) 256 if err != nil { 257 fmt.Println(err.Error()) 258 b.FailNow() 259 } 260 } 261 } 262 263 //验证加密邮件是否可以成功解密。 264 func TestEncryptDecrypt(t *testing.T) { 265 prv1, err := GenerateKey(rand.Reader, DefaultCurve, nil) 266 if err != nil { 267 fmt.Println(err.Error()) 268 t.FailNow() 269 } 270 271 prv2, err := GenerateKey(rand.Reader, DefaultCurve, nil) 272 if err != nil { 273 fmt.Println(err.Error()) 274 t.FailNow() 275 } 276 277 message := []byte("Hello, world.") 278 ct, err := Encrypt(rand.Reader, &prv2.PublicKey, message, nil, nil) 279 if err != nil { 280 fmt.Println(err.Error()) 281 t.FailNow() 282 } 283 284 pt, err := prv2.Decrypt(ct, nil, nil) 285 if err != nil { 286 fmt.Println(err.Error()) 287 t.FailNow() 288 } 289 290 if !bytes.Equal(pt, message) { 291 fmt.Println("ecies: plaintext doesn't match message") 292 t.FailNow() 293 } 294 295 _, err = prv1.Decrypt(ct, nil, nil) 296 if err == nil { 297 fmt.Println("ecies: encryption should not have succeeded") 298 t.FailNow() 299 } 300 } 301 302 func TestDecryptShared2(t *testing.T) { 303 prv, err := GenerateKey(rand.Reader, DefaultCurve, nil) 304 if err != nil { 305 t.Fatal(err) 306 } 307 message := []byte("Hello, world.") 308 shared2 := []byte("shared data 2") 309 ct, err := Encrypt(rand.Reader, &prv.PublicKey, message, nil, shared2) 310 if err != nil { 311 t.Fatal(err) 312 } 313 314 //检查使用正确的共享数据进行解密是否有效。 315 pt, err := prv.Decrypt(ct, nil, shared2) 316 if err != nil { 317 t.Fatal(err) 318 } 319 if !bytes.Equal(pt, message) { 320 t.Fatal("ecies: plaintext doesn't match message") 321 } 322 323 //在没有共享数据或共享数据不正确的情况下解密失败。 324 if _, err = prv.Decrypt(ct, nil, nil); err == nil { 325 t.Fatal("ecies: decrypting without shared data didn't fail") 326 } 327 if _, err = prv.Decrypt(ct, nil, []byte("garbage")); err == nil { 328 t.Fatal("ecies: decrypting with incorrect shared data didn't fail") 329 } 330 } 331 332 type testCase struct { 333 Curve elliptic.Curve 334 Name string 335 Expected *ECIESParams 336 } 337 338 var testCases = []testCase{ 339 { 340 Curve: elliptic.P256(), 341 Name: "P256", 342 Expected: ECIES_AES128_SHA256, 343 }, 344 { 345 Curve: elliptic.P384(), 346 Name: "P384", 347 Expected: ECIES_AES256_SHA384, 348 }, 349 { 350 Curve: elliptic.P521(), 351 Name: "P521", 352 Expected: ECIES_AES256_SHA512, 353 }, 354 } 355 356 //每条曲线的测试参数选择,P224自动失效 357 //参数选择(有关p224的讨论,请参阅自述文件)。确保 358 //为给定曲线自动选择一组参数会起作用。 359 func TestParamSelection(t *testing.T) { 360 for _, c := range testCases { 361 testParamSelection(t, c) 362 } 363 } 364 365 func testParamSelection(t *testing.T, c testCase) { 366 params := ParamsFromCurve(c.Curve) 367 if params == nil && c.Expected != nil { 368 fmt.Printf("%s (%s)\n", ErrInvalidParams.Error(), c.Name) 369 t.FailNow() 370 } else if params != nil && !cmpParams(params, c.Expected) { 371 fmt.Printf("ecies: parameters should be invalid (%s)\n", 372 c.Name) 373 t.FailNow() 374 } 375 376 prv1, err := GenerateKey(rand.Reader, DefaultCurve, nil) 377 if err != nil { 378 fmt.Printf("%s (%s)\n", err.Error(), c.Name) 379 t.FailNow() 380 } 381 382 prv2, err := GenerateKey(rand.Reader, DefaultCurve, nil) 383 if err != nil { 384 fmt.Printf("%s (%s)\n", err.Error(), c.Name) 385 t.FailNow() 386 } 387 388 message := []byte("Hello, world.") 389 ct, err := Encrypt(rand.Reader, &prv2.PublicKey, message, nil, nil) 390 if err != nil { 391 fmt.Printf("%s (%s)\n", err.Error(), c.Name) 392 t.FailNow() 393 } 394 395 pt, err := prv2.Decrypt(ct, nil, nil) 396 if err != nil { 397 fmt.Printf("%s (%s)\n", err.Error(), c.Name) 398 t.FailNow() 399 } 400 401 if !bytes.Equal(pt, message) { 402 fmt.Printf("ecies: plaintext doesn't match message (%s)\n", 403 c.Name) 404 t.FailNow() 405 } 406 407 _, err = prv1.Decrypt(ct, nil, nil) 408 if err == nil { 409 fmt.Printf("ecies: encryption should not have succeeded (%s)\n", 410 c.Name) 411 t.FailNow() 412 } 413 414 } 415 416 //确保解密操作中的基本公钥验证 417 //作品。 418 func TestBasicKeyValidation(t *testing.T) { 419 badBytes := []byte{0, 1, 5, 6, 7, 8, 9} 420 421 prv, err := GenerateKey(rand.Reader, DefaultCurve, nil) 422 if err != nil { 423 fmt.Println(err.Error()) 424 t.FailNow() 425 } 426 427 message := []byte("Hello, world.") 428 ct, err := Encrypt(rand.Reader, &prv.PublicKey, message, nil, nil) 429 if err != nil { 430 fmt.Println(err.Error()) 431 t.FailNow() 432 } 433 434 for _, b := range badBytes { 435 ct[0] = b 436 _, err := prv.Decrypt(ct, nil, nil) 437 if err != ErrInvalidPublicKey { 438 fmt.Println("ecies: validated an invalid key") 439 t.FailNow() 440 } 441 } 442 } 443 444 func TestBox(t *testing.T) { 445 prv1 := hexKey("4b50fa71f5c3eeb8fdc452224b2395af2fcc3d125e06c32c82e048c0559db03f") 446 prv2 := hexKey("d0b043b4c5d657670778242d82d68a29d25d7d711127d17b8e299f156dad361a") 447 pub2 := &prv2.PublicKey 448 449 message := []byte("Hello, world.") 450 ct, err := Encrypt(rand.Reader, pub2, message, nil, nil) 451 if err != nil { 452 t.Fatal(err) 453 } 454 455 pt, err := prv2.Decrypt(ct, nil, nil) 456 if err != nil { 457 t.Fatal(err) 458 } 459 if !bytes.Equal(pt, message) { 460 t.Fatal("ecies: plaintext doesn't match message") 461 } 462 if _, err = prv1.Decrypt(ct, nil, nil); err == nil { 463 t.Fatal("ecies: encryption should not have succeeded") 464 } 465 } 466 467 //Verify GenerateShared against static values - useful when 468 //调试基础libs中的更改 469 func TestSharedKeyStatic(t *testing.T) { 470 prv1 := hexKey("7ebbc6a8358bc76dd73ebc557056702c8cfc34e5cfcd90eb83af0347575fd2ad") 471 prv2 := hexKey("6a3d6396903245bba5837752b9e0348874e72db0c4e11e9c485a81b4ea4353b9") 472 473 skLen := MaxSharedKeyLength(&prv1.PublicKey) / 2 474 475 sk1, err := prv1.GenerateShared(&prv2.PublicKey, skLen, skLen) 476 if err != nil { 477 fmt.Println(err.Error()) 478 t.FailNow() 479 } 480 481 sk2, err := prv2.GenerateShared(&prv1.PublicKey, skLen, skLen) 482 if err != nil { 483 fmt.Println(err.Error()) 484 t.FailNow() 485 } 486 487 if !bytes.Equal(sk1, sk2) { 488 fmt.Println(ErrBadSharedKeys.Error()) 489 t.FailNow() 490 } 491 492 sk, _ := hex.DecodeString("167ccc13ac5e8a26b131c3446030c60fbfac6aa8e31149d0869f93626a4cdf62") 493 if !bytes.Equal(sk1, sk) { 494 t.Fatalf("shared secret mismatch: want: %x have: %x", sk, sk1) 495 } 496 } 497 498 func hexKey(prv string) *PrivateKey { 499 key, err := crypto.HexToECDSA(prv) 500 if err != nil { 501 panic(err) 502 } 503 return ImportECDSA(key) 504 } 505