Merge pull request #671 from open-quantum-safe/ds-tests-in-threads

Run the test_kem and test_sig tests on a thread when possible
This commit is contained in:
Vlad Gheorghiu 2020-03-27 09:44:05 -04:00 committed by GitHub
commit df189ce69d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 134 additions and 17 deletions

View File

@ -40,6 +40,10 @@ if(CMAKE_C_COMPILER_ID MATCHES "Clang")
add_compile_options(-fomit-frame-pointer)
endif()
set(THREADS_PREFER_PTHREAD_FLAG ON)
find_package(Threads REQUIRED)
set(OQS_USE_PTHREADS_IN_TESTS 1)
elseif(CMAKE_C_COMPILER_ID STREQUAL "GNU")
add_compile_options(-Werror)
add_compile_options(-Wall)
@ -76,6 +80,10 @@ elseif(CMAKE_C_COMPILER_ID STREQUAL "GNU")
endif ()
endif()
set(THREADS_PREFER_PTHREAD_FLAG ON)
find_package(Threads REQUIRED)
set(OQS_USE_PTHREADS_IN_TESTS 1)
elseif(CMAKE_C_COMPILER_ID STREQUAL "MSVC")
# Warning C4146 is raised when a unary minus operator is applied to an
# unsigned type; this has nonetheless been standard and portable for as

3
.gitignore vendored
View File

@ -8,6 +8,9 @@ tags
# CMake
/build*
# CLion
/cmake-build*
# Misc
__pycache__
.pytest_cache

View File

@ -37,10 +37,10 @@ More information on OQS can be found [here](https://openquantumsafe.org/) and in
#### Key encapsulation mechanisms
- **BIKE**: BIKE1-L1-CPA, BIKE1-L3-CPA, BIKE1-L1-FO, BIKE1-L3-FO
- **Classic McEliece**: Classic-McEliece-348864, Classic-McEliece-348864f, Classic-McEliece-460896, Classic-McEliece-460896f, Classic-McEliece-6688128, Classic-McEliece-6688128f, Classic-McEliece-6960119, Classic-McEliece-6960119f, Classic-McEliece-8192128, Classic-McEliece-8192128f
- **Classic McEliece**: Classic-McEliece-348864, Classic-McEliece-348864f, Classic-McEliece-460896, Classic-McEliece-460896f, Classic-McEliece-6688128, Classic-McEliece-6688128f, Classic-McEliece-6960119, Classic-McEliece-6960119f, Classic-McEliece-8192128, Classic-McEliece-8192128f
- **FrodoKEM**: FrodoKEM-640-AES, FrodoKEM-640-SHAKE, FrodoKEM-976-AES, FrodoKEM-976-SHAKE, FrodoKEM-1344-AES, FrodoKEM-1344-SHAKE
- **Kyber**: Kyber512, Kyber768, Kyber1024, Kyber512-90s, Kyber768-90s, Kyber1024-90s
- **LEDAcrypt**: LEDAcryptKEM-LT12, LEDAcryptKEM-LT32, LEDAcryptKEM-LT52
- **LEDAcrypt**: LEDAcryptKEM-LT12, LEDAcryptKEM-LT32, LEDAcryptKEM-LT52
- **NewHope**: NewHope-512-CCA, NewHope-1024-CCA
- **NTRU**: NTRU-HPS-2048-509, NTRU-HPS-2048-677, NTRU-HPS-4096-821, NTRU-HRSS-701
- **SABER**: LightSaber-KEM, Saber-KEM, FireSaber-KEM
@ -54,11 +54,13 @@ More information on OQS can be found [here](https://openquantumsafe.org/) and in
- **MQDSS**: MQDSS-31-48, MQDSS-31-64
- **Picnic**: Picnic-L1-FS, Picnic-L1-UR, Picnic-L3-FS, Picnic-L3-UR, Picnic-L5-FS, Picnic-L5-UR, Picnic2-L1-FS, Picnic2-L3-FS, Picnic2-L5-FS
- **qTesla**: qTesla-p-I, qTesla-p-III
- **Rainbow**: Rainbow-Ia-Classic, Rainbow-Ia-Cyclic, Rainbow-Ia-Cyclic-Compressed, Rainbow-IIIc-Classic, Rainbow-IIIc-Cyclic, Rainbow-IIIc-Cyclic-Compressed, Rainbow-Vc-Classic, Rainbow-Vc-Cyclic, Rainbow-Vc-Cyclic-Compressed
- **Rainbow**: Rainbow-Ia-Classic, Rainbow-Ia-Cyclic, Rainbow-Ia-Cyclic-Compressed, Rainbow-IIIc-Classic, Rainbow-IIIc-Cyclic, Rainbow-IIIc-Cyclic-Compressed, Rainbow-Vc-Classic, Rainbow-Vc-Cyclic, Rainbow-Vc-Cyclic-Compressed
- **SPHINCS+-Haraka**: SPHINCS+-Haraka-128f-robust, SPHINCS+-Haraka-128f-simple, SPHINCS+-Haraka-128s-robust, SPHINCS+-Haraka-128s-simple, SPHINCS+-Haraka-192f-robust, SPHINCS+-Haraka-192f-simple, SPHINCS+-Haraka-192s-robust, SPHINCS+-Haraka-192s-simple, SPHINCS+-Haraka-256f-robust, SPHINCS+-Haraka-256f-simple, SPHINCS+-Haraka-256s-robust, SPHINCS+-Haraka-256s-simple
- **SPHINCS+-SHA256**: SPHINCS+-SHA256-128f-robust, SPHINCS+-SHA256-128f-simple, SPHINCS+-SHA256-128s-robust, SPHINCS+-SHA256-128s-simple, SPHINCS+-SHA256-192f-robust, SPHINCS+-SHA256-192f-simple, SPHINCS+-SHA256-192s-robust, SPHINCS+-SHA256-192s-simple, SPHINCS+-SHA256-256f-robust, SPHINCS+-SHA256-256f-simple, SPHINCS+-SHA256-256s-robust, SPHINCS+-SHA256-256s-simple
- **SPHINCS+-SHAKE256**: SPHINCS+-SHAKE256-128f-robust, SPHINCS+-SHAKE256-128f-simple, SPHINCS+-SHAKE256-128s-robust, SPHINCS+-SHAKE256-128s-simple, SPHINCS+-SHAKE256-192f-robust, SPHINCS+-SHAKE256-192f-simple, SPHINCS+-SHAKE256-192s-robust, SPHINCS+-SHAKE256-192s-simple, SPHINCS+-SHAKE256-256f-robust, SPHINCS+-SHAKE256-256f-simple, SPHINCS+-SHAKE256-256s-robust, SPHINCS+-SHAKE256-256s-simple
Note that algorithms marked with a dagger (†) have large stack usage and may cause failures when run on threads or in constrained environments.
### Limitations and Security
As research advances, the supported algorithms may see rapid changes in their security, and may even prove insecure against both classical and quantum computers.

View File

@ -9,6 +9,8 @@
#cmakedefine OQS_USE_SHA2_OPENSSL 1
#cmakedefine OQS_USE_SHA3_OPENSSL 1
#cmakedefine OQS_USE_PTHREADS_IN_TESTS 1
#cmakedefine OQS_USE_AES_INSTRUCTIONS 1
#cmakedefine OQS_USE_AVX_INSTRUCTIONS 1
#cmakedefine OQS_USE_AVX2_INSTRUCTIONS 1

View File

@ -64,7 +64,11 @@ add_executable(kat_kem kat_kem.c)
target_link_libraries(kat_kem PRIVATE ${API_TEST_DEPS})
add_executable(test_kem test_kem.c)
target_link_libraries(test_kem PRIVATE ${API_TEST_DEPS})
if((CMAKE_C_COMPILER_ID MATCHES "Clang") OR (CMAKE_C_COMPILER_ID STREQUAL "GNU"))
target_link_libraries(test_kem PRIVATE ${API_TEST_DEPS} Threads::Threads)
else ()
target_link_libraries(test_kem PRIVATE ${API_TEST_DEPS})
endif()
add_executable(speed_kem speed_kem.c)
target_link_libraries(speed_kem PRIVATE ${API_TEST_DEPS})
@ -77,7 +81,11 @@ add_executable(kat_sig kat_sig.c)
target_link_libraries(kat_sig PRIVATE ${API_TEST_DEPS})
add_executable(test_sig test_sig.c)
target_link_libraries(test_sig PRIVATE ${API_TEST_DEPS})
if((CMAKE_C_COMPILER_ID MATCHES "Clang") OR (CMAKE_C_COMPILER_ID STREQUAL "GNU"))
target_link_libraries(test_sig PRIVATE ${API_TEST_DEPS} Threads::Threads)
else ()
target_link_libraries(test_sig PRIVATE ${API_TEST_DEPS})
endif()
add_executable(speed_sig speed_sig.c)
target_link_libraries(speed_sig PRIVATE ${API_TEST_DEPS})

View File

@ -5,6 +5,10 @@
#include <oqs/oqs.h>
#if OQS_USE_PTHREADS_IN_TESTS
#include <pthread.h>
#endif
#include "system_info.c"
/* Displays hexadecimal strings */
@ -43,8 +47,8 @@ static OQS_STATUS kem_test_correctness(const char *method_name) {
kem = OQS_KEM_new(method_name);
if (kem == NULL) {
// should always succeed since we don't call this function on KEMs that aren't enabled
return OQS_ERROR;
fprintf(stderr, "ERROR: OQS_KEM_new failed\n");
goto err;
}
printf("================================================================================\n");
@ -126,6 +130,19 @@ cleanup:
return ret;
}
#if OQS_USE_PTHREADS_IN_TESTS
struct thread_data {
char *alg_name;
OQS_STATUS rc;
};
void *test_wrapper(void *arg) {
struct thread_data *td = arg;
td->rc = kem_test_correctness(td->alg_name);
return NULL;
}
#endif
int main(int argc, char **argv) {
if (argc != 2) {
@ -143,14 +160,44 @@ int main(int argc, char **argv) {
print_system_info();
char *alg_name = argv[1];
if (!OQS_KEM_alg_is_enabled(alg_name)) {
printf("KEM algorithm %s not enabled!\n", alg_name);
return EXIT_FAILURE;
}
// Use system RNG in this program
OQS_randombytes_switch_algorithm(OQS_RAND_alg_system);
char *alg_name = argv[1];
if (!OQS_KEM_alg_is_enabled(alg_name)) {
return EXIT_FAILURE;
OQS_STATUS rc;
#if OQS_USE_PTHREADS_IN_TESTS
#define MAX_LEN_KEM_NAME_ 64
// don't run Classic McEliece or LEDAcryptKEM-LT52 in threads because of large stack usage
char no_thread_kem_patterns[][MAX_LEN_KEM_NAME_] = {"Classic-McEliece", "LEDAcryptKEM-LT52"};
int test_in_thread = 1;
for (size_t i = 0 ; i < sizeof(no_thread_kem_patterns) / MAX_LEN_KEM_NAME_; ++i) {
if (strstr(alg_name, no_thread_kem_patterns[i]) != NULL) {
test_in_thread = 0;
break;
}
}
OQS_STATUS rc = kem_test_correctness(alg_name);
if (test_in_thread) {
pthread_t thread;
struct thread_data td;
td.alg_name = alg_name;
int trc = pthread_create(&thread, NULL, test_wrapper, &td);
if (trc) {
fprintf(stderr, "ERROR: Creating pthread\n");
return EXIT_FAILURE;
}
pthread_join(thread, NULL);
rc = td.rc;
} else {
rc = kem_test_correctness(alg_name);
}
#else
rc = kem_test_correctness(alg_name);
#endif
if (rc != OQS_SUCCESS) {
return EXIT_FAILURE;
}

View File

@ -8,6 +8,10 @@
#include <oqs/oqs.h>
#if OQS_USE_PTHREADS_IN_TESTS
#include <pthread.h>
#endif
#include "system_info.c"
static OQS_STATUS sig_test_correctness(const char *method_name) {
@ -23,8 +27,8 @@ static OQS_STATUS sig_test_correctness(const char *method_name) {
sig = OQS_SIG_new(method_name);
if (sig == NULL) {
// should always succeed since we don't call this function on KEMs that aren't enabled
return OQS_ERROR;
fprintf(stderr, "ERROR: OQS_SIG_new failed\n");
goto err;
}
printf("================================================================================\n");
@ -87,6 +91,19 @@ cleanup:
return ret;
}
#if OQS_USE_PTHREADS_IN_TESTS
struct thread_data {
char *alg_name;
OQS_STATUS rc;
};
void *test_wrapper(void *arg) {
struct thread_data *td = arg;
td->rc = sig_test_correctness(td->alg_name);
return NULL;
}
#endif
int main(int argc, char **argv) {
if (argc != 2) {
@ -104,14 +121,44 @@ int main(int argc, char **argv) {
print_system_info();
char *alg_name = argv[1];
if (!OQS_SIG_alg_is_enabled(alg_name)) {
printf("Signature algorithm %s not enabled!\n", alg_name);
return EXIT_FAILURE;
}
// Use system RNG in this program
OQS_randombytes_switch_algorithm(OQS_RAND_alg_system);
char *alg_name = argv[1];
if (!OQS_SIG_alg_is_enabled(alg_name)) {
return EXIT_FAILURE;
OQS_STATUS rc;
#if OQS_USE_PTHREADS_IN_TESTS
#define MAX_LEN_SIG_NAME_ 64
// don't run Rainbow IIIc and Vc in threads because of large stack usage
char no_thread_sig_patterns[][MAX_LEN_SIG_NAME_] = {"Rainbow-IIIc", "Rainbow-Vc"};
int test_in_thread = 1;
for (size_t i = 0 ; i < sizeof(no_thread_sig_patterns) / MAX_LEN_SIG_NAME_; ++i) {
if (strstr(alg_name, no_thread_sig_patterns[i]) != NULL) {
test_in_thread = 0;
break;
}
}
OQS_STATUS rc = sig_test_correctness(alg_name);
if (test_in_thread) {
pthread_t thread;
struct thread_data td;
td.alg_name = alg_name;
int trc = pthread_create(&thread, NULL, test_wrapper, &td);
if (trc) {
fprintf(stderr, "ERROR: Creating pthread\n");
return EXIT_FAILURE;
}
pthread_join(thread, NULL);
rc = td.rc;
} else {
rc = sig_test_correctness(alg_name);
}
#else
rc = sig_test_correctness(alg_name);
#endif
if (rc != OQS_SUCCESS) {
return EXIT_FAILURE;
}