Add a performance test for EVP_PKEY_new_raw_public_key_ex()
[tools.git] / perf / newrawkey.c
1 /*
2  * Copyright 2023 The OpenSSL Project Authors. All Rights Reserved.
3  *
4  * Licensed under the Apache License 2.0 (the "License").  You may not use
5  * this file except in compliance with the License.  You can obtain a copy
6  * in the file LICENSE in the source distribution or at
7  * https://www.openssl.org/source/license.html
8  */
9
10 #include <stdlib.h>
11 #include <stdio.h>
12 #include <string.h>
13 #include <openssl/evp.h>
14 #include "perflib/perflib.h"
15
16 #define NUM_CALLS_PER_BLOCK         100
17 #define NUM_CALL_BLOCKS_PER_THREAD  100
18 #define NUM_CALLS_PER_THREAD        (NUM_CALLS_PER_BLOCK * NUM_CALL_BLOCKS_PER_THREAD)
19
20 int err = 0;
21
22 static unsigned char buf[32] = {
23     0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b,
24     0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
25     0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f
26 };
27
28 void do_newrawkey(size_t num)
29 {
30     int i;
31     EVP_PKEY *pkey;
32
33     for (i = 0; i < NUM_CALLS_PER_THREAD; i++) {
34         pkey = EVP_PKEY_new_raw_public_key_ex(NULL, "X25519", NULL, buf,
35                                               sizeof(buf));
36         if (pkey == NULL)
37             err = 1;
38         else
39             EVP_PKEY_free(pkey);
40     }
41 }
42
43 int main(int argc, char *argv[])
44 {
45     int threadcount;
46     OSSL_TIME duration;
47     uint64_t us;
48     double avcalltime;
49     int terse = 0;
50     int argnext;
51
52     if ((argc != 2 && argc != 3)
53                 || (argc == 3 && strcmp("--terse", argv[1]) != 0)) {
54         printf("Usage: newrawkey [--terse] threadcount\n");
55         return EXIT_FAILURE;
56     }
57
58     if (argc == 3) {
59         terse = 1;
60         argnext = 2;
61     } else {
62         argnext = 1;
63     }
64
65     threadcount = atoi(argv[argnext]);
66     if (threadcount < 1) {
67         printf("threadcount must be > 0\n");
68         return EXIT_FAILURE;
69     }
70
71     if (!perflib_run_multi_thread_test(do_newrawkey, threadcount, &duration)) {
72         printf("Failed to run the test\n");
73         return EXIT_FAILURE;
74     }
75
76     if (err) {
77         printf("Error during test\n");
78         return EXIT_FAILURE;
79     }
80
81     us = ossl_time2us(duration);
82
83     avcalltime = (double)us / (NUM_CALL_BLOCKS_PER_THREAD * threadcount);
84
85     if (terse)
86         printf("%lf\n", avcalltime);
87     else
88         printf("Average time per %d EVP_PKEY_new_raw_public_key_ex() calls: %lfus\n",
89                NUM_CALLS_PER_BLOCK, avcalltime);
90
91     return EXIT_SUCCESS;
92 }