diff --git a/zetaclient/tss/keysign.go b/zetaclient/tss/crypto.go similarity index 59% rename from zetaclient/tss/keysign.go rename to zetaclient/tss/crypto.go index 6164241979..1198e9dd4b 100644 --- a/zetaclient/tss/keysign.go +++ b/zetaclient/tss/crypto.go @@ -3,67 +3,22 @@ package tss import ( "bytes" "encoding/base64" + "strings" + "github.com/btcsuite/btcd/chaincfg/chainhash" "github.com/ethereum/go-ethereum/crypto" "github.com/pkg/errors" - "github.com/rs/zerolog" - tsscommon "gitlab.com/thorchain/tss/go-tss/common" "gitlab.com/thorchain/tss/go-tss/keysign" "github.com/zeta-chain/node/pkg/cosmos" - "github.com/zeta-chain/node/zetaclient/logs" ) var ( - testKeySignData = []byte("hello meta") base64Decode = base64.StdEncoding.Decode base64DecodeString = base64.StdEncoding.DecodeString + base64EncodeString = base64.StdEncoding.EncodeToString ) -// TestKeySign performs a TSS key-sign test of sample data. -func TestKeySign(keySigner KeySigner, tssPubKey string, logger zerolog.Logger) error { - logger = logger.With().Str(logs.FieldModule, "tss_keysign").Logger() - - hashedData := crypto.Keccak256Hash(testKeySignData) - - logger.Info(). - Str("keysign.test_data", string(testKeySignData)). - Str("keysign.test_data_hash", hashedData.String()). - Msg("Performing TSS key-sign test") - - req := keysign.NewRequest( - tssPubKey, - []string{base64.StdEncoding.EncodeToString(hashedData.Bytes())}, - 10, - nil, - Version, - ) - - res, err := keySigner.KeySign(req) - switch { - case err != nil: - return errors.Wrap(err, "key signing request error") - case res.Status != tsscommon.Success: - logger.Error().Interface("keysign.fail_blame", res.Blame).Msg("Keysign failed") - return errors.Wrapf(err, "key signing is not successful (status %d)", res.Status) - case len(res.Signatures) == 0: - return errors.New("signatures list is empty") - } - - // 32B msg hash, 32B R, 32B S, 1B RC - signature := res.Signatures[0] - - logger.Info().Interface("keysign.signature", signature).Msg("Received signature from TSS") - - if _, err = VerifySignature(signature, tssPubKey, hashedData.Bytes()); err != nil { - return errors.Wrap(err, "signature verification failed") - } - - logger.Info().Msg("TSS key-sign test passed") - - return nil -} - // VerifySignature checks that keysign.Signature is valid and origins from expected TSS public key. // Also returns signature as [65]byte (R, S, V) func VerifySignature(sig keysign.Signature, tssPubKey string, expectedMsgHash []byte) ([65]byte, error) { @@ -116,3 +71,10 @@ func SignatureToBytes(input keysign.Signature) (sig [65]byte, err error) { return sig, nil } + +// combineDigests combines the digests +func combineDigests(digestList []string) []byte { + digestConcat := strings.Join(digestList, "") + digestBytes := chainhash.DoubleHashH([]byte(digestConcat)) + return digestBytes.CloneBytes() +} diff --git a/zetaclient/tss/keygen.go b/zetaclient/tss/keygen.go index a70c7bb44a..1594d744d3 100644 --- a/zetaclient/tss/keygen.go +++ b/zetaclient/tss/keygen.go @@ -2,15 +2,18 @@ package tss import ( "context" + "encoding/base64" "encoding/hex" "encoding/json" "fmt" "time" + "github.com/ethereum/go-ethereum/crypto" "github.com/pkg/errors" "github.com/rs/zerolog" tsscommon "gitlab.com/thorchain/tss/go-tss/common" "gitlab.com/thorchain/tss/go-tss/keygen" + "gitlab.com/thorchain/tss/go-tss/keysign" "gitlab.com/thorchain/tss/go-tss/tss" "golang.org/x/crypto/sha3" @@ -229,3 +232,49 @@ func digestReq(req keygen.Request) (string, error) { return digest, nil } + +var testKeySignData = []byte("hello meta") + +// TestKeySign performs a TSS key-sign test of sample data. +func TestKeySign(keySigner KeySigner, tssPubKey string, logger zerolog.Logger) error { + logger = logger.With().Str(logs.FieldModule, "tss_keysign").Logger() + + hashedData := crypto.Keccak256Hash(testKeySignData) + + logger.Info(). + Str("keysign.test_data", string(testKeySignData)). + Str("keysign.test_data_hash", hashedData.String()). + Msg("Performing TSS key-sign test") + + req := keysign.NewRequest( + tssPubKey, + []string{base64.StdEncoding.EncodeToString(hashedData.Bytes())}, + 10, + nil, + Version, + ) + + res, err := keySigner.KeySign(req) + switch { + case err != nil: + return errors.Wrap(err, "key signing request error") + case res.Status != tsscommon.Success: + logger.Error().Interface("keysign.fail_blame", res.Blame).Msg("Keysign failed") + return errors.Wrapf(err, "key signing is not successful (status %d)", res.Status) + case len(res.Signatures) == 0: + return errors.New("signatures list is empty") + } + + // 32B msg hash, 32B R, 32B S, 1B RC + signature := res.Signatures[0] + + logger.Info().Interface("keysign.signature", signature).Msg("Received signature from TSS") + + if _, err = VerifySignature(signature, tssPubKey, hashedData.Bytes()); err != nil { + return errors.Wrap(err, "signature verification failed") + } + + logger.Info().Msg("TSS key-sign test passed") + + return nil +} diff --git a/zetaclient/tss/service.go b/zetaclient/tss/service.go index 0457462a6d..7fc03d9972 100644 --- a/zetaclient/tss/service.go +++ b/zetaclient/tss/service.go @@ -2,13 +2,10 @@ package tss import ( "context" - "encoding/base64" "encoding/hex" "fmt" - "strings" "time" - "github.com/btcsuite/btcd/chaincfg/chainhash" "github.com/pkg/errors" "github.com/prometheus/client_golang/prometheus" "github.com/rs/zerolog" @@ -158,7 +155,7 @@ func (s *Service) SignBatch( digestsBase64 := make([]string, len(digests)) for i, digest := range digests { - digestsBase64[i] = base64.StdEncoding.EncodeToString(digest) + digestsBase64[i] = base64EncodeString(digest) } tssPubKeyBech32 := s.PubKey().Bech32String() @@ -274,13 +271,6 @@ func (s *Service) blameFailure( return errFailure } -// combineDigests combines the digests -func combineDigests(digestList []string) []byte { - digestConcat := strings.Join(digestList, "") - digestBytes := chainhash.DoubleHashH([]byte(digestConcat)) - return digestBytes.CloneBytes() -} - func keysignLogFields(req keysign.Request, height, nonce uint64, chainID int64) map[string]any { return map[string]any{ "keysign.chain_id": chainID, diff --git a/zetaclient/tss/service_test.go b/zetaclient/tss/service_test.go index eeb126c03f..2a6bc619a1 100644 --- a/zetaclient/tss/service_test.go +++ b/zetaclient/tss/service_test.go @@ -4,7 +4,6 @@ import ( "context" "crypto/ecdsa" "crypto/rand" - "encoding/base64" "fmt" "regexp" "testing" @@ -129,6 +128,7 @@ func (m *keySignerMock) PubKeyBech32() string { return bech32 } +// AddCall mimics TSS signature process (when called with provided arguments) func (m *keySignerMock) AddCall(pk string, digests [][]byte, height int64, success bool, err error) { if success && err != nil { m.t.Fatalf("success and error are mutually exclusive") @@ -136,7 +136,7 @@ func (m *keySignerMock) AddCall(pk string, digests [][]byte, height int64, succe var ( msgs = lo.Map(digests, func(digest []byte, _ int) string { - return base64.StdEncoding.EncodeToString(digest) + return base64EncodeString(digest) }) req = keysign.NewRequest(pk, msgs, height, nil, Version) @@ -175,9 +175,9 @@ func (m *keySignerMock) sign(req keysign.Request) keysign.Response { signatures = append(signatures, keysign.Signature{ Msg: msg, - R: base64.StdEncoding.EncodeToString(sig[:32]), - S: base64.StdEncoding.EncodeToString(sig[32:64]), - RecoveryID: base64.StdEncoding.EncodeToString(sig[64:65]), + R: base64EncodeString(sig[:32]), + S: base64EncodeString(sig[32:64]), + RecoveryID: base64EncodeString(sig[64:65]), }) }