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 }