diff --git a/Makefile b/Makefile index 4c8f788f..434ab943 100644 --- a/Makefile +++ b/Makefile @@ -7,7 +7,7 @@ proto: @$(eval P_ACL_RECORDS_PATH_PB := commonspace/object/acl/aclrecordproto) @$(eval P_TREE_CHANGES_PATH_PB := commonspace/object/tree/treechangeproto) - @$(eval P_CRYPTO_PATH_PB := util/keys/cryptoproto) + @$(eval P_CRYPTO_PATH_PB := util/crypto/cryptoproto) @$(eval P_ACL_RECORDS := M$(P_ACL_RECORDS_PATH_PB)/protos/aclrecord.proto=github.com/anytypeio/any-sync/$(P_ACL_RECORDS_PATH_PB)) @$(eval P_TREE_CHANGES := M$(P_TREE_CHANGES_PATH_PB)/protos/treechange.proto=github.com/anytypeio/any-sync/$(P_TREE_CHANGES_PATH_PB)) diff --git a/go.mod b/go.mod index fb9727d1..980af79b 100644 --- a/go.mod +++ b/go.mod @@ -42,6 +42,7 @@ require ( require ( filippo.io/edwards25519 v1.0.0 // indirect github.com/alecthomas/units v0.0.0-20210927113745-59d0afb8317a // indirect + github.com/anytypeio/go-slip21 v0.0.0-20200218204727-e2e51e20ab51 // indirect github.com/beorn7/perks v1.0.1 // indirect github.com/btcsuite/btcd/btcec/v2 v2.2.0 // indirect github.com/cespare/xxhash/v2 v2.2.0 // indirect diff --git a/go.sum b/go.sum index af235b00..239250d5 100644 --- a/go.sum +++ b/go.sum @@ -7,6 +7,8 @@ github.com/alecthomas/units v0.0.0-20210927113745-59d0afb8317a h1:E/8AP5dFtMhl5K github.com/alecthomas/units v0.0.0-20210927113745-59d0afb8317a/go.mod h1:OMCwj8VM1Kc9e19TLln2VL61YJF0x1XFtfdL4JdbSyE= github.com/anytypeio/go-chash v0.0.2 h1:BSpyMC3HXNkf2eosQrHM4svov0DrvxL9tb4gnHbdmbA= github.com/anytypeio/go-chash v0.0.2/go.mod h1:G+R6q7jYgNa52NqcRhnNm28pogfWW+cuHtgBktrc2QA= +github.com/anytypeio/go-slip21 v0.0.0-20200218204727-e2e51e20ab51 h1:3Y+18zBC8LZgcL3l2dgoTEIzIUzCZa/kN0UV3ZWpbuA= +github.com/anytypeio/go-slip21 v0.0.0-20200218204727-e2e51e20ab51/go.mod h1:SoKy+W8Mf6v7XBV30xFWkIFMs7UnXwsNGrGV12yVkEs= github.com/awalterschulze/gographviz v2.0.3+incompatible h1:9sVEXJBJLwGX7EQVhLm2elIKCm7P2YHFC8v6096G09E= github.com/awalterschulze/gographviz v2.0.3+incompatible/go.mod h1:GEV5wmg4YquNw7v1kkyoX9etIk8yVmXj+AkDHuuETHs= github.com/benbjohnson/clock v1.1.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA= diff --git a/util/crypto/cryptoproto/crypto.pb.go b/util/crypto/cryptoproto/crypto.pb.go index af4ac14c..338c1dd9 100644 --- a/util/crypto/cryptoproto/crypto.pb.go +++ b/util/crypto/cryptoproto/crypto.pb.go @@ -1,5 +1,5 @@ // Code generated by protoc-gen-gogo. DO NOT EDIT. -// source: util/keys/cryptoproto/protos/crypto.proto +// source: util/crypto/cryptoproto/protos/crypto.proto package cryptoproto @@ -25,24 +25,21 @@ const _ = proto.GoGoProtoPackageIsVersion3 // please upgrade the proto package type KeyType int32 const ( - KeyType_RSA KeyType = 0 - KeyType_Ed25519 KeyType = 1 - KeyType_Secp256k1 KeyType = 2 - KeyType_ECDSA KeyType = 3 + KeyType_Ed25519Public KeyType = 0 + KeyType_Ed25519Private KeyType = 1 + KeyType_AES KeyType = 2 ) var KeyType_name = map[int32]string{ - 0: "RSA", - 1: "Ed25519", - 2: "Secp256k1", - 3: "ECDSA", + 0: "Ed25519Public", + 1: "Ed25519Private", + 2: "AES", } var KeyType_value = map[string]int32{ - "RSA": 0, - "Ed25519": 1, - "Secp256k1": 2, - "ECDSA": 3, + "Ed25519Public": 0, + "Ed25519Private": 1, + "AES": 2, } func (x KeyType) String() string { @@ -50,26 +47,26 @@ func (x KeyType) String() string { } func (KeyType) EnumDescriptor() ([]byte, []int) { - return fileDescriptor_761a9295b23470c2, []int{0} + return fileDescriptor_ddfeb19e486561de, []int{0} } -type PublicKey struct { - Type KeyType `protobuf:"varint,1,opt,name=Type,proto3,enum=utilcrypto.KeyType" json:"Type,omitempty"` +type Key struct { + Type KeyType `protobuf:"varint,1,opt,name=Type,proto3,enum=crypto.KeyType" json:"Type,omitempty"` Data []byte `protobuf:"bytes,2,opt,name=Data,proto3" json:"Data,omitempty"` } -func (m *PublicKey) Reset() { *m = PublicKey{} } -func (m *PublicKey) String() string { return proto.CompactTextString(m) } -func (*PublicKey) ProtoMessage() {} -func (*PublicKey) Descriptor() ([]byte, []int) { - return fileDescriptor_761a9295b23470c2, []int{0} +func (m *Key) Reset() { *m = Key{} } +func (m *Key) String() string { return proto.CompactTextString(m) } +func (*Key) ProtoMessage() {} +func (*Key) Descriptor() ([]byte, []int) { + return fileDescriptor_ddfeb19e486561de, []int{0} } -func (m *PublicKey) XXX_Unmarshal(b []byte) error { +func (m *Key) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) } -func (m *PublicKey) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { +func (m *Key) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { if deterministic { - return xxx_messageInfo_PublicKey.Marshal(b, m, deterministic) + return xxx_messageInfo_Key.Marshal(b, m, deterministic) } else { b = b[:cap(b)] n, err := m.MarshalToSizedBuffer(b) @@ -79,78 +76,26 @@ func (m *PublicKey) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { return b[:n], nil } } -func (m *PublicKey) XXX_Merge(src proto.Message) { - xxx_messageInfo_PublicKey.Merge(m, src) +func (m *Key) XXX_Merge(src proto.Message) { + xxx_messageInfo_Key.Merge(m, src) } -func (m *PublicKey) XXX_Size() int { +func (m *Key) XXX_Size() int { return m.Size() } -func (m *PublicKey) XXX_DiscardUnknown() { - xxx_messageInfo_PublicKey.DiscardUnknown(m) +func (m *Key) XXX_DiscardUnknown() { + xxx_messageInfo_Key.DiscardUnknown(m) } -var xxx_messageInfo_PublicKey proto.InternalMessageInfo +var xxx_messageInfo_Key proto.InternalMessageInfo -func (m *PublicKey) GetType() KeyType { +func (m *Key) GetType() KeyType { if m != nil { return m.Type } - return KeyType_RSA + return KeyType_Ed25519Public } -func (m *PublicKey) GetData() []byte { - if m != nil { - return m.Data - } - return nil -} - -type PrivateKey struct { - Type KeyType `protobuf:"varint,1,opt,name=Type,proto3,enum=utilcrypto.KeyType" json:"Type,omitempty"` - Data []byte `protobuf:"bytes,2,opt,name=Data,proto3" json:"Data,omitempty"` -} - -func (m *PrivateKey) Reset() { *m = PrivateKey{} } -func (m *PrivateKey) String() string { return proto.CompactTextString(m) } -func (*PrivateKey) ProtoMessage() {} -func (*PrivateKey) Descriptor() ([]byte, []int) { - return fileDescriptor_761a9295b23470c2, []int{1} -} -func (m *PrivateKey) XXX_Unmarshal(b []byte) error { - return m.Unmarshal(b) -} -func (m *PrivateKey) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - if deterministic { - return xxx_messageInfo_PrivateKey.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 *PrivateKey) XXX_Merge(src proto.Message) { - xxx_messageInfo_PrivateKey.Merge(m, src) -} -func (m *PrivateKey) XXX_Size() int { - return m.Size() -} -func (m *PrivateKey) XXX_DiscardUnknown() { - xxx_messageInfo_PrivateKey.DiscardUnknown(m) -} - -var xxx_messageInfo_PrivateKey proto.InternalMessageInfo - -func (m *PrivateKey) GetType() KeyType { - if m != nil { - return m.Type - } - return KeyType_RSA -} - -func (m *PrivateKey) GetData() []byte { +func (m *Key) GetData() []byte { if m != nil { return m.Data } @@ -158,34 +103,31 @@ func (m *PrivateKey) GetData() []byte { } func init() { - proto.RegisterEnum("utilcrypto.KeyType", KeyType_name, KeyType_value) - proto.RegisterType((*PublicKey)(nil), "utilcrypto.PublicKey") - proto.RegisterType((*PrivateKey)(nil), "utilcrypto.PrivateKey") + proto.RegisterEnum("crypto.KeyType", KeyType_name, KeyType_value) + proto.RegisterType((*Key)(nil), "crypto.Key") } func init() { - proto.RegisterFile("util/keys/cryptoproto/protos/crypto.proto", fileDescriptor_761a9295b23470c2) + proto.RegisterFile("util/crypto/cryptoproto/protos/crypto.proto", fileDescriptor_ddfeb19e486561de) } -var fileDescriptor_761a9295b23470c2 = []byte{ - // 222 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0xd2, 0x2c, 0x2d, 0xc9, 0xcc, - 0xd1, 0xcf, 0x4e, 0xad, 0x2c, 0xd6, 0x4f, 0x2e, 0xaa, 0x2c, 0x28, 0xc9, 0x2f, 0x28, 0xca, 0x2f, - 0xc9, 0xd7, 0x07, 0x93, 0x30, 0x21, 0x3d, 0x30, 0x4f, 0x88, 0x0b, 0xa4, 0x14, 0x22, 0xa2, 0xe4, - 0xc1, 0xc5, 0x19, 0x50, 0x9a, 0x94, 0x93, 0x99, 0xec, 0x9d, 0x5a, 0x29, 0xa4, 0xce, 0xc5, 0x12, - 0x52, 0x59, 0x90, 0x2a, 0xc1, 0xa8, 0xc0, 0xa8, 0xc1, 0x67, 0x24, 0xac, 0x87, 0x50, 0xa7, 0xe7, - 0x9d, 0x5a, 0x09, 0x92, 0x0a, 0x02, 0x2b, 0x10, 0x12, 0xe2, 0x62, 0x71, 0x49, 0x2c, 0x49, 0x94, - 0x60, 0x52, 0x60, 0xd4, 0xe0, 0x09, 0x02, 0xb3, 0x95, 0x3c, 0xb9, 0xb8, 0x02, 0x8a, 0x32, 0xcb, - 0x12, 0x4b, 0x52, 0x29, 0x35, 0x4a, 0xcb, 0x92, 0x8b, 0x1d, 0xaa, 0x48, 0x88, 0x9d, 0x8b, 0x39, - 0x28, 0xd8, 0x51, 0x80, 0x41, 0x88, 0x9b, 0x8b, 0xdd, 0x35, 0xc5, 0xc8, 0xd4, 0xd4, 0xd0, 0x52, - 0x80, 0x51, 0x88, 0x97, 0x8b, 0x33, 0x38, 0x35, 0xb9, 0xc0, 0xc8, 0xd4, 0x2c, 0xdb, 0x50, 0x80, - 0x49, 0x88, 0x93, 0x8b, 0xd5, 0xd5, 0xd9, 0x25, 0xd8, 0x51, 0x80, 0xd9, 0x49, 0xff, 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, 0x44, 0xb1, 0x06, 0x50, 0x12, 0x1b, 0x98, 0x32, - 0x06, 0x04, 0x00, 0x00, 0xff, 0xff, 0x9d, 0x04, 0x8a, 0xb8, 0x40, 0x01, 0x00, 0x00, +var fileDescriptor_ddfeb19e486561de = []byte{ + // 191 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0xd2, 0x2e, 0x2d, 0xc9, 0xcc, + 0xd1, 0x4f, 0x2e, 0xaa, 0x2c, 0x28, 0xc9, 0x87, 0x52, 0x05, 0x45, 0xf9, 0x25, 0xf9, 0xfa, 0x60, + 0xb2, 0x18, 0x2a, 0xa4, 0x07, 0xe6, 0x09, 0xb1, 0x41, 0x78, 0x4a, 0x76, 0x5c, 0xcc, 0xde, 0xa9, + 0x95, 0x42, 0xca, 0x5c, 0x2c, 0x21, 0x95, 0x05, 0xa9, 0x12, 0x8c, 0x0a, 0x8c, 0x1a, 0x7c, 0x46, + 0xfc, 0x7a, 0x50, 0xb5, 0xde, 0xa9, 0x95, 0x20, 0xe1, 0x20, 0xb0, 0xa4, 0x90, 0x10, 0x17, 0x8b, + 0x4b, 0x62, 0x49, 0xa2, 0x04, 0x93, 0x02, 0xa3, 0x06, 0x4f, 0x10, 0x98, 0xad, 0x65, 0xc9, 0xc5, + 0x0e, 0x55, 0x24, 0x24, 0xc8, 0xc5, 0xeb, 0x9a, 0x62, 0x64, 0x6a, 0x6a, 0x68, 0x19, 0x50, 0x9a, + 0x94, 0x93, 0x99, 0x2c, 0xc0, 0x20, 0x24, 0xc4, 0xc5, 0x07, 0x13, 0x2a, 0xca, 0x2c, 0x4b, 0x2c, + 0x49, 0x15, 0x60, 0x14, 0x62, 0xe7, 0x62, 0x76, 0x74, 0x0d, 0x16, 0x60, 0x72, 0x32, 0x3c, 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, 0x71, 0x1c, 0x3e, 0x49, 0x62, 0x03, 0x53, + 0xc6, 0x80, 0x00, 0x00, 0x00, 0xff, 0xff, 0x27, 0xb9, 0xba, 0xd8, 0xeb, 0x00, 0x00, 0x00, } -func (m *PublicKey) Marshal() (dAtA []byte, err error) { +func (m *Key) Marshal() (dAtA []byte, err error) { size := m.Size() dAtA = make([]byte, size) n, err := m.MarshalToSizedBuffer(dAtA[:size]) @@ -195,47 +137,12 @@ func (m *PublicKey) Marshal() (dAtA []byte, err error) { return dAtA[:n], nil } -func (m *PublicKey) MarshalTo(dAtA []byte) (int, error) { +func (m *Key) MarshalTo(dAtA []byte) (int, error) { size := m.Size() return m.MarshalToSizedBuffer(dAtA[:size]) } -func (m *PublicKey) MarshalToSizedBuffer(dAtA []byte) (int, error) { - i := len(dAtA) - _ = i - var l int - _ = l - if len(m.Data) > 0 { - i -= len(m.Data) - copy(dAtA[i:], m.Data) - i = encodeVarintCrypto(dAtA, i, uint64(len(m.Data))) - i-- - dAtA[i] = 0x12 - } - if m.Type != 0 { - i = encodeVarintCrypto(dAtA, i, uint64(m.Type)) - i-- - dAtA[i] = 0x8 - } - return len(dAtA) - i, nil -} - -func (m *PrivateKey) 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 *PrivateKey) MarshalTo(dAtA []byte) (int, error) { - size := m.Size() - return m.MarshalToSizedBuffer(dAtA[:size]) -} - -func (m *PrivateKey) MarshalToSizedBuffer(dAtA []byte) (int, error) { +func (m *Key) MarshalToSizedBuffer(dAtA []byte) (int, error) { i := len(dAtA) _ = i var l int @@ -266,23 +173,7 @@ func encodeVarintCrypto(dAtA []byte, offset int, v uint64) int { dAtA[offset] = uint8(v) return base } -func (m *PublicKey) Size() (n int) { - if m == nil { - return 0 - } - var l int - _ = l - if m.Type != 0 { - n += 1 + sovCrypto(uint64(m.Type)) - } - l = len(m.Data) - if l > 0 { - n += 1 + l + sovCrypto(uint64(l)) - } - return n -} - -func (m *PrivateKey) Size() (n int) { +func (m *Key) Size() (n int) { if m == nil { return 0 } @@ -304,7 +195,7 @@ func sovCrypto(x uint64) (n int) { func sozCrypto(x uint64) (n int) { return sovCrypto(uint64((x << 1) ^ uint64((int64(x) >> 63)))) } -func (m *PublicKey) Unmarshal(dAtA []byte) error { +func (m *Key) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -327,113 +218,10 @@ func (m *PublicKey) Unmarshal(dAtA []byte) error { fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { - return fmt.Errorf("proto: PublicKey: wiretype end group for non-group") + return fmt.Errorf("proto: Key: wiretype end group for non-group") } if fieldNum <= 0 { - return fmt.Errorf("proto: PublicKey: illegal tag %d (wire type %d)", fieldNum, wire) - } - switch fieldNum { - case 1: - if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field Type", wireType) - } - m.Type = 0 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowCrypto - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - m.Type |= KeyType(b&0x7F) << shift - if b < 0x80 { - break - } - } - case 2: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Data", wireType) - } - var byteLen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowCrypto - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - byteLen |= int(b&0x7F) << shift - if b < 0x80 { - break - } - } - if byteLen < 0 { - return ErrInvalidLengthCrypto - } - postIndex := iNdEx + byteLen - if postIndex < 0 { - return ErrInvalidLengthCrypto - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.Data = append(m.Data[:0], dAtA[iNdEx:postIndex]...) - if m.Data == nil { - m.Data = []byte{} - } - iNdEx = postIndex - default: - iNdEx = preIndex - skippy, err := skipCrypto(dAtA[iNdEx:]) - if err != nil { - return err - } - if (skippy < 0) || (iNdEx+skippy) < 0 { - return ErrInvalidLengthCrypto - } - if (iNdEx + skippy) > l { - return io.ErrUnexpectedEOF - } - iNdEx += skippy - } - } - - if iNdEx > l { - return io.ErrUnexpectedEOF - } - return nil -} -func (m *PrivateKey) 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 ErrIntOverflowCrypto - } - 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: PrivateKey: wiretype end group for non-group") - } - if fieldNum <= 0 { - return fmt.Errorf("proto: PrivateKey: illegal tag %d (wire type %d)", fieldNum, wire) + return fmt.Errorf("proto: Key: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { case 1: diff --git a/util/crypto/derived.go b/util/crypto/derived.go new file mode 100644 index 00000000..f12fca51 --- /dev/null +++ b/util/crypto/derived.go @@ -0,0 +1,17 @@ +package crypto + +import "github.com/anytypeio/go-slip21" + +const anytypeAccountPath = "m/SLIP-0021/anytype/account" + +func DeriveAccountSymmetric(seed []byte) (SymKey, error) { + master, err := slip21.DeriveForPath(anytypeAccountPath, seed) + if err != nil { + return nil, err + } + key, err := UnmarshallAESKey(master.SymmetricKey()) + if err != nil { + return nil, err + } + return key, nil +} diff --git a/util/crypto/ed25519.go b/util/crypto/ed25519.go index 0d2e9a90..0cdfdb1f 100644 --- a/util/crypto/ed25519.go +++ b/util/crypto/ed25519.go @@ -7,7 +7,10 @@ import ( "crypto/subtle" "errors" "fmt" + "github.com/anytypeio/any-sync/util/crypto/cryptoproto" + "github.com/gogo/protobuf/proto" "io" + "sync" ) // Ed25519PrivKey is an ed25519 private key. @@ -15,29 +18,34 @@ type Ed25519PrivKey struct { privKey ed25519.PrivateKey privCurve *[32]byte pubCurve *[32]byte + once sync.Once } // Ed25519PubKey is an ed25519 public key. type Ed25519PubKey struct { pubKey ed25519.PublicKey pubCurve *[32]byte + once sync.Once } func NewEd25519PrivKey(privKey ed25519.PrivateKey) PrivKey { - pK := &Ed25519PrivKey{privKey: privKey} - pubKey := pK.pubKeyBytes() - privCurve := Ed25519PrivateKeyToCurve25519(privKey) - pubCurve := Ed25519PublicKeyToCurve25519(pubKey) - pK.privCurve = (*[32]byte)(privCurve) - pK.pubCurve = (*[32]byte)(pubCurve) - return pK + return &Ed25519PrivKey{privKey: privKey} } func NewEd25519PubKey(pubKey ed25519.PublicKey) PubKey { - pK := &Ed25519PubKey{pubKey: pubKey} - pubCurve := Ed25519PublicKeyToCurve25519(pubKey) - pK.pubCurve = (*[32]byte)(pubCurve) - return pK + return &Ed25519PubKey{pubKey: pubKey} +} + +func UnmarshalEd25519PublicKeyProto(bytes []byte) (PubKey, error) { + msg := &cryptoproto.Key{} + err := proto.Unmarshal(bytes, msg) + if err != nil { + return nil, err + } + if msg.Type != cryptoproto.KeyType_Ed25519Public { + return nil, ErrIncorrectKeyType + } + return UnmarshalEd25519PublicKey(msg.Data) } func NewSigningEd25519PubKeyFromBytes(bytes []byte) (PubKey, error) { @@ -101,6 +109,13 @@ func (k *Ed25519PrivKey) Sign(msg []byte) ([]byte, error) { // Decrypt decrypts the message func (k *Ed25519PrivKey) Decrypt(msg []byte) ([]byte, error) { + k.once.Do(func() { + pubKey := k.pubKeyBytes() + privCurve := Ed25519PrivateKeyToCurve25519(k.privKey) + pubCurve := Ed25519PublicKeyToCurve25519(pubKey) + k.pubCurve = (*[32]byte)(pubCurve) + k.privCurve = (*[32]byte)(privCurve) + }) return DecryptX25519(k.privCurve, k.pubCurve, msg) } @@ -111,6 +126,10 @@ func (k *Ed25519PubKey) Raw() ([]byte, error) { // Encrypt message func (k *Ed25519PubKey) Encrypt(msg []byte) (data []byte, err error) { + k.once.Do(func() { + pubCurve := Ed25519PublicKeyToCurve25519(k.pubKey) + k.pubCurve = (*[32]byte)(pubCurve) + }) data = EncryptX25519(k.pubCurve, msg) return } @@ -130,6 +149,14 @@ func (k *Ed25519PubKey) Verify(data []byte, sig []byte) (bool, error) { return ed25519.Verify(k.pubKey, data, sig), nil } +func (k *Ed25519PubKey) Marshall() ([]byte, error) { + msg := &cryptoproto.Key{ + Type: cryptoproto.KeyType_Ed25519Public, + Data: k.pubKey, + } + return proto.Marshal(msg) +} + // UnmarshalEd25519PublicKey returns a public key from input bytes. func UnmarshalEd25519PublicKey(data []byte) (PubKey, error) { if len(data) != 32 { diff --git a/util/crypto/key.go b/util/crypto/key.go index ad408ab9..21f08142 100644 --- a/util/crypto/key.go +++ b/util/crypto/key.go @@ -2,8 +2,11 @@ package crypto import ( "crypto/subtle" + "errors" ) +var ErrIncorrectKeyType = errors.New("incorrect key type") + // Key is an abstract interface for all types of keys type Key interface { // Equals returns if the keys are equal @@ -33,6 +36,8 @@ type PubKey interface { Encrypt(message []byte) ([]byte, error) // Verify verifies the signed message and the signature Verify(data []byte, sig []byte) (bool, error) + // Marshall wraps key in proto encoding and marshalls it + Marshall() ([]byte, error) } type SymKey interface {