mirror of
https://github.com/open-quantum-safe/liboqs.git
synced 2025-12-08 00:02:59 -05:00
add portability tests (#871)
* added portability tests only on Ubuntu, documentation added * using Westmere as test CPU type; disable avx2 for common code other than sha3x4 on portable builds * removed extraneous PORTABLE_BUILD guards
This commit is contained in:
parent
1fb8a3d382
commit
b08d581acb
@ -249,6 +249,7 @@ workflows:
|
||||
context: openquantumsafe
|
||||
CONTAINER: openquantumsafe/ci-ubuntu-bionic-x86_64:latest
|
||||
CMAKE_ARGS: -DCMAKE_C_COMPILER=clang-9 -DCMAKE_BUILD_TYPE=Debug -DUSE_SANITIZER=Address
|
||||
PYTEST_ARGS: --ignore=tests/test_portability.py --numprocesses=auto
|
||||
# Disabling for now due to https://github.com/open-quantum-safe/liboqs/issues/791
|
||||
#- linux_x64:
|
||||
# name: undefined-sanitizer
|
||||
|
||||
@ -112,6 +112,8 @@ The following instructions assume we are in `build`.
|
||||
|
||||
- `test_kem`: Simple test harness for key encapsulation mechanisms
|
||||
- `test_sig`: Simple test harness for key signature schemes
|
||||
- `test_kem_mem`: Simple test harness for checking memory consumption of key encapsulation mechanisms
|
||||
- `test_sig_mem`: Simple test harness for checking memory consumption of key signature schemes
|
||||
- `kat_kem`: Program that generates known answer test (KAT) values for key encapsulation mechanisms using the same procedure as the NIST submission requirements, for checking against submitted KAT values using `tests/test_kat.py`
|
||||
- `kat_sig`: Program that generates known answer test (KAT) values for signature schemes using the same procedure as the NIST submission requirements, for checking against submitted KAT values using `tests/test_kat.py`
|
||||
- `speed_kem`: Benchmarking program for key encapsulation mechanisms; see `./speed_kem --help` for usage instructions
|
||||
@ -119,6 +121,7 @@ The following instructions assume we are in `build`.
|
||||
- `example_kem`: Minimal runnable example showing the usage of the KEM API
|
||||
- `example_sig`: Minimal runnable example showing the usage of the signature API
|
||||
- `test_aes`, `test_sha3`: Simple test harnesses for crypto sub-components
|
||||
- `test_portability`: Simple test harnesses for checking cross-CPU code portability; requires presence of `qemu`; proper operation validated only on Ubuntu
|
||||
|
||||
The test suite can be run using
|
||||
|
||||
|
||||
@ -65,7 +65,8 @@ add_library(oqs kem/kem.c
|
||||
${KEM_OBJS}
|
||||
sig/sig.c
|
||||
${SIG_OBJS}
|
||||
$<TARGET_OBJECTS:common>)
|
||||
${COMMON_OBJS})
|
||||
set(COMMON_OBJS ${COMMON_OBJS} PARENT_SCOPE)
|
||||
if(DEFINED SANITIZER_LD_FLAGS)
|
||||
target_link_libraries(oqs PUBLIC ${SANITIZER_LD_FLAGS})
|
||||
endif()
|
||||
|
||||
@ -49,10 +49,18 @@ endif()
|
||||
|
||||
# That being said, code that requires these functions must take care to ensure
|
||||
# that they fall-back appropriately.
|
||||
# What must be ensured, though, is that only sha3x4 is compiled with avx2;
|
||||
# all other code must be compiled without this extension if portability is requested
|
||||
if(OQS_USE_AVX2_INSTRUCTIONS)
|
||||
if(OQS_PORTABLE_BUILD)
|
||||
add_library(sha3x4_avx2 OBJECT sha3/sha3x4.c)
|
||||
target_compile_options(sha3x4_avx2 PRIVATE -mavx2)
|
||||
set(_COMMON_OBJS $<TARGET_OBJECTS:sha3x4_avx2>)
|
||||
else()
|
||||
set(SHA3_IMPL ${SHA3_IMPL} sha3/sha3x4.c)
|
||||
add_compile_options(-mavx2)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
add_library(common OBJECT ${AES_IMPL}
|
||||
${SHA2_IMPL}
|
||||
@ -64,3 +72,6 @@ add_library(common OBJECT ${AES_IMPL}
|
||||
if(OQS_USE_OPENSSL)
|
||||
target_include_directories(common PRIVATE ${OPENSSL_INCLUDE_DIR})
|
||||
endif()
|
||||
|
||||
set(_COMMON_OBJS ${_COMMON_OBJS} $<TARGET_OBJECTS:common>)
|
||||
set(COMMON_OBJS ${_COMMON_OBJS} PARENT_SCOPE)
|
||||
|
||||
@ -10,7 +10,7 @@
|
||||
#include <windows.h>
|
||||
#endif
|
||||
|
||||
#if (defined(OQS_USE_CPU_EXTENSIONS) && defined(OQS_PORTABLE_BUILD))
|
||||
#if defined(OQS_USE_CPU_EXTENSIONS)
|
||||
|
||||
static OQS_CPU_EXTENSIONS available_cpu_extensions = { 0 };
|
||||
static unsigned int available_cpu_extensions_set = 0;
|
||||
@ -148,10 +148,10 @@ OQS_API OQS_CPU_EXTENSIONS OQS_get_available_CPU_extensions(void) {
|
||||
}
|
||||
return available_cpu_extensions;
|
||||
}
|
||||
#endif /* OQS_USE_CPU_EXTENSIONS && OQS_PORTABLE_BUILD */
|
||||
#endif /* OQS_USE_CPU_EXTENSIONS */
|
||||
|
||||
OQS_API void OQS_init(void) {
|
||||
#if (defined(OQS_USE_CPU_EXTENSIONS) && defined(OQS_PORTABLE_BUILD))
|
||||
#if defined(OQS_USE_CPU_EXTENSIONS)
|
||||
if (!available_cpu_extensions_set) {
|
||||
#if defined(ARCH_X86_64)
|
||||
set_available_cpu_extensions_x86_64();
|
||||
@ -160,7 +160,7 @@ OQS_API void OQS_init(void) {
|
||||
#endif /* ARCH_X86_64 or ARCH_ARM_ANY */
|
||||
available_cpu_extensions_set = 1;
|
||||
}
|
||||
#endif /* OQS_USE_CPU_EXTENSIONS && OQS_PORTABLE_BUILD */
|
||||
#endif /* OQS_USE_CPU_EXTENSIONS */
|
||||
}
|
||||
|
||||
OQS_API void OQS_MEM_cleanse(void *ptr, size_t len) {
|
||||
|
||||
@ -98,7 +98,7 @@ typedef enum {
|
||||
OQS_EXTERNAL_LIB_ERROR_OPENSSL = 50,
|
||||
} OQS_STATUS;
|
||||
|
||||
#if (defined(OQS_USE_CPU_EXTENSIONS) && defined(OQS_PORTABLE_BUILD))
|
||||
#if defined(OQS_USE_CPU_EXTENSIONS)
|
||||
|
||||
/**
|
||||
* Architecture macros.
|
||||
@ -147,7 +147,7 @@ OQS_API OQS_CPU_EXTENSIONS OQS_get_available_CPU_extensions(void);
|
||||
*/
|
||||
OQS_API const char *OQS_get_cpu_extension_name(unsigned int i);
|
||||
|
||||
#endif /* OQS_USE_CPU_EXTENSIONS && OQS_PORTABLE_BUILD */
|
||||
#endif /* OQS_USE_CPU_EXTENSIONS */
|
||||
|
||||
/**
|
||||
* This currently only sets the values in the OQS_CPU_EXTENSIONS,
|
||||
|
||||
@ -34,13 +34,13 @@ if(NOT WIN32)
|
||||
execute_process(COMMAND ${PROJECT_SOURCE_DIR}/scripts/git_commit.sh OUTPUT_VARIABLE GIT_COMMIT)
|
||||
add_definitions(-DOQS_COMPILE_GIT_COMMIT="${GIT_COMMIT}")
|
||||
|
||||
add_executable(test_aes test_aes.c $<TARGET_OBJECTS:common>)
|
||||
add_executable(test_aes test_aes.c ${COMMON_OBJS})
|
||||
target_link_libraries(test_aes PRIVATE ${INTERNAL_TEST_DEPS})
|
||||
|
||||
add_executable(test_hash test_hash.c $<TARGET_OBJECTS:common>)
|
||||
add_executable(test_hash test_hash.c ${COMMON_OBJS})
|
||||
target_link_libraries(test_hash PRIVATE ${INTERNAL_TEST_DEPS})
|
||||
|
||||
add_executable(test_sha3 test_sha3.c $<TARGET_OBJECTS:common>)
|
||||
add_executable(test_sha3 test_sha3.c ${COMMON_OBJS})
|
||||
target_link_libraries(test_sha3 PRIVATE ${INTERNAL_TEST_DEPS})
|
||||
|
||||
set(UNIX_TESTS test_aes test_hash test_sha3)
|
||||
|
||||
@ -60,7 +60,7 @@ static void print_platform_info(void) {
|
||||
|
||||
/* Display all active CPU extensions: */
|
||||
static void print_cpu_extensions(void) {
|
||||
#if defined(OQS_USE_CPU_EXTENSIONS) && defined(OQS_PORTABLE_BUILD)
|
||||
#if defined(OQS_USE_CPU_EXTENSIONS)
|
||||
/* Make CPU features struct iterable */
|
||||
typedef union ext_u {
|
||||
OQS_CPU_EXTENSIONS ext_x;
|
||||
@ -81,10 +81,15 @@ static void print_cpu_extensions(void) {
|
||||
}
|
||||
}
|
||||
}
|
||||
printf("\n");
|
||||
#else /* no extensions active */
|
||||
printf("CPU exts active: None\n");
|
||||
printf("CPU exts active: None");
|
||||
#endif
|
||||
#if defined(OQS_PORTABLE_BUILD)
|
||||
printf(" (portable build)\n");
|
||||
#else
|
||||
printf("\n");
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
static void print_oqs_configuration(void) {
|
||||
|
||||
44
tests/test_portability.py
Normal file
44
tests/test_portability.py
Normal file
@ -0,0 +1,44 @@
|
||||
# SPDX-License-Identifier: MIT
|
||||
|
||||
import helpers
|
||||
import pytest
|
||||
import platform
|
||||
from pathlib import Path
|
||||
|
||||
MIN_CPUS = {}
|
||||
# set other CPU types for other architectures; Westmere supports cpuid but not avx2
|
||||
MIN_CPUS["x86_64"] = "Westmere"
|
||||
|
||||
@helpers.filtered_test
|
||||
@pytest.mark.parametrize('kem_name', helpers.available_kems_by_name())
|
||||
@pytest.mark.skipif(not "Ubuntu" in platform.platform(), reason="Only supported on Ubuntu")
|
||||
def test_kem(kem_name):
|
||||
if not(helpers.is_build_portable()):
|
||||
pytest.skip("Portability not enabled")
|
||||
|
||||
if not(helpers.is_kem_enabled_by_name(kem_name)):
|
||||
pytest.skip('Not enabled')
|
||||
|
||||
helpers.run_subprocess(["qemu-"+platform.machine(), "-cpu", MIN_CPUS[platform.machine()],
|
||||
helpers.path_to_executable('test_kem'), kem_name])
|
||||
|
||||
@helpers.filtered_test
|
||||
@pytest.mark.parametrize('sig_name', helpers.available_sigs_by_name())
|
||||
@pytest.mark.skipif(not "Ubuntu" in platform.platform(), reason="Only supported on Ubuntu")
|
||||
def test_sig(sig_name):
|
||||
if not(helpers.is_build_portable()):
|
||||
pytest.skip("Portability not enabled")
|
||||
|
||||
if not(helpers.is_sig_enabled_by_name(sig_name)):
|
||||
pytest.skip('Not enabled')
|
||||
|
||||
if (sig_name.startswith("picnic")):
|
||||
pytest.skip("Picnic portability known to not be given.")
|
||||
|
||||
helpers.run_subprocess(["qemu-"+platform.machine(), "-cpu", MIN_CPUS[platform.machine()],
|
||||
helpers.path_to_executable('test_sig'), sig_name])
|
||||
|
||||
if __name__ == "__main__":
|
||||
import sys
|
||||
pytest.main(sys.argv)
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user