github.com/lbryio/lbcd@v0.22.119/btcec/pubkey_test.go (about)

     1  // Copyright (c) 2013-2016 The btcsuite developers
     2  // Use of this source code is governed by an ISC
     3  // license that can be found in the LICENSE file.
     4  
     5  package btcec
     6  
     7  import (
     8  	"bytes"
     9  	"testing"
    10  
    11  	"github.com/davecgh/go-spew/spew"
    12  )
    13  
    14  type pubKeyTest struct {
    15  	name    string
    16  	key     []byte
    17  	format  byte
    18  	isValid bool
    19  }
    20  
    21  var pubKeyTests = []pubKeyTest{
    22  	// pubkey from bitcoin blockchain tx
    23  	// 0437cd7f8525ceed2324359c2d0ba26006d92d85
    24  	{
    25  		name: "uncompressed ok",
    26  		key: []byte{0x04, 0x11, 0xdb, 0x93, 0xe1, 0xdc, 0xdb, 0x8a,
    27  			0x01, 0x6b, 0x49, 0x84, 0x0f, 0x8c, 0x53, 0xbc, 0x1e,
    28  			0xb6, 0x8a, 0x38, 0x2e, 0x97, 0xb1, 0x48, 0x2e, 0xca,
    29  			0xd7, 0xb1, 0x48, 0xa6, 0x90, 0x9a, 0x5c, 0xb2, 0xe0,
    30  			0xea, 0xdd, 0xfb, 0x84, 0xcc, 0xf9, 0x74, 0x44, 0x64,
    31  			0xf8, 0x2e, 0x16, 0x0b, 0xfa, 0x9b, 0x8b, 0x64, 0xf9,
    32  			0xd4, 0xc0, 0x3f, 0x99, 0x9b, 0x86, 0x43, 0xf6, 0x56,
    33  			0xb4, 0x12, 0xa3,
    34  		},
    35  		isValid: true,
    36  		format:  pubkeyUncompressed,
    37  	},
    38  	{
    39  		name: "uncompressed x changed",
    40  		key: []byte{0x04, 0x15, 0xdb, 0x93, 0xe1, 0xdc, 0xdb, 0x8a,
    41  			0x01, 0x6b, 0x49, 0x84, 0x0f, 0x8c, 0x53, 0xbc, 0x1e,
    42  			0xb6, 0x8a, 0x38, 0x2e, 0x97, 0xb1, 0x48, 0x2e, 0xca,
    43  			0xd7, 0xb1, 0x48, 0xa6, 0x90, 0x9a, 0x5c, 0xb2, 0xe0,
    44  			0xea, 0xdd, 0xfb, 0x84, 0xcc, 0xf9, 0x74, 0x44, 0x64,
    45  			0xf8, 0x2e, 0x16, 0x0b, 0xfa, 0x9b, 0x8b, 0x64, 0xf9,
    46  			0xd4, 0xc0, 0x3f, 0x99, 0x9b, 0x86, 0x43, 0xf6, 0x56,
    47  			0xb4, 0x12, 0xa3,
    48  		},
    49  		isValid: false,
    50  	},
    51  	{
    52  		name: "uncompressed y changed",
    53  		key: []byte{0x04, 0x11, 0xdb, 0x93, 0xe1, 0xdc, 0xdb, 0x8a,
    54  			0x01, 0x6b, 0x49, 0x84, 0x0f, 0x8c, 0x53, 0xbc, 0x1e,
    55  			0xb6, 0x8a, 0x38, 0x2e, 0x97, 0xb1, 0x48, 0x2e, 0xca,
    56  			0xd7, 0xb1, 0x48, 0xa6, 0x90, 0x9a, 0x5c, 0xb2, 0xe0,
    57  			0xea, 0xdd, 0xfb, 0x84, 0xcc, 0xf9, 0x74, 0x44, 0x64,
    58  			0xf8, 0x2e, 0x16, 0x0b, 0xfa, 0x9b, 0x8b, 0x64, 0xf9,
    59  			0xd4, 0xc0, 0x3f, 0x99, 0x9b, 0x86, 0x43, 0xf6, 0x56,
    60  			0xb4, 0x12, 0xa4,
    61  		},
    62  		isValid: false,
    63  	},
    64  	{
    65  		name: "uncompressed claims compressed",
    66  		key: []byte{0x03, 0x11, 0xdb, 0x93, 0xe1, 0xdc, 0xdb, 0x8a,
    67  			0x01, 0x6b, 0x49, 0x84, 0x0f, 0x8c, 0x53, 0xbc, 0x1e,
    68  			0xb6, 0x8a, 0x38, 0x2e, 0x97, 0xb1, 0x48, 0x2e, 0xca,
    69  			0xd7, 0xb1, 0x48, 0xa6, 0x90, 0x9a, 0x5c, 0xb2, 0xe0,
    70  			0xea, 0xdd, 0xfb, 0x84, 0xcc, 0xf9, 0x74, 0x44, 0x64,
    71  			0xf8, 0x2e, 0x16, 0x0b, 0xfa, 0x9b, 0x8b, 0x64, 0xf9,
    72  			0xd4, 0xc0, 0x3f, 0x99, 0x9b, 0x86, 0x43, 0xf6, 0x56,
    73  			0xb4, 0x12, 0xa3,
    74  		},
    75  		isValid: false,
    76  	},
    77  	{
    78  		name: "uncompressed as hybrid ok",
    79  		key: []byte{0x07, 0x11, 0xdb, 0x93, 0xe1, 0xdc, 0xdb, 0x8a,
    80  			0x01, 0x6b, 0x49, 0x84, 0x0f, 0x8c, 0x53, 0xbc, 0x1e,
    81  			0xb6, 0x8a, 0x38, 0x2e, 0x97, 0xb1, 0x48, 0x2e, 0xca,
    82  			0xd7, 0xb1, 0x48, 0xa6, 0x90, 0x9a, 0x5c, 0xb2, 0xe0,
    83  			0xea, 0xdd, 0xfb, 0x84, 0xcc, 0xf9, 0x74, 0x44, 0x64,
    84  			0xf8, 0x2e, 0x16, 0x0b, 0xfa, 0x9b, 0x8b, 0x64, 0xf9,
    85  			0xd4, 0xc0, 0x3f, 0x99, 0x9b, 0x86, 0x43, 0xf6, 0x56,
    86  			0xb4, 0x12, 0xa3,
    87  		},
    88  		isValid: true,
    89  		format:  pubkeyHybrid,
    90  	},
    91  	{
    92  		name: "uncompressed as hybrid wrong",
    93  		key: []byte{0x06, 0x11, 0xdb, 0x93, 0xe1, 0xdc, 0xdb, 0x8a,
    94  			0x01, 0x6b, 0x49, 0x84, 0x0f, 0x8c, 0x53, 0xbc, 0x1e,
    95  			0xb6, 0x8a, 0x38, 0x2e, 0x97, 0xb1, 0x48, 0x2e, 0xca,
    96  			0xd7, 0xb1, 0x48, 0xa6, 0x90, 0x9a, 0x5c, 0xb2, 0xe0,
    97  			0xea, 0xdd, 0xfb, 0x84, 0xcc, 0xf9, 0x74, 0x44, 0x64,
    98  			0xf8, 0x2e, 0x16, 0x0b, 0xfa, 0x9b, 0x8b, 0x64, 0xf9,
    99  			0xd4, 0xc0, 0x3f, 0x99, 0x9b, 0x86, 0x43, 0xf6, 0x56,
   100  			0xb4, 0x12, 0xa3,
   101  		},
   102  		isValid: false,
   103  	},
   104  	// from tx 0b09c51c51ff762f00fb26217269d2a18e77a4fa87d69b3c363ab4df16543f20
   105  	{
   106  		name: "compressed ok (ybit = 0)",
   107  		key: []byte{0x02, 0xce, 0x0b, 0x14, 0xfb, 0x84, 0x2b, 0x1b,
   108  			0xa5, 0x49, 0xfd, 0xd6, 0x75, 0xc9, 0x80, 0x75, 0xf1,
   109  			0x2e, 0x9c, 0x51, 0x0f, 0x8e, 0xf5, 0x2b, 0xd0, 0x21,
   110  			0xa9, 0xa1, 0xf4, 0x80, 0x9d, 0x3b, 0x4d,
   111  		},
   112  		isValid: true,
   113  		format:  pubkeyCompressed,
   114  	},
   115  	// from tx fdeb8e72524e8dab0da507ddbaf5f88fe4a933eb10a66bc4745bb0aa11ea393c
   116  	{
   117  		name: "compressed ok (ybit = 1)",
   118  		key: []byte{0x03, 0x26, 0x89, 0xc7, 0xc2, 0xda, 0xb1, 0x33,
   119  			0x09, 0xfb, 0x14, 0x3e, 0x0e, 0x8f, 0xe3, 0x96, 0x34,
   120  			0x25, 0x21, 0x88, 0x7e, 0x97, 0x66, 0x90, 0xb6, 0xb4,
   121  			0x7f, 0x5b, 0x2a, 0x4b, 0x7d, 0x44, 0x8e,
   122  		},
   123  		isValid: true,
   124  		format:  pubkeyCompressed,
   125  	},
   126  	{
   127  		name: "compressed claims uncompressed (ybit = 0)",
   128  		key: []byte{0x04, 0xce, 0x0b, 0x14, 0xfb, 0x84, 0x2b, 0x1b,
   129  			0xa5, 0x49, 0xfd, 0xd6, 0x75, 0xc9, 0x80, 0x75, 0xf1,
   130  			0x2e, 0x9c, 0x51, 0x0f, 0x8e, 0xf5, 0x2b, 0xd0, 0x21,
   131  			0xa9, 0xa1, 0xf4, 0x80, 0x9d, 0x3b, 0x4d,
   132  		},
   133  		isValid: false,
   134  	},
   135  	{
   136  		name: "compressed claims uncompressed (ybit = 1)",
   137  		key: []byte{0x05, 0x26, 0x89, 0xc7, 0xc2, 0xda, 0xb1, 0x33,
   138  			0x09, 0xfb, 0x14, 0x3e, 0x0e, 0x8f, 0xe3, 0x96, 0x34,
   139  			0x25, 0x21, 0x88, 0x7e, 0x97, 0x66, 0x90, 0xb6, 0xb4,
   140  			0x7f, 0x5b, 0x2a, 0x4b, 0x7d, 0x44, 0x8e,
   141  		},
   142  		isValid: false,
   143  	},
   144  	{
   145  		name:    "wrong length)",
   146  		key:     []byte{0x05},
   147  		isValid: false,
   148  	},
   149  	{
   150  		name: "X == P",
   151  		key: []byte{0x04, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
   152  			0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
   153  			0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
   154  			0xFF, 0xFF, 0xFE, 0xFF, 0xFF, 0xFC, 0x2F, 0xb2, 0xe0,
   155  			0xea, 0xdd, 0xfb, 0x84, 0xcc, 0xf9, 0x74, 0x44, 0x64,
   156  			0xf8, 0x2e, 0x16, 0x0b, 0xfa, 0x9b, 0x8b, 0x64, 0xf9,
   157  			0xd4, 0xc0, 0x3f, 0x99, 0x9b, 0x86, 0x43, 0xf6, 0x56,
   158  			0xb4, 0x12, 0xa3,
   159  		},
   160  		isValid: false,
   161  	},
   162  	{
   163  		name: "X > P",
   164  		key: []byte{0x04, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
   165  			0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
   166  			0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
   167  			0xFF, 0xFF, 0xFE, 0xFF, 0xFF, 0xFD, 0x2F, 0xb2, 0xe0,
   168  			0xea, 0xdd, 0xfb, 0x84, 0xcc, 0xf9, 0x74, 0x44, 0x64,
   169  			0xf8, 0x2e, 0x16, 0x0b, 0xfa, 0x9b, 0x8b, 0x64, 0xf9,
   170  			0xd4, 0xc0, 0x3f, 0x99, 0x9b, 0x86, 0x43, 0xf6, 0x56,
   171  			0xb4, 0x12, 0xa3,
   172  		},
   173  		isValid: false,
   174  	},
   175  	{
   176  		name: "Y == P",
   177  		key: []byte{0x04, 0x11, 0xdb, 0x93, 0xe1, 0xdc, 0xdb, 0x8a,
   178  			0x01, 0x6b, 0x49, 0x84, 0x0f, 0x8c, 0x53, 0xbc, 0x1e,
   179  			0xb6, 0x8a, 0x38, 0x2e, 0x97, 0xb1, 0x48, 0x2e, 0xca,
   180  			0xd7, 0xb1, 0x48, 0xa6, 0x90, 0x9a, 0x5c, 0xFF, 0xFF,
   181  			0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
   182  			0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
   183  			0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0xFF,
   184  			0xFF, 0xFC, 0x2F,
   185  		},
   186  		isValid: false,
   187  	},
   188  	{
   189  		name: "Y > P",
   190  		key: []byte{0x04, 0x11, 0xdb, 0x93, 0xe1, 0xdc, 0xdb, 0x8a,
   191  			0x01, 0x6b, 0x49, 0x84, 0x0f, 0x8c, 0x53, 0xbc, 0x1e,
   192  			0xb6, 0x8a, 0x38, 0x2e, 0x97, 0xb1, 0x48, 0x2e, 0xca,
   193  			0xd7, 0xb1, 0x48, 0xa6, 0x90, 0x9a, 0x5c, 0xFF, 0xFF,
   194  			0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
   195  			0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
   196  			0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0xFF,
   197  			0xFF, 0xFD, 0x2F,
   198  		},
   199  		isValid: false,
   200  	},
   201  	{
   202  		name: "hybrid",
   203  		key: []byte{0x06, 0x79, 0xbe, 0x66, 0x7e, 0xf9, 0xdc, 0xbb,
   204  			0xac, 0x55, 0xa0, 0x62, 0x95, 0xce, 0x87, 0x0b, 0x07,
   205  			0x02, 0x9b, 0xfc, 0xdb, 0x2d, 0xce, 0x28, 0xd9, 0x59,
   206  			0xf2, 0x81, 0x5b, 0x16, 0xf8, 0x17, 0x98, 0x48, 0x3a,
   207  			0xda, 0x77, 0x26, 0xa3, 0xc4, 0x65, 0x5d, 0xa4, 0xfb,
   208  			0xfc, 0x0e, 0x11, 0x08, 0xa8, 0xfd, 0x17, 0xb4, 0x48,
   209  			0xa6, 0x85, 0x54, 0x19, 0x9c, 0x47, 0xd0, 0x8f, 0xfb,
   210  			0x10, 0xd4, 0xb8,
   211  		},
   212  		format:  pubkeyHybrid,
   213  		isValid: true,
   214  	},
   215  }
   216  
   217  func TestPubKeys(t *testing.T) {
   218  	for _, test := range pubKeyTests {
   219  		pk, err := ParsePubKey(test.key, S256())
   220  		if err != nil {
   221  			if test.isValid {
   222  				t.Errorf("%s pubkey failed when shouldn't %v",
   223  					test.name, err)
   224  			}
   225  			continue
   226  		}
   227  		if !test.isValid {
   228  			t.Errorf("%s counted as valid when it should fail",
   229  				test.name)
   230  			continue
   231  		}
   232  		var pkStr []byte
   233  		switch test.format {
   234  		case pubkeyUncompressed:
   235  			pkStr = pk.SerializeUncompressed()
   236  		case pubkeyCompressed:
   237  			pkStr = pk.SerializeCompressed()
   238  		case pubkeyHybrid:
   239  			pkStr = pk.SerializeHybrid()
   240  		}
   241  		if !bytes.Equal(test.key, pkStr) {
   242  			t.Errorf("%s pubkey: serialized keys do not match.",
   243  				test.name)
   244  			spew.Dump(test.key)
   245  			spew.Dump(pkStr)
   246  		}
   247  	}
   248  }
   249  
   250  func TestPublicKeyIsEqual(t *testing.T) {
   251  	pubKey1, err := ParsePubKey(
   252  		[]byte{0x03, 0x26, 0x89, 0xc7, 0xc2, 0xda, 0xb1, 0x33,
   253  			0x09, 0xfb, 0x14, 0x3e, 0x0e, 0x8f, 0xe3, 0x96, 0x34,
   254  			0x25, 0x21, 0x88, 0x7e, 0x97, 0x66, 0x90, 0xb6, 0xb4,
   255  			0x7f, 0x5b, 0x2a, 0x4b, 0x7d, 0x44, 0x8e,
   256  		},
   257  		S256(),
   258  	)
   259  	if err != nil {
   260  		t.Fatalf("failed to parse raw bytes for pubKey1: %v", err)
   261  	}
   262  
   263  	pubKey2, err := ParsePubKey(
   264  		[]byte{0x02, 0xce, 0x0b, 0x14, 0xfb, 0x84, 0x2b, 0x1b,
   265  			0xa5, 0x49, 0xfd, 0xd6, 0x75, 0xc9, 0x80, 0x75, 0xf1,
   266  			0x2e, 0x9c, 0x51, 0x0f, 0x8e, 0xf5, 0x2b, 0xd0, 0x21,
   267  			0xa9, 0xa1, 0xf4, 0x80, 0x9d, 0x3b, 0x4d,
   268  		},
   269  		S256(),
   270  	)
   271  	if err != nil {
   272  		t.Fatalf("failed to parse raw bytes for pubKey2: %v", err)
   273  	}
   274  
   275  	if !pubKey1.IsEqual(pubKey1) {
   276  		t.Fatalf("value of IsEqual is incorrect, %v is "+
   277  			"equal to %v", pubKey1, pubKey1)
   278  	}
   279  
   280  	if pubKey1.IsEqual(pubKey2) {
   281  		t.Fatalf("value of IsEqual is incorrect, %v is not "+
   282  			"equal to %v", pubKey1, pubKey2)
   283  	}
   284  }
   285  
   286  func TestIsCompressed(t *testing.T) {
   287  	for _, test := range pubKeyTests {
   288  		isCompressed := IsCompressedPubKey(test.key)
   289  		wantCompressed := (test.format == pubkeyCompressed)
   290  		if isCompressed != wantCompressed {
   291  			t.Fatalf("%s (%x) pubkey: unexpected compressed result, "+
   292  				"got %v, want %v", test.name, test.key,
   293  				isCompressed, wantCompressed)
   294  		}
   295  	}
   296  }