| 1 | #include <stdio.h> |
| 2 | #include <stdlib.h> |
| 3 | #include <string.h> |
| 4 | #include <time.h> |
| 5 | #include <openssl/ec.h> |
| 6 | #include <openssl/ecdsa.h> |
| 7 | #include <openssl/obj_mac.h> |
| 8 | #include <openssl/sha.h> |
| 9 | #include <openssl/rand.h> |
| 10 | #include <sys/time.h> |
| 11 | |
| 12 | #define ITERATIONS 1000 |
| 13 | #define MESSAGE "Benchmark message" |
| 14 | |
| 15 | // Function to calculate the difference in microseconds between two timevals |
| 16 | long time_diff_microseconds(struct timeval start, struct timeval end) { |
| 17 | long seconds = end.tv_sec - start.tv_sec; |
| 18 | long useconds = end.tv_usec - start.tv_usec; |
| 19 | return seconds * 1000000 + useconds; |
| 20 | } |
| 21 | |
| 22 | int main() { |
| 23 | int iterations = ITERATIONS; |
| 24 | struct timeval start, end; |
| 25 | long total_gen_time = 0; |
| 26 | long total_sign_time = 0; |
| 27 | long total_verify_time = 0; |
| 28 | long avg_gen_time, avg_sign_time, avg_verify_time; |
| 29 | |
| 30 | // Benchmarking key generation |
| 31 | printf("Benchmarking key generation...\n"); |
| 32 | for(int i = 0; i < iterations; i++) { |
| 33 | gettimeofday(&start, NULL); |
| 34 | |
| 35 | // Create a new EC_KEY object with the P-256 curve |
| 36 | EC_KEY *key = EC_KEY_new_by_curve_name(NID_X9_62_prime256v1); |
| 37 | if (key == NULL) { |
| 38 | fprintf(stderr, "Error creating EC_KEY object.\n"); |
| 39 | exit(EXIT_FAILURE); |
| 40 | } |
| 41 | |
| 42 | // Generate the key |
| 43 | if (EC_KEY_generate_key(key) != 1) { |
| 44 | fprintf(stderr, "Error generating EC key.\n"); |
| 45 | EC_KEY_free(key); |
| 46 | exit(EXIT_FAILURE); |
| 47 | } |
| 48 | |
| 49 | gettimeofday(&end, NULL); |
| 50 | total_gen_time += time_diff_microseconds(start, end); |
| 51 | |
| 52 | // Free the key |
| 53 | EC_KEY_free(key); |
| 54 | } |
| 55 | avg_gen_time = total_gen_time / iterations; |
| 56 | printf("Average key generation time: %ld µs\n", avg_gen_time); |
| 57 | |
| 58 | // Generate a single key for signing and verification |
| 59 | EC_KEY *priv_key = EC_KEY_new_by_curve_name(NID_X9_62_prime256v1); |
| 60 | if (priv_key == NULL) { |
| 61 | fprintf(stderr, "Error creating EC_KEY object.\n"); |
| 62 | exit(EXIT_FAILURE); |
| 63 | } |
| 64 | if (EC_KEY_generate_key(priv_key) != 1) { |
| 65 | fprintf(stderr, "Error generating EC key.\n"); |
| 66 | EC_KEY_free(priv_key); |
| 67 | exit(EXIT_FAILURE); |
| 68 | } |
| 69 | |
| 70 | // Prepare the message hash |
| 71 | unsigned char hash[SHA256_DIGEST_LENGTH]; |
| 72 | SHA256((unsigned char*)MESSAGE, strlen(MESSAGE), hash); |
| 73 | |
| 74 | // Benchmarking signing |
| 75 | printf("Benchmarking signing...\n"); |
| 76 | for(int i = 0; i < iterations; i++) { |
| 77 | gettimeofday(&start, NULL); |
| 78 | |
| 79 | ECDSA_SIG *signature = ECDSA_do_sign(hash, SHA256_DIGEST_LENGTH, priv_key); |
| 80 | if (signature == NULL) { |
| 81 | fprintf(stderr, "Error signing message.\n"); |
| 82 | EC_KEY_free(priv_key); |
| 83 | exit(EXIT_FAILURE); |
| 84 | } |
| 85 | |
| 86 | gettimeofday(&end, NULL); |
| 87 | total_sign_time += time_diff_microseconds(start, end); |
| 88 | |
| 89 | // Free the signature |
| 90 | ECDSA_SIG_free(signature); |
| 91 | } |
| 92 | avg_sign_time = total_sign_time / iterations; |
| 93 | printf("Average sign time: %ld µs\n", avg_sign_time); |
| 94 | |
| 95 | // Create a signature for verification benchmarking |
| 96 | ECDSA_SIG *signature = ECDSA_do_sign(hash, SHA256_DIGEST_LENGTH, priv_key); |
| 97 | if (signature == NULL) { |
| 98 | fprintf(stderr, "Error signing message for verification.\n"); |
| 99 | EC_KEY_free(priv_key); |
| 100 | exit(EXIT_FAILURE); |
| 101 | } |
| 102 | |
| 103 | // Benchmarking verification |
| 104 | printf("Benchmarking verification...\n"); |
| 105 | for(int i = 0; i < iterations; i++) { |
| 106 | gettimeofday(&start, NULL); |
| 107 | |
| 108 | int verify_status = ECDSA_do_verify(hash, SHA256_DIGEST_LENGTH, signature, priv_key); |
| 109 | |
| 110 | gettimeofday(&end, NULL); |
| 111 | total_verify_time += time_diff_microseconds(start, end); |
| 112 | |
| 113 | if (verify_status != 1) { |
| 114 | fprintf(stderr, "Signature verification failed.\n"); |
| 115 | ECDSA_SIG_free(signature); |
| 116 | EC_KEY_free(priv_key); |
| 117 | exit(EXIT_FAILURE); |
| 118 | } |
| 119 | } |
| 120 | avg_verify_time = total_verify_time / iterations; |
| 121 | printf("Average verify time: %ld µs\n", avg_verify_time); |
| 122 | |
| 123 | // Cleanup |
| 124 | ECDSA_SIG_free(signature); |
| 125 | EC_KEY_free(priv_key); |
| 126 | |
| 127 | return 0; |
| 128 | } |
| 129 | |
| 130 | |