Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

use go-ethereum ecies due to instability with ecies/go/v2 #178

Merged
merged 6 commits into from
Jul 19, 2023
Merged
Show file tree
Hide file tree
Changes from 5 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 22 additions & 8 deletions cmd/horcrux/cmd/leader_election.go
Original file line number Diff line number Diff line change
Expand Up @@ -107,26 +107,40 @@ func getLeaderCmd() *cobra.Command {
return fmt.Errorf("threshold mode configuration has no cosigners")
}

keyFile, err := config.KeyFileExistsCosignerRSA()
if err != nil {
return err
}
var id int

key, err := signer.LoadCosignerRSAKey(keyFile)
keyFileECIES, err := config.KeyFileExistsCosignerECIES()
if err != nil {
return fmt.Errorf("error reading cosigner key (%s): %w", keyFile, err)
keyFileRSA, err := config.KeyFileExistsCosignerRSA()
if err != nil {
return fmt.Errorf("cosigner encryption keys not found (%s) - (%s): %w", keyFileECIES, keyFileRSA, err)
}

key, err := signer.LoadCosignerRSAKey(keyFileRSA)
if err != nil {
return fmt.Errorf("error reading cosigner key (%s): %w", keyFileRSA, err)
}

id = key.ID
} else {
key, err := signer.LoadCosignerECIESKey(keyFileECIES)
if err != nil {
return fmt.Errorf("error reading cosigner key (%s): %w", keyFileECIES, err)
}

id = key.ID
}

var p2pListen string

for _, c := range thresholdCfg.Cosigners {
if c.ShardID == key.ID {
if c.ShardID == id {
p2pListen = c.P2PAddr
}
}

if p2pListen == "" {
return fmt.Errorf("cosigner config does not exist for our shard ID %d", key.ID)
return fmt.Errorf("cosigner config does not exist for our shard ID %d", id)
}

retryOpts := []grpcretry.CallOption{
Expand Down
7 changes: 4 additions & 3 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ require (
github.com/armon/go-metrics v0.4.1
github.com/cometbft/cometbft v0.37.2
github.com/cosmos/cosmos-sdk v0.47.3
github.com/ecies/go/v2 v2.0.6
github.com/ethereum/go-ethereum v1.12.0
github.com/gogo/protobuf v1.3.2
github.com/grpc-ecosystem/go-grpc-middleware v1.3.0
github.com/hashicorp/raft v1.5.0
Expand Down Expand Up @@ -52,15 +52,14 @@ require (
github.com/dgraph-io/ristretto v0.1.1 // indirect
github.com/dgryski/go-farm v0.0.0-20200201041132-a6ae2369ad13 // indirect
github.com/dustin/go-humanize v1.0.1 // indirect
github.com/ethereum/go-ethereum v1.11.5 // indirect
github.com/fatih/color v1.13.0 // indirect
github.com/fsnotify/fsnotify v1.6.0 // indirect
github.com/go-kit/kit v0.12.0 // indirect
github.com/go-kit/log v0.2.1 // indirect
github.com/go-logfmt/logfmt v0.5.1 // indirect
github.com/golang/glog v1.1.0 // indirect
github.com/golang/protobuf v1.5.3 // indirect
github.com/golang/snappy v0.0.4 // indirect
github.com/golang/snappy v0.0.5-0.20220116011046-fa5810519dcb // indirect
github.com/google/btree v1.1.2 // indirect
github.com/google/go-cmp v0.5.9 // indirect
github.com/gtank/merlin v0.1.1 // indirect
Expand All @@ -70,9 +69,11 @@ require (
github.com/hashicorp/go-immutable-radix v1.3.1 // indirect
github.com/hashicorp/go-msgpack v1.1.5 // indirect
github.com/hashicorp/go-multierror v1.1.1 // indirect
github.com/hashicorp/go-uuid v1.0.1 // indirect
github.com/hashicorp/golang-lru v0.5.5-0.20210104140557-80c98217689d // indirect
github.com/hashicorp/hcl v1.0.0 // indirect
github.com/hdevalence/ed25519consensus v0.1.0 // indirect
github.com/holiman/uint256 v1.2.2-0.20230321075855-87b91420868c // indirect
github.com/inconshreveable/mousetrap v1.0.1 // indirect
github.com/jmhodges/levigo v1.0.0 // indirect
github.com/klauspost/compress v1.16.3 // indirect
Expand Down
736 changes: 6 additions & 730 deletions go.sum

Large diffs are not rendered by default.

111 changes: 111 additions & 0 deletions go.work.sum

Large diffs are not rendered by default.

26 changes: 2 additions & 24 deletions signer/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -122,18 +122,7 @@ func (c RuntimeConfig) CosignerSecurityECIES() (*CosignerSecurityECIES, error) {
return nil, fmt.Errorf("error reading cosigner key (%s): %w", keyFile, err)
}

pubKeys := make([]CosignerECIESPubKey, len(key.ECIESPubs))
for i, pk := range key.ECIESPubs {
pubKeys[i] = CosignerECIESPubKey{
ID: i + 1,
PublicKey: pk,
}
}

return NewCosignerSecurityECIES(
key,
pubKeys,
), nil
return NewCosignerSecurityECIES(key), nil
}

func (c RuntimeConfig) CosignerSecurityRSA() (*CosignerSecurityRSA, error) {
Expand All @@ -147,18 +136,7 @@ func (c RuntimeConfig) CosignerSecurityRSA() (*CosignerSecurityRSA, error) {
return nil, fmt.Errorf("error reading cosigner key (%s): %w", keyFile, err)
}

pubKeys := make([]CosignerRSAPubKey, len(key.RSAPubs))
for i, pk := range key.RSAPubs {
pubKeys[i] = CosignerRSAPubKey{
ID: i + 1,
PublicKey: *pk,
}
}

return NewCosignerSecurityRSA(
key,
pubKeys,
), nil
return NewCosignerSecurityRSA(key), nil
}

func (c RuntimeConfig) cachedKeyDirectory() string {
Expand Down
7 changes: 4 additions & 3 deletions signer/cosigner_key_shares.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,8 @@ import (

cometjson "github.com/cometbft/cometbft/libs/json"
"github.com/cometbft/cometbft/privval"
ecies "github.com/ecies/go/v2"
"github.com/ethereum/go-ethereum/crypto/ecies"
"github.com/ethereum/go-ethereum/crypto/secp256k1"
tsed25519 "gitlab.com/unit410/threshold-ed25519/pkg"
"golang.org/x/sync/errgroup"
)
Expand Down Expand Up @@ -137,12 +138,12 @@ func makeECIESKeys(num int) ([]*ecies.PrivateKey, []*ecies.PublicKey, error) {
for i := 0; i < num; i++ {
i := i
eg.Go(func() error {
eciesKey, err := ecies.GenerateKey()
eciesKey, err := ecies.GenerateKey(rand.Reader, secp256k1.S256(), nil)
if err != nil {
return err
}
eciesKeys[i] = eciesKey
pubKeys[i] = eciesKey.PublicKey
pubKeys[i] = &eciesKey.PublicKey
return nil
})
}
Expand Down
63 changes: 40 additions & 23 deletions signer/cosigner_security_ecies.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,12 @@ import (
"crypto/sha256"
"encoding/json"
"fmt"
"math/big"
"os"

cometjson "github.com/cometbft/cometbft/libs/json"
ecies "github.com/ecies/go/v2"
"github.com/ethereum/go-ethereum/crypto/ecies"
"github.com/ethereum/go-ethereum/crypto/secp256k1"
"golang.org/x/sync/errgroup"
)

Expand Down Expand Up @@ -39,18 +41,20 @@ func (key *CosignerECIESKey) MarshalJSON() ([]byte, error) {
type Alias CosignerECIESKey

// marshal our private key and all public keys
privateBytes := key.ECIESKey
privateBytes := key.ECIESKey.D.Bytes()
pubKeysBytes := make([][]byte, len(key.ECIESPubs))
for i, pubKey := range key.ECIESPubs {
pubKeysBytes[i] = pubKey.Bytes(true)
pubKeysBytes[i] = []byte{0x04}
pubKeysBytes[i] = append(pubKeysBytes[i], pubKey.X.Bytes()...)
pubKeysBytes[i] = append(pubKeysBytes[i], pubKey.Y.Bytes()...)
agouin marked this conversation as resolved.
Show resolved Hide resolved
}

return json.Marshal(&struct {
ECIESKey []byte `json:"eciesKey"`
ECIESPubs [][]byte `json:"eciesPubs"`
*Alias
}{
ECIESKey: privateBytes.Bytes(),
ECIESKey: privateBytes,
ECIESPubs: pubKeysBytes,
Alias: (*Alias)(key),
})
Expand All @@ -73,14 +77,21 @@ func (key *CosignerECIESKey) UnmarshalJSON(data []byte) error {
// unmarshal the public key bytes for each cosigner
key.ECIESPubs = make([]*ecies.PublicKey, len(aux.ECIESPubs))
for i, bytes := range aux.ECIESPubs {
pub, err := ecies.NewPublicKeyFromBytes(bytes)
if err != nil {
return err
pub := &ecies.PublicKey{
X: new(big.Int).SetBytes(bytes[1:33]),
Y: new(big.Int).SetBytes(bytes[33:]),
Curve: secp256k1.S256(),
Params: ecies.ECIES_AES128_SHA256,
}

key.ECIESPubs[i] = pub
}

key.ECIESKey = ecies.NewPrivateKeyFromBytes(aux.ECIESKey)
key.ECIESKey = &ecies.PrivateKey{
PublicKey: *key.ECIESPubs[aux.ID-1],
D: new(big.Int).SetBytes(aux.ECIESKey),
}

return nil
}

Expand All @@ -101,14 +112,17 @@ func LoadCosignerECIESKey(file string) (CosignerECIESKey, error) {
}

// NewCosignerSecurityECIES creates a new CosignerSecurityECIES.
func NewCosignerSecurityECIES(key CosignerECIESKey, eciesPubKeys []CosignerECIESPubKey) *CosignerSecurityECIES {
func NewCosignerSecurityECIES(key CosignerECIESKey) *CosignerSecurityECIES {
c := &CosignerSecurityECIES{
key: key,
eciesPubKeys: make(map[int]CosignerECIESPubKey, len(eciesPubKeys)),
eciesPubKeys: make(map[int]CosignerECIESPubKey, len(key.ECIESPubs)),
}

for _, pubKey := range eciesPubKeys {
c.eciesPubKeys[pubKey.ID] = pubKey
for i, pubKey := range key.ECIESPubs {
c.eciesPubKeys[i+1] = CosignerECIESPubKey{
ID: i + 1,
PublicKey: pubKey,
}
}

return c
Expand Down Expand Up @@ -136,12 +150,12 @@ func (c *CosignerSecurityECIES) EncryptAndSign(id int, noncePub []byte, nonceSha
var eg errgroup.Group

eg.Go(func() (err error) {
encryptedShare, err = ecies.Encrypt(pubKey.PublicKey, nonceShare)
encryptedShare, err = ecies.Encrypt(rand.Reader, pubKey.PublicKey, nonceShare, nil, nil)
return err
})

eg.Go(func() (err error) {
encryptedPub, err = ecies.Encrypt(pubKey.PublicKey, noncePub)
encryptedPub, err = ecies.Encrypt(rand.Reader, pubKey.PublicKey, noncePub, nil, nil)
return err
})

Expand All @@ -164,10 +178,7 @@ func (c *CosignerSecurityECIES) EncryptAndSign(id int, noncePub []byte, nonceSha
hash := sha256.Sum256(jsonBytes)
signature, err := ecdsa.SignASN1(
rand.Reader,
&ecdsa.PrivateKey{
PublicKey: ecdsa.PublicKey(*c.key.ECIESKey.PublicKey),
D: c.key.ECIESKey.D,
},
c.key.ECIESKey.ExportECDSA(),
hash[:],
)
if err != nil {
Expand Down Expand Up @@ -206,7 +217,7 @@ func (c *CosignerSecurityECIES) DecryptAndVerify(

digest := sha256.Sum256(digestBytes)

validSignature := ecdsa.VerifyASN1((*ecdsa.PublicKey)(pubKey.PublicKey), digest[:], signature)
validSignature := ecdsa.VerifyASN1(pubKey.PublicKey.ExportECDSA(), digest[:], signature)
if !validSignature {
return nil, nil, fmt.Errorf("signature is invalid")
}
Expand All @@ -217,13 +228,19 @@ func (c *CosignerSecurityECIES) DecryptAndVerify(
var nonceShare []byte

eg.Go(func() (err error) {
noncePub, err = ecies.Decrypt(c.key.ECIESKey, encryptedNoncePub)
return err
noncePub, err = c.key.ECIESKey.Decrypt(encryptedNoncePub, nil, nil)
if err != nil {
return fmt.Errorf("failed to decrypt nonce pub: %w", err)
}
return nil
})

eg.Go(func() (err error) {
nonceShare, err = ecies.Decrypt(c.key.ECIESKey, encryptedNonceShare)
return err
nonceShare, err = c.key.ECIESKey.Decrypt(encryptedNonceShare, nil, nil)
if err != nil {
return fmt.Errorf("failed to decrypt nonce share: %w", err)
}
return nil
})

if err := eg.Wait(); err != nil {
Expand Down
Loading
Loading