Skip to content

Commit

Permalink
Cosign refactor. Use shadow embedding
Browse files Browse the repository at this point in the history
  • Loading branch information
nitronit committed Sep 3, 2023
1 parent 78ac0ec commit b19001f
Show file tree
Hide file tree
Showing 16 changed files with 171 additions and 137 deletions.
7 changes: 4 additions & 3 deletions cmd/horcrux/cmd/threshold.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ func NewThresholdValidator(
remoteIcosigners := make([]pcosigner.ICosigner, 0, len(thresholdCfg.Cosigners)-1)

var p2pListen string

var cosign pcosigner.Cosigner
var security pcosigner.ICosignerSecurity
var eciesErr error
security, eciesErr = config.CosignerSecurityECIES()
Expand All @@ -52,7 +52,8 @@ func NewThresholdValidator(
remoteIcosigners,
temp)
} else {
p2pListen = c.P2PAddr
cosign = pcosigner.NewCosign(c.ShardID, c.P2PAddr)

}
}

Expand All @@ -64,7 +65,7 @@ func NewThresholdValidator(
logger,
&config,
security,
p2pListen,
cosign,
)

// Validated prior in ValidateThresholdModeConfig
Expand Down
25 changes: 17 additions & 8 deletions pkg/multiresolver/multi_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,32 +28,41 @@ func createListener(nodeID string, homedir string) (string, func(), error) {
}

port := strconv.Itoa(sock.Addr().(*net.TCPAddr).Port)
localcosign := pcosigner.NewLocalCosigner(
log.NewNopLogger(), nil, nil, "")

// Initiliaze the localcosign as an ILocalCosigner.
cosign := pcosigner.Cosigner{}
vlocalcosign := pcosigner.NewLocalCosigner(
log.NewNopLogger(), nil, nil, cosign)

var localcosign pcosigner.ILocalCosigner
localcosign = vlocalcosign
var remoteCosigners []pcosigner.IRemoteCosigner
var timeDuration time.Duration
remoteCosigners = append(remoteCosigners, vlocalcosign)

var peers []pcosigner.ICosigner
peers = append(peers, vlocalcosign)

timeDuration := 500 * time.Millisecond

shadowRemoteCosign := pcosigner.ToIcosigner(remoteCosigners)
s := node.NewRaftStore(
nodeID,
homedir,
"127.0.0.1:"+port,
500*time.Millisecond,
nil, localcosign, shadowRemoteCosign)
log.NewNopLogger(), localcosign, peers)

// Need to set pointers to avoid nil pointers.

thresholdvalidator := node.NewThresholdValidator(log.NewNopLogger(), nil, 0, timeDuration, 0, localcosign, remoteCosigners, s)
s.SetThresholdValidator(thresholdvalidator)

transportManager, err := s.Open(shadowRemoteCosign)
transportManager, err := s.Open(peers)
if err != nil {
fmt.Printf("Error opening transport manager: %v\n", err)
return "", nil, err
}

grpcServer := grpc.NewServer()
proto.RegisterICosignerGRPCServer(grpcServer, node.NewGRPCServer(nil, s))
proto.RegisterICosignerGRPCServer(grpcServer, node.NewGRPCServer(localcosign, s))
transportManager.Register(grpcServer)

go func() {
Expand Down
11 changes: 5 additions & 6 deletions pkg/node/raft_store.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@ import (
"sync"
"time"

"github.com/davecgh/go-spew/spew"
"github.com/strangelove-ventures/horcrux/pkg/pcosigner"
"github.com/strangelove-ventures/horcrux/pkg/types"

Expand Down Expand Up @@ -69,7 +68,7 @@ type RaftStore struct {
// NewRaftStore returns a new RaftStore.
func NewRaftStore(
nodeID string, directory string, bindAddress string, timeout time.Duration,
logger log.Logger, localCosigner *pcosigner.LocalCosigner, peers []pcosigner.ICosigner) *RaftStore {
logger log.Logger, localCosigner pcosigner.ILocalCosigner, peers []pcosigner.ICosigner) *RaftStore {
cosignerRaftStore := &RaftStore{
NodeID: nodeID,
RaftDir: directory,
Expand All @@ -78,11 +77,10 @@ func NewRaftStore(
m: make(map[string]string),
logger: logger,
}
spew.Dump(peers)
spew.Dump(localCosigner)

err := cosignerRaftStore.onStart(localCosigner, peers)
if err != nil {
fmt.Printf("cosignerRaftStore.onStart: %v", err)
panic(err)
}
cosignerRaftStore.BaseService = *service.NewBaseService(logger, "CosignerRaftStore", cosignerRaftStore)
Expand All @@ -93,7 +91,7 @@ func (s *RaftStore) SetThresholdValidator(thresholdValidator *ThresholdValidator
s.thresholdValidator = thresholdValidator
}

func (s *RaftStore) init(localCosigner *pcosigner.LocalCosigner, peers []pcosigner.ICosigner) error {
func (s *RaftStore) init(localCosigner pcosigner.ILocalCosigner, peers []pcosigner.ICosigner) error {
host := p2pURLToRaftAddress(s.RaftBind)
_, port, err := net.SplitHostPort(host)
if err != nil {
Expand All @@ -106,6 +104,7 @@ func (s *RaftStore) init(localCosigner *pcosigner.LocalCosigner, peers []pcosign
}
transportManager, err := s.Open(peers)
if err != nil {
fmt.Printf("s.Open: %v", err)
return err
}
// Create a new gRPC server which is used by both the Raft, the threshold validator and the cosigner
Expand All @@ -127,7 +126,7 @@ func (s *RaftStore) OnStart() error {
s.logger.Info("Starting RaftStore")
return nil
}
func (s *RaftStore) onStart(localCosign *pcosigner.LocalCosigner, peers []pcosigner.ICosigner) error {
func (s *RaftStore) onStart(localCosign pcosigner.ILocalCosigner, peers []pcosigner.ICosigner) error {
go func() {
err := s.init(localCosign, peers)
if err != nil {
Expand Down
4 changes: 2 additions & 2 deletions pkg/node/raft_store_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -42,12 +42,12 @@ func Test_StoreInMemOpenSingleNode(t *testing.T) {
ECIESKey: eciesKey,
ECIESPubs: []*ecies.PublicKey{&eciesKey.PublicKey},
}),
"",
pcosigner.NewCosign(key.ID, ""),
)

remoteCosigns := make([]pcosigner.IRemoteCosigner, 0)
remoteCosigns = append(remoteCosigns, pcosigner.NewRemoteCosigner(1, "temp"))
shadowRemoteCosign := pcosigner.ToIcosigner(remoteCosigns)
shadowRemoteCosign := pcosigner.FromIRemoteToICosigner(remoteCosigns)
//spew.Dump(&remoteCosigns)
//spew.Dump(&shadowRemoteCosign)

Expand Down
2 changes: 1 addition & 1 deletion pkg/node/threshold_validator_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -323,7 +323,7 @@ func getTestLocalCosigners(t *testing.T, threshold, total uint8) ([]*pcosigner.L
ECIESPubs: pubKeys,
},
),
"",
pcosigner.NewCosign(i+1, ""),
)
require.NoError(t, err)

Expand Down
41 changes: 31 additions & 10 deletions pkg/pcosigner/cosigner.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,27 @@ import (
"github.com/strangelove-ventures/horcrux/pkg/proto"
)

type Cosigner struct {
id int
address string
}

func NewCosign(id int, address string) Cosigner {
return Cosigner{
id: id,
address: address,
}
}
func (cosign *Cosigner) GetAddress() string {
return cosign.address
}

// GetID returns the ID of the remote cosigner
// Implements the cosigner interface
func (cosign *RemoteCosigner) GetID() int {
return cosign.id
}

type CosignerSignBlockResponse struct {
Signature []byte
}
Expand All @@ -25,15 +46,15 @@ type CosignerSignResponse struct {
Signature []byte
}

type CosignerNonce struct {
type CosignNonce struct {
SourceID int
DestinationID int
PubKey []byte
Share []byte
Signature []byte
}

func (secretPart *CosignerNonce) toProto() *proto.Nonce {
func (secretPart *CosignNonce) toProto() *proto.Nonce {
return &proto.Nonce{
SourceID: int32(secretPart.SourceID),
DestinationID: int32(secretPart.DestinationID),
Expand All @@ -44,7 +65,7 @@ func (secretPart *CosignerNonce) toProto() *proto.Nonce {
}

// CosignerNonces is a list of CosignerNonce
type CosignerNonces []CosignerNonce
type CosignerNonces []CosignNonce

func (secretParts CosignerNonces) ToProto() (out []*proto.Nonce) {
for _, secretPart := range secretParts {
Expand All @@ -53,8 +74,8 @@ func (secretParts CosignerNonces) ToProto() (out []*proto.Nonce) {
return
}

func CosignerNonceFromProto(secretPart *proto.Nonce) CosignerNonce {
return CosignerNonce{
func CosignerNonceFromProto(secretPart *proto.Nonce) CosignNonce {
return CosignNonce{
SourceID: int(secretPart.SourceID),
DestinationID: int(secretPart.DestinationID),
PubKey: secretPart.PubKey,
Expand All @@ -63,8 +84,8 @@ func CosignerNonceFromProto(secretPart *proto.Nonce) CosignerNonce {
}
}

func CosignerNoncesFromProto(secretParts []*proto.Nonce) []CosignerNonce {
out := make([]CosignerNonce, len(secretParts))
func CosignerNoncesFromProto(secretParts []*proto.Nonce) []CosignNonce {
out := make([]CosignNonce, len(secretParts))
for i, secretPart := range secretParts {
out[i] = CosignerNonceFromProto(secretPart)
}
Expand All @@ -83,13 +104,13 @@ type CosignerSetNonceRequest struct {
Timestamp time.Time
}

type CosignerNoncesResponse struct {
Nonces []CosignerNonce
type CosignNoncesResponse struct {
Nonces []CosignNonce
}

type CosignerSetNoncesAndSignRequest struct {
ChainID string
Nonces []CosignerNonce
Nonces []CosignNonce
HRST types.HRSTKey
SignBytes []byte
}
67 changes: 0 additions & 67 deletions pkg/pcosigner/cosigner_key_shares.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,78 +6,11 @@ import (
"encoding/json"
"os"

cometjson "github.com/cometbft/cometbft/libs/json"
"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
// by splitting the secret using Shamir secret sharing.
func CreateCosignerEd25519Shards(pv privval.FilePVKey, threshold, shards uint8) []CosignerEd25519Key {
// tsed25519.DealShares splits the secret using Shamir Secret Sharing (Note its: no verifiable secret sharing)
// privshards is shamir shares
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)
if err != nil {
return nil, err
}
out := make([]CosignerRSAKey, shards)
for i, key := range rsaKeys {
out[i] = CosignerRSAKey{
ID: i + 1,
RSAKey: *key,
RSAPubs: pubKeys,
}
}
return out, nil
}

// ReadPrivValidatorFile reads in a privval.FilePVKey from a given file.
func ReadPrivValidatorFile(priv string) (out privval.FilePVKey, err error) {
var bz []byte
if bz, err = os.ReadFile(priv); err != nil {
return
}
if err = cometjson.Unmarshal(bz, &out); err != nil {
return
}
return
}

// WriteCosignerEd25519ShardFile writes a cosigner Ed25519 key to a given file name.
func WriteCosignerEd25519ShardFile(cosigner CosignerEd25519Key, file string) error {
jsonBytes, err := json.Marshal(&cosigner)
if err != nil {
return err
}
return os.WriteFile(file, jsonBytes, 0600)
}

// WriteCosignerRSAShardFile writes a cosigner RSA key to a given file name.
func WriteCosignerRSAShardFile(cosigner CosignerRSAKey, file string) error {
jsonBytes, err := json.Marshal(&cosigner)
Expand Down
2 changes: 1 addition & 1 deletion pkg/pcosigner/cosigner_security.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ type ICosignerSecurity interface {
id int,
noncePub []byte,
nonceShare []byte,
) (CosignerNonce, error)
) (CosignNonce, error)

// DecryptAndVerify decrypts the nonce and verifies the signature to authenticate the source cosigner.
DecryptAndVerify(
Expand Down
6 changes: 3 additions & 3 deletions pkg/pcosigner/cosigner_security_ecies.go
Original file line number Diff line number Diff line change
Expand Up @@ -136,8 +136,8 @@ func (c *CosignerSecurityECIES) GetID() int {
}

// EncryptAndSign encrypts the nonce and signs it for authentication.
func (c *CosignerSecurityECIES) EncryptAndSign(id int, noncePub []byte, nonceShare []byte) (CosignerNonce, error) {
nonce := CosignerNonce{
func (c *CosignerSecurityECIES) EncryptAndSign(id int, noncePub []byte, nonceShare []byte) (CosignNonce, error) {
nonce := CosignNonce{
SourceID: c.key.ID,
}

Expand Down Expand Up @@ -206,7 +206,7 @@ func (c *CosignerSecurityECIES) DecryptAndVerify(
return nil, nil, fmt.Errorf("unknown cosigner: %d", id)
}

digestMsg := CosignerNonce{
digestMsg := CosignNonce{
SourceID: id,
PubKey: encryptedNoncePub,
Share: encryptedNonceShare,
Expand Down
6 changes: 3 additions & 3 deletions pkg/pcosigner/cosigner_security_rsa.go
Original file line number Diff line number Diff line change
Expand Up @@ -128,8 +128,8 @@ func (c *CosignerSecurityRSA) GetID() int {
}

// EncryptAndSign encrypts the nonce and signs it for authentication.
func (c *CosignerSecurityRSA) EncryptAndSign(id int, noncePub []byte, nonceShare []byte) (CosignerNonce, error) {
nonce := CosignerNonce{
func (c *CosignerSecurityRSA) EncryptAndSign(id int, noncePub []byte, nonceShare []byte) (CosignNonce, error) {
nonce := CosignNonce{
SourceID: c.key.ID,
}

Expand Down Expand Up @@ -194,7 +194,7 @@ func (c *CosignerSecurityRSA) DecryptAndVerify(
return nil, nil, fmt.Errorf("unknown cosigner: %d", id)
}

digestMsg := CosignerNonce{
digestMsg := CosignNonce{
SourceID: id,
PubKey: encryptedNoncePub,
Share: encryptedNonceShare,
Expand Down
Loading

0 comments on commit b19001f

Please sign in to comment.