Skip to content

Commit 4b48481

Browse files
committed
Fat errors
1 parent b38156b commit 4b48481

File tree

2 files changed

+133
-58
lines changed

2 files changed

+133
-58
lines changed

04-onion-routing.md

Lines changed: 108 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -744,7 +744,7 @@ any further and thus need not extract an HMAC either.
744744

745745
# Returning Errors
746746

747-
The onion routing protocol includes a simple mechanism for returning encrypted
747+
The onion routing protocol includes a mechanism for returning encrypted
748748
error messages to the origin node.
749749
The returned error messages may be failures reported by any hop, including the
750750
final node.
@@ -754,58 +754,141 @@ Note that these error messages are not reliable, as they are not placed on-chain
754754
due to the possibility of hop failure.
755755

756756
Intermediate hops store the shared secret from the forward path and reuse it to
757-
obfuscate any corresponding return packet during each hop.
757+
authenticate and obfuscate any corresponding return packet during each hop.
758758
In addition, each node locally stores data regarding its own sending peer in the
759759
route, so it knows where to return-forward any eventual return packets.
760-
The node generating the error message (_erring node_) builds a return packet
760+
761+
The origin node signals to each node on the path that it supports the error
762+
format that is detailed below via a tlv record in the forward packet [TO BE
763+
SPECIFIED].
764+
765+
## Erring node
766+
767+
The node generating the error message builds a return packet
761768
consisting of the following fields:
762769

763770
1. data:
764-
* [`32*byte`:`hmac`]
765771
* [`u16`:`failure_len`]
766772
* [`failure_len*byte`:`failuremsg`]
767773
* [`u16`:`pad_len`]
768774
* [`pad_len*byte`:`pad`]
775+
* [`27*9*byte`:`payloads`]
776+
* [`378*32*byte`:`hmacs`]
777+
778+
Where `failuremsg` is defined below, and `pad` are the extra bytes used to
779+
conceal length.
780+
781+
The field `payloads` contains a per-hop payload. The erring node puts its
782+
payload at the start of this array and zeroes out the rest. The size of the
783+
field is based on the maximum number of hops in a route (27) and the payload
784+
size (9 bytes).
785+
786+
The per-hop payload consists of the following fields:
787+
1. data:
788+
* [`byte`:`payload_type`]
789+
* [`u64`:`hold_time_ms`]
790+
791+
Where `payload_type` indicates whether this hop is an intermediate hop (value 0)
792+
or the source of the error (value 1). The erring node sets this to 1. Via
793+
`hold_time_ms` each hops reports the time that it held on to the htlc. The
794+
sender can use this information to identify slow nodes and avoid them for future
795+
payment attempts.
796+
797+
The field `hmacs` contains authentication codes for each hop, with a `um` type
798+
key generated using the above process. The size of the field is based on the
799+
maximum number of hops in a route (27). Each hop adds 27 hmacs, one for each
800+
possible position that the hop could be at in the path. This is necessary
801+
because only the sender knows the position of each hop in the path. At each step
802+
back, some of the hmacs can be pruned. Pruning leads to a space requirement
803+
of (27 + 28) / 2 = 378 hmacs.
769804

770-
Where `hmac` is an HMAC authenticating the remainder of the packet, with a key
771-
generated using the above process, with key type `um`, `failuremsg` as defined
772-
below, and `pad` as the extra bytes used to conceal length.
805+
The layout of the `hmacs` field shown below. The actual format is much longer,
806+
but for readability the format is described as if the maximum route length would
807+
be just three hops.
773808

774-
The erring node then generates a new key, using the key type `ammag`.
775-
This key is then used to generate a pseudo-random stream, which is in turn
776-
applied to the packet using `XOR`.
809+
`hmac_0_2` | `hmac_0_1`| `hmac_0_0`| `hmac_1_1`| `hmac_1_0`| `hmac_2_0`
777810

778-
The obfuscation step is repeated by every hop along the return path.
779-
Upon receiving a return packet, each hop generates its `ammag`, generates the
780-
pseudo-random byte stream, and applies the result to the return packet before
781-
return-forwarding it.
811+
`hmac_x_y` is the hmac added by node `x` (counted from the node that is
812+
currently handling the failure message) assuming that this node is `y` hops
813+
away from the erring node. Each hmac covers the following data:
814+
815+
* `failure_len`, `failuremsg`, `pad_len` and `pad`.
816+
817+
* The first `y+1` payloads in `payloads`. For example, `hmac_0_2` would cover
818+
all three payloads.
819+
820+
* `y` downstream hmacs that correspond to downstream node positions relative to
821+
`x`. For example, `hmac_0_2` would cover `hmac_1_1` and `hmac_2_0`.
822+
823+
The erring node stores its 27 hmacs at the start of the array and zeroes out the
824+
rest. Strictly speaking the erring node would only need to add the single
825+
`hmac_0_0` here, because there is no downstream data to cover. However, for
826+
verification efficiency at the origin node, we still require all hmacs to be
827+
calculated. The redundant hmacs will cover portions of the zero-initialized
828+
data.
829+
830+
Finally a new key is generated, using the key type `ammag`. This key is then
831+
used to generate a pseudo-random stream, which is in turn applied to the packet
832+
using `XOR`.
833+
834+
### Requirements
835+
836+
The _erring node_:
837+
- SHOULD set `pad` such that the `failure_len` plus `pad_len` is equal to 256.
838+
- Note: this value is 118 bytes longer than the longest currently-defined
839+
message.
840+
841+
## Intermediate nodes
842+
843+
Every hop along the return path that receives a packet will in turn:
844+
845+
* Shift all existing payloads to the right and put its own payload at the
846+
start. Intermediate nodes will use payload type 0.
847+
848+
* Shift and prune all existing hmacs.
849+
850+
For the simplified three-hop layout above, the shift/prune operation would
851+
apply a transformation that results in:
852+
853+
`-` | `-` | `-` | `hmac_0'_1` | `hmac_0'_0` | `hmac_1'_0`
854+
855+
The former `hmac_x'_y` now becomes `hmac_x+1_y`. The left-most hmac for
856+
each hop is discarded.
857+
858+
* Calculate its own 27 hmacs and put them at the start of `hmacs` in the newly
859+
created space.
860+
861+
* Generate its `ammag`, generate the pseudo-random byte stream, and apply the
862+
result to obfuscate the return packet before return-forwarding it. This is
863+
identical to the obfuscation step that the erring node carries out.
864+
865+
## Origin node
782866

783867
The origin node is able to detect that it's the intended final recipient of the
784868
return message, because of course, it was the originator of the corresponding
785869
forward packet.
786870
When an origin node receives an error message matching a transfer it initiated
787871
(i.e. it cannot return-forward the error any further) it generates the `ammag`
788872
and `um` keys for each hop in the route.
789-
It then iteratively decrypts the error message, using each hop's `ammag`
790-
key, and computes the HMAC, using each hop's `um` key.
791-
The origin node can detect the sender of the error message by matching the
792-
`hmac` field with the computed HMAC.
873+
874+
It then iteratively decrypts the error message, using each hop's `ammag` key,
875+
and verifies the HMAC that corresponds to the hop's position in the path, using
876+
each hop's `um` key.
877+
878+
When the origin node encounters a payload that signals that it is a final
879+
payload, the sender of the error message has been reached and the decryption
880+
process can stop.
793881

794882
The association between the forward and return packets is handled outside of
795883
this onion routing protocol, e.g. via association with an HTLC in a payment
796884
channel.
797885

798886
### Requirements
799887

800-
The _erring node_:
801-
- SHOULD set `pad` such that the `failure_len` plus `pad_len` is equal to 256.
802-
- Note: this value is 118 bytes longer than the longest currently-defined
803-
message.
804-
805888
The _origin node_:
806889
- once the return message has been decrypted:
807890
- SHOULD store a copy of the message.
808-
- SHOULD continue decrypting, until the loop has been repeated 20 times.
891+
- SHOULD continue decrypting, until the loop has been repeated 27 times.
809892
- SHOULD use constant `ammag` and `um` keys to obfuscate the route length.
810893

811894
## Failure Messages
@@ -1156,40 +1239,7 @@ The test vectors use the following parameters:
11561239
sessionkey = 0x4141414141414141414141414141414141414141414141414141414141414141
11571240
associated data = 0x4242424242424242424242424242424242424242424242424242424242424242
11581241

1159-
The following is an in-depth trace of an example of error message creation:
1160-
1161-
# node 4 is returning an error
1162-
failure_message = 2002
1163-
# creating error message
1164-
shared_secret = b5756b9b542727dbafc6765a49488b023a725d631af688fc031217e90770c328
1165-
payload = 0002200200fe0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
1166-
um_key = 4da7f2923edce6c2d85987d1d9fa6d88023e6c3a9c3d20f07d3b10b61a78d646
1167-
raw_error_packet = 4c2fc8bc08510334b6833ad9c3e79cd1b52ae59dfe5c2a4b23ead50f09f7ee0b0002200200fe0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
1168-
# forwarding error packet
1169-
shared_secret = b5756b9b542727dbafc6765a49488b023a725d631af688fc031217e90770c328
1170-
ammag_key = 2f36bb8822e1f0d04c27b7d8bb7d7dd586e032a3218b8d414afbba6f169a4d68
1171-
stream = e9c975b07c9a374ba64fd9be3aae955e917d34d1fa33f2e90f53bbf4394713c6a8c9b16ab5f12fd45edd73c1b0c8b33002df376801ff58aaa94000bf8a86f92620f343baef38a580102395ae3abf9128d1047a0736ff9b83d456740ebbb4aeb3aa9737f18fb4afb4aa074fb26c4d702f42968888550a3bded8c05247e045b866baef0499f079fdaeef6538f31d44deafffdfd3afa2fb4ca9082b8f1c465371a9894dd8c243fb4847e004f5256b3e90e2edde4c9fb3082ddfe4d1e734cacd96ef0706bf63c9984e22dc98851bcccd1c3494351feb458c9c6af41c0044bea3c47552b1d992ae542b17a2d0bba1a096c78d169034ecb55b6e3a7263c26017f033031228833c1daefc0dedb8cf7c3e37c9c37ebfe42f3225c326e8bcfd338804c145b16e34e4
1172-
error packet for node 4: a5e6bd0c74cb347f10cce367f949098f2457d14c046fd8a22cb96efb30b0fdcda8cb9168b50f2fd45edd73c1b0c8b33002df376801ff58aaa94000bf8a86f92620f343baef38a580102395ae3abf9128d1047a0736ff9b83d456740ebbb4aeb3aa9737f18fb4afb4aa074fb26c4d702f42968888550a3bded8c05247e045b866baef0499f079fdaeef6538f31d44deafffdfd3afa2fb4ca9082b8f1c465371a9894dd8c243fb4847e004f5256b3e90e2edde4c9fb3082ddfe4d1e734cacd96ef0706bf63c9984e22dc98851bcccd1c3494351feb458c9c6af41c0044bea3c47552b1d992ae542b17a2d0bba1a096c78d169034ecb55b6e3a7263c26017f033031228833c1daefc0dedb8cf7c3e37c9c37ebfe42f3225c326e8bcfd338804c145b16e34e4
1173-
# forwarding error packet
1174-
shared_secret = 21e13c2d7cfe7e18836df50872466117a295783ab8aab0e7ecc8c725503ad02d
1175-
ammag_key = cd9ac0e09064f039fa43a31dea05f5fe5f6443d40a98be4071af4a9d704be5ad
1176-
stream = 617ca1e4624bc3f04fece3aa5a2b615110f421ec62408d16c48ea6c1b7c33fe7084a2bd9d4652fc5068e5052bf6d0acae2176018a3d8c75f37842712913900263cff92f39f3c18aa1f4b20a93e70fc429af7b2b1967ca81a761d40582daf0eb49cef66e3d6fbca0218d3022d32e994b41c884a27c28685ef1eb14603ea80a204b2f2f474b6ad5e71c6389843e3611ebeafc62390b717ca53b3670a33c517ef28a659c251d648bf4c966a4ef187113ec9848bf110816061ca4f2f68e76ceb88bd6208376460b916fb2ddeb77a65e8f88b2e71a2cbf4ea4958041d71c17d05680c051c3676fb0dc8108e5d78fb1e2c44d79a202e9d14071d536371ad47c39a05159e8d6c41d17a1e858faaaf572623aa23a38ffc73a4114cb1ab1cd7f906c6bd4e21b29694
1177-
error packet for node 3: c49a1ce81680f78f5f2000cda36268de34a3f0a0662f55b4e837c83a8773c22aa081bab1616a0011585323930fa5b9fae0c85770a2279ff59ec427ad1bbff9001c0cd1497004bd2a0f68b50704cf6d6a4bf3c8b6a0833399a24b3456961ba00736785112594f65b6b2d44d9f5ea4e49b5e1ec2af978cbe31c67114440ac51a62081df0ed46d4a3df295da0b0fe25c0115019f03f15ec86fabb4c852f83449e812f141a9395b3f70b766ebbd4ec2fae2b6955bd8f32684c15abfe8fd3a6261e52650e8807a92158d9f1463261a925e4bfba44bd20b166d532f0017185c3a6ac7957adefe45559e3072c8dc35abeba835a8cb01a71a15c736911126f27d46a36168ca5ef7dccd4e2886212602b181463e0dd30185c96348f9743a02aca8ec27c0b90dca270
1178-
forwarding error packet
1179-
shared_secret = 3a6b412548762f0dbccce5c7ae7bb8147d1caf9b5471c34120b30bc9c04891cc
1180-
ammag_key = 1bf08df8628d452141d56adfd1b25c1530d7921c23cecfc749ac03a9b694b0d3
1181-
stream = 6149f48b5a7e8f3d6f5d870b7a698e204cf64452aab4484ff1dee671fe63fd4b5f1b78ee2047dfa61e3d576b149bedaf83058f85f06a3172a3223ad6c4732d96b32955da7d2feb4140e58d86fc0f2eb5d9d1878e6f8a7f65ab9212030e8e915573ebbd7f35e1a430890be7e67c3fb4bbf2def662fa625421e7b411c29ebe81ec67b77355596b05cc155755664e59c16e21410aabe53e80404a615f44ebb31b365ca77a6e91241667b26c6cad24fb2324cf64e8b9dd6e2ce65f1f098cfd1ef41ba2d4c7def0ff165a0e7c84e7597c40e3dffe97d417c144545a0e38ee33ebaae12cc0c14650e453d46bfc48c0514f354773435ee89b7b2810606eb73262c77a1d67f3633705178d79a1078c3a01b5fadc9651feb63603d19decd3a00c1f69af2dab259593
1182-
error packet for node 2: a5d3e8634cfe78b2307d87c6d90be6fe7855b4f2cc9b1dfb19e92e4b79103f61ff9ac25f412ddfb7466e74f81b3e545563cdd8f5524dae873de61d7bdfccd496af2584930d2b566b4f8d3881f8c043df92224f38cf094cfc09d92655989531524593ec6d6caec1863bdfaa79229b5020acc034cd6deeea1021c50586947b9b8e6faa83b81fbfa6133c0af5d6b07c017f7158fa94f0d206baf12dda6b68f785b773b360fd0497e16cc402d779c8d48d0fa6315536ef0660f3f4e1865f5b38ea49c7da4fd959de4e83ff3ab686f059a45c65ba2af4a6a79166aa0f496bf04d06987b6d2ea205bdb0d347718b9aeff5b61dfff344993a275b79717cd815b6ad4c0beb568c4ac9c36ff1c315ec1119a1993c4b61e6eaa0375e0aaf738ac691abd3263bf937e3
1183-
# forwarding error packet
1184-
shared_secret = a6519e98832a0b179f62123b3567c106db99ee37bef036e783263602f3488fae
1185-
ammag_key = 59ee5867c5c151daa31e36ee42530f429c433836286e63744f2020b980302564
1186-
stream = 0f10c86f05968dd91188b998ee45dcddfbf89fe9a99aa6375c42ed5520a257e048456fe417c15219ce39d921555956ae2ff795177c63c819233f3bcb9b8b28e5ac6e33a3f9b87ca62dff43f4cc4a2755830a3b7e98c326b278e2bd31f4a9973ee99121c62873f5bfb2d159d3d48c5851e3b341f9f6634f51939188c3b9ff45feeb11160bb39ce3332168b8e744a92107db575ace7866e4b8f390f1edc4acd726ed106555900a0832575c3a7ad11bb1fe388ff32b99bcf2a0d0767a83cf293a220a983ad014d404bfa20022d8b369fe06f7ecc9c74751dcda0ff39d8bca74bf9956745ba4e5d299e0da8f68a9f660040beac03e795a046640cf8271307a8b64780b0588422f5a60ed7e36d60417562938b400802dac5f87f267204b6d5bcfd8a05b221ec2
1187-
error packet for node 1: aac3200c4968f56b21f53e5e374e3a2383ad2b1b6501bbcc45abc31e59b26881b7dfadbb56ec8dae8857add94e6702fb4c3a4de22e2e669e1ed926b04447fc73034bb730f4932acd62727b75348a648a1128744657ca6a4e713b9b646c3ca66cac02cdab44dd3439890ef3aaf61708714f7375349b8da541b2548d452d84de7084bb95b3ac2345201d624d31f4d52078aa0fa05a88b4e20202bd2b86ac5b52919ea305a8949de95e935eed0319cf3cf19ebea61d76ba92532497fcdc9411d06bcd4275094d0a4a3c5d3a945e43305a5a9256e333e1f64dbca5fcd4e03a39b9012d197506e06f29339dfee3331995b21615337ae060233d39befea925cc262873e0530408e6990f1cbd233a150ef7b004ff6166c70c68d9f8c853c1abca640b8660db2921
1188-
# forwarding error packet
1189-
shared_secret = 53eb63ea8a3fec3b3cd433b85cd62a4b145e1dda09391b348c4e1cd36a03ea66
1190-
ammag_key = 3761ba4d3e726d8abb16cba5950ee976b84937b61b7ad09e741724d7dee12eb5
1191-
stream = 3699fd352a948a05f604763c0bca2968d5eaca2b0118602e52e59121f050936c8dd90c24df7dc8cf8f1665e39a6c75e9e2c0900ea245c9ed3b0008148e0ae18bbfaea0c711d67eade980c6f5452e91a06b070bbde68b5494a92575c114660fb53cf04bf686e67ffa4a0f5ae41a59a39a8515cb686db553d25e71e7a97cc2febcac55df2711b6209c502b2f8827b13d3ad2f491c45a0cafe7b4d8d8810e805dee25d676ce92e0619b9c206f922132d806138713a8f69589c18c3fdc5acee41c1234b17ecab96b8c56a46787bba2c062468a13919afc18513835b472a79b2c35f9a91f38eb3b9e998b1000cc4a0dbd62ac1a5cc8102e373526d7e8f3c3a1b4bfb2f8a3947fe350cb89f73aa1bb054edfa9895c0fc971c2b5056dc8665902b51fced6dff80c
1192-
error packet for node 0: 9c5add3963fc7f6ed7f148623c84134b5647e1306419dbe2174e523fa9e2fbed3a06a19f899145610741c83ad40b7712aefaddec8c6baf7325d92ea4ca4d1df8bce517f7e54554608bf2bd8071a4f52a7a2f7ffbb1413edad81eeea5785aa9d990f2865dc23b4bc3c301a94eec4eabebca66be5cf638f693ec256aec514620cc28ee4a94bd9565bc4d4962b9d3641d4278fb319ed2b84de5b665f307a2db0f7fbb757366067d88c50f7e829138fde4f78d39b5b5802f1b92a8a820865af5cc79f9f30bc3f461c66af95d13e5e1f0381c184572a91dee1c849048a647a1158cf884064deddbf1b0b88dfe2f791428d0ba0f6fb2f04e14081f69165ae66d9297c118f0907705c9c4954a199bae0bb96fad763d690e7daa6cfda59ba7f2c8d11448b604d12d
1242+
The expected encrypted failure message produced at each hop can be found in this [json](fat_error.json) file.
11931243

11941244
# References
11951245

0 commit comments

Comments
 (0)