Skip to content

Commit 1a8bf62

Browse files
authored
Merge pull request #3435 from jkczyz/2024-12-hmac-payment-context
Authenticate blinded payment paths
2 parents 6e85a0d + d287bf0 commit 1a8bf62

28 files changed

+406
-222
lines changed

fuzz/src/chanmon_consistency.rs

+4-5
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,7 @@ use lightning::ln::channelmanager::{
5050
ChainParameters, ChannelManager, ChannelManagerReadArgs, PaymentId, RecipientOnionFields, Retry,
5151
};
5252
use lightning::ln::functional_test_utils::*;
53+
use lightning::ln::inbound_payment::ExpandedKey;
5354
use lightning::ln::msgs::{
5455
self, ChannelMessageHandler, CommitmentUpdate, DecodeError, Init, UpdateAddHTLC,
5556
};
@@ -60,9 +61,7 @@ use lightning::onion_message::messenger::{Destination, MessageRouter, OnionMessa
6061
use lightning::routing::router::{
6162
InFlightHtlcs, Path, PaymentParameters, Route, RouteHop, RouteParameters, Router,
6263
};
63-
use lightning::sign::{
64-
EntropySource, InMemorySigner, KeyMaterial, NodeSigner, Recipient, SignerProvider,
65-
};
64+
use lightning::sign::{EntropySource, InMemorySigner, NodeSigner, Recipient, SignerProvider};
6665
use lightning::types::payment::{PaymentHash, PaymentPreimage, PaymentSecret};
6766
use lightning::util::config::UserConfig;
6867
use lightning::util::errors::APIError;
@@ -334,10 +333,10 @@ impl NodeSigner for KeyProvider {
334333
Ok(SharedSecret::new(other_key, &node_secret))
335334
}
336335

337-
fn get_inbound_payment_key_material(&self) -> KeyMaterial {
336+
fn get_inbound_payment_key(&self) -> ExpandedKey {
338337
#[rustfmt::skip]
339338
let random_bytes = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, self.node_secret[31]];
340-
KeyMaterial(random_bytes)
339+
ExpandedKey::new(random_bytes)
341340
}
342341

343342
fn sign_invoice(

fuzz/src/full_stack.rs

+6-8
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ use lightning::ln::channelmanager::{
4343
ChainParameters, ChannelManager, InterceptId, PaymentId, RecipientOnionFields, Retry,
4444
};
4545
use lightning::ln::functional_test_utils::*;
46+
use lightning::ln::inbound_payment::ExpandedKey;
4647
use lightning::ln::msgs::{self, DecodeError};
4748
use lightning::ln::peer_handler::{
4849
IgnoringMessageHandler, MessageHandler, PeerManager, SocketDescriptor,
@@ -56,9 +57,7 @@ use lightning::routing::router::{
5657
InFlightHtlcs, PaymentParameters, Route, RouteParameters, Router,
5758
};
5859
use lightning::routing::utxo::UtxoLookup;
59-
use lightning::sign::{
60-
EntropySource, InMemorySigner, KeyMaterial, NodeSigner, Recipient, SignerProvider,
61-
};
60+
use lightning::sign::{EntropySource, InMemorySigner, NodeSigner, Recipient, SignerProvider};
6261
use lightning::types::payment::{PaymentHash, PaymentPreimage, PaymentSecret};
6362
use lightning::util::config::{ChannelConfig, UserConfig};
6463
use lightning::util::errors::APIError;
@@ -79,7 +78,6 @@ use bitcoin::secp256k1::{self, Message, PublicKey, Scalar, Secp256k1, SecretKey}
7978

8079
use std::cell::RefCell;
8180
use std::cmp;
82-
use std::convert::TryInto;
8381
use std::sync::atomic::{AtomicBool, AtomicU64, AtomicUsize, Ordering};
8482
use std::sync::{Arc, Mutex};
8583

@@ -364,7 +362,7 @@ impl<'a> Drop for MoneyLossDetector<'a> {
364362

365363
struct KeyProvider {
366364
node_secret: SecretKey,
367-
inbound_payment_key: KeyMaterial,
365+
inbound_payment_key: ExpandedKey,
368366
counter: AtomicU64,
369367
signer_state: RefCell<HashMap<u8, (bool, Arc<Mutex<EnforcementState>>)>>,
370368
}
@@ -402,8 +400,8 @@ impl NodeSigner for KeyProvider {
402400
Ok(SharedSecret::new(other_key, &node_secret))
403401
}
404402

405-
fn get_inbound_payment_key_material(&self) -> KeyMaterial {
406-
self.inbound_payment_key.clone()
403+
fn get_inbound_payment_key(&self) -> ExpandedKey {
404+
self.inbound_payment_key
407405
}
408406

409407
fn sign_invoice(
@@ -636,7 +634,7 @@ pub fn do_test(mut data: &[u8], logger: &Arc<dyn Logger>) {
636634

637635
let keys_manager = Arc::new(KeyProvider {
638636
node_secret: our_network_key.clone(),
639-
inbound_payment_key: KeyMaterial(inbound_payment_key.try_into().unwrap()),
637+
inbound_payment_key: ExpandedKey::new(inbound_payment_key),
640638
counter: AtomicU64::new(0),
641639
signer_state: RefCell::new(new_hash_map()),
642640
});

fuzz/src/invoice_request_deser.rs

+8-3
Original file line numberDiff line numberDiff line change
@@ -12,11 +12,13 @@ use bitcoin::secp256k1::{self, Keypair, Parity, PublicKey, Secp256k1, SecretKey}
1212
use core::convert::TryFrom;
1313
use lightning::blinded_path::payment::{
1414
BlindedPaymentPath, Bolt12OfferContext, ForwardTlvs, PaymentConstraints, PaymentContext,
15-
PaymentForwardNode, PaymentRelay, ReceiveTlvs,
15+
PaymentForwardNode, PaymentRelay, UnauthenticatedReceiveTlvs,
1616
};
1717
use lightning::ln::channelmanager::MIN_FINAL_CLTV_EXPIRY_DELTA;
18+
use lightning::ln::inbound_payment::ExpandedKey;
1819
use lightning::offers::invoice::UnsignedBolt12Invoice;
1920
use lightning::offers::invoice_request::{InvoiceRequest, InvoiceRequestFields};
21+
use lightning::offers::nonce::Nonce;
2022
use lightning::offers::offer::OfferId;
2123
use lightning::offers::parse::Bolt12SemanticError;
2224
use lightning::sign::EntropySource;
@@ -80,7 +82,9 @@ fn privkey(byte: u8) -> SecretKey {
8082
fn build_response<T: secp256k1::Signing + secp256k1::Verification>(
8183
invoice_request: &InvoiceRequest, secp_ctx: &Secp256k1<T>,
8284
) -> Result<UnsignedBolt12Invoice, Bolt12SemanticError> {
85+
let expanded_key = ExpandedKey::new([42; 32]);
8386
let entropy_source = Randomness {};
87+
let nonce = Nonce::from_entropy_source(&entropy_source);
8488
let payment_context = PaymentContext::Bolt12Offer(Bolt12OfferContext {
8589
offer_id: OfferId([42; 32]),
8690
invoice_request: InvoiceRequestFields {
@@ -92,14 +96,15 @@ fn build_response<T: secp256k1::Signing + secp256k1::Verification>(
9296
human_readable_name: None,
9397
},
9498
});
95-
let payee_tlvs = ReceiveTlvs {
99+
let payee_tlvs = UnauthenticatedReceiveTlvs {
96100
payment_secret: PaymentSecret([42; 32]),
97101
payment_constraints: PaymentConstraints {
98102
max_cltv_expiry: 1_000_000,
99103
htlc_minimum_msat: 1,
100104
},
101105
payment_context,
102106
};
107+
let payee_tlvs = payee_tlvs.authenticate(nonce, &expanded_key);
103108
let intermediate_nodes = [PaymentForwardNode {
104109
tlvs: ForwardTlvs {
105110
short_channel_id: 43,
@@ -109,7 +114,7 @@ fn build_response<T: secp256k1::Signing + secp256k1::Verification>(
109114
fee_base_msat: 1,
110115
},
111116
payment_constraints: PaymentConstraints {
112-
max_cltv_expiry: payee_tlvs.payment_constraints.max_cltv_expiry + 40,
117+
max_cltv_expiry: payee_tlvs.tlvs().payment_constraints.max_cltv_expiry + 40,
113118
htlc_minimum_msat: 100,
114119
},
115120
features: BlindedHopFeatures::empty(),

fuzz/src/offer_deser.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ use lightning::offers::invoice_request::InvoiceRequest;
1616
use lightning::offers::nonce::Nonce;
1717
use lightning::offers::offer::{Amount, Offer, Quantity};
1818
use lightning::offers::parse::Bolt12SemanticError;
19-
use lightning::sign::{EntropySource, KeyMaterial};
19+
use lightning::sign::EntropySource;
2020
use lightning::util::ser::Writeable;
2121

2222
#[inline]
@@ -43,7 +43,7 @@ impl EntropySource for FixedEntropy {
4343
}
4444

4545
fn build_request(offer: &Offer) -> Result<InvoiceRequest, Bolt12SemanticError> {
46-
let expanded_key = ExpandedKey::new(&KeyMaterial([42; 32]));
46+
let expanded_key = ExpandedKey::new([42; 32]);
4747
let entropy = FixedEntropy {};
4848
let nonce = Nonce::from_entropy_source(&entropy);
4949
let secp_ctx = Secp256k1::new();

fuzz/src/onion_message.rs

+3-2
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ use lightning::blinded_path::message::{
99
AsyncPaymentsContext, BlindedMessagePath, MessageContext, OffersContext,
1010
};
1111
use lightning::blinded_path::EmptyNodeIdLookUp;
12+
use lightning::ln::inbound_payment::ExpandedKey;
1213
use lightning::ln::msgs::{self, DecodeError, OnionMessageHandler};
1314
use lightning::ln::peer_handler::IgnoringMessageHandler;
1415
use lightning::ln::script::ShutdownScript;
@@ -22,7 +23,7 @@ use lightning::onion_message::messenger::{
2223
};
2324
use lightning::onion_message::offers::{OffersMessage, OffersMessageHandler};
2425
use lightning::onion_message::packet::OnionMessageContents;
25-
use lightning::sign::{EntropySource, KeyMaterial, NodeSigner, Recipient, SignerProvider};
26+
use lightning::sign::{EntropySource, NodeSigner, Recipient, SignerProvider};
2627
use lightning::types::features::InitFeatures;
2728
use lightning::util::logger::Logger;
2829
use lightning::util::ser::{Readable, Writeable, Writer};
@@ -223,7 +224,7 @@ impl NodeSigner for KeyProvider {
223224
Ok(SharedSecret::new(other_key, &node_secret))
224225
}
225226

226-
fn get_inbound_payment_key_material(&self) -> KeyMaterial {
227+
fn get_inbound_payment_key(&self) -> ExpandedKey {
227228
unreachable!()
228229
}
229230

fuzz/src/refund_deser.rs

+8-3
Original file line numberDiff line numberDiff line change
@@ -12,10 +12,12 @@ use bitcoin::secp256k1::{self, Keypair, PublicKey, Secp256k1, SecretKey};
1212
use core::convert::TryFrom;
1313
use lightning::blinded_path::payment::{
1414
BlindedPaymentPath, Bolt12RefundContext, ForwardTlvs, PaymentConstraints, PaymentContext,
15-
PaymentForwardNode, PaymentRelay, ReceiveTlvs,
15+
PaymentForwardNode, PaymentRelay, UnauthenticatedReceiveTlvs,
1616
};
1717
use lightning::ln::channelmanager::MIN_FINAL_CLTV_EXPIRY_DELTA;
18+
use lightning::ln::inbound_payment::ExpandedKey;
1819
use lightning::offers::invoice::UnsignedBolt12Invoice;
20+
use lightning::offers::nonce::Nonce;
1921
use lightning::offers::parse::Bolt12SemanticError;
2022
use lightning::offers::refund::Refund;
2123
use lightning::sign::EntropySource;
@@ -67,16 +69,19 @@ fn privkey(byte: u8) -> SecretKey {
6769
fn build_response<T: secp256k1::Signing + secp256k1::Verification>(
6870
refund: &Refund, signing_pubkey: PublicKey, secp_ctx: &Secp256k1<T>,
6971
) -> Result<UnsignedBolt12Invoice, Bolt12SemanticError> {
72+
let expanded_key = ExpandedKey::new([42; 32]);
7073
let entropy_source = Randomness {};
74+
let nonce = Nonce::from_entropy_source(&entropy_source);
7175
let payment_context = PaymentContext::Bolt12Refund(Bolt12RefundContext {});
72-
let payee_tlvs = ReceiveTlvs {
76+
let payee_tlvs = UnauthenticatedReceiveTlvs {
7377
payment_secret: PaymentSecret([42; 32]),
7478
payment_constraints: PaymentConstraints {
7579
max_cltv_expiry: 1_000_000,
7680
htlc_minimum_msat: 1,
7781
},
7882
payment_context,
7983
};
84+
let payee_tlvs = payee_tlvs.authenticate(nonce, &expanded_key);
8085
let intermediate_nodes = [PaymentForwardNode {
8186
tlvs: ForwardTlvs {
8287
short_channel_id: 43,
@@ -86,7 +91,7 @@ fn build_response<T: secp256k1::Signing + secp256k1::Verification>(
8691
fee_base_msat: 1,
8792
},
8893
payment_constraints: PaymentConstraints {
89-
max_cltv_expiry: payee_tlvs.payment_constraints.max_cltv_expiry + 40,
94+
max_cltv_expiry: payee_tlvs.tlvs().payment_constraints.max_cltv_expiry + 40,
9095
htlc_minimum_msat: 100,
9196
},
9297
features: BlindedHopFeatures::empty(),

lightning-invoice/src/lib.rs

+1
Original file line numberDiff line numberDiff line change
@@ -1086,6 +1086,7 @@ impl RawBolt11Invoice {
10861086

10871087
/// Calculate the hash of the encoded `RawBolt11Invoice` which should be signed.
10881088
pub fn signable_hash(&self) -> [u8; 32] {
1089+
#[cfg(not(fuzzing))]
10891090
use crate::ser::Base32Iterable;
10901091

10911092
Self::hash_from_parts(self.hrp.to_string().as_bytes(), self.data.fe_iter())

0 commit comments

Comments
 (0)