gitee.com/lh-her-team/common@v1.5.1/helper/libp2pcrypto/ecdsa.go (about) 1 package libp2pcrypto 2 3 import ( 4 "crypto/ecdsa" 5 "crypto/elliptic" 6 "crypto/rand" 7 "crypto/x509" 8 "encoding/asn1" 9 "errors" 10 "io" 11 "math/big" 12 13 "gitee.com/lh-her-team/common/helper/libp2pcrypto/pb" 14 15 sha256 "github.com/minio/sha256-simd" 16 ) 17 18 // ECDSAPrivateKey is an implementation of an ECDSA private key 19 type ECDSAPrivateKey struct { 20 priv *ecdsa.PrivateKey 21 } 22 23 // ECDSAPublicKey is an implementation of an ECDSA public key 24 type ECDSAPublicKey struct { 25 pub *ecdsa.PublicKey 26 } 27 28 func NewECDSAPublicKey(pub *ecdsa.PublicKey) *ECDSAPublicKey { 29 return &ECDSAPublicKey{pub: pub} 30 } 31 32 // ECDSASig holds the r and s values of an ECDSA signature 33 type ECDSASig struct { 34 R, S *big.Int 35 } 36 37 var ( 38 // ErrNotECDSAPubKey is returned when the public key passed is not an ecdsa public key 39 ErrNotECDSAPubKey = errors.New("not an ecdsa public key") 40 // ErrNilSig is returned when the signature is nil 41 ErrNilSig = errors.New("sig is nil") 42 // ErrNilPrivateKey is returned when a nil private key is provided 43 ErrNilPrivateKey = errors.New("private key is nil") 44 // ErrNilPublicKey is returned when a nil public key is provided 45 ErrNilPublicKey = errors.New("public key is nil") 46 // ECDSACurve is the default ecdsa curve used 47 ECDSACurve = elliptic.P256() 48 ) 49 50 // GenerateECDSAKeyPair generates a new ecdsa private and public key 51 func GenerateECDSAKeyPair(src io.Reader) (PrivKey, PubKey, error) { 52 return GenerateECDSAKeyPairWithCurve(ECDSACurve, src) 53 } 54 55 // GenerateECDSAKeyPairWithCurve generates a new ecdsa private and public key with a speicified curve 56 func GenerateECDSAKeyPairWithCurve(curve elliptic.Curve, src io.Reader) (PrivKey, PubKey, error) { 57 priv, err := ecdsa.GenerateKey(curve, src) 58 if err != nil { 59 return nil, nil, err 60 } 61 return &ECDSAPrivateKey{priv}, &ECDSAPublicKey{&priv.PublicKey}, nil 62 } 63 64 // ECDSAKeyPairFromKey generates a new ecdsa private and public key from an input private key 65 func ECDSAKeyPairFromKey(priv *ecdsa.PrivateKey) (PrivKey, PubKey, error) { 66 if priv == nil { 67 return nil, nil, ErrNilPrivateKey 68 } 69 return &ECDSAPrivateKey{priv}, &ECDSAPublicKey{&priv.PublicKey}, nil 70 } 71 72 // MarshalECDSAPrivateKey returns x509 bytes from a private key 73 func MarshalECDSAPrivateKey(ePriv ECDSAPrivateKey) ([]byte, error) { 74 return x509.MarshalECPrivateKey(ePriv.priv) 75 } 76 77 // MarshalECDSAPublicKey returns x509 bytes from a public key 78 func MarshalECDSAPublicKey(ePub ECDSAPublicKey) ([]byte, error) { 79 return x509.MarshalPKIXPublicKey(ePub.pub) 80 } 81 82 // UnmarshalECDSAPrivateKey returns a private key from x509 bytes 83 func UnmarshalECDSAPrivateKey(data []byte) (PrivKey, error) { 84 priv, err := x509.ParseECPrivateKey(data) 85 if err != nil { 86 return nil, err 87 } 88 return &ECDSAPrivateKey{priv}, nil 89 } 90 91 // UnmarshalECDSAPublicKey returns the public key from x509 bytes 92 func UnmarshalECDSAPublicKey(data []byte) (PubKey, error) { 93 pubIfc, err := x509.ParsePKIXPublicKey(data) 94 if err != nil { 95 return nil, err 96 } 97 pub, ok := pubIfc.(*ecdsa.PublicKey) 98 if !ok { 99 return nil, ErrNotECDSAPubKey 100 } 101 return &ECDSAPublicKey{pub}, nil 102 } 103 104 // Bytes returns the private key as protobuf bytes 105 func (ePriv *ECDSAPrivateKey) Bytes() ([]byte, error) { 106 return MarshalPrivateKey(ePriv) 107 } 108 109 // Type returns the key type 110 func (ePriv *ECDSAPrivateKey) Type() pb.KeyType { 111 return pb.KeyType_ECDSA 112 } 113 114 // Raw returns x509 bytes from a private key 115 func (ePriv *ECDSAPrivateKey) Raw() ([]byte, error) { 116 return x509.MarshalECPrivateKey(ePriv.priv) 117 } 118 119 // Equals compares two private keys 120 func (ePriv *ECDSAPrivateKey) Equals(o Key) bool { 121 return basicEquals(ePriv, o) 122 } 123 124 // Sign returns the signature of the input data 125 func (ePriv *ECDSAPrivateKey) Sign(data []byte) ([]byte, error) { 126 hash := sha256.Sum256(data) 127 r, s, err := ecdsa.Sign(rand.Reader, ePriv.priv, hash[:]) 128 if err != nil { 129 return nil, err 130 } 131 return asn1.Marshal(ECDSASig{ 132 R: r, 133 S: s, 134 }) 135 } 136 137 // GetPublic returns a public key 138 func (ePriv *ECDSAPrivateKey) GetPublic() PubKey { 139 return &ECDSAPublicKey{&ePriv.priv.PublicKey} 140 } 141 142 // Bytes returns the public key as protobuf bytes 143 func (ePub *ECDSAPublicKey) Bytes() ([]byte, error) { 144 return MarshalPublicKey(ePub) 145 } 146 147 // Type returns the key type 148 func (ePub *ECDSAPublicKey) Type() pb.KeyType { 149 return pb.KeyType_ECDSA 150 } 151 152 // Raw returns x509 bytes from a public key 153 func (ePub *ECDSAPublicKey) Raw() ([]byte, error) { 154 return x509.MarshalPKIXPublicKey(ePub.pub) 155 } 156 157 // Equals compares to public keys 158 func (ePub *ECDSAPublicKey) Equals(o Key) bool { 159 return basicEquals(ePub, o) 160 } 161 162 // Verify compares data to a signature 163 func (ePub *ECDSAPublicKey) Verify(data, sigBytes []byte) (bool, error) { 164 sig := new(ECDSASig) 165 if _, err := asn1.Unmarshal(sigBytes, sig); err != nil { 166 return false, err 167 } 168 if sig == nil { 169 return false, ErrNilSig 170 } 171 hash := sha256.Sum256(data) 172 return ecdsa.Verify(ePub.pub, hash[:], sig.R, sig.S), nil 173 }