diff --git a/bitcoin/signature.c b/bitcoin/signature.c index 698d10842..abde8369b 100644 --- a/bitcoin/signature.c +++ b/bitcoin/signature.c @@ -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; - - der[len++] = 0x30; /* Type */ - der[len++] = 0; /* Total length after this: fill it at end. */ + size_t len = 72; + secp256k1_context *ctx = secp256k1_context_create(0); - 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 } diff --git a/bitcoin/signature.h b/bitcoin/signature.h index 34692f539..4822ebd49 100644 --- a/bitcoin/signature.h +++ b/bitcoin/signature.h @@ -2,6 +2,7 @@ #define LIGHTNING_BITCOIN_SIGNATURE_H #include #include +#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 */ diff --git a/protobuf_convert.c b/protobuf_convert.c index 8ec27a6bc..e83788e2d 100644 --- a/protobuf_convert.c +++ b/protobuf_convert.c @@ -10,30 +10,56 @@ 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; } 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); }