Skip to content

Commit 8849efe

Browse files
committed
Delay adding iv_bytes to MetadataMaterial::hmac
In an upcoming commit, the iv_bytes used in MetadataMaterial will vary depending on when whether a blinded path is included in the corresponding message. Delay adding into MetadataMaterial::hmac as otherwise the HmacEngine would need to be re-initialized using an ExpandedKey, which won't be readily available.
1 parent 4a69f58 commit 8849efe

File tree

5 files changed

+39
-32
lines changed

5 files changed

+39
-32
lines changed

lightning/src/ln/inbound_payment.rs

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -81,13 +81,8 @@ impl ExpandedKey {
8181
/// Returns an [`HmacEngine`] used to construct [`Offer::metadata`].
8282
///
8383
/// [`Offer::metadata`]: crate::offers::offer::Offer::metadata
84-
pub(crate) fn hmac_for_offer(
85-
&self, nonce: Nonce, iv_bytes: &[u8; IV_LEN]
86-
) -> HmacEngine<Sha256> {
87-
let mut hmac = HmacEngine::<Sha256>::new(&self.offers_base_key);
88-
hmac.input(iv_bytes);
89-
hmac.input(&nonce.0);
90-
hmac
84+
pub(crate) fn hmac_for_offer(&self) -> HmacEngine<Sha256> {
85+
HmacEngine::<Sha256>::new(&self.offers_base_key)
9186
}
9287

9388
/// Encrypts or decrypts the given `bytes`. Used for data included in an offer message's

lightning/src/offers/invoice_request.rs

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -174,7 +174,7 @@ macro_rules! invoice_request_explicit_payer_id_builder_methods { ($self: ident,
174174
payment_id: PaymentId,
175175
) -> Self {
176176
let payment_id = Some(payment_id);
177-
let derivation_material = MetadataMaterial::new(nonce, expanded_key, IV_BYTES, payment_id);
177+
let derivation_material = MetadataMaterial::new(nonce, expanded_key, payment_id);
178178
let metadata = Metadata::Derived(derivation_material);
179179
Self {
180180
offer,
@@ -203,7 +203,7 @@ macro_rules! invoice_request_derived_payer_id_builder_methods { (
203203
secp_ctx: &'b Secp256k1<$secp_context>, payment_id: PaymentId
204204
) -> Self {
205205
let payment_id = Some(payment_id);
206-
let derivation_material = MetadataMaterial::new(nonce, expanded_key, IV_BYTES, payment_id);
206+
let derivation_material = MetadataMaterial::new(nonce, expanded_key, payment_id);
207207
let metadata = Metadata::DerivedSigningPubkey(derivation_material);
208208
Self {
209209
offer,
@@ -346,7 +346,8 @@ macro_rules! invoice_request_builder_methods { (
346346
tlv_stream.2.payer_id = $self.payer_id.as_ref();
347347
}
348348

349-
let (derived_metadata, derived_keys) = metadata.derive_from(tlv_stream, $self.secp_ctx);
349+
let (derived_metadata, derived_keys) =
350+
metadata.derive_from(IV_BYTES, tlv_stream, $self.secp_ctx);
350351
metadata = derived_metadata;
351352
keys = derived_keys;
352353
if let Some(keys) = keys {

lightning/src/offers/offer.rs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -258,7 +258,7 @@ macro_rules! offer_derived_metadata_builder_methods { ($secp_context: ty) => {
258258
node_id: PublicKey, expanded_key: &ExpandedKey, nonce: Nonce,
259259
secp_ctx: &'a Secp256k1<$secp_context>
260260
) -> Self {
261-
let derivation_material = MetadataMaterial::new(nonce, expanded_key, IV_BYTES, None);
261+
let derivation_material = MetadataMaterial::new(nonce, expanded_key, None);
262262
let metadata = Metadata::DerivedSigningPubkey(derivation_material);
263263
Self {
264264
offer: OfferContents {
@@ -405,7 +405,8 @@ macro_rules! offer_builder_methods { (
405405
// Either replace the signing pubkey with the derived pubkey or include the metadata
406406
// for verification. In the former case, the blinded paths must include
407407
// `OffersContext::InvoiceRequest` instead.
408-
let (derived_metadata, keys) = metadata.derive_from(tlv_stream, $self.secp_ctx);
408+
let (derived_metadata, keys) =
409+
metadata.derive_from(IV_BYTES, tlv_stream, $self.secp_ctx);
409410
match keys {
410411
Some(keys) => $self.offer.signing_pubkey = Some(keys.public_key()),
411412
None => $self.offer.metadata = Some(derived_metadata),

lightning/src/offers/refund.rs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -210,7 +210,7 @@ macro_rules! refund_builder_methods { (
210210
}
211211

212212
let payment_id = Some(payment_id);
213-
let derivation_material = MetadataMaterial::new(nonce, expanded_key, IV_BYTES, payment_id);
213+
let derivation_material = MetadataMaterial::new(nonce, expanded_key, payment_id);
214214
let metadata = Metadata::DerivedSigningPubkey(derivation_material);
215215
Ok(Self {
216216
refund: RefundContents {
@@ -316,7 +316,8 @@ macro_rules! refund_builder_methods { (
316316
tlv_stream.2.payer_id = None;
317317
}
318318

319-
let (derived_metadata, keys) = metadata.derive_from(tlv_stream, $self.secp_ctx);
319+
let (derived_metadata, keys) =
320+
metadata.derive_from(IV_BYTES, tlv_stream, $self.secp_ctx);
320321
metadata = derived_metadata;
321322
if let Some(keys) = keys {
322323
$self.refund.payer_id = keys.public_key();

lightning/src/offers/signer.rs

Lines changed: 27 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -140,20 +140,19 @@ impl Metadata {
140140
}
141141

142142
pub fn derive_from<W: Writeable, T: secp256k1::Signing>(
143-
self, tlv_stream: W, secp_ctx: Option<&Secp256k1<T>>
143+
self, iv_bytes: &[u8; IV_LEN], tlv_stream: W, secp_ctx: Option<&Secp256k1<T>>
144144
) -> (Self, Option<Keypair>) {
145145
match self {
146146
Metadata::Bytes(_) => (self, None),
147147
Metadata::RecipientData(_) => { debug_assert!(false); (self, None) },
148148
Metadata::PayerData(_) => { debug_assert!(false); (self, None) },
149-
Metadata::Derived(mut metadata_material) => {
150-
tlv_stream.write(&mut metadata_material.hmac).unwrap();
151-
(Metadata::Bytes(metadata_material.derive_metadata()), None)
149+
Metadata::Derived(metadata_material) => {
150+
(Metadata::Bytes(metadata_material.derive_metadata(iv_bytes, tlv_stream)), None)
152151
},
153-
Metadata::DerivedSigningPubkey(mut metadata_material) => {
154-
tlv_stream.write(&mut metadata_material.hmac).unwrap();
152+
Metadata::DerivedSigningPubkey(metadata_material) => {
155153
let secp_ctx = secp_ctx.unwrap();
156-
let (metadata, keys) = metadata_material.derive_metadata_and_keys(secp_ctx);
154+
let (metadata, keys) =
155+
metadata_material.derive_metadata_and_keys(iv_bytes, tlv_stream, secp_ctx);
157156
(Metadata::Bytes(metadata), Some(keys))
158157
},
159158
}
@@ -217,23 +216,24 @@ pub(super) struct MetadataMaterial {
217216
}
218217

219218
impl MetadataMaterial {
220-
pub fn new(
221-
nonce: Nonce, expanded_key: &ExpandedKey, iv_bytes: &[u8; IV_LEN],
222-
payment_id: Option<PaymentId>
223-
) -> Self {
219+
pub fn new(nonce: Nonce, expanded_key: &ExpandedKey, payment_id: Option<PaymentId>) -> Self {
224220
// Encrypt payment_id
225221
let encrypted_payment_id = payment_id.map(|payment_id| {
226222
expanded_key.crypt_for_offer(payment_id.0, nonce)
227223
});
228224

229225
Self {
230226
nonce,
231-
hmac: expanded_key.hmac_for_offer(nonce, iv_bytes),
227+
hmac: expanded_key.hmac_for_offer(),
232228
encrypted_payment_id,
233229
}
234230
}
235231

236-
fn derive_metadata(mut self) -> Vec<u8> {
232+
fn derive_metadata<W: Writeable>(mut self, iv_bytes: &[u8; IV_LEN], tlv_stream: W) -> Vec<u8> {
233+
self.hmac.input(iv_bytes);
234+
self.hmac.input(&self.nonce.0);
235+
tlv_stream.write(&mut self.hmac).unwrap();
236+
237237
self.hmac.input(DERIVED_METADATA_HMAC_INPUT);
238238
self.maybe_include_encrypted_payment_id();
239239

@@ -243,9 +243,13 @@ impl MetadataMaterial {
243243
bytes
244244
}
245245

246-
fn derive_metadata_and_keys<T: secp256k1::Signing>(
247-
mut self, secp_ctx: &Secp256k1<T>
246+
fn derive_metadata_and_keys<W: Writeable, T: secp256k1::Signing>(
247+
mut self, iv_bytes: &[u8; IV_LEN], tlv_stream: W, secp_ctx: &Secp256k1<T>
248248
) -> (Vec<u8>, Keypair) {
249+
self.hmac.input(iv_bytes);
250+
self.hmac.input(&self.nonce.0);
251+
tlv_stream.write(&mut self.hmac).unwrap();
252+
249253
self.hmac.input(DERIVED_METADATA_AND_KEYS_HMAC_INPUT);
250254
self.maybe_include_encrypted_payment_id();
251255

@@ -271,9 +275,12 @@ impl MetadataMaterial {
271275

272276
pub(super) fn derive_keys(nonce: Nonce, expanded_key: &ExpandedKey) -> Keypair {
273277
const IV_BYTES: &[u8; IV_LEN] = b"LDK Invoice ~~~~";
278+
let mut hmac = expanded_key.hmac_for_offer();
279+
hmac.input(IV_BYTES);
280+
hmac.input(&nonce.0);
281+
274282
let secp_ctx = Secp256k1::new();
275-
let hmac = Hmac::from_engine(expanded_key.hmac_for_offer(nonce, IV_BYTES));
276-
let privkey = SecretKey::from_slice(hmac.as_byte_array()).unwrap();
283+
let privkey = SecretKey::from_slice(Hmac::from_engine(hmac).as_byte_array()).unwrap();
277284
Keypair::from_secret_key(&secp_ctx, &privkey)
278285
}
279286

@@ -368,7 +375,9 @@ fn hmac_for_message<'a>(
368375
Ok(nonce) => nonce,
369376
Err(_) => return Err(()),
370377
};
371-
let mut hmac = expanded_key.hmac_for_offer(nonce, iv_bytes);
378+
let mut hmac = expanded_key.hmac_for_offer();
379+
hmac.input(iv_bytes);
380+
hmac.input(&nonce.0);
372381

373382
for record in tlv_stream {
374383
hmac.input(record.record_bytes);

0 commit comments

Comments
 (0)