Add payment hash to `MaybePreimageClaimableHTLC`
[rust-lightning] / lightning / src / ln / inbound_payment.rs
index 058339cbc1d2451e385307fc0fa5dbc0bf96ab2a..2d15876bf95ccad75fb90233b135ffd0fabd17ad 100644 (file)
@@ -23,10 +23,10 @@ use crate::util::crypto::hkdf_extract_expand_4x;
 use crate::util::errors::APIError;
 use crate::util::logger::Logger;
 
-use core::convert::TryInto;
+use core::convert::{TryFrom, TryInto};
 use core::ops::Deref;
 
-const IV_LEN: usize = 16;
+pub(crate) const IV_LEN: usize = 16;
 const METADATA_LEN: usize = 16;
 const METADATA_KEY_LEN: usize = 32;
 const AMT_MSAT_LEN: usize = 8;
@@ -66,6 +66,67 @@ impl ExpandedKey {
                        offers_base_key,
                }
        }
+
+       /// Returns an [`HmacEngine`] used to construct [`Offer::metadata`].
+       ///
+       /// [`Offer::metadata`]: crate::offers::offer::Offer::metadata
+       #[allow(unused)]
+       pub(crate) fn hmac_for_offer(
+               &self, nonce: Nonce, iv_bytes: &[u8; IV_LEN]
+       ) -> HmacEngine<Sha256> {
+               let mut hmac = HmacEngine::<Sha256>::new(&self.offers_base_key);
+               hmac.input(iv_bytes);
+               hmac.input(&nonce.0);
+               hmac
+       }
+}
+
+/// A 128-bit number used only once.
+///
+/// Needed when constructing [`Offer::metadata`] and deriving [`Offer::signing_pubkey`] from
+/// [`ExpandedKey`]. Must not be reused for any other derivation without first hashing.
+///
+/// [`Offer::metadata`]: crate::offers::offer::Offer::metadata
+/// [`Offer::signing_pubkey`]: crate::offers::offer::Offer::signing_pubkey
+#[allow(unused)]
+#[derive(Clone, Copy, Debug, PartialEq)]
+pub(crate) struct Nonce(pub(crate) [u8; Self::LENGTH]);
+
+impl Nonce {
+       /// Number of bytes in the nonce.
+       pub const LENGTH: usize = 16;
+
+       /// Creates a `Nonce` from the given [`EntropySource`].
+       pub fn from_entropy_source<ES: Deref>(entropy_source: ES) -> Self
+       where
+               ES::Target: EntropySource,
+       {
+               let mut bytes = [0u8; Self::LENGTH];
+               let rand_bytes = entropy_source.get_secure_random_bytes();
+               bytes.copy_from_slice(&rand_bytes[..Self::LENGTH]);
+
+               Nonce(bytes)
+       }
+
+       /// Returns a slice of the underlying bytes of size [`Nonce::LENGTH`].
+       pub fn as_slice(&self) -> &[u8] {
+               &self.0
+       }
+}
+
+impl TryFrom<&[u8]> for Nonce {
+       type Error = ();
+
+       fn try_from(bytes: &[u8]) -> Result<Self, ()> {
+               if bytes.len() != Self::LENGTH {
+                       return Err(());
+               }
+
+               let mut copied_bytes = [0u8; Self::LENGTH];
+               copied_bytes.copy_from_slice(bytes);
+
+               Ok(Self(copied_bytes))
+       }
 }
 
 enum Method {