diff --git a/bitcoin_script.c b/bitcoin_script.c index a67b91f28..c496b1994 100644 --- a/bitcoin_script.c +++ b/bitcoin_script.c @@ -1,6 +1,7 @@ #include "bitcoin_script.h" #include "bitcoin_address.h" #include "pkt.h" +#include "signature.h" #include #include #include @@ -59,6 +60,25 @@ static void add_push_bytes(u8 **scriptp, const void *mem, size_t len) add(scriptp, mem, len); } +/* Bitcoin wants DER encoding. */ +static void add_push_sig(u8 **scriptp, const struct signature *sig) +{ + u8 der[2 + 2 + sizeof(sig->r) + 2 + sizeof(sig->s)]; + + der[0] = 0x30; /* Type */ + der[1] = sizeof(der) - 2; /* Total length */ + + der[2] = 0x2; /* r value type. */ + der[3] = sizeof(sig->r); /* r length */ + memcpy(der+4, sig->r, sizeof(sig->r)); + + der[4 + sizeof(sig->r)] = 0x2; /* s value type. */ + der[4 + sizeof(sig->r) + 1] = sizeof(sig->s); /* s value length. */ + memcpy(der+4+sizeof(sig->r)+2, sig->s, sizeof(sig->s)); + + add_push_bytes(scriptp, der, sizeof(der)); +} + /* FIXME: permute? */ /* Is a < b? (If equal we don't care) */ static bool key_less(const BitcoinPubkey *a, const BitcoinPubkey *b) @@ -140,12 +160,11 @@ u8 *scriptpubkey_pay_to_pubkeyhash(const tal_t *ctx, u8 *scriptsig_pay_to_pubkeyhash(const tal_t *ctx, const struct bitcoin_address *addr, - const u8 *signature, - size_t sig_len) + const struct signature *sig) { u8 *script = tal_arr(ctx, u8, 0); - add_push_bytes(&script, signature, sig_len); + add_push_sig(&script, sig); add_push_bytes(&script, addr, sizeof(*addr)); return script; diff --git a/bitcoin_script.h b/bitcoin_script.h index 62f06852d..f71b745d8 100644 --- a/bitcoin_script.h +++ b/bitcoin_script.h @@ -6,6 +6,7 @@ struct bitcoin_address; struct bitcoin_compressed_pubkey; +struct signature; /* tal_count() gives the length of the script. */ u8 *bitcoin_redeem_2of2(const tal_t *ctx, @@ -35,8 +36,7 @@ u8 *scriptpubkey_pay_to_pubkeyhash(const tal_t *ctx, /* Create an input script to accept pay to pubkey */ u8 *scriptsig_pay_to_pubkeyhash(const tal_t *ctx, const struct bitcoin_address *addr, - const u8 *signature, - size_t sig_len); + const struct signature *sig); /* Is this a normal pay to pubkey hash? */ bool is_pay_to_pubkey_hash(const ProtobufCBinaryData *script); diff --git a/lightning.pb-c.c b/lightning.pb-c.c index 661953124..8b6904cd1 100644 --- a/lightning.pb-c.c +++ b/lightning.pb-c.c @@ -50,6 +50,49 @@ void sha256_hash__free_unpacked assert(message->base.descriptor == &sha256_hash__descriptor); protobuf_c_message_free_unpacked ((ProtobufCMessage*)message, allocator); } +void signature__init + (Signature *message) +{ + static Signature init_value = SIGNATURE__INIT; + *message = init_value; +} +size_t signature__get_packed_size + (const Signature *message) +{ + assert(message->base.descriptor == &signature__descriptor); + return protobuf_c_message_get_packed_size ((const ProtobufCMessage*)(message)); +} +size_t signature__pack + (const Signature *message, + uint8_t *out) +{ + assert(message->base.descriptor == &signature__descriptor); + return protobuf_c_message_pack ((const ProtobufCMessage*)message, out); +} +size_t signature__pack_to_buffer + (const Signature *message, + ProtobufCBuffer *buffer) +{ + assert(message->base.descriptor == &signature__descriptor); + return protobuf_c_message_pack_to_buffer ((const ProtobufCMessage*)message, buffer); +} +Signature * + signature__unpack + (ProtobufCAllocator *allocator, + size_t len, + const uint8_t *data) +{ + return (Signature *) + protobuf_c_message_unpack (&signature__descriptor, + allocator, len, data); +} +void signature__free_unpacked + (Signature *message, + ProtobufCAllocator *allocator) +{ + assert(message->base.descriptor == &signature__descriptor); + protobuf_c_message_free_unpacked ((ProtobufCMessage*)message, allocator); +} void bitcoin_input__init (BitcoinInput *message) { @@ -136,49 +179,6 @@ void bitcoin_output__free_unpacked assert(message->base.descriptor == &bitcoin_output__descriptor); protobuf_c_message_free_unpacked ((ProtobufCMessage*)message, allocator); } -void bitcoin_signature__init - (BitcoinSignature *message) -{ - static BitcoinSignature init_value = BITCOIN_SIGNATURE__INIT; - *message = init_value; -} -size_t bitcoin_signature__get_packed_size - (const BitcoinSignature *message) -{ - assert(message->base.descriptor == &bitcoin_signature__descriptor); - return protobuf_c_message_get_packed_size ((const ProtobufCMessage*)(message)); -} -size_t bitcoin_signature__pack - (const BitcoinSignature *message, - uint8_t *out) -{ - assert(message->base.descriptor == &bitcoin_signature__descriptor); - return protobuf_c_message_pack ((const ProtobufCMessage*)message, out); -} -size_t bitcoin_signature__pack_to_buffer - (const BitcoinSignature *message, - ProtobufCBuffer *buffer) -{ - assert(message->base.descriptor == &bitcoin_signature__descriptor); - return protobuf_c_message_pack_to_buffer ((const ProtobufCMessage*)message, buffer); -} -BitcoinSignature * - bitcoin_signature__unpack - (ProtobufCAllocator *allocator, - size_t len, - const uint8_t *data) -{ - return (BitcoinSignature *) - protobuf_c_message_unpack (&bitcoin_signature__descriptor, - allocator, len, data); -} -void bitcoin_signature__free_unpacked - (BitcoinSignature *message, - ProtobufCAllocator *allocator) -{ - assert(message->base.descriptor == &bitcoin_signature__descriptor); - protobuf_c_message_free_unpacked ((ProtobufCMessage*)message, allocator); -} void bitcoin_pubkey__init (BitcoinPubkey *message) { @@ -1073,6 +1073,135 @@ const ProtobufCMessageDescriptor sha256_hash__descriptor = (ProtobufCMessageInit) sha256_hash__init, NULL,NULL,NULL /* reserved[123] */ }; +static const ProtobufCFieldDescriptor signature__field_descriptors[8] = +{ + { + "r1", + 1, + PROTOBUF_C_LABEL_REQUIRED, + PROTOBUF_C_TYPE_FIXED64, + 0, /* quantifier_offset */ + offsetof(Signature, r1), + NULL, + NULL, + 0, /* flags */ + 0,NULL,NULL /* reserved1,reserved2, etc */ + }, + { + "r2", + 2, + PROTOBUF_C_LABEL_REQUIRED, + PROTOBUF_C_TYPE_FIXED64, + 0, /* quantifier_offset */ + offsetof(Signature, r2), + NULL, + NULL, + 0, /* flags */ + 0,NULL,NULL /* reserved1,reserved2, etc */ + }, + { + "r3", + 3, + PROTOBUF_C_LABEL_REQUIRED, + PROTOBUF_C_TYPE_FIXED64, + 0, /* quantifier_offset */ + offsetof(Signature, r3), + NULL, + NULL, + 0, /* flags */ + 0,NULL,NULL /* reserved1,reserved2, etc */ + }, + { + "r4", + 4, + PROTOBUF_C_LABEL_REQUIRED, + PROTOBUF_C_TYPE_FIXED64, + 0, /* quantifier_offset */ + offsetof(Signature, r4), + NULL, + NULL, + 0, /* flags */ + 0,NULL,NULL /* reserved1,reserved2, etc */ + }, + { + "s1", + 5, + PROTOBUF_C_LABEL_REQUIRED, + PROTOBUF_C_TYPE_FIXED64, + 0, /* quantifier_offset */ + offsetof(Signature, s1), + NULL, + NULL, + 0, /* flags */ + 0,NULL,NULL /* reserved1,reserved2, etc */ + }, + { + "s2", + 6, + PROTOBUF_C_LABEL_REQUIRED, + PROTOBUF_C_TYPE_FIXED64, + 0, /* quantifier_offset */ + offsetof(Signature, s2), + NULL, + NULL, + 0, /* flags */ + 0,NULL,NULL /* reserved1,reserved2, etc */ + }, + { + "s3", + 7, + PROTOBUF_C_LABEL_REQUIRED, + PROTOBUF_C_TYPE_FIXED64, + 0, /* quantifier_offset */ + offsetof(Signature, s3), + NULL, + NULL, + 0, /* flags */ + 0,NULL,NULL /* reserved1,reserved2, etc */ + }, + { + "s4", + 8, + PROTOBUF_C_LABEL_REQUIRED, + PROTOBUF_C_TYPE_FIXED64, + 0, /* quantifier_offset */ + offsetof(Signature, s4), + NULL, + NULL, + 0, /* flags */ + 0,NULL,NULL /* reserved1,reserved2, etc */ + }, +}; +static const unsigned signature__field_indices_by_name[] = { + 0, /* field[0] = r1 */ + 1, /* field[1] = r2 */ + 2, /* field[2] = r3 */ + 3, /* field[3] = r4 */ + 4, /* field[4] = s1 */ + 5, /* field[5] = s2 */ + 6, /* field[6] = s3 */ + 7, /* field[7] = s4 */ +}; +static const ProtobufCIntRange signature__number_ranges[1 + 1] = +{ + { 1, 0 }, + { 0, 8 } +}; +const ProtobufCMessageDescriptor signature__descriptor = +{ + PROTOBUF_C__MESSAGE_DESCRIPTOR_MAGIC, + "signature", + "Signature", + "Signature", + "", + sizeof(Signature), + 8, + signature__field_descriptors, + signature__field_indices_by_name, + 1, signature__number_ranges, + (ProtobufCMessageInit) signature__init, + NULL,NULL,NULL /* reserved[123] */ +}; static const ProtobufCFieldDescriptor bitcoin_input__field_descriptors[4] = { { @@ -1201,44 +1330,6 @@ const ProtobufCMessageDescriptor bitcoin_output__descriptor = (ProtobufCMessageInit) bitcoin_output__init, NULL,NULL,NULL /* reserved[123] */ }; -static const ProtobufCFieldDescriptor bitcoin_signature__field_descriptors[1] = -{ - { - "der_then_sigtype", - 1, - PROTOBUF_C_LABEL_REQUIRED, - PROTOBUF_C_TYPE_BYTES, - 0, /* quantifier_offset */ - offsetof(BitcoinSignature, der_then_sigtype), - NULL, - NULL, - 0, /* flags */ - 0,NULL,NULL /* reserved1,reserved2, etc */ - }, -}; -static const unsigned bitcoin_signature__field_indices_by_name[] = { - 0, /* field[0] = der_then_sigtype */ -}; -static const ProtobufCIntRange bitcoin_signature__number_ranges[1 + 1] = -{ - { 1, 0 }, - { 0, 1 } -}; -const ProtobufCMessageDescriptor bitcoin_signature__descriptor = -{ - PROTOBUF_C__MESSAGE_DESCRIPTOR_MAGIC, - "bitcoin_signature", - "BitcoinSignature", - "BitcoinSignature", - "", - sizeof(BitcoinSignature), - 1, - bitcoin_signature__field_descriptors, - bitcoin_signature__field_indices_by_name, - 1, bitcoin_signature__number_ranges, - (ProtobufCMessageInit) bitcoin_signature__init, - NULL,NULL,NULL /* reserved[123] */ -}; static const ProtobufCFieldDescriptor bitcoin_pubkey__field_descriptors[1] = { { @@ -1509,7 +1600,7 @@ static const ProtobufCFieldDescriptor open_commit_sig__field_descriptors[1] = PROTOBUF_C_TYPE_MESSAGE, 0, /* quantifier_offset */ offsetof(OpenCommitSig, sig), - &bitcoin_signature__descriptor, + &signature__descriptor, NULL, 0, /* flags */ 0,NULL,NULL /* reserved1,reserved2, etc */ @@ -1685,7 +1776,7 @@ static const ProtobufCFieldDescriptor update__field_descriptors[4] = PROTOBUF_C_TYPE_MESSAGE, 0, /* quantifier_offset */ offsetof(Update, sig), - &bitcoin_signature__descriptor, + &signature__descriptor, NULL, 0, /* flags */ 0,NULL,NULL /* reserved1,reserved2, etc */ @@ -1697,7 +1788,7 @@ static const ProtobufCFieldDescriptor update__field_descriptors[4] = PROTOBUF_C_TYPE_MESSAGE, 0, /* quantifier_offset */ offsetof(Update, old_anchor_sig), - &bitcoin_signature__descriptor, + &signature__descriptor, NULL, 0, /* flags */ 0,NULL,NULL /* reserved1,reserved2, etc */ @@ -1738,7 +1829,7 @@ static const ProtobufCFieldDescriptor update_accept__field_descriptors[3] = PROTOBUF_C_TYPE_MESSAGE, 0, /* quantifier_offset */ offsetof(UpdateAccept, sig), - &bitcoin_signature__descriptor, + &signature__descriptor, NULL, 0, /* flags */ 0,NULL,NULL /* reserved1,reserved2, etc */ @@ -1750,7 +1841,7 @@ static const ProtobufCFieldDescriptor update_accept__field_descriptors[3] = PROTOBUF_C_TYPE_MESSAGE, 0, /* quantifier_offset */ offsetof(UpdateAccept, old_anchor_sig), - &bitcoin_signature__descriptor, + &signature__descriptor, NULL, 0, /* flags */ 0,NULL,NULL /* reserved1,reserved2, etc */ @@ -1916,7 +2007,7 @@ static const ProtobufCFieldDescriptor new_anchor_commit_sig__field_descriptors[1 PROTOBUF_C_TYPE_MESSAGE, 0, /* quantifier_offset */ offsetof(NewAnchorCommitSig, sig), - &bitcoin_signature__descriptor, + &signature__descriptor, NULL, 0, /* flags */ 0,NULL,NULL /* reserved1,reserved2, etc */ @@ -2030,7 +2121,7 @@ static const ProtobufCFieldDescriptor close_channel__field_descriptors[1] = PROTOBUF_C_TYPE_MESSAGE, 0, /* quantifier_offset */ offsetof(CloseChannel, sig), - &bitcoin_signature__descriptor, + &signature__descriptor, NULL, 0, /* flags */ 0,NULL,NULL /* reserved1,reserved2, etc */ @@ -2068,7 +2159,7 @@ static const ProtobufCFieldDescriptor close_channel_complete__field_descriptors[ PROTOBUF_C_TYPE_MESSAGE, 0, /* quantifier_offset */ offsetof(CloseChannelComplete, sig), - &bitcoin_signature__descriptor, + &signature__descriptor, NULL, 0, /* flags */ 0,NULL,NULL /* reserved1,reserved2, etc */ diff --git a/lightning.pb-c.h b/lightning.pb-c.h index 554918482..1ab668498 100644 --- a/lightning.pb-c.h +++ b/lightning.pb-c.h @@ -16,9 +16,9 @@ PROTOBUF_C__BEGIN_DECLS typedef struct _Sha256Hash Sha256Hash; +typedef struct _Signature Signature; typedef struct _BitcoinInput BitcoinInput; typedef struct _BitcoinOutput BitcoinOutput; -typedef struct _BitcoinSignature BitcoinSignature; typedef struct _BitcoinPubkey BitcoinPubkey; typedef struct _Anchor Anchor; typedef struct _OpenChannel OpenChannel; @@ -46,7 +46,7 @@ typedef struct _Pkt Pkt; /* --- messages --- */ /* - * Protobufs don't have fixed-length fields, so this is a hack. + * Protobufs don't have fixed-length fields, so these are a hack. */ struct _Sha256Hash { @@ -61,6 +61,23 @@ struct _Sha256Hash , 0, 0, 0, 0 } +struct _Signature +{ + ProtobufCMessage base; + uint64_t r1; + uint64_t r2; + uint64_t r3; + uint64_t r4; + uint64_t s1; + uint64_t s2; + uint64_t s3; + uint64_t s4; +}; +#define SIGNATURE__INIT \ + { PROTOBUF_C_MESSAGE_INIT (&signature__descriptor) \ + , 0, 0, 0, 0, 0, 0, 0, 0 } + + /* * Identifies consumption of a bitcoin output. */ @@ -103,19 +120,6 @@ struct _BitcoinOutput , 0, {0,NULL} } -/* - * A signature to use for a transaction; DER encoded with sigtype at the end. - */ -struct _BitcoinSignature -{ - ProtobufCMessage base; - ProtobufCBinaryData der_then_sigtype; -}; -#define BITCOIN_SIGNATURE__INIT \ - { PROTOBUF_C_MESSAGE_INIT (&bitcoin_signature__descriptor) \ - , {0,NULL} } - - /* * Pubkey for commitment transaction input. */ @@ -215,7 +219,7 @@ struct _OpenChannel struct _OpenCommitSig { ProtobufCMessage base; - BitcoinSignature *sig; + Signature *sig; }; #define OPEN_COMMIT_SIG__INIT \ { PROTOBUF_C_MESSAGE_INIT (&open_commit_sig__descriptor) \ @@ -291,14 +295,14 @@ struct _Update /* * Signature for new commitment tx. */ - BitcoinSignature *sig; + Signature *sig; /* * Signature for old anchor (if any) */ /* * FIXME: optional HTLC ops. */ - BitcoinSignature *old_anchor_sig; + Signature *old_anchor_sig; }; #define UPDATE__INIT \ { PROTOBUF_C_MESSAGE_INIT (&update__descriptor) \ @@ -314,11 +318,11 @@ struct _UpdateAccept /* * Signature for new commitment tx. */ - BitcoinSignature *sig; + Signature *sig; /* * Signature for old anchor (if any) */ - BitcoinSignature *old_anchor_sig; + Signature *old_anchor_sig; /* * Hash preimage which revokes old commitment tx. */ @@ -380,7 +384,7 @@ struct _NewAnchorAck struct _NewAnchorCommitSig { ProtobufCMessage base; - BitcoinSignature *sig; + Signature *sig; }; #define NEW_ANCHOR_COMMIT_SIG__INIT \ { PROTOBUF_C_MESSAGE_INIT (&new_anchor_commit_sig__descriptor) \ @@ -425,7 +429,7 @@ struct _CloseChannel * This is our signature a new transaction which spends my current * commitment tx output 0 (which is 2/2) to script_to_me. */ - BitcoinSignature *sig; + Signature *sig; }; #define CLOSE_CHANNEL__INIT \ { PROTOBUF_C_MESSAGE_INIT (&close_channel__descriptor) \ @@ -442,7 +446,7 @@ struct _CloseChannelComplete * This is our signature a new transaction which spends your current * commitment tx output 0 (which is 2/2) to your script_to_me. */ - BitcoinSignature *sig; + Signature *sig; }; #define CLOSE_CHANNEL_COMPLETE__INIT \ { PROTOBUF_C_MESSAGE_INIT (&close_channel_complete__descriptor) \ @@ -545,6 +549,25 @@ Sha256Hash * void sha256_hash__free_unpacked (Sha256Hash *message, ProtobufCAllocator *allocator); +/* Signature methods */ +void signature__init + (Signature *message); +size_t signature__get_packed_size + (const Signature *message); +size_t signature__pack + (const Signature *message, + uint8_t *out); +size_t signature__pack_to_buffer + (const Signature *message, + ProtobufCBuffer *buffer); +Signature * + signature__unpack + (ProtobufCAllocator *allocator, + size_t len, + const uint8_t *data); +void signature__free_unpacked + (Signature *message, + ProtobufCAllocator *allocator); /* BitcoinInput methods */ void bitcoin_input__init (BitcoinInput *message); @@ -583,25 +606,6 @@ BitcoinOutput * void bitcoin_output__free_unpacked (BitcoinOutput *message, ProtobufCAllocator *allocator); -/* BitcoinSignature methods */ -void bitcoin_signature__init - (BitcoinSignature *message); -size_t bitcoin_signature__get_packed_size - (const BitcoinSignature *message); -size_t bitcoin_signature__pack - (const BitcoinSignature *message, - uint8_t *out); -size_t bitcoin_signature__pack_to_buffer - (const BitcoinSignature *message, - ProtobufCBuffer *buffer); -BitcoinSignature * - bitcoin_signature__unpack - (ProtobufCAllocator *allocator, - size_t len, - const uint8_t *data); -void bitcoin_signature__free_unpacked - (BitcoinSignature *message, - ProtobufCAllocator *allocator); /* BitcoinPubkey methods */ void bitcoin_pubkey__init (BitcoinPubkey *message); @@ -968,15 +972,15 @@ void pkt__free_unpacked typedef void (*Sha256Hash_Closure) (const Sha256Hash *message, void *closure_data); +typedef void (*Signature_Closure) + (const Signature *message, + void *closure_data); typedef void (*BitcoinInput_Closure) (const BitcoinInput *message, void *closure_data); typedef void (*BitcoinOutput_Closure) (const BitcoinOutput *message, void *closure_data); -typedef void (*BitcoinSignature_Closure) - (const BitcoinSignature *message, - void *closure_data); typedef void (*BitcoinPubkey_Closure) (const BitcoinPubkey *message, void *closure_data); @@ -1041,9 +1045,9 @@ typedef void (*Pkt_Closure) /* --- descriptors --- */ extern const ProtobufCMessageDescriptor sha256_hash__descriptor; +extern const ProtobufCMessageDescriptor signature__descriptor; extern const ProtobufCMessageDescriptor bitcoin_input__descriptor; extern const ProtobufCMessageDescriptor bitcoin_output__descriptor; -extern const ProtobufCMessageDescriptor bitcoin_signature__descriptor; extern const ProtobufCMessageDescriptor bitcoin_pubkey__descriptor; extern const ProtobufCMessageDescriptor anchor__descriptor; extern const ProtobufCMessageDescriptor open_channel__descriptor; diff --git a/lightning.proto b/lightning.proto index 4381d8ff9..29efd4312 100644 --- a/lightning.proto +++ b/lightning.proto @@ -5,7 +5,7 @@ // Helper Types // -// Protobufs don't have fixed-length fields, so this is a hack. +// Protobufs don't have fixed-length fields, so these are a hack. message sha256_hash { required fixed64 a = 1; required fixed64 b = 2; @@ -13,6 +13,17 @@ message sha256_hash { required fixed64 d = 4; } +message signature { + required fixed64 r1 = 1; + required fixed64 r2 = 2; + required fixed64 r3 = 3; + required fixed64 r4 = 4; + required fixed64 s1 = 5; + required fixed64 s2 = 6; + required fixed64 s3 = 7; + required fixed64 s4 = 8; +} + // Identifies consumption of a bitcoin output. message bitcoin_input { // This is the transaction ID. @@ -31,11 +42,6 @@ message bitcoin_output { required bytes script = 2; } -// A signature to use for a transaction; DER encoded with sigtype at the end. -message bitcoin_signature { - required bytes der_then_sigtype = 1; -}; - // Pubkey for commitment transaction input. message bitcoin_pubkey { // Either 65 or 33 bytes. @@ -82,7 +88,7 @@ message open_channel { // Supply signature for commitment tx message open_commit_sig { - required bitcoin_signature sig = 1; + required signature sig = 1; } // Supply ScriptSig for each anchor tx inputs. @@ -116,18 +122,18 @@ message update { // Change in current payment to-me (implies reverse to-you). required sint64 delta = 2; // Signature for new commitment tx. - required bitcoin_signature sig = 3; + required signature sig = 3; // Signature for old anchor (if any) - optional bitcoin_signature old_anchor_sig = 4; + optional signature old_anchor_sig = 4; // FIXME: optional HTLC ops. } // OK, I accept that update. message update_accept { // Signature for new commitment tx. - required bitcoin_signature sig = 1; + required signature sig = 1; // Signature for old anchor (if any) - optional bitcoin_signature old_anchor_sig = 2; + optional signature old_anchor_sig = 2; // Hash preimage which revokes old commitment tx. required sha256_hash revocation_preimage = 3; } @@ -151,7 +157,7 @@ message new_anchor_ack { // Now we both send signatures for new commit sig. message new_anchor_commit_sig { - required bitcoin_signature sig = 1; + required signature sig = 1; } // Here are the script sigs for the new anchor's new inputs. @@ -169,14 +175,14 @@ message new_anchor_complete { message close_channel { // This is our signature a new transaction which spends my current // commitment tx output 0 (which is 2/2) to script_to_me. - required bitcoin_signature sig = 1; + required signature sig = 1; } // OK, here's my sig so you can broadcast it too. message close_channel_complete { // This is our signature a new transaction which spends your current // commitment tx output 0 (which is 2/2) to your script_to_me. - required bitcoin_signature sig = 1; + required signature sig = 1; } // This means we're going to hang up; it's to help diagnose only! diff --git a/open-anchor-sig.c b/open-anchor-sig.c index 58665a2eb..c55008925 100644 --- a/open-anchor-sig.c +++ b/open-anchor-sig.c @@ -25,7 +25,7 @@ static u8 *tx_scriptsig(const tal_t *ctx, EC_KEY *privkey, const struct bitcoin_compressed_pubkey *pubkey) { - u8 *sig; + struct signature *sig; struct bitcoin_address addr; sig = sign_tx_input(ctx, tx, i, @@ -37,7 +37,7 @@ static u8 *tx_scriptsig(const tal_t *ctx, if (!is_pay_to_pubkey_hash(&input->subscript)) errx(1, "FIXME: Don't know how to handle input"); bitcoin_address(pubkey, &addr); - return scriptsig_pay_to_pubkeyhash(ctx, &addr, sig, tal_count(sig)); + return scriptsig_pay_to_pubkeyhash(ctx, &addr, sig); } int main(int argc, char *argv[]) diff --git a/open-commit-sig.c b/open-commit-sig.c index 5b6c50fb9..7349e6d47 100644 --- a/open-commit-sig.c +++ b/open-commit-sig.c @@ -27,7 +27,7 @@ int main(int argc, char *argv[]) struct bitcoin_tx *anchor, *commit; struct sha256_double txid; struct pkt *pkt; - u8 *sig; + struct signature *sig; size_t *inmap, *outmap; EC_KEY *privkey; bool testnet; @@ -76,7 +76,7 @@ int main(int argc, char *argv[]) sig = sign_tx_input(ctx, commit, 0, anchor->output[outmap[0]].script, anchor->output[outmap[0]].script_length, privkey); - pkt = open_commit_sig_pkt(ctx, sig, tal_count(sig)); + pkt = open_commit_sig_pkt(ctx, sig); if (!write_all(STDOUT_FILENO, pkt, sizeof(pkt->len) + le32_to_cpu(pkt->len))) err(1, "Writing out packet"); diff --git a/pkt.c b/pkt.c index 98f6df87c..8c90dabd1 100644 --- a/pkt.c +++ b/pkt.c @@ -1,10 +1,10 @@ #include #include #include -#include #include "pkt.h" #include "bitcoin_tx.h" #include "bitcoin_address.h" +#include "signature.h" #include static struct pkt *to_pkt(const tal_t *ctx, Pkt__PktCase type, void *msg) @@ -47,6 +47,37 @@ void proto_to_sha256(const Sha256Hash *pb, struct sha256 *hash) memcpy(hash->u.u8 + 24, &pb->d, 8); } +Signature *signature_to_proto(const tal_t *ctx, const struct signature *sig) +{ + Signature *pb = tal(ctx, Signature); + signature__init(pb); + + /* 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); + + return pb; +} + +void 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); +} + BitcoinPubkey *pubkey_to_proto(const tal_t *ctx, const struct bitcoin_compressed_pubkey *key) { @@ -142,14 +173,10 @@ struct pkt *leak_anchor_sigs_and_pretend_we_didnt_pkt(const tal_t *ctx, return to_pkt(ctx, PKT__PKT_OMG_FAIL, &omg_fail); } -struct pkt *open_commit_sig_pkt(const tal_t *ctx, const u8 *sig, size_t siglen) +struct pkt *open_commit_sig_pkt(const tal_t *ctx, const struct signature *sig) { OpenCommitSig o = OPEN_COMMIT_SIG__INIT; - BitcoinSignature s = BITCOIN_SIGNATURE__INIT; - - o.sig = &s; - s.der_then_sigtype.len = siglen; - s.der_then_sigtype.data = cast_const(u8 *, sig); + o.sig = signature_to_proto(ctx, sig); return to_pkt(ctx, PKT__PKT_OPEN_COMMIT_SIG, &o); } diff --git a/pkt.h b/pkt.h index 6645b4701..295e32aca 100644 --- a/pkt.h +++ b/pkt.h @@ -21,6 +21,7 @@ Pkt *pkt_from_file(const char *filename, Pkt__PktCase expect); struct sha256; struct bitcoin_compressed_pubkey; +struct signature; /** * openchannel_pkt - create an openchannel message @@ -61,15 +62,17 @@ struct pkt *leak_anchor_sigs_and_pretend_we_didnt_pkt(const tal_t *ctx, /** * open_commit_sig_pkt - create an open_commit_sig message * @ctx: tal context to allocate off. - * @sig: the der-encoded signature for the commit transaction input. - * @siglen: the length of @sig. + * @sig: the signature for the commit transaction input. */ -struct pkt *open_commit_sig_pkt(const tal_t *ctx, const u8 *sig, size_t siglen); +struct pkt *open_commit_sig_pkt(const tal_t *ctx, const struct signature *sig); /* Useful helper for allocating & populating a protobuf Sha256Hash */ Sha256Hash *sha256_to_proto(const tal_t *ctx, const struct sha256 *hash); void proto_to_sha256(const Sha256Hash *pb, struct sha256 *hash); +Signature *signature_to_proto(const tal_t *ctx, const struct signature *sig); +void proto_to_signature(const Signature *pb, struct signature *sig); + BitcoinPubkey *pubkey_to_proto(const tal_t *ctx, const struct bitcoin_compressed_pubkey *key); #endif /* LIGHTNING_PKT_H */ diff --git a/signature.c b/signature.c index 9b585c9d3..28c6ae4a8 100644 --- a/signature.c +++ b/signature.c @@ -6,12 +6,12 @@ #include #include -u8 *sign_hash(const tal_t *ctx, EC_KEY *private_key, - const struct sha256_double *h) +struct signature *sign_hash(const tal_t *ctx, EC_KEY *private_key, + const struct sha256_double *h) { ECDSA_SIG *sig; int len; - unsigned char *der, *ret; + struct signature *s; sig = ECDSA_do_sign(h->sha.u.u8, sizeof(*h), private_key); if (!sig) @@ -33,21 +33,24 @@ u8 *sign_hash(const tal_t *ctx, EC_KEY *private_key, assert(!BN_is_odd(sig->s)); } - /* This tells it to allocate for us. */ - der = NULL; - len = i2d_ECDSA_SIG(sig, &der); - ECDSA_SIG_free(sig); + s = talz(ctx, struct signature); - if (len <= 0) - return NULL; + /* Pack r and s into signature, 32 bytes each. */ + len = BN_num_bytes(sig->r); + assert(len <= sizeof(s->r)); + BN_bn2bin(sig->r, s->r + sizeof(s->r) - len); + len = BN_num_bytes(sig->s); + assert(len <= sizeof(s->s)); + BN_bn2bin(sig->s, s->s + sizeof(s->s) - len); - ret = tal_dup_arr(ctx, u8, der, len, 0); - OPENSSL_free(der); - return ret; + ECDSA_SIG_free(sig); + return s; } -u8 *sign_tx_input(const tal_t *ctx, struct bitcoin_tx *tx, unsigned int in, - const u8 *subscript, size_t subscript_len, EC_KEY *privkey) +struct signature *sign_tx_input(const tal_t *ctx, struct bitcoin_tx *tx, + unsigned int in, + const u8 *subscript, size_t subscript_len, + EC_KEY *privkey) { struct sha256_double hash; struct sha256_ctx shactx; diff --git a/signature.h b/signature.h index d08941e82..55989d474 100644 --- a/signature.h +++ b/signature.h @@ -11,14 +11,22 @@ enum sighash_type { SIGHASH_ANYONECANPAY = 0x80 }; +/* ECDSA of double SHA256. */ +struct signature { + u8 r[32]; + u8 s[32]; +}; + struct sha256_double; struct bitcoin_tx; -u8 *sign_hash(const tal_t *ctx, EC_KEY *private_key, - const struct sha256_double *h); +struct signature *sign_hash(const tal_t *ctx, EC_KEY *private_key, + const struct sha256_double *h); /* All tx input scripts must be set to 0 len. */ -u8 *sign_tx_input(const tal_t *ctx, struct bitcoin_tx *tx, unsigned int in, - const u8 *subscript, size_t subscript_len, EC_KEY *privkey); +struct signature *sign_tx_input(const tal_t *ctx, + struct bitcoin_tx *tx, unsigned int in, + const u8 *subscript, size_t subscript_len, + EC_KEY *privkey); #endif /* LIGHTNING_SIGNATURE_H */