1use bitcoin::secp256k1::{self, PublicKey, Secp256k1, SecretKey};
13
14#[allow(unused_imports)]
15use crate::prelude::*;
16
17use bitcoin::hashes::hmac::Hmac;
18use bitcoin::hashes::sha256::Hash as Sha256;
19use crate::blinded_path::{BlindedHop, BlindedPath, Direction, IntroductionNode, NodeIdLookUp};
20use crate::blinded_path::utils;
21use crate::io;
22use crate::io::Cursor;
23use crate::ln::channelmanager::PaymentId;
24use crate::ln::msgs::DecodeError;
25use crate::ln::onion_utils;
26use crate::types::payment::PaymentHash;
27use crate::offers::nonce::Nonce;
28use crate::onion_message::packet::ControlTlvs;
29use crate::routing::gossip::{NodeId, ReadOnlyNetworkGraph};
30use crate::sign::{EntropySource, NodeSigner, Recipient};
31use crate::crypto::streams::ChaChaPolyReadAdapter;
32use crate::util::scid_utils;
33use crate::util::ser::{FixedLengthReader, LengthReadableArgs, Readable, Writeable, Writer};
34
35use core::mem;
36use core::ops::Deref;
37
38#[derive(Clone, Debug, Hash, PartialEq, Eq)]
41pub struct BlindedMessagePath(pub(super) BlindedPath);
42
43impl Writeable for BlindedMessagePath {
44 fn write<W: Writer>(&self, w: &mut W) -> Result<(), io::Error> {
45 self.0.write(w)
46 }
47}
48
49impl Readable for BlindedMessagePath {
50 fn read<R: io::Read>(r: &mut R) -> Result<Self, DecodeError> {
51 Ok(Self(BlindedPath::read(r)?))
52 }
53}
54
55impl BlindedMessagePath {
56 pub fn one_hop<ES: Deref, T: secp256k1::Signing + secp256k1::Verification>(
58 recipient_node_id: PublicKey, context: MessageContext, entropy_source: ES, secp_ctx: &Secp256k1<T>
59 ) -> Result<Self, ()> where ES::Target: EntropySource {
60 Self::new(&[], recipient_node_id, context, entropy_source, secp_ctx)
61 }
62
63 pub fn new<ES: Deref, T: secp256k1::Signing + secp256k1::Verification>(
69 intermediate_nodes: &[MessageForwardNode], recipient_node_id: PublicKey,
70 context: MessageContext, entropy_source: ES, secp_ctx: &Secp256k1<T>,
71 ) -> Result<Self, ()> where ES::Target: EntropySource {
72 let introduction_node = IntroductionNode::NodeId(
73 intermediate_nodes.first().map_or(recipient_node_id, |n| n.node_id)
74 );
75 let blinding_secret_bytes = entropy_source.get_secure_random_bytes();
76 let blinding_secret = SecretKey::from_slice(&blinding_secret_bytes[..]).expect("RNG is busted");
77
78 Ok(Self(BlindedPath {
79 introduction_node,
80 blinding_point: PublicKey::from_secret_key(secp_ctx, &blinding_secret),
81 blinded_hops: blinded_hops(
82 secp_ctx, intermediate_nodes, recipient_node_id,
83 context, &blinding_secret,
84 ).map_err(|_| ())?,
85 }))
86 }
87
88 pub fn use_compact_introduction_node(&mut self, network_graph: &ReadOnlyNetworkGraph) {
95 if let IntroductionNode::NodeId(pubkey) = &self.0.introduction_node {
96 let node_id = NodeId::from_pubkey(pubkey);
97 if let Some(node_info) = network_graph.node(&node_id) {
98 if let Some((scid, channel_info)) = node_info
99 .channels
100 .iter()
101 .filter_map(|scid| network_graph.channel(*scid).map(|info| (*scid, info)))
102 .min_by_key(|(scid, _)| scid_utils::block_from_scid(*scid))
103 {
104 let direction = if node_id == channel_info.node_one {
105 Direction::NodeOne
106 } else {
107 debug_assert_eq!(node_id, channel_info.node_two);
108 Direction::NodeTwo
109 };
110 self.0.introduction_node =
111 IntroductionNode::DirectedShortChannelId(direction, scid);
112 }
113 }
114 }
115 }
116
117 pub fn public_introduction_node_id<'a>(
120 &self, network_graph: &'a ReadOnlyNetworkGraph
121 ) -> Option<&'a NodeId> {
122 self.0.public_introduction_node_id(network_graph)
123 }
124
125 pub fn introduction_node(&self) -> &IntroductionNode {
127 &self.0.introduction_node
128 }
129
130 pub fn blinding_point(&self) -> PublicKey {
134 self.0.blinding_point
135 }
136
137 pub fn blinded_hops(&self) -> &[BlindedHop] {
139 &self.0.blinded_hops
140 }
141
142 pub fn advance_path_by_one<NS: Deref, NL: Deref, T>(
147 &mut self, node_signer: &NS, node_id_lookup: &NL, secp_ctx: &Secp256k1<T>
148 ) -> Result<(), ()>
149 where
150 NS::Target: NodeSigner,
151 NL::Target: NodeIdLookUp,
152 T: secp256k1::Signing + secp256k1::Verification,
153 {
154 let control_tlvs_ss = node_signer.ecdh(Recipient::Node, &self.0.blinding_point, None)?;
155 let rho = onion_utils::gen_rho_from_shared_secret(&control_tlvs_ss.secret_bytes());
156 let encrypted_control_tlvs = &self.0.blinded_hops.get(0).ok_or(())?.encrypted_payload;
157 let mut s = Cursor::new(encrypted_control_tlvs);
158 let mut reader = FixedLengthReader::new(&mut s, encrypted_control_tlvs.len() as u64);
159 match ChaChaPolyReadAdapter::read(&mut reader, rho) {
160 Ok(ChaChaPolyReadAdapter {
161 readable: ControlTlvs::Forward(ForwardTlvs { next_hop, next_blinding_override })
162 }) => {
163 let next_node_id = match next_hop {
164 NextMessageHop::NodeId(pubkey) => pubkey,
165 NextMessageHop::ShortChannelId(scid) => match node_id_lookup.next_node_id(scid) {
166 Some(pubkey) => pubkey,
167 None => return Err(()),
168 },
169 };
170 let mut new_blinding_point = match next_blinding_override {
171 Some(blinding_point) => blinding_point,
172 None => {
173 onion_utils::next_hop_pubkey(secp_ctx, self.0.blinding_point,
174 control_tlvs_ss.as_ref()).map_err(|_| ())?
175 }
176 };
177 mem::swap(&mut self.0.blinding_point, &mut new_blinding_point);
178 self.0.introduction_node = IntroductionNode::NodeId(next_node_id);
179 self.0.blinded_hops.remove(0);
180 Ok(())
181 },
182 _ => Err(())
183 }
184 }
185
186 pub(crate) fn introduction_node_mut(&mut self) -> &mut IntroductionNode {
187 &mut self.0.introduction_node
188 }
189
190 #[cfg(test)]
191 pub fn from_raw(
192 introduction_node_id: PublicKey, blinding_point: PublicKey, blinded_hops: Vec<BlindedHop>
193 ) -> Self {
194 Self(BlindedPath {
195 introduction_node: IntroductionNode::NodeId(introduction_node_id),
196 blinding_point,
197 blinded_hops,
198 })
199 }
200
201 #[cfg(test)]
202 pub fn clear_blinded_hops(&mut self) {
203 self.0.blinded_hops.clear()
204 }
205}
206
207#[derive(Clone, Debug, Hash, PartialEq, Eq)]
211pub enum NextMessageHop {
212 NodeId(PublicKey),
214 ShortChannelId(u64),
216}
217
218#[derive(Clone, Copy, Debug, Hash, PartialEq, Eq)]
220pub struct MessageForwardNode {
221 pub node_id: PublicKey,
223 pub short_channel_id: Option<u64>,
227}
228
229pub(crate) struct ForwardTlvs {
232 pub(crate) next_hop: NextMessageHop,
234 pub(crate) next_blinding_override: Option<PublicKey>,
237}
238
239pub(crate) struct ReceiveTlvs {
241 pub context: Option<MessageContext>
245}
246
247impl Writeable for ForwardTlvs {
248 fn write<W: Writer>(&self, writer: &mut W) -> Result<(), io::Error> {
249 let (next_node_id, short_channel_id) = match self.next_hop {
250 NextMessageHop::NodeId(pubkey) => (Some(pubkey), None),
251 NextMessageHop::ShortChannelId(scid) => (None, Some(scid)),
252 };
253 encode_tlv_stream!(writer, {
255 (2, short_channel_id, option),
256 (4, next_node_id, option),
257 (8, self.next_blinding_override, option)
258 });
259 Ok(())
260 }
261}
262
263impl Writeable for ReceiveTlvs {
264 fn write<W: Writer>(&self, writer: &mut W) -> Result<(), io::Error> {
265 encode_tlv_stream!(writer, {
267 (65537, self.context, option),
268 });
269 Ok(())
270 }
271}
272
273#[derive(Clone, Debug)]
279pub enum MessageContext {
280 Offers(OffersContext),
284 AsyncPayments(AsyncPaymentsContext),
288 DNSResolver(DNSResolverContext),
293 Custom(Vec<u8>),
297}
298
299#[derive(Clone, Debug, Eq, PartialEq)]
303pub enum OffersContext {
304 InvoiceRequest {
311 nonce: Nonce,
317 },
318 OutboundPayment {
329 payment_id: PaymentId,
334
335 nonce: Nonce,
342
343 hmac: Option<Hmac<Sha256>>,
348 },
349 InboundPayment {
356 payment_hash: PaymentHash,
360
361 nonce: Nonce,
367
368 hmac: Hmac<Sha256>,
373 },
374}
375
376#[derive(Clone, Debug)]
380pub enum AsyncPaymentsContext {
381 OutboundPayment {
388 payment_id: PaymentId,
393 nonce: Nonce,
399 hmac: Hmac<Sha256>,
404 },
405}
406
407impl_writeable_tlv_based_enum!(MessageContext,
408 {0, Offers} => (),
409 {1, Custom} => (),
410 {2, AsyncPayments} => (),
411 {3, DNSResolver} => (),
412);
413
414impl_writeable_tlv_based_enum!(OffersContext,
415 (0, InvoiceRequest) => {
416 (0, nonce, required),
417 },
418 (1, OutboundPayment) => {
419 (0, payment_id, required),
420 (1, nonce, required),
421 (2, hmac, option),
422 },
423 (2, InboundPayment) => {
424 (0, payment_hash, required),
425 (1, nonce, required),
426 (2, hmac, required)
427 },
428);
429
430impl_writeable_tlv_based_enum!(AsyncPaymentsContext,
431 (0, OutboundPayment) => {
432 (0, payment_id, required),
433 (2, nonce, required),
434 (4, hmac, required),
435 },
436);
437
438#[derive(Clone, Debug, Hash, PartialEq, Eq)]
444pub struct DNSResolverContext {
445 pub nonce: [u8; 16],
450}
451
452impl_writeable_tlv_based!(DNSResolverContext, {
453 (0, nonce, required),
454});
455
456pub(super) fn blinded_hops<T: secp256k1::Signing + secp256k1::Verification>(
458 secp_ctx: &Secp256k1<T>, intermediate_nodes: &[MessageForwardNode],
459 recipient_node_id: PublicKey, context: MessageContext, session_priv: &SecretKey,
460) -> Result<Vec<BlindedHop>, secp256k1::Error> {
461 let pks = intermediate_nodes.iter().map(|node| node.node_id)
462 .chain(core::iter::once(recipient_node_id));
463 let tlvs = pks.clone()
464 .skip(1) .zip(intermediate_nodes.iter().map(|node| node.short_channel_id))
466 .map(|(pubkey, scid)| match scid {
467 Some(scid) => NextMessageHop::ShortChannelId(scid),
468 None => NextMessageHop::NodeId(pubkey),
469 })
470 .map(|next_hop| ControlTlvs::Forward(ForwardTlvs { next_hop, next_blinding_override: None }))
471 .chain(core::iter::once(ControlTlvs::Receive(ReceiveTlvs{ context: Some(context) })));
472
473 let path = pks.zip(tlvs);
474
475 utils::construct_blinded_hops(secp_ctx, path, session_priv)
476}
477