perf_crypto_ecc_dlog.c 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177
  1. /*
  2. This file is part of GNUnet.
  3. Copyright (C) 2015 GNUnet e.V.
  4. GNUnet is free software: you can redistribute it and/or modify it
  5. under the terms of the GNU Affero General Public License as published
  6. by the Free Software Foundation, either version 3 of the License,
  7. or (at your option) any later version.
  8. GNUnet is distributed in the hope that it will be useful, but
  9. WITHOUT ANY WARRANTY; without even the implied warranty of
  10. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  11. Affero General Public License for more details.
  12. You should have received a copy of the GNU Affero General Public License
  13. along with this program. If not, see <http://www.gnu.org/licenses/>.
  14. SPDX-License-Identifier: AGPL3.0-or-later
  15. */
  16. /**
  17. * @file util/perf_crypto_ecc_dlog.c
  18. * @brief benchmark for ECC DLOG calculation
  19. * @author Christian Grothoff
  20. */
  21. #include "platform.h"
  22. #include "gnunet_util_lib.h"
  23. #include <gcrypt.h>
  24. #include <gauger.h>
  25. /**
  26. * Name of the curve we are using. Note that we have hard-coded
  27. * structs that use 256 bits, so using a bigger curve will require
  28. * changes that break stuff badly. The name of the curve given here
  29. * must be agreed by all peers and be supported by libgcrypt.
  30. */
  31. #define CURVE "Ed25519"
  32. /**
  33. * Maximum value we benchmark dlog for.
  34. */
  35. #define MAX_FACT (1024 * 1024)
  36. /**
  37. * Maximum memory to use, sqrt(MAX_FACT) is a good choice.
  38. */
  39. #define MAX_MEM 1024
  40. /**
  41. * How many values do we test?
  42. */
  43. #define TEST_ITER 10
  44. /**
  45. * Range of values to use for MATH tests.
  46. */
  47. #define MATH_MAX 500000
  48. /**
  49. * Do some DLOG operations for testing.
  50. *
  51. * @param edc context for ECC operations
  52. * @param do_dlog #GNUNET_YES if we want to actually do the bencharked operation
  53. */
  54. static void
  55. test_dlog (struct GNUNET_CRYPTO_EccDlogContext *edc,
  56. int do_dlog)
  57. {
  58. gcry_mpi_t fact;
  59. gcry_mpi_t n;
  60. gcry_ctx_t ctx;
  61. gcry_mpi_point_t q;
  62. gcry_mpi_point_t g;
  63. unsigned int i;
  64. int x;
  65. int iret;
  66. GNUNET_assert (0 == gcry_mpi_ec_new (&ctx, NULL, CURVE));
  67. g = gcry_mpi_ec_get_point ("g", ctx, 0);
  68. GNUNET_assert (NULL != g);
  69. n = gcry_mpi_ec_get_mpi ("n", ctx, 0);
  70. q = gcry_mpi_point_new (0);
  71. fact = gcry_mpi_new (0);
  72. for (i = 0; i < TEST_ITER; i++)
  73. {
  74. fprintf (stderr, ".");
  75. x = GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_WEAK,
  76. MAX_FACT);
  77. if (0 == GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_WEAK,
  78. 2))
  79. {
  80. gcry_mpi_set_ui (fact, x);
  81. gcry_mpi_sub (fact, n, fact);
  82. x = -x;
  83. }
  84. else
  85. {
  86. gcry_mpi_set_ui (fact, x);
  87. }
  88. gcry_mpi_ec_mul (q, fact, g, ctx);
  89. if ((GNUNET_YES == do_dlog) &&
  90. (x !=
  91. (iret = GNUNET_CRYPTO_ecc_dlog (edc,
  92. q))))
  93. {
  94. fprintf (stderr,
  95. "DLOG failed for value %d (%d)\n",
  96. x,
  97. iret);
  98. GNUNET_assert (0);
  99. }
  100. }
  101. gcry_mpi_release (fact);
  102. gcry_mpi_release (n);
  103. gcry_mpi_point_release (g);
  104. gcry_mpi_point_release (q);
  105. gcry_ctx_release (ctx);
  106. fprintf (stderr, "\n");
  107. }
  108. int
  109. main (int argc, char *argv[])
  110. {
  111. struct GNUNET_CRYPTO_EccDlogContext *edc;
  112. struct GNUNET_TIME_Absolute start;
  113. struct GNUNET_TIME_Relative delta;
  114. if (! gcry_check_version ("1.6.0"))
  115. {
  116. fprintf (stderr,
  117. _
  118. (
  119. "libgcrypt has not the expected version (version %s is required).\n"),
  120. "1.6.0");
  121. return 0;
  122. }
  123. if (getenv ("GNUNET_GCRYPT_DEBUG"))
  124. gcry_control (GCRYCTL_SET_DEBUG_FLAGS, 1u, 0);
  125. GNUNET_log_setup ("perf-crypto-ecc-dlog",
  126. "WARNING",
  127. NULL);
  128. start = GNUNET_TIME_absolute_get ();
  129. edc = GNUNET_CRYPTO_ecc_dlog_prepare (MAX_FACT,
  130. MAX_MEM);
  131. printf ("DLOG precomputation 1M/1K took %s\n",
  132. GNUNET_STRINGS_relative_time_to_string (
  133. GNUNET_TIME_absolute_get_duration (start),
  134. GNUNET_YES));
  135. GAUGER ("UTIL", "ECC DLOG initialization",
  136. GNUNET_TIME_absolute_get_duration
  137. (start).rel_value_us / 1000LL, "ms/op");
  138. start = GNUNET_TIME_absolute_get ();
  139. /* first do a baseline run without the DLOG */
  140. test_dlog (edc, GNUNET_NO);
  141. delta = GNUNET_TIME_absolute_get_duration (start);
  142. start = GNUNET_TIME_absolute_get ();
  143. test_dlog (edc, GNUNET_YES);
  144. delta = GNUNET_TIME_relative_subtract (GNUNET_TIME_absolute_get_duration (
  145. start),
  146. delta);
  147. printf ("%u DLOG calculations took %s\n",
  148. TEST_ITER,
  149. GNUNET_STRINGS_relative_time_to_string (delta,
  150. GNUNET_YES));
  151. GAUGER ("UTIL", "ECC DLOG operations",
  152. delta.rel_value_us / 1000LL / TEST_ITER,
  153. "ms/op");
  154. GNUNET_CRYPTO_ecc_dlog_release (edc);
  155. return 0;
  156. }
  157. /* end of perf_crypto_ecc_dlog.c */