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