]> wagner.pp.ru Git - openssl-gost/engine.git/blob - benchmark/sign.c
GOST key agreement cofactor fix (#265)
[openssl-gost/engine.git] / benchmark / sign.c
1 /**********************************************************************
2  *             Simple benchmarking for gost-engine                    *
3  *                                                                    *
4  *             Copyright (c) 2018 Cryptocom LTD                       *
5  *             Copyright (c) 2018 <vt@altlinux.org>.                  *
6  *       This file is distributed under the same license as OpenSSL   *
7  **********************************************************************/
8
9 #define _GNU_SOURCE
10 #include <stdio.h>
11 #include <string.h>
12 #include <time.h>
13 #include <sys/time.h>
14 #include <getopt.h>
15 #include <openssl/rand.h>
16 #include <openssl/conf.h>
17 #include <openssl/err.h>
18 #include <openssl/evp.h>
19 #include <openssl/pem.h>
20 #include <openssl/engine.h>
21
22 const char *tests[] = {
23     "md_gost12_256", "gost2012_256", "A",
24     "md_gost12_256", "gost2012_256", "B",
25     "md_gost12_256", "gost2012_256", "C",
26     "md_gost12_256", "gost2012_256", "TCA",
27     "md_gost12_256", "gost2012_256", "TCB",
28     "md_gost12_256", "gost2012_256", "TCC",
29     "md_gost12_256", "gost2012_256", "TCD",
30
31     "md_gost12_512", "gost2012_512", "A",
32     "md_gost12_512", "gost2012_512", "B",
33     "md_gost12_512", "gost2012_512", "C",
34
35     NULL,
36 };
37
38 static EVP_PKEY *create_key(const char *algname, const char *param)
39 {
40         EVP_PKEY *key1 = EVP_PKEY_new(), *newkey = NULL;
41         EVP_PKEY_CTX *ctx = NULL;
42
43         if(EVP_PKEY_set_type_str(key1, algname, strlen(algname)) <= 0)
44         {
45                 goto err;
46         }
47         if(!(ctx = EVP_PKEY_CTX_new(key1, NULL)))
48         {
49                 goto err;
50         }
51         EVP_PKEY_keygen_init(ctx);
52         if(ERR_peek_last_error())
53         {
54                 goto err;
55         }
56         if(EVP_PKEY_CTX_ctrl_str(ctx, "paramset", param) <= 0)
57         {
58                 goto err;
59         }
60         if(EVP_PKEY_keygen(ctx, &newkey) <= 0)
61         {
62                 goto err;
63         }
64 err:
65         if(ctx)
66                 EVP_PKEY_CTX_free(ctx);
67         EVP_PKEY_free(key1);
68         return newkey;
69 }
70
71 void usage(char *name)
72 {
73         fprintf(stderr, "usage: %s [-l data_len] [-c cycles]\n", name);
74         exit(1);
75 }
76
77 int main(int argc, char **argv)
78 {
79         unsigned int data_len = 1;
80         unsigned int cycles = 100;
81         int option;
82         clockid_t clock_type = CLOCK_MONOTONIC;
83         int test, test_count = 0;
84
85         opterr = 0;
86         while((option = getopt(argc, argv, "l:c:C")) >= 0)
87         {
88                 switch (option)
89                 {
90                         case 'l':
91                                 data_len = atoi(optarg);
92                                 break;
93                         case 'c':
94                                 cycles = atoi(optarg);
95                                 break;
96                         case 'C':
97                                 clock_type = CLOCK_PROCESS_CPUTIME_ID;
98                                 break;
99                         default:
100                                 usage(argv[0]);
101                                 break;
102                 }
103         }
104         if (optind < argc) usage(argv[0]);
105         if (cycles < 100) { printf("cycles too low\n"); exit(1); }
106
107         OPENSSL_add_all_algorithms_conf();
108         ERR_load_crypto_strings();
109
110         for (test = 0; tests[test]; test += 3) {
111             double diff[2]; /* sign, verify */
112             const char *digest = tests[test];
113             const char *algo   = tests[test + 1];
114             const char *param  = tests[test + 2];
115             const EVP_MD *mdtype;
116             EVP_MD_CTX *md_ctx;
117             unsigned int siglen;
118             unsigned char *sigbuf;
119             EVP_PKEY *pkey;
120             unsigned char *data;
121             int pass;
122
123             md_ctx = EVP_MD_CTX_new();
124             mdtype = EVP_get_digestbyname(digest);
125             if (!mdtype)
126                 continue;
127             pkey = create_key(algo, param);
128             data = (unsigned char *) malloc(data_len);
129             if (!pkey)
130                 continue;
131
132             test_count++;
133             printf("wait...");
134             fflush(stdout);
135             siglen = EVP_PKEY_size(pkey);
136             sigbuf = malloc(siglen * cycles);
137         if (!sigbuf) {
138             fprintf(stderr, "No tests were run, malloc failure.\n");
139             exit(1);
140         }
141
142             for (pass = 0; pass < 2; pass++) {
143                 struct timespec ts;
144                 struct timeval debut, fin, delta;
145                 int err;
146                 unsigned int i;
147
148                 clock_gettime(clock_type, &ts);
149                 TIMESPEC_TO_TIMEVAL(&debut, &ts);
150
151                 if (pass == 0) { /* sign */
152                     for (i = 0; i < cycles; i++) {
153                         EVP_SignInit(md_ctx, mdtype);
154                         err = EVP_SignUpdate(md_ctx, data, data_len)
155                            && EVP_SignFinal(md_ctx, &sigbuf[siglen * i],
156                             (unsigned int *)&siglen, pkey);
157                         if (err != 1)
158                             printf("!");
159                         EVP_MD_CTX_reset(md_ctx);
160                     }
161                 } else { /* verify */
162                     for (i = 0; i < cycles; i++) {
163                         EVP_VerifyInit(md_ctx, mdtype);
164                         err = EVP_VerifyUpdate(md_ctx, data, data_len)
165                            && EVP_VerifyFinal(md_ctx, &sigbuf[siglen * i],
166                             siglen, pkey);
167                         EVP_MD_CTX_reset(md_ctx);
168                         if (err != 1)
169                             printf("!");
170                     }
171                 }
172
173                 clock_gettime(clock_type, &ts);
174                 TIMESPEC_TO_TIMEVAL(&fin, &ts);
175                 timersub(&fin, &debut, &delta);
176                 diff[pass] = (double)delta.tv_sec + (double)delta.tv_usec / 1000000;
177             }
178             printf("\r%s %s: sign: %.1f/s, verify: %.1f/s\n", algo, param,
179                 (double)cycles / diff[0], (double)cycles / diff[1]);
180             EVP_PKEY_free(pkey);
181             free(sigbuf);
182             free(data);
183         }
184
185         if (!test_count) {
186             fprintf(stderr, "No tests were run, something is wrong.\n");
187             exit(1);
188         }
189         exit(0);
190 }