Skip to content

Commit a413942

Browse files
committed
Introduce padding for Onion Messages
1 parent 78c0eaa commit a413942

File tree

3 files changed

+62
-11
lines changed

3 files changed

+62
-11
lines changed

lightning/src/blinded_path/message.rs

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,6 @@ impl Writeable for ForwardTlvs {
6565
NextMessageHop::NodeId(pubkey) => (Some(pubkey), None),
6666
NextMessageHop::ShortChannelId(scid) => (None, Some(scid)),
6767
};
68-
// TODO: write padding
6968
encode_tlv_stream!(writer, {
7069
(2, short_channel_id, option),
7170
(4, next_node_id, option),
@@ -77,7 +76,6 @@ impl Writeable for ForwardTlvs {
7776

7877
impl Writeable for ReceiveTlvs {
7978
fn write<W: Writer>(&self, writer: &mut W) -> Result<(), io::Error> {
80-
// TODO: write padding
8179
encode_tlv_stream!(writer, {
8280
(65537, self.context, option),
8381
});
@@ -138,17 +136,25 @@ pub(super) fn blinded_hops<T: secp256k1::Signing + secp256k1::Verification>(
138136
) -> Result<Vec<BlindedHop>, secp256k1::Error> {
139137
let pks = intermediate_nodes.iter().map(|node| &node.node_id)
140138
.chain(core::iter::once(&recipient_node_id));
141-
let tlvs = pks.clone()
139+
let tlvs: Vec<ControlTlvs> = pks.clone()
142140
.skip(1) // The first node's TLVs contains the next node's pubkey
143141
.zip(intermediate_nodes.iter().map(|node| node.short_channel_id))
144142
.map(|(pubkey, scid)| match scid {
145143
Some(scid) => NextMessageHop::ShortChannelId(scid),
146144
None => NextMessageHop::NodeId(*pubkey),
147145
})
148146
.map(|next_hop| ControlTlvs::Forward(ForwardTlvs { next_hop, next_blinding_override: None }))
149-
.chain(core::iter::once(ControlTlvs::Receive(ReceiveTlvs{ context: Some(context) })));
147+
.chain(core::iter::once(ControlTlvs::Receive(ReceiveTlvs{ context: Some(context) })))
148+
.collect();
150149

151-
utils::construct_blinded_hops(secp_ctx, pks, tlvs, session_priv)
150+
let max_length = tlvs.iter()
151+
.max_by_key(|c| c.serialized_length())
152+
.map(|c| c.serialized_length())
153+
.unwrap_or(0);
154+
155+
let length_tlvs = tlvs.into_iter().map(move |tlv| (max_length, tlv));
156+
157+
utils::construct_blinded_hops(secp_ctx, pks, length_tlvs, session_priv)
152158
}
153159

154160
// Advance the blinded onion message path by one hop, so make the second hop into the new

lightning/src/blinded_path/utils.rs

Lines changed: 38 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ use crate::ln::msgs::DecodeError;
2020
use crate::ln::onion_utils;
2121
use crate::onion_message::messenger::Destination;
2222
use crate::crypto::streams::ChaChaPolyWriteAdapter;
23-
use crate::util::ser::{Readable, Writeable};
23+
use crate::util::ser::{Readable, Writeable, Writer};
2424

2525
use crate::io;
2626

@@ -135,17 +135,49 @@ fn encrypt_payload<P: Writeable>(payload: P, encrypted_tlvs_rho: [u8; 32]) -> Ve
135135
write_adapter.encode()
136136
}
137137

138-
/// Blinded path encrypted payloads may be padded to ensure they are equal length.
139-
///
140-
/// Reads padding to the end, ignoring what's read.
141-
pub(crate) struct Padding {}
138+
/// Represents optional padding for encrypted payloads.
139+
/// Padding is used to ensure payloads have a consistent length.
140+
pub(crate) struct Padding {
141+
padding: Option<Vec<u8>>
142+
}
143+
144+
impl Padding {
145+
/// Creates a new [`Padding`] instance with a specified size.
146+
/// Use this method when defining the padding size before writing
147+
/// an encrypted payload.
148+
pub fn new(length: usize) -> Self {
149+
Self {
150+
padding: Some(vec![0; length]),
151+
}
152+
}
153+
154+
/// Creates a [`Padding`] instance with no size.
155+
/// This method is used when returning the [`Padding`] after reading.
156+
/// It essentially discards any existing padding data.
157+
pub fn none() -> Self {
158+
Self {
159+
padding: None,
160+
}
161+
}
162+
}
163+
142164
impl Readable for Padding {
165+
/// Reads and discards the padding data.
143166
#[inline]
144167
fn read<R: io::Read>(reader: &mut R) -> Result<Self, DecodeError> {
145168
loop {
146169
let mut buf = [0; 8192];
147170
if reader.read(&mut buf[..])? == 0 { break; }
148171
}
149-
Ok(Self {})
172+
Ok(Self::none())
173+
}
174+
}
175+
176+
impl Writeable for Padding {
177+
fn write<W: Writer>(&self, writer: &mut W) -> Result<(), io::Error> {
178+
match &self.padding {
179+
Some(padding) => padding.write(writer),
180+
None => return Ok(()),
181+
}
150182
}
151183
}

lightning/src/onion_message/packet.rs

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -359,3 +359,16 @@ impl Writeable for ControlTlvs {
359359
}
360360
}
361361
}
362+
363+
impl Writeable for (usize, ControlTlvs) {
364+
fn write<W: Writer>(&self, writer: &mut W) -> Result<(), io::Error> {
365+
let length = self.0 - self.1.serialized_length();
366+
let padding = Some(Padding::new(length));
367+
368+
encode_tlv_stream!(writer, {
369+
(1, padding, option)
370+
});
371+
372+
self.1.write(writer)
373+
}
374+
}

0 commit comments

Comments
 (0)