From 6c471ecd98f88b6538fe907ba12aa80e05210fb5 Mon Sep 17 00:00:00 2001 From: Roman Khimov Date: Wed, 25 Dec 2019 18:00:25 +0300 Subject: [PATCH] keys: move IsOnCurve decoding check, add a test for it This check only makes sense for 04-encoded points, because 02 and 03 derive Y from X and they're on the curve by definition. --- pkg/crypto/keys/publickey.go | 14 +++++++------- pkg/crypto/keys/publickey_test.go | 6 ++++++ 2 files changed, 13 insertions(+), 7 deletions(-) diff --git a/pkg/crypto/keys/publickey.go b/pkg/crypto/keys/publickey.go index 38f4a22a7..422efadca 100644 --- a/pkg/crypto/keys/publickey.go +++ b/pkg/crypto/keys/publickey.go @@ -173,6 +173,8 @@ func (p *PublicKey) DecodeBinary(r *io.BinReader) { return } + p256 := elliptic.P256() + p256Params := p256.Params() // Infinity switch prefix { case 0x00: @@ -202,17 +204,15 @@ func (p *PublicKey) DecodeBinary(r *io.BinReader) { } x = new(big.Int).SetBytes(xbytes) y = new(big.Int).SetBytes(ybytes) + if !p256.IsOnCurve(x, y) { + r.Err = errors.New("encoded point is not on the P256 curve") + return + } default: r.Err = errors.Errorf("invalid prefix %d", prefix) return } - c := elliptic.P256() - cp := c.Params() - if !c.IsOnCurve(x, y) { - r.Err = errors.New("enccoded point is not on the P256 curve") - return - } - if x.Cmp(cp.P) >= 0 || y.Cmp(cp.P) >= 0 { + if x.Cmp(p256Params.P) >= 0 || y.Cmp(p256Params.P) >= 0 { r.Err = errors.New("enccoded point is not correct (X or Y is bigger than P") return } diff --git a/pkg/crypto/keys/publickey_test.go b/pkg/crypto/keys/publickey_test.go index 38f80adc1..98a73a40f 100644 --- a/pkg/crypto/keys/publickey_test.go +++ b/pkg/crypto/keys/publickey_test.go @@ -69,6 +69,12 @@ func TestDecodeFromStringBadCompressed(t *testing.T) { require.Error(t, err) } +func TestDecodeFromStringNotOnCurve(t *testing.T) { + str := "04ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff" + _, err := NewPublicKeyFromString(str) + require.Error(t, err) +} + func TestPubkeyToAddress(t *testing.T) { pubKey, err := NewPublicKeyFromString("031ee4e73a17d8f76dc02532e2620bcb12425b33c0c9f9694cc2caa8226b68cad4") require.NoError(t, err)