Skip to content

Commit d734ad8

Browse files
inbound_payment: DRY verify method for use in getting preimage
in the next commit(s)
1 parent d20239b commit d734ad8

File tree

1 file changed

+34
-17
lines changed

1 file changed

+34
-17
lines changed

lightning/src/ln/channelmanager.rs

+34-17
Original file line numberDiff line numberDiff line change
@@ -237,15 +237,7 @@ mod inbound_payment {
237237
pub(super) fn verify<L: Deref>(payment_hash: PaymentHash, payment_data: msgs::FinalOnionHopData, highest_seen_timestamp: u64, keys: &ExpandedKey, logger: &L) -> Result<Option<PaymentPreimage>, ()>
238238
where L::Target: Logger
239239
{
240-
let mut iv_bytes = [0; IV_LEN];
241-
let (iv_slice, encrypted_metadata_bytes) = payment_data.payment_secret.0.split_at(IV_LEN);
242-
iv_bytes.copy_from_slice(iv_slice);
243-
244-
let chacha_block = ChaCha20::get_single_block(&keys.metadata_key, &iv_bytes);
245-
let mut metadata_bytes: [u8; METADATA_LEN] = [0; METADATA_LEN];
246-
for i in 0..METADATA_LEN {
247-
metadata_bytes[i] = chacha_block[i] ^ encrypted_metadata_bytes[i];
248-
}
240+
let (iv_bytes, metadata_bytes) = decrypt_metadata(payment_data.payment_secret, keys);
249241

250242
let payment_type_res = Method::from_bits((metadata_bytes[0] & 0b1110_0000) >> METHOD_TYPE_OFFSET);
251243
let mut amt_msat_bytes = [0; AMT_MSAT_LEN];
@@ -269,15 +261,13 @@ mod inbound_payment {
269261
}
270262
},
271263
Ok(Method::LdkPaymentHash) => {
272-
let mut hmac = HmacEngine::<Sha256>::new(&keys.ldk_pmt_hash_key);
273-
hmac.input(&iv_bytes);
274-
hmac.input(&metadata_bytes);
275-
let decoded_payment_preimage = Hmac::from_engine(hmac).into_inner();
276-
if !fixed_time_eq(&payment_hash.0, &Sha256::hash(&decoded_payment_preimage).into_inner()) {
277-
log_trace!(logger, "Failing HTLC with payment_hash {}: payment preimage {} did not match", log_bytes!(payment_hash.0), log_bytes!(decoded_payment_preimage));
278-
return Err(())
264+
match derive_ldk_payment_preimage(payment_hash, &iv_bytes, &metadata_bytes, keys) {
265+
Ok(preimage) => payment_preimage = Some(preimage),
266+
Err(bad_preimage_bytes) => {
267+
log_trace!(logger, "Failing HTLC with payment_hash {} due to mismatching preimage {}", log_bytes!(payment_hash.0), log_bytes!(bad_preimage_bytes));
268+
return Err(())
269+
}
279270
}
280-
payment_preimage = Some(PaymentPreimage(decoded_payment_preimage));
281271
},
282272
Err(unknown_bits) => {
283273
log_trace!(logger, "Failing HTLC with payment hash {} due to unknown payment type {}", log_bytes!(payment_hash.0), unknown_bits);
@@ -298,6 +288,33 @@ mod inbound_payment {
298288
Ok(payment_preimage)
299289
}
300290

291+
fn decrypt_metadata(payment_secret: PaymentSecret, keys: &ExpandedKey) -> ([u8; IV_LEN], [u8; METADATA_LEN]) {
292+
let mut iv_bytes = [0; IV_LEN];
293+
let (iv_slice, encrypted_metadata_bytes) = payment_secret.0.split_at(IV_LEN);
294+
iv_bytes.copy_from_slice(iv_slice);
295+
296+
let chacha_block = ChaCha20::get_single_block(&keys.metadata_key, &iv_bytes);
297+
let mut metadata_bytes: [u8; METADATA_LEN] = [0; METADATA_LEN];
298+
for i in 0..METADATA_LEN {
299+
metadata_bytes[i] = chacha_block[i] ^ encrypted_metadata_bytes[i];
300+
}
301+
302+
(iv_bytes, metadata_bytes)
303+
}
304+
305+
// Errors if the payment preimage doesn't match `payment_hash`. Returns the bad preimage bytes in
306+
// this case.
307+
fn derive_ldk_payment_preimage(payment_hash: PaymentHash, iv_bytes: &[u8; IV_LEN], metadata_bytes: &[u8; METADATA_LEN], keys: &ExpandedKey) -> Result<PaymentPreimage, [u8; 32]> {
308+
let mut hmac = HmacEngine::<Sha256>::new(&keys.ldk_pmt_hash_key);
309+
hmac.input(iv_bytes);
310+
hmac.input(metadata_bytes);
311+
let decoded_payment_preimage = Hmac::from_engine(hmac).into_inner();
312+
if !fixed_time_eq(&payment_hash.0, &Sha256::hash(&decoded_payment_preimage).into_inner()) {
313+
return Err(decoded_payment_preimage);
314+
}
315+
return Ok(PaymentPreimage(decoded_payment_preimage))
316+
}
317+
301318
fn hkdf_extract_expand(salt: &[u8], ikm: &KeyMaterial) -> ExpandedKey {
302319
let mut hmac = HmacEngine::<Sha256>::new(salt);
303320
hmac.input(&ikm.0);

0 commit comments

Comments
 (0)