mirror of
				https://github.com/open-quantum-safe/liboqs.git
				synced 2025-11-04 00:02:35 -05:00 
			
		
		
		
	Merge pull request #397 from open-quantum-safe/master-sync-with-nist
Sync common files on master with nist-branch
This commit is contained in:
		
						commit
						fa7cf526e0
					
				
							
								
								
									
										10
									
								
								.travis.yml
									
									
									
									
									
								
							
							
						
						
									
										10
									
								
								.travis.yml
									
									
									
									
									
								
							@ -70,16 +70,6 @@ matrix:
 | 
				
			|||||||
    before_install:
 | 
					    before_install:
 | 
				
			||||||
    - brew update
 | 
					    - brew update
 | 
				
			||||||
    - brew install libsodium doxygen graphviz
 | 
					    - brew install libsodium doxygen graphviz
 | 
				
			||||||
  - os: osx
 | 
					 | 
				
			||||||
    compiler: clang
 | 
					 | 
				
			||||||
    env:
 | 
					 | 
				
			||||||
    - CC_OVERRIDE=clang
 | 
					 | 
				
			||||||
    - AES_NI=0
 | 
					 | 
				
			||||||
    - USE_OPENSSL=1
 | 
					 | 
				
			||||||
    - OPENSSL_DIR=/usr/local/opt/openssl # openssl is a keg-only package
 | 
					 | 
				
			||||||
    before_install:
 | 
					 | 
				
			||||||
    - brew update
 | 
					 | 
				
			||||||
    - brew install libsodium doxygen graphviz
 | 
					 | 
				
			||||||
  - os: osx
 | 
					  - os: osx
 | 
				
			||||||
    compiler: clang
 | 
					    compiler: clang
 | 
				
			||||||
    env:
 | 
					    env:
 | 
				
			||||||
 | 
				
			|||||||
@ -8,16 +8,20 @@ set -e
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
source $(dirname $0)/defs.sh
 | 
					source $(dirname $0)/defs.sh
 | 
				
			||||||
 | 
					
 | 
				
			||||||
# get the list of KEMs from the list of algorithm identifiers in enum OQS_KEM_alg_name in src/kem/kem.h
 | 
					# get the list of KEMs and signatures from the list of algorithm identifiers src/kem/kem.h and src/sig/sig.h
 | 
				
			||||||
KEMS=`grep 'define OQS_KEM_alg_' src/kem/kem.h | grep -v 'default' | sed -e 's/^[^"]*"//' | sed -e 's/".*$//' | tr -d '[:blank:]'`
 | 
					# FIXME: temporarily disabling signature algorithms
 | 
				
			||||||
 | 
					ALGS=$(grep -E 'define OQS_(KEM|SIG)_alg_' src/kem/kem.h | grep -v 'default' | sed -e 's/^[^"]*"//' | sed -e 's/".*$//' | tr -d '[:blank:]')
 | 
				
			||||||
 | 
					# ALGS=$(grep -E 'define OQS_(KEM|SIG)_alg_' src/kem/kem.h src/sig/sig.h | grep -v 'default' | sed -e 's/^[^"]*"//' | sed -e 's/".*$//' | tr -d '[:blank:]')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
RET=0
 | 
					RET=0
 | 
				
			||||||
for kem in ${KEMS}; do
 | 
					for alg in ${ALGS}; do
 | 
				
			||||||
	FOUND=`grep ${kem} docs/algorithms/*.md`
 | 
						set +e
 | 
				
			||||||
 | 
						FOUND=$(grep ${alg} docs/algorithms/*.md)
 | 
				
			||||||
 | 
						set -e
 | 
				
			||||||
	if [[ -z "${FOUND}" ]];
 | 
						if [[ -z "${FOUND}" ]];
 | 
				
			||||||
	then
 | 
						then
 | 
				
			||||||
		${PRINT_RED}
 | 
							${PRINT_RED}
 | 
				
			||||||
		echo "Could not find algorithm datasheet containing '${kem}'."
 | 
							echo "Could not find algorithm datasheet containing '${alg}'."
 | 
				
			||||||
		${PRINT_RESET}
 | 
							${PRINT_RESET}
 | 
				
			||||||
		RET=1
 | 
							RET=1
 | 
				
			||||||
	fi
 | 
						fi
 | 
				
			||||||
@ -26,7 +30,9 @@ done
 | 
				
			|||||||
if [[ "${RET}" == "0" ]];
 | 
					if [[ "${RET}" == "0" ]];
 | 
				
			||||||
then
 | 
					then
 | 
				
			||||||
	${PRINT_GREEN}
 | 
						${PRINT_GREEN}
 | 
				
			||||||
	echo "Algorithm datasheet present for all KEMs #defined in src/kem/kem.h.";
 | 
						# FIXME: temporarily disabling signature algorithms
 | 
				
			||||||
 | 
						echo "Algorithm datasheet present for all algs #defined in src/kem/kem.h.";
 | 
				
			||||||
 | 
						# echo "Algorithm datasheet present for all algs #defined in src/kem/kem.h and src/sig/sig.h.";
 | 
				
			||||||
	${PRINT_RESET}
 | 
						${PRINT_RESET}
 | 
				
			||||||
fi
 | 
					fi
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -12,7 +12,7 @@ RET=0
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
# We need to temporarily remove bash fail-on-error for the last command, because grep returns with error code 1 when there are no lines found
 | 
					# We need to temporarily remove bash fail-on-error for the last command, because grep returns with error code 1 when there are no lines found
 | 
				
			||||||
set +e
 | 
					set +e
 | 
				
			||||||
FREE=`find src -name '*.c' | grep -v upstream | xargs grep '[^_]free' | grep "free(" | grep -v 'IGNORE free-check'`
 | 
					FREE=$(find src -name '*.c' | grep -v upstream | xargs grep '[^_]free' | grep "free(" | grep -v 'IGNORE free-check')
 | 
				
			||||||
ERROR_CODE=$?
 | 
					ERROR_CODE=$?
 | 
				
			||||||
set -e
 | 
					set -e
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -18,7 +18,7 @@ then
 | 
				
			|||||||
fi
 | 
					fi
 | 
				
			||||||
 | 
					
 | 
				
			||||||
# Make sure that there are no modified files to start with
 | 
					# Make sure that there are no modified files to start with
 | 
				
			||||||
MODIFIED=`git status -s`
 | 
					MODIFIED=$(git status -s)
 | 
				
			||||||
if [[ ! -z "${MODIFIED}" ]];
 | 
					if [[ ! -z "${MODIFIED}" ]];
 | 
				
			||||||
then
 | 
					then
 | 
				
			||||||
	${PRINT_RED}
 | 
						${PRINT_RED}
 | 
				
			||||||
@ -29,9 +29,12 @@ then
 | 
				
			|||||||
fi;
 | 
					fi;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
# Find clang-format
 | 
					# Find clang-format
 | 
				
			||||||
TRY_CLANGFORMAT="clang-format-3.9"
 | 
					TRY_CLANGFORMAT="/usr/local/Cellar/clang-format/2016-06-27/bin/clang-format"
 | 
				
			||||||
if [[ ! -x $(which ${TRY_CLANGFORMAT}) ]];
 | 
					if [[ ! -x $(which ${TRY_CLANGFORMAT}) ]];
 | 
				
			||||||
then
 | 
					then
 | 
				
			||||||
 | 
						TRY_CLANGFORMAT="clang-format-3.9"
 | 
				
			||||||
 | 
						if [[ ! -x $(which ${TRY_CLANGFORMAT}) ]];
 | 
				
			||||||
 | 
						then
 | 
				
			||||||
		TRY_CLANGFORMAT="clang-format"
 | 
							TRY_CLANGFORMAT="clang-format"
 | 
				
			||||||
		if [[ ! -x $(which ${TRY_CLANGFORMAT}) ]];
 | 
							if [[ ! -x $(which ${TRY_CLANGFORMAT}) ]];
 | 
				
			||||||
		then
 | 
							then
 | 
				
			||||||
@ -40,11 +43,12 @@ then
 | 
				
			|||||||
			${PRINT_RESET}
 | 
								${PRINT_RESET}
 | 
				
			||||||
			exit 1
 | 
								exit 1
 | 
				
			||||||
		fi
 | 
							fi
 | 
				
			||||||
 | 
						fi
 | 
				
			||||||
fi
 | 
					fi
 | 
				
			||||||
 | 
					
 | 
				
			||||||
# Check clang-format version
 | 
					# Check clang-format version
 | 
				
			||||||
set +e
 | 
					set +e
 | 
				
			||||||
CLANG_FORMAT_VERSION=`${TRY_CLANGFORMAT} -version | grep 3.9`
 | 
					CLANG_FORMAT_VERSION=$(${TRY_CLANGFORMAT} -version | grep 3.9)
 | 
				
			||||||
ERROR_CODE=$?
 | 
					ERROR_CODE=$?
 | 
				
			||||||
set -e
 | 
					set -e
 | 
				
			||||||
if [ ${ERROR_CODE} -ne 0 ];
 | 
					if [ ${ERROR_CODE} -ne 0 ];
 | 
				
			||||||
@ -60,7 +64,7 @@ fi;
 | 
				
			|||||||
make prettyprint CLANGFORMAT=${TRY_CLANGFORMAT}
 | 
					make prettyprint CLANGFORMAT=${TRY_CLANGFORMAT}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
# Check if there are any modified files
 | 
					# Check if there are any modified files
 | 
				
			||||||
MODIFIED=`git status -s`
 | 
					MODIFIED=$(git status -s)
 | 
				
			||||||
if [[ ! -z "${MODIFIED}" ]]; then
 | 
					if [[ ! -z "${MODIFIED}" ]]; then
 | 
				
			||||||
	${PRINT_RED}
 | 
						${PRINT_RED}
 | 
				
			||||||
	echo "Code does not adhere to the project standards. Run \"make prettyprint\".";
 | 
						echo "Code does not adhere to the project standards. Run \"make prettyprint\".";
 | 
				
			||||||
 | 
				
			|||||||
@ -26,7 +26,7 @@ Security
 | 
				
			|||||||
Parameter set 1
 | 
					Parameter set 1
 | 
				
			||||||
---------------
 | 
					---------------
 | 
				
			||||||
 | 
					
 | 
				
			||||||
"qTESLA-I" parameter set from [qTesla]
 | 
					`qTESLA_I` parameter set from [qTesla]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
**Claimed classical security:** 
 | 
					**Claimed classical security:** 
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -45,7 +45,7 @@ Parameter set 1
 | 
				
			|||||||
Parameter set 2
 | 
					Parameter set 2
 | 
				
			||||||
---------------
 | 
					---------------
 | 
				
			||||||
 | 
					
 | 
				
			||||||
"qTESLA-III-speed" parameter set from [qTesla]
 | 
					`qTESLA_III_speed` parameter set from [qTesla]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
**Claimed classical security:** 
 | 
					**Claimed classical security:** 
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -64,7 +64,7 @@ Parameter set 2
 | 
				
			|||||||
Parameter set 3
 | 
					Parameter set 3
 | 
				
			||||||
---------------
 | 
					---------------
 | 
				
			||||||
 | 
					
 | 
				
			||||||
"qTESLA-III-size" parameter set from [qTesla]
 | 
					`qTESLA_III_size` parameter set from [qTesla]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
**Claimed classical security:** 
 | 
					**Claimed classical security:** 
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -11,10 +11,10 @@ PRINT_YELLOW="tput setaf 3"
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
RET=0
 | 
					RET=0
 | 
				
			||||||
 | 
					
 | 
				
			||||||
ALGS=`grep -E 'define OQS_(KEM|SIG)_alg_' src/kem/kem.h src/sig/sig.h | grep -v 'default' | grep -v 'sidh' | sed -e 's/^[^"]*"//' | sed -e 's/".*$//' | tr -d '[:blank:]'`
 | 
					ALGS=$(grep -E 'define OQS_(KEM|SIG)_alg_' src/kem/kem.h src/sig/sig.h | grep -v 'default' | grep -v 'sidh' | sed -e 's/^[^"]*"//' | sed -e 's/".*$//' | tr -d '[:blank:]')
 | 
				
			||||||
for alg in ${ALGS}; do
 | 
					for alg in ${ALGS}; do
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	kat=`find kat_*_rsp -name ${alg}.kat |tr '\n' ' '`
 | 
						kat=$(find kat_*_rsp -name ${alg}.kat |tr '\n' ' ')
 | 
				
			||||||
	if [ -z "${kat}" ];
 | 
						if [ -z "${kat}" ];
 | 
				
			||||||
	then
 | 
						then
 | 
				
			||||||
		${PRINT_YELLOW}
 | 
							${PRINT_YELLOW}
 | 
				
			||||||
@ -24,7 +24,7 @@ for alg in ${ALGS}; do
 | 
				
			|||||||
		continue
 | 
							continue
 | 
				
			||||||
	fi
 | 
						fi
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	origs=`find src -name ${alg}.kat -o -name ${alg}.*.kat |tr '\n' ' '`
 | 
						origs=$(find src -name ${alg}.kat -o -name ${alg}.*.kat |tr '\n' ' ')
 | 
				
			||||||
	if [[ "x${origs}x" == "xx" ]];
 | 
						if [[ "x${origs}x" == "xx" ]];
 | 
				
			||||||
	then
 | 
						then
 | 
				
			||||||
		${PRINT_RED}
 | 
							${PRINT_RED}
 | 
				
			||||||
 | 
				
			|||||||
@ -8,7 +8,7 @@
 | 
				
			|||||||
#include <windows.h>
 | 
					#include <windows.h>
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void OQS_API OQS_MEM_cleanse(void *ptr, size_t len) {
 | 
					OQS_API void OQS_MEM_cleanse(void *ptr, size_t len) {
 | 
				
			||||||
#if defined(_WIN32)
 | 
					#if defined(_WIN32)
 | 
				
			||||||
	SecureZeroMemory(ptr, len);
 | 
						SecureZeroMemory(ptr, len);
 | 
				
			||||||
#elif defined(HAVE_MEMSET_S)
 | 
					#elif defined(HAVE_MEMSET_S)
 | 
				
			||||||
@ -22,14 +22,14 @@ void OQS_API OQS_MEM_cleanse(void *ptr, size_t len) {
 | 
				
			|||||||
#endif
 | 
					#endif
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void OQS_API OQS_MEM_secure_free(void *ptr, size_t len) {
 | 
					OQS_API void OQS_MEM_secure_free(void *ptr, size_t len) {
 | 
				
			||||||
	if (ptr != NULL) {
 | 
						if (ptr != NULL) {
 | 
				
			||||||
		OQS_MEM_cleanse(ptr, len);
 | 
							OQS_MEM_cleanse(ptr, len);
 | 
				
			||||||
		free(ptr); // IGNORE free-check
 | 
							free(ptr); // IGNORE free-check
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void OQS_API OQS_MEM_insecure_free(void *ptr) {
 | 
					OQS_API void OQS_MEM_insecure_free(void *ptr) {
 | 
				
			||||||
	free(ptr); // IGNORE free-check
 | 
						free(ptr); // IGNORE free-check
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -8,6 +8,7 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
#include <stdint.h>
 | 
					#include <stdint.h>
 | 
				
			||||||
#include <stdlib.h>
 | 
					#include <stdlib.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#if defined(_WIN32)
 | 
					#if defined(_WIN32)
 | 
				
			||||||
#include <oqs/winconfig.h>
 | 
					#include <oqs/winconfig.h>
 | 
				
			||||||
#else
 | 
					#else
 | 
				
			||||||
@ -97,16 +98,6 @@ void OQS_MEM_secure_free(void *ptr, size_t len);
 | 
				
			|||||||
 */
 | 
					 */
 | 
				
			||||||
void OQS_MEM_insecure_free(void *ptr);
 | 
					void OQS_MEM_insecure_free(void *ptr);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/**
 | 
					 | 
				
			||||||
 * Function to print a message to standard error.  Workaround on Android to print
 | 
					 | 
				
			||||||
 * directly to stdout.
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
#if __ANDROID__
 | 
					 | 
				
			||||||
#define eprintf(...) printf(__VA_ARGS__);
 | 
					 | 
				
			||||||
#else
 | 
					 | 
				
			||||||
#define eprintf(...) fprintf(stderr, __VA_ARGS__);
 | 
					 | 
				
			||||||
#endif
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/**
 | 
					/**
 | 
				
			||||||
 * Macros that indicates a function argument may be unused.  Used to comply with
 | 
					 * Macros that indicates a function argument may be unused.  Used to comply with
 | 
				
			||||||
 * an API specification but when an implementation doesn't actually use the argument
 | 
					 * an API specification but when an implementation doesn't actually use the argument
 | 
				
			||||||
 | 
				
			|||||||
@ -9,11 +9,13 @@
 | 
				
			|||||||
#include <unistd.h>
 | 
					#include <unistd.h>
 | 
				
			||||||
#include <strings.h>
 | 
					#include <strings.h>
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
 | 
					 | 
				
			||||||
#include <fcntl.h>
 | 
					#include <fcntl.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include <oqs/oqs.h>
 | 
					#include <oqs/oqs.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void OQS_randombytes_system(uint8_t *random_array, size_t bytes_to_read);
 | 
				
			||||||
 | 
					void OQS_randombytes_nist_kat(uint8_t *random_array, size_t bytes_to_read);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#ifdef USE_OPENSSL
 | 
					#ifdef USE_OPENSSL
 | 
				
			||||||
#include <openssl/rand.h>
 | 
					#include <openssl/rand.h>
 | 
				
			||||||
// Use OpenSSL's RAND_bytes as the default PRNG
 | 
					// Use OpenSSL's RAND_bytes as the default PRNG
 | 
				
			||||||
@ -22,8 +24,6 @@ static void (*oqs_randombytes_algorithm)(uint8_t *, size_t) = (void (*)(uint8_t
 | 
				
			|||||||
static void (*oqs_randombytes_algorithm)(uint8_t *, size_t) = &OQS_randombytes_system;
 | 
					static void (*oqs_randombytes_algorithm)(uint8_t *, size_t) = &OQS_randombytes_system;
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void OQS_randombytes_nist_kat(uint8_t *random_array, size_t bytes_to_read);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
OQS_STATUS OQS_randombytes_switch_algorithm(const char *algorithm) {
 | 
					OQS_STATUS OQS_randombytes_switch_algorithm(const char *algorithm) {
 | 
				
			||||||
	if (0 == strcasecmp(OQS_RAND_alg_system, algorithm)) {
 | 
						if (0 == strcasecmp(OQS_RAND_alg_system, algorithm)) {
 | 
				
			||||||
		oqs_randombytes_algorithm = &OQS_randombytes_system;
 | 
							oqs_randombytes_algorithm = &OQS_randombytes_system;
 | 
				
			||||||
 | 
				
			|||||||
@ -12,19 +12,12 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
#include <oqs/common.h>
 | 
					#include <oqs/common.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/*********************
 | 
					 | 
				
			||||||
 *** START NEW API ***
 | 
					 | 
				
			||||||
 *********************/
 | 
					 | 
				
			||||||
/* TODO: Consider adding NIST-KAT PRNGs from nist-branch */
 | 
					 | 
				
			||||||
/* TODO: Decide how to do statistical testing of new PRNG */
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/** Algorithm identifier for system PRNG. */
 | 
					/** Algorithm identifier for system PRNG. */
 | 
				
			||||||
#define OQS_RAND_alg_system "system"
 | 
					#define OQS_RAND_alg_system "system"
 | 
				
			||||||
/** Algorithm identifier for using OpenSSL's PRNG. */
 | 
					 | 
				
			||||||
#define OQS_RAND_alg_openssl "OpenSSL"
 | 
					 | 
				
			||||||
/** Algorithm identifier for NIST deterministic RNG for KATs. */
 | 
					/** Algorithm identifier for NIST deterministic RNG for KATs. */
 | 
				
			||||||
#define OQS_RAND_alg_nist_kat "NIST-KAT"
 | 
					#define OQS_RAND_alg_nist_kat "NIST-KAT"
 | 
				
			||||||
/** Algorithm identifier for using OpenSSL's PRNG. */
 | 
					/** Algorithm identifier for using OpenSSL's PRNG. */
 | 
				
			||||||
 | 
					#define OQS_RAND_alg_openssl "OpenSSL"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/**
 | 
					/**
 | 
				
			||||||
 * Switches OQS_randombytes to use the specified algorithm.
 | 
					 * Switches OQS_randombytes to use the specified algorithm.
 | 
				
			||||||
@ -58,19 +51,6 @@ void OQS_randombytes_custom_algorithm(void (*algorithm_ptr)(uint8_t *, size_t));
 | 
				
			|||||||
 */
 | 
					 */
 | 
				
			||||||
void OQS_randombytes(uint8_t *random_array, size_t bytes_to_read);
 | 
					void OQS_randombytes(uint8_t *random_array, size_t bytes_to_read);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/**
 | 
					 | 
				
			||||||
 * Fills the given memory with the requested number of random bytes.
 | 
					 | 
				
			||||||
 *
 | 
					 | 
				
			||||||
 * This implementation reads the bytes directly from `/dev/urandom` and will
 | 
					 | 
				
			||||||
 * block until the requested number of bytes have been read.
 | 
					 | 
				
			||||||
 *
 | 
					 | 
				
			||||||
 * The caller is responsible for providing a buffer allocated with sufficient room.
 | 
					 | 
				
			||||||
 *
 | 
					 | 
				
			||||||
 * @param[out] random_array Pointer to the memory to fill with random bytes
 | 
					 | 
				
			||||||
 * @param[in] bytes_to_read The number of random bytes to read into memory
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
void OQS_randombytes_system(uint8_t *random_array, size_t bytes_to_read);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/**
 | 
					/**
 | 
				
			||||||
 * Initializes the NIST DRBG with a given seed.
 | 
					 * Initializes the NIST DRBG with a given seed.
 | 
				
			||||||
 *
 | 
					 *
 | 
				
			||||||
@ -80,10 +60,6 @@ void OQS_randombytes_system(uint8_t *random_array, size_t bytes_to_read);
 | 
				
			|||||||
 */
 | 
					 */
 | 
				
			||||||
void OQS_randombytes_nist_kat_init(const uint8_t *entropy_input, const uint8_t *personalization_string, int security_strength);
 | 
					void OQS_randombytes_nist_kat_init(const uint8_t *entropy_input, const uint8_t *personalization_string, int security_strength);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/********************
 | 
					 | 
				
			||||||
 *** STOP NEW API ***
 | 
					 | 
				
			||||||
 ********************/
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/************************************************************
 | 
					/************************************************************
 | 
				
			||||||
 *** START DEPRECATED CODE *** expected removal Sep. 2018 ***
 | 
					 *** START DEPRECATED CODE *** expected removal Sep. 2018 ***
 | 
				
			||||||
 ************************************************************/
 | 
					 ************************************************************/
 | 
				
			||||||
 | 
				
			|||||||
@ -10,6 +10,7 @@
 | 
				
			|||||||
#include <string.h>
 | 
					#include <string.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include <oqs/common.h>
 | 
					#include <oqs/common.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#if USE_OPENSSL
 | 
					#if USE_OPENSSL
 | 
				
			||||||
#include <openssl/conf.h>
 | 
					#include <openssl/conf.h>
 | 
				
			||||||
#include <openssl/evp.h>
 | 
					#include <openssl/evp.h>
 | 
				
			||||||
 | 
				
			|||||||
@ -142,6 +142,7 @@ OQS_API OQS_STATUS OQS_KEM_keypair(const OQS_KEM *kem, uint8_t *public_key, uint
 | 
				
			|||||||
		return kem->keypair(public_key, secret_key);
 | 
							return kem->keypair(public_key, secret_key);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
OQS_API OQS_STATUS OQS_KEM_encaps(const OQS_KEM *kem, uint8_t *ciphertext, uint8_t *shared_secret, const uint8_t *public_key) {
 | 
					OQS_API OQS_STATUS OQS_KEM_encaps(const OQS_KEM *kem, uint8_t *ciphertext, uint8_t *shared_secret, const uint8_t *public_key) {
 | 
				
			||||||
	if (kem == NULL) {
 | 
						if (kem == NULL) {
 | 
				
			||||||
		return OQS_ERROR;
 | 
							return OQS_ERROR;
 | 
				
			||||||
@ -149,6 +150,7 @@ OQS_API OQS_STATUS OQS_KEM_encaps(const OQS_KEM *kem, uint8_t *ciphertext, uint8
 | 
				
			|||||||
		return kem->encaps(ciphertext, shared_secret, public_key);
 | 
							return kem->encaps(ciphertext, shared_secret, public_key);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
OQS_API OQS_STATUS OQS_KEM_decaps(const OQS_KEM *kem, uint8_t *shared_secret, const unsigned char *ciphertext, const uint8_t *secret_key) {
 | 
					OQS_API OQS_STATUS OQS_KEM_decaps(const OQS_KEM *kem, uint8_t *shared_secret, const unsigned char *ciphertext, const uint8_t *secret_key) {
 | 
				
			||||||
	if (kem == NULL) {
 | 
						if (kem == NULL) {
 | 
				
			||||||
		return OQS_ERROR;
 | 
							return OQS_ERROR;
 | 
				
			||||||
 | 
				
			|||||||
@ -207,7 +207,7 @@ OQS_API OQS_STATUS OQS_KEM_decaps(const OQS_KEM *kem, uint8_t *shared_secret, co
 | 
				
			|||||||
 *
 | 
					 *
 | 
				
			||||||
 * @param[in] kem The OQS_KEM object to free.
 | 
					 * @param[in] kem The OQS_KEM object to free.
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
void OQS_KEM_free(OQS_KEM *kem);
 | 
					OQS_API void OQS_KEM_free(OQS_KEM *kem);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include <oqs/kem_bike.h>
 | 
					#include <oqs/kem_bike.h>
 | 
				
			||||||
#include <oqs/kem_frodokem.h>
 | 
					#include <oqs/kem_frodokem.h>
 | 
				
			||||||
 | 
				
			|||||||
@ -28,7 +28,7 @@ OQS_API const char *OQS_SIG_alg_identifier(size_t i) {
 | 
				
			|||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
OQS_SIG *OQS_SIG_new(const char *method_name) {
 | 
					OQS_API OQS_SIG *OQS_SIG_new(const char *method_name) {
 | 
				
			||||||
	if (0 == strcasecmp(method_name, OQS_SIG_alg_default)) {
 | 
						if (0 == strcasecmp(method_name, OQS_SIG_alg_default)) {
 | 
				
			||||||
		return OQS_SIG_new(OQS_SIG_DEFAULT);
 | 
							return OQS_SIG_new(OQS_SIG_DEFAULT);
 | 
				
			||||||
	} else if (0 == strcasecmp(method_name, OQS_SIG_alg_qTESLA_I)) {
 | 
						} else if (0 == strcasecmp(method_name, OQS_SIG_alg_qTESLA_I)) {
 | 
				
			||||||
@ -91,7 +91,7 @@ OQS_SIG *OQS_SIG_new(const char *method_name) {
 | 
				
			|||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
OQS_STATUS OQS_SIG_keypair(const OQS_SIG *sig, uint8_t *public_key, uint8_t *secret_key) {
 | 
					OQS_API OQS_STATUS OQS_SIG_keypair(const OQS_SIG *sig, uint8_t *public_key, uint8_t *secret_key) {
 | 
				
			||||||
	if (sig == NULL || sig->keypair(public_key, secret_key) != OQS_SUCCESS) {
 | 
						if (sig == NULL || sig->keypair(public_key, secret_key) != OQS_SUCCESS) {
 | 
				
			||||||
		return OQS_ERROR;
 | 
							return OQS_ERROR;
 | 
				
			||||||
	} else {
 | 
						} else {
 | 
				
			||||||
@ -99,7 +99,7 @@ OQS_STATUS OQS_SIG_keypair(const OQS_SIG *sig, uint8_t *public_key, uint8_t *sec
 | 
				
			|||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
OQS_STATUS OQS_SIG_sign(const OQS_SIG *sig, uint8_t *signature, size_t *signature_len, const uint8_t *message, size_t message_len, const uint8_t *secret_key) {
 | 
					OQS_API OQS_STATUS OQS_SIG_sign(const OQS_SIG *sig, uint8_t *signature, size_t *signature_len, const uint8_t *message, size_t message_len, const uint8_t *secret_key) {
 | 
				
			||||||
	if (sig == NULL || sig->sign(signature, signature_len, message, message_len, secret_key) != OQS_SUCCESS) {
 | 
						if (sig == NULL || sig->sign(signature, signature_len, message, message_len, secret_key) != OQS_SUCCESS) {
 | 
				
			||||||
		return OQS_ERROR;
 | 
							return OQS_ERROR;
 | 
				
			||||||
	} else {
 | 
						} else {
 | 
				
			||||||
@ -107,7 +107,7 @@ OQS_STATUS OQS_SIG_sign(const OQS_SIG *sig, uint8_t *signature, size_t *signatur
 | 
				
			|||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
OQS_STATUS OQS_SIG_verify(const OQS_SIG *sig, const uint8_t *message, size_t message_len, const uint8_t *signature, size_t signature_len, const uint8_t *public_key) {
 | 
					OQS_API OQS_STATUS OQS_SIG_verify(const OQS_SIG *sig, const uint8_t *message, size_t message_len, const uint8_t *signature, size_t signature_len, const uint8_t *public_key) {
 | 
				
			||||||
	if (sig == NULL || sig->verify(message, message_len, signature, signature_len, public_key) != OQS_SUCCESS) {
 | 
						if (sig == NULL || sig->verify(message, message_len, signature, signature_len, public_key) != OQS_SUCCESS) {
 | 
				
			||||||
		return OQS_ERROR;
 | 
							return OQS_ERROR;
 | 
				
			||||||
	} else {
 | 
						} else {
 | 
				
			||||||
@ -115,6 +115,6 @@ OQS_STATUS OQS_SIG_verify(const OQS_SIG *sig, const uint8_t *message, size_t mes
 | 
				
			|||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void OQS_SIG_free(OQS_SIG *sig) {
 | 
					OQS_API void OQS_SIG_free(OQS_SIG *sig) {
 | 
				
			||||||
	OQS_MEM_insecure_free(sig);
 | 
						OQS_MEM_insecure_free(sig);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -74,7 +74,7 @@ typedef struct OQS_SIG {
 | 
				
			|||||||
	/** Printable string representing the name of the signature scheme. */
 | 
						/** Printable string representing the name of the signature scheme. */
 | 
				
			||||||
	const char *method_name;
 | 
						const char *method_name;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/** The NIST security level (1, 2, 3, 4, 5) claimed for this algorithm. */
 | 
						/** The NIST security level (1, 2, 3, 4, 5) claimed in this algorithm's original NIST submission. */
 | 
				
			||||||
	uint8_t claimed_nist_level;
 | 
						uint8_t claimed_nist_level;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/** Whether the signature offers EUF-CMA security (TRUE) or not (FALSE). */
 | 
						/** Whether the signature offers EUF-CMA security (TRUE) or not (FALSE). */
 | 
				
			||||||
@ -142,7 +142,7 @@ typedef struct OQS_SIG {
 | 
				
			|||||||
 * @param[in] method_name Name of the desired algorithm; one of the names in `OQS_SIG_algs`.
 | 
					 * @param[in] method_name Name of the desired algorithm; one of the names in `OQS_SIG_algs`.
 | 
				
			||||||
 * @return An OQS_SIG for the particular algorithm, or `NULL` if the algorithm has been disabled at compile-time.
 | 
					 * @return An OQS_SIG for the particular algorithm, or `NULL` if the algorithm has been disabled at compile-time.
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
OQS_SIG *OQS_SIG_new(const char *method_name);
 | 
					OQS_API OQS_SIG *OQS_SIG_new(const char *method_name);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/**
 | 
					/**
 | 
				
			||||||
 * Keypair generation algorithm.
 | 
					 * Keypair generation algorithm.
 | 
				
			||||||
@ -156,7 +156,7 @@ OQS_SIG *OQS_SIG_new(const char *method_name);
 | 
				
			|||||||
 * @param[out] secret_key The secret key represented as a byte string.
 | 
					 * @param[out] secret_key The secret key represented as a byte string.
 | 
				
			||||||
 * @return OQS_SUCCESS or OQS_ERROR
 | 
					 * @return OQS_SUCCESS or OQS_ERROR
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
OQS_STATUS OQS_SIG_keypair(const OQS_SIG *sig, uint8_t *public_key, uint8_t *secret_key);
 | 
					OQS_API OQS_STATUS OQS_SIG_keypair(const OQS_SIG *sig, uint8_t *public_key, uint8_t *secret_key);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/**
 | 
					/**
 | 
				
			||||||
 * Signature generation algorithm.
 | 
					 * Signature generation algorithm.
 | 
				
			||||||
@ -173,7 +173,7 @@ OQS_STATUS OQS_SIG_keypair(const OQS_SIG *sig, uint8_t *public_key, uint8_t *sec
 | 
				
			|||||||
 * @param[in] secret_key The secret key represented as a byte string.
 | 
					 * @param[in] secret_key The secret key represented as a byte string.
 | 
				
			||||||
 * @return OQS_SUCCESS or OQS_ERROR
 | 
					 * @return OQS_SUCCESS or OQS_ERROR
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
OQS_STATUS OQS_SIG_sign(const OQS_SIG *sig, uint8_t *signature, size_t *signature_len, const uint8_t *message, size_t message_len, const uint8_t *secret_key);
 | 
					OQS_API OQS_STATUS OQS_SIG_sign(const OQS_SIG *sig, uint8_t *signature, size_t *signature_len, const uint8_t *message, size_t message_len, const uint8_t *secret_key);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/**
 | 
					/**
 | 
				
			||||||
 * Signature verification algorithm.
 | 
					 * Signature verification algorithm.
 | 
				
			||||||
@ -186,14 +186,14 @@ OQS_STATUS OQS_SIG_sign(const OQS_SIG *sig, uint8_t *signature, size_t *signatur
 | 
				
			|||||||
 * @param[in] public_key The public key represented as a byte string.
 | 
					 * @param[in] public_key The public key represented as a byte string.
 | 
				
			||||||
 * @return OQS_SUCCESS or OQS_ERROR
 | 
					 * @return OQS_SUCCESS or OQS_ERROR
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
OQS_STATUS OQS_SIG_verify(const OQS_SIG *sig, const uint8_t *message, size_t message_len, const uint8_t *signature, size_t signature_len, const uint8_t *public_key);
 | 
					OQS_API OQS_STATUS OQS_SIG_verify(const OQS_SIG *sig, const uint8_t *message, size_t message_len, const uint8_t *signature, size_t signature_len, const uint8_t *public_key);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/**
 | 
					/**
 | 
				
			||||||
 * Frees an OQS_SIG object that was constructed by OQS_SIG_new.
 | 
					 * Frees an OQS_SIG object that was constructed by OQS_SIG_new.
 | 
				
			||||||
 *
 | 
					 *
 | 
				
			||||||
 * @param[in] sig The OQS_SIG object to free.
 | 
					 * @param[in] sig The OQS_SIG object to free.
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
void OQS_SIG_free(OQS_SIG *sig);
 | 
					OQS_API void OQS_SIG_free(OQS_SIG *sig);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include <oqs/sig_qtesla.h>
 | 
					#include <oqs/sig_qtesla.h>
 | 
				
			||||||
#include <oqs/sig_picnic.h>
 | 
					#include <oqs/sig_picnic.h>
 | 
				
			||||||
 | 
				
			|||||||
@ -41,4 +41,5 @@ test_kem_LDADD        += -L$(OPENSSL_DIR)/lib -lcrypto
 | 
				
			|||||||
test_rand_LDADD       += -L$(OPENSSL_DIR)/lib -lcrypto
 | 
					test_rand_LDADD       += -L$(OPENSSL_DIR)/lib -lcrypto
 | 
				
			||||||
test_sha3_LDADD       += -L$(OPENSSL_DIR)/lib -lcrypto
 | 
					test_sha3_LDADD       += -L$(OPENSSL_DIR)/lib -lcrypto
 | 
				
			||||||
test_sig_LDADD        += -L$(OPENSSL_DIR)/lib -lcrypto
 | 
					test_sig_LDADD        += -L$(OPENSSL_DIR)/lib -lcrypto
 | 
				
			||||||
 | 
					kat_kem_LDADD         += -L$(OPENSSL_DIR)/lib -lcrypto
 | 
				
			||||||
endif
 | 
					endif
 | 
				
			||||||
 | 
				
			|||||||
@ -48,7 +48,7 @@ START_TIMER
 | 
				
			|||||||
// another operation here
 | 
					// another operation here
 | 
				
			||||||
STOP_TIMER
 | 
					STOP_TIMER
 | 
				
			||||||
FINALIZE_TIMER
 | 
					FINALIZE_TIMER
 | 
				
			||||||
PRINT_TIME_HEADER
 | 
					PRINT_TIMER_HEADER
 | 
				
			||||||
PRINT_TIMER_AVG("my operation")
 | 
					PRINT_TIMER_AVG("my operation")
 | 
				
			||||||
PRINT_TIMER_FOOTER
 | 
					PRINT_TIMER_FOOTER
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -113,26 +113,55 @@ int gettimeofday(struct timeval *tp, struct timezone *tzp) {
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static uint64_t rdtsc(void) {
 | 
					static uint64_t _bench_rdtsc(void) {
 | 
				
			||||||
#if defined(_WIN32)
 | 
					#if defined(_WIN32) || defined(_WIN64)
 | 
				
			||||||
	return __rdtsc();
 | 
						return __rdtsc();
 | 
				
			||||||
#elif defined(__aarch64__)
 | 
					#elif defined(__i586__) || defined(__amd64__)
 | 
				
			||||||
	uint64_t x;
 | 
					 | 
				
			||||||
	asm volatile("isb; mrs %0, cntvct_el0"
 | 
					 | 
				
			||||||
	             : "=r"(x));
 | 
					 | 
				
			||||||
	return x;
 | 
					 | 
				
			||||||
#elif defined(__arm__)
 | 
					 | 
				
			||||||
	struct timespec time;
 | 
					 | 
				
			||||||
	clock_gettime(CLOCK_REALTIME, &time);
 | 
					 | 
				
			||||||
	return (int64_t)(time.tv_sec * 1e9 + time.tv_nsec);
 | 
					 | 
				
			||||||
#else
 | 
					 | 
				
			||||||
	uint64_t x;
 | 
						uint64_t x;
 | 
				
			||||||
	__asm__ volatile(".byte 0x0f, 0x31"
 | 
						__asm__ volatile(".byte 0x0f, 0x31"
 | 
				
			||||||
	                 : "=A"(x));
 | 
						                 : "=A"(x));
 | 
				
			||||||
	return x;
 | 
						return x;
 | 
				
			||||||
 | 
					#elif defined(__arm__)
 | 
				
			||||||
 | 
						/* Use the ARM performance counters. */
 | 
				
			||||||
 | 
						unsigned int value;
 | 
				
			||||||
 | 
						/* Read CCNT Register */
 | 
				
			||||||
 | 
						asm volatile("mrc p15, 0, %0, c9, c13, 0\t\n"
 | 
				
			||||||
 | 
						             : "=r"(value));
 | 
				
			||||||
 | 
						return value;
 | 
				
			||||||
 | 
					#else
 | 
				
			||||||
 | 
						struct timespec time;
 | 
				
			||||||
 | 
						clock_gettime(CLOCK_REALTIME, &time);
 | 
				
			||||||
 | 
						return (int64_t)(time.tv_sec * 1e9 + time.tv_nsec);
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#if defined(__arm__)
 | 
				
			||||||
 | 
					static void _bench_init_perfcounters(int32_t do_reset, int32_t enable_divider) {
 | 
				
			||||||
 | 
						/* In general enable all counters (including cycle counter) */
 | 
				
			||||||
 | 
						int32_t value = 1;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* Peform reset */
 | 
				
			||||||
 | 
						if (do_reset) {
 | 
				
			||||||
 | 
							value |= 2; /* reset all counters to zero */
 | 
				
			||||||
 | 
							value |= 4; /* reset cycle counter to zero */
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (enable_divider)
 | 
				
			||||||
 | 
							value |= 8; /* enable "by 64" divider for CCNT */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						value |= 16;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* Program the performance-counter control-register */
 | 
				
			||||||
 | 
						asm volatile("mcr p15, 0, %0, c9, c12, 0\t\n" ::"r"(value));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* Enable all counters */
 | 
				
			||||||
 | 
						asm volatile("mcr p15, 0, %0, c9, c12, 1\t\n" ::"r"(0x8000000f));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* Clear overflows */
 | 
				
			||||||
 | 
						asm volatile("mcr p15, 0, %0, c9, c12, 3\t\n" ::"r"(0x8000000f));
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define DEFINE_TIMER_VARIABLES                                                                              \
 | 
					#define DEFINE_TIMER_VARIABLES                                                                              \
 | 
				
			||||||
	volatile uint64_t _bench_cycles_start, _bench_cycles_end;                                               \
 | 
						volatile uint64_t _bench_cycles_start, _bench_cycles_end;                                               \
 | 
				
			||||||
	uint64_t _bench_cycles_cumulative = 0;                                                                  \
 | 
						uint64_t _bench_cycles_cumulative = 0;                                                                  \
 | 
				
			||||||
@ -142,6 +171,16 @@ static uint64_t rdtsc(void) {
 | 
				
			|||||||
	double _bench_cycles_x, _bench_cycles_mean, _bench_cycles_delta, _bench_cycles_M2, _bench_cycles_stdev; \
 | 
						double _bench_cycles_x, _bench_cycles_mean, _bench_cycles_delta, _bench_cycles_M2, _bench_cycles_stdev; \
 | 
				
			||||||
	double _bench_time_x, _bench_time_mean, _bench_time_delta, _bench_time_M2, _bench_time_stdev;
 | 
						double _bench_time_x, _bench_time_mean, _bench_time_delta, _bench_time_M2, _bench_time_stdev;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#if defined(__arm__)
 | 
				
			||||||
 | 
					#define INITIALIZE_TIMER            \
 | 
				
			||||||
 | 
						_bench_init_perfcounters(1, 0); \
 | 
				
			||||||
 | 
						_bench_iterations = 0;          \
 | 
				
			||||||
 | 
						_bench_cycles_mean = 0.0;       \
 | 
				
			||||||
 | 
						_bench_cycles_M2 = 0.0;         \
 | 
				
			||||||
 | 
						_bench_time_cumulative = 0;     \
 | 
				
			||||||
 | 
						_bench_time_mean = 0.0;         \
 | 
				
			||||||
 | 
						_bench_time_M2 = 0.0;
 | 
				
			||||||
 | 
					#else
 | 
				
			||||||
#define INITIALIZE_TIMER        \
 | 
					#define INITIALIZE_TIMER        \
 | 
				
			||||||
	_bench_iterations = 0;      \
 | 
						_bench_iterations = 0;      \
 | 
				
			||||||
	_bench_cycles_mean = 0.0;   \
 | 
						_bench_cycles_mean = 0.0;   \
 | 
				
			||||||
@ -149,15 +188,17 @@ static uint64_t rdtsc(void) {
 | 
				
			|||||||
	_bench_time_cumulative = 0; \
 | 
						_bench_time_cumulative = 0; \
 | 
				
			||||||
	_bench_time_mean = 0.0;     \
 | 
						_bench_time_mean = 0.0;     \
 | 
				
			||||||
	_bench_time_M2 = 0.0;
 | 
						_bench_time_M2 = 0.0;
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define START_TIMER                            \
 | 
					#define START_TIMER                            \
 | 
				
			||||||
	gettimeofday(&_bench_timeval_start, NULL); \
 | 
						gettimeofday(&_bench_timeval_start, NULL); \
 | 
				
			||||||
	_bench_cycles_start = rdtsc();
 | 
						_bench_cycles_start = _bench_rdtsc();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// Mean and population standard deviation are calculated in an online way using the algorithm in
 | 
					// Mean and population standard deviation are calculated in an online way using the algorithm in
 | 
				
			||||||
//     http://en.wikipedia.org/wiki/Algorithms_for_calculating_variance#Online_algorithm
 | 
					//     http://en.wikipedia.org/wiki/Algorithms_for_calculating_variance#Online_algorithm
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define STOP_TIMER                                                                                                                                                          \
 | 
					#define STOP_TIMER                                                                                                                                                          \
 | 
				
			||||||
	_bench_cycles_end = rdtsc();                                                                                                                                            \
 | 
						_bench_cycles_end = _bench_rdtsc();                                                                                                                                     \
 | 
				
			||||||
	gettimeofday(&_bench_timeval_end, NULL);                                                                                                                                \
 | 
						gettimeofday(&_bench_timeval_end, NULL);                                                                                                                                \
 | 
				
			||||||
	_bench_iterations += 1;                                                                                                                                                 \
 | 
						_bench_iterations += 1;                                                                                                                                                 \
 | 
				
			||||||
	if (_bench_cycles_end < _bench_cycles_start) {                                                                                                                          \
 | 
						if (_bench_cycles_end < _bench_cycles_start) {                                                                                                                          \
 | 
				
			||||||
 | 
				
			|||||||
@ -42,8 +42,7 @@ OQS_STATUS example_stack() {
 | 
				
			|||||||
	printf("[example_stack] OQS_KEM_frodokem_640_aes was not enabled at "
 | 
						printf("[example_stack] OQS_KEM_frodokem_640_aes was not enabled at "
 | 
				
			||||||
	       "compile-time.\n");
 | 
						       "compile-time.\n");
 | 
				
			||||||
	return OQS_ERROR;
 | 
						return OQS_ERROR;
 | 
				
			||||||
#endif
 | 
					#else
 | 
				
			||||||
#ifdef OQS_ENABLE_KEM_frodokem_640_aes
 | 
					 | 
				
			||||||
	uint8_t public_key[OQS_KEM_frodokem_640_aes_length_public_key];
 | 
						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 secret_key[OQS_KEM_frodokem_640_aes_length_secret_key];
 | 
				
			||||||
	uint8_t ciphertext[OQS_KEM_frodokem_640_aes_length_ciphertext];
 | 
						uint8_t ciphertext[OQS_KEM_frodokem_640_aes_length_ciphertext];
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										160
									
								
								tests/minimal_kex_oqs.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										160
									
								
								tests/minimal_kex_oqs.c
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,160 @@
 | 
				
			|||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * minimal_kex_oqs.c
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * Minimal example of a Diffie-Hellman post-quantum key exchange method
 | 
				
			||||||
 | 
					 * implemented in liboqs.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					*/
 | 
				
			||||||
 | 
					#include <stdio.h>
 | 
				
			||||||
 | 
					#include <stdlib.h>
 | 
				
			||||||
 | 
					#include <string.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <oqs/oqs.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#if __ANDROID__
 | 
				
			||||||
 | 
					#define eprintf(...) printf(__VA_ARGS__);
 | 
				
			||||||
 | 
					#else
 | 
				
			||||||
 | 
					#define eprintf(...) fprintf(stderr, __VA_ARGS__);
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* Cleaning up memory etc */
 | 
				
			||||||
 | 
					void cleanup(uint8_t *alice_msg, size_t alice_msg_len, uint8_t *alice_key,
 | 
				
			||||||
 | 
					             size_t alice_key_len, uint8_t *bob_msg, size_t bob_msg_len,
 | 
				
			||||||
 | 
					             uint8_t *bob_key, size_t bob_key_len, void *alice_priv,
 | 
				
			||||||
 | 
					             OQS_KEX *kex, OQS_RAND *rnd);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifdef ENABLE_KEX_NTRU
 | 
				
			||||||
 | 
					int main(void) {
 | 
				
			||||||
 | 
						/* Key exchange parameters */
 | 
				
			||||||
 | 
						void *alice_priv = NULL;   // Alice's private key
 | 
				
			||||||
 | 
						uint8_t *alice_msg = NULL; // Alice's message
 | 
				
			||||||
 | 
						size_t alice_msg_len = 0;  // Alice's message length
 | 
				
			||||||
 | 
						uint8_t *alice_key = NULL; // Alice's final key
 | 
				
			||||||
 | 
						size_t alice_key_len = 0;  // Alice's final key length
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						uint8_t *bob_msg = NULL; // Bob's message
 | 
				
			||||||
 | 
						size_t bob_msg_len = 0;  // Bob's message length
 | 
				
			||||||
 | 
						uint8_t *bob_key = NULL; // Bob's final key
 | 
				
			||||||
 | 
						size_t bob_key_len = 0;  // Bob's final key length
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* Setup the key exchange protocol */
 | 
				
			||||||
 | 
						enum OQS_KEX_alg_name alg_name = OQS_KEX_alg_default; // Alg. name
 | 
				
			||||||
 | 
						OQS_RAND *rnd = NULL;                                 // Source of randomness
 | 
				
			||||||
 | 
						OQS_KEX *kex = NULL;                                  // OQS_KEX structure
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* Setup the source of randomness */
 | 
				
			||||||
 | 
						rnd = OQS_RAND_new(OQS_RAND_alg_urandom_chacha20);
 | 
				
			||||||
 | 
						if (rnd == NULL) {
 | 
				
			||||||
 | 
							eprintf("ERROR: Setting up the randomness source!\n");
 | 
				
			||||||
 | 
							cleanup(alice_msg, alice_msg_len, alice_key, alice_key_len, bob_msg,
 | 
				
			||||||
 | 
							        bob_msg_len, bob_key, bob_key_len, alice_priv, kex, rnd);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							return EXIT_FAILURE;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* Populate the OQS_KEX structure, here's where liboqs sets up
 | 
				
			||||||
 | 
					     * the specific details of the selected KEX implementation */
 | 
				
			||||||
 | 
						kex = OQS_KEX_new(rnd, alg_name, NULL, 0, NULL);
 | 
				
			||||||
 | 
						if (kex == NULL) {
 | 
				
			||||||
 | 
							eprintf("ERROR: OQS_KEX_new failed!\n");
 | 
				
			||||||
 | 
							cleanup(alice_msg, alice_msg_len, alice_key, alice_key_len, bob_msg,
 | 
				
			||||||
 | 
							        bob_msg_len, bob_key, bob_key_len, alice_priv, kex, rnd);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							return EXIT_FAILURE;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* Proceed with the Diffie-Hellman key exchange mechanism */
 | 
				
			||||||
 | 
						printf("===============================================================\n");
 | 
				
			||||||
 | 
						printf("Diffie-Hellman post-quantum key exchange: %s\n", kex->method_name);
 | 
				
			||||||
 | 
						printf("===============================================================\n");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* Alice's initial message */
 | 
				
			||||||
 | 
						OQS_STATUS success = OQS_KEX_alice_0(kex, &alice_priv, &alice_msg, &alice_msg_len);
 | 
				
			||||||
 | 
						if (success != OQS_SUCCESS) {
 | 
				
			||||||
 | 
							eprintf("ERROR: OQS_KEX_alice_0 failed!\n");
 | 
				
			||||||
 | 
							cleanup(alice_msg, alice_msg_len, alice_key, alice_key_len, bob_msg,
 | 
				
			||||||
 | 
							        bob_msg_len, bob_key, bob_key_len, alice_priv, kex, rnd);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							return EXIT_FAILURE;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						OQS_print_part_hex_string("Alice message", alice_msg, alice_msg_len, 20);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* Bob's response */
 | 
				
			||||||
 | 
						success = OQS_KEX_bob(kex, alice_msg, alice_msg_len, &bob_msg, &bob_msg_len,
 | 
				
			||||||
 | 
						                      &bob_key, &bob_key_len);
 | 
				
			||||||
 | 
						if (success != OQS_SUCCESS) {
 | 
				
			||||||
 | 
							eprintf("ERROR: OQS_KEX_bob failed!\n");
 | 
				
			||||||
 | 
							cleanup(alice_msg, alice_msg_len, alice_key, alice_key_len, bob_msg,
 | 
				
			||||||
 | 
							        bob_msg_len, bob_key, bob_key_len, alice_priv, kex, rnd);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							return EXIT_FAILURE;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						OQS_print_part_hex_string("Bob message", bob_msg, bob_msg_len, 20);
 | 
				
			||||||
 | 
						OQS_print_hex_string("Bob session key", bob_key, bob_key_len);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* Alice processes Bob's response */
 | 
				
			||||||
 | 
						success = OQS_KEX_alice_1(kex, alice_priv, bob_msg, bob_msg_len, &alice_key,
 | 
				
			||||||
 | 
						                          &alice_key_len);
 | 
				
			||||||
 | 
						if (success != OQS_SUCCESS) {
 | 
				
			||||||
 | 
							eprintf("ERROR: OQS_KEX_alice_1 failed!\n");
 | 
				
			||||||
 | 
							cleanup(alice_msg, alice_msg_len, alice_key, alice_key_len, bob_msg,
 | 
				
			||||||
 | 
							        bob_msg_len, bob_key, bob_key_len, alice_priv, kex, rnd);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							return EXIT_FAILURE;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						OQS_print_hex_string("Alice session key", alice_key, alice_key_len);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* Compare key lengths */
 | 
				
			||||||
 | 
						if (alice_key_len != bob_key_len) {
 | 
				
			||||||
 | 
							eprintf("ERROR: Alice's session key and Bob's session keys "
 | 
				
			||||||
 | 
							        "have different lengths (%zu vs %zu)!\n",
 | 
				
			||||||
 | 
							        alice_key_len, bob_key_len);
 | 
				
			||||||
 | 
							cleanup(alice_msg, alice_msg_len, alice_key, alice_key_len, bob_msg,
 | 
				
			||||||
 | 
							        bob_msg_len, bob_key, bob_key_len, alice_priv, kex, rnd);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							return EXIT_FAILURE;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* Compare key values */
 | 
				
			||||||
 | 
						success = memcmp(alice_key, bob_key, alice_key_len);
 | 
				
			||||||
 | 
						if (success != 0) {
 | 
				
			||||||
 | 
							eprintf("ERROR: Alice's session key and Bob's session "
 | 
				
			||||||
 | 
							        "key are not equal!\n");
 | 
				
			||||||
 | 
							OQS_print_hex_string("Alice session key", alice_key, alice_key_len);
 | 
				
			||||||
 | 
							OQS_print_hex_string("Bob session key", bob_key, bob_key_len);
 | 
				
			||||||
 | 
							cleanup(alice_msg, alice_msg_len, alice_key, alice_key_len, bob_msg,
 | 
				
			||||||
 | 
							        bob_msg_len, bob_key, bob_key_len, alice_priv, kex, rnd);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							return EXIT_FAILURE;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* Success and clean-up */
 | 
				
			||||||
 | 
						printf("Alice and Bob's session keys match.\n");
 | 
				
			||||||
 | 
						cleanup(alice_msg, alice_msg_len, alice_key, alice_key_len, bob_msg,
 | 
				
			||||||
 | 
						        bob_msg_len, bob_key, bob_key_len, alice_priv, kex, rnd);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return EXIT_SUCCESS;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					#else // !ENABLE_KEX_LWE_FRODO
 | 
				
			||||||
 | 
					int main(void) {
 | 
				
			||||||
 | 
						printf("KEX algorithm not available. Make sure configure was run properly; see Readme.md.\n");
 | 
				
			||||||
 | 
						return EXIT_FAILURE;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void cleanup(uint8_t *alice_msg, size_t alice_msg_len, uint8_t *alice_key,
 | 
				
			||||||
 | 
					             size_t alice_key_len, uint8_t *bob_msg, size_t bob_msg_len,
 | 
				
			||||||
 | 
					             uint8_t *bob_key, size_t bob_key_len, void *alice_priv,
 | 
				
			||||||
 | 
					             OQS_KEX *kex, OQS_RAND *rnd) {
 | 
				
			||||||
 | 
						/* Secure cleaning */
 | 
				
			||||||
 | 
						OQS_MEM_secure_free(alice_msg, alice_msg_len);
 | 
				
			||||||
 | 
						OQS_MEM_secure_free(alice_key, alice_key_len);
 | 
				
			||||||
 | 
						OQS_MEM_secure_free(bob_msg, bob_msg_len);
 | 
				
			||||||
 | 
						OQS_MEM_secure_free(bob_key, bob_key_len);
 | 
				
			||||||
 | 
						OQS_KEX_alice_priv_free(kex, alice_priv);
 | 
				
			||||||
 | 
						OQS_KEX_free(kex);
 | 
				
			||||||
 | 
						OQS_RAND_free(rnd);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@ -1,9 +1,14 @@
 | 
				
			|||||||
 | 
					#include <stdbool.h>
 | 
				
			||||||
#include <stdio.h>
 | 
					#include <stdio.h>
 | 
				
			||||||
#include <stdlib.h>
 | 
					#include <stdlib.h>
 | 
				
			||||||
#include <string.h>
 | 
					#include <string.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include <oqs/oqs.h>
 | 
					#include <oqs/oqs.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					typedef struct magic_s {
 | 
				
			||||||
 | 
						uint8_t val[32];
 | 
				
			||||||
 | 
					} magic_t;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static OQS_STATUS kem_test_correctness(const char *method_name) {
 | 
					static OQS_STATUS kem_test_correctness(const char *method_name) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	OQS_KEM *kem = NULL;
 | 
						OQS_KEM *kem = NULL;
 | 
				
			||||||
@ -15,6 +20,13 @@ static OQS_STATUS kem_test_correctness(const char *method_name) {
 | 
				
			|||||||
	OQS_STATUS rc, ret = OQS_ERROR;
 | 
						OQS_STATUS rc, ret = OQS_ERROR;
 | 
				
			||||||
	int rv;
 | 
						int rv;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						//The magic numbers are 32 random values.
 | 
				
			||||||
 | 
						//The length of the magic number was chosen arbitrarilly to 32.
 | 
				
			||||||
 | 
						magic_t magic = {{0xfa, 0xfa, 0xfa, 0xfa, 0xbc, 0xbc, 0xbc, 0xbc,
 | 
				
			||||||
 | 
						                  0x15, 0x61, 0x15, 0x61, 0x15, 0x61, 0x15, 0x61,
 | 
				
			||||||
 | 
						                  0xad, 0xad, 0x43, 0x43, 0xad, 0xad, 0x34, 0x34,
 | 
				
			||||||
 | 
						                  0x12, 0x34, 0x56, 0x78, 0x12, 0x34, 0x56, 0x78}};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	kem = OQS_KEM_new(method_name);
 | 
						kem = OQS_KEM_new(method_name);
 | 
				
			||||||
	if (kem == NULL) {
 | 
						if (kem == NULL) {
 | 
				
			||||||
		return OQS_SUCCESS;
 | 
							return OQS_SUCCESS;
 | 
				
			||||||
@ -24,11 +36,18 @@ static OQS_STATUS kem_test_correctness(const char *method_name) {
 | 
				
			|||||||
	printf("Sample computation for KEM %s\n", kem->method_name);
 | 
						printf("Sample computation for KEM %s\n", kem->method_name);
 | 
				
			||||||
	printf("================================================================================\n");
 | 
						printf("================================================================================\n");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	public_key = malloc(kem->length_public_key);
 | 
						public_key = malloc(kem->length_public_key + sizeof(magic_t));
 | 
				
			||||||
	secret_key = malloc(kem->length_secret_key);
 | 
						secret_key = malloc(kem->length_secret_key + sizeof(magic_t));
 | 
				
			||||||
	ciphertext = malloc(kem->length_ciphertext);
 | 
						ciphertext = malloc(kem->length_ciphertext + sizeof(magic_t));
 | 
				
			||||||
	shared_secret_e = malloc(kem->length_shared_secret);
 | 
						shared_secret_e = malloc(kem->length_shared_secret + sizeof(magic_t));
 | 
				
			||||||
	shared_secret_d = malloc(kem->length_shared_secret);
 | 
						shared_secret_d = malloc(kem->length_shared_secret + sizeof(magic_t));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						//Set the magic numbers
 | 
				
			||||||
 | 
						memcpy(public_key + kem->length_public_key, magic.val, sizeof(magic_t));
 | 
				
			||||||
 | 
						memcpy(secret_key + kem->length_secret_key, magic.val, sizeof(magic_t));
 | 
				
			||||||
 | 
						memcpy(ciphertext + kem->length_ciphertext, magic.val, sizeof(magic_t));
 | 
				
			||||||
 | 
						memcpy(shared_secret_e + kem->length_shared_secret, magic.val, sizeof(magic_t));
 | 
				
			||||||
 | 
						memcpy(shared_secret_d + kem->length_shared_secret, magic.val, sizeof(magic_t));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if ((public_key == NULL) || (secret_key == NULL) || (ciphertext == NULL) || (shared_secret_e == NULL) || (shared_secret_d == NULL)) {
 | 
						if ((public_key == NULL) || (secret_key == NULL) || (ciphertext == NULL) || (shared_secret_e == NULL) || (shared_secret_d == NULL)) {
 | 
				
			||||||
		fprintf(stderr, "ERROR: malloc failed\n");
 | 
							fprintf(stderr, "ERROR: malloc failed\n");
 | 
				
			||||||
@ -63,6 +82,16 @@ static OQS_STATUS kem_test_correctness(const char *method_name) {
 | 
				
			|||||||
		printf("shared secrets are equal\n");
 | 
							printf("shared secrets are equal\n");
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						rv = memcmp(public_key + kem->length_public_key, magic.val, sizeof(magic_t));
 | 
				
			||||||
 | 
						rv |= memcmp(secret_key + kem->length_secret_key, magic.val, sizeof(magic_t));
 | 
				
			||||||
 | 
						rv |= memcmp(ciphertext + kem->length_ciphertext, magic.val, sizeof(magic_t));
 | 
				
			||||||
 | 
						rv |= memcmp(shared_secret_e + kem->length_shared_secret, magic.val, sizeof(magic_t));
 | 
				
			||||||
 | 
						rv |= memcmp(shared_secret_d + kem->length_shared_secret, magic.val, sizeof(magic_t));
 | 
				
			||||||
 | 
						if (rv != 0) {
 | 
				
			||||||
 | 
							fprintf(stderr, "ERROR: Magic numbers do not match\n");
 | 
				
			||||||
 | 
							goto err;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	ret = OQS_SUCCESS;
 | 
						ret = OQS_SUCCESS;
 | 
				
			||||||
	goto cleanup;
 | 
						goto cleanup;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -83,6 +112,7 @@ cleanup:
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
int main() {
 | 
					int main() {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	int ret = EXIT_SUCCESS;
 | 
						int ret = EXIT_SUCCESS;
 | 
				
			||||||
	OQS_STATUS rc;
 | 
						OQS_STATUS rc;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										410
									
								
								tests/test_kex.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										410
									
								
								tests/test_kex.c
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,410 @@
 | 
				
			|||||||
 | 
					#if defined(_WIN32)
 | 
				
			||||||
 | 
					#pragma warning(disable : 4244 4293)
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <stdbool.h>
 | 
				
			||||||
 | 
					#include <stdio.h>
 | 
				
			||||||
 | 
					#include <stdlib.h>
 | 
				
			||||||
 | 
					#include <string.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <oqs/oqs.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "ds_benchmark.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#if __ANDROID__
 | 
				
			||||||
 | 
					#define eprintf(...) printf(__VA_ARGS__);
 | 
				
			||||||
 | 
					#else
 | 
				
			||||||
 | 
					#define eprintf(...) fprintf(stderr, __VA_ARGS__);
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct kex_testcase {
 | 
				
			||||||
 | 
						enum OQS_KEX_alg_name alg_name;
 | 
				
			||||||
 | 
						unsigned char *seed;
 | 
				
			||||||
 | 
						size_t seed_len;
 | 
				
			||||||
 | 
						const char *named_parameters;
 | 
				
			||||||
 | 
						const char *id;
 | 
				
			||||||
 | 
						int run;
 | 
				
			||||||
 | 
						int iter;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* Add new testcases here */
 | 
				
			||||||
 | 
					struct kex_testcase kex_testcases[] = {
 | 
				
			||||||
 | 
					#ifndef DISABLE_NTRU_ON_WINDOWS_BY_DEFAULT
 | 
				
			||||||
 | 
					#ifdef ENABLE_KEX_NTRU
 | 
				
			||||||
 | 
					    {OQS_KEX_alg_ntru, NULL, 0, NULL, "ntru", 0, 25},
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define KEX_TEST_ITERATIONS 100
 | 
				
			||||||
 | 
					#define KEX_BENCH_SECONDS_DEFAULT 1
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static OQS_STATUS kex_test_correctness(OQS_RAND *rand, enum OQS_KEX_alg_name alg_name, const uint8_t *seed, const size_t seed_len, const char *named_parameters, const int print, unsigned long occurrences[256]) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						OQS_KEX *kex = NULL;
 | 
				
			||||||
 | 
						OQS_STATUS rc;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						void *alice_priv = NULL;
 | 
				
			||||||
 | 
						uint8_t *alice_msg = NULL;
 | 
				
			||||||
 | 
						size_t alice_msg_len;
 | 
				
			||||||
 | 
						uint8_t *alice_key = NULL;
 | 
				
			||||||
 | 
						size_t alice_key_len = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						uint8_t *bob_msg = NULL;
 | 
				
			||||||
 | 
						size_t bob_msg_len;
 | 
				
			||||||
 | 
						uint8_t *bob_key = NULL;
 | 
				
			||||||
 | 
						size_t bob_key_len = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* setup KEX */
 | 
				
			||||||
 | 
						kex = OQS_KEX_new(rand, alg_name, seed, seed_len, named_parameters);
 | 
				
			||||||
 | 
						if (kex == NULL) {
 | 
				
			||||||
 | 
							eprintf("new_method failed\n");
 | 
				
			||||||
 | 
							goto err;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (print) {
 | 
				
			||||||
 | 
							printf("================================================================================\n");
 | 
				
			||||||
 | 
							printf("Sample computation for key exchange method %s\n", kex->method_name);
 | 
				
			||||||
 | 
							printf("================================================================================\n");
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* Alice's initial message */
 | 
				
			||||||
 | 
						rc = OQS_KEX_alice_0(kex, &alice_priv, &alice_msg, &alice_msg_len);
 | 
				
			||||||
 | 
						if (rc != OQS_SUCCESS) {
 | 
				
			||||||
 | 
							eprintf("OQS_KEX_alice_0 failed\n");
 | 
				
			||||||
 | 
							goto err;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (print) {
 | 
				
			||||||
 | 
							OQS_print_part_hex_string("Alice message", alice_msg, alice_msg_len, 20);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* Bob's response */
 | 
				
			||||||
 | 
						rc = OQS_KEX_bob(kex, alice_msg, alice_msg_len, &bob_msg, &bob_msg_len, &bob_key, &bob_key_len);
 | 
				
			||||||
 | 
						if (rc != OQS_SUCCESS) {
 | 
				
			||||||
 | 
							eprintf("OQS_KEX_bob failed\n");
 | 
				
			||||||
 | 
							goto err;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (print) {
 | 
				
			||||||
 | 
							OQS_print_part_hex_string("Bob message", bob_msg, bob_msg_len, 20);
 | 
				
			||||||
 | 
							OQS_print_hex_string("Bob session key", bob_key, bob_key_len);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* Alice processes Bob's response */
 | 
				
			||||||
 | 
						rc = OQS_KEX_alice_1(kex, alice_priv, bob_msg, bob_msg_len, &alice_key, &alice_key_len);
 | 
				
			||||||
 | 
						if (rc != OQS_SUCCESS) {
 | 
				
			||||||
 | 
							eprintf("OQS_KEX_alice_1 failed\n");
 | 
				
			||||||
 | 
							goto err;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (print) {
 | 
				
			||||||
 | 
							OQS_print_hex_string("Alice session key", alice_key, alice_key_len);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* compare session key lengths and values */
 | 
				
			||||||
 | 
						if (alice_key_len != bob_key_len) {
 | 
				
			||||||
 | 
							eprintf("ERROR: Alice's session key and Bob's session key are different lengths (%zu vs %zu)\n", alice_key_len, bob_key_len);
 | 
				
			||||||
 | 
							goto err;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						if (memcmp(alice_key, bob_key, alice_key_len) != 0) {
 | 
				
			||||||
 | 
							eprintf("ERROR: Alice's session key and Bob's session key are not equal\n");
 | 
				
			||||||
 | 
							OQS_print_hex_string("Alice session key", alice_key, alice_key_len);
 | 
				
			||||||
 | 
							OQS_print_hex_string("Bob session key", bob_key, bob_key_len);
 | 
				
			||||||
 | 
							goto err;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						if (print) {
 | 
				
			||||||
 | 
							printf("Alice and Bob's session keys match.\n");
 | 
				
			||||||
 | 
							printf("\n\n");
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* record generated bytes for statistical analysis */
 | 
				
			||||||
 | 
						for (size_t i = 0; i < alice_key_len; i++) {
 | 
				
			||||||
 | 
							OQS_RAND_test_record_occurrence(alice_key[i], occurrences);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						rc = OQS_SUCCESS;
 | 
				
			||||||
 | 
						goto cleanup;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					err:
 | 
				
			||||||
 | 
						rc = OQS_ERROR;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					cleanup:
 | 
				
			||||||
 | 
						OQS_MEM_insecure_free(alice_msg);
 | 
				
			||||||
 | 
						OQS_MEM_secure_free(alice_key, alice_key_len);
 | 
				
			||||||
 | 
						OQS_MEM_insecure_free(bob_msg);
 | 
				
			||||||
 | 
						OQS_MEM_secure_free(bob_key, bob_key_len);
 | 
				
			||||||
 | 
						OQS_KEX_alice_priv_free(kex, alice_priv);
 | 
				
			||||||
 | 
						OQS_KEX_free(kex);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return rc;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static OQS_STATUS kex_test_correctness_wrapper(OQS_RAND *rand, enum OQS_KEX_alg_name alg_name, const uint8_t *seed, const size_t seed_len, const char *named_parameters, int iterations, bool quiet) {
 | 
				
			||||||
 | 
						OQS_KEX *kex = NULL;
 | 
				
			||||||
 | 
						OQS_STATUS ret;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						unsigned long occurrences[256];
 | 
				
			||||||
 | 
						for (int i = 0; i < 256; i++) {
 | 
				
			||||||
 | 
							occurrences[i] = 0;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						ret = kex_test_correctness(rand, alg_name, seed, seed_len, named_parameters, quiet ? 0 : 1, occurrences);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (ret != OQS_SUCCESS) {
 | 
				
			||||||
 | 
							goto err;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* setup KEX */
 | 
				
			||||||
 | 
						kex = OQS_KEX_new(rand, alg_name, seed, seed_len, named_parameters);
 | 
				
			||||||
 | 
						if (kex == NULL) {
 | 
				
			||||||
 | 
							goto err;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						printf("================================================================================\n");
 | 
				
			||||||
 | 
						printf("Testing correctness and randomness of key exchange method %s (params=%s) for %d iterations\n",
 | 
				
			||||||
 | 
						       kex->method_name, named_parameters, iterations);
 | 
				
			||||||
 | 
						printf("================================================================================\n");
 | 
				
			||||||
 | 
						for (int i = 0; i < iterations; i++) {
 | 
				
			||||||
 | 
							ret = kex_test_correctness(rand, alg_name, seed, seed_len, named_parameters, 0, occurrences);
 | 
				
			||||||
 | 
							if (ret != OQS_SUCCESS) {
 | 
				
			||||||
 | 
								goto err;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						printf("All session keys matched.\n");
 | 
				
			||||||
 | 
						OQS_RAND_report_statistics(occurrences, "");
 | 
				
			||||||
 | 
						printf("\n\n");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						ret = OQS_SUCCESS;
 | 
				
			||||||
 | 
						goto cleanup;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					err:
 | 
				
			||||||
 | 
						ret = OQS_ERROR;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					cleanup:
 | 
				
			||||||
 | 
						OQS_KEX_free(kex);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return ret;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void cleanup_alice_0(OQS_KEX *kex, void *alice_priv, uint8_t *alice_msg) {
 | 
				
			||||||
 | 
						OQS_MEM_insecure_free(alice_msg);
 | 
				
			||||||
 | 
						OQS_KEX_alice_priv_free(kex, alice_priv);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void cleanup_bob(uint8_t *bob_msg, uint8_t *bob_key, size_t bob_key_len) {
 | 
				
			||||||
 | 
						OQS_MEM_insecure_free(bob_msg);
 | 
				
			||||||
 | 
						OQS_MEM_secure_free(bob_key, bob_key_len);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static OQS_STATUS kex_bench_wrapper(OQS_RAND *rand, enum OQS_KEX_alg_name alg_name, const uint8_t *seed, const size_t seed_len, const char *named_parameters, const size_t seconds) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						OQS_KEX *kex = NULL;
 | 
				
			||||||
 | 
						OQS_STATUS rc;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						void *alice_priv = NULL;
 | 
				
			||||||
 | 
						uint8_t *alice_msg = NULL;
 | 
				
			||||||
 | 
						size_t alice_msg_len;
 | 
				
			||||||
 | 
						uint8_t *alice_key = NULL;
 | 
				
			||||||
 | 
						size_t alice_key_len = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						uint8_t *bob_msg = NULL;
 | 
				
			||||||
 | 
						size_t bob_msg_len;
 | 
				
			||||||
 | 
						uint8_t *bob_key = NULL;
 | 
				
			||||||
 | 
						size_t bob_key_len = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* setup KEX */
 | 
				
			||||||
 | 
						kex = OQS_KEX_new(rand, alg_name, seed, seed_len, named_parameters);
 | 
				
			||||||
 | 
						if (kex == NULL) {
 | 
				
			||||||
 | 
							eprintf("new_method failed\n");
 | 
				
			||||||
 | 
							goto err;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						printf("%-30s | %10s | %14s | %15s | %10s | %16s | %10s\n", kex->method_name, "", "", "", "", "", "");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						TIME_OPERATION_SECONDS({ OQS_KEX_alice_0(kex, &alice_priv, &alice_msg, &alice_msg_len); cleanup_alice_0(kex, alice_priv, alice_msg); }, "alice 0", seconds);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						OQS_KEX_alice_0(kex, &alice_priv, &alice_msg, &alice_msg_len);
 | 
				
			||||||
 | 
						TIME_OPERATION_SECONDS({ OQS_KEX_bob(kex, alice_msg, alice_msg_len, &bob_msg, &bob_msg_len, &bob_key, &bob_key_len); cleanup_bob(bob_msg, bob_key, bob_key_len); }, "bob", seconds);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						OQS_KEX_bob(kex, alice_msg, alice_msg_len, &bob_msg, &bob_msg_len, &bob_key, &bob_key_len);
 | 
				
			||||||
 | 
						TIME_OPERATION_SECONDS({ OQS_KEX_alice_1(kex, alice_priv, bob_msg, bob_msg_len, &alice_key, &alice_key_len); OQS_MEM_secure_free(alice_key, alice_key_len); }, "alice 1", seconds);
 | 
				
			||||||
 | 
						alice_key = NULL;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						printf("Communication (bytes): A->B: %zu, B->A: %zu, total: %zu; classical/quantum security bits [%u:%u] \n", alice_msg_len, bob_msg_len, alice_msg_len + bob_msg_len, kex->estimated_classical_security, kex->estimated_quantum_security);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						rc = OQS_SUCCESS;
 | 
				
			||||||
 | 
						goto cleanup;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					err:
 | 
				
			||||||
 | 
						rc = OQS_ERROR;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					cleanup:
 | 
				
			||||||
 | 
						OQS_MEM_insecure_free(alice_msg);
 | 
				
			||||||
 | 
						OQS_MEM_secure_free(alice_key, alice_key_len);
 | 
				
			||||||
 | 
						OQS_MEM_insecure_free(bob_msg);
 | 
				
			||||||
 | 
						OQS_MEM_secure_free(bob_key, bob_key_len);
 | 
				
			||||||
 | 
						OQS_KEX_alice_priv_free(kex, alice_priv);
 | 
				
			||||||
 | 
						OQS_KEX_free(kex);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return rc;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static OQS_STATUS kex_mem_bench_wrapper(OQS_RAND *rand, enum OQS_KEX_alg_name alg_name, const uint8_t *seed, const size_t seed_len, const char *named_parameters) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						OQS_KEX *kex = NULL;
 | 
				
			||||||
 | 
						OQS_STATUS rc;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						void *alice_priv = NULL;
 | 
				
			||||||
 | 
						uint8_t *alice_msg = NULL;
 | 
				
			||||||
 | 
						size_t alice_msg_len;
 | 
				
			||||||
 | 
						uint8_t *alice_key = NULL;
 | 
				
			||||||
 | 
						size_t alice_key_len = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						uint8_t *bob_msg = NULL;
 | 
				
			||||||
 | 
						size_t bob_msg_len;
 | 
				
			||||||
 | 
						uint8_t *bob_key = NULL;
 | 
				
			||||||
 | 
						size_t bob_key_len = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						kex = OQS_KEX_new(rand, alg_name, seed, seed_len, named_parameters);
 | 
				
			||||||
 | 
						if (kex == NULL) {
 | 
				
			||||||
 | 
							fprintf(stderr, "new_method failed\n");
 | 
				
			||||||
 | 
							goto err;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						printf("running %s..\n", kex->method_name);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						OQS_KEX_alice_0(kex, &alice_priv, &alice_msg, &alice_msg_len);
 | 
				
			||||||
 | 
						OQS_KEX_bob(kex, alice_msg, alice_msg_len, &bob_msg, &bob_msg_len, &bob_key, &bob_key_len);
 | 
				
			||||||
 | 
						OQS_KEX_alice_1(kex, alice_priv, bob_msg, bob_msg_len, &alice_key, &alice_key_len);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						rc = OQS_SUCCESS;
 | 
				
			||||||
 | 
						goto cleanup;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					err:
 | 
				
			||||||
 | 
						rc = OQS_ERROR;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					cleanup:
 | 
				
			||||||
 | 
						OQS_MEM_insecure_free(alice_msg);
 | 
				
			||||||
 | 
						OQS_MEM_secure_free(alice_key, alice_key_len);
 | 
				
			||||||
 | 
						OQS_MEM_insecure_free(bob_msg);
 | 
				
			||||||
 | 
						OQS_MEM_secure_free(bob_key, bob_key_len);
 | 
				
			||||||
 | 
						OQS_KEX_alice_priv_free(kex, alice_priv);
 | 
				
			||||||
 | 
						OQS_KEX_free(kex);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return rc;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void print_help() {
 | 
				
			||||||
 | 
						printf("Usage: ./test_kex [options] [algorithms]\n");
 | 
				
			||||||
 | 
						printf("\nOptions:\n");
 | 
				
			||||||
 | 
						printf("  --quiet, -q\n");
 | 
				
			||||||
 | 
						printf("    Less verbose output\n");
 | 
				
			||||||
 | 
						printf("  --bench, -b\n");
 | 
				
			||||||
 | 
						printf("    Run benchmarks\n");
 | 
				
			||||||
 | 
						printf("  --seconds -s [SECONDS]\n");
 | 
				
			||||||
 | 
						printf("    Number of seconds to run benchmarks (default==%d)\n", KEX_BENCH_SECONDS_DEFAULT);
 | 
				
			||||||
 | 
						printf("  --mem-bench\n");
 | 
				
			||||||
 | 
						printf("    Run memory benchmarks (run once and allocate only what is required)\n");
 | 
				
			||||||
 | 
						printf("\nalgorithms:\n");
 | 
				
			||||||
 | 
						size_t kex_testcases_len = sizeof(kex_testcases) / sizeof(struct kex_testcase);
 | 
				
			||||||
 | 
						for (size_t i = 0; i < kex_testcases_len; i++) {
 | 
				
			||||||
 | 
							printf("  %s\n", kex_testcases[i].id);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int main(int argc, char **argv) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						OQS_STATUS success = OQS_SUCCESS;
 | 
				
			||||||
 | 
						bool run_all = true;
 | 
				
			||||||
 | 
						bool quiet = false;
 | 
				
			||||||
 | 
						bool bench = false;
 | 
				
			||||||
 | 
						bool mem_bench = false;
 | 
				
			||||||
 | 
						size_t kex_testcases_len = sizeof(kex_testcases) / sizeof(struct kex_testcase);
 | 
				
			||||||
 | 
						size_t kex_bench_seconds = KEX_BENCH_SECONDS_DEFAULT;
 | 
				
			||||||
 | 
						for (int i = 1; i < argc; i++) {
 | 
				
			||||||
 | 
							if (argv[i][0] == '-') {
 | 
				
			||||||
 | 
								if ((strcmp(argv[i], "-h") == 0) || (strcmp(argv[i], "-help") == 0) || (strcmp(argv[i], "--help") == 0)) {
 | 
				
			||||||
 | 
									print_help();
 | 
				
			||||||
 | 
									return EXIT_SUCCESS;
 | 
				
			||||||
 | 
								} else if (strcmp(argv[i], "--quiet") == 0 || strcmp(argv[i], "-q") == 0) {
 | 
				
			||||||
 | 
									quiet = true;
 | 
				
			||||||
 | 
								} else if (strcmp(argv[i], "--bench") == 0 || strcmp(argv[i], "-b") == 0) {
 | 
				
			||||||
 | 
									bench = true;
 | 
				
			||||||
 | 
								} else if (strcmp(argv[i], "--seconds") == 0 || strcmp(argv[i], "-s") == 0) {
 | 
				
			||||||
 | 
									if (++i == argc) {
 | 
				
			||||||
 | 
										print_help();
 | 
				
			||||||
 | 
										return EXIT_SUCCESS;
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
 | 
									char *end;
 | 
				
			||||||
 | 
									int kex_bench_seconds_input = strtol(argv[i], &end, 10);
 | 
				
			||||||
 | 
									if (kex_bench_seconds_input < 1) {
 | 
				
			||||||
 | 
										print_help();
 | 
				
			||||||
 | 
										return EXIT_SUCCESS;
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
 | 
									kex_bench_seconds = kex_bench_seconds_input;
 | 
				
			||||||
 | 
								} else if ((strcmp(argv[i], "--mem-bench") == 0 || strcmp(argv[i], "-m") == 0)) {
 | 
				
			||||||
 | 
									mem_bench = true;
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
							} else {
 | 
				
			||||||
 | 
								run_all = false;
 | 
				
			||||||
 | 
								for (size_t j = 0; j < kex_testcases_len; j++) {
 | 
				
			||||||
 | 
									if (strcmp(argv[i], kex_testcases[j].id) == 0) {
 | 
				
			||||||
 | 
										kex_testcases[j].run = 1;
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* setup RAND */
 | 
				
			||||||
 | 
						OQS_RAND *rand = OQS_RAND_new(OQS_RAND_alg_urandom_chacha20);
 | 
				
			||||||
 | 
						if (rand == NULL) {
 | 
				
			||||||
 | 
							goto err;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (mem_bench) {
 | 
				
			||||||
 | 
							for (size_t i = 0; i < kex_testcases_len; i++) {
 | 
				
			||||||
 | 
								if (run_all || kex_testcases[i].run == 1) {
 | 
				
			||||||
 | 
									success = kex_mem_bench_wrapper(rand, kex_testcases[i].alg_name, kex_testcases[i].seed, kex_testcases[i].seed_len, kex_testcases[i].named_parameters);
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								if (success != OQS_SUCCESS) {
 | 
				
			||||||
 | 
									goto err;
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							printf("memory benchmarks done, exiting..\n");
 | 
				
			||||||
 | 
							success = OQS_SUCCESS;
 | 
				
			||||||
 | 
							goto cleanup;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						for (size_t i = 0; i < kex_testcases_len; i++) {
 | 
				
			||||||
 | 
							if (run_all || kex_testcases[i].run == 1) {
 | 
				
			||||||
 | 
								int num_iter = kex_testcases[i].iter;
 | 
				
			||||||
 | 
								success = kex_test_correctness_wrapper(rand, kex_testcases[i].alg_name, kex_testcases[i].seed, kex_testcases[i].seed_len, kex_testcases[i].named_parameters, num_iter, quiet);
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							if (success != OQS_SUCCESS) {
 | 
				
			||||||
 | 
								goto err;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (bench) {
 | 
				
			||||||
 | 
							PRINT_TIMER_HEADER
 | 
				
			||||||
 | 
							for (size_t i = 0; i < kex_testcases_len; i++) {
 | 
				
			||||||
 | 
								if (run_all || kex_testcases[i].run == 1) {
 | 
				
			||||||
 | 
									kex_bench_wrapper(rand, kex_testcases[i].alg_name, kex_testcases[i].seed, kex_testcases[i].seed_len, kex_testcases[i].named_parameters, kex_bench_seconds);
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							PRINT_TIMER_FOOTER
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						success = OQS_SUCCESS;
 | 
				
			||||||
 | 
						goto cleanup;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					err:
 | 
				
			||||||
 | 
						success = OQS_ERROR;
 | 
				
			||||||
 | 
						eprintf("ERROR!\n");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					cleanup:
 | 
				
			||||||
 | 
						OQS_RAND_free(rand);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return (success == OQS_SUCCESS) ? EXIT_SUCCESS : EXIT_FAILURE;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@ -7,6 +7,12 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
#include <oqs/oqs.h>
 | 
					#include <oqs/oqs.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#if __ANDROID__
 | 
				
			||||||
 | 
					#define eprintf(...) printf(__VA_ARGS__);
 | 
				
			||||||
 | 
					#else
 | 
				
			||||||
 | 
					#define eprintf(...) fprintf(stderr, __VA_ARGS__);
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct rand_testcase {
 | 
					struct rand_testcase {
 | 
				
			||||||
	enum OQS_RAND_alg_name alg_name;
 | 
						enum OQS_RAND_alg_name alg_name;
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
				
			|||||||
@ -58,8 +58,15 @@ static OQS_STATUS sig_test_correctness(const char *method_name) {
 | 
				
			|||||||
		goto err;
 | 
							goto err;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	printf("Signature is valid\n");
 | 
						/* modify the signature to invalidate it */
 | 
				
			||||||
 | 
						signature[0]++;
 | 
				
			||||||
 | 
						rc = OQS_SIG_verify(sig, message, message_len, signature, signature_len, public_key);
 | 
				
			||||||
 | 
						if (rc != OQS_ERROR) {
 | 
				
			||||||
 | 
							fprintf(stderr, "ERROR: OQS_SIG_verify should have failed!\n");
 | 
				
			||||||
 | 
							goto err;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						printf("verification passes as expected\n");
 | 
				
			||||||
	ret = OQS_SUCCESS;
 | 
						ret = OQS_SUCCESS;
 | 
				
			||||||
	goto cleanup;
 | 
						goto cleanup;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user