Browse Source

common/bolt12_merkle.h: experimental bolt 12 implementation.

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
fix-mocks
Rusty Russell 4 years ago
parent
commit
f06ad0471c
  1. 37
      bitcoin/signature.c
  2. 12
      bitcoin/signature.h
  3. 4
      common/Makefile
  4. 131
      common/bolt12_merkle.c
  5. 24
      common/bolt12_merkle.h

37
bitcoin/signature.c

@ -359,4 +359,41 @@ void fromwire_bip340sig(const u8 **cursor, size_t *max,
{
fromwire_u8_array(cursor, max, bip340sig->u8, sizeof(bip340sig->u8));
}
char *fmt_bip340sig(const tal_t *ctx, const struct bip340sig *bip340sig)
{
return tal_hexstr(ctx, bip340sig->u8, sizeof(bip340sig->u8));
}
REGISTER_TYPE_TO_HEXSTR(bip340sig);
/* BIP-340:
*
* This proposal suggests to include the tag by prefixing the hashed
* data with ''SHA256(tag) || SHA256(tag)''. Because this is a 64-byte
* long context-specific constant and the ''SHA256'' block size is
* also 64 bytes, optimized implementations are possible (identical to
* SHA256 itself, but with a modified initial state). Using SHA256 of
* the tag name itself is reasonably simple and efficient for
* implementations that don't choose to use the optimization.
*/
/* For caller convenience, we hand in tag in parts (any can be "") */
void bip340_sighash_init(struct sha256_ctx *sctx,
const char *tag1,
const char *tag2,
const char *tag3)
{
struct sha256 taghash;
sha256_init(sctx);
sha256_update(sctx, memcheck(tag1, strlen(tag1)), strlen(tag1));
sha256_update(sctx, memcheck(tag2, strlen(tag2)), strlen(tag2));
sha256_update(sctx, memcheck(tag3, strlen(tag3)), strlen(tag3));
sha256_done(sctx, &taghash);
sha256_init(sctx);
sha256_update(sctx, &taghash, sizeof(taghash));
sha256_update(sctx, &taghash, sizeof(taghash));
}

12
bitcoin/signature.h

@ -2,10 +2,12 @@
#define LIGHTNING_BITCOIN_SIGNATURE_H
#include "config.h"
#include <ccan/short_types/short_types.h>
#include <ccan/tal/tal.h>
#include <secp256k1.h>
#include <stdbool.h>
struct sha256_double;
struct sha256_ctx;
struct bitcoin_tx;
struct pubkey;
struct privkey;
@ -138,4 +140,14 @@ struct bip340sig {
void towire_bip340sig(u8 **pptr, const struct bip340sig *bip340sig);
void fromwire_bip340sig(const u8 **cursor, size_t *max,
struct bip340sig *bip340sig);
/* Get a hex string sig */
char *fmt_bip340sig(const tal_t *ctx, const struct bip340sig *bip340sig);
/* For caller convenience, we hand in tag in parts (any can be "") */
void bip340_sighash_init(struct sha256_ctx *sctx,
const char *tag1,
const char *tag2,
const char *tag3);
#endif /* LIGHTNING_BITCOIN_SIGNATURE_H */

4
common/Makefile

@ -86,6 +86,10 @@ endif
COMMON_SRC_GEN := common/status_wiregen.c common/peer_status_wiregen.c
ifeq ($(EXPERIMENTAL_FEATURES),1)
COMMON_SRC_NOGEN += common/bolt12_merkle.c
endif
COMMON_HEADERS_NOGEN := $(COMMON_SRC_NOGEN:.c=.h) \
common/closing_fee.h \
common/ecdh.h \

131
common/bolt12_merkle.c

@ -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);
}

24
common/bolt12_merkle.h

@ -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…
Cancel
Save