Skip to content

Commit

Permalink
bolt12: update to modern signature scheme.
Browse files Browse the repository at this point in the history
This changed, by popular demands.

Signed-off-by: Rusty Russell <[email protected]>
  • Loading branch information
rustyrussell authored and cdecker committed Nov 9, 2022
1 parent 1e3cb01 commit 5053561
Show file tree
Hide file tree
Showing 2 changed files with 124 additions and 95 deletions.
33 changes: 16 additions & 17 deletions common/bolt12_merkle.c
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
#include "config.h"
#include <assert.h>
#include <ccan/cast/cast.h>
#include <ccan/ilog/ilog.h>
#include <ccan/mem/mem.h>
Expand Down Expand Up @@ -54,23 +55,21 @@ static void h_simpletag_ctx(struct sha256_ctx *sctx, const char *tag)

/* BOLT-offers #12:
* The Merkle tree's leaves are, in TLV-ascending order for each tlv:
* 1. The H(`LnLeaf`,tlv).
* 2. The H(`LnAll`||all-tlvs,tlv) where "all-tlvs" consists of all non-signature TLV entries appended in ascending order.
* 1. The H("LnLeaf",tlv).
* 2. The H("LnNonce"||first-tlv,tlv-type) where first-tlv is the numerically-first TLV entry in the stream, and tlv-type is the "type" field (1-9 bytes) of the current tlv.
*/

/* Create a sha256_ctx which has the tag part done. */
static void h_lnall_ctx(struct sha256_ctx *sctx, const struct tlv_field *fields)
static void h_lnnonce_ctx(struct sha256_ctx *sctx, const struct tlv_field *fields)
{
struct sha256_ctx inner_sctx;
struct sha256 sha;

sha256_init(&inner_sctx);
sha256_update(&inner_sctx, "LnAll", 5);
SUPERVERBOSE("tag=SHA256(%s", tal_hexstr(tmpctx, "LnAll", 5));
for (size_t i = 0; i < tal_count(fields); i++) {
if (!is_signature_field(&fields[i]))
sha256_update_tlvfield(&inner_sctx, &fields[i]);
}
sha256_update(&inner_sctx, "LnNonce", 7);
SUPERVERBOSE("tag=SHA256(%s", tal_hexstr(tmpctx, "LnNonce", 7));
assert(tal_count(fields));
sha256_update_tlvfield(&inner_sctx, &fields[0]);
sha256_done(&inner_sctx, &sha);
SUPERVERBOSE(") -> %s\n",
type_to_string(tmpctx, struct sha256, &sha));
Expand All @@ -80,16 +79,16 @@ static void h_lnall_ctx(struct sha256_ctx *sctx, const struct tlv_field *fields)
sha256_update(sctx, &sha, sizeof(sha));
}

/* Use h_lnall_ctx to create nonce */
static void calc_nonce(const struct sha256_ctx *lnall_ctx,
/* Use h_lnnonce_ctx to create nonce */
static void calc_nonce(const struct sha256_ctx *lnnonce_ctx,
const struct tlv_field *field,
struct sha256 *hash)
{
/* Copy context, to add field */
struct sha256_ctx ctx = *lnall_ctx;
struct sha256_ctx ctx = *lnnonce_ctx;

SUPERVERBOSE("nonce: H(noncetag,");
sha256_update_tlvfield(&ctx, field);
sha256_update_bigsize(&ctx, field->numtype);

sha256_done(&ctx, hash);
SUPERVERBOSE(") = %s\n", type_to_string(tmpctx, struct sha256, hash));
Expand All @@ -108,7 +107,7 @@ static void calc_lnleaf(const struct tlv_field *field, struct sha256 *hash)
}

/* BOLT-offers #12:
* The Merkle tree inner nodes are H(`LnBranch`, lesser-SHA256||greater-SHA256)
* The Merkle tree inner nodes are H("LnBranch", lesser-SHA256||greater-SHA256)
*/
static struct sha256 *merkle_pair(const tal_t *ctx,
const struct sha256 *a, const struct sha256 *b)
Expand Down Expand Up @@ -159,11 +158,11 @@ static const struct sha256 *merkle_recurse(const struct sha256 **base,
void merkle_tlv(const struct tlv_field *fields, struct sha256 *merkle)
{
struct sha256 **arr;
struct sha256_ctx lnall_ctx;
struct sha256_ctx lnnonce_ctx;
size_t n;

SUPERVERBOSE("nonce tag:");
h_lnall_ctx(&lnall_ctx, fields);
h_lnnonce_ctx(&lnnonce_ctx, fields);

/* We build an oversized power-of-2 symmentic tree, but with
* NULL nodes at the end. When we recurse, we pass through
Expand All @@ -178,7 +177,7 @@ void merkle_tlv(const struct tlv_field *fields, struct sha256 *merkle)
if (is_signature_field(&fields[i]))
continue;
calc_lnleaf(&fields[i], &leaf);
calc_nonce(&lnall_ctx, &fields[i], &nonce);
calc_nonce(&lnnonce_ctx, &fields[i], &nonce);
arr[n++] = merkle_pair(arr, &leaf, &nonce);
}

Expand Down
Loading

0 comments on commit 5053561

Please sign in to comment.