github.com/murrekatt/go-ethereum@v1.5.8-0.20170123175102-fc52f2c007fb/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  	"math/rand"
    22  	"testing"
    23  
    24  	"github.com/ethereum/go-ethereum/crypto"
    25  )
    26  
    27  func copyFromBuf(dst []byte, src []byte, beg int) int {
    28  	copy(dst, src[beg:])
    29  	return beg + len(dst)
    30  }
    31  
    32  func generateMessageParams() (*MessageParams, error) {
    33  	// set all the parameters except p.Dst
    34  
    35  	buf := make([]byte, 1024)
    36  	randomize(buf)
    37  	sz := rand.Intn(400)
    38  
    39  	var p MessageParams
    40  	p.PoW = 0.01
    41  	p.WorkTime = 1
    42  	p.TTL = uint32(rand.Intn(1024))
    43  	p.Payload = make([]byte, sz)
    44  	p.Padding = make([]byte, padSizeLimitUpper)
    45  	p.KeySym = make([]byte, aesKeyLength)
    46  
    47  	var b int
    48  	b = copyFromBuf(p.Payload, buf, b)
    49  	b = copyFromBuf(p.Padding, buf, b)
    50  	b = copyFromBuf(p.KeySym, buf, b)
    51  	p.Topic = BytesToTopic(buf[b:])
    52  
    53  	var err error
    54  	p.Src, err = crypto.GenerateKey()
    55  	if err != nil {
    56  		return nil, err
    57  	}
    58  
    59  	return &p, nil
    60  }
    61  
    62  func singleMessageTest(t *testing.T, symmetric bool) {
    63  	params, err := generateMessageParams()
    64  	if err != nil {
    65  		t.Fatalf("failed generateMessageParams with seed %d: %s.", seed, err)
    66  	}
    67  
    68  	key, err := crypto.GenerateKey()
    69  	if err != nil {
    70  		t.Fatalf("failed GenerateKey with seed %d: %s.", seed, err)
    71  	}
    72  
    73  	if !symmetric {
    74  		params.KeySym = nil
    75  		params.Dst = &key.PublicKey
    76  	}
    77  
    78  	text := make([]byte, 0, 512)
    79  	steg := make([]byte, 0, 512)
    80  	text = append(text, params.Payload...)
    81  	steg = append(steg, params.Padding...)
    82  
    83  	msg := NewSentMessage(params)
    84  	env, err := msg.Wrap(params)
    85  	if err != nil {
    86  		t.Fatalf("failed Wrap with seed %d: %s.", seed, err)
    87  	}
    88  
    89  	var decrypted *ReceivedMessage
    90  	if symmetric {
    91  		decrypted, err = env.OpenSymmetric(params.KeySym)
    92  	} else {
    93  		decrypted, err = env.OpenAsymmetric(key)
    94  	}
    95  
    96  	if err != nil {
    97  		t.Fatalf("failed to encrypt with seed %d: %s.", seed, err)
    98  	}
    99  
   100  	if !decrypted.Validate() {
   101  		t.Fatalf("failed to validate with seed %d.", seed)
   102  	}
   103  
   104  	padsz := len(decrypted.Padding)
   105  	if !bytes.Equal(steg[:padsz], decrypted.Padding) {
   106  		t.Fatalf("failed with seed %d: compare padding.", seed)
   107  	}
   108  	if !bytes.Equal(text, decrypted.Payload) {
   109  		t.Fatalf("failed with seed %d: compare payload.", seed)
   110  	}
   111  	if !isMessageSigned(decrypted.Raw[0]) {
   112  		t.Fatalf("failed with seed %d: unsigned.", seed)
   113  	}
   114  	if len(decrypted.Signature) != signatureLength {
   115  		t.Fatalf("failed with seed %d: signature len %d.", seed, len(decrypted.Signature))
   116  	}
   117  	if !IsPubKeyEqual(decrypted.Src, &params.Src.PublicKey) {
   118  		t.Fatalf("failed with seed %d: signature mismatch.", seed)
   119  	}
   120  }
   121  
   122  func TestMessageEncryption(t *testing.T) {
   123  	InitSingleTest()
   124  
   125  	var symmetric bool
   126  	for i := 0; i < 256; i++ {
   127  		singleMessageTest(t, symmetric)
   128  		symmetric = !symmetric
   129  	}
   130  }
   131  
   132  func TestMessageWrap(t *testing.T) {
   133  	seed = int64(1777444222)
   134  	rand.Seed(seed)
   135  	target := 128.0
   136  
   137  	params, err := generateMessageParams()
   138  	if err != nil {
   139  		t.Fatalf("failed generateMessageParams with seed %d: %s.", seed, err)
   140  	}
   141  
   142  	msg := NewSentMessage(params)
   143  	params.TTL = 1
   144  	params.WorkTime = 12
   145  	params.PoW = target
   146  	env, err := msg.Wrap(params)
   147  	if err != nil {
   148  		t.Fatalf("failed Wrap with seed %d: %s.", seed, err)
   149  	}
   150  
   151  	pow := env.PoW()
   152  	if pow < target {
   153  		t.Fatalf("failed Wrap with seed %d: pow < target (%f vs. %f).", seed, pow, target)
   154  	}
   155  
   156  	// set PoW target too high, expect error
   157  	msg2 := NewSentMessage(params)
   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  	rand.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 := NewSentMessage(params)
   178  	params.TTL = 1
   179  	aesnonce := make([]byte, 12)
   180  	salt := make([]byte, 12)
   181  	randomize(aesnonce)
   182  	randomize(salt)
   183  
   184  	env := NewEnvelope(params.TTL, params.Topic, salt, aesnonce, msg)
   185  	if err != nil {
   186  		t.Fatalf("failed Wrap with seed %d: %s.", seed, err)
   187  	}
   188  
   189  	env.Expiry = uint32(seed) // make it deterministic
   190  	target := 32.0
   191  	params.WorkTime = 4
   192  	params.PoW = target
   193  	env.Seal(params)
   194  
   195  	env.calculatePoW(0)
   196  	pow := env.PoW()
   197  	if pow < target {
   198  		t.Fatalf("failed Wrap with seed %d: pow < target (%f vs. %f).", seed, pow, target)
   199  	}
   200  
   201  	params.WorkTime = 1
   202  	params.PoW = 1000000000.0
   203  	env.Seal(params)
   204  	env.calculatePoW(0)
   205  	pow = env.PoW()
   206  	if pow < 2*target {
   207  		t.Fatalf("failed Wrap with seed %d: pow too small %f.", seed, pow)
   208  	}
   209  }
   210  
   211  func TestEnvelopeOpen(t *testing.T) {
   212  	InitSingleTest()
   213  
   214  	var symmetric bool
   215  	for i := 0; i < 256; i++ {
   216  		singleEnvelopeOpenTest(t, symmetric)
   217  		symmetric = !symmetric
   218  	}
   219  }
   220  
   221  func singleEnvelopeOpenTest(t *testing.T, symmetric bool) {
   222  	params, err := generateMessageParams()
   223  	if err != nil {
   224  		t.Fatalf("failed generateMessageParams with seed %d: %s.", seed, err)
   225  	}
   226  
   227  	key, err := crypto.GenerateKey()
   228  	if err != nil {
   229  		t.Fatalf("failed GenerateKey with seed %d: %s.", seed, err)
   230  	}
   231  
   232  	if !symmetric {
   233  		params.KeySym = nil
   234  		params.Dst = &key.PublicKey
   235  	}
   236  
   237  	text := make([]byte, 0, 512)
   238  	steg := make([]byte, 0, 512)
   239  	text = append(text, params.Payload...)
   240  	steg = append(steg, params.Padding...)
   241  
   242  	msg := NewSentMessage(params)
   243  	env, err := msg.Wrap(params)
   244  	if err != nil {
   245  		t.Fatalf("failed Wrap with seed %d: %s.", seed, err)
   246  	}
   247  
   248  	f := Filter{KeyAsym: key, KeySym: params.KeySym}
   249  	decrypted := env.Open(&f)
   250  	if decrypted == nil {
   251  		t.Fatalf("failed to open with seed %d.", seed)
   252  	}
   253  
   254  	padsz := len(decrypted.Padding)
   255  	if !bytes.Equal(steg[:padsz], decrypted.Padding) {
   256  		t.Fatalf("failed with seed %d: compare padding.", seed)
   257  	}
   258  	if !bytes.Equal(text, decrypted.Payload) {
   259  		t.Fatalf("failed with seed %d: compare payload.", seed)
   260  	}
   261  	if !isMessageSigned(decrypted.Raw[0]) {
   262  		t.Fatalf("failed with seed %d: unsigned.", seed)
   263  	}
   264  	if len(decrypted.Signature) != signatureLength {
   265  		t.Fatalf("failed with seed %d: signature len %d.", seed, len(decrypted.Signature))
   266  	}
   267  	if !IsPubKeyEqual(decrypted.Src, &params.Src.PublicKey) {
   268  		t.Fatalf("failed with seed %d: signature mismatch.", seed)
   269  	}
   270  	if decrypted.isAsymmetricEncryption() == symmetric {
   271  		t.Fatalf("failed with seed %d: asymmetric %v vs. %v.", seed, decrypted.isAsymmetricEncryption(), symmetric)
   272  	}
   273  	if decrypted.isSymmetricEncryption() != symmetric {
   274  		t.Fatalf("failed with seed %d: symmetric %v vs. %v.", seed, decrypted.isSymmetricEncryption(), symmetric)
   275  	}
   276  	if !symmetric {
   277  		if decrypted.Dst == nil {
   278  			t.Fatalf("failed with seed %d: dst is nil.", seed)
   279  		}
   280  		if !IsPubKeyEqual(decrypted.Dst, &key.PublicKey) {
   281  			t.Fatalf("failed with seed %d: Dst.", seed)
   282  		}
   283  	}
   284  }
   285  
   286  func TestEncryptWithZeroKey(t *testing.T) {
   287  	InitSingleTest()
   288  
   289  	params, err := generateMessageParams()
   290  	if err != nil {
   291  		t.Fatalf("failed generateMessageParams with seed %d: %s.", seed, err)
   292  	}
   293  
   294  	msg := NewSentMessage(params)
   295  
   296  	params.KeySym = make([]byte, aesKeyLength)
   297  	_, err = msg.Wrap(params)
   298  	if err == nil {
   299  		t.Fatalf("wrapped with zero key, seed: %d.", seed)
   300  	}
   301  
   302  	params.KeySym = make([]byte, 0)
   303  	_, err = msg.Wrap(params)
   304  	if err == nil {
   305  		t.Fatalf("wrapped with empty key, seed: %d.", seed)
   306  	}
   307  
   308  	params.KeySym = nil
   309  	_, err = msg.Wrap(params)
   310  	if err == nil {
   311  		t.Fatalf("wrapped with nil key, seed: %d.", seed)
   312  	}
   313  }