mirror of
https://github.com/ElementsProject/lightning.git
synced 2025-03-03 10:46:58 +01:00
sphinx: Add functions to decompress
Also implements a way to decompress an onion using the devtools/onion tool Changelog-Added: devtools: The `onion` tool can now generate, compress and decompress onions for rendez-vous routing
This commit is contained in:
parent
4724d55e80
commit
49a3321d7e
3 changed files with 64 additions and 0 deletions
|
@ -785,3 +785,27 @@ u8 *unwrap_onionreply(const tal_t *ctx,
|
|||
return tal_free(final);
|
||||
return final;
|
||||
}
|
||||
|
||||
u8 *sphinx_decompress(const tal_t *ctx, const u8 *compressed,
|
||||
struct secret *shared_secret)
|
||||
{
|
||||
size_t compressedlen = tal_bytelen(compressed);
|
||||
size_t prefill_size = TOTAL_PACKET_SIZE - compressedlen;
|
||||
u8 *dst;
|
||||
int p = 0;
|
||||
|
||||
assert(prefill_size >= 0);
|
||||
assert(compressedlen >= VERSION_SIZE + PUBKEY_SIZE + HMAC_SIZE);
|
||||
dst = tal_arrz(ctx, u8, TOTAL_PACKET_SIZE);
|
||||
write_buffer(
|
||||
dst, compressed,
|
||||
VERSION_SIZE + PUBKEY_SIZE + ROUTING_INFO_SIZE - prefill_size, &p);
|
||||
|
||||
/* We can just XOR here since we initialized the array with zeros. */
|
||||
sphinx_prefill_stream_xor(dst + p, prefill_size, shared_secret);
|
||||
p += prefill_size;
|
||||
|
||||
write_buffer(dst, compressed + compressedlen - HMAC_SIZE, HMAC_SIZE,
|
||||
&p);
|
||||
return dst;
|
||||
}
|
||||
|
|
|
@ -246,6 +246,13 @@ u8 *serialize_compressed_onion(const tal_t *ctx,
|
|||
bool sphinx_path_set_rendezvous(struct sphinx_path *sp,
|
||||
const struct node_id *rendezvous_id);
|
||||
|
||||
/**
|
||||
* Given a compressed onion expand it by re-generating the prefiller and
|
||||
* inserting it in the appropriate place.
|
||||
*/
|
||||
u8 *sphinx_decompress(const tal_t *ctx, const u8 *compressed,
|
||||
struct secret *shared_secret);
|
||||
|
||||
#if DEVELOPER
|
||||
/* Override to force us to reject valid onion packets */
|
||||
extern bool dev_fail_process_onionpacket;
|
||||
|
|
|
@ -290,6 +290,30 @@ static void runtest(const char *filename)
|
|||
tal_free(ctx);
|
||||
}
|
||||
|
||||
static void decompress(char *hexprivkey, char *hexonion)
|
||||
{
|
||||
struct privkey rendezvous_key;
|
||||
size_t onionlen = hex_data_size(strlen(hexonion));
|
||||
u8 *compressed, *decompressed;
|
||||
struct pubkey ephkey;
|
||||
struct secret shared_secret;
|
||||
|
||||
if (!hex_decode(hexprivkey, strlen(hexprivkey), &rendezvous_key, sizeof(rendezvous_key)))
|
||||
errx(1, "Invalid private key hex '%s'", hexprivkey);
|
||||
|
||||
compressed = tal_arr(NULL, u8, onionlen);
|
||||
if (!hex_decode(hexonion, strlen(hexonion), compressed, onionlen))
|
||||
errx(1, "Invalid onion hex '%s'", hexonion);
|
||||
|
||||
if (onionlen < HMAC_SIZE + 1 + PUBKEY_SIZE)
|
||||
errx(1, "Onion is too short to contain the version, ephemeral key and HMAC");
|
||||
|
||||
pubkey_from_der(compressed + 1, PUBKEY_SIZE, &ephkey);
|
||||
|
||||
decompressed = sphinx_decompress(NULL, compressed, &shared_secret);
|
||||
printf("Decompressed Onion: %s\n", tal_hex(NULL, decompressed));
|
||||
}
|
||||
|
||||
/* Tal wrappers for opt. */
|
||||
static void *opt_allocfn(size_t size)
|
||||
{
|
||||
|
@ -353,6 +377,15 @@ int main(int argc, char **argv)
|
|||
do_generate(argc, argv, assocdata, NULL);
|
||||
else
|
||||
do_generate(argc, argv, assocdata, &rendezvous_id);
|
||||
} else if (streq(method, "decompress")) {
|
||||
if (argc != 4) {
|
||||
errx(2,
|
||||
"'%s decompress' requires a private key and a "
|
||||
"compressed onion",
|
||||
argv[0]);
|
||||
}
|
||||
|
||||
decompress(argv[2], argv[3]);
|
||||
} else if (streq(method, "decode")) {
|
||||
do_decode(argc, argv, assocdata);
|
||||
} else {
|
||||
|
|
Loading…
Add table
Reference in a new issue