From bac6879e20c03ea855ca499141a99480d73af609 Mon Sep 17 00:00:00 2001 From: Amaury Martiny Date: Tue, 10 Nov 2020 11:30:06 +0100 Subject: [PATCH 1/7] Generate cached pub key --- client/keys/show.go | 2 +- crypto/hd/hd.pb.go | 459 ++++++++++++++++++ crypto/hd/hdpath.go | 12 - crypto/keyring/keyring.go | 4 +- crypto/ledger/amino.go | 2 +- crypto/ledger/keys.pb.go | 394 +++++++++++++++ crypto/ledger/ledger_secp256k1.go | 50 +- crypto/ledger/ledger_test.go | 18 +- proto/cosmos/base/hd/v1beta1/hd.proto | 20 + .../ledger/secp256k1/v1beta1/keys.proto | 18 + 10 files changed, 924 insertions(+), 55 deletions(-) create mode 100644 crypto/hd/hd.pb.go create mode 100644 crypto/ledger/keys.pb.go create mode 100644 proto/cosmos/base/hd/v1beta1/hd.proto create mode 100644 proto/cosmos/crypto/ledger/secp256k1/v1beta1/keys.proto diff --git a/client/keys/show.go b/client/keys/show.go index 2cb3c457f2ec..9f658bebced5 100644 --- a/client/keys/show.go +++ b/client/keys/show.go @@ -134,7 +134,7 @@ func runShowCmd(cmd *cobra.Command, args []string) (err error) { return nil } - return ledger.ShowAddress(*hdpath, info.GetPubKey(), sdk.GetConfig().GetBech32AccountAddrPrefix()) + return ledger.ShowAddress(hdpath, info.GetPubKey(), sdk.GetConfig().GetBech32AccountAddrPrefix()) } return nil diff --git a/crypto/hd/hd.pb.go b/crypto/hd/hd.pb.go new file mode 100644 index 000000000000..a8d6c1ce5dc8 --- /dev/null +++ b/crypto/hd/hd.pb.go @@ -0,0 +1,459 @@ +// Code generated by protoc-gen-gogo. DO NOT EDIT. +// source: cosmos/base/hd/v1beta1/hd.proto + +package hd + +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 + +// BIP44Params wraps BIP 44 params (5 level BIP 32 path). +// To receive a canonical string representation ala +// m / purpose' / coinType' / account' / change / addressIndex +// call String() on a BIP44Params instance. +type BIP44Params struct { + Purpose uint32 `protobuf:"varint,1,opt,name=Purpose,proto3" json:"Purpose,omitempty"` + CoinType uint32 `protobuf:"varint,2,opt,name=CoinType,proto3" json:"CoinType,omitempty"` + Account uint32 `protobuf:"varint,3,opt,name=Account,proto3" json:"Account,omitempty"` + Change bool `protobuf:"varint,4,opt,name=Change,proto3" json:"Change,omitempty"` + AddressIndex uint32 `protobuf:"varint,5,opt,name=AddressIndex,proto3" json:"AddressIndex,omitempty"` +} + +func (m *BIP44Params) Reset() { *m = BIP44Params{} } +func (*BIP44Params) ProtoMessage() {} +func (*BIP44Params) Descriptor() ([]byte, []int) { + return fileDescriptor_2b1a395a5fd792cd, []int{0} +} +func (m *BIP44Params) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *BIP44Params) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_BIP44Params.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 *BIP44Params) XXX_Merge(src proto.Message) { + xxx_messageInfo_BIP44Params.Merge(m, src) +} +func (m *BIP44Params) XXX_Size() int { + return m.Size() +} +func (m *BIP44Params) XXX_DiscardUnknown() { + xxx_messageInfo_BIP44Params.DiscardUnknown(m) +} + +var xxx_messageInfo_BIP44Params proto.InternalMessageInfo + +func (m *BIP44Params) GetPurpose() uint32 { + if m != nil { + return m.Purpose + } + return 0 +} + +func (m *BIP44Params) GetCoinType() uint32 { + if m != nil { + return m.CoinType + } + return 0 +} + +func (m *BIP44Params) GetAccount() uint32 { + if m != nil { + return m.Account + } + return 0 +} + +func (m *BIP44Params) GetChange() bool { + if m != nil { + return m.Change + } + return false +} + +func (m *BIP44Params) GetAddressIndex() uint32 { + if m != nil { + return m.AddressIndex + } + return 0 +} + +func init() { + proto.RegisterType((*BIP44Params)(nil), "cosmos.crypto.ledger.secp256k1.BIP44Params") +} + +func init() { proto.RegisterFile("cosmos/base/hd/v1beta1/hd.proto", fileDescriptor_2b1a395a5fd792cd) } + +var fileDescriptor_2b1a395a5fd792cd = []byte{ + // 273 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0x92, 0x4f, 0xce, 0x2f, 0xce, + 0xcd, 0x2f, 0xd6, 0x4f, 0x4a, 0x2c, 0x4e, 0xd5, 0xcf, 0x48, 0xd1, 0x2f, 0x33, 0x4c, 0x4a, 0x2d, + 0x49, 0x34, 0xd4, 0xcf, 0x48, 0xd1, 0x2b, 0x28, 0xca, 0x2f, 0xc9, 0x17, 0x92, 0x83, 0x28, 0xd0, + 0x4b, 0x2e, 0xaa, 0x2c, 0x28, 0xc9, 0xd7, 0xcb, 0x49, 0x4d, 0x49, 0x4f, 0x2d, 0xd2, 0x2b, 0x4e, + 0x4d, 0x2e, 0x30, 0x32, 0x35, 0xcb, 0x36, 0x94, 0x12, 0x49, 0xcf, 0x4f, 0xcf, 0x07, 0x2b, 0xd5, + 0x07, 0xb1, 0x20, 0xba, 0x94, 0xe6, 0x33, 0x72, 0x71, 0x3b, 0x79, 0x06, 0x98, 0x98, 0x04, 0x24, + 0x16, 0x25, 0xe6, 0x16, 0x0b, 0x49, 0x70, 0xb1, 0x07, 0x94, 0x16, 0x15, 0xe4, 0x17, 0xa7, 0x4a, + 0x30, 0x2a, 0x30, 0x6a, 0xf0, 0x06, 0xc1, 0xb8, 0x42, 0x52, 0x5c, 0x1c, 0xce, 0xf9, 0x99, 0x79, + 0x21, 0x95, 0x05, 0xa9, 0x12, 0x4c, 0x60, 0x29, 0x38, 0x1f, 0xa4, 0xcb, 0x31, 0x39, 0x39, 0xbf, + 0x34, 0xaf, 0x44, 0x82, 0x19, 0xa2, 0x0b, 0xca, 0x15, 0x12, 0xe3, 0x62, 0x73, 0xce, 0x48, 0xcc, + 0x4b, 0x4f, 0x95, 0x60, 0x51, 0x60, 0xd4, 0xe0, 0x08, 0x82, 0xf2, 0x84, 0x94, 0xb8, 0x78, 0x1c, + 0x53, 0x52, 0x8a, 0x52, 0x8b, 0x8b, 0x3d, 0xf3, 0x52, 0x52, 0x2b, 0x24, 0x58, 0xc1, 0xda, 0x50, + 0xc4, 0xac, 0x58, 0x66, 0x2c, 0x90, 0x67, 0x70, 0x72, 0x38, 0xf1, 0x48, 0x8e, 0xf1, 0xc2, 0x23, + 0x39, 0xc6, 0x07, 0x8f, 0xe4, 0x18, 0x27, 0x3c, 0x96, 0x63, 0xb8, 0xf0, 0x58, 0x8e, 0xe1, 0xc6, + 0x63, 0x39, 0x86, 0x28, 0xb5, 0xf4, 0xcc, 0x92, 0x8c, 0xd2, 0x24, 0xbd, 0xe4, 0xfc, 0x5c, 0x7d, + 0x68, 0xe8, 0x40, 0x28, 0xdd, 0xe2, 0x94, 0x6c, 0x7d, 0x48, 0x38, 0xe8, 0x67, 0xa4, 0x24, 0xb1, + 0x81, 0xbd, 0x6a, 0x0c, 0x08, 0x00, 0x00, 0xff, 0xff, 0xa0, 0x53, 0x3c, 0x20, 0x43, 0x01, 0x00, + 0x00, +} + +func (m *BIP44Params) 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 *BIP44Params) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *BIP44Params) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if m.AddressIndex != 0 { + i = encodeVarintHd(dAtA, i, uint64(m.AddressIndex)) + i-- + dAtA[i] = 0x28 + } + if m.Change { + i-- + if m.Change { + dAtA[i] = 1 + } else { + dAtA[i] = 0 + } + i-- + dAtA[i] = 0x20 + } + if m.Account != 0 { + i = encodeVarintHd(dAtA, i, uint64(m.Account)) + i-- + dAtA[i] = 0x18 + } + if m.CoinType != 0 { + i = encodeVarintHd(dAtA, i, uint64(m.CoinType)) + i-- + dAtA[i] = 0x10 + } + if m.Purpose != 0 { + i = encodeVarintHd(dAtA, i, uint64(m.Purpose)) + i-- + dAtA[i] = 0x8 + } + return len(dAtA) - i, nil +} + +func encodeVarintHd(dAtA []byte, offset int, v uint64) int { + offset -= sovHd(v) + base := offset + for v >= 1<<7 { + dAtA[offset] = uint8(v&0x7f | 0x80) + v >>= 7 + offset++ + } + dAtA[offset] = uint8(v) + return base +} +func (m *BIP44Params) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.Purpose != 0 { + n += 1 + sovHd(uint64(m.Purpose)) + } + if m.CoinType != 0 { + n += 1 + sovHd(uint64(m.CoinType)) + } + if m.Account != 0 { + n += 1 + sovHd(uint64(m.Account)) + } + if m.Change { + n += 2 + } + if m.AddressIndex != 0 { + n += 1 + sovHd(uint64(m.AddressIndex)) + } + return n +} + +func sovHd(x uint64) (n int) { + return (math_bits.Len64(x|1) + 6) / 7 +} +func sozHd(x uint64) (n int) { + return sovHd(uint64((x << 1) ^ uint64((int64(x) >> 63)))) +} +func (m *BIP44Params) 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 ErrIntOverflowHd + } + 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: BIP44Params: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: BIP44Params: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Purpose", wireType) + } + m.Purpose = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowHd + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.Purpose |= uint32(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 2: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field CoinType", wireType) + } + m.CoinType = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowHd + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.CoinType |= uint32(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 3: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Account", wireType) + } + m.Account = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowHd + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.Account |= uint32(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 4: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Change", wireType) + } + var v int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowHd + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + v |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + m.Change = bool(v != 0) + case 5: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field AddressIndex", wireType) + } + m.AddressIndex = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowHd + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.AddressIndex |= uint32(b&0x7F) << shift + if b < 0x80 { + break + } + } + default: + iNdEx = preIndex + skippy, err := skipHd(dAtA[iNdEx:]) + if err != nil { + return err + } + if skippy < 0 { + return ErrInvalidLengthHd + } + if (iNdEx + skippy) < 0 { + return ErrInvalidLengthHd + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func skipHd(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, ErrIntOverflowHd + } + 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, ErrIntOverflowHd + } + 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, ErrIntOverflowHd + } + 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, ErrInvalidLengthHd + } + iNdEx += length + case 3: + depth++ + case 4: + if depth == 0 { + return 0, ErrUnexpectedEndOfGroupHd + } + depth-- + case 5: + iNdEx += 4 + default: + return 0, fmt.Errorf("proto: illegal wireType %d", wireType) + } + if iNdEx < 0 { + return 0, ErrInvalidLengthHd + } + if depth == 0 { + return iNdEx, nil + } + } + return 0, io.ErrUnexpectedEOF +} + +var ( + ErrInvalidLengthHd = fmt.Errorf("proto: negative length found during unmarshaling") + ErrIntOverflowHd = fmt.Errorf("proto: integer overflow") + ErrUnexpectedEndOfGroupHd = fmt.Errorf("proto: unexpected end of group") +) diff --git a/crypto/hd/hdpath.go b/crypto/hd/hdpath.go index 67a02f029044..4f0018144353 100644 --- a/crypto/hd/hdpath.go +++ b/crypto/hd/hdpath.go @@ -12,18 +12,6 @@ import ( "github.com/btcsuite/btcd/btcec" ) -// BIP44Params wraps BIP 44 params (5 level BIP 32 path). -// To receive a canonical string representation ala -// m / purpose' / coinType' / account' / change / addressIndex -// call String() on a BIP44Params instance. -type BIP44Params struct { - Purpose uint32 `json:"purpose"` - CoinType uint32 `json:"coinType"` - Account uint32 `json:"account"` - Change bool `json:"change"` - AddressIndex uint32 `json:"addressIndex"` -} - // NewParams creates a BIP 44 parameter object from the params: // m / purpose' / coinType' / account' / change / addressIndex func NewParams(purpose, coinType, account uint32, change bool, addressIdx uint32) *BIP44Params { diff --git a/crypto/keyring/keyring.go b/crypto/keyring/keyring.go index d3220b5b43ef..ef1f9e3080d0 100644 --- a/crypto/keyring/keyring.go +++ b/crypto/keyring/keyring.go @@ -352,7 +352,7 @@ func (ks keystore) SaveLedgerKey(uid string, algo SignatureAlgo, hrp string, coi hdPath := hd.NewFundraiserParams(account, coinType, index) - priv, _, err := ledger.NewPrivKeySecp256k1(*hdPath, hrp) + priv, _, err := ledger.NewPrivKeySecp256k1(hdPath, hrp) if err != nil { return nil, err } @@ -546,7 +546,7 @@ func SignWithLedger(info Info, msg []byte) (sig []byte, pub types.PubKey, err er return } - priv, err := ledger.NewPrivKeySecp256k1Unsafe(*path) + priv, err := ledger.NewPrivKeySecp256k1Unsafe(path) if err != nil { return } diff --git a/crypto/ledger/amino.go b/crypto/ledger/amino.go index 0e717a9604f0..677241deec6d 100644 --- a/crypto/ledger/amino.go +++ b/crypto/ledger/amino.go @@ -14,6 +14,6 @@ func init() { // RegisterAmino registers all go-crypto related types in the given (amino) codec. func RegisterAmino(cdc *codec.LegacyAmino) { - cdc.RegisterConcrete(PrivKeyLedgerSecp256k1{}, + cdc.RegisterConcrete(PrivKey{}, "tendermint/PrivKeyLedgerSecp256k1", nil) } diff --git a/crypto/ledger/keys.pb.go b/crypto/ledger/keys.pb.go new file mode 100644 index 000000000000..b19a51d4249a --- /dev/null +++ b/crypto/ledger/keys.pb.go @@ -0,0 +1,394 @@ +// Code generated by protoc-gen-gogo. DO NOT EDIT. +// source: cosmos/crypto/ledger/secp256k1/v1beta1/keys.proto + +package ledger + +import ( + fmt "fmt" + hd "github.com/cosmos/cosmos-sdk/crypto/hd" + _ "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 + +// PrivKey defines a Ledger hardware wallet secp256k1 private key. +type PrivKey struct { + // path is the derivation path used to generate the private key. + Path *hd.BIP44Params `protobuf:"bytes,1,opt,name=path,proto3" json:"path,omitempty"` + // cached_pub_key is an utility field used to cache the key's public key, + // so that we don't need to query the Ledger each time we need to access + // the public key. + CachedPubKey []byte `protobuf:"bytes,2,opt,name=cached_pub_key,json=cachedPubKey,proto3" json:"cached_pub_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_88e789035e83c74f, []int{0} +} +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) GetPath() *hd.BIP44Params { + if m != nil { + return m.Path + } + return nil +} + +func (m *PrivKey) GetCachedPubKey() []byte { + if m != nil { + return m.CachedPubKey + } + return nil +} + +func init() { + proto.RegisterType((*PrivKey)(nil), "cosmos.crypto.ledger.secp256k1.v1beta1.PrivKey") +} + +func init() { + proto.RegisterFile("cosmos/crypto/ledger/secp256k1/v1beta1/keys.proto", fileDescriptor_88e789035e83c74f) +} + +var fileDescriptor_88e789035e83c74f = []byte{ + // 256 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0x32, 0x4c, 0xce, 0x2f, 0xce, + 0xcd, 0x2f, 0xd6, 0x4f, 0x2e, 0xaa, 0x2c, 0x28, 0xc9, 0xd7, 0xcf, 0x49, 0x4d, 0x49, 0x4f, 0x2d, + 0xd2, 0x2f, 0x4e, 0x4d, 0x2e, 0x30, 0x32, 0x35, 0xcb, 0x36, 0xd4, 0x2f, 0x33, 0x4c, 0x4a, 0x2d, + 0x49, 0x34, 0xd4, 0xcf, 0x4e, 0xad, 0x2c, 0xd6, 0x2b, 0x28, 0xca, 0x2f, 0xc9, 0x17, 0x52, 0x83, + 0x68, 0xd1, 0x83, 0x68, 0xd1, 0x83, 0x68, 0xd1, 0x83, 0x6b, 0xd1, 0x83, 0x6a, 0x91, 0x12, 0x49, + 0xcf, 0x4f, 0xcf, 0x07, 0x6b, 0xd1, 0x07, 0xb1, 0x20, 0xba, 0xa5, 0xe4, 0xa1, 0x16, 0x26, 0x25, + 0x16, 0xa7, 0xea, 0x67, 0xa4, 0xc0, 0x2d, 0xc8, 0x48, 0x81, 0x28, 0x50, 0x2a, 0xe0, 0x62, 0x0f, + 0x28, 0xca, 0x2c, 0xf3, 0x4e, 0xad, 0x14, 0xb2, 0xe7, 0x62, 0x29, 0x48, 0x2c, 0xc9, 0x90, 0x60, + 0x54, 0x60, 0xd4, 0xe0, 0x36, 0xd2, 0xd6, 0x23, 0x60, 0xb1, 0x93, 0x67, 0x80, 0x89, 0x49, 0x40, + 0x62, 0x51, 0x62, 0x6e, 0x71, 0x10, 0x58, 0xa3, 0x90, 0x0a, 0x17, 0x5f, 0x72, 0x62, 0x72, 0x46, + 0x6a, 0x4a, 0x7c, 0x41, 0x69, 0x52, 0x7c, 0x76, 0x6a, 0xa5, 0x04, 0x93, 0x02, 0xa3, 0x06, 0x4f, + 0x10, 0x0f, 0x44, 0x34, 0xa0, 0x34, 0xc9, 0x3b, 0xb5, 0xd2, 0xc9, 0xe5, 0xc4, 0x23, 0x39, 0xc6, + 0x0b, 0x8f, 0xe4, 0x18, 0x1f, 0x3c, 0x92, 0x63, 0x9c, 0xf0, 0x58, 0x8e, 0xe1, 0xc2, 0x63, 0x39, + 0x86, 0x1b, 0x8f, 0xe5, 0x18, 0xa2, 0xb4, 0xd2, 0x33, 0x4b, 0x32, 0x4a, 0x93, 0xf4, 0x92, 0xf3, + 0x73, 0xf5, 0x61, 0x01, 0x05, 0xa6, 0x74, 0x8b, 0x53, 0xb2, 0x51, 0xc3, 0x2c, 0x89, 0x0d, 0xec, + 0x7c, 0x63, 0x40, 0x00, 0x00, 0x00, 0xff, 0xff, 0x78, 0xa2, 0x67, 0xd2, 0x52, 0x01, 0x00, 0x00, +} + +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.CachedPubKey) > 0 { + i -= len(m.CachedPubKey) + copy(dAtA[i:], m.CachedPubKey) + i = encodeVarintKeys(dAtA, i, uint64(len(m.CachedPubKey))) + i-- + dAtA[i] = 0x12 + } + if m.Path != nil { + { + size, err := m.Path.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintKeys(dAtA, i, uint64(size)) + } + 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 *PrivKey) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.Path != nil { + l = m.Path.Size() + n += 1 + l + sovKeys(uint64(l)) + } + l = len(m.CachedPubKey) + 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 *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 Path", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowKeys + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthKeys + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthKeys + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.Path == nil { + m.Path = &hd.BIP44Params{} + } + if err := m.Path.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field CachedPubKey", 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.CachedPubKey = append(m.CachedPubKey[:0], dAtA[iNdEx:postIndex]...) + if m.CachedPubKey == nil { + m.CachedPubKey = []byte{} + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipKeys(dAtA[iNdEx:]) + if err != nil { + return err + } + if skippy < 0 { + return ErrInvalidLengthKeys + } + if (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/ledger/ledger_secp256k1.go b/crypto/ledger/ledger_secp256k1.go index 659181d30648..70e20001d8b7 100644 --- a/crypto/ledger/ledger_secp256k1.go +++ b/crypto/ledger/ledger_secp256k1.go @@ -36,16 +36,6 @@ type ( // Signs a message (requires user confirmation) SignSECP256K1([]uint32, []byte) ([]byte, error) } - - // PrivKeyLedgerSecp256k1 implements PrivKey, calling the ledger nano we - // cache the PubKey from the first call to use it later. - PrivKeyLedgerSecp256k1 struct { - // CachedPubKey should be private, but we want to encode it via - // go-amino so we can view the address later, even without having the - // ledger attached. - CachedPubKey types.PubKey - Path hd.BIP44Params - } ) // NewPrivKeySecp256k1Unsafe will generate a new key and store the public key for later use. @@ -53,7 +43,7 @@ type ( // This function is marked as unsafe as it will retrieve a pubkey without user verification. // It can only be used to verify a pubkey but never to create new accounts/keys. In that case, // please refer to NewPrivKeySecp256k1 -func NewPrivKeySecp256k1Unsafe(path hd.BIP44Params) (types.LedgerPrivKey, error) { +func NewPrivKeySecp256k1Unsafe(path *hd.BIP44Params) (types.LedgerPrivKey, error) { device, err := getDevice() if err != nil { return nil, err @@ -65,12 +55,12 @@ func NewPrivKeySecp256k1Unsafe(path hd.BIP44Params) (types.LedgerPrivKey, error) return nil, err } - return PrivKeyLedgerSecp256k1{pubKey, path}, nil + return PrivKey{CachedPubKey: pubKey.Bytes(), Path: path}, nil } // NewPrivKeySecp256k1 will generate a new key and store the public key for later use. // The request will require user confirmation and will show account and index in the device -func NewPrivKeySecp256k1(path hd.BIP44Params, hrp string) (types.LedgerPrivKey, string, error) { +func NewPrivKeySecp256k1(path *hd.BIP44Params, hrp string) (types.LedgerPrivKey, string, error) { device, err := getDevice() if err != nil { return nil, "", err @@ -82,16 +72,16 @@ func NewPrivKeySecp256k1(path hd.BIP44Params, hrp string) (types.LedgerPrivKey, return nil, "", err } - return PrivKeyLedgerSecp256k1{pubKey, path}, addr, nil + return PrivKey{CachedPubKey: pubKey.Bytes(), Path: &path}, addr, nil } // PubKey returns the cached public key. -func (pkl PrivKeyLedgerSecp256k1) PubKey() types.PubKey { - return pkl.CachedPubKey +func (pkl PrivKey) PubKey() types.PubKey { + return &secp256k1.PubKey{Key: pkl.CachedPubKey} } // Sign returns a secp256k1 signature for the corresponding message -func (pkl PrivKeyLedgerSecp256k1) Sign(message []byte) ([]byte, error) { +func (pkl PrivKey) Sign(message []byte) ([]byte, error) { device, err := getDevice() if err != nil { return nil, err @@ -102,7 +92,7 @@ func (pkl PrivKeyLedgerSecp256k1) Sign(message []byte) ([]byte, error) { } // ShowAddress triggers a ledger device to show the corresponding address. -func ShowAddress(path hd.BIP44Params, expectedPubKey types.PubKey, +func ShowAddress(path *hd.BIP44Params, expectedPubKey types.PubKey, accountAddressPrefix string) error { device, err := getDevice() if err != nil { @@ -133,7 +123,7 @@ func ShowAddress(path hd.BIP44Params, expectedPubKey types.PubKey, // ValidateKey allows us to verify the sanity of a public key after loading it // from disk. -func (pkl PrivKeyLedgerSecp256k1) ValidateKey() error { +func (pkl PrivKey) ValidateKey() error { device, err := getDevice() if err != nil { return err @@ -144,24 +134,24 @@ func (pkl PrivKeyLedgerSecp256k1) ValidateKey() error { } // AssertIsPrivKeyInner implements the PrivKey interface. It performs a no-op. -func (pkl *PrivKeyLedgerSecp256k1) AssertIsPrivKeyInner() {} +func (pkl *PrivKey) AssertIsPrivKeyInner() {} // Bytes implements the PrivKey interface. It stores the cached public key so // we can verify the same key when we reconnect to a ledger. -func (pkl PrivKeyLedgerSecp256k1) Bytes() []byte { +func (pkl PrivKey) Bytes() []byte { return cdc.MustMarshalBinaryBare(pkl) } // Equals implements the PrivKey interface. It makes sure two private keys // refer to the same public key. -func (pkl PrivKeyLedgerSecp256k1) Equals(other types.LedgerPrivKey) bool { - if otherKey, ok := other.(PrivKeyLedgerSecp256k1); ok { - return pkl.CachedPubKey.Equals(otherKey.CachedPubKey) +func (pkl PrivKey) Equals(other types.LedgerPrivKey) bool { + if otherKey, ok := other.(PrivKey); ok { + return pkl.PubKey().Equals(otherKey.PubKey()) } return false } -func (pkl PrivKeyLedgerSecp256k1) Type() string { return "PrivKeyLedgerSecp256k1" } +func (pkl PrivKey) Type() string { return "PrivKey" } // warnIfErrors wraps a function and writes a warning to stderr. This is required // to avoid ignoring errors when defer is used. Using defer may result in linter warnings. @@ -193,14 +183,14 @@ func getDevice() (SECP256K1, error) { return device, nil } -func validateKey(device SECP256K1, pkl PrivKeyLedgerSecp256k1) error { +func validateKey(device SECP256K1, pkl PrivKey) error { pub, err := getPubKeyUnsafe(device, pkl.Path) if err != nil { return err } // verify this matches cached address - if !pub.Equals(pkl.CachedPubKey) { + if !pub.Equals(pkl.PubKey()) { return fmt.Errorf("cached key does not match retrieved key") } @@ -212,7 +202,7 @@ func validateKey(device SECP256K1, pkl PrivKeyLedgerSecp256k1) error { // Communication is checked on NewPrivKeyLedger and PrivKeyFromBytes, returning // an error, so this should only trigger if the private key is held in memory // for a while before use. -func sign(device SECP256K1, pkl PrivKeyLedgerSecp256k1, msg []byte) ([]byte, error) { +func sign(device SECP256K1, pkl PrivKey, msg []byte) ([]byte, error) { err := validateKey(device, pkl) if err != nil { return nil, err @@ -234,7 +224,7 @@ func sign(device SECP256K1, pkl PrivKeyLedgerSecp256k1, msg []byte) ([]byte, err // // since this involves IO, it may return an error, which is not exposed // in the PubKey interface, so this function allows better error handling -func getPubKeyUnsafe(device SECP256K1, path hd.BIP44Params) (types.PubKey, error) { +func getPubKeyUnsafe(device SECP256K1, path *hd.BIP44Params) (types.PubKey, error) { publicKey, err := device.GetPublicKeySECP256K1(path.DerivationPath()) if err != nil { return nil, fmt.Errorf("please open Cosmos app on the Ledger device - error: %v", err) @@ -258,7 +248,7 @@ func getPubKeyUnsafe(device SECP256K1, path hd.BIP44Params) (types.PubKey, error // // Since this involves IO, it may return an error, which is not exposed // in the PubKey interface, so this function allows better error handling. -func getPubKeyAddrSafe(device SECP256K1, path hd.BIP44Params, hrp string) (types.PubKey, string, error) { +func getPubKeyAddrSafe(device SECP256K1, path *hd.BIP44Params, hrp string) (types.PubKey, string, error) { publicKey, addr, err := device.GetAddressPubKeySECP256K1(path.DerivationPath(), hrp) if err != nil { return nil, "", fmt.Errorf("address %s rejected", addr) diff --git a/crypto/ledger/ledger_test.go b/crypto/ledger/ledger_test.go index bc85b2feba0e..24b5476fd7a7 100644 --- a/crypto/ledger/ledger_test.go +++ b/crypto/ledger/ledger_test.go @@ -16,13 +16,13 @@ import ( func TestErrorHandling(t *testing.T) { // first, try to generate a key, must return an error // (no panic) - path := *hd.NewParams(44, 555, 0, false, 0) + path := hd.NewParams(44, 555, 0, false, 0) _, err := NewPrivKeySecp256k1Unsafe(path) require.Error(t, err) } func TestPublicKeyUnsafe(t *testing.T) { - path := *hd.NewFundraiserParams(0, sdk.CoinType, 0) + path := hd.NewFundraiserParams(0, sdk.CoinType, 0) priv, err := NewPrivKeySecp256k1Unsafe(path) require.Nil(t, err, "%s", err) require.NotNil(t, priv) @@ -61,7 +61,7 @@ func TestPublicKeyUnsafeHDPath(t *testing.T) { // Check with device for i := uint32(0); i < 10; i++ { - path := *hd.NewFundraiserParams(0, sdk.CoinType, i) + path := hd.NewFundraiserParams(0, sdk.CoinType, i) fmt.Printf("Checking keys at %v\n", path) priv, err := NewPrivKeySecp256k1Unsafe(path) @@ -69,7 +69,7 @@ func TestPublicKeyUnsafeHDPath(t *testing.T) { require.NotNil(t, priv) // Check other methods - tmp := priv.(PrivKeyLedgerSecp256k1) + tmp := priv.(PrivKey) require.NoError(t, tmp.ValidateKey()) (&tmp).AssertIsPrivKeyInner() @@ -97,7 +97,7 @@ func TestPublicKeyUnsafeHDPath(t *testing.T) { } func TestPublicKeySafe(t *testing.T) { - path := *hd.NewFundraiserParams(0, sdk.CoinType, 0) + path := hd.NewFundraiserParams(0, sdk.CoinType, 0) priv, addr, err := NewPrivKeySecp256k1(path, "cosmos") require.Nil(t, err, "%s", err) @@ -154,7 +154,7 @@ func TestPublicKeyHDPath(t *testing.T) { // Check with device for i := uint32(0); i < 10; i++ { - path := *hd.NewFundraiserParams(0, sdk.CoinType, i) + path := hd.NewFundraiserParams(0, sdk.CoinType, i) fmt.Printf("Checking keys at %v\n", path) priv, addr, err := NewPrivKeySecp256k1(path, "cosmos") @@ -169,7 +169,7 @@ func TestPublicKeyHDPath(t *testing.T) { "Is your device using test mnemonic: %s ?", testutil.TestMnemonic) // Check other methods - tmp := priv.(PrivKeyLedgerSecp256k1) + tmp := priv.(PrivKey) require.NoError(t, tmp.ValidateKey()) (&tmp).AssertIsPrivKeyInner() @@ -208,7 +208,7 @@ func TestSignaturesHD(t *testing.T) { for account := uint32(0); account < 100; account += 30 { msg := getFakeTx(account) - path := *hd.NewFundraiserParams(account, sdk.CoinType, account/5) + path := hd.NewFundraiserParams(account, sdk.CoinType, account/5) fmt.Printf("Checking signature at %v --- PLEASE REVIEW AND ACCEPT IN THE DEVICE\n", path) priv, err := NewPrivKeySecp256k1Unsafe(path) @@ -225,7 +225,7 @@ func TestSignaturesHD(t *testing.T) { func TestRealDeviceSecp256k1(t *testing.T) { msg := getFakeTx(50) - path := *hd.NewFundraiserParams(0, sdk.CoinType, 0) + path := hd.NewFundraiserParams(0, sdk.CoinType, 0) priv, err := NewPrivKeySecp256k1Unsafe(path) require.Nil(t, err, "%s", err) diff --git a/proto/cosmos/base/hd/v1beta1/hd.proto b/proto/cosmos/base/hd/v1beta1/hd.proto new file mode 100644 index 000000000000..eb0d2406bb68 --- /dev/null +++ b/proto/cosmos/base/hd/v1beta1/hd.proto @@ -0,0 +1,20 @@ +syntax = "proto3"; +package cosmos.crypto.ledger.secp256k1; + +import "gogoproto/gogo.proto"; + +option go_package = "github.com/cosmos/cosmos-sdk/crypto/hd"; + +// BIP44Params wraps BIP 44 params (5 level BIP 32 path). +// To receive a canonical string representation ala +// m / purpose' / coinType' / account' / change / addressIndex +// call String() on a BIP44Params instance. +message BIP44Params { + option (gogoproto.goproto_stringer) = false; + + uint32 Purpose = 1; + uint32 CoinType = 2; + uint32 Account = 3; + bool Change = 4; + uint32 AddressIndex = 5; +} diff --git a/proto/cosmos/crypto/ledger/secp256k1/v1beta1/keys.proto b/proto/cosmos/crypto/ledger/secp256k1/v1beta1/keys.proto new file mode 100644 index 000000000000..2638de0d192a --- /dev/null +++ b/proto/cosmos/crypto/ledger/secp256k1/v1beta1/keys.proto @@ -0,0 +1,18 @@ +syntax = "proto3"; +package cosmos.crypto.ledger.secp256k1.v1beta1; + +option go_package = "github.com/cosmos/cosmos-sdk/crypto/ledger"; + +import "gogoproto/gogo.proto"; +import "cosmos/base/hd/v1beta1/hd.proto"; + +// PrivKey defines a Ledger hardware wallet secp256k1 private key. +message PrivKey { + // path is the derivation path used to generate the private key. + BIP44Params path = 1; + + // cached_pub_key is an utility field used to cache the key's public key, + // so that we don't need to query the Ledger each time we need to access + // the public key. + bytes cached_pub_key = 2; +} From 87bc583d34b3a14db3b2de6ed2a62475a925419b Mon Sep 17 00:00:00 2001 From: Amaury Martiny Date: Tue, 10 Nov 2020 11:36:25 +0100 Subject: [PATCH 2/7] Remove LedgerPrivKey --- crypto/keys/ed25519/ed25519.go | 2 +- crypto/keys/secp256k1/secp256k1.go | 2 +- crypto/ledger/ledger_secp256k1.go | 31 +++++++++++++++--------------- crypto/ledger/ledger_test.go | 10 ++++------ crypto/types/types.go | 21 +++++--------------- 5 files changed, 26 insertions(+), 40 deletions(-) diff --git a/crypto/keys/ed25519/ed25519.go b/crypto/keys/ed25519/ed25519.go index 17368c4b12ff..0a3c36547aa8 100644 --- a/crypto/keys/ed25519/ed25519.go +++ b/crypto/keys/ed25519/ed25519.go @@ -77,7 +77,7 @@ func (privKey *PrivKey) PubKey() cryptotypes.PubKey { // Equals - you probably don't need to use this. // Runs in constant time based on length of the keys. -func (privKey *PrivKey) Equals(other cryptotypes.LedgerPrivKey) bool { +func (privKey *PrivKey) Equals(other cryptotypes.PrivKey) bool { if privKey.Type() != other.Type() { return false } diff --git a/crypto/keys/secp256k1/secp256k1.go b/crypto/keys/secp256k1/secp256k1.go index eebe72a45242..4907415c8702 100644 --- a/crypto/keys/secp256k1/secp256k1.go +++ b/crypto/keys/secp256k1/secp256k1.go @@ -42,7 +42,7 @@ func (privKey *PrivKey) PubKey() cryptotypes.PubKey { // Equals - you probably don't need to use this. // Runs in constant time based on length of the -func (privKey *PrivKey) Equals(other cryptotypes.LedgerPrivKey) bool { +func (privKey *PrivKey) Equals(other cryptotypes.PrivKey) bool { return privKey.Type() == other.Type() && subtle.ConstantTimeCompare(privKey.Bytes(), other.Bytes()) == 1 } diff --git a/crypto/ledger/ledger_secp256k1.go b/crypto/ledger/ledger_secp256k1.go index 70e20001d8b7..4d0987327e90 100644 --- a/crypto/ledger/ledger_secp256k1.go +++ b/crypto/ledger/ledger_secp256k1.go @@ -43,7 +43,7 @@ type ( // This function is marked as unsafe as it will retrieve a pubkey without user verification. // It can only be used to verify a pubkey but never to create new accounts/keys. In that case, // please refer to NewPrivKeySecp256k1 -func NewPrivKeySecp256k1Unsafe(path *hd.BIP44Params) (types.LedgerPrivKey, error) { +func NewPrivKeySecp256k1Unsafe(path *hd.BIP44Params) (types.PrivKey, error) { device, err := getDevice() if err != nil { return nil, err @@ -55,12 +55,12 @@ func NewPrivKeySecp256k1Unsafe(path *hd.BIP44Params) (types.LedgerPrivKey, error return nil, err } - return PrivKey{CachedPubKey: pubKey.Bytes(), Path: path}, nil + return &PrivKey{CachedPubKey: pubKey.Bytes(), Path: path}, nil } // NewPrivKeySecp256k1 will generate a new key and store the public key for later use. // The request will require user confirmation and will show account and index in the device -func NewPrivKeySecp256k1(path *hd.BIP44Params, hrp string) (types.LedgerPrivKey, string, error) { +func NewPrivKeySecp256k1(path *hd.BIP44Params, hrp string) (types.PrivKey, string, error) { device, err := getDevice() if err != nil { return nil, "", err @@ -72,16 +72,18 @@ func NewPrivKeySecp256k1(path *hd.BIP44Params, hrp string) (types.LedgerPrivKey, return nil, "", err } - return PrivKey{CachedPubKey: pubKey.Bytes(), Path: &path}, addr, nil + return &PrivKey{CachedPubKey: pubKey.Bytes(), Path: path}, addr, nil } +var _ types.PrivKey = &PrivKey{} // Assert interface implementation. + // PubKey returns the cached public key. -func (pkl PrivKey) PubKey() types.PubKey { +func (pkl *PrivKey) PubKey() types.PubKey { return &secp256k1.PubKey{Key: pkl.CachedPubKey} } // Sign returns a secp256k1 signature for the corresponding message -func (pkl PrivKey) Sign(message []byte) ([]byte, error) { +func (pkl *PrivKey) Sign(message []byte) ([]byte, error) { device, err := getDevice() if err != nil { return nil, err @@ -130,28 +132,25 @@ func (pkl PrivKey) ValidateKey() error { } defer warnIfErrors(device.Close) - return validateKey(device, pkl) + return validateKey(device, &pkl) } -// AssertIsPrivKeyInner implements the PrivKey interface. It performs a no-op. -func (pkl *PrivKey) AssertIsPrivKeyInner() {} - // Bytes implements the PrivKey interface. It stores the cached public key so // we can verify the same key when we reconnect to a ledger. -func (pkl PrivKey) Bytes() []byte { +func (pkl *PrivKey) Bytes() []byte { return cdc.MustMarshalBinaryBare(pkl) } // Equals implements the PrivKey interface. It makes sure two private keys // refer to the same public key. -func (pkl PrivKey) Equals(other types.LedgerPrivKey) bool { - if otherKey, ok := other.(PrivKey); ok { +func (pkl *PrivKey) Equals(other types.PrivKey) bool { + if otherKey, ok := other.(*PrivKey); ok { return pkl.PubKey().Equals(otherKey.PubKey()) } return false } -func (pkl PrivKey) Type() string { return "PrivKey" } +func (pkl *PrivKey) Type() string { return "PrivKey" } // warnIfErrors wraps a function and writes a warning to stderr. This is required // to avoid ignoring errors when defer is used. Using defer may result in linter warnings. @@ -183,7 +182,7 @@ func getDevice() (SECP256K1, error) { return device, nil } -func validateKey(device SECP256K1, pkl PrivKey) error { +func validateKey(device SECP256K1, pkl *PrivKey) error { pub, err := getPubKeyUnsafe(device, pkl.Path) if err != nil { return err @@ -202,7 +201,7 @@ func validateKey(device SECP256K1, pkl PrivKey) error { // Communication is checked on NewPrivKeyLedger and PrivKeyFromBytes, returning // an error, so this should only trigger if the private key is held in memory // for a while before use. -func sign(device SECP256K1, pkl PrivKey, msg []byte) ([]byte, error) { +func sign(device SECP256K1, pkl *PrivKey, msg []byte) ([]byte, error) { err := validateKey(device, pkl) if err != nil { return nil, err diff --git a/crypto/ledger/ledger_test.go b/crypto/ledger/ledger_test.go index 24b5476fd7a7..cd8c491f274d 100644 --- a/crypto/ledger/ledger_test.go +++ b/crypto/ledger/ledger_test.go @@ -57,7 +57,7 @@ func TestPublicKeyUnsafeHDPath(t *testing.T) { const numIters = 10 - privKeys := make([]types.LedgerPrivKey, numIters) + privKeys := make([]types.PrivKey, numIters) // Check with device for i := uint32(0); i < 10; i++ { @@ -69,9 +69,8 @@ func TestPublicKeyUnsafeHDPath(t *testing.T) { require.NotNil(t, priv) // Check other methods - tmp := priv.(PrivKey) + tmp := priv.(*PrivKey) require.NoError(t, tmp.ValidateKey()) - (&tmp).AssertIsPrivKeyInner() pubKeyAddr, err := sdk.Bech32ifyPubKey(sdk.Bech32PubKeyTypeAccPub, priv.PubKey()) require.NoError(t, err) @@ -150,7 +149,7 @@ func TestPublicKeyHDPath(t *testing.T) { const numIters = 10 - privKeys := make([]types.LedgerPrivKey, numIters) + privKeys := make([]types.PrivKey, numIters) // Check with device for i := uint32(0); i < 10; i++ { @@ -169,9 +168,8 @@ func TestPublicKeyHDPath(t *testing.T) { "Is your device using test mnemonic: %s ?", testutil.TestMnemonic) // Check other methods - tmp := priv.(PrivKey) + tmp := priv.(*PrivKey) require.NoError(t, tmp.ValidateKey()) - (&tmp).AssertIsPrivKeyInner() pubKeyAddr, err := sdk.Bech32ifyPubKey(sdk.Bech32PubKeyTypeAccPub, priv.PubKey()) require.NoError(t, err) diff --git a/crypto/types/types.go b/crypto/types/types.go index eccdba73813d..228a4c61a811 100644 --- a/crypto/types/types.go +++ b/crypto/types/types.go @@ -16,28 +16,17 @@ type PubKey interface { Type() string } -// LedgerPrivKey defines a private key that is not a proto message. For now, -// LedgerSecp256k1 keys are not converted to proto.Message yet, this is why -// they use LedgerPrivKey instead of PrivKey. All other keys must use PrivKey -// instead of LedgerPrivKey. -// TODO https://github.com/cosmos/cosmos-sdk/issues/7357. -type LedgerPrivKey interface { +// PrivKey defines a private key and extends proto.Message. +type PrivKey interface { + proto.Message + Bytes() []byte Sign(msg []byte) ([]byte, error) PubKey() PubKey - Equals(LedgerPrivKey) bool + Equals(PrivKey) bool Type() string } -// PrivKey defines a private key and extends proto.Message. For now, it extends -// LedgerPrivKey (see godoc for LedgerPrivKey). Ultimately, we should remove -// LedgerPrivKey and add its methods here directly. -// TODO https://github.com/cosmos/cosmos-sdk/issues/7357. -type PrivKey interface { - proto.Message - LedgerPrivKey -} - type ( Address = tmcrypto.Address ) From afc212eac18acc3cf8ecea2a6898664686e402ad Mon Sep 17 00:00:00 2001 From: Amaury Martiny Date: Tue, 10 Nov 2020 11:43:00 +0100 Subject: [PATCH 3/7] Fix package name --- crypto/hd/hd.pb.go | 35 +++++++++---------- crypto/ledger/keys.pb.go | 27 +++++++------- proto/cosmos/base/hd/v1beta1/hd.proto | 2 +- .../ledger/secp256k1/v1beta1/keys.proto | 3 +- 4 files changed, 32 insertions(+), 35 deletions(-) diff --git a/crypto/hd/hd.pb.go b/crypto/hd/hd.pb.go index a8d6c1ce5dc8..7bc82a754f8c 100644 --- a/crypto/hd/hd.pb.go +++ b/crypto/hd/hd.pb.go @@ -103,31 +103,30 @@ func (m *BIP44Params) GetAddressIndex() uint32 { } func init() { - proto.RegisterType((*BIP44Params)(nil), "cosmos.crypto.ledger.secp256k1.BIP44Params") + proto.RegisterType((*BIP44Params)(nil), "cosmos.base.hd.v1beta1.BIP44Params") } func init() { proto.RegisterFile("cosmos/base/hd/v1beta1/hd.proto", fileDescriptor_2b1a395a5fd792cd) } var fileDescriptor_2b1a395a5fd792cd = []byte{ - // 273 bytes of a gzipped FileDescriptorProto + // 262 bytes of a gzipped FileDescriptorProto 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0x92, 0x4f, 0xce, 0x2f, 0xce, 0xcd, 0x2f, 0xd6, 0x4f, 0x4a, 0x2c, 0x4e, 0xd5, 0xcf, 0x48, 0xd1, 0x2f, 0x33, 0x4c, 0x4a, 0x2d, - 0x49, 0x34, 0xd4, 0xcf, 0x48, 0xd1, 0x2b, 0x28, 0xca, 0x2f, 0xc9, 0x17, 0x92, 0x83, 0x28, 0xd0, - 0x4b, 0x2e, 0xaa, 0x2c, 0x28, 0xc9, 0xd7, 0xcb, 0x49, 0x4d, 0x49, 0x4f, 0x2d, 0xd2, 0x2b, 0x4e, - 0x4d, 0x2e, 0x30, 0x32, 0x35, 0xcb, 0x36, 0x94, 0x12, 0x49, 0xcf, 0x4f, 0xcf, 0x07, 0x2b, 0xd5, - 0x07, 0xb1, 0x20, 0xba, 0x94, 0xe6, 0x33, 0x72, 0x71, 0x3b, 0x79, 0x06, 0x98, 0x98, 0x04, 0x24, - 0x16, 0x25, 0xe6, 0x16, 0x0b, 0x49, 0x70, 0xb1, 0x07, 0x94, 0x16, 0x15, 0xe4, 0x17, 0xa7, 0x4a, - 0x30, 0x2a, 0x30, 0x6a, 0xf0, 0x06, 0xc1, 0xb8, 0x42, 0x52, 0x5c, 0x1c, 0xce, 0xf9, 0x99, 0x79, - 0x21, 0x95, 0x05, 0xa9, 0x12, 0x4c, 0x60, 0x29, 0x38, 0x1f, 0xa4, 0xcb, 0x31, 0x39, 0x39, 0xbf, - 0x34, 0xaf, 0x44, 0x82, 0x19, 0xa2, 0x0b, 0xca, 0x15, 0x12, 0xe3, 0x62, 0x73, 0xce, 0x48, 0xcc, - 0x4b, 0x4f, 0x95, 0x60, 0x51, 0x60, 0xd4, 0xe0, 0x08, 0x82, 0xf2, 0x84, 0x94, 0xb8, 0x78, 0x1c, - 0x53, 0x52, 0x8a, 0x52, 0x8b, 0x8b, 0x3d, 0xf3, 0x52, 0x52, 0x2b, 0x24, 0x58, 0xc1, 0xda, 0x50, - 0xc4, 0xac, 0x58, 0x66, 0x2c, 0x90, 0x67, 0x70, 0x72, 0x38, 0xf1, 0x48, 0x8e, 0xf1, 0xc2, 0x23, - 0x39, 0xc6, 0x07, 0x8f, 0xe4, 0x18, 0x27, 0x3c, 0x96, 0x63, 0xb8, 0xf0, 0x58, 0x8e, 0xe1, 0xc6, - 0x63, 0x39, 0x86, 0x28, 0xb5, 0xf4, 0xcc, 0x92, 0x8c, 0xd2, 0x24, 0xbd, 0xe4, 0xfc, 0x5c, 0x7d, - 0x68, 0xe8, 0x40, 0x28, 0xdd, 0xe2, 0x94, 0x6c, 0x7d, 0x48, 0x38, 0xe8, 0x67, 0xa4, 0x24, 0xb1, - 0x81, 0xbd, 0x6a, 0x0c, 0x08, 0x00, 0x00, 0xff, 0xff, 0xa0, 0x53, 0x3c, 0x20, 0x43, 0x01, 0x00, - 0x00, + 0x49, 0x34, 0xd4, 0xcf, 0x48, 0xd1, 0x2b, 0x28, 0xca, 0x2f, 0xc9, 0x17, 0x12, 0x83, 0x28, 0xd0, + 0x03, 0x29, 0xd0, 0xcb, 0x48, 0xd1, 0x83, 0x2a, 0x90, 0x12, 0x49, 0xcf, 0x4f, 0xcf, 0x07, 0x2b, + 0xd1, 0x07, 0xb1, 0x20, 0xaa, 0x95, 0xe6, 0x33, 0x72, 0x71, 0x3b, 0x79, 0x06, 0x98, 0x98, 0x04, + 0x24, 0x16, 0x25, 0xe6, 0x16, 0x0b, 0x49, 0x70, 0xb1, 0x07, 0x94, 0x16, 0x15, 0xe4, 0x17, 0xa7, + 0x4a, 0x30, 0x2a, 0x30, 0x6a, 0xf0, 0x06, 0xc1, 0xb8, 0x42, 0x52, 0x5c, 0x1c, 0xce, 0xf9, 0x99, + 0x79, 0x21, 0x95, 0x05, 0xa9, 0x12, 0x4c, 0x60, 0x29, 0x38, 0x1f, 0xa4, 0xcb, 0x31, 0x39, 0x39, + 0xbf, 0x34, 0xaf, 0x44, 0x82, 0x19, 0xa2, 0x0b, 0xca, 0x15, 0x12, 0xe3, 0x62, 0x73, 0xce, 0x48, + 0xcc, 0x4b, 0x4f, 0x95, 0x60, 0x51, 0x60, 0xd4, 0xe0, 0x08, 0x82, 0xf2, 0x84, 0x94, 0xb8, 0x78, + 0x1c, 0x53, 0x52, 0x8a, 0x52, 0x8b, 0x8b, 0x3d, 0xf3, 0x52, 0x52, 0x2b, 0x24, 0x58, 0xc1, 0xda, + 0x50, 0xc4, 0xac, 0x58, 0x66, 0x2c, 0x90, 0x67, 0x70, 0x72, 0x38, 0xf1, 0x48, 0x8e, 0xf1, 0xc2, + 0x23, 0x39, 0xc6, 0x07, 0x8f, 0xe4, 0x18, 0x27, 0x3c, 0x96, 0x63, 0xb8, 0xf0, 0x58, 0x8e, 0xe1, + 0xc6, 0x63, 0x39, 0x86, 0x28, 0xb5, 0xf4, 0xcc, 0x92, 0x8c, 0xd2, 0x24, 0xbd, 0xe4, 0xfc, 0x5c, + 0x7d, 0x68, 0xa8, 0x40, 0x28, 0xdd, 0xe2, 0x94, 0x6c, 0xfd, 0xe4, 0xa2, 0xca, 0x82, 0x92, 0x7c, + 0xfd, 0x8c, 0x94, 0x24, 0x36, 0xb0, 0x57, 0x8d, 0x01, 0x01, 0x00, 0x00, 0xff, 0xff, 0xf0, 0x95, + 0x7c, 0x0e, 0x3b, 0x01, 0x00, 0x00, } func (m *BIP44Params) Marshal() (dAtA []byte, err error) { diff --git a/crypto/ledger/keys.pb.go b/crypto/ledger/keys.pb.go index b19a51d4249a..fee0208ef0b3 100644 --- a/crypto/ledger/keys.pb.go +++ b/crypto/ledger/keys.pb.go @@ -6,7 +6,6 @@ package ledger import ( fmt "fmt" hd "github.com/cosmos/cosmos-sdk/crypto/hd" - _ "github.com/gogo/protobuf/gogoproto" proto "github.com/gogo/protobuf/proto" io "io" math "math" @@ -90,23 +89,23 @@ func init() { } var fileDescriptor_88e789035e83c74f = []byte{ - // 256 bytes of a gzipped FileDescriptorProto + // 251 bytes of a gzipped FileDescriptorProto 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0x32, 0x4c, 0xce, 0x2f, 0xce, 0xcd, 0x2f, 0xd6, 0x4f, 0x2e, 0xaa, 0x2c, 0x28, 0xc9, 0xd7, 0xcf, 0x49, 0x4d, 0x49, 0x4f, 0x2d, 0xd2, 0x2f, 0x4e, 0x4d, 0x2e, 0x30, 0x32, 0x35, 0xcb, 0x36, 0xd4, 0x2f, 0x33, 0x4c, 0x4a, 0x2d, 0x49, 0x34, 0xd4, 0xcf, 0x4e, 0xad, 0x2c, 0xd6, 0x2b, 0x28, 0xca, 0x2f, 0xc9, 0x17, 0x52, 0x83, - 0x68, 0xd1, 0x83, 0x68, 0xd1, 0x83, 0x68, 0xd1, 0x83, 0x6b, 0xd1, 0x83, 0x6a, 0x91, 0x12, 0x49, - 0xcf, 0x4f, 0xcf, 0x07, 0x6b, 0xd1, 0x07, 0xb1, 0x20, 0xba, 0xa5, 0xe4, 0xa1, 0x16, 0x26, 0x25, - 0x16, 0xa7, 0xea, 0x67, 0xa4, 0xc0, 0x2d, 0xc8, 0x48, 0x81, 0x28, 0x50, 0x2a, 0xe0, 0x62, 0x0f, - 0x28, 0xca, 0x2c, 0xf3, 0x4e, 0xad, 0x14, 0xb2, 0xe7, 0x62, 0x29, 0x48, 0x2c, 0xc9, 0x90, 0x60, - 0x54, 0x60, 0xd4, 0xe0, 0x36, 0xd2, 0xd6, 0x23, 0x60, 0xb1, 0x93, 0x67, 0x80, 0x89, 0x49, 0x40, - 0x62, 0x51, 0x62, 0x6e, 0x71, 0x10, 0x58, 0xa3, 0x90, 0x0a, 0x17, 0x5f, 0x72, 0x62, 0x72, 0x46, - 0x6a, 0x4a, 0x7c, 0x41, 0x69, 0x52, 0x7c, 0x76, 0x6a, 0xa5, 0x04, 0x93, 0x02, 0xa3, 0x06, 0x4f, - 0x10, 0x0f, 0x44, 0x34, 0xa0, 0x34, 0xc9, 0x3b, 0xb5, 0xd2, 0xc9, 0xe5, 0xc4, 0x23, 0x39, 0xc6, - 0x0b, 0x8f, 0xe4, 0x18, 0x1f, 0x3c, 0x92, 0x63, 0x9c, 0xf0, 0x58, 0x8e, 0xe1, 0xc2, 0x63, 0x39, - 0x86, 0x1b, 0x8f, 0xe5, 0x18, 0xa2, 0xb4, 0xd2, 0x33, 0x4b, 0x32, 0x4a, 0x93, 0xf4, 0x92, 0xf3, - 0x73, 0xf5, 0x61, 0x01, 0x05, 0xa6, 0x74, 0x8b, 0x53, 0xb2, 0x51, 0xc3, 0x2c, 0x89, 0x0d, 0xec, - 0x7c, 0x63, 0x40, 0x00, 0x00, 0x00, 0xff, 0xff, 0x78, 0xa2, 0x67, 0xd2, 0x52, 0x01, 0x00, 0x00, + 0x68, 0xd1, 0x83, 0x68, 0xd1, 0x83, 0x68, 0xd1, 0x83, 0x6b, 0xd1, 0x83, 0x6a, 0x91, 0x92, 0x87, + 0x1a, 0x9d, 0x94, 0x58, 0x9c, 0xaa, 0x9f, 0x91, 0x02, 0x37, 0x2a, 0x23, 0x05, 0x62, 0x90, 0x52, + 0x06, 0x17, 0x7b, 0x40, 0x51, 0x66, 0x99, 0x77, 0x6a, 0xa5, 0x90, 0x39, 0x17, 0x4b, 0x41, 0x62, + 0x49, 0x86, 0x04, 0xa3, 0x02, 0xa3, 0x06, 0xb7, 0x91, 0xb2, 0x1e, 0xd4, 0x0a, 0x90, 0x56, 0xbd, + 0x8c, 0x14, 0x98, 0x91, 0x7a, 0x4e, 0x9e, 0x01, 0x26, 0x26, 0x01, 0x89, 0x45, 0x89, 0xb9, 0xc5, + 0x41, 0x60, 0x0d, 0x42, 0x2a, 0x5c, 0x7c, 0xc9, 0x89, 0xc9, 0x19, 0xa9, 0x29, 0xf1, 0x05, 0xa5, + 0x49, 0xf1, 0xd9, 0xa9, 0x95, 0x12, 0x4c, 0x0a, 0x8c, 0x1a, 0x3c, 0x41, 0x3c, 0x10, 0xd1, 0x80, + 0xd2, 0x24, 0xef, 0xd4, 0x4a, 0x27, 0x97, 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, 0xd2, 0x4a, 0xcf, 0x2c, 0xc9, 0x28, 0x4d, 0xd2, 0x4b, 0xce, 0xcf, 0xd5, 0x87, 0x05, 0x05, + 0x98, 0xd2, 0x2d, 0x4e, 0xc9, 0x46, 0x0d, 0x95, 0x24, 0x36, 0xb0, 0xb3, 0x8d, 0x01, 0x01, 0x00, + 0x00, 0xff, 0xff, 0x7b, 0x15, 0x09, 0xe9, 0x34, 0x01, 0x00, 0x00, } func (m *PrivKey) Marshal() (dAtA []byte, err error) { diff --git a/proto/cosmos/base/hd/v1beta1/hd.proto b/proto/cosmos/base/hd/v1beta1/hd.proto index eb0d2406bb68..86503e987d62 100644 --- a/proto/cosmos/base/hd/v1beta1/hd.proto +++ b/proto/cosmos/base/hd/v1beta1/hd.proto @@ -1,5 +1,5 @@ syntax = "proto3"; -package cosmos.crypto.ledger.secp256k1; +package cosmos.base.hd.v1beta1; import "gogoproto/gogo.proto"; diff --git a/proto/cosmos/crypto/ledger/secp256k1/v1beta1/keys.proto b/proto/cosmos/crypto/ledger/secp256k1/v1beta1/keys.proto index 2638de0d192a..a86354d42025 100644 --- a/proto/cosmos/crypto/ledger/secp256k1/v1beta1/keys.proto +++ b/proto/cosmos/crypto/ledger/secp256k1/v1beta1/keys.proto @@ -3,13 +3,12 @@ package cosmos.crypto.ledger.secp256k1.v1beta1; option go_package = "github.com/cosmos/cosmos-sdk/crypto/ledger"; -import "gogoproto/gogo.proto"; import "cosmos/base/hd/v1beta1/hd.proto"; // PrivKey defines a Ledger hardware wallet secp256k1 private key. message PrivKey { // path is the derivation path used to generate the private key. - BIP44Params path = 1; + cosmos.base.hd.v1beta1.BIP44Params path = 1; // cached_pub_key is an utility field used to cache the key's public key, // so that we don't need to query the Ledger each time we need to access From 37d1c25946f672aa2865e8e31f08893cb207ab73 Mon Sep 17 00:00:00 2001 From: Amaury Martiny Date: Tue, 10 Nov 2020 11:56:26 +0100 Subject: [PATCH 4/7] Fix proto lint --- crypto/hd/hd.pb.go | 46 +++++++++++++-------------- proto/cosmos/base/hd/v1beta1/hd.proto | 10 +++--- 2 files changed, 28 insertions(+), 28 deletions(-) diff --git a/crypto/hd/hd.pb.go b/crypto/hd/hd.pb.go index 7bc82a754f8c..884487a44555 100644 --- a/crypto/hd/hd.pb.go +++ b/crypto/hd/hd.pb.go @@ -28,11 +28,11 @@ const _ = proto.GoGoProtoPackageIsVersion3 // please upgrade the proto package // m / purpose' / coinType' / account' / change / addressIndex // call String() on a BIP44Params instance. type BIP44Params struct { - Purpose uint32 `protobuf:"varint,1,opt,name=Purpose,proto3" json:"Purpose,omitempty"` - CoinType uint32 `protobuf:"varint,2,opt,name=CoinType,proto3" json:"CoinType,omitempty"` - Account uint32 `protobuf:"varint,3,opt,name=Account,proto3" json:"Account,omitempty"` - Change bool `protobuf:"varint,4,opt,name=Change,proto3" json:"Change,omitempty"` - AddressIndex uint32 `protobuf:"varint,5,opt,name=AddressIndex,proto3" json:"AddressIndex,omitempty"` + Purpose uint32 `protobuf:"varint,1,opt,name=purpose,proto3" json:"purpose,omitempty"` + CoinType uint32 `protobuf:"varint,2,opt,name=coin_type,json=coinType,proto3" json:"coin_type,omitempty"` + Account uint32 `protobuf:"varint,3,opt,name=account,proto3" json:"account,omitempty"` + Change bool `protobuf:"varint,4,opt,name=change,proto3" json:"change,omitempty"` + AddressIndex uint32 `protobuf:"varint,5,opt,name=address_index,json=addressIndex,proto3" json:"address_index,omitempty"` } func (m *BIP44Params) Reset() { *m = BIP44Params{} } @@ -109,24 +109,24 @@ func init() { func init() { proto.RegisterFile("cosmos/base/hd/v1beta1/hd.proto", fileDescriptor_2b1a395a5fd792cd) } var fileDescriptor_2b1a395a5fd792cd = []byte{ - // 262 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0x92, 0x4f, 0xce, 0x2f, 0xce, - 0xcd, 0x2f, 0xd6, 0x4f, 0x4a, 0x2c, 0x4e, 0xd5, 0xcf, 0x48, 0xd1, 0x2f, 0x33, 0x4c, 0x4a, 0x2d, - 0x49, 0x34, 0xd4, 0xcf, 0x48, 0xd1, 0x2b, 0x28, 0xca, 0x2f, 0xc9, 0x17, 0x12, 0x83, 0x28, 0xd0, - 0x03, 0x29, 0xd0, 0xcb, 0x48, 0xd1, 0x83, 0x2a, 0x90, 0x12, 0x49, 0xcf, 0x4f, 0xcf, 0x07, 0x2b, - 0xd1, 0x07, 0xb1, 0x20, 0xaa, 0x95, 0xe6, 0x33, 0x72, 0x71, 0x3b, 0x79, 0x06, 0x98, 0x98, 0x04, - 0x24, 0x16, 0x25, 0xe6, 0x16, 0x0b, 0x49, 0x70, 0xb1, 0x07, 0x94, 0x16, 0x15, 0xe4, 0x17, 0xa7, - 0x4a, 0x30, 0x2a, 0x30, 0x6a, 0xf0, 0x06, 0xc1, 0xb8, 0x42, 0x52, 0x5c, 0x1c, 0xce, 0xf9, 0x99, - 0x79, 0x21, 0x95, 0x05, 0xa9, 0x12, 0x4c, 0x60, 0x29, 0x38, 0x1f, 0xa4, 0xcb, 0x31, 0x39, 0x39, - 0xbf, 0x34, 0xaf, 0x44, 0x82, 0x19, 0xa2, 0x0b, 0xca, 0x15, 0x12, 0xe3, 0x62, 0x73, 0xce, 0x48, - 0xcc, 0x4b, 0x4f, 0x95, 0x60, 0x51, 0x60, 0xd4, 0xe0, 0x08, 0x82, 0xf2, 0x84, 0x94, 0xb8, 0x78, - 0x1c, 0x53, 0x52, 0x8a, 0x52, 0x8b, 0x8b, 0x3d, 0xf3, 0x52, 0x52, 0x2b, 0x24, 0x58, 0xc1, 0xda, - 0x50, 0xc4, 0xac, 0x58, 0x66, 0x2c, 0x90, 0x67, 0x70, 0x72, 0x38, 0xf1, 0x48, 0x8e, 0xf1, 0xc2, - 0x23, 0x39, 0xc6, 0x07, 0x8f, 0xe4, 0x18, 0x27, 0x3c, 0x96, 0x63, 0xb8, 0xf0, 0x58, 0x8e, 0xe1, - 0xc6, 0x63, 0x39, 0x86, 0x28, 0xb5, 0xf4, 0xcc, 0x92, 0x8c, 0xd2, 0x24, 0xbd, 0xe4, 0xfc, 0x5c, - 0x7d, 0x68, 0xa8, 0x40, 0x28, 0xdd, 0xe2, 0x94, 0x6c, 0xfd, 0xe4, 0xa2, 0xca, 0x82, 0x92, 0x7c, - 0xfd, 0x8c, 0x94, 0x24, 0x36, 0xb0, 0x57, 0x8d, 0x01, 0x01, 0x00, 0x00, 0xff, 0xff, 0xf0, 0x95, - 0x7c, 0x0e, 0x3b, 0x01, 0x00, 0x00, + // 271 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x34, 0x90, 0xb1, 0x4e, 0xc3, 0x30, + 0x10, 0x86, 0x63, 0x28, 0xa5, 0x18, 0xba, 0x44, 0xa8, 0xb2, 0x40, 0x72, 0x2b, 0x90, 0x50, 0x17, + 0x62, 0x55, 0x74, 0x62, 0x42, 0xdd, 0xba, 0x55, 0x15, 0x13, 0x4b, 0xe5, 0xd8, 0x56, 0x1c, 0xa1, + 0xe4, 0xac, 0xd8, 0x41, 0xe4, 0x2d, 0x18, 0x19, 0xe1, 0x6d, 0x18, 0x3b, 0x32, 0xa2, 0xe4, 0x45, + 0x50, 0x12, 0x77, 0xb2, 0xff, 0xff, 0xbe, 0x6f, 0xb8, 0xc3, 0x53, 0x01, 0x36, 0x03, 0xcb, 0x62, + 0x6e, 0x15, 0xd3, 0x92, 0xbd, 0x2d, 0x62, 0xe5, 0xf8, 0x82, 0x69, 0x19, 0x99, 0x02, 0x1c, 0x84, + 0x93, 0x1e, 0x88, 0x5a, 0x20, 0xd2, 0x32, 0xf2, 0xc0, 0xd5, 0x65, 0x02, 0x09, 0x74, 0x08, 0x6b, + 0x7f, 0x3d, 0x7d, 0xf3, 0x8d, 0xf0, 0xf9, 0x6a, 0xbd, 0x59, 0x2e, 0x37, 0xbc, 0xe0, 0x99, 0x0d, + 0x09, 0x3e, 0x35, 0x65, 0x61, 0xc0, 0x2a, 0x82, 0x66, 0x68, 0x3e, 0xde, 0x1e, 0x62, 0x78, 0x8d, + 0xcf, 0x04, 0xa4, 0xf9, 0xce, 0x55, 0x46, 0x91, 0xa3, 0x6e, 0x36, 0x6a, 0x8b, 0xe7, 0xca, 0xa8, + 0x56, 0xe3, 0x42, 0x40, 0x99, 0x3b, 0x72, 0xdc, 0x6b, 0x3e, 0x86, 0x13, 0x3c, 0x14, 0x9a, 0xe7, + 0x89, 0x22, 0x83, 0x19, 0x9a, 0x8f, 0xb6, 0x3e, 0x85, 0xb7, 0x78, 0xcc, 0xa5, 0x2c, 0x94, 0xb5, + 0xbb, 0x34, 0x97, 0xea, 0x9d, 0x9c, 0x74, 0xde, 0x85, 0x2f, 0xd7, 0x6d, 0xf7, 0x38, 0xf8, 0xfc, + 0x9a, 0x06, 0xab, 0xa7, 0x9f, 0x9a, 0xa2, 0x7d, 0x4d, 0xd1, 0x5f, 0x4d, 0xd1, 0x47, 0x43, 0x83, + 0x7d, 0x43, 0x83, 0xdf, 0x86, 0x06, 0x2f, 0x77, 0x49, 0xea, 0x74, 0x19, 0x47, 0x02, 0x32, 0xe6, + 0xef, 0xd2, 0x3f, 0xf7, 0x56, 0xbe, 0x32, 0x51, 0x54, 0xc6, 0x01, 0xd3, 0x32, 0x1e, 0x76, 0xcb, + 0x3e, 0xfc, 0x07, 0x00, 0x00, 0xff, 0xff, 0x1d, 0x56, 0x0b, 0xa8, 0x3d, 0x01, 0x00, 0x00, } func (m *BIP44Params) Marshal() (dAtA []byte, err error) { diff --git a/proto/cosmos/base/hd/v1beta1/hd.proto b/proto/cosmos/base/hd/v1beta1/hd.proto index 86503e987d62..1d4439142e0d 100644 --- a/proto/cosmos/base/hd/v1beta1/hd.proto +++ b/proto/cosmos/base/hd/v1beta1/hd.proto @@ -12,9 +12,9 @@ option go_package = "github.com/cosmos/cosmos-sdk/crypto/hd"; message BIP44Params { option (gogoproto.goproto_stringer) = false; - uint32 Purpose = 1; - uint32 CoinType = 2; - uint32 Account = 3; - bool Change = 4; - uint32 AddressIndex = 5; + uint32 purpose = 1; + uint32 coin_type = 2; + uint32 account = 3; + bool change = 4; + uint32 address_index = 5; } From 03e8f4df58455336c6fdb47198dd4ac596a4b8f0 Mon Sep 17 00:00:00 2001 From: Amaury Martiny Date: Mon, 16 Nov 2020 13:20:45 +0100 Subject: [PATCH 5/7] Remove amino from ledger --- crypto/ledger/amino.go | 19 --------- crypto/ledger/encode_test.go | 68 ++++++++++++------------------- crypto/ledger/ledger_secp256k1.go | 8 +++- crypto/ledger/ledger_test.go | 40 ++++++++++-------- 4 files changed, 57 insertions(+), 78 deletions(-) delete mode 100644 crypto/ledger/amino.go diff --git a/crypto/ledger/amino.go b/crypto/ledger/amino.go deleted file mode 100644 index 677241deec6d..000000000000 --- a/crypto/ledger/amino.go +++ /dev/null @@ -1,19 +0,0 @@ -package ledger - -import ( - "github.com/cosmos/cosmos-sdk/codec" - cryptoAmino "github.com/cosmos/cosmos-sdk/crypto/codec" -) - -var cdc = codec.NewLegacyAmino() - -func init() { - RegisterAmino(cdc) - cryptoAmino.RegisterCrypto(cdc) -} - -// RegisterAmino registers all go-crypto related types in the given (amino) codec. -func RegisterAmino(cdc *codec.LegacyAmino) { - cdc.RegisterConcrete(PrivKey{}, - "tendermint/PrivKeyLedgerSecp256k1", nil) -} diff --git a/crypto/ledger/encode_test.go b/crypto/ledger/encode_test.go index 447891fde768..c18b0462c95f 100644 --- a/crypto/ledger/encode_test.go +++ b/crypto/ledger/encode_test.go @@ -1,63 +1,47 @@ -package ledger +package ledger_test import ( - "os" "testing" + proto "github.com/gogo/protobuf/proto" "github.com/stretchr/testify/require" - cryptotypes "github.com/cosmos/cosmos-sdk/crypto/types" + hd "github.com/cosmos/cosmos-sdk/crypto/hd" + "github.com/cosmos/cosmos-sdk/crypto/ledger" + "github.com/cosmos/cosmos-sdk/crypto/types" + "github.com/cosmos/cosmos-sdk/simapp" + sdk "github.com/cosmos/cosmos-sdk/types" ) type byter interface { Bytes() []byte } -func checkAminoJSON(t *testing.T, src interface{}, dst interface{}, isNil bool) { +func checkProtoJSON(t *testing.T, src proto.Message, dst proto.Message) { + cdc := simapp.MakeTestEncodingConfig().Marshaler + // Marshal to JSON bytes. js, err := cdc.MarshalJSON(src) require.Nil(t, err, "%+v", err) - if isNil { - require.Equal(t, string(js), `null`) - } else { - require.Contains(t, string(js), `"type":`) - require.Contains(t, string(js), `"value":`) - } + require.Contains(t, string(js), `"path":`) + require.Contains(t, string(js), `"cached_pub_key":`) // Unmarshal. err = cdc.UnmarshalJSON(js, dst) require.Nil(t, err, "%+v", err) } -// nolint: govet -func ExamplePrintRegisteredTypes() { - cdc.PrintTypes(os.Stdout) - // | Type | Name | Prefix | Length | Notes | - // | ---- | ---- | ------ | ----- | ------ | - // | PrivKeyLedgerSecp256k1 | tendermint/PrivKeyLedgerSecp256k1 | 0x10CAB393 | variable | | - // | PubKey | tendermint/PubKeyEd25519 | 0x1624DE64 | variable | | - // | PubKey | tendermint/PubKeySr25519 | 0x0DFB1005 | variable | | - // | PubKey | tendermint/PubKeySecp256k1 | 0xEB5AE987 | variable | | - // | PubKeyMultisigThreshold | tendermint/PubKeyMultisigThreshold | 0x22C1F7E2 | variable | | - // | PrivKey | tendermint/PrivKeyEd25519 | 0xA3288910 | variable | | - // | PrivKey | tendermint/PrivKeySr25519 | 0x2F82D78B | variable | | - // | PrivKey | tendermint/PrivKeySecp256k1 | 0xE1B0F79B | variable | | -} - -func TestNilEncodings(t *testing.T) { - - // Check nil Signature. - var a, b []byte - checkAminoJSON(t, &a, &b, true) - require.EqualValues(t, a, b) - - // Check nil PubKey. - var c, d cryptotypes.PubKey - checkAminoJSON(t, &c, &d, true) - require.EqualValues(t, c, d) - - // Check nil PrivKey. - var e, f cryptotypes.PrivKey - checkAminoJSON(t, &e, &f, true) - require.EqualValues(t, e, f) - +func TestEncodings(t *testing.T) { + // Check PrivKey. + path := hd.NewFundraiserParams(0, sdk.CoinType, 0) + priv1, err := ledger.NewPrivKeySecp256k1Unsafe(path) + require.NoError(t, err) + var priv2 types.PrivKey + checkProtoJSON(t, priv1, priv2) + require.EqualValues(t, priv1, priv2) + + // Check PubKey. + // pub1 := priv1.PubKey() + // var pub2 types.PubKey + // checkProtoJSON(t, pub1, pub2) + // require.EqualValues(t, pub1, pub2) } diff --git a/crypto/ledger/ledger_secp256k1.go b/crypto/ledger/ledger_secp256k1.go index 4d0987327e90..cdb406daeab8 100644 --- a/crypto/ledger/ledger_secp256k1.go +++ b/crypto/ledger/ledger_secp256k1.go @@ -5,6 +5,7 @@ import ( "os" "github.com/btcsuite/btcd/btcec" + proto "github.com/gogo/protobuf/proto" "github.com/pkg/errors" tmbtcec "github.com/tendermint/btcd/btcec" @@ -138,7 +139,12 @@ func (pkl PrivKey) ValidateKey() error { // Bytes implements the PrivKey interface. It stores the cached public key so // we can verify the same key when we reconnect to a ledger. func (pkl *PrivKey) Bytes() []byte { - return cdc.MustMarshalBinaryBare(pkl) + bz, err := proto.Marshal(pkl) + if err != nil { + panic(err) + } + + return bz } // Equals implements the PrivKey interface. It makes sure two private keys diff --git a/crypto/ledger/ledger_test.go b/crypto/ledger/ledger_test.go index cd8c491f274d..5e36fce3b500 100644 --- a/crypto/ledger/ledger_test.go +++ b/crypto/ledger/ledger_test.go @@ -1,13 +1,15 @@ -package ledger +package ledger_test import ( "fmt" "testing" + proto "github.com/gogo/protobuf/proto" "github.com/stretchr/testify/require" cryptoAmino "github.com/cosmos/cosmos-sdk/crypto/codec" "github.com/cosmos/cosmos-sdk/crypto/hd" + "github.com/cosmos/cosmos-sdk/crypto/ledger" "github.com/cosmos/cosmos-sdk/crypto/types" "github.com/cosmos/cosmos-sdk/testutil" sdk "github.com/cosmos/cosmos-sdk/types" @@ -17,18 +19,20 @@ func TestErrorHandling(t *testing.T) { // first, try to generate a key, must return an error // (no panic) path := hd.NewParams(44, 555, 0, false, 0) - _, err := NewPrivKeySecp256k1Unsafe(path) + _, err := ledger.NewPrivKeySecp256k1Unsafe(path) require.Error(t, err) } func TestPublicKeyUnsafe(t *testing.T) { path := hd.NewFundraiserParams(0, sdk.CoinType, 0) - priv, err := NewPrivKeySecp256k1Unsafe(path) + priv, err := ledger.NewPrivKeySecp256k1Unsafe(path) require.Nil(t, err, "%s", err) require.NotNil(t, priv) + bs, err := proto.Marshal(priv.PubKey()) + require.NoError(t, err) require.Equal(t, "eb5ae98721034fef9cd7c4c63588d3b03feb5281b9d232cba34d6f3d71aee59211ffbfe1fe87", - fmt.Sprintf("%x", cdc.Amino.MustMarshalBinaryBare(priv.PubKey())), + fmt.Sprintf("%x", bs), "Is your device using test mnemonic: %s ?", testutil.TestMnemonic) pubKeyAddr, err := sdk.Bech32ifyPubKey(sdk.Bech32PubKeyTypeAccPub, priv.PubKey()) @@ -64,12 +68,12 @@ func TestPublicKeyUnsafeHDPath(t *testing.T) { path := hd.NewFundraiserParams(0, sdk.CoinType, i) fmt.Printf("Checking keys at %v\n", path) - priv, err := NewPrivKeySecp256k1Unsafe(path) + priv, err := ledger.NewPrivKeySecp256k1Unsafe(path) require.Nil(t, err, "%s", err) require.NotNil(t, priv) // Check other methods - tmp := priv.(*PrivKey) + tmp := priv.(*ledger.PrivKey) require.NoError(t, tmp.ValidateKey()) pubKeyAddr, err := sdk.Bech32ifyPubKey(sdk.Bech32PubKeyTypeAccPub, priv.PubKey()) @@ -97,15 +101,17 @@ func TestPublicKeyUnsafeHDPath(t *testing.T) { func TestPublicKeySafe(t *testing.T) { path := hd.NewFundraiserParams(0, sdk.CoinType, 0) - priv, addr, err := NewPrivKeySecp256k1(path, "cosmos") + priv, addr, err := ledger.NewPrivKeySecp256k1(path, "cosmos") require.Nil(t, err, "%s", err) require.NotNil(t, priv) - require.Nil(t, ShowAddress(path, priv.PubKey(), sdk.GetConfig().GetBech32AccountAddrPrefix())) + require.Nil(t, ledger.ShowAddress(path, priv.PubKey(), sdk.GetConfig().GetBech32AccountAddrPrefix())) + bs, err := proto.Marshal(priv.PubKey()) + require.NoError(t, err) require.Equal(t, "eb5ae98721034fef9cd7c4c63588d3b03feb5281b9d232cba34d6f3d71aee59211ffbfe1fe87", - fmt.Sprintf("%x", cdc.Amino.MustMarshalBinaryBare(priv.PubKey())), + fmt.Sprintf("%x", bs), "Is your device using test mnemonic: %s ?", testutil.TestMnemonic) pubKeyAddr, err := sdk.Bech32ifyPubKey(sdk.Bech32PubKeyTypeAccPub, priv.PubKey()) @@ -156,7 +162,7 @@ func TestPublicKeyHDPath(t *testing.T) { path := hd.NewFundraiserParams(0, sdk.CoinType, i) fmt.Printf("Checking keys at %v\n", path) - priv, addr, err := NewPrivKeySecp256k1(path, "cosmos") + priv, addr, err := ledger.NewPrivKeySecp256k1(path, "cosmos") require.Nil(t, err, "%s", err) require.NotNil(t, addr) require.NotNil(t, priv) @@ -168,7 +174,7 @@ func TestPublicKeyHDPath(t *testing.T) { "Is your device using test mnemonic: %s ?", testutil.TestMnemonic) // Check other methods - tmp := priv.(*PrivKey) + tmp := priv.(*ledger.PrivKey) require.NoError(t, tmp.ValidateKey()) pubKeyAddr, err := sdk.Bech32ifyPubKey(sdk.Bech32PubKeyTypeAccPub, priv.PubKey()) @@ -180,7 +186,7 @@ func TestPublicKeyHDPath(t *testing.T) { // Store and restore serializedPk := priv.Bytes() require.NotNil(t, serializedPk) - require.True(t, len(serializedPk) >= 50) + require.True(t, len(serializedPk) >= 40) privKeys[i] = priv } @@ -209,7 +215,7 @@ func TestSignaturesHD(t *testing.T) { path := hd.NewFundraiserParams(account, sdk.CoinType, account/5) fmt.Printf("Checking signature at %v --- PLEASE REVIEW AND ACCEPT IN THE DEVICE\n", path) - priv, err := NewPrivKeySecp256k1Unsafe(path) + priv, err := ledger.NewPrivKeySecp256k1Unsafe(path) require.Nil(t, err, "%s", err) pub := priv.PubKey() @@ -224,7 +230,7 @@ func TestSignaturesHD(t *testing.T) { func TestRealDeviceSecp256k1(t *testing.T) { msg := getFakeTx(50) path := hd.NewFundraiserParams(0, sdk.CoinType, 0) - priv, err := NewPrivKeySecp256k1Unsafe(path) + priv, err := ledger.NewPrivKeySecp256k1Unsafe(path) require.Nil(t, err, "%s", err) pub := priv.PubKey() @@ -235,7 +241,8 @@ func TestRealDeviceSecp256k1(t *testing.T) { require.True(t, valid) // now, let's serialize the public key and make sure it still works - bs := cdc.Amino.MustMarshalBinaryBare(priv.PubKey()) + bs, err := proto.Marshal(priv.PubKey()) + require.NoError(t, err) pub2, err := cryptoAmino.PubKeyFromBytes(bs) require.Nil(t, err, "%+v", err) @@ -249,7 +256,8 @@ func TestRealDeviceSecp256k1(t *testing.T) { require.True(t, valid) // make sure pubkeys serialize properly as well - bs = cdc.Amino.MustMarshalBinaryBare(pub) + bs, err = proto.Marshal(pub) + require.NoError(t, err) bpub, err := cryptoAmino.PubKeyFromBytes(bs) require.NoError(t, err) require.Equal(t, pub, bpub) From 9160670c3dbb34a000bf15e36e857d025e0be936 Mon Sep 17 00:00:00 2001 From: Amaury Martiny Date: Mon, 16 Nov 2020 13:40:40 +0100 Subject: [PATCH 6/7] Fix tests --- crypto/ledger/encode_test.go | 19 +++++++++---------- crypto/ledger/ledger_test.go | 26 ++++++++++++-------------- 2 files changed, 21 insertions(+), 24 deletions(-) diff --git a/crypto/ledger/encode_test.go b/crypto/ledger/encode_test.go index c18b0462c95f..914f87593ead 100644 --- a/crypto/ledger/encode_test.go +++ b/crypto/ledger/encode_test.go @@ -7,8 +7,8 @@ import ( "github.com/stretchr/testify/require" hd "github.com/cosmos/cosmos-sdk/crypto/hd" + "github.com/cosmos/cosmos-sdk/crypto/keys/secp256k1" "github.com/cosmos/cosmos-sdk/crypto/ledger" - "github.com/cosmos/cosmos-sdk/crypto/types" "github.com/cosmos/cosmos-sdk/simapp" sdk "github.com/cosmos/cosmos-sdk/types" ) @@ -23,8 +23,7 @@ func checkProtoJSON(t *testing.T, src proto.Message, dst proto.Message) { // Marshal to JSON bytes. js, err := cdc.MarshalJSON(src) require.Nil(t, err, "%+v", err) - require.Contains(t, string(js), `"path":`) - require.Contains(t, string(js), `"cached_pub_key":`) + require.Contains(t, string(js), `"A0/vnNfExjWI07A/61KBudIyy6NNbz1xruWSEf+/4f6H"`) // The pubkey bytes as base64. // Unmarshal. err = cdc.UnmarshalJSON(js, dst) require.Nil(t, err, "%+v", err) @@ -35,13 +34,13 @@ func TestEncodings(t *testing.T) { path := hd.NewFundraiserParams(0, sdk.CoinType, 0) priv1, err := ledger.NewPrivKeySecp256k1Unsafe(path) require.NoError(t, err) - var priv2 types.PrivKey - checkProtoJSON(t, priv1, priv2) - require.EqualValues(t, priv1, priv2) + var priv2 ledger.PrivKey + checkProtoJSON(t, priv1, &priv2) + require.EqualValues(t, priv1, &priv2) // Check PubKey. - // pub1 := priv1.PubKey() - // var pub2 types.PubKey - // checkProtoJSON(t, pub1, pub2) - // require.EqualValues(t, pub1, pub2) + pub1 := priv1.PubKey() + var pub2 secp256k1.PubKey + checkProtoJSON(t, pub1, &pub2) + require.EqualValues(t, pub1, &pub2) } diff --git a/crypto/ledger/ledger_test.go b/crypto/ledger/ledger_test.go index 5e36fce3b500..1e4bdd2f6204 100644 --- a/crypto/ledger/ledger_test.go +++ b/crypto/ledger/ledger_test.go @@ -7,8 +7,8 @@ import ( proto "github.com/gogo/protobuf/proto" "github.com/stretchr/testify/require" - cryptoAmino "github.com/cosmos/cosmos-sdk/crypto/codec" "github.com/cosmos/cosmos-sdk/crypto/hd" + "github.com/cosmos/cosmos-sdk/crypto/keys/secp256k1" "github.com/cosmos/cosmos-sdk/crypto/ledger" "github.com/cosmos/cosmos-sdk/crypto/types" "github.com/cosmos/cosmos-sdk/testutil" @@ -29,10 +29,8 @@ func TestPublicKeyUnsafe(t *testing.T) { require.Nil(t, err, "%s", err) require.NotNil(t, priv) - bs, err := proto.Marshal(priv.PubKey()) - require.NoError(t, err) - require.Equal(t, "eb5ae98721034fef9cd7c4c63588d3b03feb5281b9d232cba34d6f3d71aee59211ffbfe1fe87", - fmt.Sprintf("%x", bs), + require.Equal(t, "034fef9cd7c4c63588d3b03feb5281b9d232cba34d6f3d71aee59211ffbfe1fe87", + fmt.Sprintf("%x", priv.PubKey().Bytes()), "Is your device using test mnemonic: %s ?", testutil.TestMnemonic) pubKeyAddr, err := sdk.Bech32ifyPubKey(sdk.Bech32PubKeyTypeAccPub, priv.PubKey()) @@ -85,7 +83,7 @@ func TestPublicKeyUnsafeHDPath(t *testing.T) { // Store and restore serializedPk := priv.Bytes() require.NotNil(t, serializedPk) - require.True(t, len(serializedPk) >= 50) + require.True(t, len(serializedPk) >= 40) privKeys[i] = priv } @@ -108,10 +106,8 @@ func TestPublicKeySafe(t *testing.T) { require.Nil(t, ledger.ShowAddress(path, priv.PubKey(), sdk.GetConfig().GetBech32AccountAddrPrefix())) - bs, err := proto.Marshal(priv.PubKey()) - require.NoError(t, err) - require.Equal(t, "eb5ae98721034fef9cd7c4c63588d3b03feb5281b9d232cba34d6f3d71aee59211ffbfe1fe87", - fmt.Sprintf("%x", bs), + require.Equal(t, "034fef9cd7c4c63588d3b03feb5281b9d232cba34d6f3d71aee59211ffbfe1fe87", + fmt.Sprintf("%x", priv.PubKey().Bytes()), "Is your device using test mnemonic: %s ?", testutil.TestMnemonic) pubKeyAddr, err := sdk.Bech32ifyPubKey(sdk.Bech32PubKeyTypeAccPub, priv.PubKey()) @@ -243,11 +239,12 @@ func TestRealDeviceSecp256k1(t *testing.T) { // now, let's serialize the public key and make sure it still works bs, err := proto.Marshal(priv.PubKey()) require.NoError(t, err) - pub2, err := cryptoAmino.PubKeyFromBytes(bs) + var pub2 secp256k1.PubKey + err = proto.Unmarshal(bs, &pub2) require.Nil(t, err, "%+v", err) // make sure we get the same pubkey when we load from disk - require.Equal(t, pub, pub2) + require.Equal(t, pub, &pub2) // signing with the loaded key should match the original pubkey sig, err = priv.Sign(msg) @@ -258,7 +255,8 @@ func TestRealDeviceSecp256k1(t *testing.T) { // make sure pubkeys serialize properly as well bs, err = proto.Marshal(pub) require.NoError(t, err) - bpub, err := cryptoAmino.PubKeyFromBytes(bs) + var bpub secp256k1.PubKey + err = proto.Unmarshal(bs, &bpub) require.NoError(t, err) - require.Equal(t, pub, bpub) + require.Equal(t, pub, &bpub) } From 13e0c17a8c6f58a5831dc7b2baeae01a4868152c Mon Sep 17 00:00:00 2001 From: Amaury Martiny Date: Tue, 17 Nov 2020 10:50:39 +0100 Subject: [PATCH 7/7] Add back ExamplePrintRegisteredTypes --- crypto/codec/amino_test.go | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) create mode 100644 crypto/codec/amino_test.go diff --git a/crypto/codec/amino_test.go b/crypto/codec/amino_test.go new file mode 100644 index 000000000000..97d76c2a2a76 --- /dev/null +++ b/crypto/codec/amino_test.go @@ -0,0 +1,18 @@ +package codec + +import "os" + +// nolint: govet +func ExamplePrintRegisteredTypes() { + amino.PrintTypes(os.Stdout) + // Output: + // | Type | Name | Prefix | Length | Notes | + // | ---- | ---- | ------ | ----- | ------ | + // | PubKey | tendermint/PubKeySr25519 | 0x0DFB1005 | variable | | + // | PubKey | tendermint/PubKeyEd25519 | 0x1624DE64 | variable | | + // | PubKey | tendermint/PubKeySecp256k1 | 0xEB5AE987 | variable | | + // | LegacyAminoPubKey | tendermint/PubKeyMultisigThreshold | 0x22C1F7E2 | variable | | + // | PrivKey | tendermint/PrivKeySr25519 | 0x2F82D78B | variable | | + // | PrivKey | tendermint/PrivKeyEd25519 | 0xA3288910 | variable | | + // | PrivKey | tendermint/PrivKeySecp256k1 | 0xE1B0F79B | variable | | +}