mirror of
https://github.com/ElementsProject/lightning.git
synced 2025-03-26 20:30:59 +01:00
Use raw 64-byte signatures in protocol.
DER encoding introduces problems for non-canonical encodings; we should do that only at the lightning<->bitcoin interface. Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
This commit is contained in:
parent
64b443dcd9
commit
eec612af9f
11 changed files with 348 additions and 187 deletions
|
@ -1,6 +1,7 @@
|
|||
#include "bitcoin_script.h"
|
||||
#include "bitcoin_address.h"
|
||||
#include "pkt.h"
|
||||
#include "signature.h"
|
||||
#include <openssl/ripemd.h>
|
||||
#include <ccan/endian/endian.h>
|
||||
#include <ccan/crypto/sha256/sha256.h>
|
||||
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
|
269
lightning.pb-c.c
269
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 */
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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!
|
||||
|
|
|
@ -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[])
|
||||
|
|
|
@ -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");
|
||||
|
|
41
pkt.c
41
pkt.c
|
@ -1,10 +1,10 @@
|
|||
#include <ccan/crypto/sha256/sha256.h>
|
||||
#include <ccan/tal/grab_file/grab_file.h>
|
||||
#include <ccan/err/err.h>
|
||||
#include <ccan/cast/cast.h>
|
||||
#include "pkt.h"
|
||||
#include "bitcoin_tx.h"
|
||||
#include "bitcoin_address.h"
|
||||
#include "signature.h"
|
||||
|
||||
#include <stdio.h>
|
||||
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);
|
||||
}
|
||||
|
|
9
pkt.h
9
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 */
|
||||
|
|
33
signature.c
33
signature.c
|
@ -6,12 +6,12 @@
|
|||
#include <assert.h>
|
||||
#include <ccan/cast/cast.h>
|
||||
|
||||
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);
|
||||
s = talz(ctx, struct signature);
|
||||
|
||||
/* 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);
|
||||
|
||||
ECDSA_SIG_free(sig);
|
||||
|
||||
if (len <= 0)
|
||||
return NULL;
|
||||
|
||||
ret = tal_dup_arr(ctx, u8, der, len, 0);
|
||||
OPENSSL_free(der);
|
||||
return ret;
|
||||
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;
|
||||
|
|
16
signature.h
16
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 */
|
||||
|
|
Loading…
Add table
Reference in a new issue