mirror of
https://github.com/aljazceru/lightning.git
synced 2026-01-07 16:14:26 +01:00
sphinx: Store shared secrets on the origin node
We could recompute them once we receive a reply and need to decrypt it, but why go through the trouble when we can just store them?
This commit is contained in:
committed by
Rusty Russell
parent
79f848145c
commit
9820abda7c
@@ -62,6 +62,7 @@ static void json_dev_newhtlc(struct command *cmd,
|
||||
u8 *onion;
|
||||
struct htlc_end *hend;
|
||||
struct pubkey *path = tal_arrz(cmd, struct pubkey, 1);
|
||||
struct sha256 *shared_secrets;
|
||||
|
||||
if (!json_get_params(buffer, params,
|
||||
"peerid", &peeridtok,
|
||||
@@ -126,7 +127,7 @@ static void json_dev_newhtlc(struct command *cmd,
|
||||
path[0] = *peer->id;
|
||||
randombytes_buf(&sessionkey, sizeof(sessionkey));
|
||||
packet = create_onionpacket(cmd, path, hopsdata, sessionkey, rhash.u.u8,
|
||||
sizeof(rhash));
|
||||
sizeof(rhash), &shared_secrets);
|
||||
onion = serialize_onionpacket(cmd, packet);
|
||||
|
||||
log_debug(peer->log, "JSON command to add new HTLC");
|
||||
@@ -137,6 +138,7 @@ static void json_dev_newhtlc(struct command *cmd,
|
||||
hend->msatoshis = msatoshi;
|
||||
hend->other_end = NULL;
|
||||
hend->pay_command = (void *)cmd;
|
||||
hend->path_secrets = tal_steal(hend, shared_secrets);
|
||||
|
||||
/* FIXME: If subdaemon dies? */
|
||||
msg = towire_channel_offer_htlc(cmd, msatoshi, expiry, &rhash, onion);
|
||||
|
||||
@@ -28,7 +28,14 @@ struct htlc_end {
|
||||
u32 outgoing_cltv_value;
|
||||
u32 cltv_expiry;
|
||||
struct sha256 payment_hash;
|
||||
|
||||
/* If we are forwarding, remember the shared secret for an
|
||||
* eventual reply */
|
||||
struct sha256 shared_secret;
|
||||
|
||||
/* If we are the origin, remember all shared secrets, so we
|
||||
* can unwrap an eventual reply */
|
||||
struct sha256 *path_secrets;
|
||||
};
|
||||
|
||||
static inline const struct htlc_end *keyof_htlc_end(const struct htlc_end *e)
|
||||
|
||||
@@ -163,6 +163,7 @@ static void json_sendpay(struct command *cmd,
|
||||
u64 amount, lastamount;
|
||||
struct onionpacket *packet;
|
||||
u8 *msg;
|
||||
struct sha256 *path_secrets;
|
||||
|
||||
if (!json_get_params(buffer, params,
|
||||
"route", &routetok,
|
||||
@@ -321,8 +322,8 @@ static void json_sendpay(struct command *cmd,
|
||||
randombytes_buf(&sessionkey, sizeof(sessionkey));
|
||||
|
||||
/* Onion will carry us from first peer onwards. */
|
||||
packet = create_onionpacket(cmd, ids, hop_data, sessionkey,
|
||||
rhash.u.u8, sizeof(struct sha256));
|
||||
packet = create_onionpacket(cmd, ids, hop_data, sessionkey, rhash.u.u8,
|
||||
sizeof(struct sha256), &path_secrets);
|
||||
onion = serialize_onionpacket(cmd, packet);
|
||||
|
||||
if (pc)
|
||||
@@ -344,6 +345,7 @@ static void json_sendpay(struct command *cmd,
|
||||
pc->out->msatoshis = amount;
|
||||
pc->out->other_end = NULL;
|
||||
pc->out->pay_command = pc;
|
||||
pc->out->path_secrets = tal_steal(pc->out, path_secrets);
|
||||
|
||||
log_info(ld->log, "Sending %"PRIu64" over %zu hops to deliver %"PRIu64,
|
||||
amount, n_hops, lastamount);
|
||||
|
||||
@@ -362,7 +362,8 @@ struct onionpacket *create_onionpacket(
|
||||
struct hop_data hops_data[],
|
||||
const u8 *sessionkey,
|
||||
const u8 *assocdata,
|
||||
const size_t assocdatalen
|
||||
const size_t assocdatalen,
|
||||
struct sha256 **path_secrets
|
||||
)
|
||||
{
|
||||
struct onionpacket *packet = talz(ctx, struct onionpacket);
|
||||
@@ -403,6 +404,11 @@ struct onionpacket *create_onionpacket(
|
||||
}
|
||||
memcpy(packet->mac, nexthmac, sizeof(nexthmac));
|
||||
memcpy(&packet->ephemeralkey, ¶ms[0].ephemeralkey, sizeof(secp256k1_pubkey));
|
||||
|
||||
*path_secrets = tal_arr(ctx, struct sha256, num_hops);
|
||||
for (i=0; i<num_hops; i++) {
|
||||
create_shared_secret((*path_secrets)[i].u.u8, &path[i].pubkey, sessionkey);
|
||||
}
|
||||
return packet;
|
||||
}
|
||||
|
||||
@@ -462,7 +468,7 @@ struct route_step *process_onionpacket(
|
||||
return step;
|
||||
}
|
||||
|
||||
u8 *create_onionreply(tal_t *ctx, const u8 *shared_secret,
|
||||
u8 *create_onionreply(const tal_t *ctx, const u8 *shared_secret,
|
||||
const u8 *failure_msg)
|
||||
{
|
||||
size_t msglen = tal_len(failure_msg);
|
||||
@@ -487,7 +493,7 @@ u8 *create_onionreply(tal_t *ctx, const u8 *shared_secret,
|
||||
return reply;
|
||||
}
|
||||
|
||||
u8 *wrap_onionreply(tal_t *ctx, const u8 *shared_secret, const u8 *reply)
|
||||
u8 *wrap_onionreply(const tal_t *ctx, const u8 *shared_secret, const u8 *reply)
|
||||
{
|
||||
u8 key[KEY_LEN];
|
||||
size_t streamlen = tal_len(reply);
|
||||
@@ -499,7 +505,7 @@ u8 *wrap_onionreply(tal_t *ctx, const u8 *shared_secret, const u8 *reply)
|
||||
return result;
|
||||
}
|
||||
|
||||
struct onionreply *unwrap_onionreply(tal_t *ctx, u8 **shared_secrets,
|
||||
struct onionreply *unwrap_onionreply(const tal_t *ctx, u8 **shared_secrets,
|
||||
const int numhops, const u8 *reply)
|
||||
{
|
||||
tal_t *tmpctx = tal_tmpctx(ctx);
|
||||
|
||||
@@ -78,6 +78,7 @@ struct route_step {
|
||||
* @sessionkey: 32 byte random session key to derive secrets from
|
||||
* @assocdata: associated data to commit to in HMACs
|
||||
* @assocdatalen: length of the assocdata
|
||||
* @path_secrets: (out) shared secrets generated for the entire path
|
||||
*/
|
||||
struct onionpacket *create_onionpacket(
|
||||
const tal_t * ctx,
|
||||
@@ -85,7 +86,8 @@ struct onionpacket *create_onionpacket(
|
||||
struct hop_data hops_data[],
|
||||
const u8 * sessionkey,
|
||||
const u8 *assocdata,
|
||||
const size_t assocdatalen
|
||||
const size_t assocdatalen,
|
||||
struct sha256 **path_secrets
|
||||
);
|
||||
|
||||
/**
|
||||
@@ -160,7 +162,7 @@ struct onionreply {
|
||||
* HMAC
|
||||
* @failure_msg: message (must support tal_len)
|
||||
*/
|
||||
u8 *create_onionreply(tal_t *ctx, const u8 *shared_secret, const u8 *failure_msg);
|
||||
u8 *create_onionreply(const tal_t *ctx, const u8 *shared_secret, const u8 *failure_msg);
|
||||
|
||||
/**
|
||||
* wrap_onionreply - Add another encryption layer to the reply.
|
||||
@@ -170,7 +172,7 @@ u8 *create_onionreply(tal_t *ctx, const u8 *shared_secret, const u8 *failure_msg
|
||||
* encryption.
|
||||
* @reply: the reply to wrap
|
||||
*/
|
||||
u8 *wrap_onionreply(tal_t *ctx, const u8 *shared_secret, const u8 *reply);
|
||||
u8 *wrap_onionreply(const tal_t *ctx, const u8 *shared_secret, const u8 *reply);
|
||||
|
||||
/**
|
||||
* unwrap_onionreply - Remove layers, check integrity and parse reply
|
||||
@@ -180,7 +182,7 @@ u8 *wrap_onionreply(tal_t *ctx, const u8 *shared_secret, const u8 *reply);
|
||||
* @numhops: path length and number of shared_secrets provided
|
||||
* @reply: the incoming reply
|
||||
*/
|
||||
struct onionreply *unwrap_onionreply(tal_t *ctx, u8 **shared_secrets,
|
||||
struct onionreply *unwrap_onionreply(const tal_t *ctx, u8 **shared_secrets,
|
||||
const int numhops, const u8 *reply);
|
||||
|
||||
#endif /* LIGHTNING_DAEMON_SPHINX_H */
|
||||
|
||||
@@ -140,7 +140,8 @@ int main(int argc, char **argv)
|
||||
u8 privkeys[argc - 1][32];
|
||||
u8 sessionkey[32];
|
||||
struct hop_data hops_data[num_hops];
|
||||
|
||||
struct sha256 *shared_secrets;
|
||||
|
||||
memset(&sessionkey, 'A', sizeof(sessionkey));
|
||||
|
||||
int i;
|
||||
@@ -163,7 +164,8 @@ int main(int argc, char **argv)
|
||||
hops_data,
|
||||
sessionkey,
|
||||
assocdata,
|
||||
sizeof(assocdata));
|
||||
sizeof(assocdata),
|
||||
&shared_secrets);
|
||||
|
||||
u8 *serialized = serialize_onionpacket(ctx, res);
|
||||
if (!serialized)
|
||||
|
||||
Reference in New Issue
Block a user