Added support for DH groups 22, 23 and 24, patch contributed by Joy Latten
[strongswan.git] / scripts / dh_speed.c
1
2 #include <stdio.h>
3 #include <time.h>
4 #include <library.h>
5 #include <debug.h>
6 #include <crypto/diffie_hellman.h>
7
8 static void usage()
9 {
10 printf("usage: dh_speed plugins rounds group1 [group2 [...]]\n");
11 exit(1);
12 }
13
14 struct {
15 char *name;
16 diffie_hellman_group_t group;
17 } groups[] = {
18 {"modp768", MODP_768_BIT},
19 {"modp1024", MODP_1024_BIT},
20 {"modp1024s160", MODP_1024_160},
21 {"modp1536", MODP_1536_BIT},
22 {"modp2048", MODP_2048_BIT},
23 {"modp2048s224", MODP_2048_224},
24 {"modp2048s256", MODP_2048_256},
25 {"modp3072", MODP_3072_BIT},
26 {"modp4096", MODP_4096_BIT},
27 {"modp6144", MODP_6144_BIT},
28 {"modp8192", MODP_8192_BIT},
29 {"ecp256", ECP_256_BIT},
30 {"ecp384", ECP_384_BIT},
31 {"ecp521", ECP_521_BIT},
32 {"ecp192", ECP_192_BIT},
33 {"ecp224", ECP_224_BIT},
34 };
35
36 static void start_timing(struct timespec *start)
37 {
38 clock_gettime(CLOCK_THREAD_CPUTIME_ID, start);
39 }
40
41 static double end_timing(struct timespec *start)
42 {
43 struct timespec end;
44
45 clock_gettime(CLOCK_THREAD_CPUTIME_ID, &end);
46 return (end.tv_nsec - start->tv_nsec) / 1000000000.0 +
47 (end.tv_sec - start->tv_sec) * 1.0;
48 }
49
50 static void run_test(diffie_hellman_group_t group, int rounds)
51 {
52 diffie_hellman_t *l[rounds], *r;
53 chunk_t chunk;
54 struct timespec timing;
55 int round;
56
57 r = lib->crypto->create_dh(lib->crypto, group);
58 if (!r)
59 {
60 printf("skipping %N, not supported\n",
61 diffie_hellman_group_names, group);
62 return;
63 }
64
65 printf("%N:\t",
66 diffie_hellman_group_names, group);
67
68 start_timing(&timing);
69 for (round = 0; round < rounds; round++)
70 {
71 l[round] = lib->crypto->create_dh(lib->crypto, group);
72 }
73 printf("A = g^a/s: %8.1f", rounds / end_timing(&timing));
74
75 for (round = 0; round < rounds; round++)
76 {
77 l[round]->get_my_public_value(l[round], &chunk);
78 r->set_other_public_value(r, chunk);
79 chunk_free(&chunk);
80 }
81
82 r->get_my_public_value(r, &chunk);
83 start_timing(&timing);
84 for (round = 0; round < rounds; round++)
85 {
86 l[round]->set_other_public_value(l[round], chunk);
87 }
88 printf(" | S = B^a/s: %8.1f\n", rounds / end_timing(&timing));
89 chunk_free(&chunk);
90
91 for (round = 0; round < rounds; round++)
92 {
93 l[round]->destroy(l[round]);
94 }
95 r->destroy(r);
96 }
97
98 int main(int argc, char *argv[])
99 {
100 int rounds, i, j;
101
102 if (argc < 4)
103 {
104 usage();
105 }
106
107 library_init(NULL);
108 lib->plugins->load(lib->plugins, NULL, argv[1]);
109 atexit(library_deinit);
110
111 rounds = atoi(argv[2]);
112
113 for (i = 3; i < argc; i++)
114 {
115 bool found = FALSE;
116
117 for (j = 0; j < countof(groups); j++)
118 {
119 if (streq(groups[j].name, argv[i]))
120 {
121 run_test(groups[j].group, rounds);
122 found = TRUE;
123 }
124 }
125 if (!found)
126 {
127 printf("group %s not found\n", argv[i]);
128 }
129 }
130 return 0;
131 }
132