diff --git a/CMakeLists.txt b/CMakeLists.txt
index a5a0a9238feadb767c8c71cba0e99cc112399f96..4ffafbe6f93def1d8625dd6b425b80c48ad0938b 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -2,7 +2,7 @@ project(cellframe-sdk C)
 cmake_minimum_required(VERSION 2.8)
 
 set(CMAKE_C_STANDARD 11)
-set(CELLFRAME_SDK_NATIVE_VERSION "2.1-0")
+set(CELLFRAME_SDK_NATIVE_VERSION "2.1-1")
 include(cmake/OS_Detection.cmake)
 add_definitions ("-DCELLFRAME_SDK_VERSION=\"${CELLFRAME_SDK_NATIVE_VERSION}\"")
 
@@ -16,6 +16,16 @@ if (CELLFRAME_MODULES MATCHES "network")
     set(DAPSDK_MODULES "${DAPSDK_MODULES} network-core network-client network-server")
 endif()
 
+if (BUILD_CRYPTO_TESTS)
+    if ( NOT(DAPSDK_MODULES MATCHES "core"))
+	SET(DAPSDK_MODULES "${DAPSDK_MODULES} core")
+    endif()
+    if ( NOT(DAPSDK_MODULES MATCHES "crypto"))
+	SET(DAPSDK_MODULES "${DAPSDK_MODULES} crypto")
+    endif()
+    set(BUILD_TESTS ON)
+endif()
+
 add_subdirectory(dap-sdk)
 add_subdirectory(3rdparty/monero_crypto)
 add_subdirectory(3rdparty/cuttdb)
diff --git a/dap-sdk/crypto/test/CMakeLists.txt b/dap-sdk/crypto/test/CMakeLists.txt
index 18ed49801c7a0238d38ae31ff7cc41f2d75d6867..fe129624464d805d51780fd653889e6425e914f9 100755
--- a/dap-sdk/crypto/test/CMakeLists.txt
+++ b/dap-sdk/crypto/test/CMakeLists.txt
@@ -1,11 +1,7 @@
-cmake_minimum_required(VERSION 3.0)
+cmake_minimum_required(VERSION 3.0)
 project(test)
 
 set(CMAKE_C_STANDARD 11)
 
-if(NOT SUBMODULES_NO_BUILD)
-    add_subdirectory(libdap-test)
-endif()
-
 add_subdirectory(crypto)
 add_subdirectory(cert)
diff --git a/modules/CMakeLists.txt b/modules/CMakeLists.txt
index 7b810fc7857b9a1aaf5b2bea64720b4e381bcc12..19026903b6ce517c04a435c744cb06bc802ccad1 100644
--- a/modules/CMakeLists.txt
+++ b/modules/CMakeLists.txt
@@ -75,3 +75,8 @@ endif()
 if (CELLFRAME_MODULES MATCHES "srv-vpn")
     add_subdirectory(service/vpn)
 endif()
+
+# Unit tests
+if( BUILD_TESTS)
+    add_subdirectory(test)
+endif()
\ No newline at end of file
diff --git a/modules/test/CMakeLists.txt b/modules/test/CMakeLists.txt
new file mode 100644
index 0000000000000000000000000000000000000000..70e543e45b934bcc5d43a765db96d620a4af9280
--- /dev/null
+++ b/modules/test/CMakeLists.txt
@@ -0,0 +1,9 @@
+cmake_minimum_required(VERSION 3.0)
+if(TARGET dap_test)
+    return() # The project has already been built.
+endif()
+project(dap_test)
+
+add_library(${PROJECT_NAME} STATIC dap_test.h dap_test.c dap_test_generator.h dap_test_generator.c)
+
+target_include_directories(dap_test INTERFACE .)
diff --git a/modules/test/dap_test.c b/modules/test/dap_test.c
new file mode 100644
index 0000000000000000000000000000000000000000..e4603b71d210ea96d5db7dc2690861a920a449a3
--- /dev/null
+++ b/modules/test/dap_test.c
@@ -0,0 +1,112 @@
+#include "dap_test.h"
+
+#include <sys/time.h>
+
+/*
+ How to use benchmark_xxx() functions:
+
+ void mytest_func()
+ {
+ // doing something ...
+ }
+
+ // Repeat mytest_func() 5 time
+ int dt = benchmark_test_time(mytest_func, 5);
+ // Display result, sample 'Encode and decode PASS. (4 msec.)'
+ benchmark_mgs_time("Encode and decode", dt);
+
+ // Repeat mytest_func() within 2 second
+ float rate = benchmark_test_rate(mytest_func, 2);
+ // Display result, sample 'Encode and decode PASS. (703 times/sec.)'
+ benchmark_mgs_rate("Encode and decode", rate);
+
+ */
+
+#define dap_pass_msg_benchmark(testname, benchmark_text) \
+    printf("\t%s%s PASS. %s%s\n", TEXT_COLOR_GRN, testname, benchmark_text, TEXT_COLOR_RESET); \
+    fflush(stdout); \
+
+/**
+ * Display time in the format 'x.xx sec.' or 'xx msec.'
+ */
+void benchmark_mgs_time(const char *test_name, int dt)
+{
+    char buf[120];
+    if(abs(dt) >= 1000) {
+        snprintf(buf, 120, "(%.3lf sec.)", dt * 1. / 1000);
+    }
+    else {
+
+        snprintf(buf, 120, "(%d msec.)", dt);
+    }
+    dap_pass_msg_benchmark(test_name, buf);
+}
+
+/**
+ * Display rate in the format 'xx times/sec.'
+ */
+void benchmark_mgs_rate(const char *test_name, float rate)
+{
+    char buf[120];
+    if(rate > 100) {
+        snprintf(buf, 120, "(%.0lf times/sec.)", rate);
+    }
+    else if(rate > 10) {
+        snprintf(buf, 120, "%.1lf times/sec.", rate);
+    }
+    else {
+        snprintf(buf, 120, "%.2lf times/sec.", rate);
+    }
+    dap_pass_msg_benchmark(test_name, buf);
+}
+
+/**
+ * @return current time in milliseconds
+ */
+static int get_cur_time_msec(void)
+{
+    struct timespec time;
+    clock_gettime(CLOCK_MONOTONIC, &time);
+    int msec = time.tv_sec * 1000 + (time.tv_nsec + 500000) / 1000000;
+    return msec;
+}
+
+/**
+ * Calculate the runtime of a function that repeat several times
+ * @func_name function for repeats
+ * @repeat how many times repeats
+ * @return time in milliseconds
+ */
+int benchmark_test_time(void (*func_name)(void), int repeat)
+{
+    int t1 = get_cur_time_msec();
+    for(int i = 0; i < repeat; i++)
+        func_name();
+    int t2 = get_cur_time_msec();
+    return t2 - t1;
+}
+
+/**
+ * Calculate the rate of a function that repeat at a minimum specified number of seconds
+ * @func_name function for repeats
+ * @repeat how many times repeats
+ * @return function rate, i.e. count per second
+ */
+float benchmark_test_rate(void (*func_name)(void), float sec)
+{
+    if(sec < 0.1f) {
+        dap_test_msg("undefined times/sec.");
+        return 0;
+    }
+    int t1 = get_cur_time_msec();
+    int repeat = 0, dt;
+    do {
+        func_name();
+        dt = (get_cur_time_msec() - t1);
+        repeat++;
+    }
+    while(dt < sec * 1000);
+    float rate = repeat * 1000.f / dt;
+    return rate;
+}
+
diff --git a/modules/test/dap_test.h b/modules/test/dap_test.h
new file mode 100644
index 0000000000000000000000000000000000000000..0c346732faf6f13ae2d744601ee77f1156693b3b
--- /dev/null
+++ b/modules/test/dap_test.h
@@ -0,0 +1,112 @@
+#pragma once
+#include <assert.h>
+#include <stdbool.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <time.h>
+
+#define TEXT_COLOR_RED   "\x1B[31m"
+#define TEXT_COLOR_GRN   "\x1B[32m"
+#define TEXT_COLOR_YEL   "\x1B[33m"
+#define TEXT_COLOR_BLU   "\x1B[34m"
+#define TEXT_COLOR_MAG   "\x1B[35m"
+#define TEXT_COLOR_CYN   "\x1B[36m"
+#define TEXT_COLOR_WHT   "\x1B[37m"
+#define TEXT_COLOR_RESET "\x1B[0m"
+
+/* Can be used like debug info during write test*/
+/**
+ * @brief Can be used like debug info during write test
+ */
+#define dap_test_msg(...) { \
+    printf("\t%s", TEXT_COLOR_WHT); \
+    printf(__VA_ARGS__); \
+    printf("%s\n", TEXT_COLOR_RESET); \
+    fflush(stdout); }
+
+#define dap_fail(msg) {\
+    printf("\t%s%s!%s\n", TEXT_COLOR_RED, msg, TEXT_COLOR_RESET); \
+    abort();}
+
+/* PIF - print if failed. For checking value in loop, for don't repeat output */
+/**
+ * @brief PIF - print if failed. For checking value in loop, for don't repeat output
+ */
+#define dap_assert_PIF(expr, msg) { \
+    if(expr) {} \
+    else { \
+    printf("\t%s%s FAILED!%s\n", TEXT_COLOR_RED, msg, TEXT_COLOR_RESET); \
+    abort(); } }
+
+/**
+ * @brief
+*/
+#define dap_assert(expr, testname) { \
+    if(expr) { \
+        printf("\t%s%s PASS.%s\n", TEXT_COLOR_GRN, testname, TEXT_COLOR_RESET); \
+        fflush(stdout); \
+    } else { \
+    printf("\t%s%s FAILED!%s\n", TEXT_COLOR_RED, testname, TEXT_COLOR_RESET); \
+    abort(); } } \
+
+/**
+ * @brief Display the name test
+*/
+#define dap_pass_msg(testname) { \
+    printf("\t%s%s PASS.%s\n", TEXT_COLOR_GRN, testname, TEXT_COLOR_RESET); \
+    fflush(stdout); } \
+
+/**
+ * @brief Display the name of the test module
+*/
+#define dap_print_module_name(module_name) { \
+    printf("%s%s passing the tests... %s\n", TEXT_COLOR_CYN, module_name, TEXT_COLOR_RESET); \
+    fflush(stdout); }
+
+#define dap_str_equals(str1, str2) strcmp(str1, str2) == 0
+#define dap_strn_equals(str1, str2, count) strncmp(str1, str2, count) == 0
+
+/*
+ How to use benchmark_xxx() functions:
+
+ void mytest_func()
+ {
+ // doing something ...
+ }
+
+ // Repeat mytest_func() 5 time
+ int dt = benchmark_test_time(mytest_func, 5);
+ // Display result, sample 'Encode and decode PASS. (4 msec.)'
+ benchmark_mgs_time("Encode and decode", dt);
+
+ // Repeat mytest_func() within 2 second
+ float rate = benchmark_test_rate(mytest_func, 2);
+ // Display result, sample 'Encode and decode PASS. (703 times/sec.)'
+ benchmark_mgs_rate("Encode and decode", rate);
+
+ */
+
+/**
+ * Display time in the format 'x.xx sec.' or 'xx msec.'
+ */
+void benchmark_mgs_time(const char *text, int dt);
+
+/**
+ * Display rate in the format 'xx times/sec.'
+ */
+void benchmark_mgs_rate(const char *test_name, float rate);
+/**
+ * Calculate the runtime of a function that repeat several times
+ * @func_name function for repeats
+ * @repeat how many times repeats
+ * @return time in milliseconds
+ */
+int benchmark_test_time(void (*func_name)(void), int repeat);
+/**
+ * Calculate the rate of a function that repeat at a minimum specified number of seconds
+ * @func_name function for repeats
+ * @repeat how many times repeats
+ * @return function rate, i.e. count per second
+ */
+float benchmark_test_rate(void (*func_name)(void), float sec);
diff --git a/modules/test/dap_test_generator.c b/modules/test/dap_test_generator.c
new file mode 100644
index 0000000000000000000000000000000000000000..6a540f6928582f3ffba3296af20739e00b5d5733
--- /dev/null
+++ b/modules/test/dap_test_generator.c
@@ -0,0 +1,21 @@
+#include "dap_test_generator.h"
+
+#define BYTE_SIZE 255
+
+/**
+ * @brief The function fills an array with random numbers
+ * @param[out] array Takes a pointer to an array
+ * @param[in] size Size of the array passed in the array parameter
+ *
+ * The function fills an array with random integer non-negative values
+*/
+void generate_random_byte_array(uint8_t* array, const size_t size) {
+    srand((uint32_t)time(NULL));
+    for(size_t i = 0; i < size; i++) {
+        array[i] = (uint8_t)rand() % BYTE_SIZE;
+    }
+
+    // Last byte not should be 0
+    if (array[size - 1] == 0)
+        array[size - 1] = 1;
+}
diff --git a/modules/test/dap_test_generator.h b/modules/test/dap_test_generator.h
new file mode 100644
index 0000000000000000000000000000000000000000..4c74064744cb844c864d14faf72d7e555a54b7e0
--- /dev/null
+++ b/modules/test/dap_test_generator.h
@@ -0,0 +1,7 @@
+#pragma once
+#include <stdint.h>
+#include <stdlib.h>
+#include <time.h>
+
+void generate_random_byte_array(uint8_t* array, const size_t size);
+