github.com/franono/tendermint@v0.32.2-0.20200527150959-749313264ce9/crypto/secp256k1/secp256k1_nocgo.go (about)

     1  // +build !libsecp256k1
     2  
     3  package secp256k1
     4  
     5  import (
     6  	"math/big"
     7  
     8  	secp256k1 "github.com/btcsuite/btcd/btcec"
     9  
    10  	"github.com/franono/tendermint/crypto"
    11  )
    12  
    13  // used to reject malleable signatures
    14  // see:
    15  //  - https://github.com/ethereum/go-ethereum/blob/f9401ae011ddf7f8d2d95020b7446c17f8d98dc1/crypto/signature_nocgo.go#L90-L93
    16  //  - https://github.com/ethereum/go-ethereum/blob/f9401ae011ddf7f8d2d95020b7446c17f8d98dc1/crypto/crypto.go#L39
    17  var secp256k1halfN = new(big.Int).Rsh(secp256k1.S256().N, 1)
    18  
    19  // Sign creates an ECDSA signature on curve Secp256k1, using SHA256 on the msg.
    20  // The returned signature will be of the form R || S (in lower-S form).
    21  func (privKey PrivKeySecp256k1) Sign(msg []byte) ([]byte, error) {
    22  	priv, _ := secp256k1.PrivKeyFromBytes(secp256k1.S256(), privKey[:])
    23  	sig, err := priv.Sign(crypto.Sha256(msg))
    24  	if err != nil {
    25  		return nil, err
    26  	}
    27  	sigBytes := serializeSig(sig)
    28  	return sigBytes, nil
    29  }
    30  
    31  // VerifyBytes verifies a signature of the form R || S.
    32  // It rejects signatures which are not in lower-S form.
    33  func (pubKey PubKeySecp256k1) VerifyBytes(msg []byte, sigStr []byte) bool {
    34  	if len(sigStr) != 64 {
    35  		return false
    36  	}
    37  	pub, err := secp256k1.ParsePubKey(pubKey[:], secp256k1.S256())
    38  	if err != nil {
    39  		return false
    40  	}
    41  	// parse the signature:
    42  	signature := signatureFromBytes(sigStr)
    43  	// Reject malleable signatures. libsecp256k1 does this check but btcec doesn't.
    44  	// see: https://github.com/ethereum/go-ethereum/blob/f9401ae011ddf7f8d2d95020b7446c17f8d98dc1/crypto/signature_nocgo.go#L90-L93
    45  	if signature.S.Cmp(secp256k1halfN) > 0 {
    46  		return false
    47  	}
    48  	return signature.Verify(crypto.Sha256(msg), pub)
    49  }
    50  
    51  // Read Signature struct from R || S. Caller needs to ensure
    52  // that len(sigStr) == 64.
    53  func signatureFromBytes(sigStr []byte) *secp256k1.Signature {
    54  	return &secp256k1.Signature{
    55  		R: new(big.Int).SetBytes(sigStr[:32]),
    56  		S: new(big.Int).SetBytes(sigStr[32:64]),
    57  	}
    58  }
    59  
    60  // Serialize signature to R || S.
    61  // R, S are padded to 32 bytes respectively.
    62  func serializeSig(sig *secp256k1.Signature) []byte {
    63  	rBytes := sig.R.Bytes()
    64  	sBytes := sig.S.Bytes()
    65  	sigBytes := make([]byte, 64)
    66  	// 0 pad the byte arrays from the left if they aren't big enough.
    67  	copy(sigBytes[32-len(rBytes):32], rBytes)
    68  	copy(sigBytes[64-len(sBytes):64], sBytes)
    69  	return sigBytes
    70  }