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

     1  //go:build !libsecp256k1_sdk
     2  // +build !libsecp256k1_sdk
     3  
     4  package secp256k1
     5  
     6  import (
     7  	"testing"
     8  
     9  	secp256k1 "github.com/decred/dcrd/dcrec/secp256k1/v4"
    10  	"github.com/stretchr/testify/require"
    11  )
    12  
    13  // Ensure that signature verification works, and that
    14  // non-canonical signatures fail.
    15  // Note: run with CGO_ENABLED=0 or go test -tags !cgo.
    16  func TestSignatureVerificationAndRejectUpperS(t *testing.T) {
    17  	msg := []byte("We have lingered long enough on the shores of the cosmic ocean.")
    18  	for i := 0; i < 500; i++ {
    19  		priv := GenPrivKey()
    20  		sigStr, err := priv.Sign(msg)
    21  		require.NoError(t, err)
    22  		var r secp256k1.ModNScalar
    23  		r.SetByteSlice(sigStr[:32])
    24  		var s secp256k1.ModNScalar
    25  		s.SetByteSlice(sigStr[32:64])
    26  		require.False(t, s.IsOverHalfOrder())
    27  
    28  		pub := priv.PubKey()
    29  		require.True(t, pub.VerifySignature(msg, sigStr))
    30  
    31  		// malleate:
    32  		var S256 secp256k1.ModNScalar
    33  		S256.SetByteSlice(secp256k1.S256().N.Bytes())
    34  		s.Negate().Add(&S256)
    35  		require.True(t, s.IsOverHalfOrder())
    36  
    37  		rBytes := r.Bytes()
    38  		sBytes := s.Bytes()
    39  		malSigStr := make([]byte, 64)
    40  		copy(malSigStr[32-len(rBytes):32], rBytes[:])
    41  		copy(malSigStr[64-len(sBytes):64], sBytes[:])
    42  		require.False(t, pub.VerifySignature(msg, malSigStr),
    43  			"VerifyBytes incorrect with malleated & invalid S. sig=%v, key=%v",
    44  			malSigStr,
    45  			priv,
    46  		)
    47  	}
    48  }