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  }