Skip to content

Commit

Permalink
WIP: Support different initial packet filler
Browse files Browse the repository at this point in the history
All-zero initial packets should only be used for generating
test vectors because of possible privacy leak.
"Create packet (reference test vector)" testcase updated to
new testcases provided by the RFC repo to meet this change
of spec.

See more:
lightning/bolts@8dd0b75
https://github.com/lightningnetwork/lightning-rfc/blob/master/04-onion-routing.md#packet-construction
  • Loading branch information
aarani committed Jun 11, 2021
1 parent b2f17bc commit 08b6971
Show file tree
Hide file tree
Showing 2 changed files with 28 additions and 14 deletions.
18 changes: 16 additions & 2 deletions src/DotNetLightning.Core/Crypto/Sphinx.fs
Original file line number Diff line number Diff line change
Expand Up @@ -194,22 +194,36 @@ module Sphinx =
HMAC = nextHmac }
nextPacket

module PacketFiller =
// DeterministicPacketFiller is a packet filler that generates a deterministic
// set of filler bytes by using chacha20 with a key derived from the session
// key.
let DeterministicPacketFiller (sessionKey: Key) =
generateStream(generateKey("pad",sessionKey.ToBytes()), 1300)

// BlankPacketFiller is a packet filler that doesn't attempt to fill out the
// packet at all. It should ONLY be used for generating test vectors or other
// instances that required deterministic packet generation.
[<Obsolete("BlankPacketFiller is obsolete, see here: https://github.com/lightningnetwork/lightning-rfc/commit/8dd0b75809c9a7498bb9031a6674e5f58db509f4", false)>]
let BlankPacketFiller _=
Array.zeroCreate 1300

type PacketAndSecrets = {
Packet: OnionPacket
/// Shared secrets (one per node in the route). Known (and needed) only if you're creating the
/// packet. Empty if you're just forwarding the packet to the next node
SharedSecrets: (Key * PubKey) list
}
with
static member Create (sessionKey: Key, pubKeys: PubKey list, payloads: byte[] list, ad: byte[]) =
static member Create (sessionKey: Key, pubKeys: PubKey list, payloads: byte[] list, ad: byte[], initialPacketFiller: Key -> byte[]) =
let (ephemeralPubKeys, sharedSecrets) = computeEphemeralPublicKeysAndSharedSecrets (sessionKey) (pubKeys)
let filler = generateFiller "rho" payloads sharedSecrets

let lastPacket = makeNextPacket(payloads |> List.last,
ad,
ephemeralPubKeys |> List.last,
(sharedSecrets |> List.last |> fun ss -> ss.ToBytes()),
OnionPacket.LastPacket,
{OnionPacket.LastPacket with HopData = initialPacketFiller(sessionKey)},
Some(filler))
let rec loop (hopPayloads: byte[] list, ephKeys: PubKey list, ss: Key list, packet: OnionPacket) =
if (hopPayloads.IsEmpty) then
Expand Down
24 changes: 12 additions & 12 deletions tests/DotNetLightning.Core.Tests/SphinxTests.fs
Original file line number Diff line number Diff line change
Expand Up @@ -30,10 +30,10 @@ let expectedPubKeys = [ "02eec7245d6b7d2ccb30380bfbe2a3648cd7a942653f5aa340edcea
|> List.map(hex.DecodeData >> PubKey)

let payloads = [ "000000000000000000000000000000000000000000000000000000000000000000"
"000101010101010101000000010000000100000000000000000000000000000000"
"000202020202020202000000020000000200000000000000000000000000000000"
"000303030303030303000000030000000300000000000000000000000000000000"
"000404040404040404000000040000000400000000000000000000000000000000" ]
"000101010101010101000000000000000100000001000000000000000000000000"
"000202020202020202000000000000000200000002000000000000000000000000"
"000303030303030303000000000000000300000003000000000000000000000000"
"000404040404040404000000000000000400000004000000000000000000000000" ]
|> List.map(hex.DecodeData)

let associatedData = "4242424242424242424242424242424242424242424242424242424242424242" |> hex.DecodeData
Expand Down Expand Up @@ -73,10 +73,10 @@ let bolt4Tests1 =

testCase "Create packet (reference test vector)" <| fun _ ->
let (onion, _ss) =
let p = PacketAndSecrets.Create (sessionKey, pubKeys, payloads, associatedData)
let p = PacketAndSecrets.Create (sessionKey, pubKeys, payloads, associatedData, PacketFiller.DeterministicPacketFiller)
(p.Packet, p.SharedSecrets)
let expectedPacket =
"0002eec7245d6b7d2ccb30380bfbe2a3648cd7a942653f5aa340edcea1f283686619e5f14350c2a76fc232b5e46d421e9615471ab9e0bc887beff8c95fdb878f7b3a716a996c7845c93d90e4ecbb9bde4ece2f69425c99e4bc820e44485455f135edc0d10f7d61ab590531cf08000179a333a347f8b4072f216400406bdf3bf038659793d4a1fd7b246979e3150a0a4cb052c9ec69acf0f48c3d39cd55675fe717cb7d80ce721caad69320c3a469a202f1e468c67eaf7a7cd8226d0fd32f7b48084dca885d56047694762b67021713ca673929c163ec36e04e40ca8e1c6d17569419d3039d9a1ec866abe044a9ad635778b961fc0776dc832b3a451bd5d35072d2269cf9b040f6b7a7dad84fb114ed413b1426cb96ceaf83825665ed5a1d002c1687f92465b49ed4c7f0218ff8c6c7dd7221d589c65b3b9aaa71a41484b122846c7c7b57e02e679ea8469b70e14fe4f70fee4d87b910cf144be6fe48eef24da475c0b0bcc6565ae82cd3f4e3b24c76eaa5616c6111343306ab35c1fe5ca4a77c0e314ed7dba39d6f1e0de791719c241a939cc493bea2bae1c1e932679ea94d29084278513c77b899cc98059d06a27d171b0dbdf6bee13ddc4fc17a0c4d2827d488436b57baa167544138ca2e64a11b43ac8a06cd0c2fba2d4d900ed2d9205305e2d7383cc98dacb078133de5f6fb6bed2ef26ba92cea28aafc3b9948dd9ae5559e8bd6920b8cea462aa445ca6a95e0e7ba52961b181c79e73bd581821df2b10173727a810c92b83b5ba4a0403eb710d2ca10689a35bec6c3a708e9e92f7d78ff3c5d9989574b00c6736f84c199256e76e19e78f0c98a9d580b4a658c84fc8f2096c2fbea8f5f8c59d0fdacb3be2802ef802abbecb3aba4acaac69a0e965abd8981e9896b1f6ef9d60f7a164b371af869fd0e48073742825e9434fc54da837e120266d53302954843538ea7c6c3dbfb4ff3b2fdbe244437f2a153ccf7bdb4c92aa08102d4f3cff2ae5ef86fab4653595e6a5837fa2f3e29f27a9cde5966843fb847a4a61f1e76c281fe8bb2b0a181d096100db5a1a5ce7a910238251a43ca556712eaadea167fb4d7d75825e440f3ecd782036d7574df8bceacb397abefc5f5254d2722215c53ff54af8299aaaad642c6d72a14d27882d9bbd539e1cc7a527526ba89b8c037ad09120e98ab042d3e8652b31ae0e478516bfaf88efca9f3676ffe99d2819dcaeb7610a626695f53117665d267d3f7abebd6bbd6733f645c72c389f03855bdf1e4b8075b516569b118233a0f0971d24b83113c0b096f5216a207ca99a7cddc81c130923fe3d91e7508c9ac5f2e914ff5dccab9e558566fa14efb34ac98d878580814b94b73acbfde9072f30b881f7f0fff42d4045d1ace6322d86a97d164aa84d93a60498065cc7c20e636f5862dc81531a88c60305a2e59a985be327a6902e4bed986dbf4a0b50c217af0ea7fdf9ab37f9ea1a1aaa72f54cf40154ea9b269f1a7c09f9f43245109431a175d50e2db0132337baa0ef97eed0fcf20489da36b79a1172faccc2f7ded7c60e00694282d93359c4682135642bc81f433574aa8ef0c97b4ade7ca372c5ffc23c7eddd839bab4e0f14d6df15c9dbeab176bec8b5701cf054eb3072f6dadc98f88819042bf10c407516ee58bce33fbe3b3d86a54255e577db4598e30a135361528c101683a5fcde7e8ba53f3456254be8f45fe3a56120ae96ea3773631fcb3873aa3abd91bcff00bd38bd43697a2e789e00da6077482e7b1b1a677b5afae4c54e6cbdf7377b694eb7d7a5b913476a5be923322d3de06060fd5e819635232a2cf4f0731da13b8546d1d6d4f8d75b9fce6c2341a71b0ea6f780df54bfdb0dd5cd9855179f602f9172307c7268724c3618e6817abd793adc214a0dc0bc616816632f27ea336fb56dfd"
"0002eec7245d6b7d2ccb30380bfbe2a3648cd7a942653f5aa340edcea1f283686619e5f14350c2a76fc232b5e46d421e9615471ab9e0bc887beff8c95fdb878f7b3a71e87f9aab8f6378c6ff744c1f34b393ad28d065b535c1a8668d85d3b34a1b3befd10f7d61ab590531cf08000178a333a347f8b4072e216400406bdf3bf038659793a1f9e7abc789266cc861cabd95818c0fc8efbdfdc14e3f7c2bc7eb8d6a79ef75ce721caad69320c3a469a202f3e468c67eaf7a7cda226d0fd32f7b48084dca885d014698cf05d742557763d9cb743faeae65dcc79dddaecf27fe5942be5380d15e9a1ec866abe044a9ad635778ba61fc0776dc832b39451bd5d35072d2269cf9b040a2a2fba158a0d8085926dc2e44f0c88bf487da56e13ef2d5e676a8589881b4869ed4c7f0218ff8c6c7dd7221d189c65b3b9aaa71a01484b122846c7c7b57e02e679ea8469b70e14fe4f70fee4d87b910cf144be6fe48eef24da475c0b0bcc6565a9f99728426ce2380a9580e2a9442481ceae7679906c30b1a0e21a10f26150e0645ab6edfdab1ce8f8bea7b1dee511c5fd38ac0e702c1c15bb86b52bca1b71e15b96982d262a442024c33ceb7dd8f949063c2e5e613e873250e2f8708bd4e1924abd45f65c2fa5617bfb10ee9e4a42d6b5811acc8029c16274f937dac9e8817c7e579fdb767ffe277f26d413ced06b620ede8362081da21cf67c2ca9d6f15fe5bc05f82f5bb93f8916bad3d63338ca824f3bbc11b57ce94a5fa1bc239533679903d6fec92a8c792fd86e2960188c14f21e399cfd72a50c620e10aefc6249360b463df9a89bf6836f4f26359207b765578e5ed76ae9f31b1cc48324be576e3d8e44d217445dba466f9b6293fdf05448584eb64f61e02903f834518622b7d4732471c6e0e22e22d1f45e31f0509eab39cdea5980a492a1da2aaac55a98a01216cd4bfe7abaa682af0fbff2dfed030ba28f1285df750e4d3477190dd193f8643b61d8ac1c427d590badb1f61a05d480908fbdc7c6f0502dd0c4abb51d725e92f95da2a8facb79881a844e2026911adcc659d1fb20a2fce63787c8bb0d9f6789c4b231c76da81c3f0718eb7156565a081d2be6b4170c0e0bcebddd459f53db2590c974bca0d705c055dee8c629bf854a5d58edc85228499ec6dde80cce4c8910b81b1e9e8b0f43bd39c8d69c3a80672729b7dc952dd9448688b6bd06afc2d2819cda80b66c57b52ccf7ac1a86601410d18d0c732f69de792e0894a9541684ef174de766fd4ce55efea8f53812867be6a391ac865802dbc26d93959df327ec2667c7256aa5a1d3c45a69a6158f285d6c97c3b8eedb09527848500517995a9eae4cd911df531544c77f5a9a2f22313e3eb72ca7a07dba243476bc926992e0d1e58b4a2fc8c7b01e0cad726237933ea319bad7537d39f3ed635d1e6c1d29e97b3d2160a09e30ee2b65ac5bce00996a73c008bcf351cecb97b6833b6d121dcf4644260b2946ea204732ac9954b228f0beaa15071930fd9583dfc466d12b5f0eeeba6dcf23d5ce8ae62ee5796359d97a4a15955c778d868d0ef9991d9f2833b5bb66119c5f8b396fd108baed7906cbb3cc376d13551caed97fece6f42a4c908ee279f1127fda1dd3ee77d8de0a6f3c135fa3f1cffe38591b6738dc97b55f0acc52be9753ce53e64d7e497bb00ca6123758df3b68fad99e35c04389f7514a8e36039f541598a417275e77869989782325a15b5342ac5011ff07af698584b476b35d941a4981eac590a07a092bb50342da5d3341f901aa07964a8d02b623c7b106dd0ae50bfa007a22d46c8772fa55558176602946cb1d11ea5460db7586fb89c6d3bcd3ab6dd20df4a4db63d2e7d52380800ad812b8640887e027e946df96488b47fbc4a4fadaa8beda4abe446fafea5403fae2ef"
|> hex.DecodeData
CheckArrayEqual (onion.ToBytes()) (expectedPacket)
let { Payload = payload0; NextPacket = nextPacket0; SharedSecret = _ss0 }: ParsedPacket =
Expand All @@ -99,16 +99,16 @@ let bolt4Tests1 =

Expect.equal [payload0; payload1; payload2; payload3; payload4] payloads ""

Expect.equal nextPacket0.HMAC ("2bdc5227c8eb8ba5fcfc15cfc2aa578ff208c106646d0652cd289c0a37e445bb" |> hex.DecodeData |> uint256) ""
Expect.equal nextPacket1.HMAC ("28430b210c0af631ef80dc8594c08557ce4626bdd3593314624a588cc083a1d9" |> hex.DecodeData |> uint256) ""
Expect.equal nextPacket2.HMAC ("4e888d0cc6a90e7f857af18ac858834ac251d0d1c196d198df48a0c5bf816803" |> hex.DecodeData |> uint256) ""
Expect.equal nextPacket3.HMAC ("42c10947e06bda75b35ac2a9e38005479a6feac51468712e751c71a1dcf3e31b" |> hex.DecodeData |> uint256) ""
Expect.equal nextPacket0.HMAC ("a93aa4f40241cef3e764e24b28570a0db39af82ab5102c3a04e51bec8cca9394" |> hex.DecodeData |> uint256) ""
Expect.equal nextPacket1.HMAC ("5d1b11f1efeaa9be32eb1c74b113c0b46f056bb49e2a35a51ceaece6bd31332c" |> hex.DecodeData |> uint256) ""
Expect.equal nextPacket2.HMAC ("19ca6357b5552b28e50ae226854eec874bbbf7025cf290a34c06b4eff5d2bac0" |> hex.DecodeData |> uint256) ""
Expect.equal nextPacket3.HMAC ("16d4553c6084b369073d259381bb5b02c16bb2c590bbd9e69346cf7ebd563229" |> hex.DecodeData |> uint256) ""
Expect.equal nextPacket4.HMAC ("0000000000000000000000000000000000000000000000000000000000000000" |> hex.DecodeData |> uint256) ""
()

testCase "last node replies with an error message" <| fun _ ->
let (onion, ss) =
let p = PacketAndSecrets.Create (sessionKey, pubKeys, payloads, associatedData)
let p = PacketAndSecrets.Create (sessionKey, pubKeys, payloads, associatedData, PacketFiller.BlankPacketFiller)
(p.Packet, p.SharedSecrets)
let { NextPacket = packet1; SharedSecret = ss0 }: ParsedPacket =
Sphinx.parsePacket (privKeys.[0]) (associatedData) (onion.ToBytes())
Expand Down Expand Up @@ -166,7 +166,7 @@ let bolt4Tests1 =

testCase "Intermediate node replies with an error message" <| fun _ ->
let { Packet = packet; SharedSecrets = ss } =
Sphinx.PacketAndSecrets.Create(sessionKey, pubKeys, payloads, associatedData)
Sphinx.PacketAndSecrets.Create(sessionKey, pubKeys, payloads, associatedData, PacketFiller.BlankPacketFiller)
let { NextPacket = packet1; SharedSecret = ss0 } =
Sphinx.parsePacket(privKeys.[0]) (associatedData) (packet.ToBytes())
|> Result.defaultWith(fun _ -> failwith "Fail: bolt4 intrm node replies with err msg defaultClosure0")
Expand Down

0 comments on commit 08b6971

Please sign in to comment.