Skip to content

Commit

Permalink
wallet: always create signatures with low r-value
Browse files Browse the repository at this point in the history
  • Loading branch information
gorazdko committed Oct 28, 2019
1 parent 0985c6e commit 4108356
Show file tree
Hide file tree
Showing 2 changed files with 30 additions and 6 deletions.
34 changes: 29 additions & 5 deletions bitcoin/signature.c
Original file line number Diff line number Diff line change
Expand Up @@ -75,16 +75,40 @@ static void dump_tx(const char *msg UNUSED,
}
#endif

/* Taken from bitcoin/src/key.cpp:
// Copyright (c) 2009-2018 The Bitcoin Core developers
// Copyright (c) 2017 The Zcash developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
*/
// Check that the sig has a low R value and will be less than 71 bytes
static bool SigHasLowR(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;

ok = secp256k1_ecdsa_sign(secp256k1_ctx,
s,
h->sha.u.u8,
privkey->secret.data, NULL, NULL);
unsigned char extra_entropy[32] = {0};

/* 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 (!SigHasLowR(s));
assert(ok);
}

Expand Down
2 changes: 1 addition & 1 deletion bitcoin/signature.h
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down

0 comments on commit 4108356

Please sign in to comment.