singe/thirdparty/openssl/gost-engine/benchmark/sign.c
2023-11-16 22:15:24 -06:00

187 lines
4.6 KiB
C

/**********************************************************************
* Simple benchmarking for gost-engine *
* *
* Copyright (c) 2018 Cryptocom LTD *
* Copyright (c) 2018 <vt@altlinux.org>. *
* This file is distributed under the same license as OpenSSL *
**********************************************************************/
#define _GNU_SOURCE
#include <stdio.h>
#include <string.h>
#include <time.h>
#include <sys/time.h>
#include <getopt.h>
#include <openssl/rand.h>
#include <openssl/conf.h>
#include <openssl/err.h>
#include <openssl/evp.h>
#include <openssl/pem.h>
#include <openssl/engine.h>
const char *tests[] = {
"md_gost12_256", "gost2012_256", "A",
"md_gost12_256", "gost2012_256", "B",
"md_gost12_256", "gost2012_256", "C",
"md_gost12_256", "gost2012_256", "TCA",
"md_gost12_256", "gost2012_256", "TCB",
"md_gost12_256", "gost2012_256", "TCC",
"md_gost12_256", "gost2012_256", "TCD",
"md_gost12_512", "gost2012_512", "A",
"md_gost12_512", "gost2012_512", "B",
"md_gost12_512", "gost2012_512", "C",
NULL,
};
static EVP_PKEY *create_key(const char *algname, const char *param)
{
EVP_PKEY *key1 = EVP_PKEY_new(), *newkey = NULL;
EVP_PKEY_CTX *ctx = NULL;
if (EVP_PKEY_set_type_str(key1, algname, strlen(algname)) <= 0)
goto err;
if (!(ctx = EVP_PKEY_CTX_new(key1, NULL)))
goto err;
if (EVP_PKEY_keygen_init(ctx) == 0)
goto err;
if (ERR_peek_last_error())
goto err;
if (EVP_PKEY_CTX_ctrl_str(ctx, "paramset", param) <= 0)
goto err;
if (EVP_PKEY_keygen(ctx, &newkey) <= 0)
goto err;
err:
if(ctx)
EVP_PKEY_CTX_free(ctx);
EVP_PKEY_free(key1);
return newkey;
}
void usage(char *name)
{
fprintf(stderr, "usage: %s [-l data_len] [-c cycles]\n", name);
exit(1);
}
int main(int argc, char **argv)
{
unsigned int data_len = 1;
unsigned int cycles = 100;
int option;
clockid_t clock_type = CLOCK_MONOTONIC;
int test, test_count = 0;
opterr = 0;
while((option = getopt(argc, argv, "l:c:C")) >= 0)
{
switch (option)
{
case 'l':
data_len = atoi(optarg);
break;
case 'c':
cycles = atoi(optarg);
break;
case 'C':
clock_type = CLOCK_PROCESS_CPUTIME_ID;
break;
default:
usage(argv[0]);
break;
}
}
if (optind < argc) usage(argv[0]);
if (cycles < 100) { printf("cycles too low\n"); exit(1); }
OPENSSL_add_all_algorithms_conf();
ERR_load_crypto_strings();
for (test = 0; tests[test]; test += 3) {
double diff[2]; /* sign, verify */
const char *digest = tests[test];
const char *algo = tests[test + 1];
const char *param = tests[test + 2];
const EVP_MD *mdtype;
EVP_MD_CTX *md_ctx;
unsigned int siglen;
unsigned char *sigbuf;
EVP_PKEY *pkey;
unsigned char *data;
int pass;
md_ctx = EVP_MD_CTX_new();
mdtype = EVP_get_digestbyname(digest);
if (!mdtype)
continue;
pkey = create_key(algo, param);
data = (unsigned char *) malloc(data_len);
if (!pkey)
continue;
test_count++;
printf("wait...");
fflush(stdout);
siglen = EVP_PKEY_size(pkey);
sigbuf = malloc(siglen * cycles);
if (!sigbuf) {
fprintf(stderr, "No tests were run, malloc failure.\n");
exit(1);
}
for (pass = 0; pass < 2; pass++) {
struct timespec ts;
struct timeval debut, fin, delta;
int err;
unsigned int i;
clock_gettime(clock_type, &ts);
TIMESPEC_TO_TIMEVAL(&debut, &ts);
if (pass == 0) { /* sign */
for (i = 0; i < cycles; i++) {
EVP_SignInit(md_ctx, mdtype);
err = EVP_SignUpdate(md_ctx, data, data_len)
&& EVP_SignFinal(md_ctx, &sigbuf[siglen * i],
(unsigned int *)&siglen, pkey);
if (err != 1)
printf("!");
EVP_MD_CTX_reset(md_ctx);
}
} else { /* verify */
for (i = 0; i < cycles; i++) {
EVP_VerifyInit(md_ctx, mdtype);
err = EVP_VerifyUpdate(md_ctx, data, data_len)
&& EVP_VerifyFinal(md_ctx, &sigbuf[siglen * i],
siglen, pkey);
EVP_MD_CTX_reset(md_ctx);
if (err != 1)
printf("!");
}
}
clock_gettime(clock_type, &ts);
TIMESPEC_TO_TIMEVAL(&fin, &ts);
timersub(&fin, &debut, &delta);
diff[pass] = (double)delta.tv_sec + (double)delta.tv_usec / 1000000;
}
printf("\r%s %s: sign: %.1f/s, verify: %.1f/s\n", algo, param,
(double)cycles / diff[0], (double)cycles / diff[1]);
EVP_PKEY_free(pkey);
free(sigbuf);
free(data);
}
if (!test_count) {
fprintf(stderr, "No tests were run, something is wrong.\n");
exit(1);
}
exit(0);
}