common: add blinding helpers.

We'll want this once we add blinded HTLCs.

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
This commit is contained in:
Rusty Russell 2020-04-03 13:46:56 +10:30
parent d9fc99ea39
commit 91251b1870
7 changed files with 78 additions and 84 deletions

View File

@ -37,6 +37,7 @@ CHANNELD_COMMON_OBJS := \
common/base32.o \
common/bigsize.o \
common/bip32.o \
common/blinding.o \
common/channel_config.o \
common/crypto_state.o \
common/crypto_sync.o \

View File

@ -27,6 +27,7 @@
#include <channeld/commit_tx.h>
#include <channeld/full_channel.h>
#include <channeld/gen_channel_wire.h>
#include <common/blinding.h>
#include <common/crypto_sync.h>
#include <common/dev_disconnect.h>
#include <common/features.h>
@ -1629,37 +1630,6 @@ static bool channeld_handle_custommsg(const u8 *msg)
}
#if EXPERIMENTAL_FEATURES
/* H(E(i) || ss(i)) */
static struct sha256 hash_e_and_ss(const struct pubkey *e,
const struct secret *ss)
{
u8 der[PUBKEY_CMPR_LEN];
struct sha256_ctx shactx;
struct sha256 h;
pubkey_to_der(der, e);
sha256_init(&shactx);
sha256_update(&shactx, der, sizeof(der));
sha256_update(&shactx, ss->data, sizeof(ss->data));
sha256_done(&shactx, &h);
return h;
}
/* E(i-1) = H(E(i) || ss(i)) * E(i) */
static struct pubkey next_pubkey(const struct pubkey *pk,
const struct sha256 *h)
{
struct pubkey ret;
ret = *pk;
if (secp256k1_ec_pubkey_tweak_mul(secp256k1_ctx, &ret.pubkey, h->u.u8)
!= 1)
abort();
return ret;
}
/* Peer sends onion msg. */
static void handle_onion_message(struct peer *peer, const u8 *msg)
{
@ -1866,9 +1836,10 @@ static void handle_onion_message(struct peer *peer, const u8 *msg)
if (blinding_ss) {
/* E(i-1) = H(E(i) || ss(i)) * E(i) */
struct sha256 h = hash_e_and_ss(blinding_in, blinding_ss);
struct sha256 h;
blinding_hash_e_and_ss(blinding_in, blinding_ss, &h);
next_blinding = tal(msg, struct pubkey);
*next_blinding = next_pubkey(blinding_in, &h);
blinding_next_pubkey(blinding_in, &h, next_blinding);
} else
next_blinding = NULL;

View File

@ -7,6 +7,7 @@ COMMON_SRC_NOGEN := \
common/bech32_util.c \
common/bigsize.c \
common/bip32.c \
common/blinding.c \
common/bolt11.c \
common/channel_config.c \
common/close_tx.c \

39
common/blinding.c Normal file
View File

@ -0,0 +1,39 @@
#include <bitcoin/privkey.h>
#include <bitcoin/pubkey.h>
#include <common/blinding.h>
#include <common/utils.h>
void blinding_hash_e_and_ss(const struct pubkey *e,
const struct secret *ss,
struct sha256 *sha)
{
u8 der[PUBKEY_CMPR_LEN];
struct sha256_ctx shactx;
pubkey_to_der(der, e);
sha256_init(&shactx);
sha256_update(&shactx, der, sizeof(der));
sha256_update(&shactx, ss->data, sizeof(ss->data));
sha256_done(&shactx, sha);
}
/* E(i+1) = H(E(i) || ss(i)) * E(i) */
bool blinding_next_pubkey(const struct pubkey *pk,
const struct sha256 *h,
struct pubkey *next)
{
*next = *pk;
return secp256k1_ec_pubkey_tweak_mul(secp256k1_ctx, &next->pubkey,
h->u.u8) == 1;
}
/* e(i+1) = H(E(i) || ss(i)) * e(i) */
bool blinding_next_privkey(const struct privkey *e,
const struct sha256 *h,
struct privkey *next)
{
*next = *e;
return secp256k1_ec_privkey_tweak_mul(secp256k1_ctx, next->secret.data,
h->u.u8) == 1;
}

25
common/blinding.h Normal file
View File

@ -0,0 +1,25 @@
#ifndef LIGHTNING_COMMON_BLINDING_H
#define LIGHTNING_COMMON_BLINDING_H
#include "config.h"
struct privkey;
struct pubkey;
struct secret;
struct sha256;
/* H(E(i) || ss(i)) */
void blinding_hash_e_and_ss(const struct pubkey *e,
const struct secret *ss,
struct sha256 *sha);
/* E(i+1) = H(E(i) || ss(i)) * E(i) */
bool blinding_next_pubkey(const struct pubkey *pk,
const struct sha256 *h,
struct pubkey *next);
/* e(i+1) = H(E(i) || ss(i)) * e(i) */
bool blinding_next_privkey(const struct privkey *e,
const struct sha256 *h,
struct privkey *next);
#endif /* LIGHTNING_COMMON_BLINDING_H */

View File

@ -70,7 +70,7 @@ devtools/onion.c: ccan/config.h
devtools/onion: $(DEVTOOLS_OBJS) $(DEVTOOLS_COMMON_OBJS) $(JSMN_OBJS) $(CCAN_OBJS) $(BITCOIN_OBJS) wire/fromwire.o wire/towire.o devtools/onion.o common/sphinx.o
devtools/blindedpath: $(DEVTOOLS_OBJS) $(DEVTOOLS_COMMON_OBJS) $(JSMN_OBJS) $(CCAN_OBJS) $(BITCOIN_OBJS) wire/fromwire.o wire/towire.o devtools/blindedpath.o common/sphinx.o
devtools/blindedpath: $(DEVTOOLS_OBJS) $(DEVTOOLS_COMMON_OBJS) $(JSMN_OBJS) $(CCAN_OBJS) common/blinding.o $(BITCOIN_OBJS) wire/fromwire.o wire/towire.o devtools/blindedpath.o common/sphinx.o
devtools/gossipwith: $(DEVTOOLS_OBJS) $(DEVTOOLS_COMMON_OBJS) $(JSMN_OBJS) $(CCAN_OBJS) $(BITCOIN_OBJS) wire/fromwire.o wire/towire.o wire/gen_peer_wire.o devtools/gossipwith.o common/cryptomsg.o common/cryptomsg.o common/crypto_sync.o

View File

@ -6,6 +6,7 @@
#include <ccan/opt/opt.h>
#include <ccan/str/hex/hex.h>
#include <ccan/tal/tal.h>
#include <common/blinding.h>
#include <common/hmac.h>
#include <common/sphinx.h>
#include <common/type_to_string.h>
@ -40,51 +41,6 @@ static void tal_freefn(void *ptr)
tal_free(ptr);
}
/* E(i-1) = H(E(i) || ss(i)) * E(i) */
static struct sha256 hash_e_and_ss(const struct pubkey *e,
const struct secret *ss)
{
u8 der[PUBKEY_CMPR_LEN];
struct sha256_ctx shactx;
struct sha256 h;
pubkey_to_der(der, e);
sha256_init(&shactx);
sha256_update(&shactx, der, sizeof(der));
sha256_update(&shactx, ss->data, sizeof(ss->data));
sha256_done(&shactx, &h);
return h;
}
/* E(i-1) = H(E(i) || ss(i)) * E(i) */
static struct pubkey next_pubkey(const struct pubkey *pk,
const struct sha256 *h)
{
struct pubkey ret;
ret = *pk;
if (secp256k1_ec_pubkey_tweak_mul(secp256k1_ctx, &ret.pubkey, h->u.u8)
!= 1)
abort();
return ret;
}
/* e(i+1) = H(E(i) || ss(i)) * e(i) */
static struct privkey next_privkey(const struct privkey *e,
const struct sha256 *h)
{
struct privkey ret;
ret = *e;
if (secp256k1_ec_privkey_tweak_mul(secp256k1_ctx, ret.secret.data,
h->u.u8) != 1)
abort();
return ret;
}
int main(int argc, char **argv)
{
bool first = false;
@ -155,10 +111,11 @@ int main(int argc, char **argv)
abort();
}
subkey_from_hmac("rho", &ss, &rho[i]);
h = hash_e_and_ss(&pk_e[i], &ss);
blinding_hash_e_and_ss(&pk_e[i], &ss, &h);
if (i != num-1)
pk_e[i+1] = next_pubkey(&pk_e[i], &h);
e = next_privkey(&e, &h);
blinding_next_pubkey(&pk_e[i], &h,
&pk_e[i+1]);
blinding_next_privkey(&e, &h, &e);
}
/* Print initial blinding factor */
@ -326,8 +283,8 @@ int main(int argc, char **argv)
printf("Contents: %s\n", tal_hex(tmpctx, dec));
/* E(i-1) = H(E(i) || ss(i)) * E(i) */
h = hash_e_and_ss(&blinding, &ss);
res = next_pubkey(&blinding, &h);
blinding_hash_e_and_ss(&blinding, &ss, &h);
blinding_next_pubkey(&blinding, &h, &res);
printf("Next blinding: %s\n",
type_to_string(tmpctx, struct pubkey, &res));
printf("Next onion: %s\n", tal_hex(tmpctx, serialize_onionpacket(tmpctx, rs->next)));