diff --git a/cpp/src/barretenberg/crypto/ecdsa/ecdsa_impl.hpp b/cpp/src/barretenberg/crypto/ecdsa/ecdsa_impl.hpp index 33cec9c433..3c98f77e21 100644 --- a/cpp/src/barretenberg/crypto/ecdsa/ecdsa_impl.hpp +++ b/cpp/src/barretenberg/crypto/ecdsa/ecdsa_impl.hpp @@ -28,6 +28,15 @@ signature construct_signature(const std::string& message, const key_pair Fr r_fr = Fr::serialize_from_buffer(&sig.r[0]); Fr s_fr = (z + r_fr * account.private_key) / k; + // Ensures that the s value chosen is "low". + // For more details, see: + // https://github.com/bitcoin-core/secp256k1/blob/d644dda5c9dbdecee52d1aa259235510fdc2d4ee/include/secp256k1.h#L483-L513 + uint256_t s_u256(s_fr); + bool s_hi = ((s_u256 >> 255) & 1ULL) == 1ULL; + if (s_hi) { + s_fr = -s_fr; + } + Fr::serialize_to_buffer(s_fr, &sig.s[0]); // compute recovery_id: given R = (x, y)