github.com/ethersphere/bee/v2@v2.2.0/pkg/crypto/signer_test.go (about)

     1  // Copyright 2020 The Swarm Authors. All rights reserved.
     2  // Use of this source code is governed by a BSD-style
     3  // license that can be found in the LICENSE file.
     4  
     5  package crypto_test
     6  
     7  import (
     8  	"bytes"
     9  	"encoding/hex"
    10  	"errors"
    11  	"math/big"
    12  	"testing"
    13  
    14  	"github.com/ethereum/go-ethereum/common"
    15  	"github.com/ethereum/go-ethereum/common/math"
    16  	"github.com/ethereum/go-ethereum/core/types"
    17  	"github.com/ethersphere/bee/v2/pkg/crypto"
    18  	"github.com/ethersphere/bee/v2/pkg/crypto/eip712"
    19  )
    20  
    21  func TestDefaultSigner(t *testing.T) {
    22  	t.Parallel()
    23  
    24  	testBytes := []byte("test string")
    25  	privKey, err := crypto.GenerateSecp256k1Key()
    26  	if err != nil {
    27  		t.Fatal(err)
    28  	}
    29  
    30  	signer := crypto.NewDefaultSigner(privKey)
    31  	signature, err := signer.Sign(testBytes)
    32  	if err != nil {
    33  		t.Fatal(err)
    34  	}
    35  
    36  	t.Run("OK - sign & recover", func(t *testing.T) {
    37  		t.Parallel()
    38  
    39  		pubKey, err := crypto.Recover(signature, testBytes)
    40  		if err != nil {
    41  			t.Fatal(err)
    42  		}
    43  
    44  		if pubKey.X.Cmp(privKey.PublicKey.X) != 0 || pubKey.Y.Cmp(privKey.PublicKey.Y) != 0 {
    45  			t.Fatalf("wanted %v but got %v", pubKey, &privKey.PublicKey)
    46  		}
    47  	})
    48  
    49  	t.Run("OK - recover with invalid data", func(t *testing.T) {
    50  		t.Parallel()
    51  
    52  		pubKey, err := crypto.Recover(signature, []byte("invalid"))
    53  		if err != nil {
    54  			t.Fatal(err)
    55  		}
    56  
    57  		if pubKey.X.Cmp(privKey.PublicKey.X) == 0 && pubKey.Y.Cmp(privKey.PublicKey.Y) == 0 {
    58  			t.Fatal("expected different public key")
    59  		}
    60  	})
    61  
    62  	t.Run("OK - recover with short signature", func(t *testing.T) {
    63  		t.Parallel()
    64  
    65  		_, err := crypto.Recover([]byte("invalid"), testBytes)
    66  		if err == nil {
    67  			t.Fatal("expected invalid length error but got none")
    68  		}
    69  		if !errors.Is(err, crypto.ErrInvalidLength) {
    70  			t.Fatalf("expected invalid length error but got %v", err)
    71  		}
    72  	})
    73  }
    74  
    75  func TestDefaultSignerEthereumAddress(t *testing.T) {
    76  	t.Parallel()
    77  
    78  	data, err := hex.DecodeString("634fb5a872396d9693e5c9f9d7233cfa93f395c093371017ff44aa9ae6564cdd")
    79  	if err != nil {
    80  		t.Fatal(err)
    81  	}
    82  
    83  	privKey, err := crypto.DecodeSecp256k1PrivateKey(data)
    84  	if err != nil {
    85  		t.Fatal(err)
    86  	}
    87  
    88  	signer := crypto.NewDefaultSigner(privKey)
    89  	ethAddress, err := signer.EthereumAddress()
    90  	if err != nil {
    91  		t.Fatal(err)
    92  	}
    93  
    94  	expected := common.HexToAddress("8d3766440f0d7b949a5e32995d09619a7f86e632")
    95  	if ethAddress != expected {
    96  		t.Fatalf("wrong signature. expected %x, got %x", expected, ethAddress)
    97  	}
    98  }
    99  
   100  func TestDefaultSignerSignTx(t *testing.T) {
   101  	t.Parallel()
   102  
   103  	data, err := hex.DecodeString("634fb5a872396d9693e5c9f9d7233cfa93f395c093371017ff44aa9ae6564cdd")
   104  	if err != nil {
   105  		t.Fatal(err)
   106  	}
   107  
   108  	privKey, err := crypto.DecodeSecp256k1PrivateKey(data)
   109  	if err != nil {
   110  		t.Fatal(err)
   111  	}
   112  
   113  	signer := crypto.NewDefaultSigner(privKey)
   114  	beneficiary := common.HexToAddress("8d3766440f0d7b949a5e32995d09619a7f86e632")
   115  
   116  	chainID := big.NewInt(10)
   117  
   118  	tx, err := signer.SignTx(types.NewTx(&types.LegacyTx{
   119  		Nonce:    0,
   120  		To:       &beneficiary,
   121  		Value:    big.NewInt(0),
   122  		Gas:      21000,
   123  		GasPrice: big.NewInt(1),
   124  		Data:     []byte{1},
   125  	}), chainID)
   126  	if err != nil {
   127  		t.Fatal(err)
   128  	}
   129  
   130  	expectedR := math.MustParseBig256("0x2937d18005a8236330b95c6b271ff46b06d5bf25355a06ff50939c9023245a99")
   131  	expectedS := math.MustParseBig256("0xcd7c13b2bb88a3d99004a80898fc05b50263f445f6c53ef7baf7ffca0e4a1bf")
   132  	expectedV := math.MustParseBig256("0x37")
   133  
   134  	v, r, s := tx.RawSignatureValues()
   135  
   136  	if expectedV.Cmp(v) != 0 {
   137  		t.Fatalf("wrong v value. expected %x, got %x", expectedV, v)
   138  	}
   139  
   140  	if expectedR.Cmp(r) != 0 {
   141  		t.Fatalf("wrong r value. expected %x, got %x", expectedR, r)
   142  	}
   143  
   144  	if expectedS.Cmp(s) != 0 {
   145  		t.Fatalf("wrong s value. expected %x, got %x", expectedS, s)
   146  	}
   147  }
   148  
   149  var testTypedData = &eip712.TypedData{
   150  	Domain: eip712.TypedDataDomain{
   151  		Name:    "test",
   152  		Version: "1.0",
   153  	},
   154  	Types: eip712.Types{
   155  		"EIP712Domain": {
   156  			{
   157  				Name: "name",
   158  				Type: "string",
   159  			},
   160  			{
   161  				Name: "version",
   162  				Type: "string",
   163  			},
   164  		},
   165  		"MyType": {
   166  			{
   167  				Name: "test",
   168  				Type: "string",
   169  			},
   170  		},
   171  	},
   172  	Message: eip712.TypedDataMessage{
   173  		"test": "abc",
   174  	},
   175  	PrimaryType: "MyType",
   176  }
   177  
   178  func TestDefaultSignerTypedData(t *testing.T) {
   179  	t.Parallel()
   180  
   181  	data, err := hex.DecodeString("634fb5a872396d9693e5c9f9d7233cfa93f395c093371017ff44aa9ae6564cdd")
   182  	if err != nil {
   183  		t.Fatal(err)
   184  	}
   185  
   186  	privKey, err := crypto.DecodeSecp256k1PrivateKey(data)
   187  	if err != nil {
   188  		t.Fatal(err)
   189  	}
   190  
   191  	signer := crypto.NewDefaultSigner(privKey)
   192  
   193  	sig, err := signer.SignTypedData(testTypedData)
   194  	if err != nil {
   195  		t.Fatal(err)
   196  	}
   197  
   198  	expected, err := hex.DecodeString("60f054c45d37a0359d4935da0454bc19f02a8c01ceee8a112cfe48c8e2357b842e897f76389fb96947c6d2c80cbfe081052204e7b0c3cc1194a973a09b1614f71c")
   199  	if err != nil {
   200  		t.Fatal(err)
   201  	}
   202  
   203  	if !bytes.Equal(expected, sig) {
   204  		t.Fatalf("wrong signature. expected %x, got %x", expected, sig)
   205  	}
   206  }
   207  
   208  func TestRecoverEIP712(t *testing.T) {
   209  	t.Parallel()
   210  
   211  	data, err := hex.DecodeString("634fb5a872396d9693e5c9f9d7233cfa93f395c093371017ff44aa9ae6564cdd")
   212  	if err != nil {
   213  		t.Fatal(err)
   214  	}
   215  
   216  	privKey, err := crypto.DecodeSecp256k1PrivateKey(data)
   217  	if err != nil {
   218  		t.Fatal(err)
   219  	}
   220  
   221  	expected, err := hex.DecodeString("60f054c45d37a0359d4935da0454bc19f02a8c01ceee8a112cfe48c8e2357b842e897f76389fb96947c6d2c80cbfe081052204e7b0c3cc1194a973a09b1614f71c")
   222  	if err != nil {
   223  		t.Fatal(err)
   224  	}
   225  
   226  	pubKey, err := crypto.RecoverEIP712(expected, testTypedData)
   227  	if err != nil {
   228  		t.Fatal(err)
   229  	}
   230  
   231  	if privKey.PublicKey.X.Cmp(pubKey.X) != 0 {
   232  		t.Fatalf("recovered wrong public key. wanted %x, got %x", privKey.PublicKey, pubKey)
   233  	}
   234  
   235  	if privKey.PublicKey.Y.Cmp(pubKey.Y) != 0 {
   236  		t.Fatalf("recovered wrong public key. wanted %x, got %x", privKey.PublicKey, pubKey)
   237  	}
   238  }
   239  
   240  func TestDefaultSignerDeterministic(t *testing.T) {
   241  	t.Parallel()
   242  
   243  	data, err := hex.DecodeString("634fb5a872396d9693e5c9f9d7233cfa93f395c093371017ff44aa9ae6564cdd")
   244  	if err != nil {
   245  		t.Fatal(err)
   246  	}
   247  
   248  	privKey, err := crypto.DecodeSecp256k1PrivateKey(data)
   249  	if err != nil {
   250  		t.Fatal(err)
   251  	}
   252  
   253  	digest, err := hex.DecodeString("2c26b46b68ffc68ff99b453c1d30413413422d706483bfa0f98a5e886266e7ae")
   254  	if err != nil {
   255  		t.Fatal(err)
   256  	}
   257  
   258  	signer := crypto.NewDefaultSigner(privKey)
   259  	sig, err := signer.Sign(digest)
   260  	if err != nil {
   261  		t.Fatal(err)
   262  	}
   263  	expSig, err := hex.DecodeString("336d24afef78c5883b96ad9a62552a8db3d236105cb059ddd04dc49680869dc16234f6852c277087f025d4114c4fac6b40295ecffd1194a84cdb91bd571769491b")
   264  	if err != nil {
   265  		t.Fatal(err)
   266  	}
   267  	if !bytes.Equal(expSig, sig) {
   268  		t.Fatal("signature mismatch")
   269  	}
   270  }