github.com/chain5j/chain5j-pkg@v1.0.7/crypto/signature/signature.go (about)

     1  // Package signature
     2  //
     3  // @author: xwc1125
     4  package signature
     5  
     6  import (
     7  	"crypto/ecdsa"
     8  	"crypto/elliptic"
     9  	"errors"
    10  	"math/big"
    11  
    12  	"github.com/chain5j/chain5j-pkg/crypto/signature/gmsm"
    13  	"github.com/chain5j/chain5j-pkg/crypto/signature/prime256v1"
    14  	"github.com/chain5j/chain5j-pkg/crypto/signature/secp256k1"
    15  )
    16  
    17  // Ecrecover returns the uncompressed public key that created the given signature.
    18  func Ecrecover(hash []byte, sig *SignResult) ([]byte, error) {
    19  	if sig == nil {
    20  		return nil, errors.New("sign result is empty")
    21  	}
    22  	switch sig.Name {
    23  	case P256:
    24  		return prime256v1.RecoverPubkey(elliptic.P256(), hash, sig.Signature)
    25  	case S256:
    26  		return secp256k1.RecoverPubkey(hash, sig.Signature)
    27  	case SM2P256:
    28  		pubkey, err := gmsm.UnmarshalPublicKey(sig.PubKey)
    29  		if err != nil {
    30  			return nil, err
    31  		}
    32  		b := gmsm.Verify(pubkey, hash, sig.Signature)
    33  		if b {
    34  			return sig.PubKey, nil
    35  		}
    36  		return nil, errors.New("SM2 verify is error")
    37  	default:
    38  		return nil, errors.New("unsupported signName")
    39  	}
    40  }
    41  
    42  // SigToPub returns the public key that created the given signature.
    43  func SigToPub(hash []byte, sig *SignResult) (*ecdsa.PublicKey, error) {
    44  	if sig == nil {
    45  		return nil, errors.New("sign result is empty")
    46  	}
    47  	if sig.PubKey.Nil() {
    48  		s, err := Ecrecover(hash, sig)
    49  		if err != nil {
    50  			return nil, err
    51  		}
    52  		sig.PubKey = s
    53  	}
    54  	return UnmarshalPubkeyWithECDSA(sig.Name, sig.PubKey)
    55  }
    56  
    57  // BigintToPub 将big.Int转换为PublicKey
    58  func BigintToPub(curveName string, x, y *big.Int) *ecdsa.PublicKey {
    59  	return &ecdsa.PublicKey{Curve: CurveType(curveName), X: x, Y: y}
    60  }