From c2247f9737e48b6da28e9adaaffd83ab62ed5d72 Mon Sep 17 00:00:00 2001 From: L11R Date: Thu, 24 Oct 2019 00:21:36 +0300 Subject: [PATCH] Codebase cleaning and refreshing; Go 1.13 is now minimally supported version; pkg/errors -> native error wrapping (fmt.Errors); --- .travis.yml | 3 +-- README.md | 2 ++ ecies.go | 19 ++++++++++--------- go.mod | 7 +++---- go.sum | 6 ++---- privatekey.go | 13 +++++++------ publickey.go | 23 ++++++++++++----------- utils.go | 7 ++++--- 8 files changed, 41 insertions(+), 39 deletions(-) diff --git a/.travis.yml b/.travis.yml index dcb885e..3393d4c 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,8 +1,7 @@ language: go go: - - 1.11.x - - 1.12.x + - 1.13.x script: # build test for supported platforms diff --git a/README.md b/README.md index 791e32d..00449bc 100644 --- a/README.md +++ b/README.md @@ -11,6 +11,8 @@ This is the Go version of [ecies/py](https://github.com/ecies/py) with a built-i ## Install `go get github.com/ecies/go` +Go 1.13 is required cause `fmt.Errorf` is used to wrap errors. + ## Quick Start ```go package main diff --git a/ecies.go b/ecies.go index 44e646d..cab059f 100644 --- a/ecies.go +++ b/ecies.go @@ -5,9 +5,10 @@ import ( "crypto/aes" "crypto/cipher" "crypto/rand" - "github.com/fomichev/secp256k1" - "github.com/pkg/errors" + "fmt" "math/big" + + "github.com/fomichev/secp256k1" ) // Encrypt encrypts a passed message with a receiver public key, returns ciphertext or encryption error @@ -31,19 +32,19 @@ func Encrypt(pubkey *PublicKey, msg []byte) ([]byte, error) { // AES encryption block, err := aes.NewCipher(ss) if err != nil { - return nil, errors.Wrap(err, "cannot create new aes block") + return nil, fmt.Errorf("cannot create new aes block: %w", err) } nonce := make([]byte, 16) if _, err := rand.Read(nonce); err != nil { - return nil, errors.Wrap(err, "cannot read random bytes for nonce") + return nil, fmt.Errorf("cannot read random bytes for nonce: %w", err) } ct.Write(nonce) aesgcm, err := cipher.NewGCMWithNonceSize(block, 16) if err != nil { - return nil, errors.Wrap(err, "cannot create aes gcm") + return nil, fmt.Errorf("cannot create aes gcm: %w", err) } ciphertext := aesgcm.Seal(nil, nonce, msg, nil) @@ -60,7 +61,7 @@ func Encrypt(pubkey *PublicKey, msg []byte) ([]byte, error) { func Decrypt(privkey *PrivateKey, msg []byte) ([]byte, error) { // Message cannot be less than length of public key (65) + nonce (16) + tag (16) if len(msg) <= (1 + 32 + 32 + 16 + 16) { - return nil, errors.New("invalid length of message") + return nil, fmt.Errorf("invalid length of message") } // Ephemeral sender public key @@ -88,17 +89,17 @@ func Decrypt(privkey *PrivateKey, msg []byte) ([]byte, error) { block, err := aes.NewCipher(ss) if err != nil { - return nil, errors.Wrap(err, "cannot create new aes block") + return nil, fmt.Errorf("cannot create new aes block: %w", err) } gcm, err := cipher.NewGCMWithNonceSize(block, 16) if err != nil { - return nil, errors.Wrap(err, "cannot create gcm cipher") + return nil, fmt.Errorf("cannot create gcm cipher: %w", err) } plaintext, err := gcm.Open(nil, nonce, ciphertext, nil) if err != nil { - return nil, errors.Wrap(err, "cannot decrypt ciphertext") + return nil, fmt.Errorf("cannot decrypt ciphertext: %w", err) } return plaintext, nil diff --git a/go.mod b/go.mod index f0009bd..3bcdbde 100644 --- a/go.mod +++ b/go.mod @@ -1,13 +1,12 @@ module github.com/ecies/go -go 1.12 - require ( github.com/davecgh/go-spew v1.1.1 // indirect github.com/fomichev/secp256k1 v0.0.0-20180413221153-00116ff8c62f github.com/kr/pretty v0.1.0 // indirect - github.com/pkg/errors v0.8.1 github.com/stretchr/testify v1.4.0 - golang.org/x/crypto v0.0.0-20190701094942-4def268fd1a4 + golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550 gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 // indirect ) + +go 1.13 diff --git a/go.sum b/go.sum index 59db126..e4443f4 100644 --- a/go.sum +++ b/go.sum @@ -9,16 +9,14 @@ github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORN github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= -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/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= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= -golang.org/x/crypto v0.0.0-20190701094942-4def268fd1a4 h1:HuIa8hRrWRSrqYzx1qI49NNxhdi2PrY7gxVSq1JjLDc= -golang.org/x/crypto v0.0.0-20190701094942-4def268fd1a4/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550 h1:ObdrDkeb4kJdCP557AjRjq69pTHfNouLtWZG7j9rPN8= +golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= diff --git a/privatekey.go b/privatekey.go index 47dffbb..3466b2a 100644 --- a/privatekey.go +++ b/privatekey.go @@ -6,9 +6,10 @@ import ( "crypto/rand" "crypto/subtle" "encoding/hex" - "github.com/fomichev/secp256k1" - "github.com/pkg/errors" + "fmt" "math/big" + + "github.com/fomichev/secp256k1" ) // PrivateKey is an instance of secp256k1 private key with nested public key @@ -23,7 +24,7 @@ func GenerateKey() (*PrivateKey, error) { p, x, y, err := elliptic.GenerateKey(curve, rand.Reader) if err != nil { - return nil, errors.Wrap(err, "cannot generate key pair") + return nil, fmt.Errorf("cannot generate key pair: %w", err) } return &PrivateKey{ @@ -40,7 +41,7 @@ func GenerateKey() (*PrivateKey, error) { func NewPrivateKeyFromHex(s string) (*PrivateKey, error) { b, err := hex.DecodeString(s) if err != nil { - return nil, errors.Wrap(err, "cannot decode hex string") + return nil, fmt.Errorf("cannot decode hex string: %w", err) } return NewPrivateKeyFromBytes(b), nil @@ -75,7 +76,7 @@ func (k *PrivateKey) Hex() string { // can be safely used as encryption key func (k *PrivateKey) Encapsulate(pub *PublicKey) ([]byte, error) { if pub == nil { - return nil, errors.New("public key is empty") + return nil, fmt.Errorf("public key is empty") } var secret bytes.Buffer @@ -96,7 +97,7 @@ func (k *PrivateKey) Encapsulate(pub *PublicKey) ([]byte, error) { // Must not be used as encryption key, it increases chances to perform successful key restoration attack func (k *PrivateKey) ECDH(pub *PublicKey) ([]byte, error) { if pub == nil { - return nil, errors.New("public key is empty") + return nil, fmt.Errorf("public key is empty") } // Shared secret generation diff --git a/publickey.go b/publickey.go index b193b15..3885766 100644 --- a/publickey.go +++ b/publickey.go @@ -5,9 +5,10 @@ import ( "crypto/elliptic" "crypto/subtle" "encoding/hex" - "github.com/fomichev/secp256k1" - "github.com/pkg/errors" + "fmt" "math/big" + + "github.com/fomichev/secp256k1" ) // PublicKey instance with nested elliptic.Curve interface (secp256k1 instance in our case) @@ -20,7 +21,7 @@ type PublicKey struct { func NewPublicKeyFromHex(s string) (*PublicKey, error) { b, err := hex.DecodeString(s) if err != nil { - return nil, errors.Wrap(err, "cannot decode hex string") + return nil, fmt.Errorf("cannot decode hex string: %w", err) } return NewPublicKeyFromBytes(b) @@ -34,7 +35,7 @@ func NewPublicKeyFromBytes(b []byte) (*PublicKey, error) { switch b[0] { case 0x02, 0x03: if len(b) != 33 { - return nil, errors.New("cannot parse public key") + return nil, fmt.Errorf("cannot parse public key") } x := new(big.Int).SetBytes(b[1:]) @@ -47,7 +48,7 @@ func NewPublicKeyFromBytes(b []byte) (*PublicKey, error) { } if x.Cmp(curve.Params().P) >= 0 { - return nil, errors.New("cannot parse public key") + return nil, fmt.Errorf("cannot parse public key") } // y^2 = x^3 + b @@ -63,7 +64,7 @@ func NewPublicKeyFromBytes(b []byte) (*PublicKey, error) { y.Sub(curve.Params().P, &y) } if y.Bit(0) != ybit { - return nil, errors.New("incorrectly encoded X and Y bit") + return nil, fmt.Errorf("incorrectly encoded X and Y bit") } return &PublicKey{ @@ -73,19 +74,19 @@ func NewPublicKeyFromBytes(b []byte) (*PublicKey, error) { }, nil case 0x04: if len(b) != 65 { - return nil, errors.New("cannot parse public key") + return nil, fmt.Errorf("cannot parse public key") } x := new(big.Int).SetBytes(b[1:33]) y := new(big.Int).SetBytes(b[33:]) if x.Cmp(curve.Params().P) >= 0 || y.Cmp(curve.Params().P) >= 0 { - return nil, errors.New("cannot parse public key") + return nil, fmt.Errorf("cannot parse public key") } x3 := new(big.Int).Sqrt(x).Mul(x, x) if t := new(big.Int).Sqrt(y).Sub(y, x3.Add(x3, curve.Params().B)); t.IsInt64() && t.Int64() == 0 { - return nil, errors.New("cannot parse public key") + return nil, fmt.Errorf("cannot parse public key") } return &PublicKey{ @@ -94,7 +95,7 @@ func NewPublicKeyFromBytes(b []byte) (*PublicKey, error) { Y: y, }, nil default: - return nil, errors.New("cannot parse public key") + return nil, fmt.Errorf("cannot parse public key") } } @@ -137,7 +138,7 @@ func (k *PublicKey) Hex(compressed bool) string { // can be safely used as encryption key func (k *PublicKey) Decapsulate(priv *PrivateKey) ([]byte, error) { if priv == nil { - return nil, errors.New("public key is empty") + return nil, fmt.Errorf("public key is empty") } var secret bytes.Buffer diff --git a/utils.go b/utils.go index e25af85..72af677 100644 --- a/utils.go +++ b/utils.go @@ -2,16 +2,17 @@ package eciesgo import ( "crypto/sha256" - "github.com/pkg/errors" - "golang.org/x/crypto/hkdf" + "fmt" "io" + + "golang.org/x/crypto/hkdf" ) func kdf(secret []byte) (key []byte, err error) { key = make([]byte, 32) kdf := hkdf.New(sha256.New, secret, nil, nil) if _, err := io.ReadFull(kdf, key); err != nil { - return nil, errors.Wrap(err, "cannot read secret from HKDF reader") + return nil, fmt.Errorf("cannot read secret from HKDF reader: %w", err) } return key, nil