Browse Source

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?
ppa-0.6.1
Christian Decker 8 years ago
committed by Rusty Russell
parent
commit
9820abda7c
  1. 4
      lightningd/dev_newhtlc.c
  2. 7
      lightningd/htlc_end.h
  3. 6
      lightningd/pay.c
  4. 14
      lightningd/sphinx.c
  5. 10
      lightningd/sphinx.h
  6. 6
      test/test_sphinx.c

4
lightningd/dev_newhtlc.c

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

7
lightningd/htlc_end.h

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

6
lightningd/pay.c

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

14
lightningd/sphinx.c

@ -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, &params[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);

10
lightningd/sphinx.h

@ -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 */

6
test/test_sphinx.c

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

Loading…
Cancel
Save