Skip to content

Commit c41ae8d

Browse files
DRY shared hkdf_extract_expand code to new module
1 parent 437a10b commit c41ae8d

File tree

3 files changed

+44
-53
lines changed

3 files changed

+44
-53
lines changed

lightning/src/ln/channelmanager.rs

Lines changed: 7 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,7 @@ mod inbound_payment {
8181
use ln::msgs;
8282
use ln::msgs::MAX_VALUE_MSAT;
8383
use util::chacha20::ChaCha20;
84+
use util::crypto::hkdf_extract_expand;
8485
use util::logger::Logger;
8586

8687
use core::convert::TryInto;
@@ -112,7 +113,12 @@ mod inbound_payment {
112113

113114
impl ExpandedKey {
114115
pub(super) fn new(key_material: &KeyMaterial) -> ExpandedKey {
115-
hkdf_extract_expand(b"LDK Inbound Payment Key Expansion", &key_material)
116+
let keys = hkdf_extract_expand(b"LDK Inbound Payment Key Expansion", &key_material.0, 3);
117+
Self {
118+
metadata_key: keys[0],
119+
ldk_pmt_hash_key: keys[1],
120+
user_pmt_hash_key: keys[2],
121+
}
116122
}
117123
}
118124

@@ -330,31 +336,6 @@ mod inbound_payment {
330336
}
331337
return Ok(PaymentPreimage(decoded_payment_preimage))
332338
}
333-
334-
fn hkdf_extract_expand(salt: &[u8], ikm: &KeyMaterial) -> ExpandedKey {
335-
let mut hmac = HmacEngine::<Sha256>::new(salt);
336-
hmac.input(&ikm.0);
337-
let prk = Hmac::from_engine(hmac).into_inner();
338-
let mut hmac = HmacEngine::<Sha256>::new(&prk[..]);
339-
hmac.input(&[1; 1]);
340-
let metadata_key = Hmac::from_engine(hmac).into_inner();
341-
342-
let mut hmac = HmacEngine::<Sha256>::new(&prk[..]);
343-
hmac.input(&metadata_key);
344-
hmac.input(&[2; 1]);
345-
let ldk_pmt_hash_key = Hmac::from_engine(hmac).into_inner();
346-
347-
let mut hmac = HmacEngine::<Sha256>::new(&prk[..]);
348-
hmac.input(&ldk_pmt_hash_key);
349-
hmac.input(&[3; 1]);
350-
let user_pmt_hash_key = Hmac::from_engine(hmac).into_inner();
351-
352-
ExpandedKey {
353-
metadata_key,
354-
ldk_pmt_hash_key,
355-
user_pmt_hash_key,
356-
}
357-
}
358339
}
359340

360341
// We hold various information about HTLC relay in the HTLC objects in Channel itself:

lightning/src/ln/peer_channel_encryptor.rs

Lines changed: 15 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ use prelude::*;
1212
use ln::msgs::LightningError;
1313
use ln::msgs;
1414

15-
use bitcoin::hashes::{Hash, HashEngine, Hmac, HmacEngine};
15+
use bitcoin::hashes::{Hash, HashEngine};
1616
use bitcoin::hashes::sha256::Hash as Sha256;
1717

1818
use bitcoin::secp256k1::Secp256k1;
@@ -21,6 +21,7 @@ use bitcoin::secp256k1::ecdh::SharedSecret;
2121
use bitcoin::secp256k1;
2222

2323
use util::chacha20poly1305rfc::ChaCha20Poly1305RFC;
24+
use util::crypto::hkdf_extract_expand;
2425
use bitcoin::hashes::hex::ToHex;
2526

2627
/// Maximum Lightning message data length according to
@@ -160,24 +161,11 @@ impl PeerChannelEncryptor {
160161
Ok(())
161162
}
162163

163-
fn hkdf_extract_expand(salt: &[u8], ikm: &[u8]) -> ([u8; 32], [u8; 32]) {
164-
let mut hmac = HmacEngine::<Sha256>::new(salt);
165-
hmac.input(ikm);
166-
let prk = Hmac::from_engine(hmac).into_inner();
167-
let mut hmac = HmacEngine::<Sha256>::new(&prk[..]);
168-
hmac.input(&[1; 1]);
169-
let t1 = Hmac::from_engine(hmac).into_inner();
170-
let mut hmac = HmacEngine::<Sha256>::new(&prk[..]);
171-
hmac.input(&t1);
172-
hmac.input(&[2; 1]);
173-
(t1, Hmac::from_engine(hmac).into_inner())
174-
}
175-
176164
#[inline]
177165
fn hkdf(state: &mut BidirectionalNoiseState, ss: SharedSecret) -> [u8; 32] {
178-
let (t1, t2) = Self::hkdf_extract_expand(&state.ck, &ss[..]);
179-
state.ck = t1;
180-
t2
166+
let hkdf = hkdf_extract_expand(&state.ck, &ss[..], 2);
167+
state.ck = hkdf[0];
168+
hkdf[1]
181169
}
182170

183171
#[inline]
@@ -311,7 +299,7 @@ impl PeerChannelEncryptor {
311299
let temp_k = PeerChannelEncryptor::hkdf(bidirectional_state, ss);
312300

313301
PeerChannelEncryptor::encrypt_with_ad(&mut res[50..], 0, &temp_k, &bidirectional_state.h, &[0; 0]);
314-
final_hkdf = Self::hkdf_extract_expand(&bidirectional_state.ck, &[0; 0]);
302+
final_hkdf = hkdf_extract_expand(&bidirectional_state.ck, &[0; 0], 2);
315303
ck = bidirectional_state.ck.clone();
316304
res
317305
},
@@ -320,7 +308,7 @@ impl PeerChannelEncryptor {
320308
_ => panic!("Cannot get act one after noise handshake completes"),
321309
};
322310

323-
let (sk, rk) = final_hkdf;
311+
let (sk, rk) = (final_hkdf[0], final_hkdf[1]);
324312
self.noise_state = NoiseState::Finished {
325313
sk,
326314
sn: 0,
@@ -365,15 +353,15 @@ impl PeerChannelEncryptor {
365353
let temp_k = PeerChannelEncryptor::hkdf(bidirectional_state, ss);
366354

367355
PeerChannelEncryptor::decrypt_with_ad(&mut [0; 0], 0, &temp_k, &bidirectional_state.h, &act_three[50..])?;
368-
final_hkdf = Self::hkdf_extract_expand(&bidirectional_state.ck, &[0; 0]);
356+
final_hkdf = hkdf_extract_expand(&bidirectional_state.ck, &[0; 0], 2);
369357
ck = bidirectional_state.ck.clone();
370358
},
371359
_ => panic!("Wrong direction for act"),
372360
},
373361
_ => panic!("Cannot get act one after noise handshake completes"),
374362
}
375363

376-
let (rk, sk) = final_hkdf;
364+
let (rk, sk) = (final_hkdf[0], final_hkdf[1]);
377365
self.noise_state = NoiseState::Finished {
378366
sk,
379367
sn: 0,
@@ -399,9 +387,9 @@ impl PeerChannelEncryptor {
399387
match self.noise_state {
400388
NoiseState::Finished { ref mut sk, ref mut sn, ref mut sck, rk: _, rn: _, rck: _ } => {
401389
if *sn >= 1000 {
402-
let (new_sck, new_sk) = Self::hkdf_extract_expand(sck, sk);
403-
*sck = new_sck;
404-
*sk = new_sk;
390+
let hkdf = hkdf_extract_expand(sck, sk, 2);
391+
*sck = hkdf[0];
392+
*sk = hkdf[1];
405393
*sn = 0;
406394
}
407395

@@ -425,9 +413,9 @@ impl PeerChannelEncryptor {
425413
match self.noise_state {
426414
NoiseState::Finished { sk: _, sn: _, sck: _, ref mut rk, ref mut rn, ref mut rck } => {
427415
if *rn >= 1000 {
428-
let (new_rck, new_rk) = Self::hkdf_extract_expand(rck, rk);
429-
*rck = new_rck;
430-
*rk = new_rk;
416+
let hkdf = hkdf_extract_expand(rck, rk, 2);
417+
*rck = hkdf[0];
418+
*rk = hkdf[1];
431419
*rn = 0;
432420
}
433421

lightning/src/util/mod.rs

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,3 +48,25 @@ pub mod test_utils;
4848
/// machine errors and used in fuzz targets and tests.
4949
#[cfg(any(test, feature = "fuzztarget", feature = "_test_utils"))]
5050
pub mod enforcing_trait_impls;
51+
52+
pub(crate) mod crypto {
53+
use bitcoin::hashes::{Hash, HashEngine};
54+
use bitcoin::hashes::hmac::{Hmac, HmacEngine};
55+
use bitcoin::hashes::sha256::Hash as Sha256;
56+
57+
pub fn hkdf_extract_expand(salt: &[u8], ikm: &[u8], num_keys: u8) -> Vec<[u8; 32]> {
58+
let mut keys_res: Vec<[u8; 32]> = Vec::new();
59+
let mut hmac = HmacEngine::<Sha256>::new(salt);
60+
hmac.input(ikm);
61+
let prk = Hmac::from_engine(hmac).into_inner();
62+
for i in 0..num_keys {
63+
let mut hmac = HmacEngine::<Sha256>::new(&prk[..]);
64+
if i != 0 {
65+
hmac.input(&keys_res[keys_res.len() - 1]);
66+
}
67+
hmac.input(&[i + 1; 1]);
68+
keys_res.push(Hmac::from_engine(hmac).into_inner());
69+
}
70+
keys_res
71+
}
72+
}

0 commit comments

Comments
 (0)