Skip to content
This repository has been archived by the owner on Feb 22, 2024. It is now read-only.

Commit

Permalink
Fix tests on go1.19 (#16)
Browse files Browse the repository at this point in the history
* [#15] ecdsa: Fix signature marshaling with go1.19

Signed-off-by: Evgenii Stratonikov <stratonikov@runbox.com>

* [#15] go.mod: Update go version to 1.16

Signed-off-by: Evgenii Stratonikov <stratonikov@runbox.com>

* [#15] go.mod: Drop `pkg/errors` dependency

Signed-off-by: Evgenii Stratonikov <stratonikov@runbox.com>

* [#15] *: Perform `goimports -w`

Signed-off-by: Evgenii Stratonikov <stratonikov@runbox.com>

Signed-off-by: Evgenii Stratonikov <stratonikov@runbox.com>
Co-authored-by: Evgenii Stratonikov <stratonikov@runbox.com>
  • Loading branch information
fyrchik and fyrchik authored Aug 15, 2022
1 parent 225b24f commit d29d7f9
Show file tree
Hide file tree
Showing 11 changed files with 55 additions and 177 deletions.
45 changes: 38 additions & 7 deletions ecdsa.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,10 @@ import (
"crypto/rand"
"crypto/sha512"
"crypto/x509"
"fmt"
"math/big"

"github.com/nspcc-dev/neofs-crypto/internal"
"github.com/pkg/errors"
)

const (
Expand Down Expand Up @@ -39,9 +39,18 @@ const (
// P256 is base elliptic curve.
var curve = elliptic.P256()

// Marshal converts a points into the uncompressed form specified in section 4.3.6 of ANSI X9.62.
func marshalXY(x, y *big.Int) []byte {
return elliptic.Marshal(curve, x, y)
// marshalXY converts points into the uncompressed form specified in section 4.3.6 of ANSI X9.62.
// It is also used to marshal signature, for backwards compatibility.
func marshalXY(curve elliptic.Curve, x, y *big.Int) []byte {
params := curve.Params()
curveOrderByteSize := params.P.BitLen() / 8
buf := make([]byte, 1+curveOrderByteSize*2)
// r and s are not on curve at all, leave for backwards compatibility
buf[0] = 4
_ = x.FillBytes(buf[1 : 1+curveOrderByteSize])
_ = y.FillBytes(buf[1+curveOrderByteSize:])

return buf
}

// unmarshalXY converts a point, serialized by Marshal, into an x, y pair.
Expand Down Expand Up @@ -76,7 +85,7 @@ func MarshalPublicKey(key *ecdsa.PublicKey) []byte {
return nil
}

return encodePoint(key.X, key.Y)
return elliptic.MarshalCompressed(curve, key.X, key.Y)
}

// UnmarshalPublicKey from bytes.
Expand All @@ -92,6 +101,28 @@ func UnmarshalPublicKey(data []byte) *ecdsa.PublicKey {
return nil
}

func decodePoint(data []byte) (x *big.Int, y *big.Int) {
// empty data
if len(data) == 0 {
return
}

// tries to unmarshal compressed form
// returns (nil, nil) when:
// - wrong len(data)
// - data[0] != 2 && data[0] != 3
if x, y = elliptic.UnmarshalCompressed(curve, data); x != nil && y != nil {
return x, y
}

// tries to unmarshal uncompressed form and check that points on curve
if x, y = unmarshalXY(data); x == nil || y == nil || !curve.IsOnCurve(x, y) {
x, y = nil, nil
}

return x, y
}

// UnmarshalPrivateKey from bytes.
// It is similar to `ecdsa.Generate()` but uses pre-defined big.Int and
// curve for NEO Blockchain (elliptic.P256)
Expand Down Expand Up @@ -135,7 +166,7 @@ func VerifyHash(pub *ecdsa.PublicKey, msgHash, sig []byte) error {
} else if r, s := unmarshalXY(sig); r == nil || s == nil {
return ErrCannotUnmarshal
} else if !ecdsa.Verify(pub, msgHash, r, s) {
return errors.Wrapf(ErrInvalidSignature, "%0x : %0x", r, s)
return fmt.Errorf("%w: %0x : %0x", ErrInvalidSignature, r, s)
}

return nil
Expand All @@ -156,5 +187,5 @@ func SignHash(key *ecdsa.PrivateKey, msgHash []byte) ([]byte, error) {
return nil, err
}

return marshalXY(x, y), nil
return marshalXY(key.Curve, x, y), nil
}
34 changes: 0 additions & 34 deletions ecdsa_go1.15.go

This file was deleted.

79 changes: 0 additions & 79 deletions ecdsa_older_go.go

This file was deleted.

28 changes: 0 additions & 28 deletions ecdsa_older_go_test.go

This file was deleted.

8 changes: 4 additions & 4 deletions ecdsa_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -115,12 +115,12 @@ func TestSignVerify(t *testing.T) {
r1, s1, err := ecdsa.Sign(rand.Reader, key, hashBytes(data))
require.NoError(t, err)

sign := marshalXY(r1, s1)
sign := marshalXY(key.Curve, r1, s1)
UnmarshalPublicKey(sign)
}

{ // 3. bad big.Ints
sign := marshalXY(big.NewInt(0), big.NewInt(1))
sign := marshalXY(elliptic.P256(), big.NewInt(0), big.NewInt(1))
UnmarshalPublicKey(sign)
}
})
Expand All @@ -129,7 +129,7 @@ func TestSignVerify(t *testing.T) {
t.Run("using prepared hash", func(t *testing.T) {
var (
data = []byte("Hello world")
sum = sha512.Sum512(data)
sum = sha512.Sum512(data)
key = test.DecodeKey(0)
)
sig, err := SignHash(key, sum[:])
Expand All @@ -148,7 +148,7 @@ func TestSignVerify(t *testing.T) {
hashBytes(data))
require.NoError(t, err)

sign := marshalXY(r1, s1)
sign := marshalXY(key.Curve, r1, s1)

{ // This is just to validate, that we are on right way.. try to unmarshal R/S from sign
// validate bytes length
Expand Down
3 changes: 1 addition & 2 deletions go.mod
Original file line number Diff line number Diff line change
@@ -1,10 +1,9 @@
module github.com/nspcc-dev/neofs-crypto

go 1.13
go 1.16

require (
github.com/mr-tron/base58 v1.2.0
github.com/nspcc-dev/rfc6979 v0.2.0
github.com/pkg/errors v0.9.1
github.com/stretchr/testify v1.7.0
)
10 changes: 0 additions & 10 deletions go.sum
Original file line number Diff line number Diff line change
@@ -1,25 +1,15 @@
github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/mr-tron/base58 v1.1.2 h1:ZEw4I2EgPKDJ2iEw0cNmLB3ROrEmkOtXIkaG7wZg+78=
github.com/mr-tron/base58 v1.1.2/go.mod h1:BinMc/sQntlIE1frQmRFPUoPA1Zkr8VRgBdjWI2mNwc=
github.com/mr-tron/base58 v1.2.0 h1:T/HDJBh4ZCPbU39/+c3rRvE0uKBQlU27+QI8LJ4t64o=
github.com/mr-tron/base58 v1.2.0/go.mod h1:BinMc/sQntlIE1frQmRFPUoPA1Zkr8VRgBdjWI2mNwc=
github.com/nspcc-dev/rfc6979 v0.2.0 h1:3e1WNxrN60/6N0DW7+UYisLeZJyfqZTNOjeV/toYvOE=
github.com/nspcc-dev/rfc6979 v0.2.0/go.mod h1:exhIh1PdpDC5vQmyEsGvc4YDM/lyQp/452QxGq/UEso=
github.com/pkg/errors v0.8.1 h1:iURUrRGxPUNPdy5/HRSm+Yj6okJ6UtLINN0Q9M4+h3I=
github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/testify v1.4.0 h1:2E4SXV/wtOkTonXsotYi4li6zVWxYlZuYNCXe9XRJyk=
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY=
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/yaml.v2 v2.2.2 h1:ZCJp+EgiOT7lHqUV2J862kp8Qj64Jo6az82+3Td9dZw=
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
9 changes: 4 additions & 5 deletions load.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,23 +3,22 @@ package crypto
import (
"crypto/ecdsa"
"encoding/hex"
"io/ioutil"

"github.com/pkg/errors"
"fmt"
"os"
)

// LoadPrivateKey allows to load private key from various formats:
// - wif string
// - hex string
// - file path (D-bytes or SEC 1 / ASN.1 DER form)
func LoadPrivateKey(val string) (*ecdsa.PrivateKey, error) {
if data, err := ioutil.ReadFile(val); err == nil {
if data, err := os.ReadFile(val); err == nil {
return UnmarshalPrivateKey(data)
} else if data, err = hex.DecodeString(val); err == nil {
return UnmarshalPrivateKey(data)
} else if key, err := WIFDecode(val); err == nil {
return key, nil
}

return nil, errors.Errorf("unknown key format (%q), expect: hex-string, wif or file-path", val)
return nil, fmt.Errorf("unknown key format (%q), expect: hex-string, wif or file-path", val)
}
5 changes: 3 additions & 2 deletions rfc6979.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,11 @@ package crypto
import (
"crypto/ecdsa"
"crypto/sha256"
"fmt"
"math/big"

"github.com/nspcc-dev/neofs-crypto/internal"
"github.com/nspcc-dev/rfc6979"
"github.com/pkg/errors"
)

const (
Expand Down Expand Up @@ -60,7 +60,8 @@ func SignRFC6979Hash(key *ecdsa.PrivateKey, msgHash []byte) ([]byte, error) {

func decodeSignature(sig []byte) (*big.Int, *big.Int, error) {
if ln := len(sig); ln != RFC6979SignatureSize {
return nil, nil, errors.Wrapf(ErrWrongHashSize, "actual=%d, expect=%d", ln, RFC6979SignatureSize)
return nil, nil, fmt.Errorf("%w: actual=%d, expect=%d",
ErrWrongHashSize, ln, RFC6979SignatureSize)
}

return new(big.Int).SetBytes(sig[:32]), new(big.Int).SetBytes(sig[32:]), nil
Expand Down
6 changes: 3 additions & 3 deletions wif.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,10 @@ import (
"bytes"
"crypto/ecdsa"
"crypto/sha256"
"fmt"

"github.com/mr-tron/base58"
"github.com/nspcc-dev/neofs-crypto/internal"
"github.com/pkg/errors"
)

const (
Expand Down Expand Up @@ -51,9 +51,9 @@ func WIFEncode(key *ecdsa.PrivateKey) (string, error) {
func WIFDecode(wif string) (*ecdsa.PrivateKey, error) {
data, err := base58.Decode(wif)
if err != nil {
return nil, errors.Wrap(ErrBadWIF, err.Error())
return nil, fmt.Errorf("%w: %v", ErrBadWIF, err)
} else if actual := len(data); actual != WIFLength {
return nil, errors.Wrapf(ErrBadWIF, "expect: %d, actual: %d", WIFLength, actual)
return nil, fmt.Errorf("%w: expect: %d, actual: %d", ErrBadWIF, WIFLength, actual)
} else if sum := wifCheckSum(data[:34]); !bytes.Equal(data[34:], sum) {
return nil, ErrBadChecksum
}
Expand Down
Loading

0 comments on commit d29d7f9

Please sign in to comment.