github.com/SmartMeshFoundation/Spectrum@v0.0.0-20220621030607-452a266fee1e/whisper/whisperv2/message_test.go (about)

     1  // Copyright 2014 The Spectrum Authors
     2  // This file is part of the Spectrum library.
     3  //
     4  // The Spectrum 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 Spectrum 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 Spectrum library. If not, see <http://www.gnu.org/licenses/>.
    16  
    17  package whisperv2
    18  
    19  import (
    20  	"bytes"
    21  	"crypto/elliptic"
    22  	"testing"
    23  	"time"
    24  
    25  	"github.com/SmartMeshFoundation/Spectrum/crypto"
    26  )
    27  
    28  // Tests whether a message can be wrapped without any identity or encryption.
    29  func TestMessageSimpleWrap(t *testing.T) {
    30  	payload := []byte("hello world")
    31  
    32  	msg := NewMessage(payload)
    33  	if _, err := msg.Wrap(DefaultPoW, Options{}); err != nil {
    34  		t.Fatalf("failed to wrap message: %v", err)
    35  	}
    36  	if msg.Flags&signatureFlag != 0 {
    37  		t.Fatalf("signature flag mismatch: have %d, want %d", msg.Flags&signatureFlag, 0)
    38  	}
    39  	if len(msg.Signature) != 0 {
    40  		t.Fatalf("signature found for simple wrapping: 0x%x", msg.Signature)
    41  	}
    42  	if !bytes.Equal(msg.Payload, payload) {
    43  		t.Fatalf("payload mismatch after wrapping: have 0x%x, want 0x%x", msg.Payload, payload)
    44  	}
    45  	if msg.TTL/time.Second != DefaultTTL/time.Second {
    46  		t.Fatalf("message TTL mismatch: have %v, want %v", msg.TTL, DefaultTTL)
    47  	}
    48  }
    49  
    50  // Tests whether a message can be signed, and wrapped in plain-text.
    51  func TestMessageCleartextSignRecover(t *testing.T) {
    52  	key, err := crypto.GenerateKey()
    53  	if err != nil {
    54  		t.Fatalf("failed to create crypto key: %v", err)
    55  	}
    56  	payload := []byte("hello world")
    57  
    58  	msg := NewMessage(payload)
    59  	if _, err := msg.Wrap(DefaultPoW, Options{
    60  		From: key,
    61  	}); err != nil {
    62  		t.Fatalf("failed to sign message: %v", err)
    63  	}
    64  	if msg.Flags&signatureFlag != signatureFlag {
    65  		t.Fatalf("signature flag mismatch: have %d, want %d", msg.Flags&signatureFlag, signatureFlag)
    66  	}
    67  	if !bytes.Equal(msg.Payload, payload) {
    68  		t.Fatalf("payload mismatch after signing: have 0x%x, want 0x%x", msg.Payload, payload)
    69  	}
    70  
    71  	pubKey := msg.Recover()
    72  	if pubKey == nil {
    73  		t.Fatalf("failed to recover public key")
    74  	}
    75  	p1 := elliptic.Marshal(crypto.S256(), key.PublicKey.X, key.PublicKey.Y)
    76  	p2 := elliptic.Marshal(crypto.S256(), pubKey.X, pubKey.Y)
    77  	if !bytes.Equal(p1, p2) {
    78  		t.Fatalf("public key mismatch: have 0x%x, want 0x%x", p2, p1)
    79  	}
    80  }
    81  
    82  // Tests whether a message can be encrypted and decrypted using an anonymous
    83  // sender (i.e. no signature).
    84  func TestMessageAnonymousEncryptDecrypt(t *testing.T) {
    85  	key, err := crypto.GenerateKey()
    86  	if err != nil {
    87  		t.Fatalf("failed to create recipient crypto key: %v", err)
    88  	}
    89  	payload := []byte("hello world")
    90  
    91  	msg := NewMessage(payload)
    92  	envelope, err := msg.Wrap(DefaultPoW, Options{
    93  		To: &key.PublicKey,
    94  	})
    95  	if err != nil {
    96  		t.Fatalf("failed to encrypt message: %v", err)
    97  	}
    98  	if msg.Flags&signatureFlag != 0 {
    99  		t.Fatalf("signature flag mismatch: have %d, want %d", msg.Flags&signatureFlag, 0)
   100  	}
   101  	if len(msg.Signature) != 0 {
   102  		t.Fatalf("signature found for anonymous message: 0x%x", msg.Signature)
   103  	}
   104  
   105  	out, err := envelope.Open(key)
   106  	if err != nil {
   107  		t.Fatalf("failed to open encrypted message: %v", err)
   108  	}
   109  	if !bytes.Equal(out.Payload, payload) {
   110  		t.Errorf("payload mismatch: have 0x%x, want 0x%x", out.Payload, payload)
   111  	}
   112  }
   113  
   114  // Tests whether a message can be properly signed and encrypted.
   115  func TestMessageFullCrypto(t *testing.T) {
   116  	fromKey, err := crypto.GenerateKey()
   117  	if err != nil {
   118  		t.Fatalf("failed to create sender crypto key: %v", err)
   119  	}
   120  	toKey, err := crypto.GenerateKey()
   121  	if err != nil {
   122  		t.Fatalf("failed to create recipient crypto key: %v", err)
   123  	}
   124  
   125  	payload := []byte("hello world")
   126  	msg := NewMessage(payload)
   127  	envelope, err := msg.Wrap(DefaultPoW, Options{
   128  		From: fromKey,
   129  		To:   &toKey.PublicKey,
   130  	})
   131  	if err != nil {
   132  		t.Fatalf("failed to encrypt message: %v", err)
   133  	}
   134  	if msg.Flags&signatureFlag != signatureFlag {
   135  		t.Fatalf("signature flag mismatch: have %d, want %d", msg.Flags&signatureFlag, signatureFlag)
   136  	}
   137  	if len(msg.Signature) == 0 {
   138  		t.Fatalf("no signature found for signed message")
   139  	}
   140  
   141  	out, err := envelope.Open(toKey)
   142  	if err != nil {
   143  		t.Fatalf("failed to open encrypted message: %v", err)
   144  	}
   145  	if !bytes.Equal(out.Payload, payload) {
   146  		t.Errorf("payload mismatch: have 0x%x, want 0x%x", out.Payload, payload)
   147  	}
   148  
   149  	pubKey := out.Recover()
   150  	if pubKey == nil {
   151  		t.Fatalf("failed to recover public key")
   152  	}
   153  	p1 := elliptic.Marshal(crypto.S256(), fromKey.PublicKey.X, fromKey.PublicKey.Y)
   154  	p2 := elliptic.Marshal(crypto.S256(), pubKey.X, pubKey.Y)
   155  	if !bytes.Equal(p1, p2) {
   156  		t.Fatalf("public key mismatch: have 0x%x, want 0x%x", p2, p1)
   157  	}
   158  }