diff --git a/bitcoin/signature.c b/bitcoin/signature.c index 30a50dad1..3de244993 100644 --- a/bitcoin/signature.c +++ b/bitcoin/signature.c @@ -75,16 +75,38 @@ static void dump_tx(const char *msg UNUSED, } #endif +/* Taken from https://github.com/bitcoin/bitcoin/blob/master/src/key.cpp */ +/* Check that the sig has a low R value and will be less than 71 bytes */ +static bool sig_has_low_r(const secp256k1_ecdsa_signature* sig) +{ + unsigned char compact_sig[64]; + secp256k1_ecdsa_signature_serialize_compact(secp256k1_ctx, compact_sig, sig); + + /* In DER serialization, all values are interpreted as big-endian, signed + * integers. The highest bit in the integer indicates its signed-ness; 0 is + * positive, 1 is negative. When the value is interpreted as a negative + * integer, it must be converted to a positive value by prepending a 0x00 + * byte so that the highest bit is 0. We can avoid this prepending by + * ensuring that our highest bit is always 0, and thus we must check that + * the first byte is less than 0x80. */ + return compact_sig[0] < 0x80; +} + void sign_hash(const struct privkey *privkey, const struct sha256_double *h, secp256k1_ecdsa_signature *s) { bool ok; + unsigned char extra_entropy[32] = {0}; - ok = secp256k1_ecdsa_sign(secp256k1_ctx, - s, - h->sha.u.u8, - privkey->secret.data, NULL, NULL); + /* Grind for low R */ + do { + ok = secp256k1_ecdsa_sign(secp256k1_ctx, + s, + h->sha.u.u8, + privkey->secret.data, NULL, extra_entropy); + ((u32 *)extra_entropy)[0]++; + } while (!sig_has_low_r(s)); assert(ok); } diff --git a/bitcoin/signature.h b/bitcoin/signature.h index e5195e197..de0d3342d 100644 --- a/bitcoin/signature.h +++ b/bitcoin/signature.h @@ -47,7 +47,7 @@ struct bitcoin_signature { }; /** - * sign_hash - produce a raw secp256k1 signature. + * sign_hash - produce a raw secp256k1 signature (with low R value). * @p: secret key * @h: hash to sign. * @sig: signature to fill in and return.