gitee.com/lh-her-team/common@v1.5.1/helper/libp2pcrypto/ed25519.go (about) 1 package libp2pcrypto 2 3 import ( 4 "bytes" 5 "crypto/ed25519" 6 "crypto/subtle" 7 "errors" 8 "fmt" 9 "io" 10 11 "gitee.com/lh-her-team/common/helper/libp2pcrypto/pb" 12 ) 13 14 // Ed25519PrivateKey is an ed25519 private key. 15 type Ed25519PrivateKey struct { 16 k ed25519.PrivateKey 17 } 18 19 // Ed25519PublicKey is an ed25519 public key. 20 type Ed25519PublicKey struct { 21 k ed25519.PublicKey 22 } 23 24 // GenerateEd25519Key generates a new ed25519 private and public key pair. 25 func GenerateEd25519Key(src io.Reader) (PrivKey, PubKey, error) { 26 pub, priv, err := ed25519.GenerateKey(src) 27 if err != nil { 28 return nil, nil, err 29 } 30 return &Ed25519PrivateKey{ 31 k: priv, 32 }, 33 &Ed25519PublicKey{ 34 k: pub, 35 }, 36 nil 37 } 38 39 // Type of the private key (Ed25519). 40 func (k *Ed25519PrivateKey) Type() pb.KeyType { 41 return pb.KeyType_Ed25519 42 } 43 44 // Bytes marshals an ed25519 private key to protobuf bytes. 45 func (k *Ed25519PrivateKey) Bytes() ([]byte, error) { 46 return MarshalPrivateKey(k) 47 } 48 49 // Raw private key bytes. 50 func (k *Ed25519PrivateKey) Raw() ([]byte, error) { 51 // The Ed25519 private key contains two 32-bytes curve points, the private 52 // key and the public key. 53 // It makes it more efficient to get the public key without re-computing an 54 // elliptic curve multiplication. 55 buf := make([]byte, len(k.k)) 56 copy(buf, k.k) 57 return buf, nil 58 } 59 60 func (k *Ed25519PrivateKey) pubKeyBytes() []byte { 61 return k.k[ed25519.PrivateKeySize-ed25519.PublicKeySize:] 62 } 63 64 // Equals compares two ed25519 private keys. 65 func (k *Ed25519PrivateKey) Equals(o Key) bool { 66 edk, ok := o.(*Ed25519PrivateKey) 67 if !ok { 68 return basicEquals(k, o) 69 } 70 return subtle.ConstantTimeCompare(k.k, edk.k) == 1 71 } 72 73 // GetPublic returns an ed25519 public key from a private key. 74 func (k *Ed25519PrivateKey) GetPublic() PubKey { 75 return &Ed25519PublicKey{k: k.pubKeyBytes()} 76 } 77 78 // Sign returns a signature from an input message. 79 func (k *Ed25519PrivateKey) Sign(msg []byte) ([]byte, error) { 80 return ed25519.Sign(k.k, msg), nil 81 } 82 83 // Type of the public key (Ed25519). 84 func (k *Ed25519PublicKey) Type() pb.KeyType { 85 return pb.KeyType_Ed25519 86 } 87 88 // Bytes returns a ed25519 public key as protobuf bytes. 89 func (k *Ed25519PublicKey) Bytes() ([]byte, error) { 90 return MarshalPublicKey(k) 91 } 92 93 // Raw public key bytes. 94 func (k *Ed25519PublicKey) Raw() ([]byte, error) { 95 return k.k, nil 96 } 97 98 // Equals compares two ed25519 public keys. 99 func (k *Ed25519PublicKey) Equals(o Key) bool { 100 edk, ok := o.(*Ed25519PublicKey) 101 if !ok { 102 return basicEquals(k, o) 103 } 104 return bytes.Equal(k.k, edk.k) 105 } 106 107 // Verify checks a signature against the input data. 108 func (k *Ed25519PublicKey) Verify(data []byte, sig []byte) (bool, error) { 109 return ed25519.Verify(k.k, data, sig), nil 110 } 111 112 // UnmarshalEd25519PublicKey returns a public key from input bytes. 113 func UnmarshalEd25519PublicKey(data []byte) (PubKey, error) { 114 if len(data) != 32 { 115 return nil, errors.New("expect ed25519 public key data size to be 32") 116 } 117 return &Ed25519PublicKey{ 118 k: ed25519.PublicKey(data), 119 }, nil 120 } 121 122 // UnmarshalEd25519PrivateKey returns a private key from input bytes. 123 func UnmarshalEd25519PrivateKey(data []byte) (PrivKey, error) { 124 switch len(data) { 125 case ed25519.PrivateKeySize + ed25519.PublicKeySize: 126 // Remove the redundant public key. See issue #36. 127 redundantPk := data[ed25519.PrivateKeySize:] 128 pk := data[ed25519.PrivateKeySize-ed25519.PublicKeySize : ed25519.PrivateKeySize] 129 if subtle.ConstantTimeCompare(pk, redundantPk) == 0 { 130 return nil, errors.New("expected redundant ed25519 public key to be redundant") 131 } 132 // No point in storing the extra data. 133 newKey := make([]byte, ed25519.PrivateKeySize) 134 copy(newKey, data[:ed25519.PrivateKeySize]) 135 data = newKey 136 case ed25519.PrivateKeySize: 137 default: 138 return nil, fmt.Errorf( 139 "expected ed25519 data size to be %d or %d, got %d", 140 ed25519.PrivateKeySize, 141 ed25519.PrivateKeySize+ed25519.PublicKeySize, 142 len(data), 143 ) 144 } 145 return &Ed25519PrivateKey{ 146 k: ed25519.PrivateKey(data), 147 }, nil 148 }