mirror of
https://github.com/aljazceru/lightning.git
synced 2025-12-20 15:44:21 +01:00
spec: import latest onionmessage spec, based on routeblinding.
This is from 6e99c5feaf60cb797507d181fe583224309318e9 We renamed the enctlv field to encrypted_recipient_data in the spec, and the new onion_message is message 513. We don't handle it until the next patch. Two renames: 1. blinding_seed -> blinding_point. 2. enctlv -> encrypted_recipient_data. We don't do a compat cycle for our JSON APIs for these experimental features only used by our own plugins, we just rename. Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
This commit is contained in:
@@ -2321,6 +2321,7 @@ static void peer_in(struct peer *peer, const u8 *msg)
|
|||||||
case WIRE_WARNING:
|
case WIRE_WARNING:
|
||||||
case WIRE_ERROR:
|
case WIRE_ERROR:
|
||||||
case WIRE_OBS2_ONION_MESSAGE:
|
case WIRE_OBS2_ONION_MESSAGE:
|
||||||
|
case WIRE_ONION_MESSAGE:
|
||||||
abort();
|
abort();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -58,12 +58,12 @@ static bool blind_node(const struct privkey *blinding,
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
static u8 *enctlv_from_encmsg(const tal_t *ctx,
|
static u8 *enctlv_from_encmsg_raw(const tal_t *ctx,
|
||||||
const struct privkey *blinding,
|
const struct privkey *blinding,
|
||||||
const struct pubkey *node,
|
const struct pubkey *node,
|
||||||
const struct tlv_obs2_encmsg_tlvs *encmsg,
|
const u8 *raw_encmsg TAKES,
|
||||||
struct privkey *next_blinding,
|
struct privkey *next_blinding,
|
||||||
struct pubkey *node_alias)
|
struct pubkey *node_alias)
|
||||||
{
|
{
|
||||||
/* https://github.com/lightningnetwork/lightning-rfc/blob/route-blinding/proposals/route-blinding.md */
|
/* https://github.com/lightningnetwork/lightning-rfc/blob/route-blinding/proposals/route-blinding.md */
|
||||||
struct secret ss, rho;
|
struct secret ss, rho;
|
||||||
@@ -87,9 +87,7 @@ static u8 *enctlv_from_encmsg(const tal_t *ctx,
|
|||||||
if (!blind_node(blinding, &ss, node, node_alias, next_blinding))
|
if (!blind_node(blinding, &ss, node, node_alias, next_blinding))
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
/* Marshall */
|
ret = tal_dup_talarr(ctx, u8, raw_encmsg);
|
||||||
ret = tal_arr(ctx, u8, 0);
|
|
||||||
towire_obs2_encmsg_tlvs(&ret, encmsg);
|
|
||||||
SUPERVERBOSE("\t\"encmsg_hex\": \"%s\",\n", tal_hex(tmpctx, ret));
|
SUPERVERBOSE("\t\"encmsg_hex\": \"%s\",\n", tal_hex(tmpctx, ret));
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -115,6 +113,32 @@ static u8 *enctlv_from_encmsg(const tal_t *ctx,
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static u8 *enctlv_from_obs2_encmsg(const tal_t *ctx,
|
||||||
|
const struct privkey *blinding,
|
||||||
|
const struct pubkey *node,
|
||||||
|
const struct tlv_obs2_encmsg_tlvs *encmsg,
|
||||||
|
struct privkey *next_blinding,
|
||||||
|
struct pubkey *node_alias)
|
||||||
|
{
|
||||||
|
u8 *encmsg_raw = tal_arr(NULL, u8, 0);
|
||||||
|
towire_obs2_encmsg_tlvs(&encmsg_raw, encmsg);
|
||||||
|
return enctlv_from_encmsg_raw(ctx, blinding, node, take(encmsg_raw),
|
||||||
|
next_blinding, node_alias);
|
||||||
|
}
|
||||||
|
|
||||||
|
static u8 *enctlv_from_encmsg(const tal_t *ctx,
|
||||||
|
const struct privkey *blinding,
|
||||||
|
const struct pubkey *node,
|
||||||
|
const struct tlv_encrypted_data_tlv *encmsg,
|
||||||
|
struct privkey *next_blinding,
|
||||||
|
struct pubkey *node_alias)
|
||||||
|
{
|
||||||
|
u8 *encmsg_raw = tal_arr(NULL, u8, 0);
|
||||||
|
towire_encrypted_data_tlv(&encmsg_raw, encmsg);
|
||||||
|
return enctlv_from_encmsg_raw(ctx, blinding, node, take(encmsg_raw),
|
||||||
|
next_blinding, node_alias);
|
||||||
|
}
|
||||||
|
|
||||||
bool unblind_onion(const struct pubkey *blinding,
|
bool unblind_onion(const struct pubkey *blinding,
|
||||||
void (*ecdh)(const struct pubkey *point, struct secret *ss),
|
void (*ecdh)(const struct pubkey *point, struct secret *ss),
|
||||||
struct pubkey *onion_key,
|
struct pubkey *onion_key,
|
||||||
@@ -136,16 +160,13 @@ bool unblind_onion(const struct pubkey *blinding,
|
|||||||
hmac.data) == 1;
|
hmac.data) == 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct tlv_obs2_encmsg_tlvs *decrypt_encmsg(const tal_t *ctx,
|
static u8 *decrypt_encmsg_raw(const tal_t *ctx,
|
||||||
const struct pubkey *blinding,
|
const struct pubkey *blinding,
|
||||||
const struct secret *ss,
|
const struct secret *ss,
|
||||||
const u8 *enctlv)
|
const u8 *enctlv)
|
||||||
{
|
{
|
||||||
struct secret rho;
|
struct secret rho;
|
||||||
u8 *dec;
|
u8 *dec;
|
||||||
const u8 *cursor;
|
|
||||||
size_t maxlen;
|
|
||||||
struct tlv_obs2_encmsg_tlvs *encmsg;
|
|
||||||
/* All-zero npub */
|
/* All-zero npub */
|
||||||
static const unsigned char npub[crypto_aead_chacha20poly1305_ietf_NPUBBYTES];
|
static const unsigned char npub[crypto_aead_chacha20poly1305_ietf_NPUBBYTES];
|
||||||
|
|
||||||
@@ -161,7 +182,7 @@ static struct tlv_obs2_encmsg_tlvs *decrypt_encmsg(const tal_t *ctx,
|
|||||||
if (tal_bytelen(enctlv) < crypto_aead_chacha20poly1305_ietf_ABYTES)
|
if (tal_bytelen(enctlv) < crypto_aead_chacha20poly1305_ietf_ABYTES)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
dec = tal_arr(tmpctx, u8, tal_bytelen(enctlv)
|
dec = tal_arr(ctx, u8, tal_bytelen(enctlv)
|
||||||
- crypto_aead_chacha20poly1305_ietf_ABYTES);
|
- crypto_aead_chacha20poly1305_ietf_ABYTES);
|
||||||
if (crypto_aead_chacha20poly1305_ietf_decrypt(dec, NULL,
|
if (crypto_aead_chacha20poly1305_ietf_decrypt(dec, NULL,
|
||||||
NULL,
|
NULL,
|
||||||
@@ -169,10 +190,19 @@ static struct tlv_obs2_encmsg_tlvs *decrypt_encmsg(const tal_t *ctx,
|
|||||||
NULL, 0,
|
NULL, 0,
|
||||||
npub,
|
npub,
|
||||||
rho.data) != 0)
|
rho.data) != 0)
|
||||||
return NULL;
|
return tal_free(dec);
|
||||||
|
|
||||||
cursor = dec;
|
return dec;
|
||||||
maxlen = tal_bytelen(dec);
|
}
|
||||||
|
|
||||||
|
static struct tlv_obs2_encmsg_tlvs *decrypt_obs2_encmsg(const tal_t *ctx,
|
||||||
|
const struct pubkey *blinding,
|
||||||
|
const struct secret *ss,
|
||||||
|
const u8 *enctlv)
|
||||||
|
{
|
||||||
|
struct tlv_obs2_encmsg_tlvs *encmsg;
|
||||||
|
const u8 *cursor = decrypt_encmsg_raw(tmpctx, blinding, ss, enctlv);
|
||||||
|
size_t maxlen = tal_bytelen(cursor);
|
||||||
|
|
||||||
/* BOLT-onion-message #4:
|
/* BOLT-onion-message #4:
|
||||||
*
|
*
|
||||||
@@ -187,6 +217,156 @@ static struct tlv_obs2_encmsg_tlvs *decrypt_encmsg(const tal_t *ctx,
|
|||||||
return encmsg;
|
return encmsg;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static struct tlv_encrypted_data_tlv *decrypt_encmsg(const tal_t *ctx,
|
||||||
|
const struct pubkey *blinding,
|
||||||
|
const struct secret *ss,
|
||||||
|
const u8 *enctlv)
|
||||||
|
{
|
||||||
|
struct tlv_encrypted_data_tlv *encmsg;
|
||||||
|
const u8 *cursor = decrypt_encmsg_raw(tmpctx, blinding, ss, enctlv);
|
||||||
|
size_t maxlen = tal_bytelen(cursor);
|
||||||
|
|
||||||
|
/* BOLT-onion-message #4:
|
||||||
|
*
|
||||||
|
* - if the `enctlv` is not a valid TLV...
|
||||||
|
* - MUST drop the message.
|
||||||
|
*/
|
||||||
|
encmsg = tlv_encrypted_data_tlv_new(ctx);
|
||||||
|
if (!fromwire_encrypted_data_tlv(&cursor, &maxlen, encmsg)
|
||||||
|
|| !tlv_fields_valid(encmsg->fields, NULL, NULL))
|
||||||
|
return tal_free(encmsg);
|
||||||
|
|
||||||
|
return encmsg;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool decrypt_enctlv(const struct pubkey *blinding,
|
||||||
|
const struct secret *ss,
|
||||||
|
const u8 *enctlv,
|
||||||
|
struct pubkey *next_node,
|
||||||
|
struct pubkey *next_blinding)
|
||||||
|
{
|
||||||
|
struct tlv_encrypted_data_tlv *encmsg;
|
||||||
|
|
||||||
|
encmsg = decrypt_encmsg(tmpctx, blinding, ss, enctlv);
|
||||||
|
if (!encmsg)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
/* BOLT-onion-message #4:
|
||||||
|
*
|
||||||
|
* The reader:
|
||||||
|
* - if it is not the final node according to the onion encryption:
|
||||||
|
*...
|
||||||
|
* - if the `enctlv` ... does not contain
|
||||||
|
* `next_node_id`:
|
||||||
|
* - MUST drop the message.
|
||||||
|
*/
|
||||||
|
if (!encmsg->next_node_id)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
/* BOLT-onion-message #4:
|
||||||
|
* The reader:
|
||||||
|
* - if it is not the final node according to the onion encryption:
|
||||||
|
*...
|
||||||
|
* - if the `enctlv` contains `path_id`:
|
||||||
|
* - MUST drop the message.
|
||||||
|
*/
|
||||||
|
if (encmsg->path_id)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
/* BOLT-onion-message #4:
|
||||||
|
* The reader:
|
||||||
|
* - if it is not the final node according to the onion encryption:
|
||||||
|
*...
|
||||||
|
* - if `blinding` is specified in the `enctlv`:
|
||||||
|
* - MUST pass that as `blinding` in the `onion_message`
|
||||||
|
* - otherwise:
|
||||||
|
* - MUST pass `blinding` derived as in
|
||||||
|
* [Route Blinding][route-blinding] (i.e.
|
||||||
|
* `E(i+1) = H(E(i) || ss(i)) * E(i)`).
|
||||||
|
*/
|
||||||
|
*next_node = *encmsg->next_node_id;
|
||||||
|
if (encmsg->next_blinding_override)
|
||||||
|
*next_blinding = *encmsg->next_blinding_override;
|
||||||
|
else {
|
||||||
|
/* E(i-1) = H(E(i) || ss(i)) * E(i) */
|
||||||
|
struct sha256 h;
|
||||||
|
blinding_hash_e_and_ss(blinding, ss, &h);
|
||||||
|
blinding_next_pubkey(blinding, &h, next_blinding);
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool decrypt_final_enctlv(const tal_t *ctx,
|
||||||
|
const struct pubkey *blinding,
|
||||||
|
const struct secret *ss,
|
||||||
|
const u8 *enctlv,
|
||||||
|
const struct pubkey *my_id,
|
||||||
|
struct pubkey *alias,
|
||||||
|
struct secret **path_id)
|
||||||
|
{
|
||||||
|
struct tlv_encrypted_data_tlv *encmsg;
|
||||||
|
struct secret node_id_blinding;
|
||||||
|
|
||||||
|
/* Repeat the tweak to get the alias it was using for us */
|
||||||
|
subkey_from_hmac("blinded_node_id", ss, &node_id_blinding);
|
||||||
|
*alias = *my_id;
|
||||||
|
if (secp256k1_ec_pubkey_tweak_mul(secp256k1_ctx,
|
||||||
|
&alias->pubkey,
|
||||||
|
node_id_blinding.data) != 1)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
encmsg = decrypt_encmsg(tmpctx, blinding, ss, enctlv);
|
||||||
|
if (!encmsg)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (tal_bytelen(encmsg->path_id) == sizeof(**path_id)) {
|
||||||
|
*path_id = tal(ctx, struct secret);
|
||||||
|
memcpy(*path_id, encmsg->path_id, sizeof(**path_id));
|
||||||
|
} else
|
||||||
|
*path_id = NULL;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
u8 *create_enctlv(const tal_t *ctx,
|
||||||
|
const struct privkey *blinding,
|
||||||
|
const struct pubkey *node,
|
||||||
|
const struct pubkey *next_node,
|
||||||
|
size_t padlen,
|
||||||
|
const struct pubkey *next_blinding_override,
|
||||||
|
struct privkey *next_blinding,
|
||||||
|
struct pubkey *node_alias)
|
||||||
|
{
|
||||||
|
struct tlv_encrypted_data_tlv *encmsg = tlv_encrypted_data_tlv_new(tmpctx);
|
||||||
|
if (padlen)
|
||||||
|
encmsg->padding = tal_arrz(encmsg, u8, padlen);
|
||||||
|
encmsg->next_node_id = cast_const(struct pubkey *, next_node);
|
||||||
|
encmsg->next_blinding_override = cast_const(struct pubkey *, next_blinding_override);
|
||||||
|
|
||||||
|
return enctlv_from_encmsg(ctx, blinding, node, encmsg,
|
||||||
|
next_blinding, node_alias);
|
||||||
|
}
|
||||||
|
|
||||||
|
u8 *create_final_enctlv(const tal_t *ctx,
|
||||||
|
const struct privkey *blinding,
|
||||||
|
const struct pubkey *final_node,
|
||||||
|
size_t padlen,
|
||||||
|
const struct secret *path_id,
|
||||||
|
struct pubkey *node_alias)
|
||||||
|
{
|
||||||
|
struct tlv_encrypted_data_tlv *encmsg = tlv_encrypted_data_tlv_new(tmpctx);
|
||||||
|
struct privkey unused_next_blinding;
|
||||||
|
|
||||||
|
if (padlen)
|
||||||
|
encmsg->padding = tal_arrz(encmsg, u8, padlen);
|
||||||
|
if (path_id)
|
||||||
|
encmsg->path_id = (u8 *)tal_dup(encmsg, struct secret, path_id);
|
||||||
|
|
||||||
|
return enctlv_from_encmsg(ctx, blinding, final_node, encmsg,
|
||||||
|
&unused_next_blinding, node_alias);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Obsolete variants */
|
||||||
bool decrypt_obs2_enctlv(const struct pubkey *blinding,
|
bool decrypt_obs2_enctlv(const struct pubkey *blinding,
|
||||||
const struct secret *ss,
|
const struct secret *ss,
|
||||||
const u8 *enctlv,
|
const u8 *enctlv,
|
||||||
@@ -195,7 +375,7 @@ bool decrypt_obs2_enctlv(const struct pubkey *blinding,
|
|||||||
{
|
{
|
||||||
struct tlv_obs2_encmsg_tlvs *encmsg;
|
struct tlv_obs2_encmsg_tlvs *encmsg;
|
||||||
|
|
||||||
encmsg = decrypt_encmsg(tmpctx, blinding, ss, enctlv);
|
encmsg = decrypt_obs2_encmsg(tmpctx, blinding, ss, enctlv);
|
||||||
if (!encmsg)
|
if (!encmsg)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
@@ -263,7 +443,7 @@ bool decrypt_obs2_final_enctlv(const tal_t *ctx,
|
|||||||
node_id_blinding.data) != 1)
|
node_id_blinding.data) != 1)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
encmsg = decrypt_encmsg(tmpctx, blinding, ss, enctlv);
|
encmsg = decrypt_obs2_encmsg(tmpctx, blinding, ss, enctlv);
|
||||||
if (!encmsg)
|
if (!encmsg)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
@@ -291,8 +471,8 @@ u8 *create_obs2_enctlv(const tal_t *ctx,
|
|||||||
encmsg->next_node_id = cast_const(struct pubkey *, next_node);
|
encmsg->next_node_id = cast_const(struct pubkey *, next_node);
|
||||||
encmsg->next_blinding = cast_const(struct pubkey *, override_blinding);
|
encmsg->next_blinding = cast_const(struct pubkey *, override_blinding);
|
||||||
|
|
||||||
return enctlv_from_encmsg(ctx, blinding, node, encmsg,
|
return enctlv_from_obs2_encmsg(ctx, blinding, node, encmsg,
|
||||||
next_blinding, node_alias);
|
next_blinding, node_alias);
|
||||||
}
|
}
|
||||||
|
|
||||||
u8 *create_obs2_final_enctlv(const tal_t *ctx,
|
u8 *create_obs2_final_enctlv(const tal_t *ctx,
|
||||||
@@ -310,6 +490,6 @@ u8 *create_obs2_final_enctlv(const tal_t *ctx,
|
|||||||
if (self_id)
|
if (self_id)
|
||||||
encmsg->self_id = (u8 *)tal_dup(encmsg, struct secret, self_id);
|
encmsg->self_id = (u8 *)tal_dup(encmsg, struct secret, self_id);
|
||||||
|
|
||||||
return enctlv_from_encmsg(ctx, blinding, final_node, encmsg,
|
return enctlv_from_obs2_encmsg(ctx, blinding, final_node, encmsg,
|
||||||
&unused_next_blinding, node_alias);
|
&unused_next_blinding, node_alias);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -17,18 +17,18 @@ struct secret;
|
|||||||
* @node: the pubkey of the node to encrypt for
|
* @node: the pubkey of the node to encrypt for
|
||||||
* @next_node: the pubkey of the next node, to place in enctlv
|
* @next_node: the pubkey of the next node, to place in enctlv
|
||||||
* @padlen: if non-zero, the bytes of padding to add (also adds 2 byte padding hdr)
|
* @padlen: if non-zero, the bytes of padding to add (also adds 2 byte padding hdr)
|
||||||
* @override_blinding: the optional blinding point to place in enctlv
|
* @next_blinding_override: the optional blinding point to place in enctlv
|
||||||
* @next_blinding: (out) e(i+1), the next blinding secret.
|
* @next_blinding: (out) e(i+1), the next blinding secret.
|
||||||
* @node_alias: (out) the blinded pubkey of the node to tell the recipient.
|
* @node_alias: (out) the blinded pubkey of the node to tell the recipient.
|
||||||
*
|
*
|
||||||
* Returns the enctlv blob, or NULL if the secret is invalid.
|
* Returns the enctlv blob, or NULL if the secret is invalid.
|
||||||
*/
|
*/
|
||||||
u8 *create_obs2_enctlv(const tal_t *ctx,
|
u8 *create_enctlv(const tal_t *ctx,
|
||||||
const struct privkey *blinding,
|
const struct privkey *blinding,
|
||||||
const struct pubkey *node,
|
const struct pubkey *node,
|
||||||
const struct pubkey *next_node,
|
const struct pubkey *next_node,
|
||||||
size_t padlen,
|
size_t padlen,
|
||||||
const struct pubkey *override_blinding,
|
const struct pubkey *next_blinding_override,
|
||||||
struct privkey *next_blinding,
|
struct privkey *next_blinding,
|
||||||
struct pubkey *node_alias)
|
struct pubkey *node_alias)
|
||||||
NON_NULL_ARGS(2, 3, 4, 7, 8);
|
NON_NULL_ARGS(2, 3, 4, 7, 8);
|
||||||
@@ -39,16 +39,16 @@ u8 *create_obs2_enctlv(const tal_t *ctx,
|
|||||||
* @blinding: e(i), the blinding secret
|
* @blinding: e(i), the blinding secret
|
||||||
* @final_node: the pubkey of the node to encrypt for
|
* @final_node: the pubkey of the node to encrypt for
|
||||||
* @padlen: if non-zero, the bytes of padding to add (also adds 2 byte padding hdr)
|
* @padlen: if non-zero, the bytes of padding to add (also adds 2 byte padding hdr)
|
||||||
* @self_id: secret to include in enctlv, if not NULL.
|
* @path_id: secret to include in enctlv, if not NULL.
|
||||||
* @node_alias: (out) the blinded pubkey of the node to tell the recipient.
|
* @node_alias: (out) the blinded pubkey of the node to tell the recipient.
|
||||||
*
|
*
|
||||||
* If it fails, it means one of the privkeys is bad.
|
* If it fails, it means one of the privkeys is bad.
|
||||||
*/
|
*/
|
||||||
u8 *create_obs2_final_enctlv(const tal_t *ctx,
|
u8 *create_final_enctlv(const tal_t *ctx,
|
||||||
const struct privkey *blinding,
|
const struct privkey *blinding,
|
||||||
const struct pubkey *final_node,
|
const struct pubkey *final_node,
|
||||||
size_t padlen,
|
size_t padlen,
|
||||||
const struct secret *self_id,
|
const struct secret *path_id,
|
||||||
struct pubkey *node_alias)
|
struct pubkey *node_alias)
|
||||||
NON_NULL_ARGS(2, 3, 6);
|
NON_NULL_ARGS(2, 3, 6);
|
||||||
|
|
||||||
@@ -77,7 +77,7 @@ bool unblind_onion(const struct pubkey *blinding,
|
|||||||
*
|
*
|
||||||
* Returns false if decryption failed or encmsg was malformed.
|
* Returns false if decryption failed or encmsg was malformed.
|
||||||
*/
|
*/
|
||||||
bool decrypt_obs2_enctlv(const struct pubkey *blinding,
|
bool decrypt_enctlv(const struct pubkey *blinding,
|
||||||
const struct secret *ss,
|
const struct secret *ss,
|
||||||
const u8 *enctlv,
|
const u8 *enctlv,
|
||||||
struct pubkey *next_node,
|
struct pubkey *next_node,
|
||||||
@@ -86,23 +86,55 @@ bool decrypt_obs2_enctlv(const struct pubkey *blinding,
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* decrypt_final_enctlv - Decrypt an encmsg to form an enctlv.
|
* decrypt_final_enctlv - Decrypt an encmsg to form an enctlv.
|
||||||
* @ctx: tal context for @self_id
|
* @ctx: tal context for @path_id
|
||||||
* @blinding: E(i), the blinding pubkey the previous peer gave us.
|
* @blinding: E(i), the blinding pubkey the previous peer gave us.
|
||||||
* @ss: the blinding secret from unblind_onion().
|
* @ss: the blinding secret from unblind_onion().
|
||||||
* @enctlv: the enctlv from the onion (tal, may be NULL).
|
* @enctlv: the enctlv from the onion (tal, may be NULL).
|
||||||
* @my_id: the pubkey of this node.
|
* @my_id: the pubkey of this node.
|
||||||
* @alias: (out) the node_id this was addressed to.
|
* @alias: (out) the node_id this was addressed to.
|
||||||
* @self_id: (out) the secret contained in the enctlv, if any.
|
* @path_id: (out) the secret contained in the enctlv, if any (NULL if invalid or unset)
|
||||||
*
|
*
|
||||||
* Returns false if decryption failed or encmsg was malformed.
|
* Returns false if decryption failed or encmsg was malformed.
|
||||||
*/
|
*/
|
||||||
bool decrypt_obs2_final_enctlv(const tal_t *ctx,
|
bool decrypt_final_enctlv(const tal_t *ctx,
|
||||||
const struct pubkey *blinding,
|
const struct pubkey *blinding,
|
||||||
const struct secret *ss,
|
const struct secret *ss,
|
||||||
const u8 *enctlv,
|
const u8 *enctlv,
|
||||||
const struct pubkey *my_id,
|
const struct pubkey *my_id,
|
||||||
struct pubkey *alias,
|
struct pubkey *alias,
|
||||||
struct secret **self_id)
|
struct secret **path_id)
|
||||||
|
NON_NULL_ARGS(1, 2, 4, 5);
|
||||||
|
|
||||||
|
/* Obsolete variants */
|
||||||
|
u8 *create_obs2_enctlv(const tal_t *ctx,
|
||||||
|
const struct privkey *blinding,
|
||||||
|
const struct pubkey *node,
|
||||||
|
const struct pubkey *next_node,
|
||||||
|
size_t padlen,
|
||||||
|
const struct pubkey *override_blinding,
|
||||||
|
struct privkey *next_blinding,
|
||||||
|
struct pubkey *node_alias)
|
||||||
|
NON_NULL_ARGS(2, 3, 4, 7, 8);
|
||||||
|
u8 *create_obs2_final_enctlv(const tal_t *ctx,
|
||||||
|
const struct privkey *blinding,
|
||||||
|
const struct pubkey *final_node,
|
||||||
|
size_t padlen,
|
||||||
|
const struct secret *self_id,
|
||||||
|
struct pubkey *node_alias)
|
||||||
|
NON_NULL_ARGS(2, 3, 6);
|
||||||
|
bool decrypt_obs2_enctlv(const struct pubkey *blinding,
|
||||||
|
const struct secret *ss,
|
||||||
|
const u8 *enctlv,
|
||||||
|
struct pubkey *next_node,
|
||||||
|
struct pubkey *next_blinding)
|
||||||
|
NON_NULL_ARGS(1, 2, 4, 5);
|
||||||
|
bool decrypt_obs2_final_enctlv(const tal_t *ctx,
|
||||||
|
const struct pubkey *blinding,
|
||||||
|
const struct secret *ss,
|
||||||
|
const u8 *enctlv,
|
||||||
|
const struct pubkey *my_id,
|
||||||
|
struct pubkey *alias,
|
||||||
|
struct secret **self_id)
|
||||||
NON_NULL_ARGS(1, 2, 4, 5);
|
NON_NULL_ARGS(1, 2, 4, 5);
|
||||||
|
|
||||||
#endif /* LIGHTNING_COMMON_BLINDEDPATH_H */
|
#endif /* LIGHTNING_COMMON_BLINDEDPATH_H */
|
||||||
|
|||||||
@@ -164,12 +164,48 @@ json_to_obs2_reply_path(const tal_t *ctx, const char *buffer, const jsmntok_t *t
|
|||||||
rpath->path = tal_arr(rpath, struct onionmsg_path *, hops->size);
|
rpath->path = tal_arr(rpath, struct onionmsg_path *, hops->size);
|
||||||
json_for_each_arr(i, t, hops) {
|
json_for_each_arr(i, t, hops) {
|
||||||
rpath->path[i] = tal(rpath->path, struct onionmsg_path);
|
rpath->path[i] = tal(rpath->path, struct onionmsg_path);
|
||||||
err = json_scan(tmpctx, buffer, t, "{id:%,enctlv:%}",
|
err = json_scan(tmpctx, buffer, t, "{id:%,encrypted_recipient_data:%}",
|
||||||
JSON_SCAN(json_to_pubkey,
|
JSON_SCAN(json_to_pubkey,
|
||||||
&rpath->path[i]->node_id),
|
&rpath->path[i]->node_id),
|
||||||
JSON_SCAN_TAL(rpath->path[i],
|
JSON_SCAN_TAL(rpath->path[i],
|
||||||
json_tok_bin_from_hex,
|
json_tok_bin_from_hex,
|
||||||
&rpath->path[i]->enctlv));
|
&rpath->path[i]->encrypted_recipient_data));
|
||||||
|
if (err)
|
||||||
|
return tal_free(rpath);
|
||||||
|
}
|
||||||
|
|
||||||
|
return rpath;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct tlv_onionmsg_payload_reply_path *
|
||||||
|
json_to_reply_path(const tal_t *ctx, const char *buffer, const jsmntok_t *tok)
|
||||||
|
{
|
||||||
|
struct tlv_onionmsg_payload_reply_path *rpath;
|
||||||
|
const jsmntok_t *hops, *t;
|
||||||
|
size_t i;
|
||||||
|
const char *err;
|
||||||
|
|
||||||
|
rpath = tal(ctx, struct tlv_onionmsg_payload_reply_path);
|
||||||
|
err = json_scan(tmpctx, buffer, tok, "{blinding:%,first_node_id:%}",
|
||||||
|
JSON_SCAN(json_to_pubkey, &rpath->blinding),
|
||||||
|
JSON_SCAN(json_to_pubkey, &rpath->first_node_id),
|
||||||
|
NULL);
|
||||||
|
if (err)
|
||||||
|
return tal_free(rpath);
|
||||||
|
|
||||||
|
hops = json_get_member(buffer, tok, "hops");
|
||||||
|
if (!hops || hops->size < 1)
|
||||||
|
return tal_free(rpath);
|
||||||
|
|
||||||
|
rpath->path = tal_arr(rpath, struct onionmsg_path *, hops->size);
|
||||||
|
json_for_each_arr(i, t, hops) {
|
||||||
|
rpath->path[i] = tal(rpath->path, struct onionmsg_path);
|
||||||
|
err = json_scan(tmpctx, buffer, t, "{id:%,encrypted_recipient_data:%}",
|
||||||
|
JSON_SCAN(json_to_pubkey,
|
||||||
|
&rpath->path[i]->node_id),
|
||||||
|
JSON_SCAN_TAL(rpath->path[i],
|
||||||
|
json_tok_bin_from_hex,
|
||||||
|
&rpath->path[i]->encrypted_recipient_data));
|
||||||
if (err)
|
if (err)
|
||||||
return tal_free(rpath);
|
return tal_free(rpath);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -80,6 +80,10 @@ bool split_tok(const char *buffer, const jsmntok_t *tok,
|
|||||||
jsmntok_t *b);
|
jsmntok_t *b);
|
||||||
|
|
||||||
/* Extract reply path from this JSON */
|
/* Extract reply path from this JSON */
|
||||||
|
struct tlv_onionmsg_payload_reply_path *
|
||||||
|
json_to_reply_path(const tal_t *ctx, const char *buffer, const jsmntok_t *tok);
|
||||||
|
|
||||||
|
/* Obsolete version! */
|
||||||
struct tlv_obs2_onionmsg_payload_reply_path *
|
struct tlv_obs2_onionmsg_payload_reply_path *
|
||||||
json_to_obs2_reply_path(const tal_t *ctx, const char *buffer, const jsmntok_t *tok);
|
json_to_obs2_reply_path(const tal_t *ctx, const char *buffer, const jsmntok_t *tok);
|
||||||
|
|
||||||
|
|||||||
@@ -82,8 +82,8 @@ u8 *onion_nonfinal_hop(const tal_t *ctx,
|
|||||||
tlv->short_channel_id = cast_const(struct short_channel_id *,
|
tlv->short_channel_id = cast_const(struct short_channel_id *,
|
||||||
scid);
|
scid);
|
||||||
#if EXPERIMENTAL_FEATURES
|
#if EXPERIMENTAL_FEATURES
|
||||||
tlv->blinding_seed = cast_const(struct pubkey *, blinding);
|
tlv->blinding_point = cast_const(struct pubkey *, blinding);
|
||||||
tlv->enctlv = cast_const(u8 *, enctlv);
|
tlv->encrypted_recipient_data = cast_const(u8 *, enctlv);
|
||||||
#endif
|
#endif
|
||||||
return make_tlv_hop(ctx, tlv);
|
return make_tlv_hop(ctx, tlv);
|
||||||
} else {
|
} else {
|
||||||
@@ -135,8 +135,8 @@ u8 *onion_final_hop(const tal_t *ctx,
|
|||||||
tlv->payment_data = &tlv_pdata;
|
tlv->payment_data = &tlv_pdata;
|
||||||
}
|
}
|
||||||
#if EXPERIMENTAL_FEATURES
|
#if EXPERIMENTAL_FEATURES
|
||||||
tlv->blinding_seed = cast_const(struct pubkey *, blinding);
|
tlv->blinding_point = cast_const(struct pubkey *, blinding);
|
||||||
tlv->enctlv = cast_const(u8 *, enctlv);
|
tlv->encrypted_recipient_data = cast_const(u8 *, enctlv);
|
||||||
#endif
|
#endif
|
||||||
return make_tlv_hop(ctx, tlv);
|
return make_tlv_hop(ctx, tlv);
|
||||||
} else {
|
} else {
|
||||||
@@ -362,10 +362,10 @@ struct onion_payload *onion_decode(const tal_t *ctx,
|
|||||||
#if EXPERIMENTAL_FEATURES
|
#if EXPERIMENTAL_FEATURES
|
||||||
if (!p->blinding) {
|
if (!p->blinding) {
|
||||||
/* If we have no blinding, it could be in TLV. */
|
/* If we have no blinding, it could be in TLV. */
|
||||||
if (tlv->blinding_seed) {
|
if (tlv->blinding_point) {
|
||||||
p->blinding =
|
p->blinding =
|
||||||
tal_dup(p, struct pubkey,
|
tal_dup(p, struct pubkey,
|
||||||
tlv->blinding_seed);
|
tlv->blinding_point);
|
||||||
ecdh(p->blinding, &p->blinding_ss);
|
ecdh(p->blinding, &p->blinding_ss);
|
||||||
}
|
}
|
||||||
} else
|
} else
|
||||||
@@ -377,12 +377,12 @@ struct onion_payload *onion_decode(const tal_t *ctx,
|
|||||||
if (rs->nextcase == ONION_FORWARD) {
|
if (rs->nextcase == ONION_FORWARD) {
|
||||||
struct tlv_tlv_payload *ntlv;
|
struct tlv_tlv_payload *ntlv;
|
||||||
|
|
||||||
if (!tlv->enctlv)
|
if (!tlv->encrypted_recipient_data)
|
||||||
goto fail;
|
goto fail;
|
||||||
|
|
||||||
ntlv = decrypt_tlv(tmpctx,
|
ntlv = decrypt_tlv(tmpctx,
|
||||||
&p->blinding_ss,
|
&p->blinding_ss,
|
||||||
tlv->enctlv);
|
tlv->encrypted_recipient_data);
|
||||||
if (!ntlv)
|
if (!ntlv)
|
||||||
goto fail;
|
goto fail;
|
||||||
|
|
||||||
|
|||||||
@@ -136,7 +136,7 @@ int main(int argc, char *argv[])
|
|||||||
|
|
||||||
/* We output the JSON test vectors. */
|
/* We output the JSON test vectors. */
|
||||||
printf("[{");
|
printf("[{");
|
||||||
json_strfield("test name", "Simple enctlv for Alice, next is Bob");
|
json_strfield("test name", "Simple encrypted_recipient_data for Alice, next is Bob");
|
||||||
json_strfield("node_privkey",
|
json_strfield("node_privkey",
|
||||||
type_to_string(tmpctx, struct privkey, &alice));
|
type_to_string(tmpctx, struct privkey, &alice));
|
||||||
json_strfield("node_id",
|
json_strfield("node_id",
|
||||||
@@ -145,14 +145,14 @@ int main(int argc, char *argv[])
|
|||||||
type_to_string(tmpctx, struct privkey, &blinding));
|
type_to_string(tmpctx, struct privkey, &blinding));
|
||||||
json_strfield("blinding",
|
json_strfield("blinding",
|
||||||
type_to_string(tmpctx, struct pubkey, &blinding_pub));
|
type_to_string(tmpctx, struct pubkey, &blinding_pub));
|
||||||
printf("\t\"encmsg\": {\n"
|
printf("\t\"encrypted_data_tlv\": {\n"
|
||||||
"\t\t\"next_node_id\": \"%s\"\n"
|
"\t\t\"next_node_id\": \"%s\"\n"
|
||||||
"\t},\n",
|
"\t},\n",
|
||||||
type_to_string(tmpctx, struct pubkey, &bob_id));
|
type_to_string(tmpctx, struct pubkey, &bob_id));
|
||||||
|
|
||||||
enctlv = create_obs2_enctlv(tmpctx, &blinding, &alice_id, &bob_id,
|
enctlv = create_obs2_enctlv(tmpctx, &blinding, &alice_id, &bob_id,
|
||||||
0, NULL, &blinding, &alias);
|
0, NULL, &blinding, &alias);
|
||||||
printf("\t\"enctlv_hex\": \"%s\"\n"
|
printf("\t\"encrypted_recipient_data_hex\": \"%s\"\n"
|
||||||
"},\n",
|
"},\n",
|
||||||
tal_hex(tmpctx, enctlv));
|
tal_hex(tmpctx, enctlv));
|
||||||
|
|
||||||
@@ -164,7 +164,7 @@ int main(int argc, char *argv[])
|
|||||||
|
|
||||||
printf("{");
|
printf("{");
|
||||||
json_strfield("test name",
|
json_strfield("test name",
|
||||||
"Blinding-key-override enctlv for Bob, next is Carol");
|
"Blinding-key-override encrypted_recipient_data for Bob, next is Carol");
|
||||||
json_strfield("node_privkey",
|
json_strfield("node_privkey",
|
||||||
type_to_string(tmpctx, struct privkey, &bob));
|
type_to_string(tmpctx, struct privkey, &bob));
|
||||||
json_strfield("node_id",
|
json_strfield("node_id",
|
||||||
@@ -173,7 +173,7 @@ int main(int argc, char *argv[])
|
|||||||
type_to_string(tmpctx, struct privkey, &blinding));
|
type_to_string(tmpctx, struct privkey, &blinding));
|
||||||
json_strfield("blinding",
|
json_strfield("blinding",
|
||||||
type_to_string(tmpctx, struct pubkey, &blinding_pub));
|
type_to_string(tmpctx, struct pubkey, &blinding_pub));
|
||||||
printf("\t\"encmsg\": {\n"
|
printf("\t\"encrypted_data_tlv\": {\n"
|
||||||
"\t\t\"next_node_id\": \"%s\",\n"
|
"\t\t\"next_node_id\": \"%s\",\n"
|
||||||
"\t\t\"blinding\": \"%s\"\n"
|
"\t\t\"blinding\": \"%s\"\n"
|
||||||
"\t},\n",
|
"\t},\n",
|
||||||
@@ -182,7 +182,7 @@ int main(int argc, char *argv[])
|
|||||||
|
|
||||||
enctlv = create_obs2_enctlv(tmpctx, &blinding, &bob_id, &carol_id,
|
enctlv = create_obs2_enctlv(tmpctx, &blinding, &bob_id, &carol_id,
|
||||||
0, &override_blinding_pub, &blinding, &alias);
|
0, &override_blinding_pub, &blinding, &alias);
|
||||||
printf("\t\"enctlv_hex\": \"%s\"\n"
|
printf("\t\"encrypted_recipient_data_hex\": \"%s\"\n"
|
||||||
"},\n",
|
"},\n",
|
||||||
tal_hex(tmpctx, enctlv));
|
tal_hex(tmpctx, enctlv));
|
||||||
|
|
||||||
@@ -193,7 +193,7 @@ int main(int argc, char *argv[])
|
|||||||
blinding_pub = override_blinding_pub;
|
blinding_pub = override_blinding_pub;
|
||||||
|
|
||||||
printf("{");
|
printf("{");
|
||||||
json_strfield("test name", "Padded enctlv for Carol, next is Dave");
|
json_strfield("test name", "Padded encrypted_recipient_data for Carol, next is Dave");
|
||||||
json_strfield("node_privkey",
|
json_strfield("node_privkey",
|
||||||
type_to_string(tmpctx, struct privkey, &carol));
|
type_to_string(tmpctx, struct privkey, &carol));
|
||||||
json_strfield("node_id",
|
json_strfield("node_id",
|
||||||
@@ -202,7 +202,7 @@ int main(int argc, char *argv[])
|
|||||||
type_to_string(tmpctx, struct privkey, &blinding));
|
type_to_string(tmpctx, struct privkey, &blinding));
|
||||||
json_strfield("blinding",
|
json_strfield("blinding",
|
||||||
type_to_string(tmpctx, struct pubkey, &blinding_pub));
|
type_to_string(tmpctx, struct pubkey, &blinding_pub));
|
||||||
printf("\t\"encmsg\": {\n"
|
printf("\t\"encrypted_data_tlv\": {\n"
|
||||||
"\t\t\"next_node_id\": \"%s\",\n"
|
"\t\t\"next_node_id\": \"%s\",\n"
|
||||||
"\t\t\"padding\": \"%s\"\n"
|
"\t\t\"padding\": \"%s\"\n"
|
||||||
"\t},\n",
|
"\t},\n",
|
||||||
@@ -211,7 +211,7 @@ int main(int argc, char *argv[])
|
|||||||
|
|
||||||
enctlv = create_obs2_enctlv(tmpctx, &blinding, &carol_id, &dave_id,
|
enctlv = create_obs2_enctlv(tmpctx, &blinding, &carol_id, &dave_id,
|
||||||
35, NULL, &blinding, &alias);
|
35, NULL, &blinding, &alias);
|
||||||
printf("\t\"enctlv_hex\": \"%s\"\n"
|
printf("\t\"encrypted_recipient_data_hex\": \"%s\"\n"
|
||||||
"}]\n",
|
"}]\n",
|
||||||
tal_hex(tmpctx, enctlv));
|
tal_hex(tmpctx, enctlv));
|
||||||
|
|
||||||
|
|||||||
@@ -269,11 +269,11 @@ int main(int argc, char **argv)
|
|||||||
|
|
||||||
/* Look for enctlv */
|
/* Look for enctlv */
|
||||||
if (!outer->enctlv)
|
if (!outer->enctlv)
|
||||||
errx(1, "No enctlv field");
|
errx(1, "No encrypted_recipient_data field");
|
||||||
|
|
||||||
if (tal_bytelen(outer->enctlv)
|
if (tal_bytelen(outer->enctlv)
|
||||||
< crypto_aead_chacha20poly1305_ietf_ABYTES)
|
< crypto_aead_chacha20poly1305_ietf_ABYTES)
|
||||||
errx(1, "enctlv field too short");
|
errx(1, "encrypted_recipient_data field too short");
|
||||||
|
|
||||||
dec = tal_arr(tmpctx, u8,
|
dec = tal_arr(tmpctx, u8,
|
||||||
tal_bytelen(outer->enctlv)
|
tal_bytelen(outer->enctlv)
|
||||||
@@ -286,7 +286,7 @@ int main(int argc, char **argv)
|
|||||||
npub,
|
npub,
|
||||||
rho.data);
|
rho.data);
|
||||||
if (ret != 0)
|
if (ret != 0)
|
||||||
errx(1, "Failed to decrypt enctlv field");
|
errx(1, "Failed to decrypt encrypted_recipient_data field");
|
||||||
|
|
||||||
printf("Contents: %s\n", tal_hex(tmpctx, dec));
|
printf("Contents: %s\n", tal_hex(tmpctx, dec));
|
||||||
|
|
||||||
|
|||||||
@@ -270,7 +270,7 @@ static bool print_blindedpaths(struct blinded_path **paths,
|
|||||||
printf(" %s:%s",
|
printf(" %s:%s",
|
||||||
type_to_string(tmpctx, struct pubkey,
|
type_to_string(tmpctx, struct pubkey,
|
||||||
&p[j]->node_id),
|
&p[j]->node_id),
|
||||||
tal_hex(tmpctx, p[j]->enctlv));
|
tal_hex(tmpctx, p[j]->encrypted_recipient_data));
|
||||||
if (blindedpay) {
|
if (blindedpay) {
|
||||||
if (bp_idx < tal_count(blindedpay))
|
if (bp_idx < tal_count(blindedpay))
|
||||||
printf("fee=%u/%u,cltv=%u,features=%s",
|
printf("fee=%u/%u,cltv=%u,features=%s",
|
||||||
|
|||||||
@@ -1542,7 +1542,7 @@ The payload for a call follows this format:
|
|||||||
"reply_first_node": "02df5ffe895c778e10f7742a6c5b8a0cefbe9465df58b92fadeb883752c8107c8f",
|
"reply_first_node": "02df5ffe895c778e10f7742a6c5b8a0cefbe9465df58b92fadeb883752c8107c8f",
|
||||||
"reply_blinding": "02df5ffe895c778e10f7742a6c5b8a0cefbe9465df58b92fadeb883752c8107c8f",
|
"reply_blinding": "02df5ffe895c778e10f7742a6c5b8a0cefbe9465df58b92fadeb883752c8107c8f",
|
||||||
"reply_path": [ {"id": "02df5ffe895c778e10f7742a6c5b8a0cefbe9465df58b92fadeb883752c8107c8f",
|
"reply_path": [ {"id": "02df5ffe895c778e10f7742a6c5b8a0cefbe9465df58b92fadeb883752c8107c8f",
|
||||||
"enctlv": "0a020d0d",
|
"encrypted_recipient_data": "0a020d0d",
|
||||||
"blinding": "02df5ffe895c778e10f7742a6c5b8a0cefbe9465df58b92fadeb883752c8107c8f"} ],
|
"blinding": "02df5ffe895c778e10f7742a6c5b8a0cefbe9465df58b92fadeb883752c8107c8f"} ],
|
||||||
"invoice_request": "0a020d0d",
|
"invoice_request": "0a020d0d",
|
||||||
"invoice": "0a020d0d",
|
"invoice": "0a020d0d",
|
||||||
|
|||||||
@@ -42,7 +42,7 @@ If **type** is "bolt12 offer", and **valid** is *true*:
|
|||||||
- **blinding** (pubkey): blinding factor for this path
|
- **blinding** (pubkey): blinding factor for this path
|
||||||
- **path** (array of objects): an individual path:
|
- **path** (array of objects): an individual path:
|
||||||
- **node_id** (pubkey): node_id of the hop
|
- **node_id** (pubkey): node_id of the hop
|
||||||
- **enctlv** (hex): encrypted TLV entry for this hop
|
- **encrypted_recipient_data** (hex): encrypted TLV entry for this hop
|
||||||
- **quantity_min** (u64, optional): the minimum quantity
|
- **quantity_min** (u64, optional): the minimum quantity
|
||||||
- **quantity_max** (u64, optional): the maximum quantity
|
- **quantity_max** (u64, optional): the maximum quantity
|
||||||
- **recurrence** (object, optional): how often to this offer should be used:
|
- **recurrence** (object, optional): how often to this offer should be used:
|
||||||
@@ -82,7 +82,7 @@ If **type** is "bolt12 invoice", and **valid** is *true*:
|
|||||||
- **blinding** (pubkey): blinding factor for this path
|
- **blinding** (pubkey): blinding factor for this path
|
||||||
- **path** (array of objects): an individual path:
|
- **path** (array of objects): an individual path:
|
||||||
- **node_id** (pubkey): node_id of the hop
|
- **node_id** (pubkey): node_id of the hop
|
||||||
- **enctlv** (hex): encrypted TLV entry for this hop
|
- **encrypted_recipient_data** (hex): encrypted TLV entry for this hop
|
||||||
- **quantity** (u64, optional): the quantity ordered
|
- **quantity** (u64, optional): the quantity ordered
|
||||||
- **recurrence_counter** (u32, optional): the 0-based counter for a recurring payment
|
- **recurrence_counter** (u32, optional): the 0-based counter for a recurring payment
|
||||||
- **recurrence_start** (u32, optional): the optional start period for a recurring payment
|
- **recurrence_start** (u32, optional): the optional start period for a recurring payment
|
||||||
@@ -180,4 +180,4 @@ RESOURCES
|
|||||||
|
|
||||||
Main web site: <https://github.com/ElementsProject/lightning>
|
Main web site: <https://github.com/ElementsProject/lightning>
|
||||||
|
|
||||||
[comment]: # ( SHA256STAMP:cd4a18d07c23b6a995f8db7cac25344e340e512c786b8cf743f56ecceeb84960)
|
[comment]: # ( SHA256STAMP:d05b5fc1bf230b3bbd03e2023fb0c6bbefb700f7c3cfb43512da48dbce45f005)
|
||||||
|
|||||||
@@ -146,7 +146,7 @@
|
|||||||
"type": "object",
|
"type": "object",
|
||||||
"required": [
|
"required": [
|
||||||
"node_id",
|
"node_id",
|
||||||
"enctlv"
|
"encrypted_recipient_data"
|
||||||
],
|
],
|
||||||
"additionalProperties": false,
|
"additionalProperties": false,
|
||||||
"properties": {
|
"properties": {
|
||||||
@@ -154,7 +154,7 @@
|
|||||||
"type": "pubkey",
|
"type": "pubkey",
|
||||||
"description": "node_id of the hop"
|
"description": "node_id of the hop"
|
||||||
},
|
},
|
||||||
"enctlv": {
|
"encrypted_recipient_data": {
|
||||||
"type": "hex",
|
"type": "hex",
|
||||||
"description": "encrypted TLV entry for this hop"
|
"description": "encrypted TLV entry for this hop"
|
||||||
}
|
}
|
||||||
@@ -388,7 +388,7 @@
|
|||||||
"type": "object",
|
"type": "object",
|
||||||
"required": [
|
"required": [
|
||||||
"node_id",
|
"node_id",
|
||||||
"enctlv"
|
"encrypted_recipient_data"
|
||||||
],
|
],
|
||||||
"additionalProperties": false,
|
"additionalProperties": false,
|
||||||
"properties": {
|
"properties": {
|
||||||
@@ -396,7 +396,7 @@
|
|||||||
"type": "pubkey",
|
"type": "pubkey",
|
||||||
"description": "node_id of the hop"
|
"description": "node_id of the hop"
|
||||||
},
|
},
|
||||||
"enctlv": {
|
"encrypted_recipient_data": {
|
||||||
"type": "hex",
|
"type": "hex",
|
||||||
"description": "encrypted TLV entry for this hop"
|
"description": "encrypted TLV entry for this hop"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -520,6 +520,13 @@ static struct io_plan *onionmsg_req(struct io_conn *conn, struct daemon *daemon,
|
|||||||
return daemon_conn_read_next(conn, daemon->master);
|
return daemon_conn_read_next(conn, daemon->master);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Peer sends an onion msg. */
|
||||||
|
static u8 *handle_onion_message(struct peer *peer, const u8 *msg)
|
||||||
|
{
|
||||||
|
/* FIXME! */
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
/*~ This is where the per-peer daemons send us messages. It's either forwarded
|
/*~ This is where the per-peer daemons send us messages. It's either forwarded
|
||||||
* gossip, or a request for information. We deliberately use non-overlapping
|
* gossip, or a request for information. We deliberately use non-overlapping
|
||||||
* message types so we can distinguish them. */
|
* message types so we can distinguish them. */
|
||||||
@@ -556,6 +563,9 @@ static struct io_plan *peer_msg_in(struct io_conn *conn,
|
|||||||
case WIRE_OBS2_ONION_MESSAGE:
|
case WIRE_OBS2_ONION_MESSAGE:
|
||||||
err = handle_obs2_onion_message(peer, msg);
|
err = handle_obs2_onion_message(peer, msg);
|
||||||
goto handled_relay;
|
goto handled_relay;
|
||||||
|
case WIRE_ONION_MESSAGE:
|
||||||
|
err = handle_onion_message(peer, msg);
|
||||||
|
goto handled_relay;
|
||||||
|
|
||||||
/* These are non-gossip messages (!is_msg_for_gossipd()) */
|
/* These are non-gossip messages (!is_msg_for_gossipd()) */
|
||||||
case WIRE_WARNING:
|
case WIRE_WARNING:
|
||||||
|
|||||||
@@ -37,7 +37,8 @@ static void json_add_blindedpath(struct json_stream *stream,
|
|||||||
for (size_t i = 0; i < tal_count(path); i++) {
|
for (size_t i = 0; i < tal_count(path); i++) {
|
||||||
json_object_start(stream, NULL);
|
json_object_start(stream, NULL);
|
||||||
json_add_pubkey(stream, "id", &path[i]->node_id);
|
json_add_pubkey(stream, "id", &path[i]->node_id);
|
||||||
json_add_hex_talarr(stream, "enctlv", path[i]->enctlv);
|
json_add_hex_talarr(stream, "encrypted_recipient_data",
|
||||||
|
path[i]->encrypted_recipient_data);
|
||||||
json_object_end(stream);
|
json_object_end(stream);
|
||||||
};
|
};
|
||||||
json_array_end(stream);
|
json_array_end(stream);
|
||||||
@@ -327,7 +328,7 @@ static struct command_result *json_blindedpath(struct command *cmd,
|
|||||||
|
|
||||||
for (size_t i = 0; i < nhops - 1; i++) {
|
for (size_t i = 0; i < nhops - 1; i++) {
|
||||||
path[i] = tal(path, struct onionmsg_path);
|
path[i] = tal(path, struct onionmsg_path);
|
||||||
path[i]->enctlv = create_obs2_enctlv(path[i],
|
path[i]->encrypted_recipient_data = create_obs2_enctlv(path[i],
|
||||||
&blinding_iter,
|
&blinding_iter,
|
||||||
&ids[i],
|
&ids[i],
|
||||||
&ids[i+1],
|
&ids[i+1],
|
||||||
@@ -340,7 +341,7 @@ static struct command_result *json_blindedpath(struct command *cmd,
|
|||||||
|
|
||||||
/* FIXME: Add padding! */
|
/* FIXME: Add padding! */
|
||||||
path[nhops-1] = tal(path, struct onionmsg_path);
|
path[nhops-1] = tal(path, struct onionmsg_path);
|
||||||
path[nhops-1]->enctlv = create_obs2_final_enctlv(path[nhops-1],
|
path[nhops-1]->encrypted_recipient_data = create_obs2_final_enctlv(path[nhops-1],
|
||||||
&blinding_iter,
|
&blinding_iter,
|
||||||
&ids[nhops-1],
|
&ids[nhops-1],
|
||||||
/* FIXME: Pad? */
|
/* FIXME: Pad? */
|
||||||
|
|||||||
@@ -1392,7 +1392,7 @@ static struct command_result *param_route_hops(struct command *cmd,
|
|||||||
p_opt("direction", param_number, &direction),
|
p_opt("direction", param_number, &direction),
|
||||||
p_opt("style", param_route_hop_style, &style),
|
p_opt("style", param_route_hop_style, &style),
|
||||||
p_opt("blinding", param_pubkey, &blinding),
|
p_opt("blinding", param_pubkey, &blinding),
|
||||||
p_opt("enctlv", param_bin_from_hex, &enctlv),
|
p_opt("encrypted_recipient_data", param_bin_from_hex, &enctlv),
|
||||||
NULL))
|
NULL))
|
||||||
return command_param_failed();
|
return command_param_failed();
|
||||||
|
|
||||||
|
|||||||
@@ -1286,6 +1286,7 @@ static u8 *opening_negotiate_msg(const tal_t *ctx, struct state *state)
|
|||||||
case WIRE_ANNOUNCEMENT_SIGNATURES:
|
case WIRE_ANNOUNCEMENT_SIGNATURES:
|
||||||
case WIRE_GOSSIP_TIMESTAMP_FILTER:
|
case WIRE_GOSSIP_TIMESTAMP_FILTER:
|
||||||
case WIRE_OBS2_ONION_MESSAGE:
|
case WIRE_OBS2_ONION_MESSAGE:
|
||||||
|
case WIRE_ONION_MESSAGE:
|
||||||
case WIRE_ACCEPT_CHANNEL2:
|
case WIRE_ACCEPT_CHANNEL2:
|
||||||
case WIRE_TX_ADD_INPUT:
|
case WIRE_TX_ADD_INPUT:
|
||||||
case WIRE_TX_REMOVE_INPUT:
|
case WIRE_TX_REMOVE_INPUT:
|
||||||
@@ -1632,6 +1633,7 @@ static bool run_tx_interactive(struct state *state,
|
|||||||
case WIRE_ANNOUNCEMENT_SIGNATURES:
|
case WIRE_ANNOUNCEMENT_SIGNATURES:
|
||||||
case WIRE_GOSSIP_TIMESTAMP_FILTER:
|
case WIRE_GOSSIP_TIMESTAMP_FILTER:
|
||||||
case WIRE_OBS2_ONION_MESSAGE:
|
case WIRE_OBS2_ONION_MESSAGE:
|
||||||
|
case WIRE_ONION_MESSAGE:
|
||||||
case WIRE_TX_SIGNATURES:
|
case WIRE_TX_SIGNATURES:
|
||||||
case WIRE_OPEN_CHANNEL2:
|
case WIRE_OPEN_CHANNEL2:
|
||||||
case WIRE_ACCEPT_CHANNEL2:
|
case WIRE_ACCEPT_CHANNEL2:
|
||||||
@@ -3685,6 +3687,7 @@ static u8 *handle_peer_in(struct state *state)
|
|||||||
case WIRE_ANNOUNCEMENT_SIGNATURES:
|
case WIRE_ANNOUNCEMENT_SIGNATURES:
|
||||||
case WIRE_GOSSIP_TIMESTAMP_FILTER:
|
case WIRE_GOSSIP_TIMESTAMP_FILTER:
|
||||||
case WIRE_OBS2_ONION_MESSAGE:
|
case WIRE_OBS2_ONION_MESSAGE:
|
||||||
|
case WIRE_ONION_MESSAGE:
|
||||||
case WIRE_ACCEPT_CHANNEL2:
|
case WIRE_ACCEPT_CHANNEL2:
|
||||||
case WIRE_TX_ADD_INPUT:
|
case WIRE_TX_ADD_INPUT:
|
||||||
case WIRE_TX_REMOVE_INPUT:
|
case WIRE_TX_REMOVE_INPUT:
|
||||||
|
|||||||
@@ -64,7 +64,7 @@ send_onion_reply(struct command *cmd,
|
|||||||
json_add_pubkey(req->js, "id", &reply_path->path[i]->node_id);
|
json_add_pubkey(req->js, "id", &reply_path->path[i]->node_id);
|
||||||
|
|
||||||
omp = tlv_obs2_onionmsg_payload_new(tmpctx);
|
omp = tlv_obs2_onionmsg_payload_new(tmpctx);
|
||||||
omp->enctlv = reply_path->path[i]->enctlv;
|
omp->enctlv = reply_path->path[i]->encrypted_recipient_data;
|
||||||
|
|
||||||
/* Put payload in last hop. */
|
/* Put payload in last hop. */
|
||||||
if (i == nhops - 1) {
|
if (i == nhops - 1) {
|
||||||
@@ -227,7 +227,7 @@ static void json_add_onionmsg_path(struct json_stream *js,
|
|||||||
{
|
{
|
||||||
json_object_start(js, fieldname);
|
json_object_start(js, fieldname);
|
||||||
json_add_pubkey(js, "node_id", &path->node_id);
|
json_add_pubkey(js, "node_id", &path->node_id);
|
||||||
json_add_hex_talarr(js, "enctlv", path->enctlv);
|
json_add_hex_talarr(js, "encrypted_recipient_data", path->encrypted_recipient_data);
|
||||||
if (payinfo) {
|
if (payinfo) {
|
||||||
json_add_u32(js, "fee_base_msat", payinfo->fee_base_msat);
|
json_add_u32(js, "fee_base_msat", payinfo->fee_base_msat);
|
||||||
json_add_u32(js, "fee_proportional_millionths",
|
json_add_u32(js, "fee_proportional_millionths",
|
||||||
|
|||||||
@@ -1,13 +1,15 @@
|
|||||||
--- wire/extracted_onion_wire_csv 2020-02-25 05:52:39.612291156 +1030
|
--- wire/extracted_onion_wire_csv 2020-02-25 05:52:39.612291156 +1030
|
||||||
+++ - 2020-03-20 15:11:55.763880895 +1030
|
+++ - 2020-03-20 15:11:55.763880895 +1030
|
||||||
@@ -8,6 +8,10 @@ tlvdata,tlv_payload,short_channel_id,short_channel_id,short_channel_id,
|
--- wire/onion_exp_wire.csv.~1~ 2021-11-17 10:56:59.947630815 +1030
|
||||||
|
+++ wire/onion_exp_wire.csv 2021-11-17 10:59:39.304581244 +1030
|
||||||
|
@@ -8,6 +8,10 @@
|
||||||
tlvtype,tlv_payload,payment_data,8
|
tlvtype,tlv_payload,payment_data,8
|
||||||
tlvdata,tlv_payload,payment_data,payment_secret,byte,32
|
tlvdata,tlv_payload,payment_data,payment_secret,byte,32
|
||||||
tlvdata,tlv_payload,payment_data,total_msat,tu64,
|
tlvdata,tlv_payload,payment_data,total_msat,tu64,
|
||||||
+tlvtype,tlv_payload,enctlv,10
|
+tlvtype,tlv_payload,encrypted_recipient_data,10
|
||||||
+tlvdata,tlv_payload,enctlv,enctlv,byte,...
|
+tlvdata,tlv_payload,encrypted_recipient_data,encrypted_data,byte,...
|
||||||
+tlvtype,tlv_payload,blinding_seed,12
|
+tlvtype,tlv_payload,blinding_point,12
|
||||||
+tlvdata,tlv_payload,blinding_seed,blinding_seed,pubkey,
|
+tlvdata,tlv_payload,blinding_point,blinding,point,
|
||||||
tlvtype,obs2_onionmsg_payload,reply_path,2
|
tlvtype,obs2_onionmsg_payload,reply_path,2
|
||||||
tlvdata,obs2_onionmsg_payload,reply_path,first_node_id,point,
|
tlvdata,obs2_onionmsg_payload,reply_path,first_node_id,point,
|
||||||
tlvdata,obs2_onionmsg_payload,reply_path,blinding,point,
|
tlvdata,obs2_onionmsg_payload,reply_path,blinding,point,
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
--- peer_wire.csv 2021-08-25 12:41:02.876254003 +0930
|
--- peer_wire.csv 2021-08-25 12:41:02.876254003 +0930
|
||||||
+++ peer_wire.csv.raw 2021-08-25 13:42:31.991693809 +0930
|
+++ peer_wire.csv.raw 2021-08-25 13:42:31.991693809 +0930
|
||||||
@@ -320,3 +210,7 @@
|
@@ -320,3 +210,11 @@
|
||||||
msgdata,gossip_timestamp_filter,chain_hash,chain_hash,
|
msgdata,gossip_timestamp_filter,chain_hash,chain_hash,
|
||||||
msgdata,gossip_timestamp_filter,first_timestamp,u32,
|
msgdata,gossip_timestamp_filter,first_timestamp,u32,
|
||||||
msgdata,gossip_timestamp_filter,timestamp_range,u32,
|
msgdata,gossip_timestamp_filter,timestamp_range,u32,
|
||||||
@@ -8,3 +8,7 @@
|
|||||||
+msgdata,obs2_onion_message,blinding,point,
|
+msgdata,obs2_onion_message,blinding,point,
|
||||||
+msgdata,obs2_onion_message,len,u16,
|
+msgdata,obs2_onion_message,len,u16,
|
||||||
+msgdata,obs2_onion_message,onionmsg,byte,len
|
+msgdata,obs2_onion_message,onionmsg,byte,len
|
||||||
|
+msgtype,onion_message,513,option_onion_messages
|
||||||
|
+msgdata,onion_message,blinding,point,
|
||||||
|
+msgdata,onion_message,len,u16,
|
||||||
|
+msgdata,onion_message,onionmsg,byte,len
|
||||||
|
|||||||
@@ -28,10 +28,36 @@ tlvtype,obs2_encmsg_tlvs,next_blinding,12
|
|||||||
tlvdata,obs2_encmsg_tlvs,next_blinding,blinding,point,
|
tlvdata,obs2_encmsg_tlvs,next_blinding,blinding,point,
|
||||||
tlvtype,obs2_encmsg_tlvs,self_id,14
|
tlvtype,obs2_encmsg_tlvs,self_id,14
|
||||||
tlvdata,obs2_encmsg_tlvs,self_id,data,byte,...
|
tlvdata,obs2_encmsg_tlvs,self_id,data,byte,...
|
||||||
|
tlvtype,tlv_payload,encrypted_recipient_data,10
|
||||||
|
tlvdata,tlv_payload,encrypted_recipient_data,encrypted_data,byte,...
|
||||||
|
tlvtype,tlv_payload,blinding_point,12
|
||||||
|
tlvdata,tlv_payload,blinding_point,blinding,point,
|
||||||
|
tlvtype,encrypted_data_tlv,padding,1
|
||||||
|
tlvdata,encrypted_data_tlv,padding,padding,byte,...
|
||||||
|
tlvtype,encrypted_data_tlv,short_channel_id,2
|
||||||
|
tlvdata,encrypted_data_tlv,short_channel_id,short_channel_id,short_channel_id,
|
||||||
|
tlvtype,encrypted_data_tlv,next_node_id,4
|
||||||
|
tlvdata,encrypted_data_tlv,next_node_id,node_id,point,
|
||||||
|
tlvtype,encrypted_data_tlv,path_id,6
|
||||||
|
tlvdata,encrypted_data_tlv,path_id,data,byte,...
|
||||||
|
tlvtype,encrypted_data_tlv,next_blinding_override,8
|
||||||
|
tlvdata,encrypted_data_tlv,next_blinding_override,blinding,point,
|
||||||
|
tlvtype,onionmsg_payload,reply_path,2
|
||||||
|
tlvdata,onionmsg_payload,reply_path,first_node_id,point,
|
||||||
|
tlvdata,onionmsg_payload,reply_path,blinding,point,
|
||||||
|
tlvdata,onionmsg_payload,reply_path,path,onionmsg_path,...
|
||||||
|
tlvtype,onionmsg_payload,encrypted_data_tlv,4
|
||||||
|
tlvdata,onionmsg_payload,encrypted_data_tlv,encrypted_data_tlv,byte,...
|
||||||
|
tlvtype,onionmsg_payload,invoice_request,64
|
||||||
|
tlvdata,onionmsg_payload,invoice_request,invoice_request,byte,...
|
||||||
|
tlvtype,onionmsg_payload,invoice,66
|
||||||
|
tlvdata,onionmsg_payload,invoice,invoice,byte,...
|
||||||
|
tlvtype,onionmsg_payload,invoice_error,68
|
||||||
|
tlvdata,onionmsg_payload,invoice_error,invoice_error,byte,...
|
||||||
subtype,onionmsg_path
|
subtype,onionmsg_path
|
||||||
subtypedata,onionmsg_path,node_id,point,
|
subtypedata,onionmsg_path,node_id,point,
|
||||||
subtypedata,onionmsg_path,enclen,u16,
|
subtypedata,onionmsg_path,enclen,u16,
|
||||||
subtypedata,onionmsg_path,enctlv,byte,enclen
|
subtypedata,onionmsg_path,encrypted_recipient_data,byte,enclen
|
||||||
msgtype,invalid_realm,PERM|1
|
msgtype,invalid_realm,PERM|1
|
||||||
msgtype,temporary_node_failure,NODE|2
|
msgtype,temporary_node_failure,NODE|2
|
||||||
msgtype,permanent_node_failure,PERM|NODE|2
|
msgtype,permanent_node_failure,PERM|NODE|2
|
||||||
|
|||||||
|
@@ -34,6 +34,7 @@ static bool unknown_type(enum peer_wire t)
|
|||||||
case WIRE_REPLY_CHANNEL_RANGE:
|
case WIRE_REPLY_CHANNEL_RANGE:
|
||||||
case WIRE_GOSSIP_TIMESTAMP_FILTER:
|
case WIRE_GOSSIP_TIMESTAMP_FILTER:
|
||||||
case WIRE_OBS2_ONION_MESSAGE:
|
case WIRE_OBS2_ONION_MESSAGE:
|
||||||
|
case WIRE_ONION_MESSAGE:
|
||||||
case WIRE_TX_ADD_INPUT:
|
case WIRE_TX_ADD_INPUT:
|
||||||
case WIRE_TX_REMOVE_INPUT:
|
case WIRE_TX_REMOVE_INPUT:
|
||||||
case WIRE_TX_ADD_OUTPUT:
|
case WIRE_TX_ADD_OUTPUT:
|
||||||
@@ -63,6 +64,7 @@ bool is_msg_for_gossipd(const u8 *cursor)
|
|||||||
case WIRE_QUERY_CHANNEL_RANGE:
|
case WIRE_QUERY_CHANNEL_RANGE:
|
||||||
case WIRE_REPLY_CHANNEL_RANGE:
|
case WIRE_REPLY_CHANNEL_RANGE:
|
||||||
case WIRE_OBS2_ONION_MESSAGE:
|
case WIRE_OBS2_ONION_MESSAGE:
|
||||||
|
case WIRE_ONION_MESSAGE:
|
||||||
return true;
|
return true;
|
||||||
case WIRE_WARNING:
|
case WIRE_WARNING:
|
||||||
case WIRE_INIT:
|
case WIRE_INIT:
|
||||||
|
|||||||
@@ -332,3 +332,7 @@ msgtype,obs2_onion_message,387,option_onion_messages
|
|||||||
msgdata,obs2_onion_message,blinding,point,
|
msgdata,obs2_onion_message,blinding,point,
|
||||||
msgdata,obs2_onion_message,len,u16,
|
msgdata,obs2_onion_message,len,u16,
|
||||||
msgdata,obs2_onion_message,onionmsg,byte,len
|
msgdata,obs2_onion_message,onionmsg,byte,len
|
||||||
|
msgtype,onion_message,513,option_onion_messages
|
||||||
|
msgdata,onion_message,blinding,point,
|
||||||
|
msgdata,onion_message,len,u16,
|
||||||
|
msgdata,onion_message,onionmsg,byte,len
|
||||||
|
|||||||
|
Reference in New Issue
Block a user