second-round version of SQIsign

Co-authored-by: Marius A. Aardal <marius.andre.aardal@gmail.com>
Co-authored-by: Gora Adj <gora.adj@tii.ae>
Co-authored-by: Diego F. Aranha <dfaranha@cs.au.dk>
Co-authored-by: Andrea Basso <sqisign@andreabasso.com>
Co-authored-by: Isaac Andrés Canales Martínez <icanalesm0500@gmail.com>
Co-authored-by: Jorge Chávez-Saab <jorgechavezsaab@gmail.com>
Co-authored-by: Maria Corte-Real Santos <mariascrsantos98@gmail.com>
Co-authored-by: Luca De Feo <github@defeo.lu>
Co-authored-by: Max Duparc <max.duparc@epfl.ch>
Co-authored-by: Jonathan Komada Eriksen <jonathan.eriksen97@gmail.com>
Co-authored-by: Décio Luiz Gazzoni Filho <decio@decpp.net>
Co-authored-by: Basil Hess <bhe@zurich.ibm.com>
Co-authored-by: Antonin Leroux <antonin.leroux@polytechnique.org>
Co-authored-by: Patrick Longa <plonga@microsoft.com>
Co-authored-by: Luciano Maino <mainoluciano.96@gmail.com>
Co-authored-by: Michael Meyer <michael@random-oracles.org>
Co-authored-by: Hiroshi Onuki <onuki@mist.i.u-tokyo.ac.jp>
Co-authored-by: Lorenz Panny <lorenz@yx7.cc>
Co-authored-by: Giacomo Pope <giacomopope@gmail.com>
Co-authored-by: Krijn Reijnders <reijnderskrijn@gmail.com>
Co-authored-by: Damien Robert <damien.robert@inria.fr>
Co-authored-by: Francisco Rodríguez-Henriquez <francisco.rodriguez@tii.ae>
Co-authored-by: Sina Schaeffler <sschaeffle@student.ethz.ch>
Co-authored-by: Benjamin Wesolowski <benjamin.wesolowski@ens-lyon.fr>
This commit is contained in:
SQIsign team
2025-02-06 00:00:00 +00:00
committed by Lorenz Panny
parent ff34a8cd18
commit 91e9e464fe
481 changed files with 80785 additions and 55963 deletions

View File

@@ -1,27 +1,22 @@
# SPDX-License-Identifier: Apache-2.0
FOREACH(SVARIANT ${SVARIANT_S})
string(TOLOWER ${SVARIANT} SVARIANT_LOWER)
string(TOUPPER ${SVARIANT} SVARIANT_UPPER)
add_executable(sqisign_test_kat_${SVARIANT} test_kat.c)
target_link_libraries(sqisign_test_kat_${SVARIANT} sqisign_${SVARIANT_LOWER}_test)
target_include_directories(sqisign_test_kat_${SVARIANT} PRIVATE ${PROJECT_SOURCE_DIR}/src/nistapi/${SVARIANT_LOWER} ${INC_PUBLIC} ${INC_INTBIG} ${INC_PRECOMP_${SVARIANT_UPPER}} ${INC_QUATERNION} ${INC_KLPT} ${INC_GF_${SVARIANT_UPPER}} ${INC_EC} ${INC_COMMON} ${INC_ID2ISO} ${INC_PROTOCOLS})
add_test(sqisign_${SVARIANT}_KAT sqisign_test_kat_${SVARIANT})
add_executable(sqisign_bench_${SVARIANT} bench.c)
target_link_libraries(sqisign_bench_${SVARIANT} sqisign_${SVARIANT_LOWER})
target_include_directories(sqisign_bench_${SVARIANT} PUBLIC ${PROJECT_SOURCE_DIR}/src/common ${INC_PUBLIC} ${PROJECT_SOURCE_DIR}/src/nistapi/${SVARIANT_LOWER})
if (ENABLE_SIGN)
add_executable(sqisign_test_scheme_${SVARIANT} test_sqisign.c)
target_link_libraries(sqisign_test_scheme_${SVARIANT} sqisign_${SVARIANT_LOWER})
target_include_directories(sqisign_test_scheme_${SVARIANT} PUBLIC ${PROJECT_SOURCE_DIR}/src/common ${INC_PUBLIC} ${PROJECT_SOURCE_DIR}/src/nistapi/${SVARIANT_LOWER})
add_executable(sqisign_test_scheme_${SVARIANT} test_sqisign.c)
target_link_libraries(sqisign_test_scheme_${SVARIANT} sqisign_${SVARIANT_LOWER})
target_include_directories(sqisign_test_scheme_${SVARIANT} PUBLIC ${PROJECT_SOURCE_DIR}/src/common ${INC_PUBLIC} ${PROJECT_SOURCE_DIR}/src/nistapi/${SVARIANT_LOWER})
add_test(sqisign_${SVARIANT}_SELFTEST sqisign_test_scheme_${SVARIANT})
add_executable(sqisign_test_prof_${SVARIANT} test_sqisign_prof.c)
target_link_libraries(sqisign_test_prof_${SVARIANT} sqisign_${SVARIANT_LOWER})
target_include_directories(sqisign_test_prof_${SVARIANT} PUBLIC ${PROJECT_SOURCE_DIR}/src/common ${INC_PUBLIC} ${PROJECT_SOURCE_DIR}/src/nistapi/${SVARIANT_LOWER})
endif()
add_test(sqisign_${SVARIANT}_KAT sqisign_test_kat_${SVARIANT} 0) # testing only the first KAT
add_test(sqisign_${SVARIANT}_SELFTEST sqisign_test_scheme_${SVARIANT})
set_tests_properties(sqisign_${SVARIANT}_KAT PROPERTIES TIMEOUT 0)
ENDFOREACH()

View File

@@ -1,135 +0,0 @@
// SPDX-License-Identifier: Apache-2.0
#include <sig.h>
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <inttypes.h>
#include <api.h>
#if defined(TARGET_OS_UNIX) && (defined(TARGET_ARM) || defined(TARGET_ARM64) || defined(TARGET_OTHER))
#include <time.h>
#endif
#if (defined(TARGET_ARM) || defined(TARGET_ARM64) || defined(TARGET_S390X) || defined(TARGET_OTHER))
#define print_unit printf("nsec\n");
#else
#define print_unit printf("cycles\n");
#endif
static int bench_sig(int runs, int csv);
static inline int64_t cpucycles(void);
int main(int argc, char *argv[]) {
int rc = 0;
#ifndef NDEBUG
fprintf(stderr, "\x1b[31mIt looks like SQIsign was compiled with assertions enabled.\n"
"This will severely impact performance measurements.\x1b[0m\n");
#endif
if (argc < 2) {
printf("One argument needed\n");
rc = 1;
goto end;
}
int runs = atoi(argv[1]);
rc = bench_sig(runs, 0);
end:
return rc;
}
#if (defined(TARGET_ARM) || defined(TARGET_ARM64) || defined(TARGET_S390X))
#define BENCH_UNITS "nsec"
#else
#define BENCH_UNITS "cycles"
#endif
int cmpfunc (const void *a, const void *b) {
return ( *(uint64_t *)a - * (uint64_t *)b );
}
#define BENCH_CODE_1(r) \
cycles = 0; \
for (i = 0; i < (r); ++i) { \
cycles1 = cpucycles();
#define BENCH_CODE_2(name, csv) \
cycles2 = cpucycles(); \
if(i < LIST_SIZE) \
cycles_list[i] = (cycles2 - cycles1);\
cycles = cycles + (cycles2 - cycles1); \
} \
qsort(cycles_list, (runs < LIST_SIZE)? runs : LIST_SIZE, sizeof(uint64_t), cmpfunc);\
if (csv) \
printf("%2" PRId64 ",", cycles_list[(runs < LIST_SIZE)? runs/2 : LIST_SIZE/2]); \
else { \
printf(" %-20s-> median: %2" PRId64 ", average: %2" PRId64 " ", name, \
cycles_list[(runs < LIST_SIZE)? runs/2 : LIST_SIZE/2], (cycles / runs)); \
printf("%s\n", BENCH_UNITS); \
}
#define LIST_SIZE 10000
static int bench_sig(int runs, int csv) {
int rc = 0;
int i;
int64_t cycles, cycles1, cycles2;
int64_t cycles_list[10000];
const int m_len = 32;
unsigned char *pk = calloc(CRYPTO_PUBLICKEYBYTES, 1);
unsigned char *sk = calloc(CRYPTO_SECRETKEYBYTES, 1);
unsigned char *sig = calloc(CRYPTO_BYTES + m_len, 1);
unsigned char *m = calloc(m_len, 1);
unsigned long long len = CRYPTO_BYTES;
if (csv) {
printf("%s,", CRYPTO_ALGNAME);
} else {
printf("Benchmarking %s\n", CRYPTO_ALGNAME);
}
BENCH_CODE_1(runs);
sqisign_keypair(pk, sk);
BENCH_CODE_2("sqisign_keypair", csv);
BENCH_CODE_1(runs);
sqisign_sign(sig, &len, m, m_len, sk);
BENCH_CODE_2("sqisign_sign", csv);
len = 32;
BENCH_CODE_1(runs);
sqisign_open(m, &len, sig, CRYPTO_BYTES, pk);
BENCH_CODE_2("sqisign_verify", csv);
if (csv) {
printf("\n");
}
free(pk);
free(sk);
free(sig);
free(m);
return rc;
}
static inline int64_t cpucycles(void) {
#if (defined(TARGET_AMD64) || defined(TARGET_X86))
unsigned int hi, lo;
asm volatile ("rdtsc" : "=a" (lo), "=d"(hi));
return ((int64_t) lo) | (((int64_t) hi) << 32);
#elif (defined(TARGET_S390X))
uint64_t tod;
asm volatile("stckf %0\n" : "=Q" (tod) : : "cc");
return (tod * 1000 / 4096);
#else
struct timespec time;
clock_gettime(CLOCK_REALTIME, &time);
return (int64_t)(time.tv_sec * 1e9 + time.tv_nsec);
#endif
}

View File

@@ -37,17 +37,22 @@ int main(int argc, char *argv[]) {
static int test_sig_kat(int cnt) {
#if defined(ENABLE_SIGN)
unsigned char seed[48];
unsigned char *m, *sm, *m1, *sm_rsp;
unsigned char sk[CRYPTO_SECRETKEYBYTES];
unsigned char pk[CRYPTO_PUBLICKEYBYTES];
unsigned char sk_rsp[CRYPTO_SECRETKEYBYTES];
unsigned char *sm;
#endif
unsigned char pk_rsp[CRYPTO_PUBLICKEYBYTES];
unsigned char *m, *m1, *sm_rsp;
unsigned long long mlen, smlen, mlen1;
int count;
int done;
unsigned char pk[CRYPTO_PUBLICKEYBYTES], sk[CRYPTO_SECRETKEYBYTES];
int ret_val;
char fn_rsp[64];
FILE *fp_rsp;
unsigned char pk_rsp[CRYPTO_PUBLICKEYBYTES], sk_rsp[CRYPTO_SECRETKEYBYTES];
sprintf(fn_rsp, "../../KAT/PQCsignKAT_%d_%s.rsp", CRYPTO_SECRETKEYBYTES, CRYPTO_ALGNAME);
if ( (fp_rsp = fopen(fn_rsp, "r")) == NULL ) {
@@ -57,6 +62,7 @@ static int test_sig_kat(int cnt) {
done = 0;
do {
if ( FindMarker(fp_rsp, "count = ") ) {
ret_val = fscanf(fp_rsp, "%d", &count);
} else {
@@ -67,12 +73,14 @@ static int test_sig_kat(int cnt) {
if (cnt != -1 && cnt != count)
continue;
#if defined(ENABLE_SIGN)
if ( !ReadHex(fp_rsp, seed, 48, "seed = ") ) {
printf("ERROR: unable to read 'seed' from <%s>\n", fn_rsp);
return KAT_DATA_ERROR;
}
randombytes_init(seed, NULL, 256);
#endif
if ( FindMarker(fp_rsp, "mlen = ") ) {
ret_val = fscanf(fp_rsp, "%lld", &mlen);
@@ -83,7 +91,9 @@ static int test_sig_kat(int cnt) {
m = (unsigned char *)calloc(mlen, sizeof(unsigned char));
m1 = (unsigned char *)calloc(mlen, sizeof(unsigned char));
#if defined(ENABLE_SIGN)
sm = (unsigned char *)calloc(mlen + CRYPTO_BYTES, sizeof(unsigned char));
#endif
sm_rsp = (unsigned char *)calloc(mlen + CRYPTO_BYTES, sizeof(unsigned char));
if ( !ReadHex(fp_rsp, m, (int)mlen, "msg = ") ) {
@@ -91,15 +101,20 @@ static int test_sig_kat(int cnt) {
return KAT_DATA_ERROR;
}
#if defined(ENABLE_SIGN)
// Generate the public/private keypair
if ( (ret_val = sqisign_keypair(pk, sk)) != 0) {
printf("crypto_sign_keypair returned <%d>\n", ret_val);
return KAT_CRYPTO_FAILURE;
}
#endif
if ( !ReadHex(fp_rsp, pk_rsp, CRYPTO_PUBLICKEYBYTES, "pk = ") ) {
printf("ERROR: unable to read 'pk' from <%s>\n", fn_rsp);
return KAT_DATA_ERROR;
}
#if defined(ENABLE_SIGN)
if ( !ReadHex(fp_rsp, sk_rsp, CRYPTO_SECRETKEYBYTES, "sk = ") ) {
printf("ERROR: unable to read 'sk' from <%s>\n", fn_rsp);
return KAT_DATA_ERROR;
@@ -109,6 +124,7 @@ static int test_sig_kat(int cnt) {
printf("ERROR: pk is different from <%s>\n", fn_rsp);
return KAT_VERIFICATION_ERROR;
}
if (memcmp(sk, sk_rsp, CRYPTO_SECRETKEYBYTES) != 0) {
printf("ERROR: sk is different from <%s>\n", fn_rsp);
return KAT_VERIFICATION_ERROR;
@@ -129,11 +145,28 @@ static int test_sig_kat(int cnt) {
return KAT_VERIFICATION_ERROR;
}
if ( (ret_val = sqisign_open(m1, &mlen1, sm, smlen, pk)) != 0) {
printf("crypto_sign_open returned <%d>\n", ret_val);
return KAT_CRYPTO_FAILURE;
}
#else
if ( FindMarker(fp_rsp, "smlen = ") ) {
ret_val = fscanf(fp_rsp, "%llu", &smlen);
} else {
printf("ERROR: unable to read 'smlen' from <%s>\n", fn_rsp);
return KAT_DATA_ERROR;
}
if ( !ReadHex(fp_rsp, sm_rsp, smlen, "sm = ") ) {
printf("ERROR: unable to read 'sm' from <%s>\n", fn_rsp);
return KAT_DATA_ERROR;
}
if ( (ret_val = sqisign_open(m1, &mlen1, sm_rsp, smlen, pk_rsp)) != 0 ) {
printf("crypto_sign_open returned <%d>\n", ret_val);
return KAT_CRYPTO_FAILURE;
}
#endif
if ( mlen != mlen1 ) {
printf("crypto_sign_open returned bad 'mlen': Got <%lld>, expected <%lld>\n", mlen1, mlen);
@@ -147,7 +180,9 @@ static int test_sig_kat(int cnt) {
free(m);
free(m1);
#if defined(ENABLE_SIGN)
free(sm);
#endif
free(sm_rsp);
} while ( !done );

View File

@@ -1,5 +1,6 @@
// SPDX-License-Identifier: Apache-2.0
#include <inttypes.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
@@ -7,6 +8,10 @@
#include <rng.h>
#include <sig.h>
#include <api.h>
#include <bench_test_arguments.h>
#ifdef TARGET_BIG_ENDIAN
#include <tutil.h>
#endif
#ifdef ENABLE_CT_TESTING
#include <valgrind/memcheck.h>
@@ -33,17 +38,18 @@ static void print_hex(const unsigned char *hex, int len) {
}
#endif
static int test_sqisign() {
static int test_sqisign(unsigned long long in_msglen) {
unsigned char *pk = calloc(CRYPTO_PUBLICKEYBYTES, 1);
unsigned char *sk = calloc(CRYPTO_SECRETKEYBYTES, 1);
unsigned char *sig = calloc(CRYPTO_BYTES + 32, 1);
unsigned char *sig = calloc(CRYPTO_BYTES + in_msglen, 1);
unsigned char seed[48] = { 0 };
unsigned char msg[32] = { 0 };
unsigned long long msglen = 32;
unsigned char *msg = malloc(in_msglen);
unsigned char *msg_open = malloc(in_msglen);
randombytes_init(seed, NULL, 256);
unsigned long long msglen = in_msglen;
randombytes(msg, in_msglen);
randombytes(msg_open, in_msglen);
printf("Testing Keygen, Sign, Open: %s\n", CRYPTO_ALGNAME);
@@ -57,9 +63,9 @@ static int test_sqisign() {
VALGRIND_MAKE_MEM_DEFINED(pk, CRYPTO_PUBLICKEYBYTES);
#endif
unsigned long long smlen = CRYPTO_BYTES + 32;
unsigned long long smlen = CRYPTO_BYTES + in_msglen;
res = sqisign_sign(sig, &smlen, msg, 32, sk);
res = sqisign_sign(sig, &smlen, msg, in_msglen, sk);
if (res != 0) {
res = -1;
goto err;
@@ -76,14 +82,16 @@ static int test_sqisign() {
VALGRIND_MAKE_MEM_DEFINED(sig, smlen);
#endif
res = sqisign_open(msg, &msglen, sig, smlen, pk);
if (res != 0) {
res = sqisign_open(msg_open, &msglen, sig, smlen, pk);
if (res != 0 || msglen != in_msglen || memcmp(msg_open, msg, msglen)) {
res = -1;
goto err;
}
randombytes(msg_open, in_msglen);
sig[0] = ~sig[0];
res = sqisign_open(msg, &msglen, sig, smlen, pk);
res = sqisign_open(msg_open, &msglen, sig, smlen, pk);
if (res != 1) {
res = -1;
goto err;
@@ -91,20 +99,87 @@ static int test_sqisign() {
res = 0;
}
// Test with `sm` and `m` as the same buffer
msglen = in_msglen;
randombytes(msg, in_msglen);
memcpy(sig, msg, msglen);
res = sqisign_sign(sig, &smlen, sig, in_msglen, sk);
if (res != 0) {
res = -1;
goto err;
}
randombytes(msg_open, in_msglen);
res = sqisign_open(msg_open, &msglen, sig, smlen, pk);
if (res != 0 || msglen != in_msglen || memcmp(msg_open, msg, msglen)) {
res = -1;
goto err;
}
err:
free(pk);
free(sk);
free(sig);
free(msg);
free(msg_open);
return res;
}
int main(int argc, char *argv[]) {
int rc = 0;
uint32_t seed[12] = { 0 };
int help = 0;
int seed_set = 0;
int msglen_set = 0;
int res = 0;
unsigned long long msglen = 32;
rc = test_sqisign();
for (int i = 1; i < argc; i++) {
unsigned int _msglen;
if (rc != 0) {
if (!help && strcmp(argv[i], "--help") == 0) {
help = 1;
continue;
}
if (!seed_set && !parse_seed(argv[i], seed)) {
seed_set = 1;
continue;
}
if (!msglen_set && sscanf(argv[i], "--msglen=%u", &_msglen) == 1) {
msglen = (unsigned long long) _msglen;
msglen_set = 1;
}
}
if (help) {
printf("Usage: %s [--seed=<seed>]\n", argv[0]);
printf("Where <seed> is the random seed to be used; if not present, a random seed is "
"generated\n");
return 1;
}
if (!seed_set) {
randombytes_select((unsigned char *)seed, sizeof(seed));
}
print_seed(seed);
#if defined(TARGET_BIG_ENDIAN)
for (int i = 0; i < 12; i++) {
seed[i] = BSWAP32(seed[i]);
}
#endif
randombytes_init((unsigned char *)seed, NULL, 256);
res = test_sqisign(msglen);
if (res != 0) {
printf("test failed for %s\n", argv[1]);
}
return rc;
return res;
}

File diff suppressed because one or more lines are too long