From d51443a08b74280eca6c70746a316ebd58a996ad Mon Sep 17 00:00:00 2001 From: Sebastien Rousseau Date: Tue, 21 Nov 2023 09:14:21 +0000 Subject: [PATCH] test(kyberlib): :white_check_mark: updating tests cases and naming convention --- Cargo.toml | 2 ++ README.md | 2 +- benches/api.rs | 2 +- src/loggers.rs | 56 -------------------------------- src/macros.rs | 38 +++++++++++----------- tests/KAT/readme.md | 18 ++++++++++- tests/rand_bufs/readme.md | 18 ++++++++++- tests/readme.md | 26 ++++++++++++--- tests/{kat.rs => test_kat.rs} | 0 tests/{kem.rs => test_kem.rs} | 0 tests/{kex.rs => test_kex.rs} | 0 tests/test_loggers.rs | 61 +++++++++++++++++++++++++++++++++++ 12 files changed, 140 insertions(+), 83 deletions(-) rename tests/{kat.rs => test_kat.rs} (100%) rename tests/{kem.rs => test_kem.rs} (100%) rename tests/{kex.rs => test_kex.rs} (100%) create mode 100644 tests/test_loggers.rs diff --git a/Cargo.toml b/Cargo.toml index e44098a..be4c27a 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -46,6 +46,8 @@ default-features = false features = ["getrandom"] optional = true +benchmarking = ["criterion"] + [build-dependencies] cc = {version = "1.0.73", optional = true } nasm-rs = {version = "0.2.4", optional = true } diff --git a/README.md b/README.md index 08afe79..8193915 100644 --- a/README.md +++ b/README.md @@ -12,7 +12,7 @@ align="right" # kyberlib -A Robust Rust Library for CRYSTALS-Kyber Post-Quantum Cryptography (CRYSTALS-Kyber is a finalist in the NIST Post-Quantum Cryptography Standardization Process). +A Robust Rust Library for CRYSTALS-Kyber Post-Quantum Cryptography.
diff --git a/benches/api.rs b/benches/api.rs index 74b2124..168cff0 100644 --- a/benches/api.rs +++ b/benches/api.rs @@ -1,4 +1,4 @@ -extern crate criterion; +#![cfg(feature = "benchmarking")] use criterion::{criterion_group, criterion_main, Criterion}; use kyberlib::{*, kem::{generate_key_pair, encrypt_message}}; diff --git a/src/loggers.rs b/src/loggers.rs index d9b45c5..a7f7006 100644 --- a/src/loggers.rs +++ b/src/loggers.rs @@ -162,59 +162,3 @@ impl<'a> Default for Log<'a> { } } -#[cfg(test)] -mod tests { - use super::*; - - // Assuming a maximum log message size, adjust as needed - const MAX_LOG_SIZE: usize = 1024; - - struct CustomFile { - data: [u8; MAX_LOG_SIZE], - len: usize, - } - - impl fmt::Write for CustomFile { - fn write_str(&mut self, s: &str) -> fmt::Result { - let bytes = s.as_bytes(); - let bytes_len = bytes.len(); - if self.len + bytes_len > MAX_LOG_SIZE { - return Err(fmt::Error); // Buffer overflow - } - - self.data[self.len..self.len + bytes_len].copy_from_slice(bytes); - self.len += bytes_len; - - Ok(()) - } - } - - impl CustomWrite for CustomFile { - fn custom_flush(&mut self) -> CoreResult<(), CustomError> { - Ok(()) - } - } - - #[test] - fn test_log_info() { - let mut custom_file = CustomFile { data: [0; MAX_LOG_SIZE], len: 0 }; - let log_entry = Log::new( - "session123", - "2023-11-20T12:34:56", - LogLevel::INFO, - "component_name", - "This is a log message", - LogFormat::CLF, - ); - - assert!(log_entry.log(&mut custom_file).is_ok()); - - // Convert the written bytes to a string slice for checking - let logged_data = core::str::from_utf8(&custom_file.data[..custom_file.len]) - .expect("Failed to convert to string"); - - // Here you can assert the contents of `logged_data` - // For example, checking if it contains certain substrings - assert!(logged_data.contains("This is a log message")); - } -} diff --git a/src/macros.rs b/src/macros.rs index bb74ae2..54e97fa 100644 --- a/src/macros.rs +++ b/src/macros.rs @@ -67,19 +67,19 @@ macro_rules! kyberlib_max { /// Example /// /// ```rust -/// use kyberlib::loggers::LogFormat; +/// use kyberlib::loggers::LogFormat; /// use kyberlib::kyberlib_info; /// use kyberlib::loggers::Log; /// use kyberlib::loggers::LogLevel; -/// -/// let log = kyberlib_info!( +/// +/// let log = kyberlib_info!( /// "session123", /// "2023-01-04T21:00:00", /// "app", -/// "Message logged", +/// "Message logged", /// LogFormat::CLF /// ); -/// ``` +/// ``` #[macro_export] macro_rules! kyberlib_info { ($session_id:expr, $time:expr, $component:expr, $desc:expr, $format:expr) => { @@ -96,16 +96,16 @@ macro_rules! kyberlib_info { /// Shorthand macros to create `Log` instances with different log levels. /// -/// Example -/// +/// Example +/// /// ```rust -/// use kyberlib::loggers::LogFormat; +/// use kyberlib::loggers::LogFormat; /// use kyberlib::kyberlib_error; /// use kyberlib::loggers::Log; /// use kyberlib::loggers::LogLevel; -/// +/// /// let error_log = kyberlib_error!( -/// "session123", +/// "session123", /// "2023-01-04T21:00:00", /// "app", /// "Connection failed", @@ -138,7 +138,7 @@ macro_rules! kyberlib_error { /// /// let log = kyberlib_debug!( /// "session123", -/// "2023-01-04T21:00:00", +/// "2023-01-04T21:00:00", /// "app", /// "Message logged", /// LogFormat::CLF @@ -160,21 +160,21 @@ macro_rules! kyberlib_debug { /// Shorthand macro to create a `Log` with the given log level. /// -/// Example +/// Example /// -/// ```rust +/// ```rust /// use kyberlib::loggers::{LogLevel, LogFormat}; /// use kyberlib::kyberlib_log; -/// -/// let log = kyberlib_log!( -/// "session123", +/// +/// let log = kyberlib_log!( +/// "session123", /// "2023-01-04T21:00:00", /// "app", -/// "Message logged", -/// LogFormat::CLF +/// "Message logged", +/// LogFormat::CLF /// ); /// ``` -#[macro_export] +#[macro_export] macro_rules! kyberlib_log { ($session_id:expr, $time:expr, $component:expr, $description:expr, $format:expr) => {{ use kyberlib::loggers::{Log, LogFormat, LogLevel}; diff --git a/tests/KAT/readme.md b/tests/KAT/readme.md index 43b03ab..19ef92f 100644 --- a/tests/KAT/readme.md +++ b/tests/KAT/readme.md @@ -1,4 +1,20 @@ -# Known Answer Tests + + + + + + +# kyberlib + +A Robust Rust Library for CRYSTALS-Kyber Post-Quantum Cryptography. + +## Known Answer Tests The test vectors need to be generated locally. Running [build_kats.sh](./build_kats.sh) will automate the process, otherwise follow the instructions below to clone the C reference repo, compile the test binaries, then generate and rename the files. diff --git a/tests/rand_bufs/readme.md b/tests/rand_bufs/readme.md index 3583777..e5cfefb 100644 --- a/tests/rand_bufs/readme.md +++ b/tests/rand_bufs/readme.md @@ -1,4 +1,20 @@ -# Randbuf Generation + + + + + + +# kyberlib + +A Robust Rust Library for CRYSTALS-Kyber Post-Quantum Cryptography. + +## Randbuf Generation This program generates the deterministic rng output used in the intermediate stages of keypair generation and encoding from KAT seed values. diff --git a/tests/readme.md b/tests/readme.md index 882b50b..07cc4e2 100644 --- a/tests/readme.md +++ b/tests/readme.md @@ -1,4 +1,20 @@ -# Testing + + + + + + +# kyberlib + +A Robust Rust Library for CRYSTALS-Kyber Post-Quantum Cryptography. + +## Testing Without any feature flags `cargo test` will run through the key exchange functions and some doctests for the selected security level and mode. Running the Known Answer Tests require deterministic rng buffers from the test vector files. These files are quite large, you will need to generate them yourself. Instructions for building the KAT files are [here](./KAT/readme.md). Otherwise you can run: @@ -10,13 +26,15 @@ cd KAT Which will clone the C reference repo, generate the KAT files, then rename and put them in the correct folder for testing. To run the known answer tests you will need to enable `KYBER_SECURITY_PARAMETERat` in `RUSTFLAGS`. To check different Kyber levels or 90's mode you will need to include those flags also. eg: + ```bash RUSTFLAGS=' --cfg KYBER_SECURITY_PARAMETERat' cargo test --features "kyber1024 90s" ``` -For applicible x86 architectures you must export the avx2 RUSTFLAGS if you don't want to test on the reference codebase. +For applicable x86 architectures you must export the avx2 RUSTFLAGS if you don't want to test on the reference codebase. To run a matrix of all possible features use the helper script from this folder: + ```shell ./run_all_tests.sh ``` @@ -26,12 +44,12 @@ its behaviour * KAT: Runs the known answer tests * AVX2: Runs avx2 code on x86 platforms with compiled GAS files -* NASM: Runs avx2 code with both GAS and NASM files seperately, requires a NASM compiler installed +* NASM: Runs avx2 code with both GAS and NASM files separately, requires a NASM compiler installed To activate, instantiate the variables, for example: ```shell -KAT=1 AVX2=1 NASM=1 ./run_all_tests.sh +KAT=1 AVX2=1 NASM=1 ./run_all_tests.sh ``` Test files: diff --git a/tests/kat.rs b/tests/test_kat.rs similarity index 100% rename from tests/kat.rs rename to tests/test_kat.rs diff --git a/tests/kem.rs b/tests/test_kem.rs similarity index 100% rename from tests/kem.rs rename to tests/test_kem.rs diff --git a/tests/kex.rs b/tests/test_kex.rs similarity index 100% rename from tests/kex.rs rename to tests/test_kex.rs diff --git a/tests/test_loggers.rs b/tests/test_loggers.rs new file mode 100644 index 0000000..989f9a6 --- /dev/null +++ b/tests/test_loggers.rs @@ -0,0 +1,61 @@ +// Copyright © 2023 kyberlib. All rights reserved. +// SPDX-License-Identifier: Apache-2.0 OR MIT + +#[cfg(test)] +mod tests { + use kyberlib::loggers::*; + use core::fmt; + use core::result::Result as CoreResult; + + // Assuming a maximum log message size, adjust as needed + const MAX_LOG_SIZE: usize = 1024; + + struct CustomFile { + data: [u8; MAX_LOG_SIZE], + len: usize, + } + + impl fmt::Write for CustomFile { + fn write_str(&mut self, s: &str) -> fmt::Result { + let bytes = s.as_bytes(); + let bytes_len = bytes.len(); + if self.len + bytes_len > MAX_LOG_SIZE { + return Err(fmt::Error); // Buffer overflow + } + + self.data[self.len..self.len + bytes_len].copy_from_slice(bytes); + self.len += bytes_len; + + Ok(()) + } + } + + impl CustomWrite for CustomFile { + fn custom_flush(&mut self) -> CoreResult<(), CustomError> { + Ok(()) + } + } + + #[test] + fn test_log_info() { + let mut custom_file = CustomFile { data: [0; MAX_LOG_SIZE], len: 0 }; + let log_entry = Log::new( + "session123", + "2023-11-20T12:34:56", + LogLevel::INFO, + "component_name", + "This is a log message", + LogFormat::CLF, + ); + + assert!(log_entry.log(&mut custom_file).is_ok()); + + // Convert the written bytes to a string slice for checking + let logged_data = core::str::from_utf8(&custom_file.data[..custom_file.len]) + .expect("Failed to convert to string"); + + // Here you can assert the contents of `logged_data` + // For example, checking if it contains certain substrings + assert!(logged_data.contains("This is a log message")); + } +} \ No newline at end of file