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