mirror of
https://github.com/ElementsProject/lightning.git
synced 2025-01-18 05:12:45 +01:00
bitcoin: signature fixes.
The libsecp change broke signature checking. Disable it for now, with a big FIXME. The next version should have a method for S value checking, and also compact serialization. Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
This commit is contained in:
parent
0b50a7c9eb
commit
32fe988fe8
@ -89,12 +89,12 @@ bool sign_hash(const tal_t *ctx, const struct privkey *privkey,
|
||||
|
||||
#ifdef USE_SCHNORR
|
||||
ok = secp256k1_schnorr_sign(secpctx,
|
||||
(unsigned char *)s,
|
||||
s->schnorr,
|
||||
h->sha.u.u8,
|
||||
privkey->secret, NULL, NULL);
|
||||
#else
|
||||
ok = secp256k1_ecdsa_sign(secpctx,
|
||||
(secp256k1_ecdsa_signature *)s,
|
||||
&s->sig,
|
||||
h->sha.u.u8,
|
||||
privkey->secret, NULL, NULL);
|
||||
#endif
|
||||
@ -158,11 +158,11 @@ static bool check_signed_hash(const struct sha256_double *hash,
|
||||
return false;
|
||||
|
||||
#ifdef USE_SCHNORR
|
||||
ret = secp256k1_schnorr_verify(secpctx, (unsigned char *)signature,
|
||||
ret = secp256k1_schnorr_verify(secpctx, signature->schnorr,
|
||||
hash->sha.u.u8, &key->pubkey);
|
||||
#else
|
||||
ret = secp256k1_ecdsa_verify(secpctx,
|
||||
(secp256k1_ecdsa_signature *)signature,
|
||||
&signature->sig,
|
||||
hash->sha.u.u8, &key->pubkey);
|
||||
#endif
|
||||
|
||||
@ -214,6 +214,7 @@ bool check_2of2_sig(struct bitcoin_tx *tx, size_t input_num,
|
||||
&& check_signed_hash(&hash, &sig2->sig, key2);
|
||||
}
|
||||
|
||||
#ifndef USE_SCHNORR
|
||||
/* Stolen direct from bitcoin/src/script/sign.cpp:
|
||||
// Copyright (c) 2009-2010 Satoshi Nakamoto
|
||||
// Copyright (c) 2009-2014 The Bitcoin Core developers
|
||||
@ -286,55 +287,26 @@ static bool IsValidSignatureEncoding(const unsigned char sig[], size_t len)
|
||||
return true;
|
||||
}
|
||||
|
||||
/* DER encode a value, return length used. */
|
||||
static size_t der_encode_val(const u8 *val, u8 *der)
|
||||
{
|
||||
size_t len = 0, val_len = 32;
|
||||
|
||||
der[len++] = 0x2; /* value type. */
|
||||
|
||||
/* Strip leading zeroes. */
|
||||
while (val_len && val[0] == 0) {
|
||||
val++;
|
||||
val_len--;
|
||||
}
|
||||
|
||||
/* Add zero byte if it would otherwise be signed. */
|
||||
if (val[0] & 0x80) {
|
||||
der[len++] = 1 + val_len; /* value length */
|
||||
der[len++] = 0;
|
||||
} else
|
||||
der[len++] = val_len; /* value length */
|
||||
|
||||
memcpy(der + len, val, val_len);
|
||||
return len + val_len;
|
||||
}
|
||||
|
||||
size_t signature_to_der(u8 der[72], const struct signature *sig)
|
||||
{
|
||||
size_t len = 0;
|
||||
size_t len = 72;
|
||||
secp256k1_context *ctx = secp256k1_context_create(0);
|
||||
|
||||
der[len++] = 0x30; /* Type */
|
||||
der[len++] = 0; /* Total length after this: fill it at end. */
|
||||
|
||||
len += der_encode_val(sig->r, der + len);
|
||||
len += der_encode_val(sig->s, der + len);
|
||||
|
||||
/* Fix up total length */
|
||||
der[1] = len - 2;
|
||||
secp256k1_ecdsa_signature_serialize_der(ctx, der, &len, &sig->sig);
|
||||
|
||||
/* IsValidSignatureEncoding() expect extra byte for sighash */
|
||||
assert(IsValidSignatureEncoding(der, len + 1));
|
||||
return len;
|
||||
}
|
||||
#endif /* USE_SCHNORR */
|
||||
|
||||
/* Signature must have low S value. */
|
||||
bool sig_valid(const struct signature *sig)
|
||||
{
|
||||
#ifdef USE_SCHNORR
|
||||
/* FIXME: Is there some sanity check we can do here? */
|
||||
return true;
|
||||
#else
|
||||
return (sig->s[0] & 0x80) == 0;
|
||||
/* FIXME! Need libsecp support. */
|
||||
return true;
|
||||
#endif
|
||||
}
|
||||
|
@ -2,6 +2,7 @@
|
||||
#define LIGHTNING_BITCOIN_SIGNATURE_H
|
||||
#include <ccan/short_types/short_types.h>
|
||||
#include <ccan/tal/tal.h>
|
||||
#include "secp256k1.h"
|
||||
|
||||
enum sighash_type {
|
||||
SIGHASH_ALL = 1,
|
||||
@ -12,8 +13,11 @@ enum sighash_type {
|
||||
|
||||
/* ECDSA of double SHA256. */
|
||||
struct signature {
|
||||
u8 r[32];
|
||||
u8 s[32];
|
||||
#ifdef USE_SCHNORR
|
||||
u8 schnorr[64];
|
||||
#else
|
||||
secp256k1_ecdsa_signature sig;
|
||||
#endif
|
||||
};
|
||||
|
||||
struct sha256_double;
|
||||
@ -49,7 +53,9 @@ bool check_2of2_sig(struct bitcoin_tx *tx, size_t input_num,
|
||||
/* Signature must have low S value. */
|
||||
bool sig_valid(const struct signature *s);
|
||||
|
||||
#ifndef USE_SCHNORR
|
||||
/* Give DER encoding of signature: returns length used (<= 72). */
|
||||
size_t signature_to_der(u8 der[72], const struct signature *s);
|
||||
#endif
|
||||
|
||||
#endif /* LIGHTNING_BITCOIN_SIGNATURE_H */
|
||||
|
@ -10,15 +10,28 @@ Signature *signature_to_proto(const tal_t *ctx, const struct signature *sig)
|
||||
|
||||
assert(sig_valid(sig));
|
||||
|
||||
#ifdef USE_SCHNORR
|
||||
memcpy(&pb->r1, sig->schnorr, 8);
|
||||
memcpy(&pb->r2, sig->schnorr + 8, 8);
|
||||
memcpy(&pb->r3, sig->schnorr + 16, 8);
|
||||
memcpy(&pb->r4, sig->schnorr + 24, 8);
|
||||
memcpy(&pb->s1, sig->schnorr + 32, 8);
|
||||
memcpy(&pb->s2, sig->schnorr + 40, 8);
|
||||
memcpy(&pb->s3, sig->schnorr + 48, 8);
|
||||
memcpy(&pb->s4, sig->schnorr + 56, 8);
|
||||
#else
|
||||
/* FIXME: Need a portable way to encode signatures in libsecp! */
|
||||
|
||||
/* Kill me now... */
|
||||
memcpy(&pb->r1, sig->r, 8);
|
||||
memcpy(&pb->r2, sig->r + 8, 8);
|
||||
memcpy(&pb->r3, sig->r + 16, 8);
|
||||
memcpy(&pb->r4, sig->r + 24, 8);
|
||||
memcpy(&pb->s1, sig->s, 8);
|
||||
memcpy(&pb->s2, sig->s + 8, 8);
|
||||
memcpy(&pb->s3, sig->s + 16, 8);
|
||||
memcpy(&pb->s4, sig->s + 24, 8);
|
||||
memcpy(&pb->r1, sig->sig.data, 8);
|
||||
memcpy(&pb->r2, sig->sig.data + 8, 8);
|
||||
memcpy(&pb->r3, sig->sig.data + 16, 8);
|
||||
memcpy(&pb->r4, sig->sig.data + 24, 8);
|
||||
memcpy(&pb->s1, sig->sig.data + 32, 8);
|
||||
memcpy(&pb->s2, sig->sig.data + 40, 8);
|
||||
memcpy(&pb->s3, sig->sig.data + 48, 8);
|
||||
memcpy(&pb->s4, sig->sig.data + 56, 8);
|
||||
#endif
|
||||
|
||||
return pb;
|
||||
}
|
||||
@ -26,14 +39,27 @@ Signature *signature_to_proto(const tal_t *ctx, const struct signature *sig)
|
||||
bool proto_to_signature(const Signature *pb, struct signature *sig)
|
||||
{
|
||||
/* Kill me again. */
|
||||
memcpy(sig->r, &pb->r1, 8);
|
||||
memcpy(sig->r + 8, &pb->r2, 8);
|
||||
memcpy(sig->r + 16, &pb->r3, 8);
|
||||
memcpy(sig->r + 24, &pb->r4, 8);
|
||||
memcpy(sig->s, &pb->s1, 8);
|
||||
memcpy(sig->s + 8, &pb->s2, 8);
|
||||
memcpy(sig->s + 16, &pb->s3, 8);
|
||||
memcpy(sig->s + 24, &pb->s4, 8);
|
||||
#ifdef USE_SCHNORR
|
||||
memcpy(sig->schnorr, &pb->r1, 8);
|
||||
memcpy(sig->schnorr + 8, &pb->r2, 8);
|
||||
memcpy(sig->schnorr + 16, &pb->r3, 8);
|
||||
memcpy(sig->schnorr + 24, &pb->r4, 8);
|
||||
memcpy(sig->schnorr + 32, &pb->s1, 8);
|
||||
memcpy(sig->schnorr + 40, &pb->s2, 8);
|
||||
memcpy(sig->schnorr + 48, &pb->s3, 8);
|
||||
memcpy(sig->schnorr + 56, &pb->s4, 8);
|
||||
#else
|
||||
/* FIXME: Need a portable way to encode signatures in libsecp! */
|
||||
|
||||
memcpy(sig->sig.data, &pb->r1, 8);
|
||||
memcpy(sig->sig.data + 8, &pb->r2, 8);
|
||||
memcpy(sig->sig.data + 16, &pb->r3, 8);
|
||||
memcpy(sig->sig.data + 24, &pb->r4, 8);
|
||||
memcpy(sig->sig.data + 32, &pb->s1, 8);
|
||||
memcpy(sig->sig.data + 40, &pb->s2, 8);
|
||||
memcpy(sig->sig.data + 48, &pb->s3, 8);
|
||||
memcpy(sig->sig.data + 56, &pb->s4, 8);
|
||||
#endif
|
||||
|
||||
return sig_valid(sig);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user