github.com/BlockABC/godash@v0.0.0-20191112120524-f4aa3a32c566/btcec/signature_test.go (about)

     1  // Copyright (c) 2013-2014 The btcsuite developers
     2  // Copyright (c) 2016 The Dash developers
     3  // Use of this source code is governed by an ISC
     4  // license that can be found in the LICENSE file.
     5  
     6  package btcec_test
     7  
     8  import (
     9  	"bytes"
    10  	"crypto/rand"
    11  	"encoding/hex"
    12  	"fmt"
    13  	"math/big"
    14  	"testing"
    15  
    16  	"github.com/btcsuite/fastsha256"
    17  	"github.com/BlockABC/godash/btcec"
    18  )
    19  
    20  type signatureTest struct {
    21  	name    string
    22  	sig     []byte
    23  	der     bool
    24  	isValid bool
    25  }
    26  
    27  // decodeHex decodes the passed hex string and returns the resulting bytes.  It
    28  // panics if an error occurs.  This is only used in the tests as a helper since
    29  // the only way it can fail is if there is an error in the test source code.
    30  func decodeHex(hexStr string) []byte {
    31  	b, err := hex.DecodeString(hexStr)
    32  	if err != nil {
    33  		panic("invalid hex string in test source: err " + err.Error() +
    34  			", hex: " + hexStr)
    35  	}
    36  
    37  	return b
    38  }
    39  
    40  var signatureTests = []signatureTest{
    41  	// signatures from bitcoin blockchain tx
    42  	// 0437cd7f8525ceed2324359c2d0ba26006d92d85
    43  	{
    44  		name: "valid signature.",
    45  		sig: []byte{0x30, 0x44, 0x02, 0x20, 0x4e, 0x45, 0xe1, 0x69,
    46  			0x32, 0xb8, 0xaf, 0x51, 0x49, 0x61, 0xa1, 0xd3, 0xa1,
    47  			0xa2, 0x5f, 0xdf, 0x3f, 0x4f, 0x77, 0x32, 0xe9, 0xd6,
    48  			0x24, 0xc6, 0xc6, 0x15, 0x48, 0xab, 0x5f, 0xb8, 0xcd,
    49  			0x41, 0x02, 0x20, 0x18, 0x15, 0x22, 0xec, 0x8e, 0xca,
    50  			0x07, 0xde, 0x48, 0x60, 0xa4, 0xac, 0xdd, 0x12, 0x90,
    51  			0x9d, 0x83, 0x1c, 0xc5, 0x6c, 0xbb, 0xac, 0x46, 0x22,
    52  			0x08, 0x22, 0x21, 0xa8, 0x76, 0x8d, 0x1d, 0x09,
    53  		},
    54  		der:     true,
    55  		isValid: true,
    56  	},
    57  	{
    58  		name:    "empty.",
    59  		sig:     []byte{},
    60  		isValid: false,
    61  	},
    62  	{
    63  		name: "bad magic.",
    64  		sig: []byte{0x31, 0x44, 0x02, 0x20, 0x4e, 0x45, 0xe1, 0x69,
    65  			0x32, 0xb8, 0xaf, 0x51, 0x49, 0x61, 0xa1, 0xd3, 0xa1,
    66  			0xa2, 0x5f, 0xdf, 0x3f, 0x4f, 0x77, 0x32, 0xe9, 0xd6,
    67  			0x24, 0xc6, 0xc6, 0x15, 0x48, 0xab, 0x5f, 0xb8, 0xcd,
    68  			0x41, 0x02, 0x20, 0x18, 0x15, 0x22, 0xec, 0x8e, 0xca,
    69  			0x07, 0xde, 0x48, 0x60, 0xa4, 0xac, 0xdd, 0x12, 0x90,
    70  			0x9d, 0x83, 0x1c, 0xc5, 0x6c, 0xbb, 0xac, 0x46, 0x22,
    71  			0x08, 0x22, 0x21, 0xa8, 0x76, 0x8d, 0x1d, 0x09,
    72  		},
    73  		der:     true,
    74  		isValid: false,
    75  	},
    76  	{
    77  		name: "bad 1st int marker magic.",
    78  		sig: []byte{0x30, 0x44, 0x03, 0x20, 0x4e, 0x45, 0xe1, 0x69,
    79  			0x32, 0xb8, 0xaf, 0x51, 0x49, 0x61, 0xa1, 0xd3, 0xa1,
    80  			0xa2, 0x5f, 0xdf, 0x3f, 0x4f, 0x77, 0x32, 0xe9, 0xd6,
    81  			0x24, 0xc6, 0xc6, 0x15, 0x48, 0xab, 0x5f, 0xb8, 0xcd,
    82  			0x41, 0x02, 0x20, 0x18, 0x15, 0x22, 0xec, 0x8e, 0xca,
    83  			0x07, 0xde, 0x48, 0x60, 0xa4, 0xac, 0xdd, 0x12, 0x90,
    84  			0x9d, 0x83, 0x1c, 0xc5, 0x6c, 0xbb, 0xac, 0x46, 0x22,
    85  			0x08, 0x22, 0x21, 0xa8, 0x76, 0x8d, 0x1d, 0x09,
    86  		},
    87  		der:     true,
    88  		isValid: false,
    89  	},
    90  	{
    91  		name: "bad 2nd int marker.",
    92  		sig: []byte{0x30, 0x44, 0x02, 0x20, 0x4e, 0x45, 0xe1, 0x69,
    93  			0x32, 0xb8, 0xaf, 0x51, 0x49, 0x61, 0xa1, 0xd3, 0xa1,
    94  			0xa2, 0x5f, 0xdf, 0x3f, 0x4f, 0x77, 0x32, 0xe9, 0xd6,
    95  			0x24, 0xc6, 0xc6, 0x15, 0x48, 0xab, 0x5f, 0xb8, 0xcd,
    96  			0x41, 0x03, 0x20, 0x18, 0x15, 0x22, 0xec, 0x8e, 0xca,
    97  			0x07, 0xde, 0x48, 0x60, 0xa4, 0xac, 0xdd, 0x12, 0x90,
    98  			0x9d, 0x83, 0x1c, 0xc5, 0x6c, 0xbb, 0xac, 0x46, 0x22,
    99  			0x08, 0x22, 0x21, 0xa8, 0x76, 0x8d, 0x1d, 0x09,
   100  		},
   101  		der:     true,
   102  		isValid: false,
   103  	},
   104  	{
   105  		name: "short len",
   106  		sig: []byte{0x30, 0x43, 0x02, 0x20, 0x4e, 0x45, 0xe1, 0x69,
   107  			0x32, 0xb8, 0xaf, 0x51, 0x49, 0x61, 0xa1, 0xd3, 0xa1,
   108  			0xa2, 0x5f, 0xdf, 0x3f, 0x4f, 0x77, 0x32, 0xe9, 0xd6,
   109  			0x24, 0xc6, 0xc6, 0x15, 0x48, 0xab, 0x5f, 0xb8, 0xcd,
   110  			0x41, 0x02, 0x20, 0x18, 0x15, 0x22, 0xec, 0x8e, 0xca,
   111  			0x07, 0xde, 0x48, 0x60, 0xa4, 0xac, 0xdd, 0x12, 0x90,
   112  			0x9d, 0x83, 0x1c, 0xc5, 0x6c, 0xbb, 0xac, 0x46, 0x22,
   113  			0x08, 0x22, 0x21, 0xa8, 0x76, 0x8d, 0x1d, 0x09,
   114  		},
   115  		der:     true,
   116  		isValid: false,
   117  	},
   118  	{
   119  		name: "long len",
   120  		sig: []byte{0x30, 0x45, 0x02, 0x20, 0x4e, 0x45, 0xe1, 0x69,
   121  			0x32, 0xb8, 0xaf, 0x51, 0x49, 0x61, 0xa1, 0xd3, 0xa1,
   122  			0xa2, 0x5f, 0xdf, 0x3f, 0x4f, 0x77, 0x32, 0xe9, 0xd6,
   123  			0x24, 0xc6, 0xc6, 0x15, 0x48, 0xab, 0x5f, 0xb8, 0xcd,
   124  			0x41, 0x02, 0x20, 0x18, 0x15, 0x22, 0xec, 0x8e, 0xca,
   125  			0x07, 0xde, 0x48, 0x60, 0xa4, 0xac, 0xdd, 0x12, 0x90,
   126  			0x9d, 0x83, 0x1c, 0xc5, 0x6c, 0xbb, 0xac, 0x46, 0x22,
   127  			0x08, 0x22, 0x21, 0xa8, 0x76, 0x8d, 0x1d, 0x09,
   128  		},
   129  		der:     true,
   130  		isValid: false,
   131  	},
   132  	{
   133  		name: "long X",
   134  		sig: []byte{0x30, 0x44, 0x02, 0x42, 0x4e, 0x45, 0xe1, 0x69,
   135  			0x32, 0xb8, 0xaf, 0x51, 0x49, 0x61, 0xa1, 0xd3, 0xa1,
   136  			0xa2, 0x5f, 0xdf, 0x3f, 0x4f, 0x77, 0x32, 0xe9, 0xd6,
   137  			0x24, 0xc6, 0xc6, 0x15, 0x48, 0xab, 0x5f, 0xb8, 0xcd,
   138  			0x41, 0x02, 0x20, 0x18, 0x15, 0x22, 0xec, 0x8e, 0xca,
   139  			0x07, 0xde, 0x48, 0x60, 0xa4, 0xac, 0xdd, 0x12, 0x90,
   140  			0x9d, 0x83, 0x1c, 0xc5, 0x6c, 0xbb, 0xac, 0x46, 0x22,
   141  			0x08, 0x22, 0x21, 0xa8, 0x76, 0x8d, 0x1d, 0x09,
   142  		},
   143  		der:     true,
   144  		isValid: false,
   145  	},
   146  	{
   147  		name: "long Y",
   148  		sig: []byte{0x30, 0x44, 0x02, 0x20, 0x4e, 0x45, 0xe1, 0x69,
   149  			0x32, 0xb8, 0xaf, 0x51, 0x49, 0x61, 0xa1, 0xd3, 0xa1,
   150  			0xa2, 0x5f, 0xdf, 0x3f, 0x4f, 0x77, 0x32, 0xe9, 0xd6,
   151  			0x24, 0xc6, 0xc6, 0x15, 0x48, 0xab, 0x5f, 0xb8, 0xcd,
   152  			0x41, 0x02, 0x21, 0x18, 0x15, 0x22, 0xec, 0x8e, 0xca,
   153  			0x07, 0xde, 0x48, 0x60, 0xa4, 0xac, 0xdd, 0x12, 0x90,
   154  			0x9d, 0x83, 0x1c, 0xc5, 0x6c, 0xbb, 0xac, 0x46, 0x22,
   155  			0x08, 0x22, 0x21, 0xa8, 0x76, 0x8d, 0x1d, 0x09,
   156  		},
   157  		der:     true,
   158  		isValid: false,
   159  	},
   160  	{
   161  		name: "short Y",
   162  		sig: []byte{0x30, 0x44, 0x02, 0x20, 0x4e, 0x45, 0xe1, 0x69,
   163  			0x32, 0xb8, 0xaf, 0x51, 0x49, 0x61, 0xa1, 0xd3, 0xa1,
   164  			0xa2, 0x5f, 0xdf, 0x3f, 0x4f, 0x77, 0x32, 0xe9, 0xd6,
   165  			0x24, 0xc6, 0xc6, 0x15, 0x48, 0xab, 0x5f, 0xb8, 0xcd,
   166  			0x41, 0x02, 0x19, 0x18, 0x15, 0x22, 0xec, 0x8e, 0xca,
   167  			0x07, 0xde, 0x48, 0x60, 0xa4, 0xac, 0xdd, 0x12, 0x90,
   168  			0x9d, 0x83, 0x1c, 0xc5, 0x6c, 0xbb, 0xac, 0x46, 0x22,
   169  			0x08, 0x22, 0x21, 0xa8, 0x76, 0x8d, 0x1d, 0x09,
   170  		},
   171  		der:     true,
   172  		isValid: false,
   173  	},
   174  	{
   175  		name: "trailing crap.",
   176  		sig: []byte{0x30, 0x44, 0x02, 0x20, 0x4e, 0x45, 0xe1, 0x69,
   177  			0x32, 0xb8, 0xaf, 0x51, 0x49, 0x61, 0xa1, 0xd3, 0xa1,
   178  			0xa2, 0x5f, 0xdf, 0x3f, 0x4f, 0x77, 0x32, 0xe9, 0xd6,
   179  			0x24, 0xc6, 0xc6, 0x15, 0x48, 0xab, 0x5f, 0xb8, 0xcd,
   180  			0x41, 0x02, 0x20, 0x18, 0x15, 0x22, 0xec, 0x8e, 0xca,
   181  			0x07, 0xde, 0x48, 0x60, 0xa4, 0xac, 0xdd, 0x12, 0x90,
   182  			0x9d, 0x83, 0x1c, 0xc5, 0x6c, 0xbb, 0xac, 0x46, 0x22,
   183  			0x08, 0x22, 0x21, 0xa8, 0x76, 0x8d, 0x1d, 0x09, 0x01,
   184  		},
   185  		der: true,
   186  
   187  		// This test is now passing (used to be failing) because there
   188  		// are signatures in the blockchain that have trailing zero
   189  		// bytes before the hashtype. So ParseSignature was fixed to
   190  		// permit buffers with trailing nonsense after the actual
   191  		// signature.
   192  		isValid: true,
   193  	},
   194  	{
   195  		name: "X == N ",
   196  		sig: []byte{0x30, 0x44, 0x02, 0x20, 0xFF, 0xFF, 0xFF, 0xFF,
   197  			0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
   198  			0xFF, 0xFF, 0xFE, 0xBA, 0xAE, 0xDC, 0xE6, 0xAF, 0x48,
   199  			0xA0, 0x3B, 0xBF, 0xD2, 0x5E, 0x8C, 0xD0, 0x36, 0x41,
   200  			0x41, 0x02, 0x20, 0x18, 0x15, 0x22, 0xec, 0x8e, 0xca,
   201  			0x07, 0xde, 0x48, 0x60, 0xa4, 0xac, 0xdd, 0x12, 0x90,
   202  			0x9d, 0x83, 0x1c, 0xc5, 0x6c, 0xbb, 0xac, 0x46, 0x22,
   203  			0x08, 0x22, 0x21, 0xa8, 0x76, 0x8d, 0x1d, 0x09,
   204  		},
   205  		der:     true,
   206  		isValid: false,
   207  	},
   208  	{
   209  		name: "X == N ",
   210  		sig: []byte{0x30, 0x44, 0x02, 0x20, 0xFF, 0xFF, 0xFF, 0xFF,
   211  			0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
   212  			0xFF, 0xFF, 0xFE, 0xBA, 0xAE, 0xDC, 0xE6, 0xAF, 0x48,
   213  			0xA0, 0x3B, 0xBF, 0xD2, 0x5E, 0x8C, 0xD0, 0x36, 0x41,
   214  			0x42, 0x02, 0x20, 0x18, 0x15, 0x22, 0xec, 0x8e, 0xca,
   215  			0x07, 0xde, 0x48, 0x60, 0xa4, 0xac, 0xdd, 0x12, 0x90,
   216  			0x9d, 0x83, 0x1c, 0xc5, 0x6c, 0xbb, 0xac, 0x46, 0x22,
   217  			0x08, 0x22, 0x21, 0xa8, 0x76, 0x8d, 0x1d, 0x09,
   218  		},
   219  		der:     false,
   220  		isValid: false,
   221  	},
   222  	{
   223  		name: "Y == N",
   224  		sig: []byte{0x30, 0x44, 0x02, 0x20, 0x4e, 0x45, 0xe1, 0x69,
   225  			0x32, 0xb8, 0xaf, 0x51, 0x49, 0x61, 0xa1, 0xd3, 0xa1,
   226  			0xa2, 0x5f, 0xdf, 0x3f, 0x4f, 0x77, 0x32, 0xe9, 0xd6,
   227  			0x24, 0xc6, 0xc6, 0x15, 0x48, 0xab, 0x5f, 0xb8, 0xcd,
   228  			0x41, 0x02, 0x20, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
   229  			0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
   230  			0xFE, 0xBA, 0xAE, 0xDC, 0xE6, 0xAF, 0x48, 0xA0, 0x3B,
   231  			0xBF, 0xD2, 0x5E, 0x8C, 0xD0, 0x36, 0x41, 0x41,
   232  		},
   233  		der:     true,
   234  		isValid: false,
   235  	},
   236  	{
   237  		name: "Y > N",
   238  		sig: []byte{0x30, 0x44, 0x02, 0x20, 0x4e, 0x45, 0xe1, 0x69,
   239  			0x32, 0xb8, 0xaf, 0x51, 0x49, 0x61, 0xa1, 0xd3, 0xa1,
   240  			0xa2, 0x5f, 0xdf, 0x3f, 0x4f, 0x77, 0x32, 0xe9, 0xd6,
   241  			0x24, 0xc6, 0xc6, 0x15, 0x48, 0xab, 0x5f, 0xb8, 0xcd,
   242  			0x41, 0x02, 0x20, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
   243  			0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
   244  			0xFE, 0xBA, 0xAE, 0xDC, 0xE6, 0xAF, 0x48, 0xA0, 0x3B,
   245  			0xBF, 0xD2, 0x5E, 0x8C, 0xD0, 0x36, 0x41, 0x42,
   246  		},
   247  		der:     false,
   248  		isValid: false,
   249  	},
   250  	{
   251  		name: "0 len X.",
   252  		sig: []byte{0x30, 0x24, 0x02, 0x00, 0x02, 0x20, 0x18, 0x15,
   253  			0x22, 0xec, 0x8e, 0xca, 0x07, 0xde, 0x48, 0x60, 0xa4,
   254  			0xac, 0xdd, 0x12, 0x90, 0x9d, 0x83, 0x1c, 0xc5, 0x6c,
   255  			0xbb, 0xac, 0x46, 0x22, 0x08, 0x22, 0x21, 0xa8, 0x76,
   256  			0x8d, 0x1d, 0x09,
   257  		},
   258  		der:     true,
   259  		isValid: false,
   260  	},
   261  	{
   262  		name: "0 len Y.",
   263  		sig: []byte{0x30, 0x24, 0x02, 0x20, 0x4e, 0x45, 0xe1, 0x69,
   264  			0x32, 0xb8, 0xaf, 0x51, 0x49, 0x61, 0xa1, 0xd3, 0xa1,
   265  			0xa2, 0x5f, 0xdf, 0x3f, 0x4f, 0x77, 0x32, 0xe9, 0xd6,
   266  			0x24, 0xc6, 0xc6, 0x15, 0x48, 0xab, 0x5f, 0xb8, 0xcd,
   267  			0x41, 0x02, 0x00,
   268  		},
   269  		der:     true,
   270  		isValid: false,
   271  	},
   272  	{
   273  		name: "extra R padding.",
   274  		sig: []byte{0x30, 0x45, 0x02, 0x21, 0x00, 0x4e, 0x45, 0xe1, 0x69,
   275  			0x32, 0xb8, 0xaf, 0x51, 0x49, 0x61, 0xa1, 0xd3, 0xa1,
   276  			0xa2, 0x5f, 0xdf, 0x3f, 0x4f, 0x77, 0x32, 0xe9, 0xd6,
   277  			0x24, 0xc6, 0xc6, 0x15, 0x48, 0xab, 0x5f, 0xb8, 0xcd,
   278  			0x41, 0x02, 0x20, 0x18, 0x15, 0x22, 0xec, 0x8e, 0xca,
   279  			0x07, 0xde, 0x48, 0x60, 0xa4, 0xac, 0xdd, 0x12, 0x90,
   280  			0x9d, 0x83, 0x1c, 0xc5, 0x6c, 0xbb, 0xac, 0x46, 0x22,
   281  			0x08, 0x22, 0x21, 0xa8, 0x76, 0x8d, 0x1d, 0x09,
   282  		},
   283  		der:     true,
   284  		isValid: false,
   285  	},
   286  	{
   287  		name: "extra S padding.",
   288  		sig: []byte{0x30, 0x45, 0x02, 0x20, 0x4e, 0x45, 0xe1, 0x69,
   289  			0x32, 0xb8, 0xaf, 0x51, 0x49, 0x61, 0xa1, 0xd3, 0xa1,
   290  			0xa2, 0x5f, 0xdf, 0x3f, 0x4f, 0x77, 0x32, 0xe9, 0xd6,
   291  			0x24, 0xc6, 0xc6, 0x15, 0x48, 0xab, 0x5f, 0xb8, 0xcd,
   292  			0x41, 0x02, 0x21, 0x00, 0x18, 0x15, 0x22, 0xec, 0x8e, 0xca,
   293  			0x07, 0xde, 0x48, 0x60, 0xa4, 0xac, 0xdd, 0x12, 0x90,
   294  			0x9d, 0x83, 0x1c, 0xc5, 0x6c, 0xbb, 0xac, 0x46, 0x22,
   295  			0x08, 0x22, 0x21, 0xa8, 0x76, 0x8d, 0x1d, 0x09,
   296  		},
   297  		der:     true,
   298  		isValid: false,
   299  	},
   300  	// Standard checks (in BER format, without checking for 'canonical' DER
   301  	// signatures) don't test for negative numbers here because there isn't
   302  	// a way that is the same between openssl and go that will mark a number
   303  	// as negative. The Go ASN.1 parser marks numbers as negative when
   304  	// openssl does not (it doesn't handle negative numbers that I can tell
   305  	// at all. When not parsing DER signatures, which is done by by bitcoind
   306  	// when accepting transactions into its mempool, we otherwise only check
   307  	// for the coordinates being zero.
   308  	{
   309  		name: "X == 0",
   310  		sig: []byte{0x30, 0x25, 0x02, 0x01, 0x00, 0x02, 0x20, 0x18,
   311  			0x15, 0x22, 0xec, 0x8e, 0xca, 0x07, 0xde, 0x48, 0x60,
   312  			0xa4, 0xac, 0xdd, 0x12, 0x90, 0x9d, 0x83, 0x1c, 0xc5,
   313  			0x6c, 0xbb, 0xac, 0x46, 0x22, 0x08, 0x22, 0x21, 0xa8,
   314  			0x76, 0x8d, 0x1d, 0x09,
   315  		},
   316  		der:     false,
   317  		isValid: false,
   318  	},
   319  	{
   320  		name: "Y == 0.",
   321  		sig: []byte{0x30, 0x25, 0x02, 0x20, 0x4e, 0x45, 0xe1, 0x69,
   322  			0x32, 0xb8, 0xaf, 0x51, 0x49, 0x61, 0xa1, 0xd3, 0xa1,
   323  			0xa2, 0x5f, 0xdf, 0x3f, 0x4f, 0x77, 0x32, 0xe9, 0xd6,
   324  			0x24, 0xc6, 0xc6, 0x15, 0x48, 0xab, 0x5f, 0xb8, 0xcd,
   325  			0x41, 0x02, 0x01, 0x00,
   326  		},
   327  		der:     false,
   328  		isValid: false,
   329  	},
   330  }
   331  
   332  func TestSignatures(t *testing.T) {
   333  	for _, test := range signatureTests {
   334  		var err error
   335  		if test.der {
   336  			_, err = btcec.ParseDERSignature(test.sig, btcec.S256())
   337  		} else {
   338  			_, err = btcec.ParseSignature(test.sig, btcec.S256())
   339  		}
   340  		if err != nil {
   341  			if test.isValid {
   342  				t.Errorf("%s signature failed when shouldn't %v",
   343  					test.name, err)
   344  			} /* else {
   345  				t.Errorf("%s got error %v", test.name, err)
   346  			} */
   347  			continue
   348  		}
   349  		if !test.isValid {
   350  			t.Errorf("%s counted as valid when it should fail",
   351  				test.name)
   352  		}
   353  	}
   354  }
   355  
   356  // TestSignatureSerialize ensures that serializing signatures works as expected.
   357  func TestSignatureSerialize(t *testing.T) {
   358  	tests := []struct {
   359  		name     string
   360  		ecsig    *btcec.Signature
   361  		expected []byte
   362  	}{
   363  		// signature from bitcoin blockchain tx
   364  		// 0437cd7f8525ceed2324359c2d0ba26006d92d85
   365  		{
   366  			"valid 1 - r and s most significant bits are zero",
   367  			&btcec.Signature{
   368  				R: fromHex("4e45e16932b8af514961a1d3a1a25fdf3f4f7732e9d624c6c61548ab5fb8cd41"),
   369  				S: fromHex("181522ec8eca07de4860a4acdd12909d831cc56cbbac4622082221a8768d1d09"),
   370  			},
   371  			[]byte{
   372  				0x30, 0x44, 0x02, 0x20, 0x4e, 0x45, 0xe1, 0x69,
   373  				0x32, 0xb8, 0xaf, 0x51, 0x49, 0x61, 0xa1, 0xd3,
   374  				0xa1, 0xa2, 0x5f, 0xdf, 0x3f, 0x4f, 0x77, 0x32,
   375  				0xe9, 0xd6, 0x24, 0xc6, 0xc6, 0x15, 0x48, 0xab,
   376  				0x5f, 0xb8, 0xcd, 0x41, 0x02, 0x20, 0x18, 0x15,
   377  				0x22, 0xec, 0x8e, 0xca, 0x07, 0xde, 0x48, 0x60,
   378  				0xa4, 0xac, 0xdd, 0x12, 0x90, 0x9d, 0x83, 0x1c,
   379  				0xc5, 0x6c, 0xbb, 0xac, 0x46, 0x22, 0x08, 0x22,
   380  				0x21, 0xa8, 0x76, 0x8d, 0x1d, 0x09,
   381  			},
   382  		},
   383  		// signature from bitcoin blockchain tx
   384  		// cb00f8a0573b18faa8c4f467b049f5d202bf1101d9ef2633bc611be70376a4b4
   385  		{
   386  			"valid 2 - r most significant bit is one",
   387  			&btcec.Signature{
   388  				R: fromHex("0082235e21a2300022738dabb8e1bbd9d19cfb1e7ab8c30a23b0afbb8d178abcf3"),
   389  				S: fromHex("24bf68e256c534ddfaf966bf908deb944305596f7bdcc38d69acad7f9c868724"),
   390  			},
   391  			[]byte{
   392  				0x30, 0x45, 0x02, 0x21, 0x00, 0x82, 0x23, 0x5e,
   393  				0x21, 0xa2, 0x30, 0x00, 0x22, 0x73, 0x8d, 0xab,
   394  				0xb8, 0xe1, 0xbb, 0xd9, 0xd1, 0x9c, 0xfb, 0x1e,
   395  				0x7a, 0xb8, 0xc3, 0x0a, 0x23, 0xb0, 0xaf, 0xbb,
   396  				0x8d, 0x17, 0x8a, 0xbc, 0xf3, 0x02, 0x20, 0x24,
   397  				0xbf, 0x68, 0xe2, 0x56, 0xc5, 0x34, 0xdd, 0xfa,
   398  				0xf9, 0x66, 0xbf, 0x90, 0x8d, 0xeb, 0x94, 0x43,
   399  				0x05, 0x59, 0x6f, 0x7b, 0xdc, 0xc3, 0x8d, 0x69,
   400  				0xac, 0xad, 0x7f, 0x9c, 0x86, 0x87, 0x24,
   401  			},
   402  		},
   403  		// signature from bitcoin blockchain tx
   404  		// fda204502a3345e08afd6af27377c052e77f1fefeaeb31bdd45f1e1237ca5470
   405  		{
   406  			"valid 3 - s most significant bit is one",
   407  			&btcec.Signature{
   408  				R: fromHex("1cadddc2838598fee7dc35a12b340c6bde8b389f7bfd19a1252a17c4b5ed2d71"),
   409  				S: new(big.Int).Add(fromHex("00c1a251bbecb14b058a8bd77f65de87e51c47e95904f4c0e9d52eddc21c1415ac"), btcec.S256().N),
   410  			},
   411  			[]byte{
   412  				0x30, 0x45, 0x02, 0x20, 0x1c, 0xad, 0xdd, 0xc2,
   413  				0x83, 0x85, 0x98, 0xfe, 0xe7, 0xdc, 0x35, 0xa1,
   414  				0x2b, 0x34, 0x0c, 0x6b, 0xde, 0x8b, 0x38, 0x9f,
   415  				0x7b, 0xfd, 0x19, 0xa1, 0x25, 0x2a, 0x17, 0xc4,
   416  				0xb5, 0xed, 0x2d, 0x71, 0x02, 0x21, 0x00, 0xc1,
   417  				0xa2, 0x51, 0xbb, 0xec, 0xb1, 0x4b, 0x05, 0x8a,
   418  				0x8b, 0xd7, 0x7f, 0x65, 0xde, 0x87, 0xe5, 0x1c,
   419  				0x47, 0xe9, 0x59, 0x04, 0xf4, 0xc0, 0xe9, 0xd5,
   420  				0x2e, 0xdd, 0xc2, 0x1c, 0x14, 0x15, 0xac,
   421  			},
   422  		},
   423  		{
   424  			"zero signature",
   425  			&btcec.Signature{
   426  				R: big.NewInt(0),
   427  				S: big.NewInt(0),
   428  			},
   429  			[]byte{0x30, 0x06, 0x02, 0x01, 0x00, 0x02, 0x01, 0x00},
   430  		},
   431  	}
   432  
   433  	for i, test := range tests {
   434  		result := test.ecsig.Serialize()
   435  		if !bytes.Equal(result, test.expected) {
   436  			t.Errorf("Serialize #%d (%s) unexpected result:\n"+
   437  				"got:  %x\nwant: %x", i, test.name, result,
   438  				test.expected)
   439  		}
   440  	}
   441  }
   442  
   443  func testSignCompact(t *testing.T, tag string, curve *btcec.KoblitzCurve,
   444  	data []byte, isCompressed bool) {
   445  	tmp, _ := btcec.NewPrivateKey(curve)
   446  	priv := (*btcec.PrivateKey)(tmp)
   447  
   448  	hashed := []byte("testing")
   449  	sig, err := btcec.SignCompact(curve, priv, hashed, isCompressed)
   450  	if err != nil {
   451  		t.Errorf("%s: error signing: %s", tag, err)
   452  		return
   453  	}
   454  
   455  	pk, wasCompressed, err := btcec.RecoverCompact(curve, sig, hashed)
   456  	if err != nil {
   457  		t.Errorf("%s: error recovering: %s", tag, err)
   458  		return
   459  	}
   460  	if pk.X.Cmp(priv.X) != 0 || pk.Y.Cmp(priv.Y) != 0 {
   461  		t.Errorf("%s: recovered pubkey doesn't match original "+
   462  			"(%v,%v) vs (%v,%v) ", tag, pk.X, pk.Y, priv.X, priv.Y)
   463  		return
   464  	}
   465  	if wasCompressed != isCompressed {
   466  		t.Errorf("%s: recovered pubkey doesn't match compressed state "+
   467  			"(%v vs %v)", tag, isCompressed, wasCompressed)
   468  		return
   469  	}
   470  
   471  	// If we change the compressed bit we should get the same key back,
   472  	// but the compressed flag should be reversed.
   473  	if isCompressed {
   474  		sig[0] -= 4
   475  	} else {
   476  		sig[0] += 4
   477  	}
   478  
   479  	pk, wasCompressed, err = btcec.RecoverCompact(curve, sig, hashed)
   480  	if err != nil {
   481  		t.Errorf("%s: error recovering (2): %s", tag, err)
   482  		return
   483  	}
   484  	if pk.X.Cmp(priv.X) != 0 || pk.Y.Cmp(priv.Y) != 0 {
   485  		t.Errorf("%s: recovered pubkey (2) doesn't match original "+
   486  			"(%v,%v) vs (%v,%v) ", tag, pk.X, pk.Y, priv.X, priv.Y)
   487  		return
   488  	}
   489  	if wasCompressed == isCompressed {
   490  		t.Errorf("%s: recovered pubkey doesn't match reversed "+
   491  			"compressed state (%v vs %v)", tag, isCompressed,
   492  			wasCompressed)
   493  		return
   494  	}
   495  }
   496  
   497  func TestSignCompact(t *testing.T) {
   498  	for i := 0; i < 256; i++ {
   499  		name := fmt.Sprintf("test %d", i)
   500  		data := make([]byte, 32)
   501  		_, err := rand.Read(data)
   502  		if err != nil {
   503  			t.Errorf("failed to read random data for %s", name)
   504  			continue
   505  		}
   506  		compressed := i%2 != 0
   507  		testSignCompact(t, name, btcec.S256(), data, compressed)
   508  	}
   509  }
   510  
   511  func TestRFC6979(t *testing.T) {
   512  	// Test vectors matching Trezor and CoreBitcoin implementations.
   513  	// - https://github.com/trezor/trezor-crypto/blob/9fea8f8ab377dc514e40c6fd1f7c89a74c1d8dc6/tests.c#L432-L453
   514  	// - https://github.com/oleganza/CoreBitcoin/blob/e93dd71207861b5bf044415db5fa72405e7d8fbc/CoreBitcoin/BTCKey%2BTests.m#L23-L49
   515  	tests := []struct {
   516  		key       string
   517  		msg       string
   518  		nonce     string
   519  		signature string
   520  	}{
   521  		{
   522  			"cca9fbcc1b41e5a95d369eaa6ddcff73b61a4efaa279cfc6567e8daa39cbaf50",
   523  			"sample",
   524  			"2df40ca70e639d89528a6b670d9d48d9165fdc0febc0974056bdce192b8e16a3",
   525  			"3045022100af340daf02cc15c8d5d08d7735dfe6b98a474ed373bdb5fbecf7571be52b384202205009fb27f37034a9b24b707b7c6b79ca23ddef9e25f7282e8a797efe53a8f124",
   526  		},
   527  		{
   528  			// This signature hits the case when S is higher than halforder.
   529  			// If S is not canonicalized (lowered by halforder), this test will fail.
   530  			"0000000000000000000000000000000000000000000000000000000000000001",
   531  			"Satoshi Nakamoto",
   532  			"8f8a276c19f4149656b280621e358cce24f5f52542772691ee69063b74f15d15",
   533  			"3045022100934b1ea10a4b3c1757e2b0c017d0b6143ce3c9a7e6a4a49860d7a6ab210ee3d802202442ce9d2b916064108014783e923ec36b49743e2ffa1c4496f01a512aafd9e5",
   534  		},
   535  		{
   536  			"fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364140",
   537  			"Satoshi Nakamoto",
   538  			"33a19b60e25fb6f4435af53a3d42d493644827367e6453928554f43e49aa6f90",
   539  			"3045022100fd567d121db66e382991534ada77a6bd3106f0a1098c231e47993447cd6af2d002206b39cd0eb1bc8603e159ef5c20a5c8ad685a45b06ce9bebed3f153d10d93bed5",
   540  		},
   541  		{
   542  			"f8b8af8ce3c7cca5e300d33939540c10d45ce001b8f252bfbc57ba0342904181",
   543  			"Alan Turing",
   544  			"525a82b70e67874398067543fd84c83d30c175fdc45fdeee082fe13b1d7cfdf1",
   545  			"304402207063ae83e7f62bbb171798131b4a0564b956930092b33b07b395615d9ec7e15c022058dfcc1e00a35e1572f366ffe34ba0fc47db1e7189759b9fb233c5b05ab388ea",
   546  		},
   547  		{
   548  			"0000000000000000000000000000000000000000000000000000000000000001",
   549  			"All those moments will be lost in time, like tears in rain. Time to die...",
   550  			"38aa22d72376b4dbc472e06c3ba403ee0a394da63fc58d88686c611aba98d6b3",
   551  			"30450221008600dbd41e348fe5c9465ab92d23e3db8b98b873beecd930736488696438cb6b0220547fe64427496db33bf66019dacbf0039c04199abb0122918601db38a72cfc21",
   552  		},
   553  		{
   554  			"e91671c46231f833a6406ccbea0e3e392c76c167bac1cb013f6f1013980455c2",
   555  			"There is a computer disease that anybody who works with computers knows about. It's a very serious disease and it interferes completely with the work. The trouble with computers is that you 'play' with them!",
   556  			"1f4b84c23a86a221d233f2521be018d9318639d5b8bbd6374a8a59232d16ad3d",
   557  			"3045022100b552edd27580141f3b2a5463048cb7cd3e047b97c9f98076c32dbdf85a68718b0220279fa72dd19bfae05577e06c7c0c1900c371fcd5893f7e1d56a37d30174671f6",
   558  		},
   559  	}
   560  
   561  	for i, test := range tests {
   562  		privKey, _ := btcec.PrivKeyFromBytes(btcec.S256(), decodeHex(test.key))
   563  		hash := fastsha256.Sum256([]byte(test.msg))
   564  
   565  		// Ensure deterministically generated nonce is the expected value.
   566  		gotNonce := btcec.TstNonceRFC6979(privKey.D, hash[:]).Bytes()
   567  		wantNonce := decodeHex(test.nonce)
   568  		if !bytes.Equal(gotNonce, wantNonce) {
   569  			t.Errorf("NonceRFC6979 #%d (%s): Nonce is incorrect: "+
   570  				"%x (expected %x)", i, test.msg, gotNonce,
   571  				wantNonce)
   572  			continue
   573  		}
   574  
   575  		// Ensure deterministically generated signature is the expected value.
   576  		gotSig, err := privKey.Sign(hash[:])
   577  		if err != nil {
   578  			t.Errorf("Sign #%d (%s): unexpected error: %v", i,
   579  				test.msg, err)
   580  			continue
   581  		}
   582  		gotSigBytes := gotSig.Serialize()
   583  		wantSigBytes := decodeHex(test.signature)
   584  		if !bytes.Equal(gotSigBytes, wantSigBytes) {
   585  			t.Errorf("Sign #%d (%s): mismatched signature: %x "+
   586  				"(expected %x)", i, test.msg, gotSigBytes,
   587  				wantSigBytes)
   588  			continue
   589  		}
   590  	}
   591  }
   592  
   593  func TestSignatureIsEqual(t *testing.T) {
   594  	sig1 := &btcec.Signature{
   595  		R: fromHex("0082235e21a2300022738dabb8e1bbd9d19cfb1e7ab8c30a23b0afbb8d178abcf3"),
   596  		S: fromHex("24bf68e256c534ddfaf966bf908deb944305596f7bdcc38d69acad7f9c868724"),
   597  	}
   598  	sig2 := &btcec.Signature{
   599  		R: fromHex("4e45e16932b8af514961a1d3a1a25fdf3f4f7732e9d624c6c61548ab5fb8cd41"),
   600  		S: fromHex("181522ec8eca07de4860a4acdd12909d831cc56cbbac4622082221a8768d1d09"),
   601  	}
   602  
   603  	if !sig1.IsEqual(sig1) {
   604  		t.Fatalf("value of IsEqual is incorrect, %v is "+
   605  			"equal to %v", sig1, sig1)
   606  	}
   607  
   608  	if sig1.IsEqual(sig2) {
   609  		t.Fatalf("value of IsEqual is incorrect, %v is not "+
   610  			"equal to %v", sig1, sig2)
   611  	}
   612  }