github.com/nspcc-dev/neo-go@v0.105.2-0.20240517133400-6be757af3eba/pkg/crypto/keys/publickey_test.go (about)

     1  package keys
     2  
     3  import (
     4  	"crypto/elliptic"
     5  	"encoding/hex"
     6  	"encoding/json"
     7  	"math/rand"
     8  	"sort"
     9  	"testing"
    10  
    11  	"github.com/nspcc-dev/neo-go/internal/testserdes"
    12  	"github.com/stretchr/testify/require"
    13  	"gopkg.in/yaml.v3"
    14  )
    15  
    16  func TestEncodeDecodeInfinity(t *testing.T) {
    17  	key := &PublicKey{}
    18  	b, err := testserdes.EncodeBinary(key)
    19  	require.NoError(t, err)
    20  	require.Equal(t, 1, len(b))
    21  
    22  	keyDecode := &PublicKey{}
    23  	require.NoError(t, keyDecode.DecodeBytes(b))
    24  	require.Equal(t, []byte{0x00}, keyDecode.Bytes())
    25  }
    26  
    27  func TestEncodeDecodePublicKey(t *testing.T) {
    28  	for i := 0; i < 4; i++ {
    29  		k, err := NewPrivateKey()
    30  		require.NoError(t, err)
    31  		p := k.PublicKey()
    32  		testserdes.EncodeDecodeBinary(t, p, new(PublicKey))
    33  	}
    34  
    35  	errCases := [][]byte{{}, {0x02}, {0x04}}
    36  
    37  	for _, tc := range errCases {
    38  		require.Error(t, testserdes.DecodeBinary(tc, new(PublicKey)))
    39  	}
    40  }
    41  
    42  func TestPublicKeys_Copy(t *testing.T) {
    43  	require.Nil(t, (PublicKeys)(nil).Copy())
    44  
    45  	pubz := make([]*PublicKey, 5)
    46  	for i := range pubz {
    47  		priv, err := NewPrivateKey()
    48  		require.NoError(t, err)
    49  		pubz[i] = priv.PublicKey()
    50  	}
    51  	pubs := PublicKeys(pubz)
    52  
    53  	cp := pubs.Copy()
    54  	var pubx = ([]*PublicKey)(cp)
    55  	require.Equal(t, pubz, pubx)
    56  
    57  	priv, err := NewPrivateKey()
    58  	require.NoError(t, err)
    59  	cp[0] = priv.PublicKey()
    60  
    61  	require.NotEqual(t, pubs[0], cp[0])
    62  	require.Equal(t, pubs[1:], cp[1:])
    63  }
    64  
    65  func TestNewPublicKeyFromBytes(t *testing.T) {
    66  	priv, err := NewPrivateKey()
    67  	require.NoError(t, err)
    68  
    69  	b := priv.PublicKey().Bytes()
    70  	pub, err := NewPublicKeyFromBytes(b, elliptic.P256())
    71  	require.NoError(t, err)
    72  	require.Equal(t, priv.PublicKey(), pub)
    73  	// Test cached access
    74  	pub2, err := NewPublicKeyFromBytes(b, elliptic.P256())
    75  	require.NoError(t, err)
    76  	require.Same(t, pub, pub2)
    77  
    78  	_, err = NewPublicKeyFromBytes([]byte{0x00, 0x01}, elliptic.P256())
    79  	require.Error(t, err)
    80  }
    81  
    82  func TestDecodeFromString(t *testing.T) {
    83  	str := "03b209fd4f53a7170ea4444e0cb0a6bb6a53c2bd016926989cf85f9b0fba17a70c"
    84  	pubKey, err := NewPublicKeyFromString(str)
    85  	require.NoError(t, err)
    86  	require.Equal(t, str, pubKey.StringCompressed())
    87  
    88  	_, err = NewPublicKeyFromString(str[2:])
    89  	require.Error(t, err)
    90  
    91  	str = "zzb209fd4f53a7170ea4444e0cb0a6bb6a53c2bd016926989cf85f9b0fba17a70c"
    92  	_, err = NewPublicKeyFromString(str)
    93  	require.Error(t, err)
    94  }
    95  
    96  func TestDecodeFromStringBadCompressed(t *testing.T) {
    97  	str := "02ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"
    98  	_, err := NewPublicKeyFromString(str)
    99  	require.Error(t, err)
   100  }
   101  
   102  func TestDecodeFromStringBadXMoreThanP(t *testing.T) {
   103  	str := "02ffffffff00000001000000000000000000000001ffffffffffffffffffffffff"
   104  	_, err := NewPublicKeyFromString(str)
   105  	require.Error(t, err)
   106  }
   107  
   108  func TestDecodeFromStringNotOnCurve(t *testing.T) {
   109  	str := "04ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"
   110  	_, err := NewPublicKeyFromString(str)
   111  	require.Error(t, err)
   112  }
   113  
   114  func TestDecodeFromStringUncompressed(t *testing.T) {
   115  	str := "046b17d1f2e12c4247f8bce6e563a440f277037d812deb33a0f4a13945d898c2964fe342e2fe1a7f9b8ee7eb4a7c0f9e162bce33576b315ececbb6406837bf51f5"
   116  	_, err := NewPublicKeyFromString(str)
   117  	require.NoError(t, err)
   118  }
   119  
   120  func TestPubkeyToAddress(t *testing.T) {
   121  	pubKey, err := NewPublicKeyFromString("031ee4e73a17d8f76dc02532e2620bcb12425b33c0c9f9694cc2caa8226b68cad4")
   122  	require.NoError(t, err)
   123  	actual := pubKey.Address()
   124  	expected := "NdxG5MZQy8h2qseawfSt8tTYG2iQPTwsn9"
   125  	require.Equal(t, expected, actual)
   126  }
   127  
   128  func TestDecodeBytes(t *testing.T) {
   129  	pubKey := getPubKey(t)
   130  	var testBytesFunction = func(t *testing.T, bytesFunction func() []byte) {
   131  		decodedPubKey := &PublicKey{}
   132  		err := decodedPubKey.DecodeBytes(bytesFunction())
   133  		require.NoError(t, err)
   134  		require.Equal(t, pubKey, decodedPubKey)
   135  	}
   136  	t.Run("compressed", func(t *testing.T) { testBytesFunction(t, pubKey.Bytes) })
   137  	t.Run("uncompressed", func(t *testing.T) { testBytesFunction(t, pubKey.UncompressedBytes) })
   138  }
   139  
   140  func TestSort(t *testing.T) {
   141  	pubs1 := make(PublicKeys, 10)
   142  	for i := range pubs1 {
   143  		priv, err := NewPrivateKey()
   144  		require.NoError(t, err)
   145  		pubs1[i] = priv.PublicKey()
   146  	}
   147  
   148  	pubs2 := make(PublicKeys, len(pubs1))
   149  	copy(pubs2, pubs1)
   150  
   151  	sort.Sort(pubs1)
   152  
   153  	rand.Shuffle(len(pubs2), func(i, j int) {
   154  		pubs2[i], pubs2[j] = pubs2[j], pubs2[i]
   155  	})
   156  	sort.Sort(pubs2)
   157  
   158  	// Check that sort on the same set of values produce the same result.
   159  	require.Equal(t, pubs1, pubs2)
   160  }
   161  
   162  func TestContains(t *testing.T) {
   163  	pubKey := getPubKey(t)
   164  	pubKeys := &PublicKeys{getPubKey(t)}
   165  	pubKeys.Contains(pubKey)
   166  	require.True(t, pubKeys.Contains(pubKey))
   167  }
   168  
   169  func TestUnique(t *testing.T) {
   170  	pubKeys := &PublicKeys{getPubKey(t), getPubKey(t)}
   171  	unique := pubKeys.Unique()
   172  	require.Equal(t, 1, unique.Len())
   173  }
   174  
   175  func getPubKey(t testing.TB) *PublicKey {
   176  	pubKey, err := NewPublicKeyFromString("031ee4e73a17d8f76dc02532e2620bcb12425b33c0c9f9694cc2caa8226b68cad4")
   177  	require.NoError(t, err)
   178  	return pubKey
   179  }
   180  
   181  func TestMarshallJSON(t *testing.T) {
   182  	str := "03b209fd4f53a7170ea4444e0cb0a6bb6a53c2bd016926989cf85f9b0fba17a70c"
   183  	pubKey, err := NewPublicKeyFromString(str)
   184  	require.NoError(t, err)
   185  
   186  	bytes, err := json.Marshal(&pubKey)
   187  	require.NoError(t, err)
   188  	require.Equal(t, []byte(`"`+str+`"`), bytes)
   189  }
   190  
   191  func TestUnmarshallJSON(t *testing.T) {
   192  	str := "03b209fd4f53a7170ea4444e0cb0a6bb6a53c2bd016926989cf85f9b0fba17a70c"
   193  	expected, err := NewPublicKeyFromString(str)
   194  	require.NoError(t, err)
   195  
   196  	actual := &PublicKey{}
   197  	err = json.Unmarshal([]byte(`"`+str+`"`), actual)
   198  	require.NoError(t, err)
   199  	require.Equal(t, expected, actual)
   200  }
   201  
   202  func TestUnmarshallJSONBadCompresed(t *testing.T) {
   203  	str := `"02ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"`
   204  	actual := &PublicKey{}
   205  	err := json.Unmarshal([]byte(str), actual)
   206  	require.Error(t, err)
   207  }
   208  
   209  func TestUnmarshallJSONNotAHex(t *testing.T) {
   210  	str := `"04Tb17d1f2e12c4247f8bce6e563a440f277037d812deb33a0f4a13945d898c2964fe342e2fe1a7f9b8ee7eb4a7c0f9e162bce33576b315ececbb6406837bf51f5"`
   211  	actual := &PublicKey{}
   212  	err := json.Unmarshal([]byte(str), actual)
   213  	require.Error(t, err)
   214  }
   215  
   216  func TestUnmarshallJSONBadFormat(t *testing.T) {
   217  	str := "046b17d1f2e12c4247f8bce6e563a440f277037d812deb33a0f4a13945d898c2964fe342e2fe1a7f9b8ee7eb4a7c0f9e162bce33576b315ececbb6406837bf51f5"
   218  	actual := &PublicKey{}
   219  	err := json.Unmarshal([]byte(str), actual)
   220  	require.Error(t, err)
   221  }
   222  
   223  func BenchmarkPublicEqual(t *testing.B) {
   224  	k11 := getPubKey(t)
   225  	k12 := getPubKey(t)
   226  	k2, err := NewPublicKeyFromString("03b209fd4f53a7170ea4444e0cb0a6bb6a53c2bd016926989cf85f9b0fba17a70c")
   227  	require.NoError(t, err)
   228  	for n := 0; n < t.N; n++ {
   229  		_ = k11.Equal(k12)
   230  		_ = k11.Equal(k2)
   231  	}
   232  }
   233  
   234  func BenchmarkPublicBytes(t *testing.B) {
   235  	k := getPubKey(t)
   236  	for n := 0; n < t.N; n++ {
   237  		_ = k.Bytes()
   238  	}
   239  }
   240  
   241  func BenchmarkPublicUncompressedBytes(t *testing.B) {
   242  	k := getPubKey(t)
   243  	for n := 0; n < t.N; n++ {
   244  		_ = k.Bytes()
   245  	}
   246  }
   247  
   248  func BenchmarkPublicDecodeBytes(t *testing.B) {
   249  	keyBytes, err := hex.DecodeString("03b209fd4f53a7170ea4444e0cb0a6bb6a53c2bd016926989cf85f9b0fba17a70c")
   250  	require.NoError(t, err)
   251  	k := new(PublicKey)
   252  	for n := 0; n < t.N; n++ {
   253  		require.NoError(t, k.DecodeBytes(keyBytes))
   254  	}
   255  }
   256  
   257  func TestMarshallYAML(t *testing.T) {
   258  	str := "03b209fd4f53a7170ea4444e0cb0a6bb6a53c2bd016926989cf85f9b0fba17a70c"
   259  	pubKey, err := NewPublicKeyFromString(str)
   260  	require.NoError(t, err)
   261  
   262  	bytes, err := yaml.Marshal(&pubKey)
   263  	require.NoError(t, err)
   264  
   265  	expected := []byte(str + "\n") // YAML marshaller adds new line in the end which is expected.
   266  	require.Equal(t, expected, bytes)
   267  }
   268  
   269  func TestUnmarshallYAML(t *testing.T) {
   270  	str := "03b209fd4f53a7170ea4444e0cb0a6bb6a53c2bd016926989cf85f9b0fba17a70c"
   271  	expected, err := NewPublicKeyFromString(str)
   272  	require.NoError(t, err)
   273  
   274  	actual := &PublicKey{}
   275  	err = yaml.Unmarshal([]byte(str), actual)
   276  	require.NoError(t, err)
   277  	require.Equal(t, expected, actual)
   278  }
   279  
   280  func TestUnmarshallYAMLBadCompresed(t *testing.T) {
   281  	str := `"02ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"`
   282  	actual := &PublicKey{}
   283  	err := yaml.Unmarshal([]byte(str), actual)
   284  	require.Error(t, err)
   285  	require.Contains(t, err.Error(), "error computing Y for compressed point")
   286  }
   287  
   288  func TestUnmarshallYAMLNotAHex(t *testing.T) {
   289  	str := `"04Tb17d1f2e12c4247f8bce6e563a440f277037d812deb33a0f4a13945d898c2964fe342e2fe1a7f9b8ee7eb4a7c0f9e162bce33576b315ececbb6406837bf51f5"`
   290  	actual := &PublicKey{}
   291  	err := yaml.Unmarshal([]byte(str), actual)
   292  	require.Error(t, err)
   293  	require.Contains(t, err.Error(), "failed to decode public key from hex bytes")
   294  }
   295  
   296  func TestUnmarshallYAMLUncompressed(t *testing.T) {
   297  	str := "046b17d1f2e12c4247f8bce6e563a440f277037d812deb33a0f4a13945d898c2964fe342e2fe1a7f9b8ee7eb4a7c0f9e162bce33576b315ececbb6406837bf51f5"
   298  	expected, err := NewPublicKeyFromString(str)
   299  	require.NoError(t, err)
   300  
   301  	actual := &PublicKey{}
   302  	err = yaml.Unmarshal([]byte(str), actual)
   303  	require.NoError(t, err)
   304  	require.Equal(t, expected, actual)
   305  }
   306  
   307  func TestMarshalUnmarshalYAML(t *testing.T) {
   308  	str := "03b209fd4f53a7170ea4444e0cb0a6bb6a53c2bd016926989cf85f9b0fba17a70c"
   309  	expected, err := NewPublicKeyFromString(str)
   310  	require.NoError(t, err)
   311  
   312  	testserdes.MarshalUnmarshalYAML(t, expected, new(PublicKey))
   313  }