github.com/sberex/go-sberex@v1.8.2-0.20181113200658-ed96ac38f7d7/whisper/whisperv5/message_test.go (about)

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