From 15998d4e6260a6a6212a3d9c3223f796ca4cb434 Mon Sep 17 00:00:00 2001 From: sheldon <997166273@qq.com> Date: Mon, 7 Nov 2022 17:11:52 +0800 Subject: [PATCH] cherry-pick: sm2 --- Makefile | 3 +- baseapp/baseapp_test.go | 4 +- baseapp/options.go | 6 +- baseapp/p2p.go | 17 +- client/keys/add.go | 2 +- client/tx/legacy.go | 22 ++ crypto/codec/amino.go | 5 + crypto/codec/proto.go | 3 + crypto/codec/tm.go | 11 + crypto/hd/algo.go | 37 ++ crypto/keyring/keyring.go | 4 +- crypto/keys/sm2/keys.pb.go | 496 +++++++++++++++++++++++++++ crypto/keys/sm2/sm2.go | 227 ++++++++++++ crypto/keys/sm2/sm2_test.go | 67 ++++ crypto/ledger/encode_test.go | 2 + go.mod | 3 + go.sum | 7 +- proto/cosmos/auth/v1beta1/auth.proto | 1 + proto/cosmos/crypto/sm2/keys.proto | 22 ++ simapp/simd/cmd/testnet.go | 2 +- testutil/network/network.go | 2 +- testutil/testdata/tx.go | 2 +- types/abci.go | 2 +- x/auth/ante/ante_test.go | 6 +- x/auth/ante/basic.go | 6 +- x/auth/ante/sigverify.go | 35 +- x/auth/ante/sigverify_test.go | 2 + x/auth/simulation/genesis.go | 22 +- x/auth/types/auth.pb.go | 120 ++++--- x/auth/types/params.go | 23 +- x/auth/types/params_test.go | 10 +- 31 files changed, 1083 insertions(+), 88 deletions(-) create mode 100644 crypto/keys/sm2/keys.pb.go create mode 100644 crypto/keys/sm2/sm2.go create mode 100644 crypto/keys/sm2/sm2_test.go create mode 100644 proto/cosmos/crypto/sm2/keys.proto diff --git a/Makefile b/Makefile index 442598e374f7..ed0ed490770d 100644 --- a/Makefile +++ b/Makefile @@ -63,7 +63,8 @@ ldflags = -X github.com/cosmos/cosmos-sdk/version.Name=sim \ -X github.com/cosmos/cosmos-sdk/version.Version=$(VERSION) \ -X github.com/cosmos/cosmos-sdk/version.Commit=$(COMMIT) \ -X "github.com/cosmos/cosmos-sdk/version.BuildTags=$(build_tags_comma_sep)" \ - -X github.com/tendermint/tendermint/version.TMCoreSemVer=$(TMVERSION) + -X github.com/tendermint/tendermint/version.TMCoreSemVer=$(TMVERSION) \ + -X github.com/tendermint/tendermint/crypto/algo.Algo=sm2 ifeq ($(ENABLE_ROCKSDB),true) BUILD_TAGS += rocksdb_build diff --git a/baseapp/baseapp_test.go b/baseapp/baseapp_test.go index bf5d6b213e8d..cd6e723dbe14 100644 --- a/baseapp/baseapp_test.go +++ b/baseapp/baseapp_test.go @@ -1706,14 +1706,14 @@ func TestGRPCQuery(t *testing.T) { // Test p2p filter queries func TestP2PQuery(t *testing.T) { addrPeerFilterOpt := func(bapp *BaseApp) { - bapp.SetAddrPeerFilter(func(addrport string) abci.ResponseQuery { + bapp.SetAddrPeerFilter(func(ctx sdk.Context, addrport string) abci.ResponseQuery { require.Equal(t, "1.1.1.1:8000", addrport) return abci.ResponseQuery{Code: uint32(3)} }) } idPeerFilterOpt := func(bapp *BaseApp) { - bapp.SetIDPeerFilter(func(id string) abci.ResponseQuery { + bapp.SetIDPeerFilter(func(ctx sdk.Context, id string) abci.ResponseQuery { require.Equal(t, "testid", id) return abci.ResponseQuery{Code: uint32(4)} }) diff --git a/baseapp/options.go b/baseapp/options.go index ad8b7f9d5e7f..a01ffbc6fb2c 100644 --- a/baseapp/options.go +++ b/baseapp/options.go @@ -151,9 +151,9 @@ func (app *BaseApp) SetEndBlocker(endBlocker sdk.EndBlocker) { } func (app *BaseApp) SetAnteHandler(ah sdk.AnteHandler) { - if app.sealed { - panic("SetAnteHandler() on sealed BaseApp") - } + //if app.sealed { + // panic("SetAnteHandler() on sealed BaseApp") + //} app.anteHandler = ah } diff --git a/baseapp/p2p.go b/baseapp/p2p.go index c11639f608b9..01ad9b171c1f 100644 --- a/baseapp/p2p.go +++ b/baseapp/p2p.go @@ -19,18 +19,18 @@ type peerFilters struct { } // FilterPeerByAddrPort filters peers by address/port. -func (app *BaseApp) FilterPeerByAddrPort(info string) abci.ResponseQuery { +func (app *BaseApp) FilterPeerByAddrPort(ctx sdk.Context, info string) abci.ResponseQuery { if app.addrPeerFilter != nil { - return app.addrPeerFilter(info) + return app.addrPeerFilter(ctx, info) } return abci.ResponseQuery{} } // FilterPeerByID filters peers by node ID. -func (app *BaseApp) FilterPeerByID(info string) abci.ResponseQuery { +func (app *BaseApp) FilterPeerByID(ctx sdk.Context, info string) abci.ResponseQuery { if app.idPeerFilter != nil { - return app.idPeerFilter(info) + return app.idPeerFilter(ctx, info) } return abci.ResponseQuery{} @@ -47,6 +47,11 @@ func handleQueryP2P(app *BaseApp, path []string) abci.ResponseQuery { ) } + ctx, err := app.createQueryContext(0, false) + if err != nil { + return sdkerrors.QueryResult(err, false) + } + var resp abci.ResponseQuery cmd, typ, arg := path[1], path[2], path[3] @@ -54,10 +59,10 @@ func handleQueryP2P(app *BaseApp, path []string) abci.ResponseQuery { case "filter": switch typ { case "addr": - resp = app.FilterPeerByAddrPort(arg) + resp = app.FilterPeerByAddrPort(ctx, arg) case "id": - resp = app.FilterPeerByID(arg) + resp = app.FilterPeerByID(ctx, arg) } default: diff --git a/client/keys/add.go b/client/keys/add.go index b0a3fdf787db..488b5d3ce73a 100644 --- a/client/keys/add.go +++ b/client/keys/add.go @@ -76,7 +76,7 @@ Example: f.Uint32(flagCoinType, sdk.GetConfig().GetCoinType(), "coin type number for HD derivation") f.Uint32(flagAccount, 0, "Account number for HD derivation (less than equal 2147483647)") f.Uint32(flagIndex, 0, "Address index number for HD derivation (less than equal 2147483647)") - f.String(flags.FlagKeyAlgorithm, string(hd.Secp256k1Type), "Key signing algorithm to generate keys for") + f.String(flags.FlagKeyAlgorithm, string(hd.Sm2Type), "Key signing algorithm to generate keys for") return cmd } diff --git a/client/tx/legacy.go b/client/tx/legacy.go index c07982a3fe4d..7750aff96e28 100644 --- a/client/tx/legacy.go +++ b/client/tx/legacy.go @@ -2,6 +2,7 @@ package tx import ( "fmt" + sdk "github.com/cosmos/cosmos-sdk/types" "github.com/cosmos/cosmos-sdk/client" "github.com/cosmos/cosmos-sdk/codec" @@ -63,3 +64,24 @@ func CopyTx(tx signing.Tx, builder client.TxBuilder, ignoreSignatureError bool) return nil } + +// ConvertAndEncodeStdTx encodes the stdTx as a transaction in the format specified by txConfig +func ConvertAndEncodeStdTx(txConfig client.TxConfig, stdTx legacytx.StdTx) ([]byte, error) { + builder := txConfig.NewTxBuilder() + + var theTx sdk.Tx + + // check if we need a StdTx anyway, in that case don't copy + if _, ok := builder.GetTx().(legacytx.StdTx); ok { + theTx = stdTx + } else { + err := CopyTx(stdTx, builder, false) + if err != nil { + return nil, err + } + + theTx = builder.GetTx() + } + + return txConfig.TxEncoder()(theTx) +} diff --git a/crypto/codec/amino.go b/crypto/codec/amino.go index 50119ed19858..a71feae5f073 100644 --- a/crypto/codec/amino.go +++ b/crypto/codec/amino.go @@ -7,6 +7,7 @@ import ( "github.com/cosmos/cosmos-sdk/crypto/keys/ed25519" kmultisig "github.com/cosmos/cosmos-sdk/crypto/keys/multisig" "github.com/cosmos/cosmos-sdk/crypto/keys/secp256k1" + "github.com/cosmos/cosmos-sdk/crypto/keys/sm2" cryptotypes "github.com/cosmos/cosmos-sdk/crypto/types" ) @@ -20,6 +21,8 @@ func RegisterCrypto(cdc *codec.LegacyAmino) { ed25519.PubKeyName, nil) cdc.RegisterConcrete(&secp256k1.PubKey{}, secp256k1.PubKeyName, nil) + cdc.RegisterConcrete(&sm2.PubKey{}, + sm2.PubKeyName, nil) cdc.RegisterConcrete(&kmultisig.LegacyAminoPubKey{}, kmultisig.PubKeyAminoRoute, nil) @@ -30,4 +33,6 @@ func RegisterCrypto(cdc *codec.LegacyAmino) { ed25519.PrivKeyName, nil) cdc.RegisterConcrete(&secp256k1.PrivKey{}, secp256k1.PrivKeyName, nil) + cdc.RegisterConcrete(&sm2.PrivKey{}, + sm2.PrivKeyName, nil) } diff --git a/crypto/codec/proto.go b/crypto/codec/proto.go index 1340dab03de5..7b714ef7cb80 100644 --- a/crypto/codec/proto.go +++ b/crypto/codec/proto.go @@ -6,6 +6,7 @@ import ( "github.com/cosmos/cosmos-sdk/crypto/keys/multisig" "github.com/cosmos/cosmos-sdk/crypto/keys/secp256k1" "github.com/cosmos/cosmos-sdk/crypto/keys/secp256r1" + "github.com/cosmos/cosmos-sdk/crypto/keys/sm2" cryptotypes "github.com/cosmos/cosmos-sdk/crypto/types" ) @@ -13,12 +14,14 @@ import ( func RegisterInterfaces(registry codectypes.InterfaceRegistry) { var pk *cryptotypes.PubKey registry.RegisterInterface("cosmos.crypto.PubKey", pk) + registry.RegisterImplementations(pk, &sm2.PubKey{}) registry.RegisterImplementations(pk, &ed25519.PubKey{}) registry.RegisterImplementations(pk, &secp256k1.PubKey{}) registry.RegisterImplementations(pk, &multisig.LegacyAminoPubKey{}) var priv *cryptotypes.PrivKey registry.RegisterInterface("cosmos.crypto.PrivKey", priv) + registry.RegisterImplementations(priv, &sm2.PrivKey{}) registry.RegisterImplementations(priv, &secp256k1.PrivKey{}) registry.RegisterImplementations(priv, &ed25519.PrivKey{}) //nolint secp256r1.RegisterInterfaces(registry) diff --git a/crypto/codec/tm.go b/crypto/codec/tm.go index 8c841e96b3c7..585912402ce1 100644 --- a/crypto/codec/tm.go +++ b/crypto/codec/tm.go @@ -7,6 +7,7 @@ import ( "github.com/cosmos/cosmos-sdk/crypto/keys/ed25519" "github.com/cosmos/cosmos-sdk/crypto/keys/secp256k1" + "github.com/cosmos/cosmos-sdk/crypto/keys/sm2" cryptotypes "github.com/cosmos/cosmos-sdk/crypto/types" sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" ) @@ -22,6 +23,10 @@ func FromTmProtoPublicKey(protoPk tmprotocrypto.PublicKey) (cryptotypes.PubKey, return &secp256k1.PubKey{ Key: protoPk.Secp256K1, }, nil + case *tmprotocrypto.PublicKey_Sm2: + return &sm2.PubKey{ + Key: protoPk.Sm2, + }, nil default: return nil, sdkerrors.Wrapf(sdkerrors.ErrInvalidType, "cannot convert %v from Tendermint public key", protoPk) } @@ -42,6 +47,12 @@ func ToTmProtoPublicKey(pk cryptotypes.PubKey) (tmprotocrypto.PublicKey, error) Secp256K1: pk.Key, }, }, nil + case *sm2.PubKey: + return tmprotocrypto.PublicKey{ + Sum: &tmprotocrypto.PublicKey_Sm2{ + Sm2: pk.Key, + }, + }, nil default: return tmprotocrypto.PublicKey{}, sdkerrors.Wrapf(sdkerrors.ErrInvalidType, "cannot convert %v to Tendermint public key", pk) } diff --git a/crypto/hd/algo.go b/crypto/hd/algo.go index 0feb4ff49b47..bff70ae907ca 100644 --- a/crypto/hd/algo.go +++ b/crypto/hd/algo.go @@ -4,6 +4,7 @@ import ( "github.com/cosmos/go-bip39" "github.com/cosmos/cosmos-sdk/crypto/keys/secp256k1" + "github.com/cosmos/cosmos-sdk/crypto/keys/sm2" "github.com/cosmos/cosmos-sdk/crypto/types" ) @@ -20,11 +21,15 @@ const ( Ed25519Type = PubKeyType("ed25519") // Sr25519Type represents the Sr25519Type signature system. Sr25519Type = PubKeyType("sr25519") + // Sm2Type represents the Sm2Type signature system. + Sm2Type = PubKeyType("sm2") ) // Secp256k1 uses the Bitcoin secp256k1 ECDSA parameters. var Secp256k1 = secp256k1Algo{} +var Sm2 = sm2Algo{} + type ( DeriveFn func(mnemonic string, bip39Passphrase, hdPath string) ([]byte, error) GenerateFn func(bz []byte) types.PrivKey @@ -68,3 +73,35 @@ func (s secp256k1Algo) Generate() GenerateFn { return &secp256k1.PrivKey{Key: bzArr} } } + +type sm2Algo struct{} + +func (s sm2Algo) Name() PubKeyType { + return Sm2Type +} + +// Derive derives and returns the secp256k1 private key for the given seed and HD path. +func (s sm2Algo) Derive() DeriveFn { + return func(mnemonic string, bip39Passphrase, hdPath string) ([]byte, error) { + seed, err := bip39.NewSeedWithErrorChecking(mnemonic, bip39Passphrase) + if err != nil { + return nil, err + } + + masterPriv, ch := ComputeMastersFromSeed(seed) + if len(hdPath) == 0 { + return masterPriv[:], nil + } + derivedKey, err := DerivePrivateKeyForPath(masterPriv, ch, hdPath) + return derivedKey[:], err + } +} + +// Generate generates a sm2 private key from the given bytes. +func (s sm2Algo) Generate() GenerateFn { + return func(bz []byte) types.PrivKey { + var bzArr [sm2.PrivKeySize]byte + copy(bzArr[:], bz) + return &sm2.PrivKey{Key: bzArr[:]} + } +} diff --git a/crypto/keyring/keyring.go b/crypto/keyring/keyring.go index d34bfe3c0369..7af263d08012 100644 --- a/crypto/keyring/keyring.go +++ b/crypto/keyring/keyring.go @@ -205,8 +205,8 @@ func newKeystore(kr keyring.Keyring, cdc codec.Codec, backend string, opts ...Op // Default options for keybase, these can be overwritten using the // Option function options := Options{ - SupportedAlgos: SigningAlgoList{hd.Secp256k1}, - SupportedAlgosLedger: SigningAlgoList{hd.Secp256k1}, + SupportedAlgos: SigningAlgoList{hd.Secp256k1, hd.Sm2}, + SupportedAlgosLedger: SigningAlgoList{hd.Secp256k1, hd.Sm2}, } for _, optionFn := range opts { diff --git a/crypto/keys/sm2/keys.pb.go b/crypto/keys/sm2/keys.pb.go new file mode 100644 index 000000000000..9d1f63bfa47f --- /dev/null +++ b/crypto/keys/sm2/keys.pb.go @@ -0,0 +1,496 @@ +// Code generated by protoc-gen-gogo. DO NOT EDIT. +// source: cosmos/crypto/sm2/keys.proto + +package sm2 + +import ( + fmt "fmt" + _ "github.com/gogo/protobuf/gogoproto" + proto "github.com/gogo/protobuf/proto" + io "io" + math "math" + math_bits "math/bits" +) + +// Reference imports to suppress errors if they are not otherwise used. +var _ = proto.Marshal +var _ = fmt.Errorf +var _ = math.Inf + +// This is a compile-time assertion to ensure that this generated file +// is compatible with the proto package it is being compiled against. +// A compilation error at this line likely means your copy of the +// proto package needs to be updated. +const _ = proto.GoGoProtoPackageIsVersion3 // please upgrade the proto package + +// PubKey defines a secp256k1 public key +// Key is the compressed form of the pubkey. The first byte depends is a 0x02 byte +// if the y-coordinate is the lexicographically largest of the two associated with +// the x-coordinate. Otherwise the first byte is a 0x03. +// This prefix is followed with the x-coordinate. +type PubKey struct { + Key []byte `protobuf:"bytes,1,opt,name=key,proto3" json:"key,omitempty"` +} + +func (m *PubKey) Reset() { *m = PubKey{} } +func (*PubKey) ProtoMessage() {} +func (*PubKey) Descriptor() ([]byte, []int) { + return fileDescriptor_5b7c2a655929c3c2, []int{0} +} +func (m *PubKey) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *PubKey) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_PubKey.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *PubKey) XXX_Merge(src proto.Message) { + xxx_messageInfo_PubKey.Merge(m, src) +} +func (m *PubKey) XXX_Size() int { + return m.Size() +} +func (m *PubKey) XXX_DiscardUnknown() { + xxx_messageInfo_PubKey.DiscardUnknown(m) +} + +var xxx_messageInfo_PubKey proto.InternalMessageInfo + +func (m *PubKey) GetKey() []byte { + if m != nil { + return m.Key + } + return nil +} + +// PrivKey defines a secp256k1 private key. +type PrivKey struct { + Key []byte `protobuf:"bytes,1,opt,name=key,proto3" json:"key,omitempty"` +} + +func (m *PrivKey) Reset() { *m = PrivKey{} } +func (m *PrivKey) String() string { return proto.CompactTextString(m) } +func (*PrivKey) ProtoMessage() {} +func (*PrivKey) Descriptor() ([]byte, []int) { + return fileDescriptor_5b7c2a655929c3c2, []int{1} +} +func (m *PrivKey) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *PrivKey) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_PrivKey.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *PrivKey) XXX_Merge(src proto.Message) { + xxx_messageInfo_PrivKey.Merge(m, src) +} +func (m *PrivKey) XXX_Size() int { + return m.Size() +} +func (m *PrivKey) XXX_DiscardUnknown() { + xxx_messageInfo_PrivKey.DiscardUnknown(m) +} + +var xxx_messageInfo_PrivKey proto.InternalMessageInfo + +func (m *PrivKey) GetKey() []byte { + if m != nil { + return m.Key + } + return nil +} + +func init() { + proto.RegisterType((*PubKey)(nil), "cosmos.crypto.sm2.PubKey") + proto.RegisterType((*PrivKey)(nil), "cosmos.crypto.sm2.PrivKey") +} + +func init() { proto.RegisterFile("cosmos/crypto/sm2/keys.proto", fileDescriptor_5b7c2a655929c3c2) } + +var fileDescriptor_5b7c2a655929c3c2 = []byte{ + // 180 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0x92, 0x49, 0xce, 0x2f, 0xce, + 0xcd, 0x2f, 0xd6, 0x4f, 0x2e, 0xaa, 0x2c, 0x28, 0xc9, 0xd7, 0x2f, 0xce, 0x35, 0xd2, 0xcf, 0x4e, + 0xad, 0x2c, 0xd6, 0x2b, 0x28, 0xca, 0x2f, 0xc9, 0x17, 0x12, 0x84, 0xc8, 0xea, 0x41, 0x64, 0xf5, + 0x8a, 0x73, 0x8d, 0xa4, 0x44, 0xd2, 0xf3, 0xd3, 0xf3, 0xc1, 0xb2, 0xfa, 0x20, 0x16, 0x44, 0xa1, + 0x92, 0x02, 0x17, 0x5b, 0x40, 0x69, 0x92, 0x77, 0x6a, 0xa5, 0x90, 0x00, 0x17, 0x73, 0x76, 0x6a, + 0xa5, 0x04, 0xa3, 0x02, 0xa3, 0x06, 0x4f, 0x10, 0x88, 0x69, 0xc5, 0x32, 0x63, 0x81, 0x3c, 0x83, + 0x92, 0x34, 0x17, 0x7b, 0x40, 0x51, 0x66, 0x19, 0x56, 0x25, 0x4e, 0x6e, 0x27, 0x1e, 0xc9, 0x31, + 0x5e, 0x78, 0x24, 0xc7, 0xf8, 0xe0, 0x91, 0x1c, 0xe3, 0x84, 0xc7, 0x72, 0x0c, 0x17, 0x1e, 0xcb, + 0x31, 0xdc, 0x78, 0x2c, 0xc7, 0x10, 0xa5, 0x93, 0x9e, 0x59, 0x92, 0x51, 0x9a, 0xa4, 0x97, 0x9c, + 0x9f, 0xab, 0x0f, 0x73, 0x2a, 0x98, 0xd2, 0x2d, 0x4e, 0xc9, 0x86, 0xb9, 0x1a, 0xe4, 0x62, 0x90, + 0xd3, 0x93, 0xd8, 0xc0, 0xae, 0x31, 0x06, 0x04, 0x00, 0x00, 0xff, 0xff, 0xa0, 0x23, 0x67, 0x98, + 0xd6, 0x00, 0x00, 0x00, +} + +func (m *PubKey) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *PubKey) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *PubKey) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if len(m.Key) > 0 { + i -= len(m.Key) + copy(dAtA[i:], m.Key) + i = encodeVarintKeys(dAtA, i, uint64(len(m.Key))) + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + +func (m *PrivKey) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *PrivKey) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *PrivKey) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if len(m.Key) > 0 { + i -= len(m.Key) + copy(dAtA[i:], m.Key) + i = encodeVarintKeys(dAtA, i, uint64(len(m.Key))) + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + +func encodeVarintKeys(dAtA []byte, offset int, v uint64) int { + offset -= sovKeys(v) + base := offset + for v >= 1<<7 { + dAtA[offset] = uint8(v&0x7f | 0x80) + v >>= 7 + offset++ + } + dAtA[offset] = uint8(v) + return base +} +func (m *PubKey) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.Key) + if l > 0 { + n += 1 + l + sovKeys(uint64(l)) + } + return n +} + +func (m *PrivKey) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.Key) + if l > 0 { + n += 1 + l + sovKeys(uint64(l)) + } + return n +} + +func sovKeys(x uint64) (n int) { + return (math_bits.Len64(x|1) + 6) / 7 +} +func sozKeys(x uint64) (n int) { + return sovKeys(uint64((x << 1) ^ uint64((int64(x) >> 63)))) +} +func (m *PubKey) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowKeys + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: PubKey: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: PubKey: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Key", 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 + } + m.Key = append(m.Key[:0], dAtA[iNdEx:postIndex]...) + if m.Key == nil { + m.Key = []byte{} + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipKeys(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthKeys + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *PrivKey) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowKeys + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: PrivKey: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: PrivKey: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Key", 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 + } + m.Key = append(m.Key[:0], dAtA[iNdEx:postIndex]...) + if m.Key == nil { + m.Key = []byte{} + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipKeys(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthKeys + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func skipKeys(dAtA []byte) (n int, err error) { + l := len(dAtA) + iNdEx := 0 + depth := 0 + for iNdEx < l { + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return 0, ErrIntOverflowKeys + } + if iNdEx >= l { + return 0, io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + wireType := int(wire & 0x7) + switch wireType { + case 0: + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return 0, ErrIntOverflowKeys + } + if iNdEx >= l { + return 0, io.ErrUnexpectedEOF + } + iNdEx++ + if dAtA[iNdEx-1] < 0x80 { + break + } + } + case 1: + iNdEx += 8 + case 2: + var length int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return 0, ErrIntOverflowKeys + } + if iNdEx >= l { + return 0, io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + length |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + if length < 0 { + return 0, ErrInvalidLengthKeys + } + iNdEx += length + case 3: + depth++ + case 4: + if depth == 0 { + return 0, ErrUnexpectedEndOfGroupKeys + } + depth-- + case 5: + iNdEx += 4 + default: + return 0, fmt.Errorf("proto: illegal wireType %d", wireType) + } + if iNdEx < 0 { + return 0, ErrInvalidLengthKeys + } + if depth == 0 { + return iNdEx, nil + } + } + return 0, io.ErrUnexpectedEOF +} + +var ( + ErrInvalidLengthKeys = fmt.Errorf("proto: negative length found during unmarshaling") + ErrIntOverflowKeys = fmt.Errorf("proto: integer overflow") + ErrUnexpectedEndOfGroupKeys = fmt.Errorf("proto: unexpected end of group") +) diff --git a/crypto/keys/sm2/sm2.go b/crypto/keys/sm2/sm2.go new file mode 100644 index 000000000000..0e8302eb31d0 --- /dev/null +++ b/crypto/keys/sm2/sm2.go @@ -0,0 +1,227 @@ +package sm2 + +import ( + "crypto/rand" + "crypto/sha256" + "crypto/subtle" + "fmt" + "io" + "math/big" + + "github.com/tjfoc/gmsm/sm2" + + "github.com/tendermint/tendermint/crypto" + tmsm2 "github.com/tendermint/tendermint/crypto/sm2" + "github.com/tendermint/tendermint/crypto/tmhash" + + "github.com/cosmos/cosmos-sdk/codec" + cryptotypes "github.com/cosmos/cosmos-sdk/crypto/types" + "github.com/cosmos/cosmos-sdk/types/errors" +) + +const ( + PrivKeyName = "cosmos/PrivKeySm2" + PubKeyName = "cosmos/PubKeySm2" + + PrivKeySize = 32 + PubKeySize = 33 + SignatureSize = 64 + + keyType = "sm2" +) + +var ( + _ cryptotypes.PrivKey = &PrivKey{} + _ codec.AminoMarshaler = &PrivKey{} +) + +// -------------------------------------------------------- +func (privKey PrivKey) Type() string { + return keyType +} + +// MarshalAmino overrides Amino binary marshalling. +func (privKey PrivKey) MarshalAmino() ([]byte, error) { + return privKey.Key, nil +} + +// UnmarshalAmino overrides Amino binary marshalling. +func (privKey *PrivKey) UnmarshalAmino(bz []byte) error { + if len(bz) != PrivKeySize { + return fmt.Errorf("invalid privkey size") + } + privKey.Key = bz + + return nil +} + +// MarshalAminoJSON overrides Amino JSON marshalling. +func (privKey PrivKey) MarshalAminoJSON() ([]byte, error) { + // When we marshal to Amino JSON, we don't marshal the "key" field itself, + // just its contents (i.e. the key bytes). + return privKey.MarshalAmino() +} + +// UnmarshalAminoJSON overrides Amino JSON marshalling. +func (privKey *PrivKey) UnmarshalAminoJSON(bz []byte) error { + return privKey.UnmarshalAmino(bz) +} + +func (privKey PrivKey) Bytes() []byte { + return privKey.Key +} + +func (privKey PrivKey) 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 PrivKey) PubKey() cryptotypes.PubKey { + priv := privKey.GetPrivateKey() + compPubkey := sm2.Compress(&priv.PublicKey) + + pubkeyBytes := make([]byte, PubKeySize) + copy(pubkeyBytes, compPubkey) + + return &PubKey{Key: pubkeyBytes} +} + +func (privKey PrivKey) Equals(other cryptotypes.LedgerPrivKey) bool { + if privKey.Type() != other.Type() { + return false + } + + return subtle.ConstantTimeCompare(privKey.Bytes(), other.Bytes()) == 1 +} + +func (privKey PrivKey) GetPrivateKey() *sm2.PrivateKey { + k := new(big.Int).SetBytes(privKey.Key[: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() PrivKey { + return genPrivKey(crypto.CReader()) +} + +func genPrivKey(rand io.Reader) PrivKey { + seed := make([]byte, 32) + if _, err := io.ReadFull(rand, seed); err != nil { + panic(err) + } + + privKey, err := sm2.GenerateKey(rand) + if err != nil { + panic(err) + } + + privKeyBytes := make([]byte, PrivKeySize) + copy(privKeyBytes, privKey.D.Bytes()) + + return PrivKey{Key: privKeyBytes} +} + +func GenPrivKeyFromSecret(secret []byte) PrivKey { + 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) + + return PrivKey{Key: k.Bytes()} +} + +var _ cryptotypes.PubKey = &PubKey{} +var _ codec.AminoMarshaler = &PubKey{} + +// -------------------------------------------------------- + +func (pubKey PubKey) Address() crypto.Address { + if len(pubKey.Key) != PubKeySize { + panic("pubkey is incorrect size") + } + return crypto.Address(tmhash.SumTruncated(pubKey.Key)) +} + +func (pubKey PubKey) Bytes() []byte { + return pubKey.Key +} + +func (pubKey *PubKey) VerifySignature(msg []byte, sig []byte) bool { + if len(sig) != SignatureSize { + return false + } + + publicKey := sm2.Decompress(pubKey.Key) + r := new(big.Int).SetBytes(sig[:32]) + s := new(big.Int).SetBytes(sig[32:]) + + return sm2.Sm2Verify(publicKey, msg, nil, r, s) +} + +func (pubKey PubKey) String() string { + return fmt.Sprintf("PubKeySm2{%X}", pubKey.Key) +} + +func (pubKey *PubKey) Type() string { + return keyType +} + +func (pubKey PubKey) Equals(other cryptotypes.PubKey) bool { + if pubKey.Type() != other.Type() { + return false + } + + return subtle.ConstantTimeCompare(pubKey.Bytes(), other.Bytes()) == 1 +} + +// MarshalAmino overrides Amino binary marshalling. +func (pubKey PubKey) MarshalAmino() ([]byte, error) { + return pubKey.Key, nil +} + +// UnmarshalAmino overrides Amino binary marshalling. +func (pubKey *PubKey) UnmarshalAmino(bz []byte) error { + if len(bz) != PubKeySize { + return errors.Wrap(errors.ErrInvalidPubKey, "invalid pubkey size") + } + pubKey.Key = bz + + return nil +} + +// MarshalAminoJSON overrides Amino JSON marshalling. +func (pubKey PubKey) MarshalAminoJSON() ([]byte, error) { + // When we marshal to Amino JSON, we don't marshal the "key" field itself, + // just its contents (i.e. the key bytes). + return pubKey.MarshalAmino() +} + +// UnmarshalAminoJSON overrides Amino JSON marshalling. +func (pubKey *PubKey) UnmarshalAminoJSON(bz []byte) error { + return pubKey.UnmarshalAmino(bz) +} + +// AsTmPubKey converts our own PubKey into a Tendermint ED25519 pubkey. +func (pubKey *PubKey) AsTmPubKey() crypto.PubKey { + var pubkey tmsm2.PubKeySm2 + copy(pubkey[:], pubKey.Key) + return pubkey +} diff --git a/crypto/keys/sm2/sm2_test.go b/crypto/keys/sm2/sm2_test.go new file mode 100644 index 000000000000..16078201fe2c --- /dev/null +++ b/crypto/keys/sm2/sm2_test.go @@ -0,0 +1,67 @@ +package sm2_test + +import ( + "fmt" + "testing" + + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + + "github.com/tendermint/tendermint/crypto" + + "github.com/cosmos/cosmos-sdk/crypto/keys/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.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 TestGenPrivKeySm2FromSecret(t *testing.T) { + a := sm2.GenPrivKeyFromSecret([]byte("mySecret1")) + b := sm2.GenPrivKeyFromSecret([]byte("mySecret1")) + c := sm2.GenPrivKeyFromSecret([]byte("mySecret2")) + + require.Equal(t, a, b) + require.NotEqual(t, a, c) +} diff --git a/crypto/ledger/encode_test.go b/crypto/ledger/encode_test.go index 7a60c3d147f5..1af44ac4e033 100644 --- a/crypto/ledger/encode_test.go +++ b/crypto/ledger/encode_test.go @@ -34,10 +34,12 @@ func ExamplePrintRegisteredTypes() { // | Type | Name | Prefix | Length | Notes | // | ---- | ---- | ------ | ----- | ------ | // | PrivKeyLedgerSecp256k1 | tendermint/PrivKeyLedgerSecp256k1 | 0x10CAB393 | variable | | + // | PubKeySm2 | tendermint/PubKeySm2 | 0xE7CD5A35 | 0x21 | | // | PubKey | tendermint/PubKeyEd25519 | 0x1624DE64 | variable | | // | PubKey | tendermint/PubKeySr25519 | 0x0DFB1005 | variable | | // | PubKey | tendermint/PubKeySecp256k1 | 0xEB5AE987 | variable | | // | PubKeyMultisigThreshold | tendermint/PubKeyMultisigThreshold | 0x22C1F7E2 | variable | | + // | PrivKeySm2 | tendermint/PrivKeySm2 | 0x5D16439B | 0x20 | | // | PrivKey | tendermint/PrivKeyEd25519 | 0xA3288910 | variable | | // | PrivKey | tendermint/PrivKeySr25519 | 0x2F82D78B | variable | | // | PrivKey | tendermint/PrivKeySecp256k1 | 0xE1B0F79B | variable | | diff --git a/go.mod b/go.mod index 4e5bfeb141f7..54902c50a1a2 100644 --- a/go.mod +++ b/go.mod @@ -53,6 +53,7 @@ require ( github.com/tendermint/go-amino v0.16.0 github.com/tendermint/tendermint v0.34.22 github.com/tendermint/tm-db v0.6.7 + github.com/tjfoc/gmsm v1.4.0 golang.org/x/crypto v0.0.0-20220722155217-630584e8d5aa golang.org/x/exp v0.0.0-20220722155223-a9213eeb770e google.golang.org/genproto v0.0.0-20220815135757-37a418bb8959 @@ -168,6 +169,8 @@ replace ( github.com/gogo/protobuf => github.com/regen-network/protobuf v1.3.3-alpha.regen.1 github.com/jhump/protoreflect => github.com/jhump/protoreflect v1.9.0 + + github.com/tendermint/tendermint => github.com/bianjieai/tendermint v0.34.22-irita-221107 ) retract v0.46.2 diff --git a/go.sum b/go.sum index 7d05b9dc6562..18250a467e95 100644 --- a/go.sum +++ b/go.sum @@ -145,6 +145,8 @@ github.com/bgentry/go-netrc v0.0.0-20140422174119-9fd32a8b3d3d h1:xDfNPAt8lFiC1U github.com/bgentry/go-netrc v0.0.0-20140422174119-9fd32a8b3d3d/go.mod h1:6QX/PXZ00z/TKoufEY6K/a0k6AhaJrQKdFe6OfVXsa4= github.com/bgentry/speakeasy v0.1.0 h1:ByYyxL9InA1OWqxJqqp2A5pYHUrCiAL6K3J+LKSsQkY= github.com/bgentry/speakeasy v0.1.0/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kBD4zp0CCIs= +github.com/bianjieai/tendermint v0.34.22-irita-221107 h1:LiFs3jH72dOh+wyF5MQE3RtU9qh429naGVP9xi3EJwg= +github.com/bianjieai/tendermint v0.34.22-irita-221107/go.mod h1:8ruxLM15hv1mPcrvETcq/4dnwMG4jpkhCu8jrp0pd2c= github.com/bmizerany/pat v0.0.0-20170815010413-6226ea591a40/go.mod h1:8rLXio+WjiTceGBHIoTvn60HIbs7Hm7bcHjyrSqYB9c= github.com/boltdb/bolt v1.3.1/go.mod h1:clJnj/oiGkjum5o1McbSZDSLxVThjynRyGBgiAx27Ps= github.com/btcsuite/btcd v0.0.0-20190115013929-ed77733ec07d/go.mod h1:d3C0AkH6BRcvO8T0UEPu53cnw4IbV63x1bEjildYhO0= @@ -944,8 +946,6 @@ github.com/tendermint/crypto v0.0.0-20191022145703-50d29ede1e15 h1:hqAk8riJvK4RM github.com/tendermint/crypto v0.0.0-20191022145703-50d29ede1e15/go.mod h1:z4YtwM70uOnk8h0pjJYlj3zdYwi9l03By6iAIF5j/Pk= github.com/tendermint/go-amino v0.16.0 h1:GyhmgQKvqF82e2oZeuMSp9JTN0N09emoSZlb2lyGa2E= github.com/tendermint/go-amino v0.16.0/go.mod h1:TQU0M1i/ImAo+tYpZi73AU3V/dKeCoMC9Sphe2ZwGME= -github.com/tendermint/tendermint v0.34.22 h1:XMhtC8s8QqJO4l/dn+TkQvevTRSow3Vixjclr41o+2Q= -github.com/tendermint/tendermint v0.34.22/go.mod h1:YpP5vBEAKUT4g6oyfjKgFeZmdB/GjkJAxfF+cgmJg6Y= github.com/tendermint/tm-db v0.6.7 h1:fE00Cbl0jayAoqlExN6oyQJ7fR/ZtoVOmvPJ//+shu8= github.com/tendermint/tm-db v0.6.7/go.mod h1:byQDzFkZV1syXr/ReXS808NxA2xvyuuVgXOJ/088L6I= github.com/tidwall/gjson v1.12.1/go.mod h1:/wbyibRr2FHMks5tjHJ5F8dMZh3AcwJEMf5vlfC0lxk= @@ -955,6 +955,8 @@ github.com/tidwall/pretty v1.2.0/go.mod h1:ITEVvHYasfjBbM0u2Pg8T2nJnzm8xPwvNhhso github.com/tidwall/sjson v1.2.4/go.mod h1:098SZ494YoMWPmMO6ct4dcFnqxwj9r/gF0Etp19pSNM= github.com/tinylib/msgp v1.0.2/go.mod h1:+d+yLhGm8mzTaHzB+wgMYrodPfmZrzkirds8fDWklFE= 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/tklauser/go-sysconf v0.3.5/go.mod h1:MkWzOF4RMCshBAMXuhXJs64Rte09mITnppBXY/rYEFI= github.com/tklauser/numcpus v0.2.2/go.mod h1:x3qojaO3uyYt0i56EW/VUYs7uBvdl2fkfZFu0T9wgjM= github.com/tmc/grpc-websocket-proxy v0.0.0-20170815181823-89b8d40f7ca8/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= @@ -1030,6 +1032,7 @@ golang.org/x/crypto v0.0.0-20200510223506-06a226fb4e37/go.mod h1:LzIPMQfyMNhhGPh golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20200728195943-123391ffb6de/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20200820211705-5c72a883971a/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-20210322153248-0c34fe9e7dc2/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4= golang.org/x/crypto v0.0.0-20210421170649-83a5a9bb288b/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4= diff --git a/proto/cosmos/auth/v1beta1/auth.proto b/proto/cosmos/auth/v1beta1/auth.proto index 963c6f15198d..ee343e893df0 100644 --- a/proto/cosmos/auth/v1beta1/auth.proto +++ b/proto/cosmos/auth/v1beta1/auth.proto @@ -44,4 +44,5 @@ message Params { uint64 tx_size_cost_per_byte = 3; uint64 sig_verify_cost_ed25519 = 4 [(gogoproto.customname) = "SigVerifyCostED25519"]; uint64 sig_verify_cost_secp256k1 = 5 [(gogoproto.customname) = "SigVerifyCostSecp256k1"]; + uint64 sig_verify_cost_sm2 = 6 [(gogoproto.customname) = "SigVerifyCostSm2", (gogoproto.moretags) = "yaml:\"sig_verify_cost_sm2\""]; } diff --git a/proto/cosmos/crypto/sm2/keys.proto b/proto/cosmos/crypto/sm2/keys.proto new file mode 100644 index 000000000000..a12600dfe35d --- /dev/null +++ b/proto/cosmos/crypto/sm2/keys.proto @@ -0,0 +1,22 @@ +syntax = "proto3"; +package cosmos.crypto.sm2; + +import "gogoproto/gogo.proto"; + +option go_package = "github.com/cosmos/cosmos-sdk/crypto/keys/sm2"; + +// PubKey defines a secp256k1 public key +// Key is the compressed form of the pubkey. The first byte depends is a 0x02 byte +// if the y-coordinate is the lexicographically largest of the two associated with +// the x-coordinate. Otherwise the first byte is a 0x03. +// This prefix is followed with the x-coordinate. +message PubKey { + option (gogoproto.goproto_stringer) = false; + + bytes key = 1; +} + +// PrivKey defines a secp256k1 private key. +message PrivKey { + bytes key = 1; +} diff --git a/simapp/simd/cmd/testnet.go b/simapp/simd/cmd/testnet.go index 10fde021701c..f39f6adf7198 100644 --- a/simapp/simd/cmd/testnet.go +++ b/simapp/simd/cmd/testnet.go @@ -79,7 +79,7 @@ func addTestnetFlagsToCmd(cmd *cobra.Command) { cmd.Flags().StringP(flagOutputDir, "o", "./.testnets", "Directory to store initialization data for the testnet") cmd.Flags().String(flags.FlagChainID, "", "genesis file chain-id, if left blank will be randomly created") cmd.Flags().String(server.FlagMinGasPrices, fmt.Sprintf("0.000006%s", sdk.DefaultBondDenom), "Minimum gas prices to accept for transactions; All fees in a tx must meet this minimum (e.g. 0.01photino,0.001stake)") - cmd.Flags().String(flags.FlagKeyAlgorithm, string(hd.Secp256k1Type), "Key signing algorithm to generate keys for") + cmd.Flags().String(flags.FlagKeyAlgorithm, string(hd.Sm2Type), "Key signing algorithm to generate keys for") } // NewTestnetCmd creates a root testnet command with subcommands to run an in-process testnet or initialize diff --git a/testutil/network/network.go b/testutil/network/network.go index e08787435037..4f1e685e3b72 100644 --- a/testutil/network/network.go +++ b/testutil/network/network.go @@ -121,7 +121,7 @@ func DefaultConfig() Config { BondedTokens: sdk.TokensFromConsensusPower(100, sdk.DefaultPowerReduction), PruningStrategy: pruningtypes.PruningOptionNothing, CleanupDir: true, - SigningAlgo: string(hd.Secp256k1Type), + SigningAlgo: string(hd.Sm2Type), KeyringOptions: []keyring.Option{}, PrintMnemonic: false, } diff --git a/testutil/testdata/tx.go b/testutil/testdata/tx.go index d16dd06d0ebd..65ed1e412da8 100644 --- a/testutil/testdata/tx.go +++ b/testutil/testdata/tx.go @@ -36,7 +36,7 @@ func NewTestFeeAmount() sdk.Coins { // NewTestGasLimit is a test fee gas limit. func NewTestGasLimit() uint64 { - return 200000 + return 400000 } // NewTestMsg creates a message for testing with the given signers. diff --git a/types/abci.go b/types/abci.go index 8f71362eda6d..a95dcf5fb077 100644 --- a/types/abci.go +++ b/types/abci.go @@ -18,4 +18,4 @@ type BeginBlocker func(ctx Context, req abci.RequestBeginBlock) abci.ResponseBeg type EndBlocker func(ctx Context, req abci.RequestEndBlock) abci.ResponseEndBlock // PeerFilter responds to p2p filtering queries from Tendermint -type PeerFilter func(info string) abci.ResponseQuery +type PeerFilter func(ctx Context, info string) abci.ResponseQuery diff --git a/x/auth/ante/ante_test.go b/x/auth/ante/ante_test.go index f2bc8f83a726..f93ce0f89fd4 100644 --- a/x/auth/ante/ante_test.go +++ b/x/auth/ante/ante_test.go @@ -1110,9 +1110,9 @@ func (suite *AnteTestSuite) TestAnteHandlerReCheck() { name string params types.Params }{ - {"memo size check", types.NewParams(1, types.DefaultTxSigLimit, types.DefaultTxSizeCostPerByte, types.DefaultSigVerifyCostED25519, types.DefaultSigVerifyCostSecp256k1)}, - {"txsize check", types.NewParams(types.DefaultMaxMemoCharacters, types.DefaultTxSigLimit, 10000000, types.DefaultSigVerifyCostED25519, types.DefaultSigVerifyCostSecp256k1)}, - {"sig verify cost check", types.NewParams(types.DefaultMaxMemoCharacters, types.DefaultTxSigLimit, types.DefaultTxSizeCostPerByte, types.DefaultSigVerifyCostED25519, 100000000)}, + {"memo size check", types.NewParams(1, types.DefaultTxSigLimit, types.DefaultTxSizeCostPerByte, types.DefaultSigVerifyCostED25519, types.DefaultSigVerifyCostSecp256k1, types.DefaultSigVerifyCostSm2)}, + {"txsize check", types.NewParams(types.DefaultMaxMemoCharacters, types.DefaultTxSigLimit, 10000000, types.DefaultSigVerifyCostED25519, types.DefaultSigVerifyCostSecp256k1, types.DefaultSigVerifyCostSm2)}, + {"sig verify cost check", types.NewParams(types.DefaultMaxMemoCharacters, types.DefaultTxSigLimit, types.DefaultTxSizeCostPerByte, types.DefaultSigVerifyCostED25519, 100000000, types.DefaultSigVerifyCostSm2)}, } for _, tc := range testCases { // set testcase parameters diff --git a/x/auth/ante/basic.go b/x/auth/ante/basic.go index 52c219f79e4d..e6a9af4f4594 100644 --- a/x/auth/ante/basic.go +++ b/x/auth/ante/basic.go @@ -113,16 +113,16 @@ func (cgts ConsumeTxSizeGasDecorator) AnteHandle(ctx sdk.Context, tx sdk.Tx, sim acc := cgts.ak.GetAccount(ctx, signer) - // use placeholder simSecp256k1Pubkey if sig is nil + // use placeholder simSm2Pubkey if sig is nil if acc == nil || acc.GetPubKey() == nil { - pubkey = simSecp256k1Pubkey + pubkey = simSm2Pubkey } else { pubkey = acc.GetPubKey() } // use stdsignature to mock the size of a full signature simSig := legacytx.StdSignature{ //nolint:staticcheck // this will be removed when proto is ready - Signature: simSecp256k1Sig[:], + Signature: simSm2Sig[:], PubKey: pubkey, } diff --git a/x/auth/ante/sigverify.go b/x/auth/ante/sigverify.go index a24af86667e0..8e181e8abac7 100644 --- a/x/auth/ante/sigverify.go +++ b/x/auth/ante/sigverify.go @@ -10,6 +10,7 @@ import ( kmultisig "github.com/cosmos/cosmos-sdk/crypto/keys/multisig" "github.com/cosmos/cosmos-sdk/crypto/keys/secp256k1" "github.com/cosmos/cosmos-sdk/crypto/keys/secp256r1" + "github.com/cosmos/cosmos-sdk/crypto/keys/sm2" cryptotypes "github.com/cosmos/cosmos-sdk/crypto/types" "github.com/cosmos/cosmos-sdk/crypto/types/multisig" sdk "github.com/cosmos/cosmos-sdk/types" @@ -22,18 +23,16 @@ import ( var ( // simulation signature values used to estimate gas consumption - key = make([]byte, secp256k1.PubKeySize) - simSecp256k1Pubkey = &secp256k1.PubKey{Key: key} - simSecp256k1Sig [64]byte + simSm2Pubkey *sm2.PubKey + simSm2Sig [64]byte _ authsigning.SigVerifiableTx = (*legacytx.StdTx)(nil) // assert StdTx implements SigVerifiableTx ) func init() { - // This decodes a valid hex string into a sepc256k1Pubkey for use in transaction simulation + // This decodes a valid hex string into a simSm2Pubkey for use in transaction simulation bz, _ := hex.DecodeString("035AD6810A47F073553FF30D2FCC7E0D3B1C0B74B61A1AAA2582344037151E143A") - copy(key, bz) - simSecp256k1Pubkey.Key = key + simSm2Pubkey = &sm2.PubKey{Key: bz} } // SignatureVerificationGasConsumer is the type of function that is used to both @@ -72,7 +71,7 @@ func (spkd SetPubKeyDecorator) AnteHandle(ctx sdk.Context, tx sdk.Tx, simulate b if !simulate { continue } - pk = simSecp256k1Pubkey + pk = simSm2Pubkey } // Only make check if simulate=false if !simulate && !bytes.Equal(pk.Address(), signers[i]) { @@ -175,7 +174,7 @@ func (sgcd SigGasConsumeDecorator) AnteHandle(ctx sdk.Context, tx sdk.Tx, simula // shall consume the largest amount, i.e. it takes more gas to verify // secp256k1 keys than ed25519 ones. if simulate && pubKey == nil { - pubKey = simSecp256k1Pubkey + pubKey = simSm2Pubkey } // make a SignatureV2 with PubKey filled in from above @@ -265,11 +264,18 @@ func (svd SigVerificationDecorator) AnteHandle(ctx sdk.Context, tx sdk.Tx, simul } // Check account sequence number. - if sig.Sequence != acc.GetSequence() { - return ctx, sdkerrors.Wrapf( - sdkerrors.ErrWrongSequence, - "account sequence mismatch, expected %d, got %d", acc.GetSequence(), sig.Sequence, - ) + // When using Amino StdSignatures, we actually don't have the Sequence in + // the SignatureV2 struct (it's only in the SignDoc). In this case, we + // cannot check sequence directly, and must do it via signature + // verification (in the VerifySignature call below). + onlyAminoSigners := OnlyLegacyAminoSigners(sig.Data) + if !onlyAminoSigners { + if sig.Sequence != acc.GetSequence() { + return ctx, sdkerrors.Wrapf( + sdkerrors.ErrWrongSequence, + "account sequence mismatch, expected %d, got %d", acc.GetSequence(), sig.Sequence, + ) + } } // retrieve signer data @@ -392,6 +398,9 @@ func DefaultSigVerificationGasConsumer( ) error { pubkey := sig.PubKey switch pubkey := pubkey.(type) { + case *sm2.PubKey: + meter.ConsumeGas(params.SigVerifyCostSm2, "ante verify: sm2") + return nil case *ed25519.PubKey: meter.ConsumeGas(params.SigVerifyCostED25519, "ante verify: ed25519") return sdkerrors.Wrap(sdkerrors.ErrInvalidPubKey, "ED25519 public keys are unsupported") diff --git a/x/auth/ante/sigverify_test.go b/x/auth/ante/sigverify_test.go index c002818d3b26..e1bf15b1d725 100644 --- a/x/auth/ante/sigverify_test.go +++ b/x/auth/ante/sigverify_test.go @@ -9,6 +9,7 @@ import ( kmultisig "github.com/cosmos/cosmos-sdk/crypto/keys/multisig" "github.com/cosmos/cosmos-sdk/crypto/keys/secp256k1" "github.com/cosmos/cosmos-sdk/crypto/keys/secp256r1" + "github.com/cosmos/cosmos-sdk/crypto/keys/sm2" cryptotypes "github.com/cosmos/cosmos-sdk/crypto/types" "github.com/cosmos/cosmos-sdk/crypto/types/multisig" "github.com/cosmos/cosmos-sdk/simapp" @@ -96,6 +97,7 @@ func (suite *AnteTestSuite) TestConsumeSignatureVerificationGas() { shouldErr bool }{ {"PubKeyEd25519", args{sdk.NewInfiniteGasMeter(), nil, ed25519.GenPrivKey().PubKey(), params}, p.SigVerifyCostED25519, true}, + {"PubKeySm2", args{sdk.NewInfiniteGasMeter(), nil, sm2.GenPrivKey().PubKey(), params}, types.DefaultSigVerifyCostSm2, false}, {"PubKeySecp256k1", args{sdk.NewInfiniteGasMeter(), nil, secp256k1.GenPrivKey().PubKey(), params}, p.SigVerifyCostSecp256k1, false}, {"PubKeySecp256r1", args{sdk.NewInfiniteGasMeter(), nil, skR1.PubKey(), params}, p.SigVerifyCostSecp256r1(), false}, {"Multisig", args{sdk.NewInfiniteGasMeter(), multisignature1, multisigKey1, params}, expectedCost1, false}, diff --git a/x/auth/simulation/genesis.go b/x/auth/simulation/genesis.go index 4b31bf7d49e0..3d03aa82e771 100644 --- a/x/auth/simulation/genesis.go +++ b/x/auth/simulation/genesis.go @@ -19,6 +19,7 @@ const ( TxSizeCostPerByte = "tx_size_cost_per_byte" SigVerifyCostED25519 = "sig_verify_cost_ed25519" SigVerifyCostSECP256K1 = "sig_verify_cost_secp256k1" + SigVerifyCostSm2 = "sig_verify_cost_sm2" ) // RandomGenesisAccounts defines the default RandomGenesisAccountsFn used on the SDK. @@ -87,6 +88,11 @@ func GenSigVerifyCostSECP256K1(r *rand.Rand) uint64 { return uint64(simulation.RandIntBetween(r, 500, 1000)) } +// GenSigVerifyCostSM2 randomized SigVerifyCostSM2 +func GenSigVerifyCostSM2(r *rand.Rand) uint64 { + return uint64(simulation.RandIntBetween(r, 500, 1000)) +} + // RandomizedGenState generates a random GenesisState for auth func RandomizedGenState(simState *module.SimulationState, randGenAccountsFn types.RandomGenesisAccountsFn) { var maxMemoChars uint64 @@ -119,8 +125,20 @@ func RandomizedGenState(simState *module.SimulationState, randGenAccountsFn type func(r *rand.Rand) { sigVerifyCostSECP256K1 = GenSigVerifyCostSECP256K1(r) }, ) - params := types.NewParams(maxMemoChars, txSigLimit, txSizeCostPerByte, - sigVerifyCostED25519, sigVerifyCostSECP256K1) + var sigVerifyCostSm2 uint64 + simState.AppParams.GetOrGenerate( + simState.Cdc, SigVerifyCostSm2, &sigVerifyCostSECP256K1, simState.Rand, + func(r *rand.Rand) { sigVerifyCostSm2 = GenSigVerifyCostSM2(r) }, + ) + + params := types.NewParams( + maxMemoChars, + txSigLimit, + txSizeCostPerByte, + sigVerifyCostED25519, + sigVerifyCostSECP256K1, + sigVerifyCostSm2, + ) genesisAccs := randGenAccountsFn(simState) authGenesis := types.NewGenesisState(params, genesisAccs) diff --git a/x/auth/types/auth.pb.go b/x/auth/types/auth.pb.go index 7391b2188ae4..0cc9954aa01d 100644 --- a/x/auth/types/auth.pb.go +++ b/x/auth/types/auth.pb.go @@ -113,6 +113,7 @@ type Params struct { TxSizeCostPerByte uint64 `protobuf:"varint,3,opt,name=tx_size_cost_per_byte,json=txSizeCostPerByte,proto3" json:"tx_size_cost_per_byte,omitempty"` SigVerifyCostED25519 uint64 `protobuf:"varint,4,opt,name=sig_verify_cost_ed25519,json=sigVerifyCostEd25519,proto3" json:"sig_verify_cost_ed25519,omitempty"` SigVerifyCostSecp256k1 uint64 `protobuf:"varint,5,opt,name=sig_verify_cost_secp256k1,json=sigVerifyCostSecp256k1,proto3" json:"sig_verify_cost_secp256k1,omitempty"` + SigVerifyCostSm2 uint64 `protobuf:"varint,6,opt,name=sig_verify_cost_sm2,json=sigVerifyCostSm2,proto3" json:"sig_verify_cost_sm2,omitempty" yaml:"sig_verify_cost_sm2"` } func (m *Params) Reset() { *m = Params{} } @@ -182,6 +183,13 @@ func (m *Params) GetSigVerifyCostSecp256k1() uint64 { return 0 } +func (m *Params) GetSigVerifyCostSm2() uint64 { + if m != nil { + return m.SigVerifyCostSm2 + } + return 0 +} + func init() { proto.RegisterType((*BaseAccount)(nil), "cosmos.auth.v1beta1.BaseAccount") proto.RegisterType((*ModuleAccount)(nil), "cosmos.auth.v1beta1.ModuleAccount") @@ -191,46 +199,48 @@ func init() { func init() { proto.RegisterFile("cosmos/auth/v1beta1/auth.proto", fileDescriptor_7e1f7e915d020d2d) } var fileDescriptor_7e1f7e915d020d2d = []byte{ - // 609 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x6c, 0x53, 0x3f, 0x6f, 0xd3, 0x4e, - 0x18, 0x8e, 0xdb, 0xfc, 0xfa, 0xe7, 0xd2, 0x56, 0xea, 0x35, 0xbf, 0xe2, 0x66, 0xb0, 0xad, 0x4a, - 0x48, 0x41, 0x22, 0x0e, 0x09, 0x2a, 0x12, 0xdd, 0xea, 0x82, 0x50, 0x05, 0x85, 0xca, 0x11, 0x0c, - 0x2c, 0xd6, 0xd9, 0x79, 0xeb, 0x9e, 0x9a, 0xf3, 0x19, 0xdf, 0xb9, 0x8a, 0xfb, 0x09, 0x18, 0x19, - 0x19, 0xfb, 0x01, 0x18, 0x3b, 0x33, 0xa3, 0x4e, 0x15, 0x13, 0x53, 0x84, 0xd2, 0x01, 0xc4, 0xa7, - 0x40, 0xb9, 0x73, 0xaa, 0x16, 0x75, 0xf2, 0xbd, 0xcf, 0xf3, 0xdc, 0xf3, 0xfe, 0xf3, 0x21, 0x2b, - 0xe2, 0x82, 0x71, 0xd1, 0x26, 0xb9, 0x3c, 0x6a, 0x9f, 0x74, 0x42, 0x90, 0xa4, 0xa3, 0x02, 0x37, - 0xcd, 0xb8, 0xe4, 0x78, 0x4d, 0xf3, 0xae, 0x82, 0x4a, 0xbe, 0xb1, 0xa1, 0xc1, 0x40, 0x49, 0xda, - 0xa5, 0x42, 0x05, 0x8d, 0x7a, 0xcc, 0x63, 0xae, 0xf1, 0xc9, 0xa9, 0x44, 0x37, 0x62, 0xce, 0xe3, - 0x01, 0xb4, 0x55, 0x14, 0xe6, 0x87, 0x6d, 0x92, 0x14, 0x9a, 0xda, 0xfc, 0x65, 0xa0, 0x9a, 0x47, - 0x04, 0xec, 0x44, 0x11, 0xcf, 0x13, 0x89, 0xbb, 0x68, 0x9e, 0xf4, 0xfb, 0x19, 0x08, 0x61, 0x1a, - 0x8e, 0xd1, 0x5c, 0xf4, 0xcc, 0xef, 0xe7, 0xad, 0x7a, 0x99, 0x63, 0x47, 0x33, 0x3d, 0x99, 0xd1, - 0x24, 0xf6, 0xa7, 0x42, 0xfc, 0x02, 0xcd, 0xa7, 0x79, 0x18, 0x1c, 0x43, 0x61, 0xce, 0x38, 0x46, - 0xb3, 0xd6, 0xad, 0xbb, 0x3a, 0xa1, 0x3b, 0x4d, 0xe8, 0xee, 0x24, 0x85, 0x67, 0xfe, 0x19, 0xd9, - 0xf5, 0x34, 0x0f, 0x07, 0x34, 0x9a, 0x68, 0x1f, 0x72, 0x46, 0x25, 0xb0, 0x54, 0x16, 0xfe, 0x5c, - 0x9a, 0x87, 0x2f, 0xa1, 0xc0, 0xf7, 0xd1, 0x0a, 0xd1, 0x75, 0x04, 0x49, 0xce, 0x42, 0xc8, 0xcc, - 0x59, 0xc7, 0x68, 0x56, 0xfd, 0xe5, 0x12, 0x7d, 0xad, 0x40, 0xdc, 0x40, 0x0b, 0x02, 0x3e, 0xe4, - 0x90, 0x44, 0x60, 0x56, 0x95, 0xe0, 0x3a, 0xde, 0x36, 0x3f, 0x9e, 0xd9, 0x95, 0xcf, 0x67, 0x76, - 0xe5, 0xf7, 0x99, 0x5d, 0xb9, 0x38, 0x6f, 0x2d, 0x94, 0x8d, 0xed, 0x6d, 0x7e, 0x31, 0xd0, 0xf2, - 0x3e, 0xef, 0xe7, 0x83, 0xeb, 0x5e, 0xf7, 0xd0, 0x52, 0x48, 0x04, 0x04, 0xa5, 0xbb, 0x6a, 0xb8, - 0xd6, 0x75, 0xdc, 0x3b, 0x66, 0xee, 0xde, 0x98, 0x91, 0x57, 0xbd, 0x1c, 0xd9, 0x86, 0x5f, 0x0b, - 0x6f, 0x8c, 0x0d, 0xa3, 0x6a, 0x42, 0x18, 0xa8, 0xfe, 0x17, 0x7d, 0x75, 0xc6, 0x0e, 0xaa, 0xa5, - 0x90, 0x31, 0x2a, 0x04, 0xe5, 0x89, 0x30, 0x67, 0x9d, 0xd9, 0xe6, 0xa2, 0x7f, 0x13, 0xda, 0x6e, - 0x4c, 0x8b, 0xbd, 0x38, 0x6f, 0xad, 0xdc, 0xaa, 0x6d, 0x6f, 0xf3, 0xeb, 0x0c, 0x9a, 0x3b, 0x20, - 0x19, 0x61, 0x02, 0xbb, 0x68, 0x8d, 0x91, 0x61, 0xc0, 0x80, 0xf1, 0x20, 0x3a, 0x22, 0x19, 0x89, - 0x24, 0x64, 0x7a, 0x3f, 0x55, 0x7f, 0x95, 0x91, 0xe1, 0x3e, 0x30, 0xbe, 0x7b, 0x4d, 0x60, 0x07, - 0x2d, 0xc9, 0x61, 0x20, 0x68, 0x1c, 0x0c, 0x28, 0xa3, 0x52, 0x15, 0x55, 0xf5, 0x91, 0x1c, 0xf6, - 0x68, 0xfc, 0x6a, 0x82, 0xe0, 0x47, 0xe8, 0x7f, 0xa5, 0x38, 0x85, 0x20, 0xe2, 0x42, 0x06, 0x29, - 0x64, 0x41, 0x58, 0x48, 0x28, 0xe7, 0xbd, 0x3a, 0x91, 0x9e, 0xc2, 0x2e, 0x17, 0xf2, 0x00, 0x32, - 0xaf, 0x90, 0x80, 0xdf, 0xa0, 0x7b, 0x13, 0xc3, 0x13, 0xc8, 0xe8, 0x61, 0xa1, 0x2f, 0x41, 0xbf, - 0xbb, 0xb5, 0xd5, 0x79, 0xaa, 0x57, 0xe0, 0x99, 0xe3, 0x91, 0x5d, 0xef, 0xd1, 0xf8, 0x9d, 0x52, - 0x4c, 0xae, 0x3e, 0x7f, 0xa6, 0x78, 0xbf, 0x2e, 0x6e, 0xa1, 0xfa, 0x16, 0x7e, 0x8b, 0x36, 0xfe, - 0x35, 0x14, 0x10, 0xa5, 0xdd, 0xad, 0x27, 0xc7, 0x1d, 0xf3, 0x3f, 0x65, 0xd9, 0x18, 0x8f, 0xec, - 0xf5, 0x5b, 0x96, 0xbd, 0xa9, 0xc2, 0x5f, 0x17, 0x77, 0xe2, 0xdb, 0x0b, 0xe5, 0xee, 0x0d, 0x6f, - 0xf7, 0xdb, 0xd8, 0x32, 0x2e, 0xc7, 0x96, 0xf1, 0x73, 0x6c, 0x19, 0x9f, 0xae, 0xac, 0xca, 0xe5, - 0x95, 0x55, 0xf9, 0x71, 0x65, 0x55, 0xde, 0x3f, 0x88, 0xa9, 0x3c, 0xca, 0x43, 0x37, 0xe2, 0xac, - 0x7c, 0x3d, 0xe5, 0xa7, 0x25, 0xfa, 0xc7, 0xed, 0xa1, 0x7e, 0x8c, 0xb2, 0x48, 0x41, 0x84, 0x73, - 0xea, 0x0f, 0x7e, 0xfc, 0x37, 0x00, 0x00, 0xff, 0xff, 0x35, 0x25, 0xef, 0x58, 0xa8, 0x03, 0x00, - 0x00, + // 646 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x6c, 0x53, 0x41, 0x6f, 0xd3, 0x4a, + 0x10, 0x8e, 0x5f, 0xf2, 0xd2, 0x76, 0xd3, 0x56, 0xed, 0x36, 0xaf, 0xcf, 0xcd, 0xc1, 0xb6, 0x22, + 0x3d, 0x29, 0x4f, 0x22, 0x0e, 0x31, 0x2a, 0x12, 0xb9, 0xd5, 0x05, 0xa1, 0x0a, 0x0a, 0x95, 0x23, + 0x38, 0x70, 0xb1, 0xd6, 0xce, 0xd4, 0xb5, 0x9a, 0xf5, 0x1a, 0xef, 0xba, 0x8a, 0xfb, 0x0b, 0x38, + 0x72, 0xe4, 0x58, 0xee, 0x1c, 0xfb, 0x23, 0x50, 0x4f, 0x15, 0x27, 0x4e, 0x11, 0x4a, 0x0f, 0x20, + 0x8e, 0xfc, 0x02, 0x94, 0xb5, 0x53, 0x35, 0xa5, 0x27, 0xef, 0x7c, 0xdf, 0x37, 0xdf, 0xce, 0xcc, + 0x7a, 0x90, 0xe6, 0x33, 0x4e, 0x19, 0xef, 0x90, 0x54, 0x1c, 0x75, 0x4e, 0xba, 0x1e, 0x08, 0xd2, + 0x95, 0x81, 0x19, 0x27, 0x4c, 0x30, 0xbc, 0x91, 0xf3, 0xa6, 0x84, 0x0a, 0xbe, 0xb1, 0x95, 0x83, + 0xae, 0x94, 0x74, 0x0a, 0x85, 0x0c, 0x1a, 0xf5, 0x80, 0x05, 0x2c, 0xc7, 0xa7, 0xa7, 0x02, 0xdd, + 0x0a, 0x18, 0x0b, 0x86, 0xd0, 0x91, 0x91, 0x97, 0x1e, 0x76, 0x48, 0x94, 0xe5, 0x54, 0xf3, 0xbb, + 0x82, 0x6a, 0x36, 0xe1, 0xb0, 0xe3, 0xfb, 0x2c, 0x8d, 0x04, 0xb6, 0xd0, 0x02, 0x19, 0x0c, 0x12, + 0xe0, 0x5c, 0x55, 0x0c, 0xa5, 0xb5, 0x64, 0xab, 0x5f, 0xce, 0xdb, 0xf5, 0xe2, 0x8e, 0x9d, 0x9c, + 0xe9, 0x8b, 0x24, 0x8c, 0x02, 0x67, 0x26, 0xc4, 0x4f, 0xd1, 0x42, 0x9c, 0x7a, 0xee, 0x31, 0x64, + 0xea, 0x5f, 0x86, 0xd2, 0xaa, 0x59, 0x75, 0x33, 0xbf, 0xd0, 0x9c, 0x5d, 0x68, 0xee, 0x44, 0x99, + 0xad, 0xfe, 0x1c, 0xeb, 0xf5, 0x38, 0xf5, 0x86, 0xa1, 0x3f, 0xd5, 0xde, 0x63, 0x34, 0x14, 0x40, + 0x63, 0x91, 0x39, 0xd5, 0x38, 0xf5, 0x9e, 0x41, 0x86, 0xff, 0x43, 0xab, 0x24, 0xaf, 0xc3, 0x8d, + 0x52, 0xea, 0x41, 0xa2, 0x96, 0x0d, 0xa5, 0x55, 0x71, 0x56, 0x0a, 0xf4, 0x85, 0x04, 0x71, 0x03, + 0x2d, 0x72, 0x78, 0x9b, 0x42, 0xe4, 0x83, 0x5a, 0x91, 0x82, 0xeb, 0xb8, 0xa7, 0xbe, 0x3b, 0xd3, + 0x4b, 0x1f, 0xce, 0xf4, 0xd2, 0x8f, 0x33, 0xbd, 0x74, 0x71, 0xde, 0x5e, 0x2c, 0x1a, 0xdb, 0x6b, + 0x7e, 0x52, 0xd0, 0xca, 0x3e, 0x1b, 0xa4, 0xc3, 0xeb, 0x5e, 0xf7, 0xd0, 0xb2, 0x47, 0x38, 0xb8, + 0x85, 0xbb, 0x6c, 0xb8, 0x66, 0x19, 0xe6, 0x1d, 0x33, 0x37, 0x6f, 0xcc, 0xc8, 0xae, 0x5c, 0x8e, + 0x75, 0xc5, 0xa9, 0x79, 0x37, 0xc6, 0x86, 0x51, 0x25, 0x22, 0x14, 0x64, 0xff, 0x4b, 0x8e, 0x3c, + 0x63, 0x03, 0xd5, 0x62, 0x48, 0x68, 0xc8, 0x79, 0xc8, 0x22, 0xae, 0x96, 0x8d, 0x72, 0x6b, 0xc9, + 0xb9, 0x09, 0xf5, 0x1a, 0xb3, 0x62, 0x2f, 0xce, 0xdb, 0xab, 0x73, 0xb5, 0xed, 0x35, 0x3f, 0x96, + 0x51, 0xf5, 0x80, 0x24, 0x84, 0x72, 0x6c, 0xa2, 0x0d, 0x4a, 0x46, 0x2e, 0x05, 0xca, 0x5c, 0xff, + 0x88, 0x24, 0xc4, 0x17, 0x90, 0xe4, 0xef, 0x53, 0x71, 0xd6, 0x29, 0x19, 0xed, 0x03, 0x65, 0xbb, + 0xd7, 0x04, 0x36, 0xd0, 0xb2, 0x18, 0xb9, 0x3c, 0x0c, 0xdc, 0x61, 0x48, 0x43, 0x21, 0x8b, 0xaa, + 0x38, 0x48, 0x8c, 0xfa, 0x61, 0xf0, 0x7c, 0x8a, 0xe0, 0xfb, 0xe8, 0x1f, 0xa9, 0x38, 0x05, 0xd7, + 0x67, 0x5c, 0xb8, 0x31, 0x24, 0xae, 0x97, 0x09, 0x28, 0xe6, 0xbd, 0x3e, 0x95, 0x9e, 0xc2, 0x2e, + 0xe3, 0xe2, 0x00, 0x12, 0x3b, 0x13, 0x80, 0x5f, 0xa2, 0x7f, 0xa7, 0x86, 0x27, 0x90, 0x84, 0x87, + 0x59, 0x9e, 0x04, 0x03, 0x6b, 0x7b, 0xbb, 0xfb, 0x28, 0x7f, 0x02, 0x5b, 0x9d, 0x8c, 0xf5, 0x7a, + 0x3f, 0x0c, 0x5e, 0x4b, 0xc5, 0x34, 0xf5, 0xc9, 0x63, 0xc9, 0x3b, 0x75, 0x3e, 0x87, 0xe6, 0x59, + 0xf8, 0x15, 0xda, 0xba, 0x6d, 0xc8, 0xc1, 0x8f, 0xad, 0xed, 0x87, 0xc7, 0x5d, 0xf5, 0x6f, 0x69, + 0xd9, 0x98, 0x8c, 0xf5, 0xcd, 0x39, 0xcb, 0xfe, 0x4c, 0xe1, 0x6c, 0xf2, 0x3b, 0x71, 0x4c, 0xd0, + 0xc6, 0x1f, 0xb6, 0xd4, 0x52, 0xab, 0xd2, 0xd0, 0x9a, 0x8c, 0xf5, 0xb5, 0x79, 0x43, 0x6a, 0xfd, + 0x1a, 0xeb, 0x8d, 0x8c, 0xd0, 0x61, 0xaf, 0x79, 0x47, 0x62, 0xd3, 0x59, 0xe3, 0xb7, 0xf4, 0xbd, + 0xc5, 0xe2, 0xf7, 0x52, 0xec, 0xdd, 0xcf, 0x13, 0x4d, 0xb9, 0x9c, 0x68, 0xca, 0xb7, 0x89, 0xa6, + 0xbc, 0xbf, 0xd2, 0x4a, 0x97, 0x57, 0x5a, 0xe9, 0xeb, 0x95, 0x56, 0x7a, 0xf3, 0x7f, 0x10, 0x8a, + 0xa3, 0xd4, 0x33, 0x7d, 0x46, 0x8b, 0x05, 0x2d, 0x3e, 0x6d, 0x3e, 0x38, 0xee, 0x8c, 0xf2, 0x7d, + 0x17, 0x59, 0x0c, 0xdc, 0xab, 0xca, 0x25, 0x79, 0xf0, 0x3b, 0x00, 0x00, 0xff, 0xff, 0xec, 0x9c, + 0x06, 0x37, 0x0b, 0x04, 0x00, 0x00, } func (this *Params) Equal(that interface{}) bool { @@ -267,6 +277,9 @@ func (this *Params) Equal(that interface{}) bool { if this.SigVerifyCostSecp256k1 != that1.SigVerifyCostSecp256k1 { return false } + if this.SigVerifyCostSm2 != that1.SigVerifyCostSm2 { + return false + } return true } func (m *BaseAccount) Marshal() (dAtA []byte, err error) { @@ -392,6 +405,11 @@ func (m *Params) MarshalToSizedBuffer(dAtA []byte) (int, error) { _ = i var l int _ = l + if m.SigVerifyCostSm2 != 0 { + i = encodeVarintAuth(dAtA, i, uint64(m.SigVerifyCostSm2)) + i-- + dAtA[i] = 0x30 + } if m.SigVerifyCostSecp256k1 != 0 { i = encodeVarintAuth(dAtA, i, uint64(m.SigVerifyCostSecp256k1)) i-- @@ -498,6 +516,9 @@ func (m *Params) Size() (n int) { if m.SigVerifyCostSecp256k1 != 0 { n += 1 + sovAuth(uint64(m.SigVerifyCostSecp256k1)) } + if m.SigVerifyCostSm2 != 0 { + n += 1 + sovAuth(uint64(m.SigVerifyCostSm2)) + } return n } @@ -937,6 +958,25 @@ func (m *Params) Unmarshal(dAtA []byte) error { break } } + case 6: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field SigVerifyCostSm2", wireType) + } + m.SigVerifyCostSm2 = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowAuth + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.SigVerifyCostSm2 |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } default: iNdEx = preIndex skippy, err := skipAuth(dAtA[iNdEx:]) diff --git a/x/auth/types/params.go b/x/auth/types/params.go index a3d9b79da559..8f92ddbb2989 100644 --- a/x/auth/types/params.go +++ b/x/auth/types/params.go @@ -15,6 +15,7 @@ const ( DefaultTxSizeCostPerByte uint64 = 10 DefaultSigVerifyCostED25519 uint64 = 590 DefaultSigVerifyCostSecp256k1 uint64 = 1000 + DefaultSigVerifyCostSm2 uint64 = 7850 ) // Parameter keys @@ -24,13 +25,14 @@ var ( KeyTxSizeCostPerByte = []byte("TxSizeCostPerByte") KeySigVerifyCostED25519 = []byte("SigVerifyCostED25519") KeySigVerifyCostSecp256k1 = []byte("SigVerifyCostSecp256k1") + KeySigVerifyCostSm2 = []byte("SigVerifyCostSm2") ) var _ paramtypes.ParamSet = &Params{} // NewParams creates a new Params object func NewParams( - maxMemoCharacters, txSigLimit, txSizeCostPerByte, sigVerifyCostED25519, sigVerifyCostSecp256k1 uint64, + maxMemoCharacters, txSigLimit, txSizeCostPerByte, sigVerifyCostED25519, sigVerifyCostSecp256k1, sigVerifyCostSm2 uint64, ) Params { return Params{ MaxMemoCharacters: maxMemoCharacters, @@ -38,6 +40,7 @@ func NewParams( TxSizeCostPerByte: txSizeCostPerByte, SigVerifyCostED25519: sigVerifyCostED25519, SigVerifyCostSecp256k1: sigVerifyCostSecp256k1, + SigVerifyCostSm2: sigVerifyCostSm2, } } @@ -55,6 +58,7 @@ func (p *Params) ParamSetPairs() paramtypes.ParamSetPairs { paramtypes.NewParamSetPair(KeyTxSizeCostPerByte, &p.TxSizeCostPerByte, validateTxSizeCostPerByte), paramtypes.NewParamSetPair(KeySigVerifyCostED25519, &p.SigVerifyCostED25519, validateSigVerifyCostED25519), paramtypes.NewParamSetPair(KeySigVerifyCostSecp256k1, &p.SigVerifyCostSecp256k1, validateSigVerifyCostSecp256k1), + paramtypes.NewParamSetPair(KeySigVerifyCostSm2, &p.SigVerifyCostSm2, validateSigVerifyCostSm2), } } @@ -66,6 +70,7 @@ func DefaultParams() Params { TxSizeCostPerByte: DefaultTxSizeCostPerByte, SigVerifyCostED25519: DefaultSigVerifyCostED25519, SigVerifyCostSecp256k1: DefaultSigVerifyCostSecp256k1, + SigVerifyCostSm2: DefaultSigVerifyCostSm2, } } @@ -126,6 +131,19 @@ func validateSigVerifyCostSecp256k1(i interface{}) error { return nil } +func validateSigVerifyCostSm2(i interface{}) error { + v, ok := i.(uint64) + if !ok { + return fmt.Errorf("invalid parameter type: %T", i) + } + + if v == 0 { + return fmt.Errorf("invalid Sm2 signature verification cost: %d", v) + } + + return nil +} + func validateMaxMemoCharacters(i interface{}) error { v, ok := i.(uint64) if !ok { @@ -163,6 +181,9 @@ func (p Params) Validate() error { if err := validateSigVerifyCostSecp256k1(p.SigVerifyCostSecp256k1); err != nil { return err } + if err := validateSigVerifyCostSm2(p.SigVerifyCostSm2); err != nil { + return err + } if err := validateMaxMemoCharacters(p.MaxMemoCharacters); err != nil { return err } diff --git a/x/auth/types/params_test.go b/x/auth/types/params_test.go index fcec36cb833c..149c5a0e366f 100644 --- a/x/auth/types/params_test.go +++ b/x/auth/types/params_test.go @@ -26,15 +26,15 @@ func TestParams_Validate(t *testing.T) { }{ {"default params", types.DefaultParams(), nil}, {"invalid tx signature limit", types.NewParams(types.DefaultMaxMemoCharacters, 0, types.DefaultTxSizeCostPerByte, - types.DefaultSigVerifyCostED25519, types.DefaultSigVerifyCostSecp256k1), fmt.Errorf("invalid tx signature limit: 0")}, + types.DefaultSigVerifyCostED25519, types.DefaultSigVerifyCostSecp256k1, types.DefaultSigVerifyCostSm2), fmt.Errorf("invalid tx signature limit: 0")}, {"invalid ED25519 signature verification cost", types.NewParams(types.DefaultMaxMemoCharacters, types.DefaultTxSigLimit, types.DefaultTxSizeCostPerByte, - 0, types.DefaultSigVerifyCostSecp256k1), fmt.Errorf("invalid ED25519 signature verification cost: 0")}, + 0, types.DefaultSigVerifyCostSecp256k1, types.DefaultSigVerifyCostSm2), fmt.Errorf("invalid ED25519 signature verification cost: 0")}, {"invalid SECK256k1 signature verification cost", types.NewParams(types.DefaultMaxMemoCharacters, types.DefaultTxSigLimit, types.DefaultTxSizeCostPerByte, - types.DefaultSigVerifyCostED25519, 0), fmt.Errorf("invalid SECK256k1 signature verification cost: 0")}, + types.DefaultSigVerifyCostED25519, 0, types.DefaultSigVerifyCostSm2), fmt.Errorf("invalid SECK256k1 signature verification cost: 0")}, {"invalid max memo characters", types.NewParams(0, types.DefaultTxSigLimit, types.DefaultTxSizeCostPerByte, - types.DefaultSigVerifyCostED25519, types.DefaultSigVerifyCostSecp256k1), fmt.Errorf("invalid max memo characters: 0")}, + types.DefaultSigVerifyCostED25519, types.DefaultSigVerifyCostSecp256k1, types.DefaultSigVerifyCostSm2), fmt.Errorf("invalid max memo characters: 0")}, {"invalid tx size cost per byte", types.NewParams(types.DefaultMaxMemoCharacters, types.DefaultTxSigLimit, 0, - types.DefaultSigVerifyCostED25519, types.DefaultSigVerifyCostSecp256k1), fmt.Errorf("invalid tx size cost per byte: 0")}, + types.DefaultSigVerifyCostED25519, types.DefaultSigVerifyCostSecp256k1, types.DefaultSigVerifyCostSm2), fmt.Errorf("invalid tx size cost per byte: 0")}, } for _, tt := range tests { tt := tt