github.com/linapex/ethereum-go-chinese@v0.0.0-20190316121929-f8b7a73c3fa1/whisper/whisperv6/message_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:46</date>
    10  //</624450125590171648>
    11  
    12  
    13  package whisperv6
    14  
    15  import (
    16  	"bytes"
    17  	"crypto/aes"
    18  	"crypto/cipher"
    19  	mrand "math/rand"
    20  	"testing"
    21  
    22  	"github.com/ethereum/go-ethereum/common/hexutil"
    23  	"github.com/ethereum/go-ethereum/crypto"
    24  	"github.com/ethereum/go-ethereum/rlp"
    25  )
    26  
    27  func generateMessageParams() (*MessageParams, error) {
    28  //设置除P.DST和P.PADDING以外的所有参数
    29  
    30  	buf := make([]byte, 4)
    31  	mrand.Read(buf)
    32  	sz := mrand.Intn(400)
    33  
    34  	var p MessageParams
    35  	p.PoW = 0.01
    36  	p.WorkTime = 1
    37  	p.TTL = uint32(mrand.Intn(1024))
    38  	p.Payload = make([]byte, sz)
    39  	p.KeySym = make([]byte, aesKeyLength)
    40  	mrand.Read(p.Payload)
    41  	mrand.Read(p.KeySym)
    42  	p.Topic = BytesToTopic(buf)
    43  
    44  	var err error
    45  	p.Src, err = crypto.GenerateKey()
    46  	if err != nil {
    47  		return nil, err
    48  	}
    49  
    50  	return &p, nil
    51  }
    52  
    53  func singleMessageTest(t *testing.T, symmetric bool) {
    54  	params, err := generateMessageParams()
    55  	if err != nil {
    56  		t.Fatalf("failed generateMessageParams with seed %d: %s.", seed, err)
    57  	}
    58  
    59  	key, err := crypto.GenerateKey()
    60  	if err != nil {
    61  		t.Fatalf("failed GenerateKey with seed %d: %s.", seed, err)
    62  	}
    63  
    64  	if !symmetric {
    65  		params.KeySym = nil
    66  		params.Dst = &key.PublicKey
    67  	}
    68  
    69  	text := make([]byte, 0, 512)
    70  	text = append(text, params.Payload...)
    71  
    72  	msg, err := NewSentMessage(params)
    73  	if err != nil {
    74  		t.Fatalf("failed to create new message with seed %d: %s.", seed, err)
    75  	}
    76  	env, err := msg.Wrap(params)
    77  	if err != nil {
    78  		t.Fatalf("failed Wrap with seed %d: %s.", seed, err)
    79  	}
    80  
    81  	var decrypted *ReceivedMessage
    82  	if symmetric {
    83  		decrypted, err = env.OpenSymmetric(params.KeySym)
    84  	} else {
    85  		decrypted, err = env.OpenAsymmetric(key)
    86  	}
    87  
    88  	if err != nil {
    89  		t.Fatalf("failed to encrypt with seed %d: %s.", seed, err)
    90  	}
    91  
    92  	if !decrypted.ValidateAndParse() {
    93  		t.Fatalf("failed to validate with seed %d, symmetric = %v.", seed, symmetric)
    94  	}
    95  
    96  	if !bytes.Equal(text, decrypted.Payload) {
    97  		t.Fatalf("failed with seed %d: compare payload.", seed)
    98  	}
    99  	if !isMessageSigned(decrypted.Raw[0]) {
   100  		t.Fatalf("failed with seed %d: unsigned.", seed)
   101  	}
   102  	if len(decrypted.Signature) != signatureLength {
   103  		t.Fatalf("failed with seed %d: signature len %d.", seed, len(decrypted.Signature))
   104  	}
   105  	if !IsPubKeyEqual(decrypted.Src, &params.Src.PublicKey) {
   106  		t.Fatalf("failed with seed %d: signature mismatch.", seed)
   107  	}
   108  }
   109  
   110  func TestMessageEncryption(t *testing.T) {
   111  	InitSingleTest()
   112  
   113  	var symmetric bool
   114  	for i := 0; i < 256; i++ {
   115  		singleMessageTest(t, symmetric)
   116  		symmetric = !symmetric
   117  	}
   118  }
   119  
   120  func TestMessageWrap(t *testing.T) {
   121  	seed = int64(1777444222)
   122  	mrand.Seed(seed)
   123  	target := 128.0
   124  
   125  	params, err := generateMessageParams()
   126  	if err != nil {
   127  		t.Fatalf("failed generateMessageParams with seed %d: %s.", seed, err)
   128  	}
   129  
   130  	msg, err := NewSentMessage(params)
   131  	if err != nil {
   132  		t.Fatalf("failed to create new message with seed %d: %s.", seed, err)
   133  	}
   134  	params.TTL = 1
   135  	params.WorkTime = 12
   136  	params.PoW = target
   137  	env, err := msg.Wrap(params)
   138  	if err != nil {
   139  		t.Fatalf("failed Wrap with seed %d: %s.", seed, err)
   140  	}
   141  
   142  	pow := env.PoW()
   143  	if pow < target {
   144  		t.Fatalf("failed Wrap with seed %d: pow < target (%f vs. %f).", seed, pow, target)
   145  	}
   146  
   147  //设置POW目标太高,预期错误
   148  	msg2, err := NewSentMessage(params)
   149  	if err != nil {
   150  		t.Fatalf("failed to create new message with seed %d: %s.", seed, err)
   151  	}
   152  	params.TTL = 1000000
   153  	params.WorkTime = 1
   154  	params.PoW = 10000000.0
   155  	_, err = msg2.Wrap(params)
   156  	if err == nil {
   157  		t.Fatalf("unexpectedly reached the PoW target with seed %d.", seed)
   158  	}
   159  }
   160  
   161  func TestMessageSeal(t *testing.T) {
   162  //此测试取决于种子的确定性选择(1976726903)
   163  	seed = int64(1976726903)
   164  	mrand.Seed(seed)
   165  
   166  	params, err := generateMessageParams()
   167  	if err != nil {
   168  		t.Fatalf("failed generateMessageParams with seed %d: %s.", seed, err)
   169  	}
   170  
   171  	msg, err := NewSentMessage(params)
   172  	if err != nil {
   173  		t.Fatalf("failed to create new message with seed %d: %s.", seed, err)
   174  	}
   175  	params.TTL = 1
   176  
   177  	env := NewEnvelope(params.TTL, params.Topic, msg)
   178  	if err != nil {
   179  		t.Fatalf("failed Wrap with seed %d: %s.", seed, err)
   180  	}
   181  
   182  env.Expiry = uint32(seed) //使其具有确定性
   183  	target := 32.0
   184  	params.WorkTime = 4
   185  	params.PoW = target
   186  	env.Seal(params)
   187  
   188  	env.calculatePoW(0)
   189  	pow := env.PoW()
   190  	if pow < target {
   191  		t.Fatalf("failed Wrap with seed %d: pow < target (%f vs. %f).", seed, pow, target)
   192  	}
   193  
   194  	params.WorkTime = 1
   195  	params.PoW = 1000000000.0
   196  	env.Seal(params)
   197  	env.calculatePoW(0)
   198  	pow = env.PoW()
   199  	if pow < 2*target {
   200  		t.Fatalf("failed Wrap with seed %d: pow too small %f.", seed, pow)
   201  	}
   202  }
   203  
   204  func TestEnvelopeOpen(t *testing.T) {
   205  	InitSingleTest()
   206  
   207  	var symmetric bool
   208  	for i := 0; i < 32; i++ {
   209  		singleEnvelopeOpenTest(t, symmetric)
   210  		symmetric = !symmetric
   211  	}
   212  }
   213  
   214  func singleEnvelopeOpenTest(t *testing.T, symmetric bool) {
   215  	params, err := generateMessageParams()
   216  	if err != nil {
   217  		t.Fatalf("failed generateMessageParams with seed %d: %s.", seed, err)
   218  	}
   219  
   220  	key, err := crypto.GenerateKey()
   221  	if err != nil {
   222  		t.Fatalf("failed GenerateKey with seed %d: %s.", seed, err)
   223  	}
   224  
   225  	if !symmetric {
   226  		params.KeySym = nil
   227  		params.Dst = &key.PublicKey
   228  	}
   229  
   230  	text := make([]byte, 0, 512)
   231  	text = append(text, params.Payload...)
   232  
   233  	msg, err := NewSentMessage(params)
   234  	if err != nil {
   235  		t.Fatalf("failed to create new message with seed %d: %s.", seed, err)
   236  	}
   237  	env, err := msg.Wrap(params)
   238  	if err != nil {
   239  		t.Fatalf("failed Wrap with seed %d: %s.", seed, err)
   240  	}
   241  
   242  	var f Filter
   243  	if symmetric {
   244  		f = Filter{KeySym: params.KeySym}
   245  	} else {
   246  		f = Filter{KeyAsym: key}
   247  	}
   248  	decrypted := env.Open(&f)
   249  	if decrypted == nil {
   250  		t.Fatalf("failed to open with seed %d.", seed)
   251  	}
   252  
   253  	if !bytes.Equal(text, decrypted.Payload) {
   254  		t.Fatalf("failed with seed %d: compare payload.", seed)
   255  	}
   256  	if !isMessageSigned(decrypted.Raw[0]) {
   257  		t.Fatalf("failed with seed %d: unsigned.", seed)
   258  	}
   259  	if len(decrypted.Signature) != signatureLength {
   260  		t.Fatalf("failed with seed %d: signature len %d.", seed, len(decrypted.Signature))
   261  	}
   262  	if !IsPubKeyEqual(decrypted.Src, &params.Src.PublicKey) {
   263  		t.Fatalf("failed with seed %d: signature mismatch.", seed)
   264  	}
   265  	if decrypted.isAsymmetricEncryption() == symmetric {
   266  		t.Fatalf("failed with seed %d: asymmetric %v vs. %v.", seed, decrypted.isAsymmetricEncryption(), symmetric)
   267  	}
   268  	if decrypted.isSymmetricEncryption() != symmetric {
   269  		t.Fatalf("failed with seed %d: symmetric %v vs. %v.", seed, decrypted.isSymmetricEncryption(), symmetric)
   270  	}
   271  	if !symmetric {
   272  		if decrypted.Dst == nil {
   273  			t.Fatalf("failed with seed %d: dst is nil.", seed)
   274  		}
   275  		if !IsPubKeyEqual(decrypted.Dst, &key.PublicKey) {
   276  			t.Fatalf("failed with seed %d: Dst.", seed)
   277  		}
   278  	}
   279  }
   280  
   281  func TestEncryptWithZeroKey(t *testing.T) {
   282  	InitSingleTest()
   283  
   284  	params, err := generateMessageParams()
   285  	if err != nil {
   286  		t.Fatalf("failed generateMessageParams with seed %d: %s.", seed, err)
   287  	}
   288  	msg, err := NewSentMessage(params)
   289  	if err != nil {
   290  		t.Fatalf("failed to create new message with seed %d: %s.", seed, err)
   291  	}
   292  	params.KeySym = make([]byte, aesKeyLength)
   293  	_, err = msg.Wrap(params)
   294  	if err == nil {
   295  		t.Fatalf("wrapped with zero key, seed: %d.", seed)
   296  	}
   297  
   298  	params, err = generateMessageParams()
   299  	if err != nil {
   300  		t.Fatalf("failed generateMessageParams with seed %d: %s.", seed, err)
   301  	}
   302  	msg, err = NewSentMessage(params)
   303  	if err != nil {
   304  		t.Fatalf("failed to create new message with seed %d: %s.", seed, err)
   305  	}
   306  	params.KeySym = make([]byte, 0)
   307  	_, err = msg.Wrap(params)
   308  	if err == nil {
   309  		t.Fatalf("wrapped with empty key, seed: %d.", seed)
   310  	}
   311  
   312  	params, err = generateMessageParams()
   313  	if err != nil {
   314  		t.Fatalf("failed generateMessageParams with seed %d: %s.", seed, err)
   315  	}
   316  	msg, err = NewSentMessage(params)
   317  	if err != nil {
   318  		t.Fatalf("failed to create new message with seed %d: %s.", seed, err)
   319  	}
   320  	params.KeySym = nil
   321  	_, err = msg.Wrap(params)
   322  	if err == nil {
   323  		t.Fatalf("wrapped with nil key, seed: %d.", seed)
   324  	}
   325  }
   326  
   327  func TestRlpEncode(t *testing.T) {
   328  	InitSingleTest()
   329  
   330  	params, err := generateMessageParams()
   331  	if err != nil {
   332  		t.Fatalf("failed generateMessageParams with seed %d: %s.", seed, err)
   333  	}
   334  	msg, err := NewSentMessage(params)
   335  	if err != nil {
   336  		t.Fatalf("failed to create new message with seed %d: %s.", seed, err)
   337  	}
   338  	env, err := msg.Wrap(params)
   339  	if err != nil {
   340  		t.Fatalf("wrapped with zero key, seed: %d.", seed)
   341  	}
   342  
   343  	raw, err := rlp.EncodeToBytes(env)
   344  	if err != nil {
   345  		t.Fatalf("RLP encode failed: %s.", err)
   346  	}
   347  
   348  	var decoded Envelope
   349  	rlp.DecodeBytes(raw, &decoded)
   350  	if err != nil {
   351  		t.Fatalf("RLP decode failed: %s.", err)
   352  	}
   353  
   354  	he := env.Hash()
   355  	hd := decoded.Hash()
   356  
   357  	if he != hd {
   358  		t.Fatalf("Hashes are not equal: %x vs. %x", he, hd)
   359  	}
   360  }
   361  
   362  func singlePaddingTest(t *testing.T, padSize int) {
   363  	params, err := generateMessageParams()
   364  	if err != nil {
   365  		t.Fatalf("failed generateMessageParams with seed %d and sz=%d: %s.", seed, padSize, err)
   366  	}
   367  	params.Padding = make([]byte, padSize)
   368  	params.PoW = 0.0000000001
   369  	pad := make([]byte, padSize)
   370  	_, err = mrand.Read(pad)
   371  	if err != nil {
   372  		t.Fatalf("padding is not generated (seed %d): %s", seed, err)
   373  	}
   374  	n := copy(params.Padding, pad)
   375  	if n != padSize {
   376  		t.Fatalf("padding is not copied (seed %d): %s", seed, err)
   377  	}
   378  	msg, err := NewSentMessage(params)
   379  	if err != nil {
   380  		t.Fatalf("failed to create new message with seed %d: %s.", seed, err)
   381  	}
   382  	env, err := msg.Wrap(params)
   383  	if err != nil {
   384  		t.Fatalf("failed to wrap, seed: %d and sz=%d.", seed, padSize)
   385  	}
   386  	f := Filter{KeySym: params.KeySym}
   387  	decrypted := env.Open(&f)
   388  	if decrypted == nil {
   389  		t.Fatalf("failed to open, seed and sz=%d: %d.", seed, padSize)
   390  	}
   391  	if !bytes.Equal(pad, decrypted.Padding) {
   392  		t.Fatalf("padding is not retireved as expected with seed %d and sz=%d:\n[%x]\n[%x].", seed, padSize, pad, decrypted.Padding)
   393  	}
   394  }
   395  
   396  func TestPadding(t *testing.T) {
   397  	InitSingleTest()
   398  
   399  	for i := 1; i < 260; i++ {
   400  		singlePaddingTest(t, i)
   401  	}
   402  
   403  	lim := 256 * 256
   404  	for i := lim - 5; i < lim+2; i++ {
   405  		singlePaddingTest(t, i)
   406  	}
   407  
   408  	for i := 0; i < 256; i++ {
   409  		n := mrand.Intn(256*254) + 256
   410  		singlePaddingTest(t, n)
   411  	}
   412  
   413  	for i := 0; i < 256; i++ {
   414  		n := mrand.Intn(256*1024) + 256*256
   415  		singlePaddingTest(t, n)
   416  	}
   417  }
   418  
   419  func TestPaddingAppendedToSymMessagesWithSignature(t *testing.T) {
   420  	params := &MessageParams{
   421  		Payload: make([]byte, 246),
   422  		KeySym:  make([]byte, aesKeyLength),
   423  	}
   424  
   425  	pSrc, err := crypto.GenerateKey()
   426  
   427  	if err != nil {
   428  		t.Fatalf("Error creating the signature key %v", err)
   429  		return
   430  	}
   431  	params.Src = pSrc
   432  
   433  //模拟有效负载低于256的消息,以便
   434  //有效载荷+标志+签名>256。检查结果
   435  //在下一个256边界上填充。
   436  	msg := sentMessage{}
   437  	const payloadSizeFieldMinSize = 1
   438  	msg.Raw = make([]byte, flagsLength+payloadSizeFieldMinSize+len(params.Payload))
   439  
   440  	err = msg.appendPadding(params)
   441  
   442  	if err != nil {
   443  		t.Fatalf("Error appending padding to message %v", err)
   444  		return
   445  	}
   446  
   447  	if len(msg.Raw) != 512-signatureLength {
   448  		t.Errorf("Invalid size %d != 512", len(msg.Raw))
   449  	}
   450  }
   451  
   452  func TestAesNonce(t *testing.T) {
   453  	key := hexutil.MustDecode("0x03ca634cae0d49acb401d8a4c6b6fe8c55b70d115bf400769cc1400f3258cd31")
   454  	block, err := aes.NewCipher(key)
   455  	if err != nil {
   456  		t.Fatalf("NewCipher failed: %s", err)
   457  	}
   458  	aesgcm, err := cipher.NewGCM(block)
   459  	if err != nil {
   460  		t.Fatalf("NewGCM failed: %s", err)
   461  	}
   462  //这是此包中最重要的单个测试。
   463  //如果失败了,耳语就不起作用了。
   464  	if aesgcm.NonceSize() != aesNonceLength {
   465  		t.Fatalf("Nonce size is wrong. This is a critical error. Apparently AES nonce size have changed in the new version of AES GCM package. Whisper will not be working until this problem is resolved.")
   466  	}
   467  }
   468