From 1d82bf51fcf55f158265053e2d5b4a9aeb098e42 Mon Sep 17 00:00:00 2001 From: Rusty Russell Date: Tue, 30 Jun 2015 13:37:17 +0930 Subject: [PATCH] signature: fix invalid S check. The even-S check was based on https://github.com/sipa/bitcoin/commit/a81cd9680 which was replaced by a low-S check in commit e0e14e43d9586409e42919f6cb955540134cda2a Abstract out and fix the check. Signed-off-by: Rusty Russell --- bitcoin/signature.c | 6 ++++++ bitcoin/signature.h | 3 +++ protobuf_convert.c | 5 ++--- 3 files changed, 11 insertions(+), 3 deletions(-) diff --git a/bitcoin/signature.c b/bitcoin/signature.c index 7b9d8a7e7..9f4fc19fd 100644 --- a/bitcoin/signature.c +++ b/bitcoin/signature.c @@ -306,3 +306,9 @@ size_t signature_to_der(u8 der[72], const struct signature *sig) assert(IsValidSignatureEncoding(der, len + 1)); return len; } + +/* Signature must have low S value. */ +bool sig_valid(const struct signature *sig) +{ + return (sig->s[0] & 0x80) == 0; +} diff --git a/bitcoin/signature.h b/bitcoin/signature.h index f5c23555f..34692f539 100644 --- a/bitcoin/signature.h +++ b/bitcoin/signature.h @@ -46,6 +46,9 @@ bool check_2of2_sig(struct bitcoin_tx *tx, size_t input_num, const struct bitcoin_signature *sig1, const struct bitcoin_signature *sig2); +/* Signature must have low S value. */ +bool sig_valid(const struct signature *s); + /* Give DER encoding of signature: returns length used (<= 72). */ size_t signature_to_der(u8 der[72], const struct signature *s); diff --git a/protobuf_convert.c b/protobuf_convert.c index 1cf0d1e2a..31240bd00 100644 --- a/protobuf_convert.c +++ b/protobuf_convert.c @@ -8,7 +8,7 @@ Signature *signature_to_proto(const tal_t *ctx, const struct signature *sig) Signature *pb = tal(ctx, Signature); signature__init(pb); - assert((sig->s[31] & 1) == 0); + assert(sig_valid(sig)); /* Kill me now... */ memcpy(&pb->r1, sig->r, 8); @@ -35,8 +35,7 @@ bool proto_to_signature(const Signature *pb, struct signature *sig) memcpy(sig->s + 16, &pb->s3, 8); memcpy(sig->s + 24, &pb->s4, 8); - /* S must be even */ - return (sig->s[31] & 1) == 0; + return sig_valid(sig); } BitcoinPubkey *pubkey_to_proto(const tal_t *ctx, const struct pubkey *key)