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

     1  package sm2
     2  
     3  import (
     4  	"bytes"
     5  	crypto2 "crypto"
     6  	"crypto/rand"
     7  	"encoding/asn1"
     8  	"encoding/pem"
     9  	"fmt"
    10  
    11  	"gitee.com/lh-her-team/common/crypto"
    12  	"gitee.com/lh-her-team/common/crypto/hash"
    13  	tjsm2 "github.com/tjfoc/gmsm/sm2"
    14  	gmx509 "github.com/tjfoc/gmsm/x509"
    15  )
    16  
    17  type PublicKey struct {
    18  	K *tjsm2.PublicKey
    19  }
    20  
    21  func (pk *PublicKey) Bytes() ([]byte, error) {
    22  	if pk.K == nil {
    23  		return nil, fmt.Errorf("public key is nil")
    24  	}
    25  	return gmx509.MarshalPKIXPublicKey(pk.K)
    26  }
    27  
    28  func (pk *PublicKey) Verify(digest []byte, sig []byte) (bool, error) {
    29  	if sig == nil {
    30  		return false, fmt.Errorf("nil signature")
    31  	}
    32  	sigStruct := &Sig{}
    33  	if _, err := asn1.Unmarshal(sig, sigStruct); err != nil {
    34  		return false, fmt.Errorf("fail to decode signature: [%v]", err)
    35  	}
    36  	if !tjsm2.Verify(pk.K, digest, sigStruct.R, sigStruct.S) {
    37  		return false, fmt.Errorf("invalid sm2 signature")
    38  	}
    39  	return true, nil
    40  }
    41  
    42  func (pk *PublicKey) VerifyWithOpts(msg []byte, sig []byte, opts *crypto.SignOpts) (bool, error) {
    43  	if opts == nil {
    44  		return pk.Verify(msg, sig)
    45  	}
    46  	if opts.Hash == crypto.HASH_TYPE_SM3 && pk.Type() == crypto.SM2 {
    47  		uid := opts.UID
    48  		if len(uid) == 0 {
    49  			uid = crypto.CRYPTO_DEFAULT_UID
    50  		}
    51  		if sig == nil {
    52  			return false, fmt.Errorf("nil signature")
    53  		}
    54  		sigStruct := &Sig{}
    55  		if _, err := asn1.Unmarshal(sig, sigStruct); err != nil {
    56  			return false, fmt.Errorf("fail to decode signature: [%v]", err)
    57  		}
    58  		return tjsm2.Sm2Verify(pk.K, msg, []byte(uid), sigStruct.R, sigStruct.S), nil
    59  	}
    60  	dgst, err := hash.Get(opts.Hash, msg)
    61  	if err != nil {
    62  		return false, err
    63  	}
    64  	return pk.Verify(dgst, sig)
    65  }
    66  
    67  func (pk *PublicKey) Type() crypto.KeyType {
    68  	switch pk.K.Curve {
    69  	case tjsm2.P256Sm2():
    70  		return crypto.SM2
    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  	block := &pem.Block{
    81  		Type:  "PUBLIC KEY",
    82  		Bytes: pkDER,
    83  	}
    84  	buf := new(bytes.Buffer)
    85  	if err = pem.Encode(buf, block); err != nil {
    86  		return "", err
    87  	}
    88  	return buf.String(), nil
    89  }
    90  
    91  func (pk *PublicKey) ToStandardKey() crypto2.PublicKey {
    92  	return pk.K
    93  }
    94  
    95  func (pk *PublicKey) Encrypt(data []byte) ([]byte, error) {
    96  	return pk.EncryptWithOpts(data, defaultSM2Opts)
    97  }
    98  
    99  func (pk *PublicKey) EncryptWithOpts(data []byte, opts *crypto.EncOpts) ([]byte, error) {
   100  	if opts == nil || opts.EnableASN1 {
   101  		return tjsm2.EncryptAsn1(pk.K, data, rand.Reader)
   102  	}
   103  	return tjsm2.Encrypt(pk.K, data, rand.Reader, tjsm2.C1C3C2)
   104  }