diff --git a/crypto/keys/bls12381/bls12381.go b/crypto/keys/bls12381/bls12381.go index 4806b26685..eab266c3d2 100644 --- a/crypto/keys/bls12381/bls12381.go +++ b/crypto/keys/bls12381/bls12381.go @@ -112,7 +112,7 @@ func GenPrivKey() *PrivKey { return &PrivKey{Key: genPrivKey(crypto.CReader())} } -// genPrivKey generates a new secp256k1 private key using the provided reader. +// genPrivKey generates a new bls12381 private key using the provided reader. func genPrivKey(rand io.Reader) []byte { var ikm [SeedSize]byte _, err := io.ReadFull(rand, ikm[:]) diff --git a/crypto/keys/bls12381/multisig.go b/crypto/keys/bls12381/multisig.go new file mode 100644 index 0000000000..18e499e390 --- /dev/null +++ b/crypto/keys/bls12381/multisig.go @@ -0,0 +1,102 @@ +package bls12381 + +import ( + "encoding/base64" + "fmt" + + blst "github.com/supranational/blst/bindings/go" +) + +func aggregatePublicKey(pks []*PubKey) (*blst.P1Affine, error) { + pubkeys := make([]*blst.P1Affine, len(pks)) + for i, pk := range pks { + pubkeys[i] = new(blst.P1Affine).Deserialize(pk.Key) + if pubkeys[i] == nil { + return nil, fmt.Errorf("failed to deserialize public key") + } + } + + aggregator := new(blst.P1Aggregate) + b := aggregator.Aggregate(pubkeys, false) + if !b { + return nil, fmt.Errorf("failed to aggregate public keys") + } + apk := aggregator.ToAffine() + + return apk, nil +} + +// AggregateSignature combines a set of verified signatures into a single bls signature +func AggregateSignature(sigs [][]byte) ([]byte, error) { + sigmas := make([]*blst.P2Affine, len(sigs)) + for i, sig := range sigs { + sigmas[i] = new(blst.P2Affine).Uncompress(sig) + if sigmas[i] == nil { + return nil, fmt.Errorf("failed to deserialize the %d-th signature", i) + } + } + + aggregator := new(blst.P2Aggregate) + b := aggregator.Aggregate(sigmas, false) + if !b { + return nil, fmt.Errorf("failed to aggregate signatures") + } + aggSigBytes := aggregator.ToAffine().Compress() + return aggSigBytes, nil +} + +// VerifyMultiSignature assumes public key is already validated +func VerifyMultiSignature(msg []byte, sig []byte, pks []*PubKey) error { + return VerifyAggregateSignature([][]byte{msg}, sig, [][]*PubKey{pks}) +} + +func Unique(msgs [][]byte) bool { + if len(msgs) <= 1 { + return true + } + msgMap := make(map[string]bool, len(msgs)) + for _, msg := range msgs { + s := base64.StdEncoding.EncodeToString(msg) + if _, ok := msgMap[s]; ok { + return false + } + msgMap[s] = true + } + return true +} + +func VerifyAggregateSignature(msgs [][]byte, sig []byte, pkss [][]*PubKey) error { + n := len(msgs) + if n == 0 { + return fmt.Errorf("messages cannot be empty") + } + + if len(pkss) != n { + return fmt.Errorf("the number of messages and public key sets must match") + } + + if !Unique(msgs) { + return fmt.Errorf("messages must be pairwise distinct") + } + + apks := make([]*blst.P1Affine, len(pkss)) + for i, pks := range pkss { + apk, err := aggregatePublicKey(pks) + if err != nil { + return fmt.Errorf("cannot aggregate public keys: %s", err.Error()) + } + apks[i] = apk + } + + sigma := new(blst.P2Affine).Uncompress(sig) + if sigma == nil { + return fmt.Errorf("failed to deserialize signature") + } + + dst := []byte("BLS_SIG_BLS12381G2_XMD:SHA-256_SSWU_RO_POP_") + if !sigma.AggregateVerify(true, apks, false, msgs, dst) { + return fmt.Errorf("failed to verify signature") + } + + return nil +} diff --git a/crypto/keys/bls12381/multisig_test.go b/crypto/keys/bls12381/multisig_test.go new file mode 100644 index 0000000000..c0024f859b --- /dev/null +++ b/crypto/keys/bls12381/multisig_test.go @@ -0,0 +1,124 @@ +package bls12381_test + +import ( + "fmt" + "testing" + + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + + bls "github.com/cosmos/cosmos-sdk/crypto/keys/bls12381" +) + +func TestBlsMultiSig(t *testing.T) { + total := 5 + pks := make([]*bls.PubKey, total) + sigs := make([][]byte, total) + msg := []byte("hello world") + for i := 0; i < total; i++ { + sk := bls.GenPrivKey() + pk, ok := sk.PubKey().(*bls.PubKey) + require.True(t, ok) + + sig, err := sk.Sign(msg) + require.Nil(t, err) + + pks[i] = pk + sigs[i] = sig + } + + aggSig, err := bls.AggregateSignature(sigs) + require.Nil(t, err) + + assert.Nil(t, bls.VerifyMultiSignature(msg, aggSig, pks)) + +} + +func TestBlsAggSig(t *testing.T) { + total := 5 + pks := make([][]*bls.PubKey, total) + sigs := make([][]byte, total) + msgs := make([][]byte, total) + for i := 0; i < total; i++ { + msgs[i] = []byte(fmt.Sprintf("message %d", i)) + sk := bls.GenPrivKey() + pk, ok := sk.PubKey().(*bls.PubKey) + require.True(t, ok) + + sig, err := sk.Sign(msgs[i]) + require.Nil(t, err) + + pks[i] = []*bls.PubKey{pk} + sigs[i] = sig + } + + aggSig, err := bls.AggregateSignature(sigs) + require.Nil(t, err) + + assert.Nil(t, bls.VerifyAggregateSignature(msgs, aggSig, pks)) + +} + +func benchmarkBlsVerifyMulti(total int, b *testing.B) { + pks := make([]*bls.PubKey, total) + sigs := make([][]byte, total) + msg := []byte("hello world") + for i := 0; i < total; i++ { + sk := bls.GenPrivKey() + pk, ok := sk.PubKey().(*bls.PubKey) + require.True(b, ok) + + sig, err := sk.Sign(msg) + require.Nil(b, err) + + pks[i] = pk + sigs[i] = sig + } + + aggSig, err := bls.AggregateSignature(sigs) + require.Nil(b, err) + + b.ResetTimer() + for i := 0; i < b.N; i++ { + bls.VerifyMultiSignature(msg, aggSig, pks) + } +} + +func BenchmarkBlsVerifyMulti8(b *testing.B) { benchmarkBlsVerifyMulti(8, b) } +func BenchmarkBlsVerifyMulti16(b *testing.B) { benchmarkBlsVerifyMulti(16, b) } +func BenchmarkBlsVerifyMulti32(b *testing.B) { benchmarkBlsVerifyMulti(32, b) } +func BenchmarkBlsVerifyMulti64(b *testing.B) { benchmarkBlsVerifyMulti(64, b) } +func BenchmarkBlsVerifyMulti128(b *testing.B) { benchmarkBlsVerifyMulti(128, b) } + +func benchmarkBlsVerifyAgg(total int, b *testing.B) { + pks := make([][]*bls.PubKey, total) + sigs := make([][]byte, total) + msgs := make([][]byte, total) + for i := 0; i < total; i++ { + msgs[i] = []byte(fmt.Sprintf("message %d", i)) + sk := bls.GenPrivKey() + pk, ok := sk.PubKey().(*bls.PubKey) + require.True(b, ok) + + sig, err := sk.Sign(msgs[i]) + require.Nil(b, err) + + pks[i] = []*bls.PubKey{pk} + sigs[i] = sig + } + + aggSig, err := bls.AggregateSignature(sigs) + require.Nil(b, err) + + b.ResetTimer() + + for i := 0; i < b.N; i++ { + bls.VerifyAggregateSignature(msgs, aggSig, pks) + } +} + +func BenchmarkBlsVerifyAgg8(b *testing.B) { benchmarkBlsVerifyAgg(8, b) } +func BenchmarkBlsVerifyAgg16(b *testing.B) { benchmarkBlsVerifyAgg(16, b) } +func BenchmarkBlsVerifyAgg32(b *testing.B) { benchmarkBlsVerifyAgg(32, b) } +func BenchmarkBlsVerifyAgg64(b *testing.B) { benchmarkBlsVerifyAgg(64, b) } +func BenchmarkBlsVerifyAgg128(b *testing.B) { benchmarkBlsVerifyAgg(128, b) } diff --git a/docs/core/proto-docs.md b/docs/core/proto-docs.md index 6c16c68c78..e1cc1ec4c7 100644 --- a/docs/core/proto-docs.md +++ b/docs/core/proto-docs.md @@ -1147,6 +1147,7 @@ type for additional functionality (e.g. vesting). | `pub_key` | [google.protobuf.Any](#google.protobuf.Any) | | | | `account_number` | [uint64](#uint64) | | | | `sequence` | [uint64](#uint64) | | | +| `pop_is_valid` | [bool](#bool) | | | diff --git a/proto/cosmos/auth/v1beta1/auth.proto b/proto/cosmos/auth/v1beta1/auth.proto index 799568c186..9be92bd2ce 100644 --- a/proto/cosmos/auth/v1beta1/auth.proto +++ b/proto/cosmos/auth/v1beta1/auth.proto @@ -23,6 +23,7 @@ message BaseAccount { [(gogoproto.jsontag) = "public_key,omitempty", (gogoproto.moretags) = "yaml:\"public_key\""]; uint64 account_number = 3 [(gogoproto.moretags) = "yaml:\"account_number\""]; uint64 sequence = 4; + bool pop_is_valid = 5; } // ModuleAccount defines an account for modules that holds coins on a pool. diff --git a/types/errors/errors.go b/types/errors/errors.go index 026f5f569b..909b97f691 100644 --- a/types/errors/errors.go +++ b/types/errors/errors.go @@ -134,6 +134,9 @@ var ( // supported. ErrNotSupported = Register(RootCodespace, 37, "feature not supported") + // ErrInvalidPop to doc + ErrInvalidPop = Register(RootCodespace, 38, "invalid pop for public key") + // ErrPanic is only set when we recover from a panic, so we know to // redact potentially sensitive system info ErrPanic = Register(UndefinedCodespace, 111222, "panic") diff --git a/x/auth/ante/ante.go b/x/auth/ante/ante.go index 8cc025bad2..ee474b8fbc 100644 --- a/x/auth/ante/ante.go +++ b/x/auth/ante/ante.go @@ -28,6 +28,7 @@ func NewAnteHandler( NewDeductFeeDecorator(ak, bankKeeper), NewSigGasConsumeDecorator(ak, sigGasConsumer), NewSigVerificationDecorator(ak, signModeHandler), + NewSetPopValidDecorator(ak), NewIncrementSequenceDecorator(ak), ) } diff --git a/x/auth/ante/sigverify.go b/x/auth/ante/sigverify.go index db5df87a9a..38a89ea7d8 100644 --- a/x/auth/ante/sigverify.go +++ b/x/auth/ante/sigverify.go @@ -318,6 +318,40 @@ func (svd SigVerificationDecorator) AnteHandle(ctx sdk.Context, tx sdk.Tx, simul return next(ctx, tx, simulate) } +// SetPopValidDecorator handles the validation status of the proof-of-possession (POP) of an individual public key. +// A valid transaction and signature can be viewed as a POP for the signer's public key. +// POP is required when forming a compact multisig group in order to prevent rogue public key attacks. +type SetPopValidDecorator struct { + ak AccountKeeper +} + +func NewSetPopValidDecorator(ak AccountKeeper) SetPopValidDecorator { + return SetPopValidDecorator{ + ak: ak, + } +} + +func (spvd SetPopValidDecorator) AnteHandle(ctx sdk.Context, tx sdk.Tx, simulate bool, next sdk.AnteHandler) (sdk.Context, error) { + sigTx, ok := tx.(authsigning.SigVerifiableTx) + if !ok { + return ctx, sdkerrors.Wrap(sdkerrors.ErrTxDecode, "invalid transaction type") + } + + for _, addr := range sigTx.GetSigners() { + acc := spvd.ak.GetAccount(ctx, addr) + pk := acc.GetPubKey() + + switch pk.(type) { + case *bls12381.PubKey, *secp256k1.PubKey, *ed25519.PubKey: + if err := acc.SetPopValid(true); err != nil { + return ctx, sdkerrors.Wrap(sdkerrors.ErrInvalidPop, err.Error()) + } + } + } + + return next(ctx, tx, simulate) +} + // IncrementSequenceDecorator handles incrementing sequences of all signers. // Use the IncrementSequenceDecorator decorator to prevent replay attacks. Note, // there is no need to execute IncrementSequenceDecorator on RecheckTX since diff --git a/x/auth/types/account.go b/x/auth/types/account.go index eb9939ffce..9b1b89ec6c 100644 --- a/x/auth/types/account.go +++ b/x/auth/types/account.go @@ -32,6 +32,7 @@ func NewBaseAccount(address sdk.AccAddress, pubKey cryptotypes.PubKey, accountNu Address: address.String(), AccountNumber: accountNumber, Sequence: sequence, + PopIsValid: false, } err := acc.SetPubKey(pubKey) @@ -117,6 +118,20 @@ func (acc *BaseAccount) SetSequence(seq uint64) error { return nil } +// SetPopValid - Implements sdk.AccountI. +func (acc *BaseAccount) SetPopValid(isValid bool) error { + if acc.PubKey == nil { + return errors.New("public key is not set yet") + } + acc.PopIsValid = isValid + return nil +} + +// GetPopValid - Implements sdk.AccountI. +func (acc *BaseAccount) GetPopValid() bool { + return acc.PopIsValid +} + // Validate checks for errors on the account fields func (acc BaseAccount) Validate() error { if acc.Address == "" || acc.PubKey == nil { @@ -222,6 +237,11 @@ func (ma ModuleAccount) SetSequence(seq uint64) error { return fmt.Errorf("not supported for module accounts") } +// SetPopValid - Implements AccountI +func (ma ModuleAccount) SetPopValid(isValid bool) error { + return fmt.Errorf("not supported for module accounts") +} + // Validate checks for errors on the account fields func (ma ModuleAccount) Validate() error { if strings.TrimSpace(ma.Name) == "" { @@ -324,6 +344,9 @@ type AccountI interface { GetSequence() uint64 SetSequence(uint64) error + GetPopValid() bool + SetPopValid(bool) error + // Ensure that account implements stringer String() string } diff --git a/x/auth/types/auth.pb.go b/x/auth/types/auth.pb.go index 83918950e7..c8afc4e899 100644 --- a/x/auth/types/auth.pb.go +++ b/x/auth/types/auth.pb.go @@ -33,6 +33,7 @@ type BaseAccount struct { PubKey *types.Any `protobuf:"bytes,2,opt,name=pub_key,json=pubKey,proto3" json:"public_key,omitempty" yaml:"public_key"` AccountNumber uint64 `protobuf:"varint,3,opt,name=account_number,json=accountNumber,proto3" json:"account_number,omitempty" yaml:"account_number"` Sequence uint64 `protobuf:"varint,4,opt,name=sequence,proto3" json:"sequence,omitempty"` + PopIsValid bool `protobuf:"varint,5,opt,name=pop_is_valid,json=popIsValid,proto3" json:"pop_is_valid,omitempty"` } func (m *BaseAccount) Reset() { *m = BaseAccount{} } @@ -199,52 +200,54 @@ func init() { func init() { proto.RegisterFile("cosmos/auth/v1beta1/auth.proto", fileDescriptor_7e1f7e915d020d2d) } var fileDescriptor_7e1f7e915d020d2d = []byte{ - // 707 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x74, 0x54, 0x3f, 0x4f, 0xdb, 0x40, - 0x14, 0x8f, 0x4b, 0x1a, 0xe0, 0x02, 0x48, 0x98, 0x04, 0x9c, 0xb4, 0xf2, 0x59, 0x9e, 0x52, 0xa9, - 0x71, 0x94, 0x20, 0xaa, 0x12, 0x55, 0x55, 0x31, 0xed, 0x80, 0x5a, 0x10, 0x32, 0x52, 0x87, 0xaa, - 0x92, 0x6b, 0x3b, 0x87, 0xb1, 0x88, 0x73, 0xc6, 0x77, 0x46, 0x31, 0x9f, 0xa0, 0x63, 0xc7, 0x8e, - 0x7c, 0x08, 0xbe, 0x41, 0x97, 0x8e, 0x88, 0xa1, 0xea, 0x64, 0x55, 0x61, 0xa9, 0x3a, 0x7a, 0xaf, - 0x54, 0xe5, 0xce, 0x09, 0x09, 0x4a, 0xa7, 0xf8, 0xbd, 0xdf, 0xbf, 0x77, 0xef, 0x94, 0x03, 0xb2, - 0x83, 0x89, 0x8f, 0x49, 0xc3, 0x8a, 0xe8, 0x49, 0xe3, 0xbc, 0x69, 0x23, 0x6a, 0x35, 0x59, 0xa1, - 0x05, 0x21, 0xa6, 0x58, 0x5c, 0xe3, 0xb8, 0xc6, 0x5a, 0x19, 0x5e, 0xad, 0xf0, 0xa6, 0xc9, 0x28, - 0x8d, 0x8c, 0xc1, 0x8a, 0x6a, 0xc9, 0xc5, 0x2e, 0xe6, 0xfd, 0xe1, 0x57, 0xd6, 0xad, 0xb8, 0x18, - 0xbb, 0x5d, 0xd4, 0x60, 0x95, 0x1d, 0x1d, 0x37, 0xac, 0x5e, 0xcc, 0x21, 0xf5, 0xaf, 0x00, 0x8a, - 0xba, 0x45, 0xd0, 0x8e, 0xe3, 0xe0, 0xa8, 0x47, 0x45, 0x09, 0xcc, 0x5b, 0x9d, 0x4e, 0x88, 0x08, - 0x91, 0x04, 0x45, 0xa8, 0x2d, 0x1a, 0xa3, 0x52, 0xfc, 0x08, 0xe6, 0x83, 0xc8, 0x36, 0x4f, 0x51, - 0x2c, 0x3d, 0x50, 0x84, 0x5a, 0xb1, 0x55, 0xd2, 0xb8, 0xad, 0x36, 0xb2, 0xd5, 0x76, 0x7a, 0xb1, - 0x5e, 0xff, 0x93, 0xc0, 0x52, 0x10, 0xd9, 0x5d, 0xcf, 0x19, 0x72, 0x9f, 0x62, 0xdf, 0xa3, 0xc8, - 0x0f, 0x68, 0x9c, 0x26, 0x70, 0x35, 0xb6, 0xfc, 0x6e, 0x5b, 0xbd, 0x43, 0x55, 0xa3, 0x10, 0x44, - 0xf6, 0x5b, 0x14, 0x8b, 0xaf, 0xc0, 0x8a, 0xc5, 0x47, 0x30, 0x7b, 0x91, 0x6f, 0xa3, 0x50, 0x9a, - 0x53, 0x84, 0x5a, 0x5e, 0xaf, 0xa4, 0x09, 0x2c, 0x73, 0xd9, 0x34, 0xae, 0x1a, 0xcb, 0x59, 0xe3, - 0x80, 0xd5, 0x62, 0x15, 0x2c, 0x10, 0x74, 0x16, 0xa1, 0x9e, 0x83, 0xa4, 0xfc, 0x50, 0x6b, 0x8c, - 0xeb, 0xb6, 0xf4, 0xf9, 0x12, 0xe6, 0xbe, 0x5e, 0xc2, 0xdc, 0xef, 0x4b, 0x98, 0xbb, 0xb9, 0xaa, - 0x2f, 0x64, 0xc7, 0xdd, 0x53, 0xbf, 0x09, 0x60, 0x79, 0x1f, 0x77, 0xa2, 0xee, 0x78, 0x03, 0x9f, - 0xc0, 0x92, 0x6d, 0x11, 0x64, 0x66, 0xee, 0x6c, 0x0d, 0xc5, 0x96, 0xa2, 0xcd, 0xb8, 0x09, 0x6d, - 0x62, 0x73, 0xfa, 0xa3, 0xeb, 0x04, 0x0a, 0x69, 0x02, 0xd7, 0xf8, 0xb4, 0x93, 0x1e, 0xaa, 0x51, - 0xb4, 0x27, 0x76, 0x2c, 0x82, 0x7c, 0xcf, 0xf2, 0x11, 0x5b, 0xe3, 0xa2, 0xc1, 0xbe, 0x45, 0x05, - 0x14, 0x03, 0x14, 0xfa, 0x1e, 0x21, 0x1e, 0xee, 0x11, 0x69, 0x4e, 0x99, 0xab, 0x2d, 0x1a, 0x93, - 0xad, 0x76, 0x75, 0x74, 0x86, 0x9b, 0xab, 0xfa, 0xca, 0xd4, 0xc8, 0x7b, 0xea, 0x8f, 0x3c, 0x28, - 0x1c, 0x5a, 0xa1, 0xe5, 0x13, 0xf1, 0x00, 0xac, 0xf9, 0x56, 0xdf, 0xf4, 0x91, 0x8f, 0x4d, 0xe7, - 0xc4, 0x0a, 0x2d, 0x87, 0xa2, 0x90, 0x5f, 0x66, 0x5e, 0x97, 0xd3, 0x04, 0x56, 0xf9, 0x7c, 0x33, - 0x48, 0xaa, 0xb1, 0xea, 0x5b, 0xfd, 0x7d, 0xe4, 0xe3, 0xdd, 0x71, 0x4f, 0xdc, 0x06, 0x4b, 0xb4, - 0x6f, 0x12, 0xcf, 0x35, 0xbb, 0x9e, 0xef, 0x51, 0x36, 0x74, 0x5e, 0xdf, 0xb8, 0x3b, 0xe8, 0x24, - 0xaa, 0x1a, 0x80, 0xf6, 0x8f, 0x3c, 0xf7, 0xdd, 0xb0, 0x10, 0x0d, 0x50, 0x66, 0xe0, 0x05, 0x32, - 0x1d, 0x4c, 0xa8, 0x19, 0xa0, 0xd0, 0xb4, 0x63, 0x8a, 0xb2, 0xab, 0x55, 0xd2, 0x04, 0x3e, 0x9e, - 0xf0, 0xb8, 0x4f, 0x53, 0x8d, 0xd5, 0xa1, 0xd9, 0x05, 0xda, 0xc5, 0x84, 0x1e, 0xa2, 0x50, 0x8f, - 0x29, 0x12, 0xcf, 0xc0, 0xc6, 0x30, 0xed, 0x1c, 0x85, 0xde, 0x71, 0xcc, 0xf9, 0xa8, 0xd3, 0xda, - 0xda, 0x6a, 0x6e, 0xf3, 0x4b, 0xd7, 0xdb, 0x83, 0x04, 0x96, 0x8e, 0x3c, 0xf7, 0x3d, 0x63, 0x0c, - 0xa5, 0x6f, 0x5e, 0x33, 0x3c, 0x4d, 0xa0, 0xcc, 0xd3, 0xfe, 0x63, 0xa0, 0x1a, 0x25, 0x32, 0xa5, - 0xe3, 0x6d, 0x31, 0x06, 0x95, 0xfb, 0x0a, 0x82, 0x9c, 0xa0, 0xb5, 0xf5, 0xec, 0xb4, 0x29, 0x3d, - 0x64, 0xa1, 0x2f, 0x07, 0x09, 0x5c, 0x9f, 0x0a, 0x3d, 0x1a, 0x31, 0xd2, 0x04, 0x2a, 0xb3, 0x63, - 0xc7, 0x26, 0xaa, 0xb1, 0x4e, 0x66, 0x6a, 0xc5, 0x08, 0x48, 0xf7, 0x55, 0x76, 0x97, 0x34, 0x5b, - 0x9b, 0xcf, 0x9b, 0x52, 0x81, 0x25, 0xbf, 0x18, 0x24, 0xb0, 0x3c, 0x95, 0xac, 0x67, 0x84, 0x34, - 0x81, 0x70, 0x76, 0xf0, 0xc8, 0x42, 0x35, 0xca, 0x64, 0x96, 0xb2, 0xbd, 0x90, 0xfd, 0x55, 0x04, - 0x7d, 0xf7, 0xfb, 0x40, 0x16, 0xae, 0x07, 0xb2, 0xf0, 0x6b, 0x20, 0x0b, 0x5f, 0x6e, 0xe5, 0xdc, - 0xf5, 0xad, 0x9c, 0xfb, 0x79, 0x2b, 0xe7, 0x3e, 0x3c, 0x71, 0x3d, 0x7a, 0x12, 0xd9, 0x9a, 0x83, - 0xfd, 0xec, 0x09, 0xca, 0x7e, 0xea, 0xa4, 0x73, 0xda, 0xe8, 0xf3, 0x17, 0x8d, 0xc6, 0x01, 0x22, - 0x76, 0x81, 0x3d, 0x10, 0x9b, 0xff, 0x02, 0x00, 0x00, 0xff, 0xff, 0x5a, 0x52, 0xeb, 0xf4, 0xed, - 0x04, 0x00, 0x00, + // 738 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x74, 0x54, 0xcf, 0x4e, 0xe3, 0x46, + 0x18, 0x8f, 0x21, 0x0d, 0x61, 0x02, 0x48, 0x98, 0x04, 0x9c, 0xb4, 0xf2, 0x58, 0x3e, 0xa5, 0x52, + 0xe3, 0x28, 0x41, 0x54, 0x25, 0xaa, 0xaa, 0x62, 0xda, 0x03, 0x6a, 0x41, 0xc8, 0x48, 0x1c, 0xaa, + 0x4a, 0xde, 0xb1, 0x33, 0x18, 0x8b, 0x38, 0x63, 0x3c, 0x63, 0x14, 0xf3, 0x04, 0x7b, 0xdc, 0xe3, + 0xde, 0x96, 0x87, 0xe0, 0x0d, 0xf6, 0xb2, 0x47, 0xc4, 0x61, 0xb5, 0x27, 0x6b, 0x15, 0x2e, 0xab, + 0x3d, 0xfa, 0x09, 0x56, 0x1e, 0x3b, 0x21, 0x41, 0xd9, 0x53, 0xfc, 0xfd, 0xbe, 0xdf, 0x9f, 0x99, + 0x6f, 0x26, 0x03, 0x64, 0x9b, 0x50, 0x8f, 0xd0, 0x36, 0x0a, 0xd9, 0x65, 0xfb, 0xa6, 0x63, 0x61, + 0x86, 0x3a, 0xbc, 0xd0, 0xfc, 0x80, 0x30, 0x22, 0x6e, 0x65, 0x7d, 0x8d, 0x43, 0x79, 0xbf, 0x51, + 0xcf, 0x40, 0x93, 0x53, 0xda, 0x39, 0x83, 0x17, 0x8d, 0xaa, 0x43, 0x1c, 0x92, 0xe1, 0xe9, 0x57, + 0x8e, 0xd6, 0x1d, 0x42, 0x9c, 0x01, 0x6e, 0xf3, 0xca, 0x0a, 0x2f, 0xda, 0x68, 0x18, 0x65, 0x2d, + 0xf5, 0xdd, 0x12, 0xa8, 0xe8, 0x88, 0xe2, 0x03, 0xdb, 0x26, 0xe1, 0x90, 0x89, 0x12, 0x58, 0x41, + 0xfd, 0x7e, 0x80, 0x29, 0x95, 0x04, 0x45, 0x68, 0xae, 0x1a, 0x93, 0x52, 0xfc, 0x1f, 0xac, 0xf8, + 0xa1, 0x65, 0x5e, 0xe1, 0x48, 0x5a, 0x52, 0x84, 0x66, 0xa5, 0x5b, 0xd5, 0x32, 0x5b, 0x6d, 0x62, + 0xab, 0x1d, 0x0c, 0x23, 0xbd, 0xf5, 0x35, 0x86, 0x55, 0x3f, 0xb4, 0x06, 0xae, 0x9d, 0x72, 0x7f, + 0x21, 0x9e, 0xcb, 0xb0, 0xe7, 0xb3, 0x28, 0x89, 0xe1, 0x66, 0x84, 0xbc, 0x41, 0x4f, 0x7d, 0xee, + 0xaa, 0x46, 0xc9, 0x0f, 0xad, 0x7f, 0x70, 0x24, 0xfe, 0x09, 0x36, 0x50, 0xb6, 0x04, 0x73, 0x18, + 0x7a, 0x16, 0x0e, 0xa4, 0x65, 0x45, 0x68, 0x16, 0xf5, 0x7a, 0x12, 0xc3, 0x5a, 0x26, 0x9b, 0xef, + 0xab, 0xc6, 0x7a, 0x0e, 0x9c, 0xf0, 0x5a, 0x6c, 0x80, 0x32, 0xc5, 0xd7, 0x21, 0x1e, 0xda, 0x58, + 0x2a, 0xa6, 0x5a, 0x63, 0x5a, 0x8b, 0x0a, 0x58, 0xf3, 0x89, 0x6f, 0xba, 0xd4, 0xbc, 0x41, 0x03, + 0xb7, 0x2f, 0xfd, 0xa0, 0x08, 0xcd, 0xb2, 0x01, 0x7c, 0xe2, 0x1f, 0xd1, 0xf3, 0x14, 0xe9, 0x49, + 0xaf, 0xef, 0x60, 0xe1, 0xed, 0x1d, 0x2c, 0x7c, 0xb9, 0x83, 0x85, 0xc7, 0xfb, 0x56, 0x39, 0x1f, + 0xc8, 0x91, 0xfa, 0x5e, 0x00, 0xeb, 0xc7, 0xa4, 0x1f, 0x0e, 0xa6, 0x33, 0x7a, 0x05, 0xd6, 0x2c, + 0x44, 0xb1, 0x99, 0xe7, 0xf3, 0x41, 0x55, 0xba, 0x8a, 0xb6, 0xe0, 0xac, 0xb4, 0x99, 0xd9, 0xea, + 0x3f, 0x3e, 0xc4, 0x50, 0x48, 0x62, 0xb8, 0x95, 0xed, 0x67, 0xd6, 0x43, 0x35, 0x2a, 0xd6, 0xcc, + 0x29, 0x88, 0xa0, 0x38, 0x44, 0x1e, 0xe6, 0x83, 0x5e, 0x35, 0xf8, 0xb7, 0xa8, 0x80, 0x8a, 0x8f, + 0x03, 0xcf, 0xa5, 0xd4, 0x25, 0x43, 0x2a, 0x2d, 0x2b, 0xcb, 0xcd, 0x55, 0x63, 0x16, 0xea, 0x35, + 0x26, 0x7b, 0x78, 0xbc, 0x6f, 0x6d, 0xcc, 0x2d, 0xf9, 0x48, 0xfd, 0x58, 0x04, 0xa5, 0x53, 0x14, + 0x20, 0x8f, 0x8a, 0x27, 0x60, 0xcb, 0x43, 0x23, 0xd3, 0xc3, 0x1e, 0x31, 0xed, 0x4b, 0x14, 0x20, + 0x9b, 0xe1, 0x20, 0x3b, 0xee, 0xa2, 0x2e, 0x27, 0x31, 0x6c, 0x64, 0xeb, 0x5b, 0x40, 0x52, 0x8d, + 0x4d, 0x0f, 0x8d, 0x8e, 0xb1, 0x47, 0x0e, 0xa7, 0x98, 0xb8, 0x0f, 0xd6, 0xd8, 0xc8, 0xa4, 0xae, + 0x63, 0x0e, 0x5c, 0xcf, 0x65, 0x7c, 0xd1, 0x45, 0x7d, 0xe7, 0x79, 0xa3, 0xb3, 0x5d, 0xd5, 0x00, + 0x6c, 0x74, 0xe6, 0x3a, 0xff, 0xa6, 0x85, 0x68, 0x80, 0x1a, 0x6f, 0xde, 0x62, 0xd3, 0x26, 0x94, + 0x99, 0x3e, 0x0e, 0x4c, 0x2b, 0x62, 0x38, 0x3f, 0x7c, 0x25, 0x89, 0xe1, 0x4f, 0x33, 0x1e, 0x2f, + 0x69, 0xaa, 0xb1, 0x99, 0x9a, 0xdd, 0xe2, 0x43, 0x42, 0xd9, 0x29, 0x0e, 0xf4, 0x88, 0x61, 0xf1, + 0x1a, 0xec, 0xa4, 0x69, 0x37, 0x38, 0x70, 0x2f, 0xa2, 0x8c, 0x8f, 0xfb, 0xdd, 0xbd, 0xbd, 0xce, + 0x7e, 0x76, 0x2d, 0xf4, 0xde, 0x38, 0x86, 0xd5, 0x33, 0xd7, 0x39, 0xe7, 0x8c, 0x54, 0xfa, 0xf7, + 0x5f, 0xbc, 0x9f, 0xc4, 0x50, 0xce, 0xd2, 0xbe, 0x63, 0xa0, 0x1a, 0x55, 0x3a, 0xa7, 0xcb, 0x60, + 0x31, 0x02, 0xf5, 0x97, 0x0a, 0x8a, 0x6d, 0xbf, 0xbb, 0xf7, 0xeb, 0x55, 0x87, 0xdf, 0xb5, 0xa2, + 0xfe, 0xc7, 0x38, 0x86, 0xdb, 0x73, 0xa1, 0x67, 0x13, 0x46, 0x12, 0x43, 0x65, 0x71, 0xec, 0xd4, + 0x44, 0x35, 0xb6, 0xe9, 0x42, 0xad, 0x18, 0x02, 0xe9, 0xa5, 0xca, 0x1a, 0xd0, 0x4e, 0x77, 0xf7, + 0xb7, 0x8e, 0x54, 0xe2, 0xc9, 0xbf, 0x8f, 0x63, 0x58, 0x9b, 0x4b, 0xd6, 0x73, 0x42, 0x12, 0x43, + 0xb8, 0x38, 0x78, 0x62, 0xa1, 0x1a, 0x35, 0xba, 0x48, 0xd9, 0x2b, 0xe7, 0x7f, 0x15, 0x41, 0x3f, + 0xfc, 0x30, 0x96, 0x85, 0x87, 0xb1, 0x2c, 0x7c, 0x1e, 0xcb, 0xc2, 0x9b, 0x27, 0xb9, 0xf0, 0xf0, + 0x24, 0x17, 0x3e, 0x3d, 0xc9, 0x85, 0xff, 0x7e, 0x76, 0x5c, 0x76, 0x19, 0x5a, 0x9a, 0x4d, 0xbc, + 0xfc, 0x91, 0xca, 0x7f, 0x5a, 0xb4, 0x7f, 0xd5, 0x1e, 0x65, 0x6f, 0x1e, 0x8b, 0x7c, 0x4c, 0xad, + 0x12, 0x7f, 0x42, 0x76, 0xbf, 0x05, 0x00, 0x00, 0xff, 0xff, 0xd9, 0x96, 0xbb, 0xf8, 0x0f, 0x05, + 0x00, 0x00, } func (this *Params) Equal(that interface{}) bool { @@ -306,6 +309,16 @@ func (m *BaseAccount) MarshalToSizedBuffer(dAtA []byte) (int, error) { _ = i var l int _ = l + if m.PopIsValid { + i-- + if m.PopIsValid { + dAtA[i] = 1 + } else { + dAtA[i] = 0 + } + i-- + dAtA[i] = 0x28 + } if m.Sequence != 0 { i = encodeVarintAuth(dAtA, i, uint64(m.Sequence)) i-- @@ -473,6 +486,9 @@ func (m *BaseAccount) Size() (n int) { if m.Sequence != 0 { n += 1 + sovAuth(uint64(m.Sequence)) } + if m.PopIsValid { + n += 2 + } return n } @@ -667,6 +683,26 @@ func (m *BaseAccount) Unmarshal(dAtA []byte) error { break } } + case 5: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field PopIsValid", wireType) + } + var v int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowAuth + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + v |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + m.PopIsValid = bool(v != 0) default: iNdEx = preIndex skippy, err := skipAuth(dAtA[iNdEx:])