@@ -18,7 +18,8 @@ use crate::ln::types::{PaymentHash, PaymentPreimage, PaymentSecret};
18
18
use crate :: ln:: msgs;
19
19
use crate :: ln:: msgs:: MAX_VALUE_MSAT ;
20
20
use crate :: crypto:: chacha20:: ChaCha20 ;
21
- use crate :: crypto:: utils:: hkdf_extract_expand_5x;
21
+ use crate :: crypto:: chacha20poly1305rfc:: ChaCha20Poly1305RFC ;
22
+ use crate :: crypto:: utils:: { hkdf_extract_expand_5x, hkdf_extract_expand_twice} ;
22
23
use crate :: util:: errors:: APIError ;
23
24
use crate :: util:: logger:: Logger ;
24
25
@@ -53,6 +54,8 @@ pub struct ExpandedKey {
53
54
offers_base_key : [ u8 ; 32 ] ,
54
55
/// The key used to encrypt message metadata for BOLT 12 Offers.
55
56
offers_encryption_key : [ u8 ; 32 ] ,
57
+ /// The key used to encrypt our peer storage that would be sent to our peers.
58
+ our_peerstorage_encryption_key : [ u8 ; 32 ] ,
56
59
}
57
60
58
61
impl ExpandedKey {
@@ -67,12 +70,14 @@ impl ExpandedKey {
67
70
offers_base_key,
68
71
offers_encryption_key,
69
72
) = hkdf_extract_expand_5x ( b"LDK Inbound Payment Key Expansion" , & key_material. 0 ) ;
73
+ let ( our_peerstorage_encryption_key, _) = hkdf_extract_expand_twice ( b"Peer Storage Encryption Key" , & key_material. 0 ) ;
70
74
Self {
71
75
metadata_key,
72
76
ldk_pmt_hash_key,
73
77
user_pmt_hash_key,
74
78
offers_base_key,
75
79
offers_encryption_key,
80
+ our_peerstorage_encryption_key
76
81
}
77
82
}
78
83
@@ -94,6 +99,29 @@ impl ExpandedKey {
94
99
ChaCha20 :: encrypt_single_block_in_place ( & self . offers_encryption_key , & nonce. 0 , & mut bytes) ;
95
100
bytes
96
101
}
102
+
103
+ /// Encrypt given plaintext using [`ExpandedKey::our_peerstorage_encryption_key`].
104
+ pub ( crate ) fn encrypt_our_peer_storage ( & self , res : & mut [ u8 ] , n : u64 , h : & [ u8 ] , plaintext : & [ u8 ] ) {
105
+ let mut nonce = [ 0 ; 12 ] ;
106
+ nonce[ 4 ..] . copy_from_slice ( & n. to_le_bytes ( ) [ ..] ) ;
107
+
108
+ let mut chacha = ChaCha20Poly1305RFC :: new ( & self . our_peerstorage_encryption_key , & nonce, h) ;
109
+ let mut tag = [ 0 ; 16 ] ;
110
+ chacha. encrypt ( plaintext, & mut res[ 0 ..plaintext. len ( ) ] , & mut tag) ;
111
+ res[ plaintext. len ( ) ..] . copy_from_slice ( & tag) ;
112
+ }
113
+
114
+ /// Decrypt given cyphertext using [`ExpandedKey::our_peerstorage_encryption_key`].
115
+ pub ( crate ) fn decrypt_our_peer_storage ( & self , res : & mut [ u8 ] , n : u64 , h : & [ u8 ] , cyphertext : & [ u8 ] ) -> Result < ( ) , ( ) > {
116
+ let mut nonce = [ 0 ; 12 ] ;
117
+ nonce[ 4 ..] . copy_from_slice ( & n. to_le_bytes ( ) [ ..] ) ;
118
+
119
+ let mut chacha = ChaCha20Poly1305RFC :: new ( & self . our_peerstorage_encryption_key , & nonce, h) ;
120
+ if chacha. variable_time_decrypt ( & cyphertext[ 0 ..cyphertext. len ( ) - 16 ] , res, & cyphertext[ cyphertext. len ( ) - 16 ..] ) . is_err ( ) {
121
+ return Err ( ( ) ) ;
122
+ }
123
+ Ok ( ( ) )
124
+ }
97
125
}
98
126
99
127
/// A 128-bit number used only once.
0 commit comments