github.com/ylsgit/go-ethereum@v1.6.5/whisper/whisperv5/message_test.go (about)

     1  // Copyright 2016 The go-ethereum Authors
     2  // This file is part of the go-ethereum library.
     3  //
     4  // The go-ethereum library is free software: you can redistribute it and/or modify
     5  // it under the terms of the GNU Lesser General Public License as published by
     6  // the Free Software Foundation, either version 3 of the License, or
     7  // (at your option) any later version.
     8  //
     9  // The go-ethereum library is distributed in the hope that it will be useful,
    10  // but WITHOUT ANY WARRANTY; without even the implied warranty of
    11  // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
    12  // GNU Lesser General Public License for more details.
    13  //
    14  // You should have received a copy of the GNU Lesser General Public License
    15  // along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
    16  
    17  package whisperv5
    18  
    19  import (
    20  	"bytes"
    21  	mrand "math/rand"
    22  	"testing"
    23  
    24  	"github.com/ethereum/go-ethereum/crypto"
    25  	"github.com/ethereum/go-ethereum/rlp"
    26  )
    27  
    28  func copyFromBuf(dst []byte, src []byte, beg int) int {
    29  	copy(dst, src[beg:])
    30  	return beg + len(dst)
    31  }
    32  
    33  func generateMessageParams() (*MessageParams, error) {
    34  	// set all the parameters except p.Dst and p.Padding
    35  
    36  	buf := make([]byte, 4)
    37  	mrand.Read(buf)
    38  	sz := mrand.Intn(400)
    39  
    40  	var p MessageParams
    41  	p.PoW = 0.01
    42  	p.WorkTime = 1
    43  	p.TTL = uint32(mrand.Intn(1024))
    44  	p.Payload = make([]byte, sz)
    45  	p.KeySym = make([]byte, aesKeyLength)
    46  	mrand.Read(p.Payload)
    47  	mrand.Read(p.KeySym)
    48  	p.Topic = BytesToTopic(buf)
    49  
    50  	var err error
    51  	p.Src, err = crypto.GenerateKey()
    52  	if err != nil {
    53  		return nil, err
    54  	}
    55  
    56  	return &p, nil
    57  }
    58  
    59  func singleMessageTest(t *testing.T, symmetric bool) {
    60  	params, err := generateMessageParams()
    61  	if err != nil {
    62  		t.Fatalf("failed generateMessageParams with seed %d: %s.", seed, err)
    63  	}
    64  
    65  	key, err := crypto.GenerateKey()
    66  	if err != nil {
    67  		t.Fatalf("failed GenerateKey with seed %d: %s.", seed, err)
    68  	}
    69  
    70  	if !symmetric {
    71  		params.KeySym = nil
    72  		params.Dst = &key.PublicKey
    73  	}
    74  
    75  	text := make([]byte, 0, 512)
    76  	text = append(text, params.Payload...)
    77  
    78  	msg, err := NewSentMessage(params)
    79  	if err != nil {
    80  		t.Fatalf("failed to create new message with seed %d: %s.", seed, err)
    81  	}
    82  	env, err := msg.Wrap(params)
    83  	if err != nil {
    84  		t.Fatalf("failed Wrap with seed %d: %s.", seed, err)
    85  	}
    86  
    87  	var decrypted *ReceivedMessage
    88  	if symmetric {
    89  		decrypted, err = env.OpenSymmetric(params.KeySym)
    90  	} else {
    91  		decrypted, err = env.OpenAsymmetric(key)
    92  	}
    93  
    94  	if err != nil {
    95  		t.Fatalf("failed to encrypt with seed %d: %s.", seed, err)
    96  	}
    97  
    98  	if !decrypted.Validate() {
    99  		t.Fatalf("failed to validate with seed %d.", seed)
   100  	}
   101  
   102  	if !bytes.Equal(text, decrypted.Payload) {
   103  		t.Fatalf("failed with seed %d: compare payload.", seed)
   104  	}
   105  	if !isMessageSigned(decrypted.Raw[0]) {
   106  		t.Fatalf("failed with seed %d: unsigned.", seed)
   107  	}
   108  	if len(decrypted.Signature) != signatureLength {
   109  		t.Fatalf("failed with seed %d: signature len %d.", seed, len(decrypted.Signature))
   110  	}
   111  	if !IsPubKeyEqual(decrypted.Src, &params.Src.PublicKey) {
   112  		t.Fatalf("failed with seed %d: signature mismatch.", seed)
   113  	}
   114  }
   115  
   116  func TestMessageEncryption(t *testing.T) {
   117  	InitSingleTest()
   118  
   119  	var symmetric bool
   120  	for i := 0; i < 256; i++ {
   121  		singleMessageTest(t, symmetric)
   122  		symmetric = !symmetric
   123  	}
   124  }
   125  
   126  func TestMessageWrap(t *testing.T) {
   127  	seed = int64(1777444222)
   128  	mrand.Seed(seed)
   129  	target := 128.0
   130  
   131  	params, err := generateMessageParams()
   132  	if err != nil {
   133  		t.Fatalf("failed generateMessageParams with seed %d: %s.", seed, err)
   134  	}
   135  
   136  	msg, err := NewSentMessage(params)
   137  	if err != nil {
   138  		t.Fatalf("failed to create new message with seed %d: %s.", seed, err)
   139  	}
   140  	params.TTL = 1
   141  	params.WorkTime = 12
   142  	params.PoW = target
   143  	env, err := msg.Wrap(params)
   144  	if err != nil {
   145  		t.Fatalf("failed Wrap with seed %d: %s.", seed, err)
   146  	}
   147  
   148  	pow := env.PoW()
   149  	if pow < target {
   150  		t.Fatalf("failed Wrap with seed %d: pow < target (%f vs. %f).", seed, pow, target)
   151  	}
   152  
   153  	// set PoW target too high, expect error
   154  	msg2, err := NewSentMessage(params)
   155  	if err != nil {
   156  		t.Fatalf("failed to create new message with seed %d: %s.", seed, err)
   157  	}
   158  	params.TTL = 1000000
   159  	params.WorkTime = 1
   160  	params.PoW = 10000000.0
   161  	env, err = msg2.Wrap(params)
   162  	if err == nil {
   163  		t.Fatalf("unexpectedly reached the PoW target with seed %d.", seed)
   164  	}
   165  }
   166  
   167  func TestMessageSeal(t *testing.T) {
   168  	// this test depends on deterministic choice of seed (1976726903)
   169  	seed = int64(1976726903)
   170  	mrand.Seed(seed)
   171  
   172  	params, err := generateMessageParams()
   173  	if err != nil {
   174  		t.Fatalf("failed generateMessageParams with seed %d: %s.", seed, err)
   175  	}
   176  
   177  	msg, err := NewSentMessage(params)
   178  	if err != nil {
   179  		t.Fatalf("failed to create new message with seed %d: %s.", seed, err)
   180  	}
   181  	params.TTL = 1
   182  	aesnonce := make([]byte, 12)
   183  	mrand.Read(aesnonce)
   184  
   185  	env := NewEnvelope(params.TTL, params.Topic, aesnonce, msg)
   186  	if err != nil {
   187  		t.Fatalf("failed Wrap with seed %d: %s.", seed, err)
   188  	}
   189  
   190  	env.Expiry = uint32(seed) // make it deterministic
   191  	target := 32.0
   192  	params.WorkTime = 4
   193  	params.PoW = target
   194  	env.Seal(params)
   195  
   196  	env.calculatePoW(0)
   197  	pow := env.PoW()
   198  	if pow < target {
   199  		t.Fatalf("failed Wrap with seed %d: pow < target (%f vs. %f).", seed, pow, target)
   200  	}
   201  
   202  	params.WorkTime = 1
   203  	params.PoW = 1000000000.0
   204  	env.Seal(params)
   205  	env.calculatePoW(0)
   206  	pow = env.PoW()
   207  	if pow < 2*target {
   208  		t.Fatalf("failed Wrap with seed %d: pow too small %f.", seed, pow)
   209  	}
   210  }
   211  
   212  func TestEnvelopeOpen(t *testing.T) {
   213  	InitSingleTest()
   214  
   215  	var symmetric bool
   216  	for i := 0; i < 256; i++ {
   217  		singleEnvelopeOpenTest(t, symmetric)
   218  		symmetric = !symmetric
   219  	}
   220  }
   221  
   222  func singleEnvelopeOpenTest(t *testing.T, symmetric bool) {
   223  	params, err := generateMessageParams()
   224  	if err != nil {
   225  		t.Fatalf("failed generateMessageParams with seed %d: %s.", seed, err)
   226  	}
   227  
   228  	key, err := crypto.GenerateKey()
   229  	if err != nil {
   230  		t.Fatalf("failed GenerateKey with seed %d: %s.", seed, err)
   231  	}
   232  
   233  	if !symmetric {
   234  		params.KeySym = nil
   235  		params.Dst = &key.PublicKey
   236  	}
   237  
   238  	text := make([]byte, 0, 512)
   239  	text = append(text, params.Payload...)
   240  
   241  	msg, err := NewSentMessage(params)
   242  	if err != nil {
   243  		t.Fatalf("failed to create new message with seed %d: %s.", seed, err)
   244  	}
   245  	env, err := msg.Wrap(params)
   246  	if err != nil {
   247  		t.Fatalf("failed Wrap with seed %d: %s.", seed, err)
   248  	}
   249  
   250  	f := Filter{KeyAsym: key, KeySym: params.KeySym}
   251  	decrypted := env.Open(&f)
   252  	if decrypted == nil {
   253  		t.Fatalf("failed to open with seed %d.", seed)
   254  	}
   255  
   256  	if !bytes.Equal(text, decrypted.Payload) {
   257  		t.Fatalf("failed with seed %d: compare payload.", seed)
   258  	}
   259  	if !isMessageSigned(decrypted.Raw[0]) {
   260  		t.Fatalf("failed with seed %d: unsigned.", seed)
   261  	}
   262  	if len(decrypted.Signature) != signatureLength {
   263  		t.Fatalf("failed with seed %d: signature len %d.", seed, len(decrypted.Signature))
   264  	}
   265  	if !IsPubKeyEqual(decrypted.Src, &params.Src.PublicKey) {
   266  		t.Fatalf("failed with seed %d: signature mismatch.", seed)
   267  	}
   268  	if decrypted.isAsymmetricEncryption() == symmetric {
   269  		t.Fatalf("failed with seed %d: asymmetric %v vs. %v.", seed, decrypted.isAsymmetricEncryption(), symmetric)
   270  	}
   271  	if decrypted.isSymmetricEncryption() != symmetric {
   272  		t.Fatalf("failed with seed %d: symmetric %v vs. %v.", seed, decrypted.isSymmetricEncryption(), symmetric)
   273  	}
   274  	if !symmetric {
   275  		if decrypted.Dst == nil {
   276  			t.Fatalf("failed with seed %d: dst is nil.", seed)
   277  		}
   278  		if !IsPubKeyEqual(decrypted.Dst, &key.PublicKey) {
   279  			t.Fatalf("failed with seed %d: Dst.", seed)
   280  		}
   281  	}
   282  }
   283  
   284  func TestEncryptWithZeroKey(t *testing.T) {
   285  	InitSingleTest()
   286  
   287  	params, err := generateMessageParams()
   288  	if err != nil {
   289  		t.Fatalf("failed generateMessageParams with seed %d: %s.", seed, err)
   290  	}
   291  	msg, err := NewSentMessage(params)
   292  	if err != nil {
   293  		t.Fatalf("failed to create new message with seed %d: %s.", seed, err)
   294  	}
   295  	params.KeySym = make([]byte, aesKeyLength)
   296  	_, err = msg.Wrap(params)
   297  	if err == nil {
   298  		t.Fatalf("wrapped with zero key, seed: %d.", seed)
   299  	}
   300  
   301  	params, err = generateMessageParams()
   302  	if err != nil {
   303  		t.Fatalf("failed generateMessageParams with seed %d: %s.", seed, err)
   304  	}
   305  	msg, err = NewSentMessage(params)
   306  	if err != nil {
   307  		t.Fatalf("failed to create new message with seed %d: %s.", seed, err)
   308  	}
   309  	params.KeySym = make([]byte, 0)
   310  	_, err = msg.Wrap(params)
   311  	if err == nil {
   312  		t.Fatalf("wrapped with empty key, seed: %d.", seed)
   313  	}
   314  
   315  	params, err = generateMessageParams()
   316  	if err != nil {
   317  		t.Fatalf("failed generateMessageParams with seed %d: %s.", seed, err)
   318  	}
   319  	msg, err = NewSentMessage(params)
   320  	if err != nil {
   321  		t.Fatalf("failed to create new message with seed %d: %s.", seed, err)
   322  	}
   323  	params.KeySym = nil
   324  	_, err = msg.Wrap(params)
   325  	if err == nil {
   326  		t.Fatalf("wrapped with nil key, seed: %d.", seed)
   327  	}
   328  }
   329  
   330  func TestRlpEncode(t *testing.T) {
   331  	InitSingleTest()
   332  
   333  	params, err := generateMessageParams()
   334  	if err != nil {
   335  		t.Fatalf("failed generateMessageParams with seed %d: %s.", seed, err)
   336  	}
   337  	msg, err := NewSentMessage(params)
   338  	if err != nil {
   339  		t.Fatalf("failed to create new message with seed %d: %s.", seed, err)
   340  	}
   341  	env, err := msg.Wrap(params)
   342  	if err != nil {
   343  		t.Fatalf("wrapped with zero key, seed: %d.", seed)
   344  	}
   345  
   346  	raw, err := rlp.EncodeToBytes(env)
   347  	if err != nil {
   348  		t.Fatalf("RLP encode failed: %s.", err)
   349  	}
   350  
   351  	var decoded Envelope
   352  	rlp.DecodeBytes(raw, &decoded)
   353  	if err != nil {
   354  		t.Fatalf("RLP decode failed: %s.", err)
   355  	}
   356  
   357  	he := env.Hash()
   358  	hd := decoded.Hash()
   359  
   360  	if he != hd {
   361  		t.Fatalf("Hashes are not equal: %x vs. %x", he, hd)
   362  	}
   363  }
   364  
   365  func singlePaddingTest(t *testing.T, padSize int) {
   366  	params, err := generateMessageParams()
   367  	if err != nil {
   368  		t.Fatalf("failed generateMessageParams with seed %d and sz=%d: %s.", seed, padSize, err)
   369  	}
   370  	params.Padding = make([]byte, padSize)
   371  	params.PoW = 0.0000000001
   372  	pad := make([]byte, padSize)
   373  	_, err = mrand.Read(pad)
   374  	if err != nil {
   375  		t.Fatalf("padding is not generated (seed %d): %s", seed, err)
   376  	}
   377  	n := copy(params.Padding, pad)
   378  	if n != padSize {
   379  		t.Fatalf("padding is not copied (seed %d): %s", seed, err)
   380  	}
   381  	msg, err := NewSentMessage(params)
   382  	if err != nil {
   383  		t.Fatalf("failed to create new message with seed %d: %s.", seed, err)
   384  	}
   385  	env, err := msg.Wrap(params)
   386  	if err != nil {
   387  		t.Fatalf("failed to wrap, seed: %d and sz=%d.", seed, padSize)
   388  	}
   389  	f := Filter{KeySym: params.KeySym}
   390  	decrypted := env.Open(&f)
   391  	if decrypted == nil {
   392  		t.Fatalf("failed to open, seed and sz=%d: %d.", seed, padSize)
   393  	}
   394  	if !bytes.Equal(pad, decrypted.Padding) {
   395  		t.Fatalf("padding is not retireved as expected with seed %d and sz=%d:\n[%x]\n[%x].", seed, padSize, pad, decrypted.Padding)
   396  	}
   397  }
   398  
   399  func TestPadding(t *testing.T) {
   400  	InitSingleTest()
   401  
   402  	for i := 1; i < 260; i++ {
   403  		singlePaddingTest(t, i)
   404  	}
   405  
   406  	lim := 256 * 256
   407  	for i := lim - 5; i < lim+2; i++ {
   408  		singlePaddingTest(t, i)
   409  	}
   410  
   411  	for i := 0; i < 256; i++ {
   412  		n := mrand.Intn(256*254) + 256
   413  		singlePaddingTest(t, n)
   414  	}
   415  
   416  	for i := 0; i < 256; i++ {
   417  		n := mrand.Intn(256*1024) + 256*256
   418  		singlePaddingTest(t, n)
   419  	}
   420  }