test_ecc_scalarproduct.c 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175
  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_ecc_scalarproduct.c
  18. * @brief testcase for math behind ECC SP calculation
  19. * @author Christian Grothoff
  20. */
  21. #include "platform.h"
  22. #include "gnunet_util_lib.h"
  23. #include <gcrypt.h>
  24. /**
  25. * Global context.
  26. */
  27. static struct GNUNET_CRYPTO_EccDlogContext *edc;
  28. /**
  29. * Perform SP calculation.
  30. *
  31. * @param avec 0-terminated vector of Alice's values
  32. * @param bvec 0-terminated vector of Bob's values
  33. * @return avec * bvec
  34. */
  35. static int
  36. test_sp (const unsigned int *avec,
  37. const unsigned int *bvec)
  38. {
  39. unsigned int len;
  40. unsigned int i;
  41. gcry_mpi_t a;
  42. gcry_mpi_t a_inv;
  43. gcry_mpi_t ri;
  44. gcry_mpi_t val;
  45. gcry_mpi_t ria;
  46. gcry_mpi_t tmp;
  47. gcry_mpi_point_t *g;
  48. gcry_mpi_point_t *h;
  49. gcry_mpi_point_t pg;
  50. gcry_mpi_point_t ph;
  51. gcry_mpi_point_t pgi;
  52. gcry_mpi_point_t gsp;
  53. int sp;
  54. /* determine length */
  55. for (len=0;0 != avec[len];len++) ;
  56. if (0 == len)
  57. return 0;
  58. /* Alice */
  59. GNUNET_CRYPTO_ecc_rnd_mpi (edc,
  60. &a, &a_inv);
  61. g = GNUNET_new_array (len,
  62. gcry_mpi_point_t);
  63. h = GNUNET_new_array (len,
  64. gcry_mpi_point_t);
  65. ria = gcry_mpi_new (0);
  66. tmp = gcry_mpi_new (0);
  67. for (i=0;i<len;i++)
  68. {
  69. ri = GNUNET_CRYPTO_ecc_random_mod_n (edc);
  70. g[i] = GNUNET_CRYPTO_ecc_dexp_mpi (edc,
  71. ri);
  72. /* ria = ri * a */
  73. gcry_mpi_mul (ria,
  74. ri,
  75. a);
  76. /* tmp = ria + avec[i] */
  77. gcry_mpi_add_ui (tmp,
  78. ria,
  79. avec[i]);
  80. h[i] = GNUNET_CRYPTO_ecc_dexp_mpi (edc,
  81. tmp);
  82. }
  83. gcry_mpi_release (ria);
  84. gcry_mpi_release (tmp);
  85. /* Bob */
  86. val = gcry_mpi_new (0);
  87. gcry_mpi_set_ui (val, bvec[0]);
  88. pg = GNUNET_CRYPTO_ecc_pmul_mpi (edc,
  89. g[0],
  90. val);
  91. ph = GNUNET_CRYPTO_ecc_pmul_mpi (edc,
  92. h[0],
  93. val);
  94. for (i=1;i<len;i++)
  95. {
  96. gcry_mpi_point_t m;
  97. gcry_mpi_point_t tmp;
  98. gcry_mpi_set_ui (val, bvec[i]);
  99. m = GNUNET_CRYPTO_ecc_pmul_mpi (edc,
  100. g[i],
  101. val);
  102. tmp = GNUNET_CRYPTO_ecc_add (edc,
  103. m,
  104. pg);
  105. gcry_mpi_point_release (m);
  106. gcry_mpi_point_release (pg);
  107. gcry_mpi_point_release (g[i]);
  108. pg = tmp;
  109. m = GNUNET_CRYPTO_ecc_pmul_mpi (edc,
  110. h[i],
  111. val);
  112. tmp = GNUNET_CRYPTO_ecc_add (edc,
  113. m,
  114. ph);
  115. gcry_mpi_point_release (m);
  116. gcry_mpi_point_release (ph);
  117. gcry_mpi_point_release (h[i]);
  118. ph = tmp;
  119. }
  120. gcry_mpi_release (val);
  121. GNUNET_free (g);
  122. GNUNET_free (h);
  123. /* Alice */
  124. pgi = GNUNET_CRYPTO_ecc_pmul_mpi (edc,
  125. pg,
  126. a_inv);
  127. gsp = GNUNET_CRYPTO_ecc_add (edc,
  128. pgi,
  129. ph);
  130. gcry_mpi_point_release (pgi);
  131. gcry_mpi_point_release (ph);
  132. sp = GNUNET_CRYPTO_ecc_dlog (edc,
  133. gsp);
  134. gcry_mpi_point_release (gsp);
  135. return sp;
  136. }
  137. int
  138. main (int argc, char *argv[])
  139. {
  140. static unsigned int v11[] = { 1, 1, 0 };
  141. static unsigned int v22[] = { 2, 2, 0 };
  142. static unsigned int v35[] = { 3, 5, 0 };
  143. static unsigned int v24[] = { 2, 4, 0 };
  144. GNUNET_log_setup ("test-ecc-scalarproduct",
  145. "WARNING",
  146. NULL);
  147. edc = GNUNET_CRYPTO_ecc_dlog_prepare (128, 128);
  148. GNUNET_assert ( 2 == test_sp (v11, v11));
  149. GNUNET_assert ( 4 == test_sp (v22, v11));
  150. GNUNET_assert ( 8 == test_sp (v35, v11));
  151. GNUNET_assert (26 == test_sp (v35, v24));
  152. GNUNET_assert (26 == test_sp (v24, v35));
  153. GNUNET_assert (16 == test_sp (v22, v35));
  154. GNUNET_CRYPTO_ecc_dlog_release (edc);
  155. return 0;
  156. }
  157. /* end of test_ecc_scalarproduct.c */