github.com/aquanetwork/aquachain@v1.7.8/opt/whisper/whisperv6/message_test.go (about)

     1  // Copyright 2016 The aquachain Authors
     2  // This file is part of the aquachain library.
     3  //
     4  // The aquachain 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 aquachain 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 aquachain library. If not, see <http://www.gnu.org/licenses/>.
    16  
    17  package whisperv6
    18  
    19  import (
    20  	"bytes"
    21  	"crypto/aes"
    22  	"crypto/cipher"
    23  	mrand "math/rand"
    24  	"testing"
    25  
    26  	"gitlab.com/aquachain/aquachain/common/hexutil"
    27  	"gitlab.com/aquachain/aquachain/crypto"
    28  	"gitlab.com/aquachain/aquachain/rlp"
    29  )
    30  
    31  func generateMessageParams() (*MessageParams, error) {
    32  	// set all the parameters except p.Dst and p.Padding
    33  
    34  	buf := make([]byte, 4)
    35  	mrand.Read(buf)
    36  	sz := mrand.Intn(400)
    37  
    38  	var p MessageParams
    39  	p.PoW = 0.01
    40  	p.WorkTime = 1
    41  	p.TTL = uint32(mrand.Intn(1024))
    42  	p.Payload = make([]byte, sz)
    43  	p.KeySym = make([]byte, aesKeyLength)
    44  	mrand.Read(p.Payload)
    45  	mrand.Read(p.KeySym)
    46  	p.Topic = BytesToTopic(buf)
    47  
    48  	var err error
    49  	p.Src, err = crypto.GenerateKey()
    50  	if err != nil {
    51  		return nil, err
    52  	}
    53  
    54  	return &p, nil
    55  }
    56  
    57  func singleMessageTest(t *testing.T, symmetric bool) {
    58  	params, err := generateMessageParams()
    59  	if err != nil {
    60  		t.Fatalf("failed generateMessageParams with seed %d: %s.", seed, err)
    61  	}
    62  
    63  	key, err := crypto.GenerateKey()
    64  	if err != nil {
    65  		t.Fatalf("failed GenerateKey with seed %d: %s.", seed, err)
    66  	}
    67  
    68  	if !symmetric {
    69  		params.KeySym = nil
    70  		params.Dst = &key.PublicKey
    71  	}
    72  
    73  	text := make([]byte, 0, 512)
    74  	text = append(text, params.Payload...)
    75  
    76  	msg, err := NewSentMessage(params)
    77  	if err != nil {
    78  		t.Fatalf("failed to create new message with seed %d: %s.", seed, err)
    79  	}
    80  	env, err := msg.Wrap(params)
    81  	if err != nil {
    82  		t.Fatalf("failed Wrap with seed %d: %s.", seed, err)
    83  	}
    84  
    85  	var decrypted *ReceivedMessage
    86  	if symmetric {
    87  		decrypted, err = env.OpenSymmetric(params.KeySym)
    88  	} else {
    89  		decrypted, err = env.OpenAsymmetric(key)
    90  	}
    91  
    92  	if err != nil {
    93  		t.Fatalf("failed to encrypt with seed %d: %s.", seed, err)
    94  	}
    95  
    96  	if !decrypted.ValidateAndParse() {
    97  		t.Fatalf("failed to validate with seed %d, symmetric = %v.", seed, symmetric)
    98  	}
    99  
   100  	if !bytes.Equal(text, decrypted.Payload) {
   101  		t.Fatalf("failed with seed %d: compare payload.", seed)
   102  	}
   103  	if !isMessageSigned(decrypted.Raw[0]) {
   104  		t.Fatalf("failed with seed %d: unsigned.", seed)
   105  	}
   106  	if len(decrypted.Signature) != signatureLength {
   107  		t.Fatalf("failed with seed %d: signature len %d.", seed, len(decrypted.Signature))
   108  	}
   109  	if !IsPubKeyEqual(decrypted.Src, &params.Src.PublicKey) {
   110  		t.Fatalf("failed with seed %d: signature mismatch.", seed)
   111  	}
   112  }
   113  
   114  func TestMessageEncryption(t *testing.T) {
   115  	InitSingleTest()
   116  
   117  	var symmetric bool
   118  	for i := 0; i < 256; i++ {
   119  		singleMessageTest(t, symmetric)
   120  		symmetric = !symmetric
   121  	}
   122  }
   123  
   124  func TestMessageWrap(t *testing.T) {
   125  	seed = int64(1777444222)
   126  	mrand.Seed(seed)
   127  	target := 128.0
   128  
   129  	params, err := generateMessageParams()
   130  	if err != nil {
   131  		t.Fatalf("failed generateMessageParams with seed %d: %s.", seed, err)
   132  	}
   133  
   134  	msg, err := NewSentMessage(params)
   135  	if err != nil {
   136  		t.Fatalf("failed to create new message with seed %d: %s.", seed, err)
   137  	}
   138  	params.TTL = 1
   139  	params.WorkTime = 12
   140  	params.PoW = target
   141  	env, err := msg.Wrap(params)
   142  	if err != nil {
   143  		t.Fatalf("failed Wrap with seed %d: %s.", seed, err)
   144  	}
   145  
   146  	pow := env.PoW()
   147  	if pow < target {
   148  		t.Fatalf("failed Wrap with seed %d: pow < target (%f vs. %f).", seed, pow, target)
   149  	}
   150  
   151  	// set PoW target too high, expect error
   152  	msg2, err := NewSentMessage(params)
   153  	if err != nil {
   154  		t.Fatalf("failed to create new message with seed %d: %s.", seed, err)
   155  	}
   156  	params.TTL = 1000000
   157  	params.WorkTime = 1
   158  	params.PoW = 10000000.0
   159  	_, err = msg2.Wrap(params)
   160  	if err == nil {
   161  		t.Fatalf("unexpectedly reached the PoW target with seed %d.", seed)
   162  	}
   163  }
   164  
   165  func TestMessageSeal(t *testing.T) {
   166  	// this test depends on deterministic choice of seed (1976726903)
   167  	seed = int64(1976726903)
   168  	mrand.Seed(seed)
   169  
   170  	params, err := generateMessageParams()
   171  	if err != nil {
   172  		t.Fatalf("failed generateMessageParams with seed %d: %s.", seed, err)
   173  	}
   174  
   175  	msg, err := NewSentMessage(params)
   176  	if err != nil {
   177  		t.Fatalf("failed to create new message with seed %d: %s.", seed, err)
   178  	}
   179  	params.TTL = 1
   180  
   181  	env := NewEnvelope(params.TTL, params.Topic, msg)
   182  	if err != nil {
   183  		t.Fatalf("failed Wrap with seed %d: %s.", seed, err)
   184  	}
   185  
   186  	env.Expiry = uint32(seed) // make it deterministic
   187  	target := 32.0
   188  	params.WorkTime = 4
   189  	params.PoW = target
   190  	env.Seal(params)
   191  
   192  	env.calculatePoW(0)
   193  	pow := env.PoW()
   194  	if pow < target {
   195  		t.Fatalf("failed Wrap with seed %d: pow < target (%f vs. %f).", seed, pow, target)
   196  	}
   197  
   198  	params.WorkTime = 1
   199  	params.PoW = 1000000000.0
   200  	env.Seal(params)
   201  	env.calculatePoW(0)
   202  	pow = env.PoW()
   203  	if pow < 2*target {
   204  		t.Fatalf("failed Wrap with seed %d: pow too small %f.", seed, pow)
   205  	}
   206  }
   207  
   208  func TestEnvelopeOpen(t *testing.T) {
   209  	InitSingleTest()
   210  
   211  	var symmetric bool
   212  	for i := 0; i < 32; i++ {
   213  		singleEnvelopeOpenTest(t, symmetric)
   214  		symmetric = !symmetric
   215  	}
   216  }
   217  
   218  func singleEnvelopeOpenTest(t *testing.T, symmetric bool) {
   219  	params, err := generateMessageParams()
   220  	if err != nil {
   221  		t.Fatalf("failed generateMessageParams with seed %d: %s.", seed, err)
   222  	}
   223  
   224  	key, err := crypto.GenerateKey()
   225  	if err != nil {
   226  		t.Fatalf("failed GenerateKey with seed %d: %s.", seed, err)
   227  	}
   228  
   229  	if !symmetric {
   230  		params.KeySym = nil
   231  		params.Dst = &key.PublicKey
   232  	}
   233  
   234  	text := make([]byte, 0, 512)
   235  	text = append(text, params.Payload...)
   236  
   237  	msg, err := NewSentMessage(params)
   238  	if err != nil {
   239  		t.Fatalf("failed to create new message with seed %d: %s.", seed, err)
   240  	}
   241  	env, err := msg.Wrap(params)
   242  	if err != nil {
   243  		t.Fatalf("failed Wrap with seed %d: %s.", seed, err)
   244  	}
   245  
   246  	var f Filter
   247  	if symmetric {
   248  		f = Filter{KeySym: params.KeySym}
   249  	} else {
   250  		f = Filter{KeyAsym: key}
   251  	}
   252  	decrypted := env.Open(&f)
   253  	if decrypted == nil {
   254  		t.Fatalf("failed to open with seed %d.", seed)
   255  	}
   256  
   257  	if !bytes.Equal(text, decrypted.Payload) {
   258  		t.Fatalf("failed with seed %d: compare payload.", seed)
   259  	}
   260  	if !isMessageSigned(decrypted.Raw[0]) {
   261  		t.Fatalf("failed with seed %d: unsigned.", seed)
   262  	}
   263  	if len(decrypted.Signature) != signatureLength {
   264  		t.Fatalf("failed with seed %d: signature len %d.", seed, len(decrypted.Signature))
   265  	}
   266  	if !IsPubKeyEqual(decrypted.Src, &params.Src.PublicKey) {
   267  		t.Fatalf("failed with seed %d: signature mismatch.", seed)
   268  	}
   269  	if decrypted.isAsymmetricEncryption() == symmetric {
   270  		t.Fatalf("failed with seed %d: asymmetric %v vs. %v.", seed, decrypted.isAsymmetricEncryption(), symmetric)
   271  	}
   272  	if decrypted.isSymmetricEncryption() != symmetric {
   273  		t.Fatalf("failed with seed %d: symmetric %v vs. %v.", seed, decrypted.isSymmetricEncryption(), symmetric)
   274  	}
   275  	if !symmetric {
   276  		if decrypted.Dst == nil {
   277  			t.Fatalf("failed with seed %d: dst is nil.", seed)
   278  		}
   279  		if !IsPubKeyEqual(decrypted.Dst, &key.PublicKey) {
   280  			t.Fatalf("failed with seed %d: Dst.", seed)
   281  		}
   282  	}
   283  }
   284  
   285  func TestEncryptWithZeroKey(t *testing.T) {
   286  	InitSingleTest()
   287  
   288  	params, err := generateMessageParams()
   289  	if err != nil {
   290  		t.Fatalf("failed generateMessageParams with seed %d: %s.", seed, err)
   291  	}
   292  	msg, err := NewSentMessage(params)
   293  	if err != nil {
   294  		t.Fatalf("failed to create new message with seed %d: %s.", seed, err)
   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, err = generateMessageParams()
   303  	if err != nil {
   304  		t.Fatalf("failed generateMessageParams with seed %d: %s.", seed, err)
   305  	}
   306  	msg, err = NewSentMessage(params)
   307  	if err != nil {
   308  		t.Fatalf("failed to create new message with seed %d: %s.", seed, err)
   309  	}
   310  	params.KeySym = make([]byte, 0)
   311  	_, err = msg.Wrap(params)
   312  	if err == nil {
   313  		t.Fatalf("wrapped with empty key, seed: %d.", seed)
   314  	}
   315  
   316  	params, err = generateMessageParams()
   317  	if err != nil {
   318  		t.Fatalf("failed generateMessageParams with seed %d: %s.", seed, err)
   319  	}
   320  	msg, err = NewSentMessage(params)
   321  	if err != nil {
   322  		t.Fatalf("failed to create new message with seed %d: %s.", seed, err)
   323  	}
   324  	params.KeySym = nil
   325  	_, err = msg.Wrap(params)
   326  	if err == nil {
   327  		t.Fatalf("wrapped with nil key, seed: %d.", seed)
   328  	}
   329  }
   330  
   331  func TestRlpEncode(t *testing.T) {
   332  	InitSingleTest()
   333  
   334  	params, err := generateMessageParams()
   335  	if err != nil {
   336  		t.Fatalf("failed generateMessageParams with seed %d: %s.", seed, err)
   337  	}
   338  	msg, err := NewSentMessage(params)
   339  	if err != nil {
   340  		t.Fatalf("failed to create new message with seed %d: %s.", seed, err)
   341  	}
   342  	env, err := msg.Wrap(params)
   343  	if err != nil {
   344  		t.Fatalf("wrapped with zero key, seed: %d.", seed)
   345  	}
   346  
   347  	raw, err := rlp.EncodeToBytes(env)
   348  	if err != nil {
   349  		t.Fatalf("RLP encode failed: %s.", err)
   350  	}
   351  
   352  	var decoded Envelope
   353  	rlp.DecodeBytes(raw, &decoded)
   354  	if err != nil {
   355  		t.Fatalf("RLP decode failed: %s.", err)
   356  	}
   357  
   358  	he := env.Hash()
   359  	hd := decoded.Hash()
   360  
   361  	if he != hd {
   362  		t.Fatalf("Hashes are not equal: %x vs. %x", he, hd)
   363  	}
   364  }
   365  
   366  func singlePaddingTest(t *testing.T, padSize int) {
   367  	params, err := generateMessageParams()
   368  	if err != nil {
   369  		t.Fatalf("failed generateMessageParams with seed %d and sz=%d: %s.", seed, padSize, err)
   370  	}
   371  	params.Padding = make([]byte, padSize)
   372  	params.PoW = 0.0000000001
   373  	pad := make([]byte, padSize)
   374  	_, err = mrand.Read(pad)
   375  	if err != nil {
   376  		t.Fatalf("padding is not generated (seed %d): %s", seed, err)
   377  	}
   378  	n := copy(params.Padding, pad)
   379  	if n != padSize {
   380  		t.Fatalf("padding is not copied (seed %d): %s", seed, err)
   381  	}
   382  	msg, err := NewSentMessage(params)
   383  	if err != nil {
   384  		t.Fatalf("failed to create new message with seed %d: %s.", seed, err)
   385  	}
   386  	env, err := msg.Wrap(params)
   387  	if err != nil {
   388  		t.Fatalf("failed to wrap, seed: %d and sz=%d.", seed, padSize)
   389  	}
   390  	f := Filter{KeySym: params.KeySym}
   391  	decrypted := env.Open(&f)
   392  	if decrypted == nil {
   393  		t.Fatalf("failed to open, seed and sz=%d: %d.", seed, padSize)
   394  	}
   395  	if !bytes.Equal(pad, decrypted.Padding) {
   396  		t.Fatalf("padding is not retireved as expected with seed %d and sz=%d:\n[%x]\n[%x].", seed, padSize, pad, decrypted.Padding)
   397  	}
   398  }
   399  
   400  func TestPadding(t *testing.T) {
   401  	InitSingleTest()
   402  
   403  	for i := 1; i < 260; i++ {
   404  		singlePaddingTest(t, i)
   405  	}
   406  
   407  	lim := 256 * 256
   408  	for i := lim - 5; i < lim+2; i++ {
   409  		singlePaddingTest(t, i)
   410  	}
   411  
   412  	for i := 0; i < 256; i++ {
   413  		n := mrand.Intn(256*254) + 256
   414  		singlePaddingTest(t, n)
   415  	}
   416  
   417  	for i := 0; i < 256; i++ {
   418  		n := mrand.Intn(256*1024) + 256*256
   419  		singlePaddingTest(t, n)
   420  	}
   421  }
   422  
   423  func TestPaddingAppendedToSymMessagesWithSignature(t *testing.T) {
   424  	params := &MessageParams{
   425  		Payload: make([]byte, 246),
   426  		KeySym:  make([]byte, aesKeyLength),
   427  	}
   428  
   429  	pSrc, err := crypto.GenerateKey()
   430  
   431  	if err != nil {
   432  		t.Fatalf("Error creating the signature key %v", err)
   433  		return
   434  	}
   435  	params.Src = pSrc
   436  
   437  	// Simulate a message with a payload just under 256 so that
   438  	// payload + flag + signature > 256. Check that the result
   439  	// is padded on the next 256 boundary.
   440  	msg := sentMessage{}
   441  	const payloadSizeFieldMinSize = 1
   442  	msg.Raw = make([]byte, flagsLength+payloadSizeFieldMinSize+len(params.Payload))
   443  
   444  	err = msg.appendPadding(params)
   445  
   446  	if err != nil {
   447  		t.Fatalf("Error appending padding to message %v", err)
   448  		return
   449  	}
   450  
   451  	if len(msg.Raw) != 512-signatureLength {
   452  		t.Errorf("Invalid size %d != 512", len(msg.Raw))
   453  	}
   454  }
   455  
   456  func TestAesNonce(t *testing.T) {
   457  	key := hexutil.MustDecode("0x03ca634cae0d49acb401d8a4c6b6fe8c55b70d115bf400769cc1400f3258cd31")
   458  	block, err := aes.NewCipher(key)
   459  	if err != nil {
   460  		t.Fatalf("NewCipher failed: %s", err)
   461  	}
   462  	aesgcm, err := cipher.NewGCM(block)
   463  	if err != nil {
   464  		t.Fatalf("NewGCM failed: %s", err)
   465  	}
   466  	// This is the most important single test in this package.
   467  	// If it fails, whisper will not be working.
   468  	if aesgcm.NonceSize() != aesNonceLength {
   469  		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.")
   470  	}
   471  }