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 }