Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Authenticate blinded payment paths #3435

Merged
merged 10 commits into from
Dec 13, 2024
9 changes: 4 additions & 5 deletions fuzz/src/chanmon_consistency.rs
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ use lightning::ln::channelmanager::{
ChainParameters, ChannelManager, ChannelManagerReadArgs, PaymentId, RecipientOnionFields, Retry,
};
use lightning::ln::functional_test_utils::*;
use lightning::ln::inbound_payment::ExpandedKey;
use lightning::ln::msgs::{
self, ChannelMessageHandler, CommitmentUpdate, DecodeError, Init, UpdateAddHTLC,
};
Expand All @@ -60,9 +61,7 @@ use lightning::onion_message::messenger::{Destination, MessageRouter, OnionMessa
use lightning::routing::router::{
InFlightHtlcs, Path, PaymentParameters, Route, RouteHop, RouteParameters, Router,
};
use lightning::sign::{
EntropySource, InMemorySigner, KeyMaterial, NodeSigner, Recipient, SignerProvider,
};
use lightning::sign::{EntropySource, InMemorySigner, NodeSigner, Recipient, SignerProvider};
use lightning::types::payment::{PaymentHash, PaymentPreimage, PaymentSecret};
use lightning::util::config::UserConfig;
use lightning::util::errors::APIError;
Expand Down Expand Up @@ -334,10 +333,10 @@ impl NodeSigner for KeyProvider {
Ok(SharedSecret::new(other_key, &node_secret))
}

fn get_inbound_payment_key_material(&self) -> KeyMaterial {
fn get_inbound_payment_key(&self) -> ExpandedKey {
#[rustfmt::skip]
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]];
KeyMaterial(random_bytes)
ExpandedKey::new(random_bytes)
}

fn sign_invoice(
Expand Down
14 changes: 6 additions & 8 deletions fuzz/src/full_stack.rs
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ use lightning::ln::channelmanager::{
ChainParameters, ChannelManager, InterceptId, PaymentId, RecipientOnionFields, Retry,
};
use lightning::ln::functional_test_utils::*;
use lightning::ln::inbound_payment::ExpandedKey;
use lightning::ln::msgs::{self, DecodeError};
use lightning::ln::peer_handler::{
IgnoringMessageHandler, MessageHandler, PeerManager, SocketDescriptor,
Expand All @@ -56,9 +57,7 @@ use lightning::routing::router::{
InFlightHtlcs, PaymentParameters, Route, RouteParameters, Router,
};
use lightning::routing::utxo::UtxoLookup;
use lightning::sign::{
EntropySource, InMemorySigner, KeyMaterial, NodeSigner, Recipient, SignerProvider,
};
use lightning::sign::{EntropySource, InMemorySigner, NodeSigner, Recipient, SignerProvider};
use lightning::types::payment::{PaymentHash, PaymentPreimage, PaymentSecret};
use lightning::util::config::{ChannelConfig, UserConfig};
use lightning::util::errors::APIError;
Expand All @@ -79,7 +78,6 @@ use bitcoin::secp256k1::{self, Message, PublicKey, Scalar, Secp256k1, SecretKey}

use std::cell::RefCell;
use std::cmp;
use std::convert::TryInto;
use std::sync::atomic::{AtomicBool, AtomicU64, AtomicUsize, Ordering};
use std::sync::{Arc, Mutex};

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

struct KeyProvider {
node_secret: SecretKey,
inbound_payment_key: KeyMaterial,
inbound_payment_key: ExpandedKey,
counter: AtomicU64,
signer_state: RefCell<HashMap<u8, (bool, Arc<Mutex<EnforcementState>>)>>,
}
Expand Down Expand Up @@ -402,8 +400,8 @@ impl NodeSigner for KeyProvider {
Ok(SharedSecret::new(other_key, &node_secret))
}

fn get_inbound_payment_key_material(&self) -> KeyMaterial {
self.inbound_payment_key.clone()
fn get_inbound_payment_key(&self) -> ExpandedKey {
self.inbound_payment_key
}

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

let keys_manager = Arc::new(KeyProvider {
node_secret: our_network_key.clone(),
inbound_payment_key: KeyMaterial(inbound_payment_key.try_into().unwrap()),
inbound_payment_key: ExpandedKey::new(inbound_payment_key),
counter: AtomicU64::new(0),
signer_state: RefCell::new(new_hash_map()),
});
Expand Down
11 changes: 8 additions & 3 deletions fuzz/src/invoice_request_deser.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,13 @@ use bitcoin::secp256k1::{self, Keypair, Parity, PublicKey, Secp256k1, SecretKey}
use core::convert::TryFrom;
use lightning::blinded_path::payment::{
BlindedPaymentPath, Bolt12OfferContext, ForwardTlvs, PaymentConstraints, PaymentContext,
PaymentForwardNode, PaymentRelay, ReceiveTlvs,
PaymentForwardNode, PaymentRelay, UnauthenticatedReceiveTlvs,
};
use lightning::ln::channelmanager::MIN_FINAL_CLTV_EXPIRY_DELTA;
use lightning::ln::inbound_payment::ExpandedKey;
use lightning::offers::invoice::UnsignedBolt12Invoice;
use lightning::offers::invoice_request::{InvoiceRequest, InvoiceRequestFields};
use lightning::offers::nonce::Nonce;
use lightning::offers::offer::OfferId;
use lightning::offers::parse::Bolt12SemanticError;
use lightning::sign::EntropySource;
Expand Down Expand Up @@ -80,7 +82,9 @@ fn privkey(byte: u8) -> SecretKey {
fn build_response<T: secp256k1::Signing + secp256k1::Verification>(
invoice_request: &InvoiceRequest, secp_ctx: &Secp256k1<T>,
) -> Result<UnsignedBolt12Invoice, Bolt12SemanticError> {
let expanded_key = ExpandedKey::new([42; 32]);
let entropy_source = Randomness {};
let nonce = Nonce::from_entropy_source(&entropy_source);
let payment_context = PaymentContext::Bolt12Offer(Bolt12OfferContext {
offer_id: OfferId([42; 32]),
invoice_request: InvoiceRequestFields {
Expand All @@ -92,14 +96,15 @@ fn build_response<T: secp256k1::Signing + secp256k1::Verification>(
human_readable_name: None,
},
});
let payee_tlvs = ReceiveTlvs {
let payee_tlvs = UnauthenticatedReceiveTlvs {
payment_secret: PaymentSecret([42; 32]),
payment_constraints: PaymentConstraints {
max_cltv_expiry: 1_000_000,
htlc_minimum_msat: 1,
},
payment_context,
};
let payee_tlvs = payee_tlvs.authenticate(nonce, &expanded_key);
let intermediate_nodes = [PaymentForwardNode {
tlvs: ForwardTlvs {
short_channel_id: 43,
Expand All @@ -109,7 +114,7 @@ fn build_response<T: secp256k1::Signing + secp256k1::Verification>(
fee_base_msat: 1,
},
payment_constraints: PaymentConstraints {
max_cltv_expiry: payee_tlvs.payment_constraints.max_cltv_expiry + 40,
max_cltv_expiry: payee_tlvs.tlvs().payment_constraints.max_cltv_expiry + 40,
htlc_minimum_msat: 100,
},
features: BlindedHopFeatures::empty(),
Expand Down
4 changes: 2 additions & 2 deletions fuzz/src/offer_deser.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ use lightning::offers::invoice_request::InvoiceRequest;
use lightning::offers::nonce::Nonce;
use lightning::offers::offer::{Amount, Offer, Quantity};
use lightning::offers::parse::Bolt12SemanticError;
use lightning::sign::{EntropySource, KeyMaterial};
use lightning::sign::EntropySource;
use lightning::util::ser::Writeable;

#[inline]
Expand All @@ -43,7 +43,7 @@ impl EntropySource for FixedEntropy {
}

fn build_request(offer: &Offer) -> Result<InvoiceRequest, Bolt12SemanticError> {
let expanded_key = ExpandedKey::new(&KeyMaterial([42; 32]));
let expanded_key = ExpandedKey::new([42; 32]);
let entropy = FixedEntropy {};
let nonce = Nonce::from_entropy_source(&entropy);
let secp_ctx = Secp256k1::new();
Expand Down
5 changes: 3 additions & 2 deletions fuzz/src/onion_message.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ use lightning::blinded_path::message::{
AsyncPaymentsContext, BlindedMessagePath, MessageContext, OffersContext,
};
use lightning::blinded_path::EmptyNodeIdLookUp;
use lightning::ln::inbound_payment::ExpandedKey;
use lightning::ln::msgs::{self, DecodeError, OnionMessageHandler};
use lightning::ln::peer_handler::IgnoringMessageHandler;
use lightning::ln::script::ShutdownScript;
Expand All @@ -22,7 +23,7 @@ use lightning::onion_message::messenger::{
};
use lightning::onion_message::offers::{OffersMessage, OffersMessageHandler};
use lightning::onion_message::packet::OnionMessageContents;
use lightning::sign::{EntropySource, KeyMaterial, NodeSigner, Recipient, SignerProvider};
use lightning::sign::{EntropySource, NodeSigner, Recipient, SignerProvider};
use lightning::types::features::InitFeatures;
use lightning::util::logger::Logger;
use lightning::util::ser::{Readable, Writeable, Writer};
Expand Down Expand Up @@ -223,7 +224,7 @@ impl NodeSigner for KeyProvider {
Ok(SharedSecret::new(other_key, &node_secret))
}

fn get_inbound_payment_key_material(&self) -> KeyMaterial {
fn get_inbound_payment_key(&self) -> ExpandedKey {
unreachable!()
}

Expand Down
11 changes: 8 additions & 3 deletions fuzz/src/refund_deser.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,12 @@ use bitcoin::secp256k1::{self, Keypair, PublicKey, Secp256k1, SecretKey};
use core::convert::TryFrom;
use lightning::blinded_path::payment::{
BlindedPaymentPath, Bolt12RefundContext, ForwardTlvs, PaymentConstraints, PaymentContext,
PaymentForwardNode, PaymentRelay, ReceiveTlvs,
PaymentForwardNode, PaymentRelay, UnauthenticatedReceiveTlvs,
};
use lightning::ln::channelmanager::MIN_FINAL_CLTV_EXPIRY_DELTA;
use lightning::ln::inbound_payment::ExpandedKey;
use lightning::offers::invoice::UnsignedBolt12Invoice;
use lightning::offers::nonce::Nonce;
use lightning::offers::parse::Bolt12SemanticError;
use lightning::offers::refund::Refund;
use lightning::sign::EntropySource;
Expand Down Expand Up @@ -67,16 +69,19 @@ fn privkey(byte: u8) -> SecretKey {
fn build_response<T: secp256k1::Signing + secp256k1::Verification>(
refund: &Refund, signing_pubkey: PublicKey, secp_ctx: &Secp256k1<T>,
) -> Result<UnsignedBolt12Invoice, Bolt12SemanticError> {
let expanded_key = ExpandedKey::new([42; 32]);
let entropy_source = Randomness {};
let nonce = Nonce::from_entropy_source(&entropy_source);
let payment_context = PaymentContext::Bolt12Refund(Bolt12RefundContext {});
let payee_tlvs = ReceiveTlvs {
let payee_tlvs = UnauthenticatedReceiveTlvs {
payment_secret: PaymentSecret([42; 32]),
payment_constraints: PaymentConstraints {
max_cltv_expiry: 1_000_000,
htlc_minimum_msat: 1,
},
payment_context,
};
let payee_tlvs = payee_tlvs.authenticate(nonce, &expanded_key);
let intermediate_nodes = [PaymentForwardNode {
tlvs: ForwardTlvs {
short_channel_id: 43,
Expand All @@ -86,7 +91,7 @@ fn build_response<T: secp256k1::Signing + secp256k1::Verification>(
fee_base_msat: 1,
},
payment_constraints: PaymentConstraints {
max_cltv_expiry: payee_tlvs.payment_constraints.max_cltv_expiry + 40,
max_cltv_expiry: payee_tlvs.tlvs().payment_constraints.max_cltv_expiry + 40,
htlc_minimum_msat: 100,
},
features: BlindedHopFeatures::empty(),
Expand Down
1 change: 1 addition & 0 deletions lightning-invoice/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1086,6 +1086,7 @@ impl RawBolt11Invoice {

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

Self::hash_from_parts(self.hrp.to_string().as_bytes(), self.data.fe_iter())
Expand Down
Loading
Loading