-
Notifications
You must be signed in to change notification settings - Fork 995
Multi-frame onion format proposal #2363
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
3f7990d
9ef4896
4240cad
ad636d1
2546a30
abcf9a0
62f63d2
6d91de6
acccab5
75d10b5
38d29de
c5e6080
3a6ed03
6c83600
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Large diffs are not rendered by default.
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -12,17 +12,25 @@ | |
| #include <wire/gen_onion_wire.h> | ||
| #include <wire/wire.h> | ||
|
|
||
| #define SECURITY_PARAMETER 32 | ||
| #define NUM_MAX_HOPS 20 | ||
| #define PAYLOAD_SIZE 32 | ||
| #define HOP_DATA_SIZE (1 + SECURITY_PARAMETER + PAYLOAD_SIZE) | ||
| #define ROUTING_INFO_SIZE (HOP_DATA_SIZE * NUM_MAX_HOPS) | ||
| #define TOTAL_PACKET_SIZE (1 + 33 + SECURITY_PARAMETER + ROUTING_INFO_SIZE) | ||
| #define VERSION_SIZE 1 | ||
| #define REALM_SIZE 1 | ||
| #define HMAC_SIZE 32 | ||
| #define PUBKEY_SIZE 33 | ||
| #define FRAME_SIZE 65 | ||
| #define NUM_MAX_FRAMES 20 | ||
| #define ROUTING_INFO_SIZE (FRAME_SIZE * NUM_MAX_FRAMES) | ||
| #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 { | ||
| /* Cleartext information */ | ||
| u8 version; | ||
| u8 mac[SECURITY_PARAMETER]; | ||
| u8 mac[HMAC_SIZE]; | ||
| struct pubkey ephemeralkey; | ||
|
|
||
| /* Encrypted information */ | ||
|
|
@@ -34,6 +42,18 @@ enum route_next_case { | |
| ONION_FORWARD = 1, | ||
| }; | ||
|
|
||
| /** | ||
| * A sphinx payment path. | ||
| * | ||
| * This struct defines a path a payment is taking through the Lightning | ||
| * Network, including the session_key used to generate secrets, the associated | ||
| * data that'll be included in the HMACs and the payloads at each hop in the | ||
| * path. The struct is opaque since it should not be modified externally. Use | ||
| * `sphinx_path_new` or `sphinx_path_new_with_key` (testing only) to create a | ||
| * new instance. | ||
| */ | ||
| struct sphinx_path; | ||
|
|
||
| /* BOLT #4: | ||
| * | ||
| * The `hops_data` field is a structure that holds obfuscations of the | ||
|
|
@@ -69,14 +89,23 @@ struct hop_data { | |
| struct short_channel_id channel_id; | ||
| struct amount_msat amt_forward; | ||
| u32 outgoing_cltv; | ||
| /* Padding omitted, will be zeroed */ | ||
| u8 hmac[SECURITY_PARAMETER]; | ||
| }; | ||
|
|
||
| enum sphinx_payload_type { | ||
| SPHINX_V0_PAYLOAD = 0, | ||
| SPHINX_RAW_PAYLOAD = 255, | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Whenever we overload values for internal usage, I always worry about leakage (someone sends us a realm 255 onion in future). Let's make |
||
| }; | ||
|
|
||
| struct route_step { | ||
| enum route_next_case nextcase; | ||
| struct onionpacket *next; | ||
| struct hop_data hop_data; | ||
| u8 realm; | ||
| enum sphinx_payload_type type; | ||
| union { | ||
| struct hop_data v0; | ||
| } payload; | ||
| u8 *raw_payload; | ||
| u8 payload_frames; | ||
| }; | ||
|
|
||
| /** | ||
|
|
@@ -95,11 +124,7 @@ struct route_step { | |
| */ | ||
| struct onionpacket *create_onionpacket( | ||
| const tal_t * ctx, | ||
| struct pubkey path[], | ||
| struct hop_data hops_data[], | ||
| const u8 * sessionkey, | ||
| const u8 *assocdata, | ||
| const size_t assocdatalen, | ||
| struct sphinx_path *sp, | ||
| struct secret **path_secrets | ||
| ); | ||
|
|
||
|
|
@@ -197,4 +222,35 @@ struct onionreply *unwrap_onionreply(const tal_t *ctx, | |
| const struct secret *shared_secrets, | ||
| const int numhops, const u8 *reply); | ||
|
|
||
| /** | ||
| * Create a new empty sphinx_path. | ||
| * | ||
| * The sphinx_path instance can then be decorated with other functions and | ||
| * passed to `create_onionpacket` to generate the packet. | ||
| */ | ||
| struct sphinx_path *sphinx_path_new(const tal_t *ctx, | ||
| const u8 *associated_data); | ||
|
|
||
| /** | ||
| * Create a new empty sphinx_path with a given `session_key`. | ||
| * | ||
| * This MUST NOT be used outside of tests and tools as it may leak the path | ||
| * details if the `session_key` is not randomly generated. | ||
| */ | ||
| struct sphinx_path *sphinx_path_new_with_key(const tal_t *ctx, | ||
| const u8 *associated_data, | ||
| const struct secret *session_key); | ||
|
|
||
| /** | ||
| * Add a V0 (Realm 0) single frame hop to the path. | ||
| */ | ||
| void sphinx_add_v0_hop(struct sphinx_path *path, const struct pubkey *pubkey, | ||
| const struct short_channel_id *scid, struct amount_msat forward, | ||
| u32 outgoing_cltv); | ||
| /** | ||
| * Add a raw payload hop to the path. | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Maybe note it's expose for testing... |
||
| */ | ||
| void sphinx_add_raw_hop(struct sphinx_path *path, const struct pubkey *pubkey, | ||
| u8 realm, const u8 *payload); | ||
|
|
||
| #endif /* LIGHTNING_COMMON_SPHINX_H */ | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,42 @@ | ||
| { | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Would prefer to see this tested in a unit test rather than a devtool, though. |
||
| "comment": "This is a simple testcase in which we only use v0 payloads, and all hops have single frame payloads", | ||
| "generate": { | ||
| "session_key": "4141414141414141414141414141414141414141414141414141414141414141", | ||
| "associated_data": "4242424242424242424242424242424242424242424242424242424242424242", | ||
| "hops": [ | ||
| { | ||
| "realm": 0, | ||
| "pubkey": "02eec7245d6b7d2ccb30380bfbe2a3648cd7a942653f5aa340edcea1f283686619", | ||
| "payload": "0000000000000000000000000000000000000000000000000000000000000000" | ||
| }, | ||
| { | ||
| "realm": 0, | ||
| "pubkey": "0324653eac434488002cc06bbfb7f10fe18991e35f9fe4302dbea6d2353dc0ab1c", | ||
| "payload": "0101010101010101000000000000000100000001000000000000000000000000" | ||
| }, | ||
| { | ||
| "realm": 0, | ||
| "pubkey": "027f31ebc5462c1fdce1b737ecff52d37d75dea43ce11c74d25aa297165faa2007", | ||
| "payload": "0202020202020202000000000000000200000002000000000000000000000000" | ||
| }, | ||
| { | ||
| "realm": 0, | ||
| "pubkey": "032c0b7cf95324a07d05398b240174dc0c2be444d96b159aa6c7f7b1e668680991", | ||
| "payload": "0303030303030303000000000000000300000003000000000000000000000000" | ||
| }, | ||
| { | ||
| "realm": 0, | ||
| "pubkey": "02edabbd16b41c8371b92ef2f04c1185b4f03b6dcd52ba9b78d9d7c89c8f221145", | ||
| "payload": "0404040404040404000000000000000400000004000000000000000000000000" | ||
| } | ||
| ] | ||
| }, | ||
| "onion": "0002eec7245d6b7d2ccb30380bfbe2a3648cd7a942653f5aa340edcea1f283686619e5f14350c2a76fc232b5e46d421e9615471ab9e0bc887beff8c95fdb878f7b3a71da571226458c510bbadd1276f045c21c520a07d35da256ef75b4367962437b0dd10f7d61ab590531cf08000178a333a347f8b4072e216400406bdf3bf038659793a86cae5f52d32f3438527b47a1cfc54285a8afec3a4c9f3323db0c946f5d4cb2ce721caad69320c3a469a202f3e468c67eaf7a7cda226d0fd32f7b48084dca885d15222e60826d5d971f64172d98e0760154400958f00e86697aa1aa9d41bee8119a1ec866abe044a9ad635778ba61fc0776dc832b39451bd5d35072d2269cf9b040d6ba38b54ec35f81d7fc67678c3be47274f3c4cc472aff005c3469eb3bc140769ed4c7f0218ff8c6c7dd7221d189c65b3b9aaa71a01484b122846c7c7b57e02e679ea8469b70e14fe4f70fee4d87b910cf144be6fe48eef24da475c0b0bcc6565ae82cd3f4e3b24c76eaa5616c6111343306ab35c1fe5ca4a77c0e314ed7dba39d6f1e0de791719c241a939cc493bea2bae1c1e932679ea94d29084278513c77b899cc98059d06a27d171b0dbdf6bee13ddc4fc17a0c4d2827d488436b57baa167544138ca2e64a11b43ac8a06cd0c2fba2d4d900ed2d9205305e2d7383cc98dacb078133de5f6fb6bed2ef26ba92cea28aafc3b9948dd9ae5559e8bd6920b8cea462aa445ca6a95e0e7ba52961b181c79e73bd581821df2b10173727a810c92b83b5ba4a0403eb710d2ca10689a35bec6c3a708e9e92f7d78ff3c5d9989574b00c6736f84c199256e76e19e78f0c98a9d580b4a658c84fc8f2096c2fbea8f5f8c59d0fdacb3be2802ef802abbecb3aba4acaac69a0e965abd8981e9896b1f6ef9d60f7a164b371af869fd0e48073742825e9434fc54da837e120266d53302954843538ea7c6c3dbfb4ff3b2fdbe244437f2a153ccf7bdb4c92aa08102d4f3cff2ae5ef86fab4653595e6a5837fa2f3e29f27a9cde5966843fb847a4a61f1e76c281fe8bb2b0a181d096100db5a1a5ce7a910238251a43ca556712eaadea167fb4d7d75825e440f3ecd782036d7574df8bceacb397abefc5f5254d2722215c53ff54af8299aaaad642c6d72a14d27882d9bbd539e1cc7a527526ba89b8c037ad09120e98ab042d3e8652b31ae0e478516bfaf88efca9f3676ffe99d2819dcaeb7610a626695f53117665d267d3f7abebd6bbd6733f645c72c389f03855bdf1e4b8075b516569b118233a0f0971d24b83113c0b096f5216a207ca99a7cddc81c130923fe3d91e7508c9ac5f2e914ff5dccab9e558566fa14efb34ac98d878580814b94b73acbfde9072f30b881f7f0fff42d4045d1ace6322d86a97d164aa84d93a60498065cc7c20e636f5862dc81531a88c60305a2e59a985be327a6902e4bed986dbf4a0b50c217af0ea7fdf9ab37f9ea1a1aaa72f54cf40154ea9b269f1a7c09f9f43245109431a175d50e2db0132337baa0ef97eed0fcf20489da36b79a1172faccc2f7ded7c60e00694282d93359c4682135642bc81f433574aa8ef0c97b4ade7ca372c5ffc23c7eddd839bab4e0f14d6df15c9dbeab176bec8b5701cf054eb3072f6dadc98f88819042bf10c407516ee58bce33fbe3b3d86a54255e577db4598e30a135361528c101683a5fcde7e8ba53f3456254be8f45fe3a56120ae96ea3773631fcb3873aa3abd91bcff00bd38bd43697a2e789e00da6077482e7b1b1a677b5afae4c54e6cbdf7377b694eb7d7a5b913476a5be923322d3de06060fd5e819635232a2cf4f0731da13b8546d1d6d4f8d75b9fce6c2341a71b0ea6f780df54bfdb0dd5cd9855179f602f917265f21f9190c70217774a6fbaaa7d63ad64199f4664813b955cff954949076dcf", | ||
| "decode": [ | ||
| "4141414141414141414141414141414141414141414141414141414141414141", | ||
| "4242424242424242424242424242424242424242424242424242424242424242", | ||
| "4343434343434343434343434343434343434343434343434343434343434343", | ||
| "4444444444444444444444444444444444444444444444444444444444444444", | ||
| "4545454545454545454545454545454545454545454545454545454545454545" | ||
| ] | ||
| } | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
A properly marked
/* BOLT #4quote here would be illiminating and useful :)