77// You may not use this file except in accordance with one or both of these
88// licenses.
99
10- //! `OurPeerStorage ` enables storage of encrypted serialized channel data.
11- //! It provides encryption and decryption of data to maintain data integrity and
10+ //! `DecryptedOurPeerStorage ` enables storage of encrypted serialized channel data.
11+ //! It provides encryption of data to maintain data integrity and
1212//! security during transmission.
13- //!
1413
1514use bitcoin:: hashes:: sha256:: Hash as Sha256 ;
1615use bitcoin:: hashes:: { Hash , HashEngine , Hmac , HmacEngine } ;
@@ -20,113 +19,111 @@ use crate::sign::PeerStorageKey;
2019use crate :: crypto:: chacha20poly1305rfc:: ChaCha20Poly1305RFC ;
2120use crate :: prelude:: * ;
2221
23- /// [`OurPeerStorage `] is used to store encrypted channel information that allows for the creation of a
22+ /// [`DecryptedOurPeerStorage `] is used to store serialised channel information that allows for the creation of a
2423/// `peer_storage` backup.
2524///
2625/// This structure is designed to serialize channel data for backup and supports encryption
27- /// and decryption using `ChaCha20Poly1305RFC` for transmission.
26+ /// using `ChaCha20Poly1305RFC` for transmission.
2827///
2928/// # Key Methods
30- /// - [`OurPeerStorage ::new`]: Returns [`OurPeerStorage `] with the given encrypted_data .
31- /// - [`OurPeerStorage::create_from_data `]: Returns [`OurPeerStorage `] created from encrypting the provided data.
32- /// - [`OurPeerStorage::decrypt_our_peer_storage `]: Decrypts the [`OurPeerStorage::encrypted_data `] using the key and returns decrypted data .
29+ /// - [`DecryptedOurPeerStorage ::new`]: Returns [`DecryptedOurPeerStorage `] with the given data .
30+ /// - [`DecryptedOurPeerStorage::encrypt `]: Returns [`EncryptedOurPeerStorage `] created from encrypting the provided data.
31+ /// - [`DecryptedOurPeerStorage::into_vec `]: Returns the data in [`Vec<u8> `] format .
3332///
3433/// ## Example
3534/// ```
36- /// use lightning::ln::our_peer_storage::OurPeerStorage ;
35+ /// use lightning::ln::our_peer_storage::DecryptedOurPeerStorage ;
3736/// use lightning::sign::PeerStorageKey;
3837/// let key = PeerStorageKey{inner: [0u8; 32]};
39- /// let decrypted_ops = OurPeerStorage::DecryptedPeerStorage { data: vec![1, 2, 3]} ;
40- /// let our_peer_storage = decrypted_ops.encrypt_peer_storage (&key, [0u8; 32]);
41- /// let decrypted_data = our_peer_storage.decrypt_peer_storage (&key).unwrap();
38+ /// let decrypted_ops = DecryptedOurPeerStorage::new( vec![1, 2, 3]) ;
39+ /// let our_peer_storage = decrypted_ops.encrypt (&key, [0u8; 32]);
40+ /// let decrypted_data = our_peer_storage.decrypt (&key).unwrap();
4241/// assert_eq!(decrypted_data.into_vec(), vec![1, 2, 3]);
4342/// ```
44- #[ derive( PartialEq , Eq , Debug ) ]
45- pub enum OurPeerStorage {
46- /// Contains ciphertext for transmission.
47- EncryptedPeerStorage {
48- /// Stores ciphertext.
49- cipher : Vec < u8 > ,
50- } ,
51- /// Contains serialised decrypted peer storage backup.
52- DecryptedPeerStorage {
53- /// Stores decrypted serialised data.
54- data : Vec < u8 > ,
55- } ,
43+ pub struct DecryptedOurPeerStorage {
44+ data : Vec < u8 > ,
5645}
5746
58- impl OurPeerStorage {
59- /// Return [`OurPeerStorage::EncryptedPeerStorage`] or [`OurPeerStorage::DecryptedPeerStorage`]
60- /// in [`Vec<u8>`] form.
47+ impl DecryptedOurPeerStorage {
48+ /// Returns [`DecryptedOurPeerStorage`] with the given data.
49+ pub fn new ( data : Vec < u8 > ) -> Self {
50+ Self { data }
51+ }
52+
53+ /// Returns data stored in [`Vec<u8>`] format.
6154 pub fn into_vec ( self ) -> Vec < u8 > {
62- match self {
63- OurPeerStorage :: DecryptedPeerStorage { data } => data,
64- OurPeerStorage :: EncryptedPeerStorage { cipher } => cipher,
65- }
55+ self . data
6656 }
6757
68- /// Returns [`OurPeerStorage::EncryptedPeerStorage`] with encrypted `cipher`.
69- ///
70- /// This function takes a `key` (for encryption) and random_bytes (to derive nonce for encryption)
71- /// and returns a [`OurPeerStorage::EncryptedPeerStorage`] with encrypted data inside.
72- /// It should only be called on [`OurPeerStorage::DecryptedPeerStorage`] otherwise it would panic.
73- ///
74- /// The resulting serialised data is intended to be directly used for transmission to the peers.
75- pub fn encrypt_peer_storage (
76- self , key : & PeerStorageKey , random_bytes : [ u8 ; 32 ] ,
77- ) -> OurPeerStorage {
78- match self {
79- OurPeerStorage :: DecryptedPeerStorage { mut data } => {
80- let plaintext_len = data. len ( ) ;
81- let nonce = derive_nonce ( key, & random_bytes) ;
82-
83- let mut chacha = ChaCha20Poly1305RFC :: new ( & key. inner , & nonce, b"" ) ;
84- let mut tag = [ 0 ; 16 ] ;
85- chacha. encrypt_full_message_in_place ( & mut data[ 0 ..plaintext_len] , & mut tag) ;
86-
87- data. extend_from_slice ( & tag) ;
88-
89- // Prepend `random_bytes` in front of the encrypted_blob.
90- data. splice ( 0 ..0 , random_bytes) ;
91- Self :: EncryptedPeerStorage { cipher : data }
92- } ,
93- OurPeerStorage :: EncryptedPeerStorage { cipher : _ } => {
94- panic ! ( "Expected OurPeerStorage::DecryptedPeerStorage!" ) ;
95- } ,
96- }
58+ /// Encrypts the data inside [`DecryptedOurPeerStorage`] using [`PeerStorageKey`] and `random_bytes`
59+ /// and returns [`EncryptedOurPeerStorage`].
60+ pub fn encrypt ( self , key : & PeerStorageKey , random_bytes : [ u8 ; 32 ] ) -> EncryptedOurPeerStorage {
61+ let mut data = self . data ;
62+ let plaintext_len = data. len ( ) ;
63+ let nonce = derive_nonce ( key, & random_bytes) ;
64+
65+ let mut chacha = ChaCha20Poly1305RFC :: new ( & key. inner , & nonce, b"" ) ;
66+ let mut tag = [ 0 ; 16 ] ;
67+ chacha. encrypt_full_message_in_place ( & mut data[ 0 ..plaintext_len] , & mut tag) ;
68+
69+ data. extend_from_slice ( & tag) ;
70+
71+ // Prepend `random_bytes` in front of the encrypted_blob.
72+ data. splice ( 0 ..0 , random_bytes) ;
73+
74+ EncryptedOurPeerStorage { cipher : data }
9775 }
76+ }
77+
78+ /// [`EncryptedOurPeerStorage`] represents encrypted state of the corresponding [`DecryptedOurPeerStorage`].
79+ ///
80+ /// # Key Methods
81+ /// - [`EncryptedOurPeerStorage::new`]: Returns [`EncryptedOurPeerStorage`] with the given encrypted cipher.
82+ /// - [`EncryptedOurPeerStorage::decrypt`]: Returns [`DecryptedOurPeerStorage`] created from decrypting the cipher.
83+ /// - [`EncryptedOurPeerStorage::into_vec`]: Returns the cipher in [`Vec<u8>`] format.
84+ pub struct EncryptedOurPeerStorage {
85+ cipher : Vec < u8 > ,
86+ }
9887
99- /// This expects a [`OurPeerStorage::EncryptedPeerStorage`] which would be consumed
100- /// to return a [`OurPeerStorage::DecryptedPeerStorage`] in case of successful decryption.
101- ///
102- /// It would return error if the ciphertext inside [`OurPeerStorage::EncryptedPeerStorage`] is
103- /// not correct and panic if it is called on [`OurPeerStorage::DecryptedPeerStorage`].
104- pub fn decrypt_peer_storage ( self , key : & PeerStorageKey ) -> Result < Self , ( ) > {
105- match self {
106- OurPeerStorage :: EncryptedPeerStorage { mut cipher } => {
107- let cyphertext_len = cipher. len ( ) ;
88+ impl EncryptedOurPeerStorage {
89+ /// Returns [`EncryptedOurPeerStorage`] if cipher is of appropriate length, else returns error.
90+ pub fn new ( cipher : Vec < u8 > ) -> Result < Self , ( ) > {
91+ // Ciphertext is of the form: random_bytes(32 bytes) + encrypted_data + tag(16 bytes).
92+ const MIN_CIPHERTEXT_LEN : usize = 32 + 16 ;
93+
94+ if cipher. len ( ) < MIN_CIPHERTEXT_LEN {
95+ return Err ( ( ) ) ;
96+ }
97+ return Ok ( Self { cipher } ) ;
98+ }
10899
109- // Ciphertext is of the form: random_bytes(32 bytes) + encrypted_data + tag(16 bytes).
110- let ( data_mut, tag) = cipher. split_at_mut ( cyphertext_len - 16 ) ;
111- let ( random_bytes, encrypted_data) = data_mut. split_at_mut ( 32 ) ;
100+ /// Returns cipher in the format [`Vec<u8>`].
101+ pub fn into_vec ( self ) -> Vec < u8 > {
102+ self . cipher
103+ }
112104
113- let nonce = derive_nonce ( key, random_bytes) ;
105+ /// Returns [`DecryptedOurPeerStorage`] if it successfully decrypts the ciphertext with the `key`,
106+ /// else returns error.
107+ pub fn decrypt ( self , key : & PeerStorageKey ) -> Result < DecryptedOurPeerStorage , ( ) > {
108+ let mut cipher = self . cipher ;
109+ let cyphertext_len = cipher. len ( ) ;
114110
115- let mut chacha = ChaCha20Poly1305RFC :: new ( & key. inner , & nonce, b"" ) ;
111+ // Ciphertext is of the form: random_bytes(32 bytes) + encrypted_data + tag(16 bytes).
112+ let ( data_mut, tag) = cipher. split_at_mut ( cyphertext_len - 16 ) ;
113+ let ( random_bytes, encrypted_data) = data_mut. split_at_mut ( 32 ) ;
116114
117- if chacha. check_decrypt_in_place ( encrypted_data, tag) . is_err ( ) {
118- return Err ( ( ) ) ;
119- }
115+ let nonce = derive_nonce ( key, random_bytes) ;
120116
121- cipher. truncate ( cyphertext_len - 16 ) ;
122- cipher. drain ( 0 ..32 ) ;
117+ let mut chacha = ChaCha20Poly1305RFC :: new ( & key. inner , & nonce, b"" ) ;
123118
124- Ok ( Self :: DecryptedPeerStorage { data : cipher } )
125- } ,
126- OurPeerStorage :: DecryptedPeerStorage { data : _ } => {
127- panic ! ( "Expected OurPeerStorage::EncryptedPeerStorage!" ) ;
128- } ,
119+ if chacha. check_decrypt_in_place ( encrypted_data, tag) . is_err ( ) {
120+ return Err ( ( ) ) ;
129121 }
122+
123+ cipher. truncate ( cyphertext_len - 16 ) ;
124+ cipher. drain ( 0 ..32 ) ;
125+
126+ Ok ( DecryptedOurPeerStorage { data : cipher } )
130127 }
131128}
132129
@@ -145,7 +142,7 @@ fn derive_nonce(key: &PeerStorageKey, random_bytes: &[u8]) -> [u8; 12] {
145142
146143#[ cfg( test) ]
147144mod tests {
148- use crate :: ln:: our_peer_storage:: { derive_nonce, OurPeerStorage } ;
145+ use crate :: ln:: our_peer_storage:: { derive_nonce, DecryptedOurPeerStorage } ;
149146 use crate :: sign:: PeerStorageKey ;
150147
151148 #[ test]
@@ -156,18 +153,15 @@ mod tests {
156153 let random_bytes2 = [ 201 ; 32 ] ;
157154
158155 // Happy Path
159- let decrypted_ops = OurPeerStorage :: DecryptedPeerStorage { data : vec ! [ 42u8 ; 32 ] } ;
160- let decrypted_ops_res = decrypted_ops
161- . encrypt_peer_storage ( & key1, random_bytes1)
162- . decrypt_peer_storage ( & key1)
163- . unwrap ( ) ;
156+ let decrypted_ops = DecryptedOurPeerStorage :: new ( vec ! [ 42u8 ; 32 ] ) ;
157+ let decrypted_ops_res: DecryptedOurPeerStorage =
158+ decrypted_ops. encrypt ( & key1, random_bytes1) . decrypt ( & key1) . unwrap ( ) ;
164159 assert_eq ! ( decrypted_ops_res. into_vec( ) , vec![ 42u8 ; 32 ] ) ;
165160
166161 // Changing Key
167- let decrypted_ops_wrong_key = OurPeerStorage :: DecryptedPeerStorage { data : vec ! [ 42u8 ; 32 ] } ;
168- let decrypted_ops_wrong_key_res = decrypted_ops_wrong_key
169- . encrypt_peer_storage ( & key2, random_bytes2)
170- . decrypt_peer_storage ( & key1) ;
162+ let decrypted_ops_wrong_key = DecryptedOurPeerStorage :: new ( vec ! [ 42u8 ; 32 ] ) ;
163+ let decrypted_ops_wrong_key_res =
164+ decrypted_ops_wrong_key. encrypt ( & key2, random_bytes2) . decrypt ( & key1) ;
171165 assert ! ( decrypted_ops_wrong_key_res. is_err( ) ) ;
172166
173167 // Nonce derivation happy path
0 commit comments