From 8ced6f74d41fcc772f3e92cd4590818c5f463661 Mon Sep 17 00:00:00 2001 From: Arseny Aprelev Date: Sun, 5 Jun 2016 21:46:28 +0300 Subject: [PATCH] Updates libgost15 to 0.4.0, see details Major changes + Renames methods, manages src subdirectories, renames main header + Integrates CTest + Tweaks Travis CI script Minor changes + Modifies method of implementation selection + Removes compiler-specific stuff + Adds platform header + Disables coverage in selftests --- .travis.yml | 32 ++-- README.md | 21 ++- src/CMakeLists.txt | 2 +- src/benchmark/CMakeLists.txt | 12 +- src/benchmark/src/benchmark.cpp | 6 +- src/libgost15/CMakeLists.txt | 62 +++----- .../libgost15/{gost15.h => libgost15.h} | 13 +- src/libgost15/include/libgost15/platform.h | 14 ++ src/libgost15/src/{ => SIMD}/SIMD.c | 16 +- src/libgost15/src/{ => SIMD}/SIMD_tables.c | 2 +- src/libgost15/src/{ => SIMD}/SIMD_tables.h | 2 +- src/libgost15/src/{ => compact}/compact.c | 13 +- src/libgost15/src/{ => optimised}/optimised.c | 16 +- .../src/{ => optimised}/optimised_tables.c | 2 +- .../src/{ => optimised}/optimised_tables.h | 2 +- src/libgost15/src/{ => shared}/tables.c | 2 +- src/libgost15/src/{ => shared}/tables.h | 0 src/libgost15/tests/CMakeLists.txt | 26 +-- src/libgost15/tests/decryption.c | 47 ++++++ src/libgost15/tests/encryption.c | 36 +++++ src/libgost15/tests/schedule.c | 50 ++++++ src/libgost15/tests/selftests_gost.c | 148 ------------------ 22 files changed, 258 insertions(+), 266 deletions(-) rename src/libgost15/include/libgost15/{gost15.h => libgost15.h} (77%) create mode 100644 src/libgost15/include/libgost15/platform.h rename src/libgost15/src/{ => SIMD}/SIMD.c (96%) rename src/libgost15/src/{ => SIMD}/SIMD_tables.c (99%) rename src/libgost15/src/{ => SIMD}/SIMD_tables.h (94%) rename src/libgost15/src/{ => compact}/compact.c (97%) rename src/libgost15/src/{ => optimised}/optimised.c (94%) rename src/libgost15/src/{ => optimised}/optimised_tables.c (99%) rename src/libgost15/src/{ => optimised}/optimised_tables.h (94%) rename src/libgost15/src/{ => shared}/tables.c (99%) rename src/libgost15/src/{ => shared}/tables.h (100%) create mode 100644 src/libgost15/tests/decryption.c create mode 100644 src/libgost15/tests/encryption.c create mode 100644 src/libgost15/tests/schedule.c delete mode 100644 src/libgost15/tests/selftests_gost.c diff --git a/.travis.yml b/.travis.yml index 0a4a399..1a15c92 100644 --- a/.travis.yml +++ b/.travis.yml @@ -10,24 +10,19 @@ compiler: - clang env: - global: - - ENABLE_COVERAGE=ON - matrix: - - ENABLE_PRECALCULATIONS=OFF ENABLE_SIMD=OFF BUILD_TYPE=Release - - ENABLE_PRECALCULATIONS=OFF ENABLE_SIMD=OFF BUILD_TYPE=Debug - - ENABLE_PRECALCULATIONS=ON ENABLE_SIMD=OFF BUILD_TYPE=Release - - ENABLE_PRECALCULATIONS=ON ENABLE_SIMD=OFF BUILD_TYPE=Debug -# allow_failures: -# - ENABLE_PRECALCULATIONS=ON ENABLE_SIMD=ON BUILD_TYPE=Debug -# - ENABLE_PRECALCULATIONS=ON ENABLE_SIMD=ON BUILD_TYPE=Release + - Coverage=ON BuildType=Release Implementation=Compact + - Coverage=ON BuildType=Release Implementation=Optimised +matrix: + allow_failures: + - env: Coverage=ON BuildType=Release Implementation=SIMD install: # Installing CMake 3.2.1 - wget --no-check-certificate http://www.cmake.org/files/v3.2/cmake-3.2.1.tar.gz - tar -xzf cmake-3.2.1.tar.gz - cd cmake-3.2.1 - - cmake . - - make + - cmake . > /dev/null + - make > /dev/null - cd .. - rm -rf cmake-3.2.1.tar.gz @@ -37,15 +32,16 @@ before_script: - cd build - ../cmake-3.2.1/bin/cmake - -DCMAKE_BUILD_TYPE=$BUILD_TYPE - -DENABLE_PRECALCULATIONS=$ENABLE_PRECALCULATIONS - -DENABLE_SIMD=$ENABLE_SIMD - -DENABLE_COVERAGE=$ENABLE_COVERAGE + -DCMAKE_BUILD_TYPE=$BuildType + -DIMPLEMENTATION=$Implementation + -DENABLE_COVERAGE=$Coverage + -DCMAKE_VERBOSE_MAKEFILE=ON + -DCMAKE_RULE_MESSAGES=OFF ../src/ script: - - make selftests_gost - - ./libgost15/tests/selftests_gost + - make --no-print-directory all + - cd libgost15/tests/ && ctest after_success: - bash <(curl -s https://codecov.io/bash) diff --git a/README.md b/README.md index d9ee650..fb68311 100644 --- a/README.md +++ b/README.md @@ -41,6 +41,13 @@ All functions provided by `libgost15` are thread-safe thus measuring takes place | Block encryption | 1.2840 MB/s | 62.6575 MB/s | 112.2875 MB/s | | Block decryption | 1.2676 MB/s | 64.4036 MB/s | 114.6625 MB/s | +Performance measuring is enabled when `benchmark` target is built with CMake: + +``` +cmake -DIMPLEMENTATION=[implementation] [target] +make benchmark +./benchmark/benchmark +``` ### Implementations @@ -54,26 +61,30 @@ Why use this and not [official TC26 implementation](http://tc26.ru/standard/gost * All sixteen R transformations are merged into single L transformation thus cutting out rotations. * Better grammar and code organisation. -This implementation is build by default and it does not require any special predefined variables. +This implementation is built with `-DIMPLEMENTATION=Compact` option: + +``` +cmake -DIMPLEMENTATION=Compact [target] +``` #### Optimised implementation Optimised implementation employs vector-by-matrix multiplication precomutation technique described in [no link yet], similar to one in 64KB versions of AES. This implementation is much faster that the compact one, but requires 128KB os additional memory in data segment for storing precomputed tables. Does not require SSE instructions. -To use optimised implementation, define `ENABLE_PRECALCULATIONS` environment variable before building: +This implementation is built with `-DIMPLEMENTATION=Optimised` option: ``` -cmake -DCMAKE_BUILD_TYPE=Release -DENABLE_PRECALCULATIONS=ON ... +cmake -DIMPLEMENTATION=Optimised [target] ``` #### SIMD implementation SIMD implementation utilises SSE instruction set, a set of extended processor instructions which enable one to operate over 128-bit XMM registers, thus further speeding up optimised implementation. Requires SSE2 or higher. -To use optimised implementation, define both `ENABLE_PRECALCULATIONS` and `ENABLE_SIMD` environment variables before building: +This implementation is built with `-DIMPLEMENTATION=SIMD` option: ``` -cmake -DCMAKE_BUILD_TYPE=Release -DENABLE_PRECALCULATIONS=ON -DENABLE_SIMD=ON ... +cmake -DIMPLEMENTATION=SIMD [target] ``` Future versions of `libgost15` might enable this implementation version by default when optimised version is selected and SSE instruction set (SSE2+) is available. diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index bef109e..bfec8c2 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -1,7 +1,7 @@ cmake_minimum_required(VERSION 3.2) ## libgost15-lib project declaration -project(aprelev-libgost15 VERSION 0.3.6) +project(libgost15-wrap VERSION 0.4.0) ## libgost15 library and selftests add_subdirectory(libgost15) diff --git a/src/benchmark/CMakeLists.txt b/src/benchmark/CMakeLists.txt index 1ad6dd5..adbeb4f 100644 --- a/src/benchmark/CMakeLists.txt +++ b/src/benchmark/CMakeLists.txt @@ -7,8 +7,18 @@ cmake_minimum_required(VERSION 3.2) ## libgost15 project declaration -project(libgost15-benchmark VERSION 0.3.5 LANGUAGES CXX) +project(benchmark VERSION 0.3.6 LANGUAGES CXX) +## benchmark definition add_executable(benchmark src/benchmark.cpp) + +## Falling back to strict C++11 standard set_target_properties(benchmark PROPERTIES CXX_STANDARD 11) +set_target_properties(benchmark PROPERTIES CXX_STANDARD_REQUIRED ON) +set_target_properties(benchmark PROPERTIES CXX_EXTENSIONS OFF) + +## Excluding benchmark from all target +set_target_properties(benchmark PROPERTIES EXCLUDE_FROM_ALL ON) + +## Linking libgost15 target_link_libraries(benchmark libgost15) \ No newline at end of file diff --git a/src/benchmark/src/benchmark.cpp b/src/benchmark/src/benchmark.cpp index 0fda530..d8ce4a8 100644 --- a/src/benchmark/src/benchmark.cpp +++ b/src/benchmark/src/benchmark.cpp @@ -4,7 +4,7 @@ #include #include #include -#include +#include const auto defaultDuration = std::chrono::duration(2000.); @@ -90,7 +90,7 @@ void benchmarkEncryption(std::chrono::duration minimumDurati auto startedAt_ = std::chrono::high_resolution_clock::now(); for (size_t iterationIndex_ = 0; iterationIndex_ < iterations_; ++iterationIndex_) { - encryptBlock(roundKeys_, block_); + encryptBlockWithGost15(roundKeys_, block_); } auto finishedAt_ = std::chrono::high_resolution_clock::now(); @@ -128,7 +128,7 @@ void benchmarkDecryption(std::chrono::duration minimumDurati auto startedAt_ = std::chrono::high_resolution_clock::now(); for (size_t iterationIndex_ = 0; iterationIndex_ < iterations_; ++iterationIndex_) { - encryptBlock(roundKeys_, block_); + encryptBlockWithGost15(roundKeys_, block_); } auto finishedAt_ = std::chrono::high_resolution_clock::now(); diff --git a/src/libgost15/CMakeLists.txt b/src/libgost15/CMakeLists.txt index 3388840..844175a 100644 --- a/src/libgost15/CMakeLists.txt +++ b/src/libgost15/CMakeLists.txt @@ -7,28 +7,29 @@ cmake_minimum_required(VERSION 3.2) ## libgost15 project declaration -project(libgost15 VERSION 0.3.5 LANGUAGES C) +project(libgost15 VERSION 0.4.0 LANGUAGES C) ## libgost15 global options -option(ENABLE_PRECALCULATIONS "Use optimised implementation with precalculated tables" OFF) -option(ENABLE_SIMD "Enable SIMD code optimisations" OFF) +set(IMPLEMENTATION "Optimised" CACHE STRING "Implementation version: Compact, Optimised or SIMD.") ## libgost15 definition add_library(libgost15) ## libgost15 source files -if (ENABLE_PRECALCULATIONS AND ENABLE_SIMD) - message(WARNING "Building SIMD implementation version.") - target_sources(libgost15 PRIVATE src/SIMD.c src/tables.c src/SIMD_tables.c) -elseif(ENABLE_PRECALCULATIONS) - message(WARNING "Building optimised implementation version.") - target_sources(libgost15 PRIVATE src/optimised.c src/tables.c src/optimised_tables.c) +if (IMPLEMENTATION STREQUAL SIMD) + message(AUTHOR_WARNING "Building SIMD implementation version.") + target_sources(libgost15 PRIVATE src/SIMD/SIMD.c src/SIMD/SIMD_tables.c src/shared/tables.c) +elseif(IMPLEMENTATION STREQUAL Optimised) + message(AUTHOR_WARNING "Building optimised implementation version.") + target_sources(libgost15 PRIVATE src/optimised/optimised.c src/optimised/optimised_tables.c src/shared/tables.c) +elseif(IMPLEMENTATION STREQUAL Compact) + message(AUTHOR_WARNING "Building compact implementation version.") + target_sources(libgost15 PRIVATE src/compact/compact.c src/shared/tables.c) else() - message(WARNING "Building compact implementation version.") - target_sources(libgost15 PRIVATE src/compact.c src/tables.c) + message(FATAL_ERROR "No implementation specified.") endif() -## libgost15 include directories and compiler features +## libgost15 include directories target_include_directories(libgost15 PUBLIC $) target_include_directories(libgost15 PUBLIC $) target_include_directories(libgost15 PRIVATE src) @@ -40,38 +41,13 @@ endif() ## Falling back to strict C standard set_target_properties(libgost15 PROPERTIES C_EXTENSIONS OFF) +set_target_properties(libgost15 PROPERTIES C_STANDARD 99) +set_target_properties(libgost15 PROPERTIES C_STANDARD_REQUIRED ON) -## libgost15 GCC compiler-specific flags -if(CMAKE_C_COMPILER_ID MATCHES "GNU") - target_compile_options(libgost15 PRIVATE $<$:-pedantic -Wall -Wextra -Werror -Wno-unused-function -Wno-cast-align>) - target_compile_options(libgost15 PRIVATE $<$:-march=native>) - - ## Disabling SIMD if required - if(NOT ENABLE_SIMD) - target_compile_options(libgost15 PRIVATE -mno-sse) - endif() - - ## Enabling coverage - if(ENABLE_COVERAGE) - target_link_libraries(libgost15 PRIVATE --coverage) - target_compile_options(libgost15 PRIVATE --coverage) - endif() - -## libgost15 Clang compiler-specific flags -elseif(CMAKE_C_COMPILER_ID MATCHES "Clang") - target_compile_options(libgost15 PRIVATE $<$:-Weverything -Werror -Wno-unused-function -Wno-cast-align>) - target_compile_options(libgost15 PRIVATE $<$:-march=native>) - - ## Disabling SIMD if required - if(NOT ENABLE_SIMD) - target_compile_options(libgost15 PRIVATE -mno-sse) - endif() - - ## Enabling coverage - if(ENABLE_COVERAGE) - target_link_libraries(libgost15 PRIVATE --coverage) - target_compile_options(libgost15 PRIVATE --coverage) - endif() +## Enabling coverage +if(ENABLE_COVERAGE) + target_link_libraries(libgost15 PRIVATE --coverage) + target_compile_options(libgost15 PRIVATE --coverage) endif() ## libgost15 selftests diff --git a/src/libgost15/include/libgost15/gost15.h b/src/libgost15/include/libgost15/libgost15.h similarity index 77% rename from src/libgost15/include/libgost15/gost15.h rename to src/libgost15/include/libgost15/libgost15.h index 1f394a0..92f1a0c 100644 --- a/src/libgost15/include/libgost15/gost15.h +++ b/src/libgost15/include/libgost15/libgost15.h @@ -1,9 +1,7 @@ #if !defined LIBGOST15_HEADER_INCLUDED_ #define LIBGOST15_HEADER_INCLUDED_ -#include -#include - +#include enum { NumberOfRounds = 10, @@ -19,22 +17,23 @@ extern const size_t WorkspaceOfScheduleRoundKeys; extern "C" { #endif -void encryptBlock( +void encryptBlockWithGost15( const void *roundKeys, void *block ); -void decryptBlock( + +void decryptBlockWithGost15( const void *roundKeys, void *block ); -void scheduleEncryptionRoundKeys( +void scheduleEncryptionRoundKeysForGost15( void *roundKeys, const void *key, void *memory ); -void scheduleDecryptionRoundKeys( +void scheduleDecryptionRoundKeysForGost15( void *roundKeys, const void *key, void *memory diff --git a/src/libgost15/include/libgost15/platform.h b/src/libgost15/include/libgost15/platform.h new file mode 100644 index 0000000..077cf28 --- /dev/null +++ b/src/libgost15/include/libgost15/platform.h @@ -0,0 +1,14 @@ +#if !defined LIBGOST15_PLATFORM_HEADER_INCLUDED_ +#define LIBGOST15_PLATFORM_HEADER_INCLUDED_ + +#include +#include + +/* TODO: Make platform-dependent keywords available within CMake. + */ + +/* Restrict keyword macros. */ + +/* Force inline keyword macros. */ + +#endif diff --git a/src/libgost15/src/SIMD.c b/src/libgost15/src/SIMD/SIMD.c similarity index 96% rename from src/libgost15/src/SIMD.c rename to src/libgost15/src/SIMD/SIMD.c index 4586391..9d62777 100644 --- a/src/libgost15/src/SIMD.c +++ b/src/libgost15/src/SIMD/SIMD.c @@ -1,8 +1,8 @@ +#include +#include +#include #include #include -#include -#include -#include // TODO: Beat alignment warnings with Clang's and GCC's -Wcast-align. @@ -139,7 +139,7 @@ static void applyFTransformation( } -void scheduleEncryptionRoundKeys( +void scheduleEncryptionRoundKeysForGost15( void *restrict roundKeys, const void *restrict key, void *restrict memory @@ -165,13 +165,13 @@ void scheduleEncryptionRoundKeys( } -void scheduleDecryptionRoundKeys( +void scheduleDecryptionRoundKeysForGost15( void *restrict roundKeys, const void *restrict key, void *restrict memory ) { uint64_t *roundKeys_ = roundKeys; - scheduleEncryptionRoundKeys(roundKeys, key, memory); + scheduleEncryptionRoundKeysForGost15(roundKeys, key, memory); for (int keyIndex_ = 1; keyIndex_ <= 8; ++keyIndex_) { __m128i temporary1_, temporary2_; @@ -184,7 +184,7 @@ void scheduleDecryptionRoundKeys( } -void encryptBlock( +void encryptBlockWithGost15( const void *restrict roundKeys, void *restrict data ) { @@ -202,7 +202,7 @@ void encryptBlock( } -void decryptBlock( +void decryptBlockWithGost15( const void *restrict roundKeys, void *restrict data ) { diff --git a/src/libgost15/src/SIMD_tables.c b/src/libgost15/src/SIMD/SIMD_tables.c similarity index 99% rename from src/libgost15/src/SIMD_tables.c rename to src/libgost15/src/SIMD/SIMD_tables.c index 0735b9d..de3efba 100644 --- a/src/libgost15/src/SIMD_tables.c +++ b/src/libgost15/src/SIMD/SIMD_tables.c @@ -1,4 +1,4 @@ -#include +#include const uint8_t ALIGNED(bitmask[16]) = { 0x00, 0xff, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff, diff --git a/src/libgost15/src/SIMD_tables.h b/src/libgost15/src/SIMD/SIMD_tables.h similarity index 94% rename from src/libgost15/src/SIMD_tables.h rename to src/libgost15/src/SIMD/SIMD_tables.h index f9fefe6..ce686f7 100644 --- a/src/libgost15/src/SIMD_tables.h +++ b/src/libgost15/src/SIMD/SIMD_tables.h @@ -1,7 +1,7 @@ #if !defined LIBGOST15_SIMD_TABLES_HEADER_INCLUDED_ #define LIBGOST15_SIMD_TABLES_HEADER_INCLUDED_ -#include +#include /* Crude alignment macros. */ #if defined _MSC_VER diff --git a/src/libgost15/src/compact.c b/src/libgost15/src/compact/compact.c similarity index 97% rename from src/libgost15/src/compact.c rename to src/libgost15/src/compact/compact.c index 13e7a53..23171d0 100644 --- a/src/libgost15/src/compact.c +++ b/src/libgost15/src/compact/compact.c @@ -1,6 +1,7 @@ +#include +#include #include -#include -#include + const size_t WorkspaceOfScheduleRoundKeys = BlockLengthInBytes * 2; @@ -191,7 +192,7 @@ static void scheduleRoundKeys( } -void scheduleEncryptionRoundKeys( +void scheduleEncryptionRoundKeysForGost15( void *restrict roundKeys, const void *restrict key, void *restrict memory @@ -200,7 +201,7 @@ void scheduleEncryptionRoundKeys( } -void scheduleDecryptionRoundKeys( +void scheduleDecryptionRoundKeysForGost15( void *restrict roundKeys, const void *restrict key, void *restrict memory @@ -209,7 +210,7 @@ void scheduleDecryptionRoundKeys( } -void encryptBlock( +void encryptBlockWithGost15( const void *restrict roundKeys, void *restrict block ) { @@ -224,7 +225,7 @@ void encryptBlock( } -void decryptBlock( +void decryptBlockWithGost15( const void *restrict roundKeys, void *restrict block ) { diff --git a/src/libgost15/src/optimised.c b/src/libgost15/src/optimised/optimised.c similarity index 94% rename from src/libgost15/src/optimised.c rename to src/libgost15/src/optimised/optimised.c index 476ee95..d058232 100644 --- a/src/libgost15/src/optimised.c +++ b/src/libgost15/src/optimised/optimised.c @@ -1,7 +1,7 @@ +#include +#include +#include #include -#include -#include -#include const size_t WorkspaceOfScheduleRoundKeys = BlockLengthInBytes * 2; @@ -99,7 +99,7 @@ static void applyFTransformation( } -void scheduleEncryptionRoundKeys( +void scheduleEncryptionRoundKeysForGost15( void *restrict roundKeys, const void *restrict key, void *restrict memory @@ -129,7 +129,7 @@ void scheduleEncryptionRoundKeys( } -void scheduleDecryptionRoundKeys( +void scheduleDecryptionRoundKeysForGost15( void *restrict roundKeys, const void *restrict key, void *restrict memory @@ -137,7 +137,7 @@ void scheduleDecryptionRoundKeys( uint64_t *roundKeys_ = roundKeys; uint64_t cache_[2] = {0}; - scheduleEncryptionRoundKeys(roundKeys, key, memory); + scheduleEncryptionRoundKeysForGost15(roundKeys, key, memory); for (int roundKeyIndex_ = 1; roundKeyIndex_ <= 8; ++roundKeyIndex_) { memcpy(cache_, @@ -150,7 +150,7 @@ void scheduleDecryptionRoundKeys( } -void encryptBlock( +void encryptBlockWithGost15( const void *restrict roundKeys, void *restrict data ) { @@ -171,7 +171,7 @@ void encryptBlock( } -void decryptBlock( +void decryptBlockWithGost15( const void *restrict roundKeys, void *restrict data ) { diff --git a/src/libgost15/src/optimised_tables.c b/src/libgost15/src/optimised/optimised_tables.c similarity index 99% rename from src/libgost15/src/optimised_tables.c rename to src/libgost15/src/optimised/optimised_tables.c index 8738ccb..b6bb3cf 100644 --- a/src/libgost15/src/optimised_tables.c +++ b/src/libgost15/src/optimised/optimised_tables.c @@ -1,4 +1,4 @@ -#include +#include const union qword_t roundConstantsLeft[32] = { {{0x6e, 0xa2, 0x76, 0x72, 0x6c, 0x48, 0x7a, 0xb8,}}, diff --git a/src/libgost15/src/optimised_tables.h b/src/libgost15/src/optimised/optimised_tables.h similarity index 94% rename from src/libgost15/src/optimised_tables.h rename to src/libgost15/src/optimised/optimised_tables.h index 5cf4f01..1d317a9 100644 --- a/src/libgost15/src/optimised_tables.h +++ b/src/libgost15/src/optimised/optimised_tables.h @@ -1,7 +1,7 @@ #if !defined LIBGOST15_OPTIMISED_TABLES_HEADER_INCLUDED_ #define LIBGOST15_OPTIMISED_TABLES_HEADER_INCLUDED_ -#include +#include union qword_t { uint8_t asBytes[8]; diff --git a/src/libgost15/src/tables.c b/src/libgost15/src/shared/tables.c similarity index 99% rename from src/libgost15/src/tables.c rename to src/libgost15/src/shared/tables.c index 4579a5a..4f884ff 100644 --- a/src/libgost15/src/tables.c +++ b/src/libgost15/src/shared/tables.c @@ -1,4 +1,4 @@ -#include +#include const uint8_t roundConstants[512] = { 0x6e, 0xa2, 0x76, 0x72, 0x6c, 0x48, 0x7a, 0xb8, 0x5d, 0x27, 0xbd, 0x10, 0xdd, 0x84, 0x94, 0x01, diff --git a/src/libgost15/src/tables.h b/src/libgost15/src/shared/tables.h similarity index 100% rename from src/libgost15/src/tables.h rename to src/libgost15/src/shared/tables.h diff --git a/src/libgost15/tests/CMakeLists.txt b/src/libgost15/tests/CMakeLists.txt index 9bc7116..eff8068 100644 --- a/src/libgost15/tests/CMakeLists.txt +++ b/src/libgost15/tests/CMakeLists.txt @@ -4,18 +4,18 @@ ## ## ########################################################################################## -## libgost15 selftests target declaration -add_executable(selftests_gost selftests_gost.c) +function(add_test_executable test_name) + add_executable(${test_name} ${ARGN}) + set_target_properties(${test_name} PROPERTIES + C_EXTENSIONS OFF + C_STANDARD 99 + C_STANDARD_REQUIRED ON) + target_link_libraries(${test_name} PUBLIC libgost15) + add_test(${test_name} ${test_name}) +endfunction(add_test_executable) -## Linking libgost15 -target_link_libraries(selftests_gost PUBLIC libgost15) - -## Enabling coverage -if(ENABLE_COVERAGE) - target_link_libraries(selftests_gost PRIVATE --coverage) - target_compile_options(selftests_gost PRIVATE --coverage) -endif() - -## Enabling and adding tests +## Selftests declaration enable_testing() -add_test(selftests_gost selftests_gost) +add_test_executable(KeyScheduleTest schedule.c) +add_test_executable(BlockEncryptionTest encryption.c) +add_test_executable(BlockDecryptionTest decryption.c) diff --git a/src/libgost15/tests/decryption.c b/src/libgost15/tests/decryption.c new file mode 100644 index 0000000..f61fbca --- /dev/null +++ b/src/libgost15/tests/decryption.c @@ -0,0 +1,47 @@ +#include +#include +#include + + +int testBlockDecryption(void) { + int numberOfFailedTests_ = 0; + void *roundKeys_ = NULL, *memory_ = NULL; + + const uint8_t secretKey_[KeyLengthInBytes] = { + 0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff, 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, + 0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54, 0x32, 0x10, 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef, + }; + + uint8_t block_[BlockLengthInBytes] = { + 0x7f, 0x67, 0x9d, 0x90, 0xbe, 0xbc, 0x24, 0x30, 0x5a, 0x46, 0x8d, 0x42, 0xb9, 0xd4, 0xed, 0xcd, + }; + + const uint8_t expectedPlaintext_[BlockLengthInBytes] = { + 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x00, 0xff, 0xee, 0xdd, 0xcc, 0xbb, 0xaa, 0x99, 0x88, + }; + + roundKeys_ = malloc(NumberOfRounds * BlockLengthInBytes); + if (!roundKeys_) { + ++numberOfFailedTests_; + goto cleanup; + } + + memory_ = malloc(WorkspaceOfScheduleRoundKeys); + if (!memory_ && WorkspaceOfScheduleRoundKeys) { + ++numberOfFailedTests_; + goto cleanup; + } + + scheduleDecryptionRoundKeysForGost15(roundKeys_, secretKey_, memory_); + decryptBlockWithGost15(roundKeys_, block_); + numberOfFailedTests_ += (memcmp(block_, expectedPlaintext_, BlockLengthInBytes) != 0); + + cleanup: + free(memory_); + return numberOfFailedTests_; +} + + +int main(void) { + return testBlockDecryption(); +} diff --git a/src/libgost15/tests/encryption.c b/src/libgost15/tests/encryption.c new file mode 100644 index 0000000..a67dd73 --- /dev/null +++ b/src/libgost15/tests/encryption.c @@ -0,0 +1,36 @@ +#include +#include +#include + + +int testBlockEncryption(void) { + int numberOfFailedTests_ = 0; + const uint8_t roundKeys_[NumberOfRounds * BlockLengthInBytes] = { + 0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff, 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, + 0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54, 0x32, 0x10, 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef, + 0xdb, 0x31, 0x48, 0x53, 0x15, 0x69, 0x43, 0x43, 0x22, 0x8d, 0x6a, 0xef, 0x8c, 0xc7, 0x8c, 0x44, + 0x3d, 0x45, 0x53, 0xd8, 0xe9, 0xcf, 0xec, 0x68, 0x15, 0xeb, 0xad, 0xc4, 0x0a, 0x9f, 0xfd, 0x04, + 0x57, 0x64, 0x64, 0x68, 0xc4, 0x4a, 0x5e, 0x28, 0xd3, 0xe5, 0x92, 0x46, 0xf4, 0x29, 0xf1, 0xac, + 0xbd, 0x07, 0x94, 0x35, 0x16, 0x5c, 0x64, 0x32, 0xb5, 0x32, 0xe8, 0x28, 0x34, 0xda, 0x58, 0x1b, + 0x51, 0xe6, 0x40, 0x75, 0x7e, 0x87, 0x45, 0xde, 0x70, 0x57, 0x27, 0x26, 0x5a, 0x00, 0x98, 0xb1, + 0x5a, 0x79, 0x25, 0x01, 0x7b, 0x9f, 0xdd, 0x3e, 0xd7, 0x2a, 0x91, 0xa2, 0x22, 0x86, 0xf9, 0x84, + 0xbb, 0x44, 0xe2, 0x53, 0x78, 0xc7, 0x31, 0x23, 0xa5, 0xf3, 0x2f, 0x73, 0xcd, 0xb6, 0xe5, 0x17, + 0x72, 0xe9, 0xdd, 0x74, 0x16, 0xbc, 0xf4, 0x5b, 0x75, 0x5d, 0xba, 0xa8, 0x8e, 0x4a, 0x40, 0x43, + }; + uint8_t block_[BlockLengthInBytes] = { + 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x00, 0xff, 0xee, 0xdd, 0xcc, 0xbb, 0xaa, 0x99, 0x88, + }; + const uint8_t expectedCiphertext_[BlockLengthInBytes] = { + 0x7f, 0x67, 0x9d, 0x90, 0xbe, 0xbc, 0x24, 0x30, 0x5a, 0x46, 0x8d, 0x42, 0xb9, 0xd4, 0xed, 0xcd, + }; + + encryptBlockWithGost15(roundKeys_, block_); + numberOfFailedTests_ += (memcmp(block_, expectedCiphertext_, BlockLengthInBytes) != 0); + + return numberOfFailedTests_; +} + + +int main(void) { + return testBlockEncryption(); +} diff --git a/src/libgost15/tests/schedule.c b/src/libgost15/tests/schedule.c new file mode 100644 index 0000000..d4fb7c0 --- /dev/null +++ b/src/libgost15/tests/schedule.c @@ -0,0 +1,50 @@ +#include +#include +#include + + +int testKeyScheduling(void) { + int numberOfFailedTests_ = 0; + void *roundKeys_ = NULL, *memory_ = NULL; + const uint8_t secretKey_[KeyLengthInBytes] = { + 0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff, 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, + 0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54, 0x32, 0x10, 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef, + }; + const uint8_t expectedRoundKeys_[NumberOfRounds * BlockLengthInBytes] = { + 0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff, 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, + 0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54, 0x32, 0x10, 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef, + 0xdb, 0x31, 0x48, 0x53, 0x15, 0x69, 0x43, 0x43, 0x22, 0x8d, 0x6a, 0xef, 0x8c, 0xc7, 0x8c, 0x44, + 0x3d, 0x45, 0x53, 0xd8, 0xe9, 0xcf, 0xec, 0x68, 0x15, 0xeb, 0xad, 0xc4, 0x0a, 0x9f, 0xfd, 0x04, + 0x57, 0x64, 0x64, 0x68, 0xc4, 0x4a, 0x5e, 0x28, 0xd3, 0xe5, 0x92, 0x46, 0xf4, 0x29, 0xf1, 0xac, + 0xbd, 0x07, 0x94, 0x35, 0x16, 0x5c, 0x64, 0x32, 0xb5, 0x32, 0xe8, 0x28, 0x34, 0xda, 0x58, 0x1b, + 0x51, 0xe6, 0x40, 0x75, 0x7e, 0x87, 0x45, 0xde, 0x70, 0x57, 0x27, 0x26, 0x5a, 0x00, 0x98, 0xb1, + 0x5a, 0x79, 0x25, 0x01, 0x7b, 0x9f, 0xdd, 0x3e, 0xd7, 0x2a, 0x91, 0xa2, 0x22, 0x86, 0xf9, 0x84, + 0xbb, 0x44, 0xe2, 0x53, 0x78, 0xc7, 0x31, 0x23, 0xa5, 0xf3, 0x2f, 0x73, 0xcd, 0xb6, 0xe5, 0x17, + 0x72, 0xe9, 0xdd, 0x74, 0x16, 0xbc, 0xf4, 0x5b, 0x75, 0x5d, 0xba, 0xa8, 0x8e, 0x4a, 0x40, 0x43, + }; + + roundKeys_ = malloc(NumberOfRounds * BlockLengthInBytes); + if (!roundKeys_) { + ++numberOfFailedTests_; + goto cleanup; + } + + memory_ = malloc(WorkspaceOfScheduleRoundKeys); + if (!memory_ && WorkspaceOfScheduleRoundKeys) { + ++numberOfFailedTests_; + goto cleanup; + } + + scheduleEncryptionRoundKeysForGost15(roundKeys_, secretKey_, memory_); + numberOfFailedTests_ += (memcmp(roundKeys_, expectedRoundKeys_, NumberOfRounds * BlockLengthInBytes) != 0); + + cleanup: + free(roundKeys_); + free(memory_); + return numberOfFailedTests_; +} + + +int main(void) { + return testKeyScheduling(); +} diff --git a/src/libgost15/tests/selftests_gost.c b/src/libgost15/tests/selftests_gost.c deleted file mode 100644 index 1472c5e..0000000 --- a/src/libgost15/tests/selftests_gost.c +++ /dev/null @@ -1,148 +0,0 @@ -#include -#include -#include -#include - - -int testKeyScheduling(void) { - int numberOfFailedTests_ = 0; - void *roundKeys_ = NULL, *memory_ = NULL; - const uint8_t secretKey_[KeyLengthInBytes] = { - 0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff, 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, - 0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54, 0x32, 0x10, 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef, - }; - const uint8_t expectedRoundKeys_[NumberOfRounds * BlockLengthInBytes] = { - 0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff, 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, - 0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54, 0x32, 0x10, 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef, - 0xdb, 0x31, 0x48, 0x53, 0x15, 0x69, 0x43, 0x43, 0x22, 0x8d, 0x6a, 0xef, 0x8c, 0xc7, 0x8c, 0x44, - 0x3d, 0x45, 0x53, 0xd8, 0xe9, 0xcf, 0xec, 0x68, 0x15, 0xeb, 0xad, 0xc4, 0x0a, 0x9f, 0xfd, 0x04, - 0x57, 0x64, 0x64, 0x68, 0xc4, 0x4a, 0x5e, 0x28, 0xd3, 0xe5, 0x92, 0x46, 0xf4, 0x29, 0xf1, 0xac, - 0xbd, 0x07, 0x94, 0x35, 0x16, 0x5c, 0x64, 0x32, 0xb5, 0x32, 0xe8, 0x28, 0x34, 0xda, 0x58, 0x1b, - 0x51, 0xe6, 0x40, 0x75, 0x7e, 0x87, 0x45, 0xde, 0x70, 0x57, 0x27, 0x26, 0x5a, 0x00, 0x98, 0xb1, - 0x5a, 0x79, 0x25, 0x01, 0x7b, 0x9f, 0xdd, 0x3e, 0xd7, 0x2a, 0x91, 0xa2, 0x22, 0x86, 0xf9, 0x84, - 0xbb, 0x44, 0xe2, 0x53, 0x78, 0xc7, 0x31, 0x23, 0xa5, 0xf3, 0x2f, 0x73, 0xcd, 0xb6, 0xe5, 0x17, - 0x72, 0xe9, 0xdd, 0x74, 0x16, 0xbc, 0xf4, 0x5b, 0x75, 0x5d, 0xba, 0xa8, 0x8e, 0x4a, 0x40, 0x43, - }; - - roundKeys_ = malloc(NumberOfRounds * BlockLengthInBytes); - if (!roundKeys_) { - ++numberOfFailedTests_; - goto cleanup; - } - - memory_ = malloc(WorkspaceOfScheduleRoundKeys); - if (!memory_ && WorkspaceOfScheduleRoundKeys) { - ++numberOfFailedTests_; - goto cleanup; - } - - scheduleEncryptionRoundKeys(roundKeys_, secretKey_, memory_); - numberOfFailedTests_ += (memcmp(roundKeys_, expectedRoundKeys_, NumberOfRounds * BlockLengthInBytes) != 0); - - cleanup: - free(roundKeys_); - free(memory_); - return numberOfFailedTests_; -} - - -int testBlockEncryption(void) { - int numberOfFailedTests_ = 0; - const uint8_t roundKeys_[NumberOfRounds * BlockLengthInBytes] = { - 0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff, 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, - 0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54, 0x32, 0x10, 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef, - 0xdb, 0x31, 0x48, 0x53, 0x15, 0x69, 0x43, 0x43, 0x22, 0x8d, 0x6a, 0xef, 0x8c, 0xc7, 0x8c, 0x44, - 0x3d, 0x45, 0x53, 0xd8, 0xe9, 0xcf, 0xec, 0x68, 0x15, 0xeb, 0xad, 0xc4, 0x0a, 0x9f, 0xfd, 0x04, - 0x57, 0x64, 0x64, 0x68, 0xc4, 0x4a, 0x5e, 0x28, 0xd3, 0xe5, 0x92, 0x46, 0xf4, 0x29, 0xf1, 0xac, - 0xbd, 0x07, 0x94, 0x35, 0x16, 0x5c, 0x64, 0x32, 0xb5, 0x32, 0xe8, 0x28, 0x34, 0xda, 0x58, 0x1b, - 0x51, 0xe6, 0x40, 0x75, 0x7e, 0x87, 0x45, 0xde, 0x70, 0x57, 0x27, 0x26, 0x5a, 0x00, 0x98, 0xb1, - 0x5a, 0x79, 0x25, 0x01, 0x7b, 0x9f, 0xdd, 0x3e, 0xd7, 0x2a, 0x91, 0xa2, 0x22, 0x86, 0xf9, 0x84, - 0xbb, 0x44, 0xe2, 0x53, 0x78, 0xc7, 0x31, 0x23, 0xa5, 0xf3, 0x2f, 0x73, 0xcd, 0xb6, 0xe5, 0x17, - 0x72, 0xe9, 0xdd, 0x74, 0x16, 0xbc, 0xf4, 0x5b, 0x75, 0x5d, 0xba, 0xa8, 0x8e, 0x4a, 0x40, 0x43, - }; - uint8_t block_[BlockLengthInBytes] = { - 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x00, 0xff, 0xee, 0xdd, 0xcc, 0xbb, 0xaa, 0x99, 0x88, - }; - const uint8_t expectedCiphertext_[BlockLengthInBytes] = { - 0x7f, 0x67, 0x9d, 0x90, 0xbe, 0xbc, 0x24, 0x30, 0x5a, 0x46, 0x8d, 0x42, 0xb9, 0xd4, 0xed, 0xcd, - }; - - encryptBlock(roundKeys_, block_); - numberOfFailedTests_ += (memcmp(block_, expectedCiphertext_, BlockLengthInBytes) != 0); - - return numberOfFailedTests_; -} - - -int testBlockDecryption(void) { - int numberOfFailedTests_ = 0; - void *roundKeys_ = NULL, *memory_ = NULL; - - const uint8_t secretKey_[KeyLengthInBytes] = { - 0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff, 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, - 0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54, 0x32, 0x10, 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef, - }; - - uint8_t block_[BlockLengthInBytes] = { - 0x7f, 0x67, 0x9d, 0x90, 0xbe, 0xbc, 0x24, 0x30, 0x5a, 0x46, 0x8d, 0x42, 0xb9, 0xd4, 0xed, 0xcd, - }; - - const uint8_t expectedPlaintext_[BlockLengthInBytes] = { - 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x00, 0xff, 0xee, 0xdd, 0xcc, 0xbb, 0xaa, 0x99, 0x88, - }; - - roundKeys_ = malloc(NumberOfRounds * BlockLengthInBytes); - if (!roundKeys_) { - ++numberOfFailedTests_; - goto cleanup; - } - - memory_ = malloc(WorkspaceOfScheduleRoundKeys); - if (!memory_ && WorkspaceOfScheduleRoundKeys) { - ++numberOfFailedTests_; - goto cleanup; - } - - scheduleDecryptionRoundKeys(roundKeys_, secretKey_, memory_); - decryptBlock(roundKeys_, block_); - numberOfFailedTests_ += (memcmp(block_, expectedPlaintext_, BlockLengthInBytes) != 0); - - cleanup: - free(memory_); - return numberOfFailedTests_; -} - - -int main(void) { - int globalNumberOfFailedTests_ = 0, localNumberOfFailedTests_ = 0; - printf("Running GOST selftests:\n"); - - printf("\tKey scheduling selftest: "); - if ((localNumberOfFailedTests_ = testKeyScheduling())) { - printf("FAILED, errors occured: %i.\n", localNumberOfFailedTests_); - globalNumberOfFailedTests_ += localNumberOfFailedTests_; - } - else { - printf("OK.\n"); - } - - printf("\tEncryption selftest: "); - if ((localNumberOfFailedTests_ = testBlockEncryption())) { - printf("FAILED, errors occured: %i.\n", localNumberOfFailedTests_); - globalNumberOfFailedTests_ += localNumberOfFailedTests_; - } - else { - printf("OK.\n"); - } - - printf("\tDecryption selftest: "); - if ((localNumberOfFailedTests_ = testBlockDecryption())) { - printf("FAILED, errors occured: %i.\n", localNumberOfFailedTests_); - globalNumberOfFailedTests_ += localNumberOfFailedTests_; - } - else { - printf("OK.\n"); - } - - return globalNumberOfFailedTests_; -}