github.com/cosmos/cosmos-sdk@v0.50.1/crypto/keys/secp256k1/secp256k1_nocgo.go (about)

     1  //go:build !libsecp256k1_sdk
     2  // +build !libsecp256k1_sdk
     3  
     4  package secp256k1
     5  
     6  import (
     7  	"errors"
     8  
     9  	"github.com/cometbft/cometbft/crypto"
    10  	secp256k1 "github.com/decred/dcrd/dcrec/secp256k1/v4"
    11  	"github.com/decred/dcrd/dcrec/secp256k1/v4/ecdsa"
    12  )
    13  
    14  // Sign creates an ECDSA signature on curve Secp256k1, using SHA256 on the msg.
    15  // The returned signature will be of the form R || S (in lower-S form).
    16  func (privKey *PrivKey) Sign(msg []byte) ([]byte, error) {
    17  	priv := secp256k1.PrivKeyFromBytes(privKey.Key)
    18  	sig := ecdsa.SignCompact(priv, crypto.Sha256(msg), false)
    19  
    20  	// remove the first byte which is compactSigRecoveryCode
    21  	return sig[1:], nil
    22  }
    23  
    24  // VerifyBytes verifies a signature of the form R || S.
    25  // It rejects signatures which are not in lower-S form.
    26  func (pubKey *PubKey) VerifySignature(msg, sigStr []byte) bool {
    27  	if len(sigStr) != 64 {
    28  		return false
    29  	}
    30  	pub, err := secp256k1.ParsePubKey(pubKey.Key)
    31  	if err != nil {
    32  		return false
    33  	}
    34  	// parse the signature, will return error if it is not in lower-S form
    35  	signature, err := signatureFromBytes(sigStr)
    36  	if err != nil {
    37  		return false
    38  	}
    39  	return signature.Verify(crypto.Sha256(msg), pub)
    40  }
    41  
    42  // Read Signature struct from R || S. Caller needs to ensure
    43  // that len(sigStr) == 64.
    44  // Rejects malleable signatures (if S value if it is over half order).
    45  func signatureFromBytes(sigStr []byte) (*ecdsa.Signature, error) {
    46  	var r secp256k1.ModNScalar
    47  	r.SetByteSlice(sigStr[:32])
    48  	var s secp256k1.ModNScalar
    49  	s.SetByteSlice(sigStr[32:64])
    50  	if s.IsOverHalfOrder() {
    51  		return nil, errors.New("signature is not in lower-S form")
    52  	}
    53  
    54  	return ecdsa.NewSignature(&r, &s), nil
    55  }