Add another ExpandedKey derivation for Offers
authorJeffrey Czyz <jkczyz@gmail.com>
Tue, 7 Feb 2023 21:25:36 +0000 (15:25 -0600)
committerJeffrey Czyz <jkczyz@gmail.com>
Tue, 18 Apr 2023 18:30:32 +0000 (13:30 -0500)
To support transient signing pubkeys and payer ids for Offers, add
another key derivation to ExpandedKey. Also useful for constructing
metadata for stateless message authentication.

lightning/src/ln/inbound_payment.rs
lightning/src/util/crypto.rs

index 0c6d6f2b804bccd8cfb651c24995bf4959998a91..058339cbc1d2451e385307fc0fa5dbc0bf96ab2a 100644 (file)
@@ -19,7 +19,7 @@ use crate::ln::{PaymentHash, PaymentPreimage, PaymentSecret};
 use crate::ln::msgs;
 use crate::ln::msgs::MAX_VALUE_MSAT;
 use crate::util::chacha20::ChaCha20;
-use crate::util::crypto::hkdf_extract_expand_thrice;
+use crate::util::crypto::hkdf_extract_expand_4x;
 use crate::util::errors::APIError;
 use crate::util::logger::Logger;
 
@@ -48,6 +48,8 @@ pub struct ExpandedKey {
        /// The key used to authenticate a user-provided payment hash and metadata as previously
        /// registered with LDK.
        user_pmt_hash_key: [u8; 32],
+       /// The base key used to derive signing keys and authenticate messages for BOLT 12 Offers.
+       offers_base_key: [u8; 32],
 }
 
 impl ExpandedKey {
@@ -55,12 +57,13 @@ impl ExpandedKey {
        ///
        /// It is recommended to cache this value and not regenerate it for each new inbound payment.
        pub fn new(key_material: &KeyMaterial) -> ExpandedKey {
-               let (metadata_key, ldk_pmt_hash_key, user_pmt_hash_key) =
-                       hkdf_extract_expand_thrice(b"LDK Inbound Payment Key Expansion", &key_material.0);
+               let (metadata_key, ldk_pmt_hash_key, user_pmt_hash_key, offers_base_key) =
+                       hkdf_extract_expand_4x(b"LDK Inbound Payment Key Expansion", &key_material.0);
                Self {
                        metadata_key,
                        ldk_pmt_hash_key,
                        user_pmt_hash_key,
+                       offers_base_key,
                }
        }
 }
index 2f2d33b29f7ea53c0a2dda084ac7a139583c6345..39dfd39b785b048535163756ddc417ff80009ed4 100644 (file)
@@ -20,13 +20,18 @@ macro_rules! hkdf_extract_expand {
                let (k1, k2, _) = hkdf_extract_expand!($salt, $ikm);
                (k1, k2)
        }};
-       ($salt: expr, $ikm: expr, 3) => {{
+       ($salt: expr, $ikm: expr, 4) => {{
                let (k1, k2, prk) = hkdf_extract_expand!($salt, $ikm);
 
                let mut hmac = HmacEngine::<Sha256>::new(&prk[..]);
                hmac.input(&k2);
                hmac.input(&[3; 1]);
-               (k1, k2, Hmac::from_engine(hmac).into_inner())
+               let k3 = Hmac::from_engine(hmac).into_inner();
+
+               let mut hmac = HmacEngine::<Sha256>::new(&prk[..]);
+               hmac.input(&k3);
+               hmac.input(&[4; 1]);
+               (k1, k2, k3, Hmac::from_engine(hmac).into_inner())
        }}
 }
 
@@ -34,8 +39,8 @@ pub fn hkdf_extract_expand_twice(salt: &[u8], ikm: &[u8]) -> ([u8; 32], [u8; 32]
        hkdf_extract_expand!(salt, ikm, 2)
 }
 
-pub fn hkdf_extract_expand_thrice(salt: &[u8], ikm: &[u8]) -> ([u8; 32], [u8; 32], [u8; 32]) {
-       hkdf_extract_expand!(salt, ikm, 3)
+pub fn hkdf_extract_expand_4x(salt: &[u8], ikm: &[u8]) -> ([u8; 32], [u8; 32], [u8; 32], [u8; 32]) {
+       hkdf_extract_expand!(salt, ikm, 4)
 }
 
 #[inline]