github.com/decred/dcrlnd@v0.7.6/lnwire/signature_test.go (about)

     1  package lnwire
     2  
     3  import (
     4  	"math/big"
     5  	"testing"
     6  
     7  	secpv2 "github.com/decred/dcrd/dcrec/secp256k1/v2"
     8  	"github.com/decred/dcrd/dcrec/secp256k1/v4"
     9  	"github.com/stretchr/testify/require"
    10  )
    11  
    12  func TestSignatureSerializeDeserialize(t *testing.T) {
    13  	t.Parallel()
    14  
    15  	// Local-scoped closure to serialize and deserialize a Signature and
    16  	// check for errors as well as check if the results are correct.
    17  	signatureSerializeDeserialize := func(e secpv2.Signature) error {
    18  		// NOTE(decred): Instead of using NewSigFromSignature we use
    19  		// NewSigFromRawSignature due to performing the test with the
    20  		// v2 secp256k1 lib that allows internal access to R and S and
    21  		// allows creating invalid encoded sigs.
    22  		sig, err := NewSigFromRawSignature(e.Serialize())
    23  		if err != nil {
    24  			return err
    25  		}
    26  
    27  		_, err = sig.ToSignature()
    28  		if err != nil {
    29  			return err
    30  		}
    31  
    32  		// NOTE(decred) These are commented because the secp256k1/v4
    33  		// doesn't provide access to the internal R and S.
    34  		/*
    35  			if e.R.Cmp(e2.R) != 0 {
    36  				return fmt.Errorf("Pre/post-serialize Rs don't match"+
    37  					": %s, %s", e.R, e2.R)
    38  			}
    39  			if e.S.Cmp(e2.S) != 0 {
    40  				return fmt.Errorf("Pre/post-serialize Ss don't match"+
    41  					": %s, %s", e.S, e2.S)
    42  			}
    43  		*/
    44  		return nil
    45  	}
    46  
    47  	sig := secpv2.Signature{}
    48  
    49  	// Check R = N-1, S = 128.
    50  	sig.R = big.NewInt(1) // Allocate a big.Int before we call .Sub.
    51  	sig.R.Sub(secp256k1.S256().N, sig.R)
    52  	sig.S = big.NewInt(128)
    53  	err := signatureSerializeDeserialize(sig)
    54  	if err != nil {
    55  		t.Fatalf("R = N-1, S = 128: %s", err.Error())
    56  	}
    57  
    58  	// Check R = N-1, S = 127.
    59  	sig.S = big.NewInt(127)
    60  	err = signatureSerializeDeserialize(sig)
    61  	if err != nil {
    62  		t.Fatalf("R = N-1, S = 127: %s", err.Error())
    63  	}
    64  
    65  	// Check R = N-1, S = N>>1.
    66  	sig.S.Set(secp256k1.S256().N)
    67  	sig.S.Rsh(sig.S, 1)
    68  	err = signatureSerializeDeserialize(sig)
    69  	if err != nil {
    70  		t.Fatalf("R = N-1, S = N>>1: %s", err.Error())
    71  	}
    72  
    73  	// Check R = N-1, S = N.
    74  	sig.S.Set(secp256k1.S256().N)
    75  	err = signatureSerializeDeserialize(sig)
    76  	if err.Error() != "invalid signature: S is 0" {
    77  		t.Fatalf("R = N-1, S = N should become R = N-1, S = 0: %s",
    78  			err.Error())
    79  	}
    80  
    81  	// Check R = N-1, S = N-1.
    82  	sig.S.Sub(sig.S, big.NewInt(1))
    83  	// NOTE(decred): this is commented because secp256k1/v4 doesn't provide
    84  	// access to R and S for the comparison to be performed.
    85  	/*
    86  		err = signatureSerializeDeserialize(sig)
    87  		if err.Error() != "Pre/post-serialize Ss don't match: 115792089237316"+
    88  			"195423570985008687907852837564279074904382605163141518161494"+
    89  			"336, 1" {
    90  			t.Fatalf("R = N-1, S = N-1 should become R = N-1, S = 1: %s",
    91  				err.Error())
    92  		}
    93  	*/
    94  
    95  	// Check R = 2N, S = 128
    96  	sig.R.Mul(secp256k1.S256().N, big.NewInt(2))
    97  	sig.S.Set(big.NewInt(127))
    98  	err = signatureSerializeDeserialize(sig)
    99  	if err.Error() != "element R is over 32 bytes long without padding" {
   100  		t.Fatalf("R = 2N, S = 128, R should be over 32 bytes: %s",
   101  			err.Error())
   102  	}
   103  }
   104  
   105  var (
   106  	// signatures from bitcoin blockchain tx
   107  	// 0437cd7f8525ceed2324359c2d0ba26006d92d85.
   108  	normalSig = []byte{
   109  		0x30, 0x44, 0x02, 0x20,
   110  		// r value
   111  		0x4e, 0x45, 0xe1, 0x69, 0x32, 0xb8, 0xaf, 0x51,
   112  		0x49, 0x61, 0xa1, 0xd3, 0xa1, 0xa2, 0x5f, 0xdf,
   113  		0x3f, 0x4f, 0x77, 0x32, 0xe9, 0xd6, 0x24, 0xc6,
   114  		0xc6, 0x15, 0x48, 0xab, 0x5f, 0xb8, 0xcd, 0x41,
   115  
   116  		0x02, 0x20,
   117  		// s value
   118  		0x18, 0x15, 0x22, 0xec, 0x8e, 0xca, 0x07, 0xde,
   119  		0x48, 0x60, 0xa4, 0xac, 0xdd, 0x12, 0x90, 0x9d,
   120  		0x83, 0x1c, 0xc5, 0x6c, 0xbb, 0xac, 0x46, 0x22,
   121  		0x08, 0x22, 0x21, 0xa8, 0x76, 0x8d, 0x1d, 0x09,
   122  	}
   123  
   124  	// minimal length with 1 byte r and 1 byte s.
   125  	minSig = []byte{
   126  		0x30, 0x06, 0x02, 0x01, 0x00, 0x02, 0x01, 0x00,
   127  	}
   128  
   129  	// sig length is below 6.
   130  	smallLenSig = []byte{
   131  		0x30, 0x05, 0x02, 0x01, 0x00, 0x02, 0x01, 0x00,
   132  	}
   133  
   134  	// sig length is above 6.
   135  	largeLenSig = []byte{
   136  		0x30, 0x07, 0x02, 0x01, 0x00, 0x02, 0x01, 0x00,
   137  	}
   138  
   139  	// r length is 2.
   140  	largeRSig = []byte{
   141  		0x30, 0x06, 0x02, 0x02, 0x00, 0x02, 0x01, 0x00,
   142  	}
   143  
   144  	// r length is 0.
   145  	smallRSig = []byte{
   146  		0x30, 0x06, 0x02, 0x00, 0x00, 0x02, 0x01, 0x00,
   147  	}
   148  
   149  	// s length is 2.
   150  	largeSSig = []byte{
   151  		0x30, 0x06, 0x02, 0x01, 0x00, 0x02, 0x02, 0x00,
   152  	}
   153  
   154  	// s length is 0.
   155  	smallSSig = []byte{
   156  		0x30, 0x06, 0x02, 0x01, 0x00, 0x02, 0x00, 0x00,
   157  	}
   158  
   159  	// r length is 33.
   160  	missPaddingRSig = []byte{
   161  		0x30, 0x25, 0x02, 0x21,
   162  		// r value with a wrong padding.
   163  		0xff,
   164  		0x4e, 0x45, 0xe1, 0x69, 0x32, 0xb8, 0xaf, 0x51,
   165  		0x49, 0x61, 0xa1, 0xd3, 0xa1, 0xa2, 0x5f, 0xdf,
   166  		0x3f, 0x4f, 0x77, 0x32, 0xe9, 0xd6, 0x24, 0xc6,
   167  		0xc6, 0x15, 0x48, 0xab, 0x5f, 0xb8, 0xcd, 0x41,
   168  		// s value is 0.
   169  		0x02, 0x01, 0x00,
   170  	}
   171  
   172  	// s length is 33.
   173  	missPaddingSSig = []byte{
   174  		// r value is 0.
   175  		0x30, 0x25, 0x02, 0x01, 0x00,
   176  		0x02, 0x21,
   177  		// s value with a wrong padding.
   178  		0xff,
   179  		0x18, 0x15, 0x22, 0xec, 0x8e, 0xca, 0x07, 0xde,
   180  		0x48, 0x60, 0xa4, 0xac, 0xdd, 0x12, 0x90, 0x9d,
   181  		0x83, 0x1c, 0xc5, 0x6c, 0xbb, 0xac, 0x46, 0x22,
   182  		0x08, 0x22, 0x21, 0xa8, 0x76, 0x8d, 0x1d, 0x09,
   183  	}
   184  )
   185  
   186  func TestNewSigFromRawSignature(t *testing.T) {
   187  	t.Parallel()
   188  	testCases := []struct {
   189  		name        string
   190  		rawSig      []byte
   191  		expectedErr error
   192  		expectedSig Sig
   193  	}{
   194  		{
   195  			name:        "valid signature",
   196  			rawSig:      normalSig,
   197  			expectedErr: nil,
   198  			expectedSig: Sig{
   199  				// r value
   200  				0x4e, 0x45, 0xe1, 0x69, 0x32, 0xb8, 0xaf, 0x51,
   201  				0x49, 0x61, 0xa1, 0xd3, 0xa1, 0xa2, 0x5f, 0xdf,
   202  				0x3f, 0x4f, 0x77, 0x32, 0xe9, 0xd6, 0x24, 0xc6,
   203  				0xc6, 0x15, 0x48, 0xab, 0x5f, 0xb8, 0xcd, 0x41,
   204  				// s value
   205  				0x18, 0x15, 0x22, 0xec, 0x8e, 0xca, 0x07, 0xde,
   206  				0x48, 0x60, 0xa4, 0xac, 0xdd, 0x12, 0x90, 0x9d,
   207  				0x83, 0x1c, 0xc5, 0x6c, 0xbb, 0xac, 0x46, 0x22,
   208  				0x08, 0x22, 0x21, 0xa8, 0x76, 0x8d, 0x1d, 0x09,
   209  			},
   210  		},
   211  		{
   212  			name:        "minimal length signature",
   213  			rawSig:      minSig,
   214  			expectedErr: nil,
   215  			// NOTE: r and s are both 0x00 here.
   216  			expectedSig: Sig{},
   217  		},
   218  		{
   219  			name:        "signature length too short",
   220  			rawSig:      []byte{0x30},
   221  			expectedErr: errSigTooShort,
   222  			expectedSig: Sig{},
   223  		},
   224  		{
   225  			name:        "sig length too large",
   226  			rawSig:      largeLenSig,
   227  			expectedErr: errBadLength,
   228  			expectedSig: Sig{},
   229  		},
   230  		{
   231  			name:        "sig length too small",
   232  			rawSig:      smallLenSig,
   233  			expectedErr: errBadLength,
   234  			expectedSig: Sig{},
   235  		},
   236  		{
   237  			name:        "r length too large",
   238  			rawSig:      largeRSig,
   239  			expectedErr: errBadRLength,
   240  			expectedSig: Sig{},
   241  		},
   242  		{
   243  			name:        "r length too small",
   244  			rawSig:      smallRSig,
   245  			expectedErr: errBadRLength,
   246  			expectedSig: Sig{},
   247  		},
   248  		{
   249  			name:        "s length too large",
   250  			rawSig:      largeSSig,
   251  			expectedErr: errBadSLength,
   252  			expectedSig: Sig{},
   253  		},
   254  		{
   255  			name:        "s length too small",
   256  			rawSig:      smallSSig,
   257  			expectedErr: errBadSLength,
   258  			expectedSig: Sig{},
   259  		},
   260  		{
   261  			name:        "missing padding in r",
   262  			rawSig:      missPaddingRSig,
   263  			expectedErr: errRTooLong,
   264  			expectedSig: Sig{},
   265  		},
   266  		{
   267  			name:        "missing padding in s",
   268  			rawSig:      missPaddingSSig,
   269  			expectedErr: errSTooLong,
   270  			expectedSig: Sig{},
   271  		},
   272  	}
   273  
   274  	for _, tc := range testCases {
   275  		tc := tc
   276  		t.Run(tc.name, func(t *testing.T) {
   277  			result, err := NewSigFromRawSignature(tc.rawSig)
   278  			require.Equal(t, tc.expectedErr, err)
   279  			require.Equal(t, tc.expectedSig, result)
   280  		})
   281  	}
   282  }