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