NIST std algs list selection enablement (#1355)

* std/r4/all algs enablement

* Switch example to use Kyber-768.

* std algs as option only

Co-authored-by: Douglas Stebila <dstebila@uwaterloo.ca>
This commit is contained in:
Michael Baentsch 2023-01-14 10:01:29 +01:00 committed by GitHub
parent aed3b4965f
commit fe3cb02cb1
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
10 changed files with 119 additions and 77 deletions

View File

@ -2,6 +2,48 @@
include(CMakeDependentOption)
# Switch off all algs except for those passed in the alglist
function(filter_algs alglist)
# Set every OQS_ENABLE_* variable =OFF unless one of the following conditions holds:
# 1. the switch for one of the requested minimal build algorithm's family, e.g OQS_ENABLE_KEM_KYBER
# 2. the switch for one of the requested algorithms, e.g. OQS_ENABLE_KEM_kyber_768.
# 3. the switch for platform-specific ("_aesni" or "_avx2") implementation of
# one of the requested algorithms, e.g. OQS_ENABLE_KEM_kyber_768_avx2.
get_cmake_property(_vars VARIABLES)
foreach (_var ${_vars})
if(_var MATCHES "^OQS_ENABLE_..._" AND NOT _var MATCHES "_AVAILABLE$" AND ${_var})
set(${_var} OFF PARENT_SCOPE)
# Case 1, family name
foreach (_alg ${ARGV0})
string(TOUPPER ${_alg} upalg)
if("OQS_ENABLE_${upalg}i" MATCHES "^${_var}")
set(${_var} ON PARENT_SCOPE)
endif()
endforeach()
# Case 2, exact match
foreach (_alg ${ARGV0})
if(${_var}X STREQUAL "OQS_ENABLE_${_alg}X")
set(${_var} ON PARENT_SCOPE)
endif()
endforeach()
# Case 3, platform specific
string(REPLACE "_aesni" "" _var_base ${_var})
string(REPLACE "_avx2" "" _var_base ${_var_base})
string(REPLACE "_avx" "" _var_base ${_var_base})
string(REPLACE "_aarch64" "" _var_base ${_var_base})
foreach (_alg ${ARGV0})
if(${_var}_AVAILABLE)
if(${_var_base}X STREQUAL ${_alg}X)
set(${_var} ON PARENT_SCOPE)
endif()
endif()
endforeach()
endif()
endforeach()
message(STATUS "Algorithms filtered for ${ARGV0}")
endfunction()
if(DEFINED OQS_KEM_DEFAULT)
message(WARNING "OQS_KEM_DEFAULT not longer supported")
endif()
@ -490,42 +532,18 @@ if((OQS_MINIMAL_BUILD STREQUAL "ON"))
message(FATAL_ERROR "OQS_MINIMAL_BUILD option ${OQS_MINIMAL_BUILD} no longer supported")
endif()
if(NOT ((OQS_MINIMAL_BUILD STREQUAL "") OR (OQS_MINIMAL_BUILD STREQUAL "OFF")))
# Set every OQS_ENABLE_* variable =OFF unless it one of the following.
# 1. the switch for one of the requested minimal build algorithm's family, e.g OQS_ENABLE_KEM_KYBER
# 2. the switch for one of the requested algorithms, e.g. OQS_ENABLE_KEM_kyber_768.
# 3. the switch for platform-specific ("_aesni" or "_avx2") implementation of
# one of the requested algorithms, e.g. OQS_ENABLE_KEM_kyber_768_avx2.
get_cmake_property(_vars VARIABLES)
foreach (_var ${_vars})
if(_var MATCHES "^OQS_ENABLE_..._" AND NOT _var MATCHES "_AVAILABLE$")
set(${_var} OFF)
# Case 1, family name
foreach (_alg ${OQS_MINIMAL_BUILD})
string(TOUPPER ${_alg} upalg)
if(${upalg} MATCHES "^${_var}")
set(${_var} ON)
endif()
endforeach()
# Case 2, exact match
foreach (_alg ${OQS_MINIMAL_BUILD})
if(${_var}X STREQUAL ${_alg}X)
set(${_var} ON)
endif()
endforeach()
# Case 3, platform specific
string(REPLACE "_aesni" "" _var_base ${_var})
string(REPLACE "_avx2" "" _var_base ${_var_base})
string(REPLACE "_avx" "" _var_base ${_var_base})
string(REPLACE "_aarch64" "" _var_base ${_var_base})
foreach (_alg ${OQS_MINIMAL_BUILD})
if(${_var}_AVAILABLE)
if(${_var_base}X STREQUAL ${_alg}X)
set(${_var} ON)
endif()
endif()
endforeach()
endif()
endforeach()
if(NOT DEFINED OQS_ALGS_ENABLED OR OQS_ALGS_ENABLED STREQUAL "")
set(OQS_ALGS_ENABLED "All")
endif()
if(NOT ((OQS_MINIMAL_BUILD STREQUAL "") OR (OQS_MINIMAL_BUILD STREQUAL "OFF")))
filter_algs("${OQS_MINIMAL_BUILD}")
elseif (${OQS_ALGS_ENABLED} STREQUAL "STD")
filter_algs("KEM_kyber_512;KEM_kyber_768;KEM_kyber_1024;SIG_dilithium_2;SIG_dilithium_3;SIG_dilithium_5;SIG_falcon_512;SIG_falcon_1024;SIG_sphincs_sha256_128f_simple;SIG_sphincs_sha256_128s_simple;SIG_sphincs_sha256_192f_simple;SIG_sphincs_sha256_192s_simple;SIG_sphincs_sha256_256f_simple;SIG_sphincs_sha256_256s_simple;SIG_sphincs_shake256_128f_simple;SIG_sphincs_shake256_128s_simple;SIG_sphincs_shake256_192f_simple;SIG_sphincs_shake256_192s_simple;SIG_sphincs_shake256_256f_simple;SIG_sphincs_shake256_256s_simple")
elseif(${OQS_ALGS_ENABLED} STREQUAL "NIST_R4")
filter_algs("KEM_classic_mceliece_348864;KEM_classic_mceliece_348864f;KEM_classic_mceliece_460896;KEM_classic_mceliece_460896f;KEM_classic_mceliece_6688128;KEM_classic_mceliece_6688128f;KEM_classic_mceliece_6960119;KEM_classic_mceliece_6960119f;KEM_classic_mceliece_8192128;KEM_classic_mceliece_8192128f;KEM_hqc_128;KEM_hqc_192;KEM_hqc_256;KEM_bike_l1;KEM_bike_l3")
else()
message(STATUS "Alg enablement unchanged")
endif()

View File

@ -70,7 +70,7 @@ jobs:
mkdir build && cd build && source ~/.bashrc && \
cmake .. --warn-uninitialized \
-GNinja << parameters.CMAKE_ARGS >> \
-DOQS_MINIMAL_BUILD="OQS_ENABLE_KEM_<< parameters.KEM_NAME >>;OQS_ENABLE_SIG_<< parameters.SIG_NAME >>" \
-DOQS_MINIMAL_BUILD="KEM_<< parameters.KEM_NAME >>;SIG_<< parameters.SIG_NAME >>" \
> config.log 2>&1 && \
cat config.log && \
cmake -LA .. && ! (grep "uninitialized variable" config.log)

View File

@ -35,7 +35,7 @@ jobs:
cd build && \
cmake .. --warn-uninitialized \
-GNinja \
-DOQS_MINIMAL_BUILD="OQS_ENABLE_KEM_$KEM_NAME;OQS_ENABLE_SIG_$SIG_NAME" \
-DOQS_MINIMAL_BUILD="KEM_$KEM_NAME;SIG_$SIG_NAME" \
> config.log 2>&1 && \
cat config.log && \
cmake -LA .. && \
@ -63,6 +63,10 @@ jobs:
container: openquantumsafe/ci-alpine-amd64:latest
CMAKE_ARGS: -DOQS_USE_OPENSSL=OFF
PYTEST_ARGS: --ignore=tests/test_alg_info.py
- name: focal-std-openssl
container: openquantumsafe/ci-ubuntu-focal-x86_64:latest
CMAKE_ARGS: -DOQS_ALGS_ENABLED=STD
PYTEST_ARGS: --ignore=tests/test_leaks.py
# disabled until #1067 lands
# - name: address-sanitizer
# container: openquantumsafe/ci-ubuntu-focal-x86_64:latest

View File

@ -6,6 +6,7 @@ The following options can be passed to CMake before the build file generation pr
- [BUILD_SHARED_LIBS](#BUILD_SHARED_LIBS)
- [CMAKE_BUILD_TYPE](#CMAKE_BUILD_TYPE)
- [CMAKE_INSTALL_PREFIX](#CMAKE_INSTALL_PREFIX)
- [OQS_ALGS_ENABLED](#OQS_ALGS_ENABLED)
- [OQS_BUILD_ONLY_LIB](#OQS_BUILD_ONLY_LIB)
- [OQS_ENABLE_KEM_ALG/OQS_ENABLE_SIG_ALG](#OQS_ENABLE_KEM_ALG/OQS_ENABLE_SIG_ALG)
- [OQS_MINIMAL_BUILD](#OQS_MINIMAL_BUILD)
@ -43,13 +44,17 @@ For example: if `OQS_ENABLE_KEM_BIKE` is set to `ON`, the options `OQS_ENABLE_KE
For a full list of such options and their default values, consult [.CMake/alg_support.cmake](https://github.com/open-quantum-safe/liboqs/blob/master/.CMake/alg_support.cmake).
## OQS_ALGS_ENABLED
Selects algorithm set enabled. Possible values are "STD" selecting all algorithms standardized by NIST; "NIST_R4" selecting all algorithms evaluated in round 4 of the NIST PQC competition; "All" (or any other value) selecting all algorithms integrated into liboqs. If the parameter is not given "All" is set by default. Parameter setting "STD" minimizes library size but may require re-running code generator scripts in projects integrating `liboqs`, e.g., [oqs-openssl111](https://github.com/open-quantum-safe/openssl) or [oqs-openssh](https://github.com/open-quantum-safe/openssh).
## OQS_BUILD_ONLY_LIB
Can be `ON` or `OFF`. When `ON`, only liboqs is built, and all the targets: `run_tests`, `gen_docs`, and `prettyprint` are excluded from the build system.
## OQS_MINIMAL_BUILD
If set, this defines a semicolon deliminated list of algorithms to be contained in a minimal build of `liboqs`: Only algorithms explicitly set here are included in a build: For example running `cmake -DOQS_MINIMAL_BUILD="OQS_ENABLE_KEM_kyber_768;OQS_ENABLE_SIG_dilithium_3" ..` will build a minimum-size `liboqs` library only containing support for Kyber768 and Dilithium3.
If set, this defines a semicolon deliminated list of algorithms to be contained in a minimal build of `liboqs`: Only algorithms explicitly set here are included in a build: For example running `cmake -DOQS_MINIMAL_BUILD="KEM_kyber_768;SIG_dilithium_3" ..` will build a minimum-size `liboqs` library only containing support for Kyber768 and Dilithium3.
The full list of identifiers that can set are listed [here for KEM algorithms](https://github.com/open-quantum-safe/liboqs/blob/main/src/kem/kem.h#L34) and [here for Signature algorithms](https://github.com/open-quantum-safe/liboqs/blob/f3caccff9e6225e7c50ca27f5ee6e58b7bc74188/src/sig/sig.h#L34). Default setting is empty, thus including all [supported algorithms](https://github.com/open-quantum-safe/liboqs#supported-algorithms) in the build.

View File

@ -36,6 +36,8 @@ More information on OQS can be found [here](https://openquantumsafe.org/) and in
Details on each supported algorithm can be found in the [docs/algorithms](https://github.com/open-quantum-safe/liboqs/tree/main/docs/algorithms) folder.
The list below indicates all algorithms supported by liboqs, but not all those algorithms have been selected for standardization by NIST, specifically Kyber (excluding the "-90s" variants), Dilithium (excluding the "-AES" variants), Falcon, and SPHINCS+ (excluding the "robust" variants). Activating only those standardized algorithms for use in `liboqs` can be facilitated by setting the [OQS_ALGS_ENABLED](CONFIGURE.md#oqs_algs_enabled) build configuration variable to `STD`. By default `liboqs` is built supporting all, incl. experimental, PQ algorithms listed below.
#### Key encapsulation mechanisms
<!--- OQS_TEMPLATE_FRAGMENT_LIST_KEXS_START -->

View File

@ -14,16 +14,21 @@ environment:
matrix:
- BUILD_SHARED: ON
COMPILER: cygwin
OQS_ALGS_ENABLED: All
- BUILD_SHARED: OFF
COMPILER: cygwin
OQS_ALGS_ENABLED: STD
- BUILD_SHARED: ON
OQS_USE_OPENSSL: ON
COMPILER: cygwin
OQS_ALGS_ENABLED: NIST_R4
- BUILD_SHARED: OFF
COMPILER: msvc2019
OQS_ALGS_ENABLED: NIST_R4
- BUILD_SHARED: OFF
COMPILER: msvc2019
OQS_USE_OPENSSL: ON
OQS_ALGS_ENABLED: All
- BUILD_SHARED: ON
COMPILER: msvc2019
# Disabled until https://github.com/open-quantum-safe/liboqs/issues/1218#issuecomment-1170067669 resolved

View File

@ -2,12 +2,12 @@
IF %COMPILER%==cygwin (
@echo on
SET "PATH=C:\cywin64\bin;c:\cygwin64;%PATH%"
c:\cygwin64\bin\bash.exe -lc "setup-x86_64.exe -qnNdO -R C:/cygwin64 -l C:/cygwin/var/cache/setup -P openssl -P libssl-devel -P ninja -P cmake -P gcc && cd ${APPVEYOR_BUILD_FOLDER} && openssl version && cygcheck -c && pwd && mkdir build && cd build && cmake .. -GNinja -DCMAKE_C_COMPILER=gcc -DOQS_DIST_BUILD=ON -DOQS_ENABLE_SIG_SPHINCS=OFF -DBUILD_SHARED_LIBS=%BUILD_SHARED% -DOQS_USE_OPENSSL=%OQS_USE_OPENSSL% && ninja "
c:\cygwin64\bin\bash.exe -lc "setup-x86_64.exe -qnNdO -R C:/cygwin64 -l C:/cygwin/var/cache/setup -P openssl -P libssl-devel -P ninja -P cmake -P gcc && cd ${APPVEYOR_BUILD_FOLDER} && openssl version && cygcheck -c && pwd && mkdir build && cd build && cmake .. -GNinja -DCMAKE_C_COMPILER=gcc -DOQS_DIST_BUILD=ON -DOQS_ENABLE_SIG_SPHINCS=OFF -DBUILD_SHARED_LIBS=%BUILD_SHARED% -DOQS_USE_OPENSSL=%OQS_USE_OPENSSL% -DOQS_ALGS_ENABLED=%OQS_ALGS_ENABLED% && ninja "
)
IF %COMPILER%==msys2 (
@echo on
SET "PATH=C:\msys64\mingw64\bin;%PATH%"
bash -lc "cd ${APPVEYOR_BUILD_FOLDER} && mkdir build && cd build && cmake .. -GNinja -DOQS_DIST_BUILD=ON -DOQS_ENABLE_SIG_SPHINCS=OFF -DBUILD_SHARED_LIBS=%BUILD_SHARED% -DOQS_USE_OPENSSL=%OQS_USE_OPENSSL% && ninja"
bash -lc "cd ${APPVEYOR_BUILD_FOLDER} && mkdir build && cd build && cmake .. -GNinja -DOQS_DIST_BUILD=ON -DOQS_ENABLE_SIG_SPHINCS=OFF -DBUILD_SHARED_LIBS=%BUILD_SHARED% -DOQS_USE_OPENSSL=%OQS_USE_OPENSSL% -DOQS_ALGS_ENABLED=%OQS_ALGS_ENABLED% && ninja"
)
IF %COMPILER%==msvc2019 (
@echo on
@ -15,6 +15,6 @@ IF %COMPILER%==msvc2019 (
mkdir build
cd build
REM SPHINCS causes a big slowdown in the tests
cmake .. -GNinja -DOQS_DIST_BUILD=ON -DOQS_ENABLE_SIG_SPHINCS=OFF -DBUILD_SHARED_LIBS=%BUILD_SHARED% -DOQS_USE_OPENSSL=%OQS_USE_OPENSSL%
cmake .. -GNinja -DOQS_DIST_BUILD=ON -DOQS_ENABLE_SIG_SPHINCS=OFF -DBUILD_SHARED_LIBS=%BUILD_SHARED% -DOQS_USE_OPENSSL=%OQS_USE_OPENSSL% -DOQS_ALGS_ENABLED=%OQS_ALGS_ENABLED%
ninja
)

View File

@ -883,7 +883,7 @@ INPUT = src/common/common.h \
src/sig/sig.h \
README.md \
CONFIGURE.md \
CONTRIBUTORS
CONTRIBUTORS
# This tag can be used to specify the character encoding of the source files
# that doxygen parses. Internally doxygen uses the UTF-8 encoding. Doxygen uses
@ -1710,8 +1710,8 @@ MATHJAX_RELPATH = https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.2/
# The MATHJAX_EXTENSIONS tag can be used to specify one or more MathJax
# extension names that should be enabled during MathJax rendering. For example
# for MathJax version 2 (see https://docs.mathjax.org/en/v2.7-latest/tex.html
# #tex-and-latex-extensions):
# for MathJax version 2 (see
# https://docs.mathjax.org/en/v2.7-latest/tex.html#tex-and-latex-extensions):
# MATHJAX_EXTENSIONS = TeX/AMSmath TeX/AMSsymbols
# For example for MathJax version 3 (see
# http://docs.mathjax.org/en/latest/input/tex/extensions/index.html):

View File

@ -29,55 +29,55 @@ void cleanup_heap(uint8_t *secret_key, uint8_t *shared_secret_e,
* statically on the stack, calling a specific algorithm's functions
* directly.
*
* The macros OQS_KEM_frodokem_640_aes_length_* and the functions
* OQS_KEM_frodokem_640_aes_* are only defined if the algorithm
* FrodoKEM-640-AES was enabled at compile-time which must be
* checked using the OQS_ENABLE_KEM_frodokem_640_aes macro.
* The macros OQS_KEM_kyber_768_length_* and the functions
* OQS_KEM_kyber_768_* are only defined if the algorithm
* Kyber-768 was enabled at compile-time which must be
* checked using the OQS_ENABLE_KEM_kyber_768 macro.
*
* <oqs/oqsconfig.h>, which is included in <oqs/oqs.h>, contains macros
* indicating which algorithms were enabled when this instance of liboqs
* was compiled.
*/
static OQS_STATUS example_stack(void) {
#ifndef OQS_ENABLE_KEM_frodokem_640_aes // if FrodoKEM-640-AES was not enabled at compile-time
printf("[example_stack] OQS_KEM_frodokem_640_aes was not enabled at "
#ifndef OQS_ENABLE_KEM_kyber_768 // if Kyber-768 was not enabled at compile-time
printf("[example_stack] OQS_KEM_kyber_768 was not enabled at "
"compile-time.\n");
return OQS_ERROR;
return OQS_SUCCESS; // nothing done successfully ;-)
#else
uint8_t public_key[OQS_KEM_frodokem_640_aes_length_public_key];
uint8_t secret_key[OQS_KEM_frodokem_640_aes_length_secret_key];
uint8_t ciphertext[OQS_KEM_frodokem_640_aes_length_ciphertext];
uint8_t shared_secret_e[OQS_KEM_frodokem_640_aes_length_shared_secret];
uint8_t shared_secret_d[OQS_KEM_frodokem_640_aes_length_shared_secret];
uint8_t public_key[OQS_KEM_kyber_768_length_public_key];
uint8_t secret_key[OQS_KEM_kyber_768_length_secret_key];
uint8_t ciphertext[OQS_KEM_kyber_768_length_ciphertext];
uint8_t shared_secret_e[OQS_KEM_kyber_768_length_shared_secret];
uint8_t shared_secret_d[OQS_KEM_kyber_768_length_shared_secret];
OQS_STATUS rc = OQS_KEM_frodokem_640_aes_keypair(public_key, secret_key);
OQS_STATUS rc = OQS_KEM_kyber_768_keypair(public_key, secret_key);
if (rc != OQS_SUCCESS) {
fprintf(stderr, "ERROR: OQS_KEM_frodokem_640_aes_keypair failed!\n");
cleanup_stack(secret_key, OQS_KEM_frodokem_640_aes_length_secret_key,
fprintf(stderr, "ERROR: OQS_KEM_kyber_768_keypair failed!\n");
cleanup_stack(secret_key, OQS_KEM_kyber_768_length_secret_key,
shared_secret_e, shared_secret_d,
OQS_KEM_frodokem_640_aes_length_shared_secret);
OQS_KEM_kyber_768_length_shared_secret);
return OQS_ERROR;
}
rc = OQS_KEM_frodokem_640_aes_encaps(ciphertext, shared_secret_e, public_key);
rc = OQS_KEM_kyber_768_encaps(ciphertext, shared_secret_e, public_key);
if (rc != OQS_SUCCESS) {
fprintf(stderr, "ERROR: OQS_KEM_frodokem_640_aes_encaps failed!\n");
cleanup_stack(secret_key, OQS_KEM_frodokem_640_aes_length_secret_key,
fprintf(stderr, "ERROR: OQS_KEM_kyber_768_encaps failed!\n");
cleanup_stack(secret_key, OQS_KEM_kyber_768_length_secret_key,
shared_secret_e, shared_secret_d,
OQS_KEM_frodokem_640_aes_length_shared_secret);
OQS_KEM_kyber_768_length_shared_secret);
return OQS_ERROR;
}
rc = OQS_KEM_frodokem_640_aes_decaps(shared_secret_d, ciphertext, secret_key);
rc = OQS_KEM_kyber_768_decaps(shared_secret_d, ciphertext, secret_key);
if (rc != OQS_SUCCESS) {
fprintf(stderr, "ERROR: OQS_KEM_frodokem_640_aes_decaps failed!\n");
cleanup_stack(secret_key, OQS_KEM_frodokem_640_aes_length_secret_key,
fprintf(stderr, "ERROR: OQS_KEM_kyber_768_decaps failed!\n");
cleanup_stack(secret_key, OQS_KEM_kyber_768_length_secret_key,
shared_secret_e, shared_secret_d,
OQS_KEM_frodokem_640_aes_length_shared_secret);
OQS_KEM_kyber_768_length_shared_secret);
return OQS_ERROR;
}
printf("[example_stack] OQS_KEM_frodokem_640_aes operations completed.\n");
printf("[example_stack] OQS_KEM_kyber_768 operations completed.\n");
return OQS_SUCCESS; // success!
#endif
@ -100,11 +100,11 @@ static OQS_STATUS example_heap(void) {
uint8_t *shared_secret_e = NULL;
uint8_t *shared_secret_d = NULL;
kem = OQS_KEM_new(OQS_KEM_alg_frodokem_640_aes);
kem = OQS_KEM_new(OQS_KEM_alg_kyber_768);
if (kem == NULL) {
printf("[example_heap] OQS_KEM_frodokem_640_aes was not enabled at "
printf("[example_heap] OQS_KEM_kyber_768 was not enabled at "
"compile-time.\n");
return OQS_ERROR;
return OQS_SUCCESS;
}
public_key = malloc(kem->length_public_key);
@ -146,7 +146,7 @@ static OQS_STATUS example_heap(void) {
return OQS_ERROR;
}
printf("[example_heap] OQS_KEM_frodokem_640_aes operations completed.\n");
printf("[example_heap] OQS_KEM_kyber_768 operations completed.\n");
cleanup_heap(secret_key, shared_secret_e, shared_secret_d, public_key,
ciphertext, kem);

View File

@ -77,7 +77,7 @@ static OQS_STATUS example_stack(void) {
#else
printf("[example_stack] OQS_SIG_dilithium_2 was not enabled at compile-time.\n");
return OQS_ERROR;
return OQS_SUCCESS;
#endif
}
@ -92,6 +92,8 @@ static OQS_STATUS example_stack(void) {
*/
static OQS_STATUS example_heap(void) {
#ifdef OQS_ENABLE_SIG_dilithium_2
OQS_SIG *sig = NULL;
uint8_t *public_key = NULL;
uint8_t *secret_key = NULL;
@ -142,6 +144,12 @@ static OQS_STATUS example_heap(void) {
printf("[example_heap] OQS_SIG_dilithium_2 operations completed.\n");
cleanup_heap(public_key, secret_key, message, signature, sig);
return OQS_SUCCESS; // success
#else
printf("[example_heap] OQS_SIG_dilithium_2 was not enabled at compile-time.\n");
return OQS_SUCCESS;
#endif
}
int main(void) {