diff --git a/abci/example/kvstore/persistent_kvstore.go b/abci/example/kvstore/persistent_kvstore.go index 320918b5b1e..7952052391b 100644 --- a/abci/example/kvstore/persistent_kvstore.go +++ b/abci/example/kvstore/persistent_kvstore.go @@ -208,7 +208,7 @@ func isValidatorTx(tx []byte) bool { } // format is "val:pubkey!power" -// pubkey is a base64-encoded 32-byte ed25519 key +// pubkey is a base64-encoded 32-byte ed25519 key or sm2 key func (app *PersistentKVStoreApplication) execValidatorTx(tx []byte) types.ResponseDeliverTx { tx = tx[len(ValidatorSetChangePrefix):] diff --git a/abci/types/pubkey.go b/abci/types/pubkey.go index 8530d95383b..c1617890082 100644 --- a/abci/types/pubkey.go +++ b/abci/types/pubkey.go @@ -6,6 +6,7 @@ import ( "github.com/tendermint/tendermint/crypto/ed25519" cryptoenc "github.com/tendermint/tendermint/crypto/encoding" "github.com/tendermint/tendermint/crypto/secp256k1" + "github.com/tendermint/tendermint/crypto/sm2" ) func Ed25519ValidatorUpdate(pk []byte, power int64) ValidatorUpdate { @@ -38,6 +39,18 @@ func UpdateValidator(pk []byte, power int64, keyType string) ValidatorUpdate { PubKey: pkp, Power: power, } + case sm2.KeyType: + var pke sm2.PubKeySm2 + copy(pke[:], pk) + pkp, err := cryptoenc.PubKeyToProto(pke) + if err != nil { + panic(err) + } + return ValidatorUpdate{ + // Address: + PubKey: pkp, + Power: power, + } default: panic(fmt.Sprintf("key type %s not supported", keyType)) } diff --git a/cmd/priv_val_server/main.go b/cmd/priv_val_server/main.go index 813ce6b1404..dc63f0d984a 100644 --- a/cmd/priv_val_server/main.go +++ b/cmd/priv_val_server/main.go @@ -5,7 +5,8 @@ import ( "os" "time" - "github.com/tendermint/tendermint/crypto/ed25519" + "github.com/tendermint/tendermint/crypto/algo" + "github.com/tendermint/tendermint/libs/log" tmnet "github.com/tendermint/tendermint/libs/net" tmos "github.com/tendermint/tendermint/libs/os" @@ -43,7 +44,7 @@ func main() { dialer = privval.DialUnixFn(address) case "tcp": connTimeout := 3 * time.Second // TODO - dialer = privval.DialTCPFn(address, connTimeout, ed25519.GenPrivKey()) + dialer = privval.DialTCPFn(address, connTimeout, algo.GenPrivKey()) default: logger.Error("Unknown protocol", "protocol", protocol) os.Exit(1) diff --git a/crypto/algo/algo.go b/crypto/algo/algo.go new file mode 100644 index 00000000000..c4662f5a635 --- /dev/null +++ b/crypto/algo/algo.go @@ -0,0 +1,175 @@ +package algo + +import ( + "github.com/tendermint/tendermint/crypto" + "github.com/tendermint/tendermint/crypto/ed25519" + "github.com/tendermint/tendermint/crypto/sm2" +) + +const ( + ED25519 = "ed25519" + SM2 = "sm2" +) + +var Algo = "ed25519" + +func GetPubKeyType() string { + switch Algo { + case ED25519: + return ed25519.KeyType + + case SM2: + return sm2.KeyType + + default: + return ed25519.KeyType + } +} + +func GetPrivKeyBytes(privKey crypto.PrivKey) []byte { + switch Algo { + case ED25519: + key := privKey.(ed25519.PrivKey) + return key[:] + + case SM2: + key := privKey.(sm2.PrivKeySm2) + return key[:] + + default: + key := privKey.(ed25519.PrivKey) + return key[:] + } +} + +func GetPubKeyBytes(pubKey crypto.PubKey) []byte { + switch Algo { + case ED25519: + key := pubKey.(ed25519.PubKey) + return key[:] + + case SM2: + key := pubKey.(sm2.PubKeySm2) + return key[:] + + default: + key := pubKey.(ed25519.PubKey) + return key[:] + } +} + +func GetPubKeyFromData(keyType string, keyData []byte) crypto.PubKey { + switch Algo { + case ED25519: + pubkey := ed25519.PubKey{} + copy(pubkey[:], keyData) + return pubkey + + case SM2: + pubkey := sm2.PubKeySm2{} + copy(pubkey[:], keyData) + return pubkey + + default: + pubkey := ed25519.PubKey{} + copy(pubkey[:], keyData) + return pubkey + } +} + +func GenPrivKey() crypto.PrivKey { + switch Algo { + case ED25519: + return ed25519.GenPrivKey() + + case SM2: + return sm2.GenPrivKey() + + default: + return ed25519.GenPrivKey() + } +} + +func GenPrivKeyFromSecret(secret []byte) crypto.PrivKey { + switch Algo { + case ED25519: + return ed25519.GenPrivKeyFromSecret(secret) + + case SM2: + return sm2.GenPrivKeySm2FromSecret(secret) + + default: + return ed25519.GenPrivKeyFromSecret(secret) + } +} + +func GetPrivKeySize() int { + switch Algo { + case ED25519: + return 64 + + case SM2: + return sm2.PrivKeySize + + default: + return 64 + } +} + +func GetPubKeySize() int { + switch Algo { + case ED25519: + return ed25519.PubKeySize + + case SM2: + return sm2.PubKeySize + + default: + return ed25519.PubKeySize + } +} + +func GetSignatureSize() int { + switch Algo { + case ED25519: + return ed25519.SignatureSize + + case SM2: + return sm2.SignatureSize + + default: + return ed25519.SignatureSize + } +} + +func VerifyPubKeyType(pubKey crypto.PubKey) bool { + switch Algo { + case ED25519: + if _, ok := pubKey.(ed25519.PubKey); ok { + return true + } + + case SM2: + if _, ok := pubKey.(sm2.PubKeySm2); ok { + return true + } + } + + return false +} + +func VerifyPrivKeyType(privKey crypto.PrivKey) bool { + switch Algo { + case ED25519: + if _, ok := privKey.(ed25519.PrivKey); ok { + return true + } + + case SM2: + if _, ok := privKey.(sm2.PrivKeySm2); ok { + return true + } + } + + return false +} diff --git a/crypto/encoding/codec.go b/crypto/encoding/codec.go index 3c552ed2353..79cf3ce80c3 100644 --- a/crypto/encoding/codec.go +++ b/crypto/encoding/codec.go @@ -6,6 +6,7 @@ import ( "github.com/tendermint/tendermint/crypto" "github.com/tendermint/tendermint/crypto/ed25519" "github.com/tendermint/tendermint/crypto/secp256k1" + "github.com/tendermint/tendermint/crypto/sm2" "github.com/tendermint/tendermint/libs/json" pc "github.com/tendermint/tendermint/proto/tendermint/crypto" ) @@ -20,6 +21,12 @@ func init() { func PubKeyToProto(k crypto.PubKey) (pc.PublicKey, error) { var kp pc.PublicKey switch k := k.(type) { + case sm2.PubKeySm2: + kp = pc.PublicKey{ + Sum: &pc.PublicKey_Sm2{ + Sm2: k[:], + }, + } case ed25519.PubKey: kp = pc.PublicKey{ Sum: &pc.PublicKey_Ed25519{ @@ -41,6 +48,14 @@ func PubKeyToProto(k crypto.PubKey) (pc.PublicKey, error) { // PubKeyFromProto takes a protobuf Pubkey and transforms it to a crypto.Pubkey func PubKeyFromProto(k pc.PublicKey) (crypto.PubKey, error) { switch k := k.Sum.(type) { + case *pc.PublicKey_Sm2: + if len(k.Sm2) != sm2.PubKeySize { + return nil, fmt.Errorf("invalid size for PubKeySm2. Got %d, expected %d", + len(k.Sm2), sm2.PubKeySize) + } + pk := sm2.PubKeySm2{} + copy(pk[:], k.Sm2) + return pk, nil case *pc.PublicKey_Ed25519: if len(k.Ed25519) != ed25519.PubKeySize { return nil, fmt.Errorf("invalid size for PubKeyEd25519. Got %d, expected %d", diff --git a/crypto/sm2/bench_test.go b/crypto/sm2/bench_test.go new file mode 100644 index 00000000000..902a0c38f69 --- /dev/null +++ b/crypto/sm2/bench_test.go @@ -0,0 +1,26 @@ +package sm2 + +import ( + "io" + "testing" + + "github.com/tendermint/tendermint/crypto" + "github.com/tendermint/tendermint/crypto/internal/benchmarking" +) + +func BenchmarkKeyGeneration(b *testing.B) { + benchmarkKeygenWrapper := func(reader io.Reader) crypto.PrivKey { + return genPrivKey(reader) + } + benchmarking.BenchmarkKeyGeneration(b, benchmarkKeygenWrapper) +} + +func BenchmarkSigning(b *testing.B) { + priv := GenPrivKey() + benchmarking.BenchmarkSigning(b, priv) +} + +func BenchmarkVerification(b *testing.B) { + priv := GenPrivKey() + benchmarking.BenchmarkVerification(b, priv) +} diff --git a/crypto/sm2/sm2.go b/crypto/sm2/sm2.go new file mode 100644 index 00000000000..44f1843f0b8 --- /dev/null +++ b/crypto/sm2/sm2.go @@ -0,0 +1,204 @@ +package sm2 + +import ( + "bytes" + "crypto/rand" + "crypto/sha256" + "crypto/subtle" + "fmt" + + "io" + "math/big" + + "github.com/tjfoc/gmsm/sm2" + + "github.com/tendermint/tendermint/crypto" + "github.com/tendermint/tendermint/crypto/tmhash" + tmjson "github.com/tendermint/tendermint/libs/json" +) + +const ( + PrivKeyName = "tendermint/PrivKeySm2" + PubKeyName = "tendermint/PubKeySm2" + + PrivKeySize = 32 + PubKeySize = 33 + SignatureSize = 64 + + KeyType = "sm2" +) + +func init() { + tmjson.RegisterType(PubKeySm2{}, PubKeyName) + tmjson.RegisterType(PrivKeySm2{}, PrivKeyName) +} + +type PrivKeySm2 [PrivKeySize]byte + +// Bytes returns the privkey byte format. +func (privKey PrivKeySm2) Bytes() []byte { + return privKey[:] +} + +type PubKeySm2 [PubKeySize]byte + +func (pubKey PubKeySm2) Type() string { + return KeyType +} + +var _ crypto.PrivKey = PrivKeySm2{} +var _ crypto.PubKey = PubKeySm2{} + +func (privKey PrivKeySm2) Sign(msg []byte) ([]byte, error) { + priv := privKey.GetPrivateKey() + r, s, err := sm2.Sm2Sign(priv, msg, nil, rand.Reader) + if err != nil { + return nil, err + } + R := r.Bytes() + S := s.Bytes() + sig := make([]byte, 64) + copy(sig[32-len(R):32], R[:]) + copy(sig[64-len(S):64], S[:]) + + return sig, nil +} + +func (privKey PrivKeySm2) Sm2Sign(msg []byte) ([]byte, error) { + r, s, err := sm2.Sm2Sign(privKey.GetPrivateKey(), msg, nil, rand.Reader) + if err != nil { + return nil, err + } + + R := r.Bytes() + S := s.Bytes() + sig := make([]byte, 64) + copy(sig[32-len(R):32], R[:]) + copy(sig[64-len(S):64], S[:]) + + return sig, nil +} + +func (privKey PrivKeySm2) PubKey() crypto.PubKey { + priv := privKey.GetPrivateKey() + compPubkey := sm2.Compress(&priv.PublicKey) + var pubKey PubKeySm2 + copy(pubKey[:], compPubkey) + + return pubKey +} + +func (privKey PrivKeySm2) PubKeySm2() PubKeySm2 { + priv := privKey.GetPrivateKey() + compPubkey := sm2.Compress(&priv.PublicKey) + + var pubKey PubKeySm2 + copy(pubKey[:], compPubkey) + + return pubKey +} + +func (privKey PrivKeySm2) Equals(other crypto.PrivKey) bool { + if otherSm2, ok := other.(PrivKeySm2); ok { + return subtle.ConstantTimeCompare(privKey[:], otherSm2[:]) == 1 + } + + return false +} + +func (privKey PrivKeySm2) Type() string { + return KeyType +} + +func (privKey PrivKeySm2) GetPrivateKey() *sm2.PrivateKey { + k := new(big.Int).SetBytes(privKey[:32]) + c := sm2.P256Sm2() + priv := new(sm2.PrivateKey) + priv.PublicKey.Curve = c + priv.D = k + priv.PublicKey.X, priv.PublicKey.Y = c.ScalarBaseMult(k.Bytes()) + + return priv +} + +func GenPrivKey() PrivKeySm2 { + return genPrivKey(crypto.CReader()) +} + +func genPrivKey(rand io.Reader) PrivKeySm2 { + seed := make([]byte, 32) + if _, err := io.ReadFull(rand, seed); err != nil { + panic(err) + } + + privKey, err := sm2.GenerateKey(rand) + if err != nil { + panic(err) + } + + var privKeySm2 PrivKeySm2 + copy(privKeySm2[:], privKey.D.Bytes()) + + return privKeySm2 +} + +func GenPrivKeySm2FromSecret(secret []byte) PrivKeySm2 { + one := new(big.Int).SetInt64(1) + secHash := sha256.Sum256(secret) + + k := new(big.Int).SetBytes(secHash[:]) + n := new(big.Int).Sub(sm2.P256Sm2().Params().N, one) + k.Mod(k, n) + k.Add(k, one) + + var privKeySm2 PrivKeySm2 + copy(privKeySm2[:], k.Bytes()) + + return privKeySm2 +} + +// -------------------------------------------------------- + +func (pubKey PubKeySm2) Address() crypto.Address { + return crypto.Address(tmhash.SumTruncated(pubKey[:])) +} + +func (pubKey PubKeySm2) Bytes() []byte { + return pubKey[:] +} + +func (pubKey PubKeySm2) VerifySignature(msg []byte, sig []byte) bool { + if len(sig) != SignatureSize { + return false + } + + publicKey := sm2.Decompress(pubKey[:]) + r := new(big.Int).SetBytes(sig[:32]) + s := new(big.Int).SetBytes(sig[32:]) + + return sm2.Sm2Verify(publicKey, msg, nil, r, s) +} + +func (pubKey PubKeySm2) Sm2VerifyBytes(msg []byte, sig []byte) bool { + if len(sig) != SignatureSize { + return false + } + + publicKey := sm2.Decompress(pubKey[:]) + r := new(big.Int).SetBytes(sig[:32]) + s := new(big.Int).SetBytes(sig[32:]) + + return sm2.Sm2Verify(publicKey, msg, nil, r, s) +} + +func (pubKey PubKeySm2) String() string { + return fmt.Sprintf("PubKeySm2{%X}", pubKey[:]) +} + +func (pubKey PubKeySm2) Equals(other crypto.PubKey) bool { + if otherSm2, ok := other.(PubKeySm2); ok { + return bytes.Equal(pubKey[:], otherSm2[:]) + } + + return false +} diff --git a/crypto/sm2/sm2_test.go b/crypto/sm2/sm2_test.go new file mode 100644 index 00000000000..910c806532a --- /dev/null +++ b/crypto/sm2/sm2_test.go @@ -0,0 +1,66 @@ +package sm2_test + +import ( + "fmt" + "testing" + + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + + "github.com/tendermint/tendermint/crypto" + "github.com/tendermint/tendermint/crypto/sm2" +) + +// nolint +func TestSignAndValidate(t *testing.T) { + for i := 0; i < 1000; i++ { + privKey := sm2.GenPrivKey() + pubKey := privKey.PubKey() + + msg := crypto.CRandBytes(128) + sig, err := privKey.Sign(msg) + require.Nil(t, err) + + // Test the signature + if !pubKey.VerifySignature(msg, sig) { + fmt.Printf("# %d: Verify error\n", i) + } + + // Mutate the signature, just one bit. + sig[7] ^= byte(0x01) + + assert.False(t, pubKey.VerifySignature(msg, sig)) + } + +} + +func TestSm2SignAndSm2Validate(t *testing.T) { + for i := 0; i < 1000; i++ { + privKey := sm2.GenPrivKey() + pubKey := privKey.PubKey().(sm2.PubKeySm2) + + msg := crypto.CRandBytes(128) + sig, err := privKey.Sm2Sign(msg) + require.Nil(t, err) + + // Test the signature + if !pubKey.Sm2VerifyBytes(msg, sig) { + fmt.Printf("# %d: Verify error\n", i) + } + + // Mutate the signature, just one bit. + sig[7] ^= byte(0x01) + + assert.False(t, pubKey.VerifySignature(msg, sig)) + } + +} + +func TestGenPrivKeySm2FromSecret(t *testing.T) { + a := sm2.GenPrivKeySm2FromSecret([]byte("mySecret1")) + b := sm2.GenPrivKeySm2FromSecret([]byte("mySecret1")) + c := sm2.GenPrivKeySm2FromSecret([]byte("mySecret2")) + + require.Equal(t, a, b) + require.NotEqual(t, a, c) +} diff --git a/go.mod b/go.mod index 7b7953f0ad7..c364d336784 100644 --- a/go.mod +++ b/go.mod @@ -36,6 +36,7 @@ require ( github.com/spf13/viper v1.12.0 github.com/stretchr/testify v1.8.0 github.com/tendermint/tm-db v0.6.6 + github.com/tjfoc/gmsm v1.4.0 golang.org/x/crypto v0.0.0-20220525230936-793ad666bf5e golang.org/x/net v0.0.0-20220726230323-06994584191e google.golang.org/grpc v1.48.0 diff --git a/go.sum b/go.sum index 1a6f9961b96..aee8f7530ce 100644 --- a/go.sum +++ b/go.sum @@ -901,6 +901,8 @@ github.com/tetafro/godot v1.4.11/go.mod h1:LR3CJpxDVGlYOWn3ZZg1PgNZdTUvzsZWu8xaE github.com/timakin/bodyclose v0.0.0-20210704033933-f49887972144 h1:kl4KhGNsJIbDHS9/4U9yQo1UcPQM0kOMJHn29EoH/Ro= github.com/timakin/bodyclose v0.0.0-20210704033933-f49887972144/go.mod h1:Qimiffbc6q9tBWlVV6x0P9sat/ao1xEkREYPPj9hphk= github.com/tinylib/msgp v1.1.5/go.mod h1:eQsjooMTnV42mHu917E26IogZ2930nFyBQdofk10Udg= +github.com/tjfoc/gmsm v1.4.0 h1:8nbaiZG+iVdh+fXVw0DZoZZa7a4TGm3Qab+xdrdzj8s= +github.com/tjfoc/gmsm v1.4.0/go.mod h1:j4INPkHWMrhJb38G+J6W4Tw0AbuN8Thu3PbdVYhVcTE= github.com/tmc/grpc-websocket-proxy v0.0.0-20170815181823-89b8d40f7ca8/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= github.com/tmc/grpc-websocket-proxy v0.0.0-20200427203606-3cfed13b9966/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= @@ -996,6 +998,7 @@ golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8U golang.org/x/crypto v0.0.0-20191206172530-e9b2fee46413/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20200115085410-6d4e4cb37c7d/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +golang.org/x/crypto v0.0.0-20201012173705-84dcc777aaee/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20201221181555-eec23a3978ad/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I= golang.org/x/crypto v0.0.0-20210421170649-83a5a9bb288b/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4= golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= @@ -1028,7 +1031,6 @@ golang.org/x/lint v0.0.0-20191125180803-fdd1cda4f05f/go.mod h1:5qLYkcX4OjUUV8bRu golang.org/x/lint v0.0.0-20200130185559-910be7a94367/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= golang.org/x/lint v0.0.0-20200302205851-738671d3881b/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= golang.org/x/lint v0.0.0-20201208152925-83fdc39ff7b5/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= -golang.org/x/lint v0.0.0-20210508222113-6edffad5e616 h1:VLliZ0d+/avPrXXH+OakdXhpJuEoBZuwh1m2j7U6Iug= golang.org/x/lint v0.0.0-20210508222113-6edffad5e616/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= golang.org/x/mobile v0.0.0-20190312151609-d3739f865fa6/go.mod h1:z+o9i4GpDbdi3rU15maQ/Ox0txvL9dWGYEHz965HBQE= golang.org/x/mobile v0.0.0-20190719004257-d2bd2a29d028/go.mod h1:E/iHnbuqvinMTCcRqshq8CkpyQDoeVncDDYHnLhea+o= @@ -1081,6 +1083,7 @@ golang.org/x/net v0.0.0-20200625001655-4c5254603344/go.mod h1:/O7V0waA8r7cgGh81R golang.org/x/net v0.0.0-20200707034311-ab3426394381/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= golang.org/x/net v0.0.0-20200813134508-3edf25e44fcc/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= +golang.org/x/net v0.0.0-20201010224723-4f7140c49acb/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= golang.org/x/net v0.0.0-20201031054903-ff519b6c9102/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= golang.org/x/net v0.0.0-20201110031124-69a78807bb2b/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= diff --git a/libs/bytes/bytes.go b/libs/bytes/bytes.go index 95b4cc35fca..6877718748a 100644 --- a/libs/bytes/bytes.go +++ b/libs/bytes/bytes.go @@ -63,3 +63,8 @@ func (bz HexBytes) Format(s fmt.State, verb rune) { s.Write([]byte(fmt.Sprintf("%X", []byte(bz)))) } } + +// MarshalYAML returns the YAML representation +func (bz HexBytes) MarshalYAML() (interface{}, error) { + return bz.String(), nil +} diff --git a/p2p/conn/secret_connection.go b/p2p/conn/secret_connection.go index 76a93af5fbc..860f29308a7 100644 --- a/p2p/conn/secret_connection.go +++ b/p2p/conn/secret_connection.go @@ -13,6 +13,8 @@ import ( "net" "time" + "github.com/tendermint/tendermint/crypto/algo" + gogotypes "github.com/gogo/protobuf/types" "github.com/gtank/merlin" pool "github.com/libp2p/go-buffer-pool" @@ -22,7 +24,6 @@ import ( "golang.org/x/crypto/nacl/box" "github.com/tendermint/tendermint/crypto" - "github.com/tendermint/tendermint/crypto/ed25519" cryptoenc "github.com/tendermint/tendermint/crypto/encoding" "github.com/tendermint/tendermint/libs/async" "github.com/tendermint/tendermint/libs/protoio" @@ -167,8 +168,8 @@ func MakeSecretConnection(conn io.ReadWriteCloser, locPrivKey crypto.PrivKey) (* } remPubKey, remSignature := authSigMsg.Key, authSigMsg.Sig - if _, ok := remPubKey.(ed25519.PubKey); !ok { - return nil, fmt.Errorf("expected ed25519 pubkey, got %T", remPubKey) + if !algo.VerifyPubKeyType(remPubKey) { + return nil, fmt.Errorf("expected %s pubkey, got %T", algo.Algo, remPubKey) } if !remPubKey.VerifySignature(challenge[:], remSignature) { return nil, errors.New("challenge verification failed") diff --git a/p2p/key.go b/p2p/key.go index f0f3dfd030c..3cfde7ef52d 100644 --- a/p2p/key.go +++ b/p2p/key.go @@ -7,7 +7,7 @@ import ( "io/ioutil" "github.com/tendermint/tendermint/crypto" - "github.com/tendermint/tendermint/crypto/ed25519" + "github.com/tendermint/tendermint/crypto/algo" tmjson "github.com/tendermint/tendermint/libs/json" tmos "github.com/tendermint/tendermint/libs/os" ) @@ -56,7 +56,7 @@ func LoadOrGenNodeKey(filePath string) (*NodeKey, error) { return nodeKey, nil } - privKey := ed25519.GenPrivKey() + privKey := algo.GenPrivKey() nodeKey := &NodeKey{ PrivKey: privKey, } diff --git a/p2p/mock/peer.go b/p2p/mock/peer.go index 59f6e0f4aa4..e96c80e3aa2 100644 --- a/p2p/mock/peer.go +++ b/p2p/mock/peer.go @@ -3,7 +3,8 @@ package mock import ( "net" - "github.com/tendermint/tendermint/crypto/ed25519" + "github.com/tendermint/tendermint/crypto/algo" + "github.com/tendermint/tendermint/libs/service" "github.com/tendermint/tendermint/p2p" "github.com/tendermint/tendermint/p2p/conn" @@ -27,7 +28,7 @@ func NewPeer(ip net.IP) *Peer { } else { netAddr = p2p.NewNetAddressIPPort(ip, 26656) } - nodeKey := p2p.NodeKey{PrivKey: ed25519.GenPrivKey()} + nodeKey := p2p.NodeKey{PrivKey: algo.GenPrivKey()} netAddr.ID = nodeKey.ID() mp := &Peer{ ip: ip, diff --git a/privval/file.go b/privval/file.go index fa33bb0ae61..eb8c6e2ba12 100644 --- a/privval/file.go +++ b/privval/file.go @@ -7,10 +7,11 @@ import ( "io/ioutil" "time" + "github.com/tendermint/tendermint/crypto/algo" + "github.com/gogo/protobuf/proto" "github.com/tendermint/tendermint/crypto" - "github.com/tendermint/tendermint/crypto/ed25519" tmbytes "github.com/tendermint/tendermint/libs/bytes" tmjson "github.com/tendermint/tendermint/libs/json" tmos "github.com/tendermint/tendermint/libs/os" @@ -170,7 +171,8 @@ func NewFilePV(privKey crypto.PrivKey, keyFilePath, stateFilePath string) *FileP // GenFilePV generates a new validator with randomly generated private key // and sets the filePaths, but does not call Save(). func GenFilePV(keyFilePath, stateFilePath string) *FilePV { - return NewFilePV(ed25519.GenPrivKey(), keyFilePath, stateFilePath) + //return NewFilePV(ed25519.GenPrivKey(), keyFilePath, stateFilePath) + return NewFilePV(algo.GenPrivKey(), keyFilePath, stateFilePath) } // LoadFilePV loads a FilePV from the filePaths. The FilePV handles double diff --git a/privval/socket_listeners.go b/privval/socket_listeners.go index 4e318390a7d..12f0e5d5a61 100644 --- a/privval/socket_listeners.go +++ b/privval/socket_listeners.go @@ -4,7 +4,8 @@ import ( "net" "time" - "github.com/tendermint/tendermint/crypto/ed25519" + "github.com/tendermint/tendermint/crypto" + p2pconn "github.com/tendermint/tendermint/p2p/conn" ) @@ -44,7 +45,7 @@ var _ net.Listener = (*TCPListener)(nil) type TCPListener struct { *net.TCPListener - secretConnKey ed25519.PrivKey + secretConnKey crypto.PrivKey timeoutAccept time.Duration timeoutReadWrite time.Duration @@ -52,7 +53,7 @@ type TCPListener struct { // NewTCPListener returns a listener that accepts authenticated encrypted connections // using the given secretConnKey and the default timeout values. -func NewTCPListener(ln net.Listener, secretConnKey ed25519.PrivKey) *TCPListener { +func NewTCPListener(ln net.Listener, secretConnKey crypto.PrivKey) *TCPListener { return &TCPListener{ TCPListener: ln.(*net.TCPListener), secretConnKey: secretConnKey, diff --git a/privval/utils.go b/privval/utils.go index 0b8cced342e..5c83c687c00 100644 --- a/privval/utils.go +++ b/privval/utils.go @@ -5,7 +5,8 @@ import ( "fmt" "net" - "github.com/tendermint/tendermint/crypto/ed25519" + "github.com/tendermint/tendermint/crypto/algo" + "github.com/tendermint/tendermint/libs/log" tmnet "github.com/tendermint/tendermint/libs/net" ) @@ -39,7 +40,7 @@ func NewSignerListener(listenAddr string, logger log.Logger) (*SignerListenerEnd listener = NewUnixListener(ln) case "tcp": // TODO: persist this key so external signer can actually authenticate us - listener = NewTCPListener(ln, ed25519.GenPrivKey()) + listener = NewTCPListener(ln, algo.GenPrivKey()) default: return nil, fmt.Errorf( "wrong listen address: expected either 'tcp' or 'unix' protocols, got %s", diff --git a/proto/tendermint/crypto/keys.pb.go b/proto/tendermint/crypto/keys.pb.go index 70cfe16e011..f05a464dd23 100644 --- a/proto/tendermint/crypto/keys.pb.go +++ b/proto/tendermint/crypto/keys.pb.go @@ -29,6 +29,7 @@ type PublicKey struct { // Types that are valid to be assigned to Sum: // *PublicKey_Ed25519 // *PublicKey_Secp256K1 + // *PublicKey_Sm2 Sum isPublicKey_Sum `protobuf_oneof:"sum"` } @@ -79,9 +80,13 @@ type PublicKey_Ed25519 struct { type PublicKey_Secp256K1 struct { Secp256K1 []byte `protobuf:"bytes,2,opt,name=secp256k1,proto3,oneof" json:"secp256k1,omitempty"` } +type PublicKey_Sm2 struct { + Sm2 []byte `protobuf:"bytes,3,opt,name=sm2,proto3,oneof" json:"sm2,omitempty"` +} func (*PublicKey_Ed25519) isPublicKey_Sum() {} func (*PublicKey_Secp256K1) isPublicKey_Sum() {} +func (*PublicKey_Sm2) isPublicKey_Sum() {} func (m *PublicKey) GetSum() isPublicKey_Sum { if m != nil { @@ -104,11 +109,19 @@ func (m *PublicKey) GetSecp256K1() []byte { return nil } +func (m *PublicKey) GetSm2() []byte { + if x, ok := m.GetSum().(*PublicKey_Sm2); ok { + return x.Sm2 + } + return nil +} + // XXX_OneofWrappers is for the internal use of the proto package. func (*PublicKey) XXX_OneofWrappers() []interface{} { return []interface{}{ (*PublicKey_Ed25519)(nil), (*PublicKey_Secp256K1)(nil), + (*PublicKey_Sm2)(nil), } } @@ -119,20 +132,21 @@ func init() { func init() { proto.RegisterFile("tendermint/crypto/keys.proto", fileDescriptor_cb048658b234868c) } var fileDescriptor_cb048658b234868c = []byte{ - // 199 bytes of a gzipped FileDescriptorProto + // 211 bytes of a gzipped FileDescriptorProto 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0x92, 0x29, 0x49, 0xcd, 0x4b, 0x49, 0x2d, 0xca, 0xcd, 0xcc, 0x2b, 0xd1, 0x4f, 0x2e, 0xaa, 0x2c, 0x28, 0xc9, 0xd7, 0xcf, 0x4e, 0xad, 0x2c, 0xd6, 0x2b, 0x28, 0xca, 0x2f, 0xc9, 0x17, 0x12, 0x44, 0xc8, 0xea, 0x41, 0x64, 0xa5, - 0x44, 0xd2, 0xf3, 0xd3, 0xf3, 0xc1, 0xb2, 0xfa, 0x20, 0x16, 0x44, 0xa1, 0x52, 0x04, 0x17, 0x67, + 0x44, 0xd2, 0xf3, 0xd3, 0xf3, 0xc1, 0xb2, 0xfa, 0x20, 0x16, 0x44, 0xa1, 0x52, 0x0e, 0x17, 0x67, 0x40, 0x69, 0x52, 0x4e, 0x66, 0xb2, 0x77, 0x6a, 0xa5, 0x90, 0x14, 0x17, 0x7b, 0x6a, 0x8a, 0x91, 0xa9, 0xa9, 0xa1, 0xa5, 0x04, 0xa3, 0x02, 0xa3, 0x06, 0x8f, 0x07, 0x43, 0x10, 0x4c, 0x40, 0x48, 0x8e, 0x8b, 0xb3, 0x38, 0x35, 0xb9, 0xc0, 0xc8, 0xd4, 0x2c, 0xdb, 0x50, 0x82, 0x09, 0x2a, 0x8b, - 0x10, 0xb2, 0xe2, 0x78, 0xb1, 0x40, 0x9e, 0xf1, 0xc5, 0x42, 0x79, 0x46, 0x27, 0x56, 0x2e, 0xe6, - 0xe2, 0xd2, 0x5c, 0xa7, 0xa0, 0x13, 0x8f, 0xe4, 0x18, 0x2f, 0x3c, 0x92, 0x63, 0x7c, 0xf0, 0x48, - 0x8e, 0x71, 0xc2, 0x63, 0x39, 0x86, 0x0b, 0x8f, 0xe5, 0x18, 0x6e, 0x3c, 0x96, 0x63, 0x88, 0xb2, - 0x48, 0xcf, 0x2c, 0xc9, 0x28, 0x4d, 0xd2, 0x4b, 0xce, 0xcf, 0xd5, 0x47, 0xf2, 0x05, 0x12, 0x13, - 0xe2, 0x4c, 0x0c, 0x1f, 0x26, 0xb1, 0x81, 0x25, 0x8c, 0x01, 0x01, 0x00, 0x00, 0xff, 0xff, 0xe8, - 0x1d, 0x1e, 0xe2, 0xfd, 0x00, 0x00, 0x00, + 0x10, 0x12, 0x12, 0xe2, 0x62, 0x2e, 0xce, 0x35, 0x92, 0x60, 0x86, 0xca, 0x80, 0x38, 0x56, 0x1c, + 0x2f, 0x16, 0xc8, 0x33, 0xbe, 0x58, 0x28, 0xcf, 0xe8, 0xc4, 0xca, 0xc5, 0x5c, 0x5c, 0x9a, 0xeb, + 0x14, 0x74, 0xe2, 0x91, 0x1c, 0xe3, 0x85, 0x47, 0x72, 0x8c, 0x0f, 0x1e, 0xc9, 0x31, 0x4e, 0x78, + 0x2c, 0xc7, 0x70, 0xe1, 0xb1, 0x1c, 0xc3, 0x8d, 0xc7, 0x72, 0x0c, 0x51, 0x16, 0xe9, 0x99, 0x25, + 0x19, 0xa5, 0x49, 0x7a, 0xc9, 0xf9, 0xb9, 0xfa, 0x48, 0x3e, 0x43, 0x62, 0x42, 0x9c, 0x8e, 0xe1, + 0xeb, 0x24, 0x36, 0xb0, 0x84, 0x31, 0x20, 0x00, 0x00, 0xff, 0xff, 0xc1, 0x33, 0xfd, 0xa2, 0x11, + 0x01, 0x00, 0x00, } func (this *PublicKey) Compare(that interface{}) int { @@ -173,6 +187,8 @@ func (this *PublicKey) Compare(that interface{}) int { thisType = 0 case *PublicKey_Secp256K1: thisType = 1 + case *PublicKey_Sm2: + thisType = 2 default: panic(fmt.Sprintf("compare: unexpected type %T in oneof", this.Sum)) } @@ -182,6 +198,8 @@ func (this *PublicKey) Compare(that interface{}) int { that1Type = 0 case *PublicKey_Secp256K1: that1Type = 1 + case *PublicKey_Sm2: + that1Type = 2 default: panic(fmt.Sprintf("compare: unexpected type %T in oneof", that1.Sum)) } @@ -257,6 +275,36 @@ func (this *PublicKey_Secp256K1) Compare(that interface{}) int { } return 0 } +func (this *PublicKey_Sm2) Compare(that interface{}) int { + if that == nil { + if this == nil { + return 0 + } + return 1 + } + + that1, ok := that.(*PublicKey_Sm2) + if !ok { + that2, ok := that.(PublicKey_Sm2) + if ok { + that1 = &that2 + } else { + return 1 + } + } + if that1 == nil { + if this == nil { + return 0 + } + return 1 + } else if this == nil { + return -1 + } + if c := bytes.Compare(this.Sm2, that1.Sm2); c != 0 { + return c + } + return 0 +} func (this *PublicKey) Equal(that interface{}) bool { if that == nil { return this == nil @@ -335,6 +383,30 @@ func (this *PublicKey_Secp256K1) Equal(that interface{}) bool { } return true } +func (this *PublicKey_Sm2) Equal(that interface{}) bool { + if that == nil { + return this == nil + } + + that1, ok := that.(*PublicKey_Sm2) + if !ok { + that2, ok := that.(PublicKey_Sm2) + if ok { + that1 = &that2 + } else { + return false + } + } + if that1 == nil { + return this == nil + } else if this == nil { + return false + } + if !bytes.Equal(this.Sm2, that1.Sm2) { + return false + } + return true +} func (m *PublicKey) Marshal() (dAtA []byte, err error) { size := m.Size() dAtA = make([]byte, size) @@ -399,6 +471,22 @@ func (m *PublicKey_Secp256K1) MarshalToSizedBuffer(dAtA []byte) (int, error) { } return len(dAtA) - i, nil } +func (m *PublicKey_Sm2) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *PublicKey_Sm2) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + if m.Sm2 != nil { + i -= len(m.Sm2) + copy(dAtA[i:], m.Sm2) + i = encodeVarintKeys(dAtA, i, uint64(len(m.Sm2))) + i-- + dAtA[i] = 0x1a + } + return len(dAtA) - i, nil +} func encodeVarintKeys(dAtA []byte, offset int, v uint64) int { offset -= sovKeys(v) base := offset @@ -446,6 +534,18 @@ func (m *PublicKey_Secp256K1) Size() (n int) { } return n } +func (m *PublicKey_Sm2) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.Sm2 != nil { + l = len(m.Sm2) + n += 1 + l + sovKeys(uint64(l)) + } + return n +} func sovKeys(x uint64) (n int) { return (math_bits.Len64(x|1) + 6) / 7 @@ -548,6 +648,39 @@ func (m *PublicKey) Unmarshal(dAtA []byte) error { copy(v, dAtA[iNdEx:postIndex]) m.Sum = &PublicKey_Secp256K1{v} iNdEx = postIndex + case 3: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Sm2", wireType) + } + var byteLen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowKeys + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + byteLen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if byteLen < 0 { + return ErrInvalidLengthKeys + } + postIndex := iNdEx + byteLen + if postIndex < 0 { + return ErrInvalidLengthKeys + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + v := make([]byte, postIndex-iNdEx) + copy(v, dAtA[iNdEx:postIndex]) + m.Sum = &PublicKey_Sm2{v} + iNdEx = postIndex default: iNdEx = preIndex skippy, err := skipKeys(dAtA[iNdEx:]) diff --git a/proto/tendermint/crypto/keys.proto b/proto/tendermint/crypto/keys.proto index 16fd7adf3ee..b1717ef3f55 100644 --- a/proto/tendermint/crypto/keys.proto +++ b/proto/tendermint/crypto/keys.proto @@ -13,5 +13,6 @@ message PublicKey { oneof sum { bytes ed25519 = 1; bytes secp256k1 = 2; + bytes sm2 = 3; } } diff --git a/tools/tm-signer-harness/internal/test_harness.go b/tools/tm-signer-harness/internal/test_harness.go index 33ae537fe01..a5172e0257c 100644 --- a/tools/tm-signer-harness/internal/test_harness.go +++ b/tools/tm-signer-harness/internal/test_harness.go @@ -8,9 +8,10 @@ import ( "os/signal" "time" + "github.com/tendermint/tendermint/crypto" + "github.com/tendermint/tendermint/crypto/tmhash" - "github.com/tendermint/tendermint/crypto/ed25519" "github.com/tendermint/tendermint/privval" "github.com/tendermint/tendermint/state" @@ -74,7 +75,7 @@ type TestHarnessConfig struct { ConnDeadline time.Duration AcceptRetries int - SecretConnKey ed25519.PrivKey + SecretConnKey crypto.PrivKey ExitWhenComplete bool // Whether or not to call os.Exit when the harness has completed. } diff --git a/tools/tm-signer-harness/main.go b/tools/tm-signer-harness/main.go index d624234ae0e..e61761f48f3 100644 --- a/tools/tm-signer-harness/main.go +++ b/tools/tm-signer-harness/main.go @@ -8,7 +8,8 @@ import ( "path/filepath" "time" - "github.com/tendermint/tendermint/crypto/ed25519" + "github.com/tendermint/tendermint/crypto/algo" + "github.com/tendermint/tendermint/libs/log" "github.com/tendermint/tendermint/privval" "github.com/tendermint/tendermint/tools/tm-signer-harness/internal" @@ -117,7 +118,7 @@ func runTestHarness(acceptRetries int, bindAddr, tmhome string) { AcceptDeadline: time.Duration(defaultAcceptDeadline) * time.Second, AcceptRetries: acceptRetries, ConnDeadline: time.Duration(defaultConnDeadline) * time.Second, - SecretConnKey: ed25519.GenPrivKey(), + SecretConnKey: algo.GenPrivKey(), ExitWhenComplete: true, } harness, err := internal.NewTestHarness(logger, cfg) @@ -135,7 +136,7 @@ func extractKey(tmhome, outputPath string) { keyFile := filepath.Join(internal.ExpandPath(tmhome), "config", "priv_validator_key.json") stateFile := filepath.Join(internal.ExpandPath(tmhome), "data", "priv_validator_state.json") fpv := privval.LoadFilePV(keyFile, stateFile) - pkb := []byte(fpv.Key.PrivKey.(ed25519.PrivKey)) + pkb := algo.GetPrivKeyBytes(fpv.Key.PrivKey) if err := ioutil.WriteFile(internal.ExpandPath(outputPath), pkb[:32], 0600); err != nil { logger.Info("Failed to write private key", "output", outputPath, "err", err) os.Exit(1) diff --git a/types/params.go b/types/params.go index 16c85aa5574..f16896fc978 100644 --- a/types/params.go +++ b/types/params.go @@ -50,10 +50,10 @@ func DefaultEvidenceParams() tmproto.EvidenceParams { } // DefaultValidatorParams returns a default ValidatorParams, which allows -// only ed25519 pubkeys. +// only ed25519 and sm2 pubkeys. func DefaultValidatorParams() tmproto.ValidatorParams { return tmproto.ValidatorParams{ - PubKeyTypes: []string{ABCIPubKeyTypeEd25519}, + PubKeyTypes: []string{GetABCIPubKeyType()}, } } diff --git a/types/priv_validator.go b/types/priv_validator.go index 49211773a08..a73ee77efc7 100644 --- a/types/priv_validator.go +++ b/types/priv_validator.go @@ -5,8 +5,9 @@ import ( "errors" "fmt" + "github.com/tendermint/tendermint/crypto/algo" + "github.com/tendermint/tendermint/crypto" - "github.com/tendermint/tendermint/crypto/ed25519" tmproto "github.com/tendermint/tendermint/proto/tendermint/types" ) @@ -54,7 +55,7 @@ type MockPV struct { } func NewMockPV() MockPV { - return MockPV{ed25519.GenPrivKey(), false, false} + return MockPV{algo.GenPrivKey(), false, false} } // NewMockPVWithParams allows one to create a MockPV instance, but with finer @@ -141,5 +142,5 @@ func (pv *ErroringMockPV) SignProposal(chainID string, proposal *tmproto.Proposa // NewErroringMockPV returns a MockPV that fails on each signing request. Again, for testing only. func NewErroringMockPV() *ErroringMockPV { - return &ErroringMockPV{MockPV{ed25519.GenPrivKey(), false, false}} + return &ErroringMockPV{MockPV{algo.GenPrivKey(), false, false}} } diff --git a/types/protobuf.go b/types/protobuf.go index 1ee094a9f05..6e7e633c61b 100644 --- a/types/protobuf.go +++ b/types/protobuf.go @@ -3,9 +3,11 @@ package types import ( abci "github.com/tendermint/tendermint/abci/types" "github.com/tendermint/tendermint/crypto" + "github.com/tendermint/tendermint/crypto/algo" "github.com/tendermint/tendermint/crypto/ed25519" cryptoenc "github.com/tendermint/tendermint/crypto/encoding" "github.com/tendermint/tendermint/crypto/secp256k1" + "github.com/tendermint/tendermint/crypto/sm2" tmproto "github.com/tendermint/tendermint/proto/tendermint/types" ) @@ -15,6 +17,7 @@ import ( const ( ABCIPubKeyTypeEd25519 = ed25519.KeyType ABCIPubKeyTypeSecp256k1 = secp256k1.KeyType + ABCIPubKeyTypeSm2 = sm2.KeyType ) // TODO: Make non-global by allowing for registration of more pubkey types @@ -22,10 +25,22 @@ const ( var ABCIPubKeyTypesToNames = map[string]string{ ABCIPubKeyTypeEd25519: ed25519.PubKeyName, ABCIPubKeyTypeSecp256k1: secp256k1.PubKeyName, + ABCIPubKeyTypeSm2: sm2.PubKeyName, } //------------------------------------------------------- +func GetABCIPubKeyType() string { + switch algo.Algo { + case algo.ED25519: + return ABCIPubKeyTypeEd25519 + case algo.SM2: + return ABCIPubKeyTypeSm2 + default: + return ABCIPubKeyTypeEd25519 + } +} + // TM2PB is used for converting Tendermint ABCI to protobuf ABCI. // UNSTABLE var TM2PB = tm2pb{} diff --git a/types/signable.go b/types/signable.go index 25e30731686..3a269fc0cdf 100644 --- a/types/signable.go +++ b/types/signable.go @@ -1,7 +1,7 @@ package types import ( - "github.com/tendermint/tendermint/crypto/ed25519" + "github.com/tendermint/tendermint/crypto/algo" tmmath "github.com/tendermint/tendermint/libs/math" ) @@ -9,7 +9,7 @@ var ( // MaxSignatureSize is a maximum allowed signature size for the Proposal // and Vote. // XXX: secp256k1 does not have Size nor MaxSize defined. - MaxSignatureSize = tmmath.MaxInt(ed25519.SignatureSize, 64) + MaxSignatureSize = tmmath.MaxInt(algo.GetSignatureSize(), 64) ) // Signable is an interface for all signable things.