Skip to content

Commit 13e75ac

Browse files
committed
HMAC construction and verification for PaymentID
When receiving an InvoiceError in response to an InvoiceRequest, the corresponding payment should be abandoned. Add functions for constructing and verifying an HMAC over a Payment ID to allow for this.
1 parent 8834336 commit 13e75ac

File tree

1 file changed

+22
-0
lines changed

1 file changed

+22
-0
lines changed

lightning/src/offers/signer.rs

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,9 @@ const DERIVED_METADATA_AND_KEYS_HMAC_INPUT: &[u8; 16] = &[2; 16];
3636
const WITHOUT_ENCRYPTED_PAYMENT_ID_HMAC_INPUT: &[u8; 16] = &[3; 16];
3737
const WITH_ENCRYPTED_PAYMENT_ID_HMAC_INPUT: &[u8; 16] = &[4; 16];
3838

39+
// HMAC input for a `PaymentId`. The HMAC is used in `OffersContext::OutboundPayment`.
40+
const PAYMENT_ID_HMAC_INPUT: &[u8; 16] = &[5; 16];
41+
3942
/// Message metadata which possibly is derived from [`MetadataMaterial`] such that it can be
4043
/// verified.
4144
#[derive(Clone)]
@@ -391,3 +394,22 @@ fn hmac_for_message<'a>(
391394

392395
Ok(hmac)
393396
}
397+
398+
pub(crate) fn hmac_for_payment_id(
399+
payment_id: PaymentId, nonce: Nonce, expanded_key: &ExpandedKey,
400+
) -> Hmac<Sha256> {
401+
const IV_BYTES: &[u8; IV_LEN] = b"LDK Payment ID ~";
402+
let mut hmac = expanded_key.hmac_for_offer();
403+
hmac.input(IV_BYTES);
404+
hmac.input(&nonce.0);
405+
hmac.input(PAYMENT_ID_HMAC_INPUT);
406+
hmac.input(&payment_id.0);
407+
408+
Hmac::from_engine(hmac)
409+
}
410+
411+
pub(crate) fn verify_payment_id(
412+
payment_id: PaymentId, hmac: Hmac<Sha256>, nonce: Nonce, expanded_key: &ExpandedKey,
413+
) -> bool {
414+
hmac_for_payment_id(payment_id, nonce, expanded_key) == hmac
415+
}

0 commit comments

Comments
 (0)