gitee.com/lh-her-team/common@v1.5.1/crypto/asym/ecdsa/pk.go (about)

     1  package ecdsa
     2  
     3  import (
     4  	"bytes"
     5  	crypto2 "crypto"
     6  	"crypto/ecdsa"
     7  	"crypto/elliptic"
     8  	"crypto/x509"
     9  	"encoding/asn1"
    10  	"encoding/hex"
    11  	"encoding/pem"
    12  	"fmt"
    13  
    14  	"gitee.com/lh-her-team/common/crypto"
    15  	"gitee.com/lh-her-team/common/crypto/hash"
    16  	"github.com/btcsuite/btcd/btcec"
    17  )
    18  
    19  type PublicKey struct {
    20  	K *ecdsa.PublicKey
    21  }
    22  
    23  func (pk *PublicKey) Bytes() ([]byte, error) {
    24  	if pk.K == nil {
    25  		return nil, fmt.Errorf("public key is nil")
    26  	}
    27  	if pk.Type() == crypto.ECC_Secp256k1 {
    28  		rawKey := (*btcec.PublicKey)(pk.K).SerializeCompressed()
    29  		return rawKey, nil
    30  	}
    31  	return x509.MarshalPKIXPublicKey(pk.K)
    32  }
    33  
    34  func (pk *PublicKey) Verify(digest []byte, sig []byte) (bool, error) {
    35  	if sig == nil {
    36  		return false, fmt.Errorf("nil signature")
    37  	}
    38  	sigStruct := &Sig{}
    39  	if _, err := asn1.Unmarshal(sig, sigStruct); err != nil {
    40  		return false, fmt.Errorf("fail to decode signature: [%v]", err)
    41  	}
    42  	if !ecdsa.Verify(pk.K, digest, sigStruct.R, sigStruct.S) {
    43  		return false, fmt.Errorf("struct invalid ecdsa signature")
    44  	}
    45  	return true, nil
    46  }
    47  
    48  func (pk *PublicKey) VerifyWithOpts(msg []byte, sig []byte, opts *crypto.SignOpts) (bool, error) {
    49  	if opts == nil {
    50  		return pk.Verify(msg, sig)
    51  	}
    52  	dgst, err := hash.Get(opts.Hash, msg)
    53  	if err != nil {
    54  		return false, err
    55  	}
    56  	return pk.Verify(dgst, sig)
    57  }
    58  
    59  func (pk *PublicKey) Type() crypto.KeyType {
    60  	if pk.K != nil {
    61  		switch pk.K.Curve {
    62  		case elliptic.P256():
    63  			return crypto.ECC_NISTP256
    64  		case elliptic.P384():
    65  			return crypto.ECC_NISTP384
    66  		case elliptic.P521():
    67  			return crypto.ECC_NISTP521
    68  		case btcec.S256():
    69  			return crypto.ECC_Secp256k1
    70  		}
    71  	}
    72  	return -1
    73  }
    74  
    75  func (pk *PublicKey) String() (string, error) {
    76  	pkDER, err := pk.Bytes()
    77  	if err != nil {
    78  		return "", err
    79  	}
    80  	if pk.Type() == crypto.ECC_Secp256k1 {
    81  		return hex.EncodeToString(pkDER), nil
    82  	}
    83  	block := &pem.Block{
    84  		Type:  "PUBLIC KEY",
    85  		Bytes: pkDER,
    86  	}
    87  	buf := new(bytes.Buffer)
    88  	if err = pem.Encode(buf, block); err != nil {
    89  		return "", err
    90  	}
    91  	return buf.String(), nil
    92  }
    93  
    94  func (pk *PublicKey) ToStandardKey() crypto2.PublicKey {
    95  	return pk.K
    96  }