diff --git a/crypto/signature_nocgo.go b/crypto/signature_nocgo.go
index 78b99c02b0b2a25733d98b44b1e85951ebfe03a3..f636b23772871ab2dfb5c119f17bf491c8c9cae3 100644
--- a/crypto/signature_nocgo.go
+++ b/crypto/signature_nocgo.go
@@ -87,6 +87,10 @@ func VerifySignature(pubkey, hash, signature []byte) bool {
 	if err != nil {
 		return false
 	}
+	// Reject malleable signatures. libsecp256k1 does this check but btcec doesn't.
+	if sig.S.Cmp(secp256k1_halfN) > 0 {
+		return false
+	}
 	return sig.Verify(hash, key)
 }
 
diff --git a/crypto/signature_test.go b/crypto/signature_test.go
index 5e2efc7e05a1a12eefa53d357dbc83770af009ce..aecff76bfbda408d928a6441f025e7c0ec2c67e0 100644
--- a/crypto/signature_test.go
+++ b/crypto/signature_test.go
@@ -75,6 +75,16 @@ func TestVerifySignature(t *testing.T) {
 	}
 }
 
+// This test checks that VerifySignature rejects malleable signatures with s > N/2.
+func TestVerifySignatureMalleable(t *testing.T) {
+	sig := hexutil.MustDecode("0x638a54215d80a6713c8d523a6adc4e6e73652d859103a36b700851cb0e61b66b8ebfc1a610c57d732ec6e0a8f06a9a7a28df5051ece514702ff9cdff0b11f454")
+	key := hexutil.MustDecode("0x03ca634cae0d49acb401d8a4c6b6fe8c55b70d115bf400769cc1400f3258cd3138")
+	msg := hexutil.MustDecode("0xd301ce462d3e639518f482c7f03821fec1e602018630ce621e1e7851c12343a6")
+	if VerifySignature(key, msg, sig) {
+		t.Error("VerifySignature returned true for malleable signature")
+	}
+}
+
 func TestDecompressPubkey(t *testing.T) {
 	key, err := DecompressPubkey(testpubkeyc)
 	if err != nil {