test_crypto_ecc_dlog.c 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195
  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/test_crypto_ecc_dlog.c
  18. * @brief testcase for ECC DLOG calculation
  19. * @author Christian Grothoff
  20. */
  21. #include "platform.h"
  22. #include "gnunet_util_lib.h"
  23. #include <gcrypt.h>
  24. /**
  25. * Name of the curve we are using. Note that we have hard-coded
  26. * structs that use 256 bits, so using a bigger curve will require
  27. * changes that break stuff badly. The name of the curve given here
  28. * must be agreed by all peers and be supported by libgcrypt.
  29. */
  30. #define CURVE "Ed25519"
  31. /**
  32. * Maximum value we test dlog for.
  33. */
  34. #define MAX_FACT 100
  35. /**
  36. * Maximum memory to use, sqrt(MAX_FACT) is a good choice.
  37. */
  38. #define MAX_MEM 10
  39. /**
  40. * How many values do we test?
  41. */
  42. #define TEST_ITER 10
  43. /**
  44. * Range of values to use for MATH tests.
  45. */
  46. #define MATH_MAX 5
  47. /**
  48. * Do some DLOG operations for testing.
  49. *
  50. * @param edc context for ECC operations
  51. */
  52. static void
  53. test_dlog (struct GNUNET_CRYPTO_EccDlogContext *edc)
  54. {
  55. gcry_mpi_t fact;
  56. gcry_mpi_t n;
  57. gcry_ctx_t ctx;
  58. gcry_mpi_point_t q;
  59. gcry_mpi_point_t g;
  60. unsigned int i;
  61. int x;
  62. int iret;
  63. GNUNET_assert (0 == gcry_mpi_ec_new (&ctx, NULL, CURVE));
  64. g = gcry_mpi_ec_get_point ("g", ctx, 0);
  65. GNUNET_assert (NULL != g);
  66. n = gcry_mpi_ec_get_mpi ("n", ctx, 0);
  67. q = gcry_mpi_point_new (0);
  68. fact = gcry_mpi_new (0);
  69. for (i = 0; i < TEST_ITER; i++)
  70. {
  71. fprintf (stderr, ".");
  72. x = GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_WEAK,
  73. MAX_FACT);
  74. if (0 == GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_WEAK,
  75. 2))
  76. {
  77. gcry_mpi_set_ui (fact, x);
  78. gcry_mpi_sub (fact, n, fact);
  79. x = -x;
  80. }
  81. else
  82. {
  83. gcry_mpi_set_ui (fact, x);
  84. }
  85. gcry_mpi_ec_mul (q, fact, g, ctx);
  86. if (x !=
  87. (iret = GNUNET_CRYPTO_ecc_dlog (edc,
  88. q)))
  89. {
  90. fprintf (stderr,
  91. "DLOG failed for value %d (%d)\n",
  92. x,
  93. iret);
  94. GNUNET_assert (0);
  95. }
  96. }
  97. gcry_mpi_release (fact);
  98. gcry_mpi_release (n);
  99. gcry_mpi_point_release (g);
  100. gcry_mpi_point_release (q);
  101. gcry_ctx_release (ctx);
  102. fprintf (stderr, "\n");
  103. }
  104. /**
  105. * Do some arithmetic operations for testing.
  106. *
  107. * @param edc context for ECC operations
  108. */
  109. static void
  110. test_math (struct GNUNET_CRYPTO_EccDlogContext *edc)
  111. {
  112. int i;
  113. int j;
  114. gcry_mpi_point_t ip;
  115. gcry_mpi_point_t jp;
  116. gcry_mpi_point_t r;
  117. gcry_mpi_point_t ir;
  118. gcry_mpi_point_t irj;
  119. gcry_mpi_point_t r_inv;
  120. gcry_mpi_point_t sum;
  121. for (i = -MATH_MAX; i < MATH_MAX; i++)
  122. {
  123. ip = GNUNET_CRYPTO_ecc_dexp (edc, i);
  124. for (j = -MATH_MAX; j < MATH_MAX; j++)
  125. {
  126. fprintf (stderr, ".");
  127. jp = GNUNET_CRYPTO_ecc_dexp (edc, j);
  128. GNUNET_CRYPTO_ecc_rnd (edc,
  129. &r,
  130. &r_inv);
  131. ir = GNUNET_CRYPTO_ecc_add (edc, ip, r);
  132. irj = GNUNET_CRYPTO_ecc_add (edc, ir, jp);
  133. sum = GNUNET_CRYPTO_ecc_add (edc, irj, r_inv);
  134. GNUNET_assert (i + j ==
  135. GNUNET_CRYPTO_ecc_dlog (edc,
  136. sum));
  137. GNUNET_CRYPTO_ecc_free (jp);
  138. GNUNET_CRYPTO_ecc_free (ir);
  139. GNUNET_CRYPTO_ecc_free (irj);
  140. GNUNET_CRYPTO_ecc_free (r);
  141. GNUNET_CRYPTO_ecc_free (r_inv);
  142. GNUNET_CRYPTO_ecc_free (sum);
  143. }
  144. GNUNET_CRYPTO_ecc_free (ip);
  145. }
  146. fprintf (stderr, "\n");
  147. }
  148. int
  149. main (int argc, char *argv[])
  150. {
  151. struct GNUNET_CRYPTO_EccDlogContext *edc;
  152. if (! gcry_check_version ("1.6.0"))
  153. {
  154. fprintf (stderr,
  155. _
  156. (
  157. "libgcrypt has not the expected version (version %s is required).\n"),
  158. "1.6.0");
  159. return 0;
  160. }
  161. if (getenv ("GNUNET_GCRYPT_DEBUG"))
  162. gcry_control (GCRYCTL_SET_DEBUG_FLAGS, 1u, 0);
  163. GNUNET_log_setup ("test-crypto-ecc-dlog",
  164. "WARNING",
  165. NULL);
  166. edc = GNUNET_CRYPTO_ecc_dlog_prepare (MAX_FACT,
  167. MAX_MEM);
  168. test_dlog (edc);
  169. test_math (edc);
  170. GNUNET_CRYPTO_ecc_dlog_release (edc);
  171. return 0;
  172. }
  173. /* end of test_crypto_ecc_dlog.c */