Require any Router also implements MessageRouter
[rust-lightning] / lightning / src / util / chacha20poly1305rfc.rs
index 1dbd91e65e0488168f59d439cdd4565f8d56803f..d5792e0ac2b35f28bc8a90d43217d1874cd0e3ce 100644 (file)
 // This is a port of Andrew Moons poly1305-donna
 // https://github.com/floodyberry/poly1305-donna
 
-use ln::msgs::DecodeError;
-use util::ser::{FixedLengthReader, LengthRead, LengthReadableArgs, Readable, Writeable, Writer};
-use io::{self, Read, Write};
+use crate::ln::msgs::DecodeError;
+use crate::util::ser::{FixedLengthReader, LengthRead, LengthReadableArgs, Readable, Writeable, Writer};
+use crate::io::{self, Read, Write};
 
 #[cfg(not(fuzzing))]
 mod real_chachapoly {
-       use util::chacha20::ChaCha20;
-       use util::poly1305::Poly1305;
+       use crate::util::chacha20::ChaCha20;
+       use crate::util::poly1305::Poly1305;
        use bitcoin::hashes::cmp::fixed_time_eq;
 
        #[derive(Clone, Copy)]
@@ -74,6 +74,11 @@ mod real_chachapoly {
                        self.mac.raw_result(out_tag);
                }
 
+               pub fn encrypt_full_message_in_place(&mut self, input_output: &mut [u8], out_tag: &mut [u8]) {
+                       self.encrypt_in_place(input_output);
+                       self.finish_and_get_tag(out_tag);
+               }
+
                // Encrypt `input_output` in-place. To finish and calculate the tag, use `finish_and_get_tag`
                // below.
                pub(super) fn encrypt_in_place(&mut self, input_output: &mut [u8]) {
@@ -117,10 +122,15 @@ mod real_chachapoly {
                        }
                }
 
-               // Decrypt in place, without checking the tag. Use `finish_and_check_tag` to check it
-               // later when decryption finishes.
-               //
-               // Should never be `pub` because the public API should always enforce tag checking.
+               pub fn check_decrypt_in_place(&mut self, input_output: &mut [u8], tag: &[u8]) -> Result<(), ()> {
+                       self.decrypt_in_place(input_output);
+                       if self.finish_and_check_tag(tag) { Ok(()) } else { Err(()) }
+               }
+
+               /// Decrypt in place, without checking the tag. Use `finish_and_check_tag` to check it
+               /// later when decryption finishes.
+               ///
+               /// Should never be `pub` because the public API should always enforce tag checking.
                pub(super) fn decrypt_in_place(&mut self, input_output: &mut [u8]) {
                        debug_assert!(self.finished == false);
                        self.mac.input(input_output);
@@ -128,8 +138,8 @@ mod real_chachapoly {
                        self.cipher.process_in_place(input_output);
                }
 
-               // If we were previously decrypting with `decrypt_in_place`, this method must be used to finish
-               // decrypting and check the tag. Returns whether or not the tag is valid.
+               /// If we were previously decrypting with `just_decrypt_in_place`, this method must be used
+               /// to check the tag. Returns whether or not the tag is valid.
                pub(super) fn finish_and_check_tag(&mut self, tag: &[u8]) -> bool {
                        debug_assert!(self.finished == false);
                        self.finished = true;
@@ -223,7 +233,6 @@ impl<'a, T: Writeable> Writeable for ChaChaPolyWriteAdapter<'a, T> {
 /// Enables the use of the serialization macros for objects that need to be simultaneously decrypted and
 /// deserialized. This allows us to avoid an intermediate Vec allocation.
 pub(crate) struct ChaChaPolyReadAdapter<R: Readable> {
-       #[allow(unused)] // This will be used soon for onion messages
        pub readable: R,
 }
 
@@ -284,6 +293,11 @@ mod fuzzy_chachapoly {
                        self.finished = true;
                }
 
+               pub fn encrypt_full_message_in_place(&mut self, input_output: &mut [u8], out_tag: &mut [u8]) {
+                       self.encrypt_in_place(input_output);
+                       self.finish_and_get_tag(out_tag);
+               }
+
                pub(super) fn encrypt_in_place(&mut self, _input_output: &mut [u8]) {
                        assert!(self.finished == false);
                }
@@ -304,6 +318,11 @@ mod fuzzy_chachapoly {
                        true
                }
 
+               pub fn check_decrypt_in_place(&mut self, input_output: &mut [u8], tag: &[u8]) -> Result<(), ()> {
+                       self.decrypt_in_place(input_output);
+                       if self.finish_and_check_tag(tag) { Ok(()) } else { Err(()) }
+               }
+
                pub(super) fn decrypt_in_place(&mut self, _input: &mut [u8]) {
                        assert!(self.finished == false);
                }
@@ -320,21 +339,21 @@ pub use self::fuzzy_chachapoly::ChaCha20Poly1305RFC;
 
 #[cfg(test)]
 mod tests {
-       use ln::msgs::DecodeError;
+       use crate::ln::msgs::DecodeError;
        use super::{ChaChaPolyReadAdapter, ChaChaPolyWriteAdapter};
-       use util::ser::{self, FixedLengthReader, LengthReadableArgs, Writeable};
+       use crate::util::ser::{self, FixedLengthReader, LengthReadableArgs, Writeable};
 
        // Used for for testing various lengths of serialization.
-       #[derive(Debug, PartialEq)]
+       #[derive(Debug, PartialEq, Eq)]
        struct TestWriteable {
                field1: Vec<u8>,
                field2: Vec<u8>,
                field3: Vec<u8>,
        }
        impl_writeable_tlv_based!(TestWriteable, {
-               (1, field1, vec_type),
-               (2, field2, vec_type),
-               (3, field3, vec_type),
+               (1, field1, required_vec),
+               (2, field2, required_vec),
+               (3, field3, required_vec),
        });
 
        #[test]
@@ -402,7 +421,7 @@ mod tests {
        #[test]
        fn chacha_stream_adapters_ser_macros() {
                // Test that our stream adapters work as expected with the TLV macros.
-               // This also serves to test the `option: $trait` variant of the `decode_tlv` ser macro.
+               // This also serves to test the `option: $trait` variant of the `_decode_tlv` ser macro.
                do_chacha_stream_adapters_ser_macros().unwrap()
        }
 }