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 }