use crate::ln::msgs;
use crate::ln::msgs::MAX_VALUE_MSAT;
use crate::util::chacha20::ChaCha20;
-use crate::util::crypto::hkdf_extract_expand_4x;
+use crate::util::crypto::hkdf_extract_expand_5x;
use crate::util::errors::APIError;
use crate::util::logger::Logger;
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],
+ /// The key used to encrypt message metadata for BOLT 12 Offers.
+ offers_encryption_key: [u8; 32],
}
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, offers_base_key) =
- hkdf_extract_expand_4x(b"LDK Inbound Payment Key Expansion", &key_material.0);
+ let (
+ metadata_key,
+ ldk_pmt_hash_key,
+ user_pmt_hash_key,
+ offers_base_key,
+ offers_encryption_key,
+ ) = hkdf_extract_expand_5x(b"LDK Inbound Payment Key Expansion", &key_material.0);
Self {
metadata_key,
ldk_pmt_hash_key,
user_pmt_hash_key,
offers_base_key,
+ offers_encryption_key,
}
}
hmac.input(&nonce.0);
hmac
}
+
+ /// Encrypts or decrypts the given `bytes`. Used for data included in an offer message's
+ /// metadata (e.g., payment id).
+ pub(crate) fn crypt_for_offer(&self, mut bytes: [u8; 32], nonce: Nonce) -> [u8; 32] {
+ ChaCha20::encrypt_single_block_in_place(&self.offers_encryption_key, &nonce.0, &mut bytes);
+ bytes
+ }
}
/// A 128-bit number used only once.
let (iv_slice, encrypted_metadata_slice) = payment_secret_bytes.split_at_mut(IV_LEN);
iv_slice.copy_from_slice(iv_bytes);
- let chacha_block = ChaCha20::get_single_block(metadata_key, iv_bytes);
- for i in 0..METADATA_LEN {
- encrypted_metadata_slice[i] = chacha_block[i] ^ metadata_bytes[i];
- }
+ ChaCha20::encrypt_single_block(
+ metadata_key, iv_bytes, encrypted_metadata_slice, metadata_bytes
+ );
PaymentSecret(payment_secret_bytes)
}
let (iv_slice, encrypted_metadata_bytes) = payment_secret.0.split_at(IV_LEN);
iv_bytes.copy_from_slice(iv_slice);
- let chacha_block = ChaCha20::get_single_block(&keys.metadata_key, &iv_bytes);
let mut metadata_bytes: [u8; METADATA_LEN] = [0; METADATA_LEN];
- for i in 0..METADATA_LEN {
- metadata_bytes[i] = chacha_block[i] ^ encrypted_metadata_bytes[i];
- }
+ ChaCha20::encrypt_single_block(
+ &keys.metadata_key, &iv_bytes, &mut metadata_bytes, encrypted_metadata_bytes
+ );
(iv_bytes, metadata_bytes)
}