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