dh_speed.c 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152
  1. /*
  2. * Copyright (C) 2009 Martin Willi
  3. * HSR Hochschule fuer Technik Rapperswil
  4. *
  5. * This program is free software; you can redistribute it and/or modify it
  6. * under the terms of the GNU General Public License as published by the
  7. * Free Software Foundation; either version 2 of the License, or (at your
  8. * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
  9. *
  10. * This program is distributed in the hope that it will be useful, but
  11. * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
  12. * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
  13. * for more details.
  14. */
  15. #include <stdio.h>
  16. #include <time.h>
  17. #include <assert.h>
  18. #include <library.h>
  19. #include <utils/debug.h>
  20. #include <crypto/diffie_hellman.h>
  21. static void usage()
  22. {
  23. printf("usage: dh_speed plugins rounds group1 [group2 [...]]\n");
  24. exit(1);
  25. }
  26. struct {
  27. char *name;
  28. diffie_hellman_group_t group;
  29. } groups[] = {
  30. {"modp768", MODP_768_BIT},
  31. {"modp1024", MODP_1024_BIT},
  32. {"modp1024s160", MODP_1024_160},
  33. {"modp1536", MODP_1536_BIT},
  34. {"modp2048", MODP_2048_BIT},
  35. {"modp2048s224", MODP_2048_224},
  36. {"modp2048s256", MODP_2048_256},
  37. {"modp3072", MODP_3072_BIT},
  38. {"modp4096", MODP_4096_BIT},
  39. {"modp6144", MODP_6144_BIT},
  40. {"modp8192", MODP_8192_BIT},
  41. {"ecp256", ECP_256_BIT},
  42. {"ecp384", ECP_384_BIT},
  43. {"ecp521", ECP_521_BIT},
  44. {"ecp192", ECP_192_BIT},
  45. {"ecp224", ECP_224_BIT},
  46. {"curve25519", CURVE_25519},
  47. {"curve448", CURVE_448},
  48. };
  49. static void start_timing(struct timespec *start)
  50. {
  51. clock_gettime(CLOCK_THREAD_CPUTIME_ID, start);
  52. }
  53. static double end_timing(struct timespec *start)
  54. {
  55. struct timespec end;
  56. clock_gettime(CLOCK_THREAD_CPUTIME_ID, &end);
  57. return (end.tv_nsec - start->tv_nsec) / 1000000000.0 +
  58. (end.tv_sec - start->tv_sec) * 1.0;
  59. }
  60. static void run_test(diffie_hellman_group_t group, int rounds)
  61. {
  62. diffie_hellman_t *l[rounds], *r;
  63. chunk_t chunk, chunks[rounds], lsecrets[rounds], rsecrets[rounds];
  64. struct timespec timing;
  65. int round;
  66. r = lib->crypto->create_dh(lib->crypto, group);
  67. if (!r)
  68. {
  69. printf("skipping %N, not supported\n",
  70. diffie_hellman_group_names, group);
  71. return;
  72. }
  73. printf("%N:\t", diffie_hellman_group_names, group);
  74. start_timing(&timing);
  75. for (round = 0; round < rounds; round++)
  76. {
  77. l[round] = lib->crypto->create_dh(lib->crypto, group);
  78. assert(l[round]->get_my_public_value(l[round], &chunks[round]));
  79. }
  80. printf("A = g^a/s: %8.1f", rounds / end_timing(&timing));
  81. for (round = 0; round < rounds; round++)
  82. {
  83. assert(r->set_other_public_value(r, chunks[round]));
  84. assert(r->get_shared_secret(r, &rsecrets[round]));
  85. chunk_free(&chunks[round]);
  86. }
  87. assert(r->get_my_public_value(r, &chunk));
  88. start_timing(&timing);
  89. for (round = 0; round < rounds; round++)
  90. {
  91. assert(l[round]->set_other_public_value(l[round], chunk));
  92. assert(l[round]->get_shared_secret(l[round], &lsecrets[round]));
  93. }
  94. printf(" | S = B^a/s: %8.1f\n", rounds / end_timing(&timing));
  95. chunk_free(&chunk);
  96. for (round = 0; round < rounds; round++)
  97. {
  98. assert(chunk_equals(rsecrets[round], lsecrets[round]));
  99. free(lsecrets[round].ptr);
  100. free(rsecrets[round].ptr);
  101. l[round]->destroy(l[round]);
  102. }
  103. r->destroy(r);
  104. }
  105. int main(int argc, char *argv[])
  106. {
  107. int rounds, i, j;
  108. if (argc < 4)
  109. {
  110. usage();
  111. }
  112. library_init(NULL, "dh_speed");
  113. lib->plugins->load(lib->plugins, argv[1]);
  114. atexit(library_deinit);
  115. rounds = atoi(argv[2]);
  116. for (i = 3; i < argc; i++)
  117. {
  118. bool found = FALSE;
  119. for (j = 0; j < countof(groups); j++)
  120. {
  121. if (streq(groups[j].name, argv[i]))
  122. {
  123. run_test(groups[j].group, rounds);
  124. found = TRUE;
  125. }
  126. }
  127. if (!found)
  128. {
  129. printf("group %s not found\n", argv[i]);
  130. }
  131. }
  132. return 0;
  133. }