Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add benchmarking for stateful hash based schemes: speed_sig_stfl #1952

Merged
merged 11 commits into from
Oct 22, 2024
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 5 additions & 1 deletion tests/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,7 @@ target_link_libraries(test_sig_mem PRIVATE ${TEST_DEPS})
add_executable(speed_sig speed_sig.c)
target_link_libraries(speed_sig PRIVATE ${TEST_DEPS})


set(SIG_TESTS example_sig kat_sig test_sig test_sig_mem speed_sig vectors_sig)

# SIG_STFL API tests
Expand All @@ -133,7 +134,10 @@ else ()
target_link_libraries(test_sig_stfl PRIVATE ${TEST_DEPS})
endif()

set(SIG_STFL_TESTS kat_sig_stfl test_sig_stfl)
add_executable(speed_sig_stfl speed_sig_stfl.c)
target_link_libraries(speed_sig_stfl PRIVATE ${TEST_DEPS})

set(SIG_STFL_TESTS kat_sig_stfl test_sig_stfl speed_sig_stfl)

add_executable(dump_alg_info dump_alg_info.c)
target_link_libraries(dump_alg_info PRIVATE ${TEST_DEPS})
Expand Down
16 changes: 16 additions & 0 deletions tests/ds_benchmark.h
Original file line number Diff line number Diff line change
Expand Up @@ -289,4 +289,20 @@ static void _bench_init_perfcounters(void) {
PRINT_TIMER_AVG(op_name) \
}

#define TIME_OPERATION_SECONDS_MAXIT(op, op_name, secs, maxit, refresh) \
dstebila marked this conversation as resolved.
Show resolved Hide resolved
{ \
DEFINE_TIMER_VARIABLES \
INITIALIZE_TIMER \
uint64_t _bench_time_goal_usecs = 1000000 * secs; \
while (_bench_time_cumulative < _bench_time_goal_usecs) { \
for (unsigned long long i = 0; i < (maxit) && _bench_time_cumulative < _bench_time_goal_usecs; i++) { \
START_TIMER { op; } \
STOP_TIMER \
} \
if (_bench_time_cumulative < _bench_time_goal_usecs) { refresh; } \
} \
FINALIZE_TIMER \
PRINT_TIMER_AVG(op_name) \
}

#endif
221 changes: 221 additions & 0 deletions tests/speed_sig_stfl.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,221 @@
// SPDX-License-Identifier: MIT

#include <math.h>
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include <oqs/oqs.h>

#if defined(OQS_USE_RASPBERRY_PI)
#define _OQS_RASPBERRY_PI
#endif
#if defined(OQS_SPEED_USE_ARM_PMU)
#define SPEED_USE_ARM_PMU
#endif
#include "ds_benchmark.h"
#include "system_info.c"

OQS_STATUS dummy_secure_storage(uint8_t *sk_buf, size_t sk_buf_len, void *context)
{
return OQS_SUCCESS;
}

static void fullcycle(OQS_SIG_STFL *sig, uint8_t *public_key, OQS_SIG_STFL_SECRET_KEY *secret_key, uint8_t *signature, size_t signature_len, uint8_t *message, size_t message_len) {
if (OQS_SIG_STFL_keypair(sig, public_key, secret_key) != OQS_SUCCESS) {
printf("keygen error. Exiting.\n");
exit(-1);
}
if (OQS_SIG_STFL_sign(sig, signature, &signature_len, message, message_len, secret_key) != OQS_SUCCESS) {
printf("sign error. Exiting.\n");
exit(-1);
}
if (OQS_SIG_STFL_verify(sig, message, message_len, signature, signature_len, public_key) != OQS_SUCCESS) {
printf("verify error. Exiting.\n");
exit(-1);
}
}

static OQS_STATUS sig_speed_wrapper(const char *method_name, uint64_t duration, bool printInfo, bool doFullCycle) {

OQS_SIG_STFL *sig = NULL;
uint8_t *public_key = NULL;
OQS_SIG_STFL_SECRET_KEY *secret_key = NULL;
uint8_t *message = NULL;
uint8_t *signature = NULL;
size_t message_len = 50;
size_t signature_len = 0;
OQS_STATUS ret = OQS_ERROR;

sig = OQS_SIG_STFL_new(method_name);
if (sig == NULL) {
return OQS_SUCCESS;
}

secret_key = OQS_SIG_STFL_SECRET_KEY_new(sig->method_name);
if (secret_key == NULL) {
fprintf(stderr, "ERROR: OQS_SIG_STFL_SECRET_KEY_new failed\n");
goto err;
}
// for LMS context must not be NULL
OQS_SIG_STFL_SECRET_KEY_SET_store_cb(secret_key, &dummy_secure_storage, secret_key);

public_key = malloc(sig->length_public_key);
message = malloc(message_len);
signature = malloc(sig->length_signature);

if ((public_key == NULL) || (secret_key == NULL) || (message == NULL) || (signature == NULL)) {
fprintf(stderr, "ERROR: malloc failed\n");
goto err;
}

OQS_randombytes(message, message_len);

printf("%-36s | %10s | %14s | %15s | %10s | %25s | %10s\n", sig->method_name, "", "", "", "", "", "");
if (!doFullCycle) {
TIME_OPERATION_SECONDS(OQS_SIG_STFL_keypair(sig, public_key, secret_key), "keypair", duration)
unsigned long long max_sigs;
OQS_SIG_STFL_sigs_total(sig, &max_sigs, secret_key);
TIME_OPERATION_SECONDS_MAXIT(OQS_SIG_STFL_sign(sig, signature, &signature_len, message, message_len, secret_key), "sign", duration,
max_sigs, OQS_SIG_STFL_keypair(sig, public_key, secret_key) )
TIME_OPERATION_SECONDS(OQS_SIG_STFL_verify(sig, message, message_len, signature, signature_len, public_key), "verify", duration)
} else {
TIME_OPERATION_SECONDS(fullcycle(sig, public_key, secret_key, signature, signature_len, message, message_len), "fullcycle", duration)
}


if (printInfo) {
printf("public key bytes: %zu, secret key bytes: %zu, signature bytes: %zu\n", sig->length_public_key, sig->length_secret_key, sig->length_signature);
if (signature_len != sig->length_signature) {
printf(" Actual signature length returned (%zu) less than declared maximum signature length (%zu)\n", signature_len, sig->length_signature);
}
}

ret = OQS_SUCCESS;
goto cleanup;

err:
ret = OQS_ERROR;

cleanup:
if (sig != NULL) {
OQS_SIG_STFL_SECRET_KEY_free(secret_key);
}
OQS_MEM_insecure_free(public_key);
OQS_MEM_insecure_free(signature);
OQS_MEM_insecure_free(message);
OQS_SIG_STFL_free(sig);

return ret;
}

static OQS_STATUS printAlgs(void) {
for (size_t i = 0; i < OQS_SIG_STFL_algs_length; i++) {
OQS_SIG_STFL *sig = OQS_SIG_STFL_new(OQS_SIG_STFL_alg_identifier(i));
if (sig == NULL) {
printf("%s (disabled)\n", OQS_SIG_STFL_alg_identifier(i));
} else {
printf("%s\n", OQS_SIG_STFL_alg_identifier(i));
}
OQS_SIG_STFL_free(sig);
}
return OQS_SUCCESS;
}

int main(int argc, char **argv) {

int ret = EXIT_SUCCESS;
OQS_STATUS rc;

bool printUsage = false;
uint64_t duration = 3;
bool printSigInfo = false;
bool doFullCycle = false;

OQS_SIG_STFL *single_sig = NULL;

OQS_init();
OQS_randombytes_switch_algorithm(OQS_RAND_alg_openssl);

for (int i = 1; i < argc; i++) {
if (strcmp(argv[i], "--algs") == 0) {
rc = printAlgs();
if (rc == OQS_SUCCESS) {
OQS_destroy();
return EXIT_SUCCESS;
} else {
OQS_destroy();
return EXIT_FAILURE;
}
} else if ((strcmp(argv[i], "--duration") == 0) || (strcmp(argv[i], "-d") == 0)) {
if (i < argc - 1) {
duration = (uint64_t)strtol(argv[i + 1], NULL, 10);
if (duration > 0) {
i += 1;
continue;
}
}
} else if ((strcmp(argv[i], "--help") == 0) || (strcmp(argv[i], "-h") == 0)) {
printUsage = true;
break;
} else if ((strcmp(argv[i], "--info") == 0) || (strcmp(argv[i], "-i") == 0)) {
printSigInfo = true;
continue;
} else if ((strcmp(argv[i], "--fullcycle") == 0) || (strcmp(argv[i], "-f") == 0)) {
doFullCycle = true;
continue;
} else {
single_sig = OQS_SIG_STFL_new(argv[i]);
if (single_sig == NULL) {
printUsage = true;
break;
}
}
}

if (printUsage) {
fprintf(stderr, "Usage: speed_sig <options> <alg>\n");
fprintf(stderr, "\n");
fprintf(stderr, "<options>\n");
fprintf(stderr, "--algs Print supported algorithms and terminate\n");
fprintf(stderr, "--duration n\n");
fprintf(stderr, " -d n Run each speed test for approximately n seconds, default n=3\n");
fprintf(stderr, "--help\n");
fprintf(stderr, " -h Print usage\n");
fprintf(stderr, "--info\n");
fprintf(stderr, " -i Print info (sizes, security level) about each SIG\n");
fprintf(stderr, "--fullcycle\n");
fprintf(stderr, " -f Test full keygen-sign-verify cycle of each SIG\n");
fprintf(stderr, "\n");
fprintf(stderr, "<alg> Only run the specified SIG method; must be one of the algorithms output by --algs\n");
OQS_destroy();
return EXIT_FAILURE;
}

print_system_info();

printf("Speed test\n");
printf("==========\n");

PRINT_TIMER_HEADER
if (single_sig != NULL) {
rc = sig_speed_wrapper(single_sig->method_name, duration, printSigInfo, doFullCycle);
if (rc != OQS_SUCCESS) {
ret = EXIT_FAILURE;
}
OQS_SIG_STFL_free(single_sig);

} else {
for (size_t i = 0; i < OQS_SIG_STFL_algs_length; i++) {
rc = sig_speed_wrapper(OQS_SIG_STFL_alg_identifier(i), duration, printSigInfo, doFullCycle);
if (rc != OQS_SUCCESS) {
ret = EXIT_FAILURE;
}
}
}
PRINT_TIMER_FOOTER
OQS_destroy();

return ret;
}
Loading