Skip to content

Commit

Permalink
Refactor threshold signer key loading and creation
Browse files Browse the repository at this point in the history
  • Loading branch information
nitronit committed Dec 9, 2023
1 parent 9a73088 commit d297fa4
Show file tree
Hide file tree
Showing 8 changed files with 51 additions and 48 deletions.
4 changes: 2 additions & 2 deletions cmd/horcrux/cmd/address.go
Original file line number Diff line number Diff line change
Expand Up @@ -45,9 +45,9 @@ func addressCmd() *cobra.Command {
return err
}

key, err := signer.LoadCosignerEd25519Key(keyFile)
key, err := signer.LoadThresholdSignerEd25519Key(keyFile)
if err != nil {
return fmt.Errorf("error reading cosigner key: %w, check that key is present for chain Index: %s", err, chainID)
return fmt.Errorf("error reading threshold key: %w, check that key is present for chain id: %s", err, chainID)
}

pubKey = key.PubKey
Expand Down
2 changes: 1 addition & 1 deletion cmd/horcrux/cmd/shards.go
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,7 @@ func createCosignerEd25519ShardsCmd() *cobra.Command {
return nil
}

csKeys, err := signer.CreateCosignerEd25519ShardsFromFile(keyFile, threshold, shards)
csKeys, err := signer.CreateEd25519ThresholdSignShardsFromFile(keyFile, threshold, shards)
if err != nil {
return err
}
Expand Down
19 changes: 1 addition & 18 deletions signer/cosigner_key.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,6 @@ package signer

import (
"encoding/json"
"os"

cometcrypto "github.com/cometbft/cometbft/crypto"
cometcryptoed25519 "github.com/cometbft/cometbft/crypto/ed25519"
cometcryptoencoding "github.com/cometbft/cometbft/crypto/encoding"
Expand All @@ -12,6 +10,7 @@ import (
)

// CosignerEd25519Key is a single Ed255219 key shard for an m-of-n threshold signer.
// TODO: CosignerEd25519Key is almost a duplicate of ThresholdSignerEd25519Key
type CosignerEd25519Key struct {
PubKey cometcrypto.PubKey `json:"pubKey"`
PrivateShard []byte `json:"privateShard"`
Expand Down Expand Up @@ -83,19 +82,3 @@ func (key *CosignerEd25519Key) UnmarshalJSON(data []byte) error {
key.PubKey = pubkey
return nil
}

// LoadCosignerEd25519Key loads a CosignerEd25519Key from file.
func LoadCosignerEd25519Key(file string) (CosignerEd25519Key, error) {
pvKey := CosignerEd25519Key{}
keyJSONBytes, err := os.ReadFile(file)
if err != nil {
return pvKey, err
}

err = json.Unmarshal(keyJSONBytes, &pvKey)
if err != nil {
return pvKey, err
}

return pvKey, nil
}
24 changes: 0 additions & 24 deletions signer/cosigner_key_shares.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,33 +10,9 @@ import (
"github.com/cometbft/cometbft/privval"
"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"
)

// CreateCosignerEd25519ShardsFromFile creates CosignerEd25519Key objects from a priv_validator_key.json file
func CreateCosignerEd25519ShardsFromFile(priv string, threshold, shards uint8) ([]CosignerEd25519Key, error) {
pv, err := ReadPrivValidatorFile(priv)
if err != nil {
return nil, err
}
return CreateCosignerEd25519Shards(pv, threshold, shards), nil
}

// CreateCosignerEd25519Shards creates CosignerEd25519Key objects from a privval.FilePVKey
func CreateCosignerEd25519Shards(pv privval.FilePVKey, threshold, shards uint8) []CosignerEd25519Key {
privShards := tsed25519.DealShares(tsed25519.ExpandSecret(pv.PrivKey.Bytes()[:32]), threshold, shards)
out := make([]CosignerEd25519Key, shards)
for i, shard := range privShards {
out[i] = CosignerEd25519Key{
PubKey: pv.PubKey,
PrivateShard: shard,
ID: i + 1,
}
}
return out
}

// CreateCosignerRSAShards generate CosignerRSAKey objects.
func CreateCosignerRSAShards(shards int) ([]CosignerRSAKey, error) {
rsaKeys, pubKeys, err := makeRSAKeys(shards)
Expand Down
43 changes: 43 additions & 0 deletions signer/threshold_signer.go
Original file line number Diff line number Diff line change
@@ -1,7 +1,11 @@
package signer

import (
"encoding/json"
"github.com/cometbft/cometbft/privval"
"github.com/strangelove-ventures/horcrux/pkg/types"
tsed25519 "gitlab.com/unit410/threshold-ed25519/pkg"
"os"
)

// Interface for the local signer whether it's a soft sign or HSM
Expand All @@ -15,3 +19,42 @@ type ThresholdSigner interface {
// CombineSignatures combines multiple partial signatures to a full signature.
CombineSignatures([]types.PartialSignature) ([]byte, error)
}

// LoadThresholdSignerEd25519Key loads the persistent ThresholdSignerEd25519Key from file.
func LoadThresholdSignerEd25519Key(file string) (CosignerEd25519Key, error) {
pvKey := CosignerEd25519Key{}
keyJSONBytes, err := os.ReadFile(file)
if err != nil {
return pvKey, err
}

err = json.Unmarshal(keyJSONBytes, &pvKey)
if err != nil {
return pvKey, err
}

return pvKey, nil
}

// CreateEd25519ThresholdSignShardsFromFile creates CosignerEd25519Key objects from a priv_validator_key.json file
func CreateEd25519ThresholdSignShardsFromFile(priv string, threshold, shards uint8) ([]CosignerEd25519Key, error) {
pv, err := ReadPrivValidatorFile(priv)
if err != nil {
return nil, err
}
return CreateEd25519ThresholdSignShards(pv, threshold, shards), nil
}

// CreateEd25519ThresholdSignShards creates CosignerEd25519Key objects from a privval.FilePVKey
func CreateEd25519ThresholdSignShards(pv privval.FilePVKey, threshold, shards uint8) []CosignerEd25519Key {
privShards := tsed25519.DealShares(tsed25519.ExpandSecret(pv.PrivKey.Bytes()[:32]), threshold, shards)
out := make([]CosignerEd25519Key, shards)
for i, shard := range privShards {
out[i] = CosignerEd25519Key{
PubKey: pv.PubKey,
PrivateShard: shard,
ID: i + 1,
}
}
return out
}
2 changes: 1 addition & 1 deletion signer/threshold_signer_bls.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ func NewThresholdSignerSoftBLS(config *RuntimeConfig, id int, chainID string) (*
return nil, err
}

key, err := LoadCosignerEd25519Key(keyFile)
key, err := LoadThresholdSignerEd25519Key(keyFile)
if err != nil {
return nil, fmt.Errorf("error reading cosigner key: %s", err)
}
Expand Down
3 changes: 2 additions & 1 deletion signer/threshold_signer_soft.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ func NewThresholdSignerSoft(config *RuntimeConfig, id int, chainID string) (*Thr
return nil, err
}

key, err := LoadCosignerEd25519Key(keyFile)
key, err := LoadThresholdSignerEd25519Key(keyFile)
if err != nil {
return nil, fmt.Errorf("error reading cosigner key: %s", err)
}
Expand Down Expand Up @@ -87,6 +87,7 @@ func (s *ThresholdSignerSoft) sumNonces(nonces []types.Nonce) (tsed25519.Scalar,
return nonceShare, noncePub, nil
}

// GenerateNonces is a function that generates Nonces to be used in the MPC
func GenerateNonces(threshold, total uint8) (types.Nonces, error) {
secret := make([]byte, 32)
if _, err := rand.Read(secret); err != nil {
Expand Down
2 changes: 1 addition & 1 deletion test/validator_threshold.go
Original file line number Diff line number Diff line change
Expand Up @@ -257,7 +257,7 @@ func getShardedPrivvalKey(ctx context.Context, node *cosmos.ChainNode, threshold
return nil, nil, err
}

ed25519Shards := signer.CreateCosignerEd25519Shards(pvKey, threshold, shards)
ed25519Shards := signer.CreateEd25519ThresholdSignShards(pvKey, threshold, shards)

return ed25519Shards, pvKey.PubKey, nil
}
Expand Down

0 comments on commit d297fa4

Please sign in to comment.