Rusty Russell
4 years ago
5 changed files with 208 additions and 0 deletions
@ -0,0 +1,131 @@ |
|||
#include <bitcoin/signature.h> |
|||
#include <ccan/crypto/sha256/sha256.h> |
|||
#include <ccan/mem/mem.h> |
|||
#include <common/bolt12_merkle.h> |
|||
|
|||
/* BOLT-offers #12:
|
|||
* TLV types 240 through 1000 are considered signature elements. |
|||
*/ |
|||
static bool is_signature_field(const struct tlv_field *field) |
|||
{ |
|||
return field->numtype >= 240 && field->numtype <= 1000; |
|||
} |
|||
|
|||
static void sha256_update_bigsize(struct sha256_ctx *ctx, u64 bigsize) |
|||
{ |
|||
u8 buf[BIGSIZE_MAX_LEN]; |
|||
size_t len; |
|||
|
|||
len = bigsize_put(buf, bigsize); |
|||
sha256_update(ctx, buf, len); |
|||
} |
|||
|
|||
static void sha256_update_tlvfield(struct sha256_ctx *ctx, |
|||
const struct tlv_field *field) |
|||
{ |
|||
/* We don't keep it raw, so reconstruct. */ |
|||
sha256_update_bigsize(ctx, field->numtype); |
|||
sha256_update_bigsize(ctx, field->length); |
|||
sha256_update(ctx, field->value, field->length); |
|||
} |
|||
|
|||
/* BOLT-offers #12:
|
|||
* The Merkle Tree's leaves are, in TLV-ascending order: |
|||
* 1. The SHA256 of: `LnLeaf` followed by the TLV entry. |
|||
* 2. The SHA256 of: `LnAll` followed all non-signature TLV entries appended |
|||
* in ascending order. |
|||
*/ |
|||
|
|||
static void calc_lnall(const struct tlv_field *fields, struct sha256 *hash) |
|||
{ |
|||
struct sha256_ctx sctx; |
|||
|
|||
sha256_init(&sctx); |
|||
sha256_update(&sctx, "LnAll", 5); |
|||
for (size_t i = 0; i < tal_count(fields); i++) { |
|||
if (!is_signature_field(&fields[i])) |
|||
sha256_update_tlvfield(&sctx, &fields[i]); |
|||
} |
|||
sha256_done(&sctx, hash); |
|||
} |
|||
|
|||
static void calc_lnleaf(const struct tlv_field *field, struct sha256 *hash) |
|||
{ |
|||
struct sha256_ctx sctx; |
|||
|
|||
sha256_init(&sctx); |
|||
sha256_update(&sctx, "LnLeaf", 6); |
|||
sha256_update_tlvfield(&sctx, field); |
|||
sha256_done(&sctx, hash); |
|||
} |
|||
|
|||
static struct sha256 merkle_pair(const struct sha256 a, const struct sha256 b) |
|||
{ |
|||
struct sha256 res; |
|||
struct sha256_ctx sctx; |
|||
|
|||
sha256_init(&sctx); |
|||
sha256_update(&sctx, "LnBranch", 8); |
|||
sha256_update(&sctx, a.u.u8, sizeof(a.u.u8)); |
|||
sha256_update(&sctx, b.u.u8, sizeof(b.u.u8)); |
|||
sha256_done(&sctx, &res); |
|||
|
|||
return res; |
|||
} |
|||
|
|||
static struct sha256 merkle_recurse(const struct sha256 *arr, size_t len) |
|||
{ |
|||
if (len == 1) |
|||
return arr[0]; |
|||
|
|||
return merkle_pair(merkle_recurse(arr, len / 2), |
|||
merkle_recurse(arr + len / 2, len - len / 2)); |
|||
} |
|||
|
|||
void merkle_tlv(const struct tlv_field *fields, struct sha256 *merkle) |
|||
{ |
|||
struct sha256 lnall, *arr; |
|||
size_t n; |
|||
|
|||
calc_lnall(fields, &lnall); |
|||
arr = tal_arr(NULL, struct sha256, tal_count(fields)); |
|||
|
|||
n = 0; |
|||
for (size_t i = 0; i < tal_count(fields); i++) { |
|||
struct sha256 s; |
|||
if (is_signature_field(&fields[i])) |
|||
continue; |
|||
calc_lnleaf(&fields[i], &s); |
|||
arr[n++] = merkle_pair(s, lnall); |
|||
} |
|||
|
|||
*merkle = merkle_recurse(arr, n); |
|||
tal_free(arr); |
|||
} |
|||
|
|||
/* BOLT-offers #12:
|
|||
* All signatures are created as per |
|||
* [BIP-340](https://github.com/bitcoin/bips/blob/master/bip-0340.mediawiki),
|
|||
* and tagged as recommended there. Thus to sign a message `msg` with |
|||
* `tag`, `m` is SHA256(SHA256(`tag`) || SHA256(`tag`) || `msg`). The |
|||
* notation used here is `SIG(tag,msg,key)`. |
|||
* |
|||
* Each form is signed using one or more TLV signature elements; TLV |
|||
* types 240 through 1000 are considered signature elements. For these |
|||
* the tag is `lightning` | `messagename` | `fieldname`, and `msg` is the |
|||
* merkle-root; `lightning` is the literal 9-byte ASCII string, |
|||
* `messagename` is the name of the TLV stream being signed (i.e. `offer` |
|||
* or `invoice`) and the `fieldname` is the TLV field containing the |
|||
* signature (e.g. `signature` or `recurrence_signature`). |
|||
*/ |
|||
void sighash_from_merkle(const char *messagename, |
|||
const char *fieldname, |
|||
const struct sha256 *merkle, |
|||
struct sha256 *sighash) |
|||
{ |
|||
struct sha256_ctx sctx; |
|||
|
|||
bip340_sighash_init(&sctx, "lightning", messagename, fieldname); |
|||
sha256_update(&sctx, merkle, sizeof(*merkle)); |
|||
sha256_done(&sctx, sighash); |
|||
} |
@ -0,0 +1,24 @@ |
|||
#ifndef LIGHTNING_COMMON_BOLT12_MERKLE_H |
|||
#define LIGHTNING_COMMON_BOLT12_MERKLE_H |
|||
#include "config.h" |
|||
#include <wire/bolt12_exp_wiregen.h> |
|||
|
|||
/**
|
|||
* merkle_tlv - bolt12-style merkle hash of this tlv minus signature fields |
|||
* @fields: tal_arr of fields from tlv. |
|||
* @merkle: returned merkle hash. |
|||
*/ |
|||
void merkle_tlv(const struct tlv_field *fields, struct sha256 *merkle); |
|||
|
|||
/**
|
|||
* sighash_from_merkle - bolt12-style signature hash using this merkle root. |
|||
* @messagename: message name, such as "offer". |
|||
* @fieldname: field name, such as "recurrence_signature". |
|||
* @merkle: the merkle root as calculated by merkle_tlv. |
|||
* @sighash: the returned hash. |
|||
*/ |
|||
void sighash_from_merkle(const char *messagename, |
|||
const char *fieldname, |
|||
const struct sha256 *merkle, |
|||
struct sha256 *sighash); |
|||
#endif /* LIGHTNING_COMMON_BOLT12_MERKLE_H */ |
Loading…
Reference in new issue