Skip to content

Commit

Permalink
Merge pull request #3435 from jkczyz/2024-12-hmac-payment-context
Browse files Browse the repository at this point in the history
Authenticate blinded payment paths
  • Loading branch information
TheBlueMatt authored Dec 13, 2024
2 parents 6e85a0d + d287bf0 commit 1a8bf62
Show file tree
Hide file tree
Showing 28 changed files with 406 additions and 222 deletions.
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

0 comments on commit 1a8bf62

Please sign in to comment.