sphinx: Cleanup sphinx onion construction, remove realm

The realm has lost significance, so let's unify this into the type.

Signed-off-by: Christian Decker <decker.christian@gmail.com>
This commit is contained in:
Christian Decker 2019-05-29 17:20:28 +02:00 committed by Rusty Russell
parent 660921a9dd
commit c752c3318d
3 changed files with 22 additions and 40 deletions

View file

@ -45,7 +45,7 @@ struct keyset {
* generation is payload agnostic. */ * generation is payload agnostic. */
struct sphinx_hop { struct sphinx_hop {
struct pubkey pubkey; struct pubkey pubkey;
u8 realm; enum sphinx_payload_type type;
const u8 *payload; const u8 *payload;
u8 hmac[HMAC_SIZE]; u8 hmac[HMAC_SIZE];
}; };
@ -101,7 +101,7 @@ static size_t sphinx_hop_size(const struct sphinx_hop *hop)
/* Backwards compatibility: realm 0 is the legacy hop_data format and /* Backwards compatibility: realm 0 is the legacy hop_data format and
* always has 65 bytes in size */ * always has 65 bytes in size */
if (hop->realm == 0x00) if (hop->type == SPHINX_V0_PAYLOAD)
return 65; return 65;
/* Since this uses the bigsize serialization format for variable /* Since this uses the bigsize serialization format for variable
@ -126,11 +126,11 @@ static size_t sphinx_path_payloads_size(const struct sphinx_path *path)
} }
void sphinx_add_raw_hop(struct sphinx_path *path, const struct pubkey *pubkey, void sphinx_add_raw_hop(struct sphinx_path *path, const struct pubkey *pubkey,
u8 realm, const u8 *payload) enum sphinx_payload_type type, const u8 *payload)
{ {
struct sphinx_hop sp; struct sphinx_hop sp;
sp.payload = payload; sp.payload = payload;
sp.realm = realm; sp.type = type;
sp.pubkey = *pubkey; sp.pubkey = *pubkey;
tal_arr_expand(&path->hops, sp); tal_arr_expand(&path->hops, sp);
assert(sphinx_path_payloads_size(path) <= ROUTING_INFO_SIZE); assert(sphinx_path_payloads_size(path) <= ROUTING_INFO_SIZE);
@ -446,12 +446,12 @@ static bool sphinx_write_frame(u8 *dest, const struct sphinx_hop *hop)
int pos = 0; int pos = 0;
#if !EXPERIMENTAL_FEATURES #if !EXPERIMENTAL_FEATURES
if (hop->realm != 0x00) if (hop->type != SPHINX_V0_PAYLOAD)
return false; return false;
#endif #endif
/* Backwards compatibility for the legacy hop_data format. */ /* Backwards compatibility for the legacy hop_data format. */
if (hop->realm == 0x00) if (hop->type == SPHINX_V0_PAYLOAD)
dest[pos++] = 0x00; dest[pos++] = 0x00;
else else
pos += varint_put(dest+pos, raw_size); pos += varint_put(dest+pos, raw_size);
@ -483,10 +483,11 @@ static void sphinx_parse_payload(struct route_step *step, const u8 *src)
vsize = 1; vsize = 1;
raw_size = 32; raw_size = 32;
hop_size = FRAME_SIZE; hop_size = FRAME_SIZE;
step->realm = src[0]; step->type = SPHINX_V0_PAYLOAD;
} else { } else {
vsize = varint_get(src, 3, &raw_size); vsize = varint_get(src, 3, &raw_size);
hop_size = raw_size + vsize + HMAC_SIZE; hop_size = raw_size + vsize + HMAC_SIZE;
step->type = SPHINX_TLV_PAYLOAD;
} }
/* Copy common pieces over */ /* Copy common pieces over */
@ -495,12 +496,8 @@ static void sphinx_parse_payload(struct route_step *step, const u8 *src)
/* And now try to parse whatever the payload contains so we can use it /* And now try to parse whatever the payload contains so we can use it
* later. */ * later. */
if (step->realm == SPHINX_V0_PAYLOAD) { if (step->type == SPHINX_V0_PAYLOAD)
step->type = SPHINX_V0_PAYLOAD;
deserialize_hop_data(&step->payload.v0, src); deserialize_hop_data(&step->payload.v0, src);
} else {
step->type = SPHINX_RAW_PAYLOAD;
}
} }
struct onionpacket *create_onionpacket( struct onionpacket *create_onionpacket(

View file

@ -17,16 +17,9 @@
#define HMAC_SIZE 32 #define HMAC_SIZE 32
#define PUBKEY_SIZE 33 #define PUBKEY_SIZE 33
#define FRAME_SIZE 65 #define FRAME_SIZE 65
#define NUM_MAX_FRAMES 20 #define ROUTING_INFO_SIZE 1300
#define ROUTING_INFO_SIZE (FRAME_SIZE * NUM_MAX_FRAMES)
#define TOTAL_PACKET_SIZE (VERSION_SIZE + PUBKEY_SIZE + HMAC_SIZE + ROUTING_INFO_SIZE) #define TOTAL_PACKET_SIZE (VERSION_SIZE + PUBKEY_SIZE + HMAC_SIZE + ROUTING_INFO_SIZE)
#if EXPERIMENTAL_FEATURES
#define MAX_FRAMES_PER_HOP (1 << 4)
#else
#define MAX_FRAMES_PER_HOP 1
#endif
struct onionpacket { struct onionpacket {
/* Cleartext information */ /* Cleartext information */
u8 version; u8 version;
@ -93,6 +86,7 @@ struct hop_data {
enum sphinx_payload_type { enum sphinx_payload_type {
SPHINX_V0_PAYLOAD = 0, SPHINX_V0_PAYLOAD = 0,
SPHINX_TLV_PAYLOAD = 1,
SPHINX_INVALID_PAYLOAD = 254, SPHINX_INVALID_PAYLOAD = 254,
SPHINX_RAW_PAYLOAD = 255, SPHINX_RAW_PAYLOAD = 255,
}; };
@ -100,13 +94,11 @@ enum sphinx_payload_type {
struct route_step { struct route_step {
enum route_next_case nextcase; enum route_next_case nextcase;
struct onionpacket *next; struct onionpacket *next;
u8 realm;
enum sphinx_payload_type type; enum sphinx_payload_type type;
union { union {
struct hop_data v0; struct hop_data v0;
} payload; } payload;
u8 *raw_payload; u8 *raw_payload;
u8 payload_frames;
}; };
/** /**
@ -252,6 +244,6 @@ void sphinx_add_v0_hop(struct sphinx_path *path, const struct pubkey *pubkey,
* Add a raw payload hop to the path. * Add a raw payload hop to the path.
*/ */
void sphinx_add_raw_hop(struct sphinx_path *path, const struct pubkey *pubkey, void sphinx_add_raw_hop(struct sphinx_path *path, const struct pubkey *pubkey,
u8 realm, const u8 *payload); enum sphinx_payload_type type, const u8 *payload);
#endif /* LIGHTNING_COMMON_SPHINX_H */ #endif /* LIGHTNING_COMMON_SPHINX_H */

View file

@ -201,13 +201,13 @@ static void runtest(const char *filename)
bool valid; bool valid;
char *buffer = grab_file(ctx, filename); char *buffer = grab_file(ctx, filename);
const jsmntok_t *toks, *session_key_tok, *associated_data_tok, *gentok, const jsmntok_t *toks, *session_key_tok, *associated_data_tok, *gentok,
*hopstok, *hop, *payloadtok, *pubkeytok, *realmtok, *oniontok, *decodetok; *hopstok, *hop, *payloadtok, *pubkeytok, *typetok, *oniontok, *decodetok;
const u8 *associated_data, *session_key_raw, *payload, *serialized, *onion; const u8 *associated_data, *session_key_raw, *payload, *serialized, *onion;
struct secret session_key, *shared_secrets; struct secret session_key, *shared_secrets;
struct pubkey pubkey; struct pubkey pubkey;
struct sphinx_path *path; struct sphinx_path *path;
size_t i; size_t i;
int realm; enum sphinx_payload_type type;
struct onionpacket *res; struct onionpacket *res;
struct route_step *step; struct route_step *step;
char *hexprivkey; char *hexprivkey;
@ -232,12 +232,16 @@ static void runtest(const char *filename)
hopstok = json_get_member(buffer, gentok, "hops"); hopstok = json_get_member(buffer, gentok, "hops");
json_for_each_arr(i, hop, hopstok) { json_for_each_arr(i, hop, hopstok) {
payloadtok = json_get_member(buffer, hop, "payload"); payloadtok = json_get_member(buffer, hop, "payload");
realmtok = json_get_member(buffer, hop, "realm"); typetok = json_get_member(buffer, hop, "type");
pubkeytok = json_get_member(buffer, hop, "pubkey"); pubkeytok = json_get_member(buffer, hop, "pubkey");
payload = json_tok_bin_from_hex(ctx, buffer, payloadtok); payload = json_tok_bin_from_hex(ctx, buffer, payloadtok);
json_to_pubkey(buffer, pubkeytok, &pubkey); json_to_pubkey(buffer, pubkeytok, &pubkey);
json_to_int(buffer, realmtok, &realm); if (!typetok || json_tok_streq(buffer, typetok, "legacy")) {
sphinx_add_raw_hop(path, &pubkey, realm, payload); type = SPHINX_V0_PAYLOAD;
} else {
type = SPHINX_RAW_PAYLOAD;
}
sphinx_add_raw_hop(path, &pubkey, type, payload);
} }
res = create_onionpacket(ctx, path, &shared_secrets); res = create_onionpacket(ctx, path, &shared_secrets);
serialized = serialize_onionpacket(ctx, res); serialized = serialize_onionpacket(ctx, res);
@ -259,17 +263,6 @@ static void runtest(const char *filename)
} }
printf("Generated onion: %s\n", tal_hex(ctx, serialized)); printf("Generated onion: %s\n", tal_hex(ctx, serialized));
hopstok = json_get_member(buffer, gentok, "hops");
json_for_each_arr(i, hop, hopstok) {
payloadtok = json_get_member(buffer, hop, "payload");
realmtok = json_get_member(buffer, hop, "realm");
pubkeytok = json_get_member(buffer, hop, "pubkey");
payload = json_tok_bin_from_hex(ctx, buffer, payloadtok);
json_to_pubkey(buffer, pubkeytok, &pubkey);
json_to_int(buffer, realmtok, &realm);
sphinx_add_raw_hop(path, &pubkey, realm, payload);
}
decodetok = json_get_member(buffer, toks, "decode"); decodetok = json_get_member(buffer, toks, "decode");
json_for_each_arr(i, hop, decodetok) { json_for_each_arr(i, hop, decodetok) {
@ -279,7 +272,7 @@ static void runtest(const char *filename)
serialized = serialize_onionpacket(ctx, step->next); serialized = serialize_onionpacket(ctx, step->next);
if (!serialized) if (!serialized)
errx(1, "Error serializing message."); errx(1, "Error serializing message.");
printf(" Realm: %d\n", step->realm); printf(" Type: %d\n", step->type);
printf(" Payload: %s\n", tal_hex(ctx, step->raw_payload)); printf(" Payload: %s\n", tal_hex(ctx, step->raw_payload));
printf(" Next onion: %s\n", tal_hex(ctx, serialized)); printf(" Next onion: %s\n", tal_hex(ctx, serialized));
printf(" Next HMAC: %s\n", tal_hexstr(ctx, step->next->mac, HMAC_SIZE)); printf(" Next HMAC: %s\n", tal_hexstr(ctx, step->next->mac, HMAC_SIZE));