Skip to content

Commit

Permalink
EI-528 - Revert to go-ethereum for secp256k functionality (introduced…
Browse files Browse the repository at this point in the history
… in 398057a)

- github.com/fomichev/secp256k1 has negative performance impact
- vulnerability associated with go-ethereum is not relevant (i.e. code not touched)
  See also ethereum/go-ethereum#23866
- Bump github.com/ethereum/go-ethereum to v1.10.14
  • Loading branch information
vtermanis committed Jan 7, 2022
1 parent 2b2b4a1 commit 088a185
Show file tree
Hide file tree
Showing 6 changed files with 526 additions and 59 deletions.
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ module github.com/Iotic-Labs/iotics-identity-go
go 1.16

require (
github.com/fomichev/secp256k1 v0.0.0-20180413221153-00116ff8c62f
github.com/ethereum/go-ethereum v1.10.14
github.com/go-bdd/gobdd v1.1.3
github.com/golang-jwt/jwt v3.2.1+incompatible
github.com/google/go-cmp v0.5.6 // indirect
Expand Down
513 changes: 502 additions & 11 deletions go.sum

Large diffs are not rendered by default.

15 changes: 11 additions & 4 deletions pkg/crypto/key_pair_secrets_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,14 @@
package crypto_test

import (
"github.com/Iotic-Labs/iotics-identity-go/pkg/test"
"strings"
"testing"

"github.com/Iotic-Labs/iotics-identity-go/pkg/test"

id "github.com/Iotic-Labs/iotics-identity-go/pkg/identity"

"github.com/fomichev/secp256k1"
"github.com/ethereum/go-ethereum/crypto/secp256k1"

"github.com/Iotic-Labs/iotics-identity-go/pkg/crypto"
"github.com/tyler-smith/go-bip39"
Expand Down Expand Up @@ -164,26 +165,32 @@ func Test_validate_bip39_seed_should_raise_if_invalid_seed(t *testing.T) {
}

func Test_can_get_private_key_from_key_pair_secrets_bip39(t *testing.T) {
const expectedBitSize = 256
validKeyPairSecrets, _ := crypto.NewKeyPairSecrets(test.ValidBip39Seed32B, test.ValidKeyPairPath, crypto.SeedMethodBip39, "")

privateKey, err := crypto.GetPrivateKey(validKeyPairSecrets)

assert.NilError(t, err)
assert.Assert(t, privateKey != nil)

curve := secp256k1.SECP256K1()
curve := privateKey.PublicKey.Curve.(*secp256k1.BitCurve)
assert.Assert(t, curve != nil)
assert.Assert(t, curve.BitSize == expectedBitSize)
assert.Assert(t, curve.IsOnCurve(privateKey.X, privateKey.Y))
}

func Test_can_get_private_key_from_key_pair_secrets_none(t *testing.T) {
const expectedBitSize = 256
validKeyPairSecrets, _ := crypto.NewKeyPairSecrets(test.ValidBip39Seed32B, test.ValidKeyPairPath, crypto.SeedMethodNone, "")

privateKey, err := crypto.GetPrivateKey(validKeyPairSecrets)

assert.NilError(t, err)
assert.Assert(t, privateKey != nil)

curve := secp256k1.SECP256K1()
curve := privateKey.PublicKey.Curve.(*secp256k1.BitCurve)
assert.Assert(t, curve != nil)
assert.Assert(t, curve.BitSize == expectedBitSize)
assert.Assert(t, curve.IsOnCurve(privateKey.X, privateKey.Y))
}

Expand Down
35 changes: 4 additions & 31 deletions pkg/crypto/keys.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,10 @@ package crypto

import (
"crypto/ecdsa"
"crypto/elliptic"
"encoding/hex"
"errors"
"fmt"
"math/big"

"github.com/fomichev/secp256k1"
ethcrypto "github.com/ethereum/go-ethereum/crypto"
"github.com/jbenet/go-base58"
)

Expand All @@ -20,25 +17,7 @@ func GetPrivateKeyFromExponent(privateExponentHex string) (*ecdsa.PrivateKey, er
if err != nil {
return nil, err
}

privateECDSA := new(ecdsa.PrivateKey)
privateECDSA.PublicKey.Curve = secp256k1.SECP256K1()
privateECDSA.D = new(big.Int).SetBytes(privateKeyBytes)

// The privateECDSA.D must < N
if privateECDSA.D.Cmp(privateECDSA.Curve.Params().N) >= 0 {
return nil, fmt.Errorf("invalid private key, >=N")
}
// The privateECDSA.D must not be zero or negative.
if privateECDSA.D.Sign() <= 0 {
return nil, fmt.Errorf("invalid length, need 256 bits")
}

privateECDSA.PublicKey.X, privateECDSA.PublicKey.Y = privateECDSA.PublicKey.Curve.ScalarBaseMult(privateKeyBytes)
if privateECDSA.PublicKey.X == nil {
return nil, errors.New("invalid private key")
}
return privateECDSA, nil
return ethcrypto.ToECDSA(privateKeyBytes)
}

// GetPublicKeysFromPrivateKey Get public keys (bytes and base58) from private key (ECDSA)
Expand All @@ -49,7 +28,7 @@ func GetPublicKeysFromPrivateKey(privateKey *ecdsa.PrivateKey) ([]byte, string,
return nil, "", errors.New("error casting public key to ECDSA")
}

publicKeyDer := elliptic.Marshal(secp256k1.SECP256K1(), publicKeyECDSA.X, publicKeyECDSA.Y)
publicKeyDer := ethcrypto.FromECDSAPub(publicKeyECDSA)
publicKeyBase58 := base58.EncodeAlphabet(publicKeyDer, base58.BTCAlphabet)

return publicKeyDer, publicKeyBase58, nil
Expand All @@ -58,11 +37,5 @@ func GetPublicKeysFromPrivateKey(privateKey *ecdsa.PrivateKey) ([]byte, string,
// GetPublicKeyFromBase58 Get public key ECDSA from public key base58
func GetPublicKeyFromBase58(publicBase58 string) (*ecdsa.PublicKey, error) {
publicKeyBytes := base58.DecodeAlphabet(publicBase58, base58.BTCAlphabet)

curve := secp256k1.SECP256K1()
x, y := elliptic.Unmarshal(curve, publicKeyBytes)
if x == nil {
return nil, fmt.Errorf("invalid secp256k1 public key")
}
return &ecdsa.PublicKey{Curve: curve, X: x, Y: y}, nil
return ethcrypto.UnmarshalPubkey(publicKeyBytes)
}
7 changes: 5 additions & 2 deletions pkg/crypto/keys_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import (
"github.com/Iotic-Labs/iotics-identity-go/pkg/test"

"github.com/Iotic-Labs/iotics-identity-go/pkg/crypto"
"github.com/fomichev/secp256k1"
"github.com/ethereum/go-ethereum/crypto/secp256k1"
"github.com/jbenet/go-base58"
"gotest.tools/assert"
)
Expand All @@ -30,11 +30,14 @@ func Test_get_public_keys_from_private_ecdsa(t *testing.T) {
}

func Test_get_public_ecdsa_from_base58(t *testing.T) {
const expectedBitSize = 256
publicKey, err := crypto.GetPublicKeyFromBase58(test.ValidPublicBase58)
assert.NilError(t, err)
assert.Assert(t, publicKey != nil)

curve := secp256k1.SECP256K1()
curve := publicKey.Curve.(*secp256k1.BitCurve)
assert.Assert(t, curve != nil)
assert.Assert(t, curve.BitSize == expectedBitSize)
assert.Assert(t, curve.IsOnCurve(publicKey.X, publicKey.Y))
}

Expand Down
13 changes: 3 additions & 10 deletions pkg/validation/identity.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,12 @@
package validation

import (
"crypto/elliptic"
"encoding/hex"
"fmt"
"regexp"
"strings"

"github.com/fomichev/secp256k1"
ethcrypto "github.com/ethereum/go-ethereum/crypto"
"github.com/jbenet/go-base58"

"golang.org/x/crypto/blake2b"
Expand Down Expand Up @@ -60,14 +59,8 @@ func ValidatePublicKey(publicKeyBytes []byte) error {
if publicKeyBytes[0] != 4 {
return fmt.Errorf("public key bytes not in uncompressed format")
}

curve := secp256k1.SECP256K1()
x, _ := elliptic.Unmarshal(curve, publicKeyBytes)
if x == nil {
return fmt.Errorf("invalid secp256k1 public key")
}

return nil
_, err := ethcrypto.UnmarshalPubkey(publicKeyBytes)
return err
}

// ValidateKeyName validates key name.
Expand Down

0 comments on commit 088a185

Please sign in to comment.