diff options
author | Christian Grothoff <christian@grothoff.org> | 2015-07-06 14:22:51 +0000 |
---|---|---|
committer | Christian Grothoff <christian@grothoff.org> | 2015-07-06 14:22:51 +0000 |
commit | 0f9e6bcd1e511abae16ecc4c86056b0c26d73936 (patch) | |
tree | 4ba3af76391ee6c67563316de29b6ad8830cd7f2 /src/util | |
parent | f1e619572751f7652db025f66f119d6a0308114b (diff) | |
download | gnunet-0f9e6bcd1e511abae16ecc4c86056b0c26d73936.tar.gz gnunet-0f9e6bcd1e511abae16ecc4c86056b0c26d73936.zip |
-fix non-deterministic peerstore sync failure
Diffstat (limited to 'src/util')
-rw-r--r-- | src/util/crypto_ecc_dlog.c | 231 | ||||
-rw-r--r-- | src/util/crypto_paillier.c | 2 | ||||
-rw-r--r-- | src/util/gnunet-ecc.c | 13 | ||||
-rw-r--r-- | src/util/resolver_api.c | 5 | ||||
-rw-r--r-- | src/util/test_crypto_ecc_dlog.c | 102 |
5 files changed, 323 insertions, 30 deletions
diff --git a/src/util/crypto_ecc_dlog.c b/src/util/crypto_ecc_dlog.c index 34f3c203d..3a2a91532 100644 --- a/src/util/crypto_ecc_dlog.c +++ b/src/util/crypto_ecc_dlog.c | |||
@@ -20,11 +20,10 @@ | |||
20 | 20 | ||
21 | /** | 21 | /** |
22 | * @file util/crypto_ecc_dlog.c | 22 | * @file util/crypto_ecc_dlog.c |
23 | * @brief ECC discreate logarithm for small values | 23 | * @brief ECC addition and discreate logarithm for small values. |
24 | * Allows us to use ECC for computations as long as the | ||
25 | * result is relativey small. | ||
24 | * @author Christian Grothoff | 26 | * @author Christian Grothoff |
25 | * | ||
26 | * TODO: | ||
27 | * - support negative factors | ||
28 | */ | 27 | */ |
29 | #include "platform.h" | 28 | #include "platform.h" |
30 | #include <gcrypt.h> | 29 | #include <gcrypt.h> |
@@ -66,9 +65,27 @@ extract_pk (gcry_mpi_point_t pt, | |||
66 | */ | 65 | */ |
67 | struct GNUNET_CRYPTO_EccDlogContext | 66 | struct GNUNET_CRYPTO_EccDlogContext |
68 | { | 67 | { |
68 | /** | ||
69 | * Maximum absolute value the calculation supports. | ||
70 | */ | ||
69 | unsigned int max; | 71 | unsigned int max; |
72 | |||
73 | /** | ||
74 | * How much memory should we use (relates to the number of entries in the map). | ||
75 | */ | ||
70 | unsigned int mem; | 76 | unsigned int mem; |
77 | |||
78 | /** | ||
79 | * Map mapping points (here "interpreted" as EdDSA public keys) to | ||
80 | * a "void * = long" which corresponds to the numeric value of the | ||
81 | * point. As NULL is used to represent "unknown", the actual value | ||
82 | * represented by the entry in the map is the "long" minus @e max. | ||
83 | */ | ||
71 | struct GNUNET_CONTAINER_MultiPeerMap *map; | 84 | struct GNUNET_CONTAINER_MultiPeerMap *map; |
85 | |||
86 | /** | ||
87 | * Context to use for operations on the elliptic curve. | ||
88 | */ | ||
72 | gcry_ctx_t ctx; | 89 | gcry_ctx_t ctx; |
73 | 90 | ||
74 | }; | 91 | }; |
@@ -91,8 +108,10 @@ GNUNET_CRYPTO_ecc_dlog_prepare (unsigned int max, | |||
91 | struct GNUNET_PeerIdentity key; | 108 | struct GNUNET_PeerIdentity key; |
92 | gcry_mpi_point_t gKi; | 109 | gcry_mpi_point_t gKi; |
93 | gcry_mpi_t fact; | 110 | gcry_mpi_t fact; |
111 | gcry_mpi_t n; | ||
94 | unsigned int i; | 112 | unsigned int i; |
95 | 113 | ||
114 | GNUNET_assert (max < INT32_MAX); | ||
96 | edc = GNUNET_new (struct GNUNET_CRYPTO_EccDlogContext); | 115 | edc = GNUNET_new (struct GNUNET_CRYPTO_EccDlogContext); |
97 | edc->max = max; | 116 | edc->max = max; |
98 | edc->mem = mem; | 117 | edc->mem = mem; |
@@ -115,10 +134,25 @@ GNUNET_CRYPTO_ecc_dlog_prepare (unsigned int max, | |||
115 | GNUNET_assert (GNUNET_OK == | 134 | GNUNET_assert (GNUNET_OK == |
116 | GNUNET_CONTAINER_multipeermap_put (edc->map, | 135 | GNUNET_CONTAINER_multipeermap_put (edc->map, |
117 | &key, | 136 | &key, |
118 | (void*) (long) i + 1, | 137 | (void*) (long) i + max, |
138 | GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY)); | ||
139 | } | ||
140 | /* negative values */ | ||
141 | n = gcry_mpi_ec_get_mpi ("n", edc->ctx, 1); | ||
142 | for (i=1;i<mem;i++) | ||
143 | { | ||
144 | gcry_mpi_set_ui (fact, i * K); | ||
145 | gcry_mpi_sub (fact, n, fact); | ||
146 | gcry_mpi_ec_mul (gKi, fact, g, edc->ctx); | ||
147 | extract_pk (gKi, edc->ctx, &key); | ||
148 | GNUNET_assert (GNUNET_OK == | ||
149 | GNUNET_CONTAINER_multipeermap_put (edc->map, | ||
150 | &key, | ||
151 | (void*) (long) max - i, | ||
119 | GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY)); | 152 | GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY)); |
120 | } | 153 | } |
121 | gcry_mpi_release (fact); | 154 | gcry_mpi_release (fact); |
155 | gcry_mpi_release (n); | ||
122 | gcry_mpi_point_release (gKi); | 156 | gcry_mpi_point_release (gKi); |
123 | gcry_mpi_point_release (g); | 157 | gcry_mpi_point_release (g); |
124 | return edc; | 158 | return edc; |
@@ -132,7 +166,7 @@ GNUNET_CRYPTO_ecc_dlog_prepare (unsigned int max, | |||
132 | * @param input point on the curve to factor | 166 | * @param input point on the curve to factor |
133 | * @return `edc->max` if dlog failed, otherwise the factor | 167 | * @return `edc->max` if dlog failed, otherwise the factor |
134 | */ | 168 | */ |
135 | unsigned int | 169 | int |
136 | GNUNET_CRYPTO_ecc_dlog (struct GNUNET_CRYPTO_EccDlogContext *edc, | 170 | GNUNET_CRYPTO_ecc_dlog (struct GNUNET_CRYPTO_EccDlogContext *edc, |
137 | gcry_mpi_point_t input) | 171 | gcry_mpi_point_t input) |
138 | { | 172 | { |
@@ -141,7 +175,7 @@ GNUNET_CRYPTO_ecc_dlog (struct GNUNET_CRYPTO_EccDlogContext *edc, | |||
141 | struct GNUNET_PeerIdentity key; | 175 | struct GNUNET_PeerIdentity key; |
142 | gcry_mpi_point_t q; | 176 | gcry_mpi_point_t q; |
143 | unsigned int i; | 177 | unsigned int i; |
144 | unsigned int res; | 178 | int res; |
145 | void *retp; | 179 | void *retp; |
146 | 180 | ||
147 | g = gcry_mpi_ec_get_point ("g", edc->ctx, 0); | 181 | g = gcry_mpi_ec_get_point ("g", edc->ctx, 0); |
@@ -159,10 +193,10 @@ GNUNET_CRYPTO_ecc_dlog (struct GNUNET_CRYPTO_EccDlogContext *edc, | |||
159 | &key); | 193 | &key); |
160 | if (NULL != retp) | 194 | if (NULL != retp) |
161 | { | 195 | { |
162 | res = (((long) retp) - 1) * K - i; | 196 | res = (((long) retp) - edc->max) * K - i; |
163 | fprintf (stderr, | 197 | /* we continue the loop here to make the implementation |
164 | "Got DLOG %u\n", | 198 | "constant-time". If we do not care about this, we could just |
165 | res); | 199 | 'break' here and do fewer operations... */ |
166 | } | 200 | } |
167 | if (i == edc->max/edc->mem) | 201 | if (i == edc->max/edc->mem) |
168 | break; | 202 | break; |
@@ -180,6 +214,40 @@ GNUNET_CRYPTO_ecc_dlog (struct GNUNET_CRYPTO_EccDlogContext *edc, | |||
180 | 214 | ||
181 | 215 | ||
182 | /** | 216 | /** |
217 | * Generate a random value mod n. | ||
218 | * | ||
219 | * @param edc ECC context | ||
220 | * @return random value mod n. | ||
221 | */ | ||
222 | gcry_mpi_t | ||
223 | GNUNET_CRYPTO_ecc_random_mod_n (struct GNUNET_CRYPTO_EccDlogContext *edc) | ||
224 | { | ||
225 | gcry_mpi_t n; | ||
226 | unsigned int highbit; | ||
227 | gcry_mpi_t r; | ||
228 | |||
229 | n = gcry_mpi_ec_get_mpi ("n", edc->ctx, 1); | ||
230 | |||
231 | /* check public key for number of bits, bail out if key is all zeros */ | ||
232 | highbit = 256; /* Curve25519 */ | ||
233 | while ( (! gcry_mpi_test_bit (n, highbit)) && | ||
234 | (0 != highbit) ) | ||
235 | highbit--; | ||
236 | GNUNET_assert (0 != highbit); | ||
237 | /* generate fact < n (without bias) */ | ||
238 | GNUNET_assert (NULL != (r = gcry_mpi_new (0))); | ||
239 | do { | ||
240 | gcry_mpi_randomize (r, | ||
241 | highbit + 1, | ||
242 | GCRY_STRONG_RANDOM); | ||
243 | } | ||
244 | while (gcry_mpi_cmp (r, n) >= 0); | ||
245 | gcry_mpi_release (n); | ||
246 | return r; | ||
247 | } | ||
248 | |||
249 | |||
250 | /** | ||
183 | * Release precalculated values. | 251 | * Release precalculated values. |
184 | * | 252 | * |
185 | * @param edc dlog context | 253 | * @param edc dlog context |
@@ -191,6 +259,147 @@ GNUNET_CRYPTO_ecc_dlog_release (struct GNUNET_CRYPTO_EccDlogContext *edc) | |||
191 | GNUNET_CONTAINER_multipeermap_destroy (edc->map); | 259 | GNUNET_CONTAINER_multipeermap_destroy (edc->map); |
192 | GNUNET_free (edc); | 260 | GNUNET_free (edc); |
193 | } | 261 | } |
262 | |||
263 | |||
264 | /** | ||
265 | * Multiply the generator g of the elliptic curve by @a val | ||
266 | * to obtain the point on the curve representing @a val. | ||
267 | * Afterwards, point addition will correspond to integer | ||
268 | * addition. #GNUNET_CRYPTO_ecc_dlog() can be used to | ||
269 | * convert a point back to an integer (as long as the | ||
270 | * integer is smaller than the MAX of the @a edc context). | ||
271 | * | ||
272 | * @param edc calculation context for ECC operations | ||
273 | * @param val value to encode into a point | ||
274 | * @return representation of the value as an ECC point, | ||
275 | * must be freed using #GNUNET_CRYPTO_ecc_free() | ||
276 | */ | ||
277 | gcry_mpi_point_t | ||
278 | GNUNET_CRYPTO_ecc_dexp (struct GNUNET_CRYPTO_EccDlogContext *edc, | ||
279 | int val) | ||
280 | { | ||
281 | gcry_mpi_t fact; | ||
282 | gcry_mpi_t n; | ||
283 | gcry_mpi_point_t g; | ||
284 | gcry_mpi_point_t r; | ||
285 | |||
286 | g = gcry_mpi_ec_get_point ("g", edc->ctx, 0); | ||
287 | GNUNET_assert (NULL != g); | ||
288 | fact = gcry_mpi_new (0); | ||
289 | if (val < 0) | ||
290 | { | ||
291 | n = gcry_mpi_ec_get_mpi ("n", edc->ctx, 1); | ||
292 | gcry_mpi_set_ui (fact, - val); | ||
293 | gcry_mpi_sub (fact, n, fact); | ||
294 | gcry_mpi_release (n); | ||
295 | } | ||
296 | else | ||
297 | { | ||
298 | gcry_mpi_set_ui (fact, val); | ||
299 | } | ||
300 | r = gcry_mpi_point_new (0); | ||
301 | gcry_mpi_ec_mul (r, fact, g, edc->ctx); | ||
302 | gcry_mpi_release (fact); | ||
303 | gcry_mpi_point_release (g); | ||
304 | return r; | ||
305 | } | ||
306 | |||
307 | |||
308 | /** | ||
309 | * Multiply the generator g of the elliptic curve by @a val | ||
310 | * to obtain the point on the curve representing @a val. | ||
311 | * | ||
312 | * @param edc calculation context for ECC operations | ||
313 | * @param val (positive) value to encode into a point | ||
314 | * @return representation of the value as an ECC point, | ||
315 | * must be freed using #GNUNET_CRYPTO_ecc_free() | ||
316 | */ | ||
317 | gcry_mpi_point_t | ||
318 | GNUNET_CRYPTO_ecc_dexp_mpi (struct GNUNET_CRYPTO_EccDlogContext *edc, | ||
319 | gcry_mpi_t val) | ||
320 | { | ||
321 | gcry_mpi_point_t g; | ||
322 | gcry_mpi_point_t r; | ||
323 | |||
324 | g = gcry_mpi_ec_get_point ("g", edc->ctx, 0); | ||
325 | GNUNET_assert (NULL != g); | ||
326 | r = gcry_mpi_point_new (0); | ||
327 | gcry_mpi_ec_mul (r, val, g, edc->ctx); | ||
328 | gcry_mpi_point_release (g); | ||
329 | return r; | ||
330 | } | ||
331 | |||
332 | |||
333 | /** | ||
334 | * Add two points on the elliptic curve. | ||
335 | * | ||
336 | * @param edc calculation context for ECC operations | ||
337 | * @param a some value | ||
338 | * @param b some value | ||
339 | * @return @a a + @a b, must be freed using #GNUNET_CRYPTO_ecc_free() | ||
340 | */ | ||
341 | gcry_mpi_point_t | ||
342 | GNUNET_CRYPTO_ecc_add (struct GNUNET_CRYPTO_EccDlogContext *edc, | ||
343 | gcry_mpi_point_t a, | ||
344 | gcry_mpi_point_t b) | ||
345 | { | ||
346 | gcry_mpi_point_t r; | ||
194 | 347 | ||
348 | r = gcry_mpi_point_new (0); | ||
349 | gcry_mpi_ec_add (r, a, b, edc->ctx); | ||
350 | return r; | ||
351 | } | ||
352 | |||
353 | |||
354 | /** | ||
355 | * Obtain a random point on the curve and its | ||
356 | * additive inverse. Both returned values | ||
357 | * must be freed using #GNUNET_CRYPTO_ecc_free(). | ||
358 | * | ||
359 | * @param edc calculation context for ECC operations | ||
360 | * @param[out] r set to a random point on the curve | ||
361 | * @param[out] r_inv set to the additive inverse of @a r | ||
362 | */ | ||
363 | void | ||
364 | GNUNET_CRYPTO_ecc_rnd (struct GNUNET_CRYPTO_EccDlogContext *edc, | ||
365 | gcry_mpi_point_t *r, | ||
366 | gcry_mpi_point_t *r_inv) | ||
367 | { | ||
368 | gcry_mpi_t fact; | ||
369 | gcry_mpi_t n; | ||
370 | gcry_mpi_point_t g; | ||
371 | |||
372 | fact = GNUNET_CRYPTO_ecc_random_mod_n (edc); | ||
373 | |||
374 | /* calculate 'r' */ | ||
375 | g = gcry_mpi_ec_get_point ("g", edc->ctx, 0); | ||
376 | GNUNET_assert (NULL != g); | ||
377 | *r = gcry_mpi_point_new (0); | ||
378 | gcry_mpi_ec_mul (*r, fact, g, edc->ctx); | ||
379 | |||
380 | /* calculate 'r_inv' */ | ||
381 | n = gcry_mpi_ec_get_mpi ("n", edc->ctx, 1); | ||
382 | gcry_mpi_sub (fact, n, fact); /* fact = n - fact = - fact */ | ||
383 | *r_inv = gcry_mpi_point_new (0); | ||
384 | gcry_mpi_ec_mul (*r_inv, fact, g, edc->ctx); | ||
385 | |||
386 | gcry_mpi_release (n); | ||
387 | gcry_mpi_release (fact); | ||
388 | gcry_mpi_point_release (g); | ||
389 | } | ||
390 | |||
391 | |||
392 | /** | ||
393 | * Free a point value returned by the API. | ||
394 | * | ||
395 | * @param p point to free | ||
396 | */ | ||
397 | void | ||
398 | GNUNET_CRYPTO_ecc_free (gcry_mpi_point_t p) | ||
399 | { | ||
400 | gcry_mpi_point_release (p); | ||
401 | } | ||
402 | |||
403 | |||
195 | /* end of crypto_ecc_dlog.c */ | 404 | /* end of crypto_ecc_dlog.c */ |
196 | 405 | ||
diff --git a/src/util/crypto_paillier.c b/src/util/crypto_paillier.c index 8d5245d3e..e348be80a 100644 --- a/src/util/crypto_paillier.c +++ b/src/util/crypto_paillier.c | |||
@@ -269,7 +269,7 @@ GNUNET_CRYPTO_paillier_encrypt (const struct GNUNET_CRYPTO_PaillierPublicKey *pu | |||
269 | } | 269 | } |
270 | 270 | ||
271 | /* generate r < n (without bias) */ | 271 | /* generate r < n (without bias) */ |
272 | GNUNET_assert (0 != (r = gcry_mpi_new (0))); | 272 | GNUNET_assert (NULL != (r = gcry_mpi_new (0))); |
273 | do { | 273 | do { |
274 | gcry_mpi_randomize (r, highbit + 1, GCRY_STRONG_RANDOM); | 274 | gcry_mpi_randomize (r, highbit + 1, GCRY_STRONG_RANDOM); |
275 | } | 275 | } |
diff --git a/src/util/gnunet-ecc.c b/src/util/gnunet-ecc.c index 5585ae85c..081cd0525 100644 --- a/src/util/gnunet-ecc.c +++ b/src/util/gnunet-ecc.c | |||
@@ -28,6 +28,9 @@ | |||
28 | #include "gnunet_testing_lib.h" | 28 | #include "gnunet_testing_lib.h" |
29 | #include <gcrypt.h> | 29 | #include <gcrypt.h> |
30 | 30 | ||
31 | /** | ||
32 | * Number of characters a Base32-encoded public key requires. | ||
33 | */ | ||
31 | #define KEY_STR_LEN sizeof(struct GNUNET_CRYPTO_EddsaPublicKey)*8/5+1 | 34 | #define KEY_STR_LEN sizeof(struct GNUNET_CRYPTO_EddsaPublicKey)*8/5+1 |
32 | 35 | ||
33 | /** | 36 | /** |
@@ -69,9 +72,9 @@ create_keys (const char *fn, const char *prefix) | |||
69 | struct GNUNET_CRYPTO_EddsaPrivateKey *pk; | 72 | struct GNUNET_CRYPTO_EddsaPrivateKey *pk; |
70 | struct GNUNET_CRYPTO_EddsaPublicKey target_pub; | 73 | struct GNUNET_CRYPTO_EddsaPublicKey target_pub; |
71 | static char vanity[KEY_STR_LEN + 1]; | 74 | static char vanity[KEY_STR_LEN + 1]; |
72 | int len; | 75 | size_t len; |
73 | int n; | 76 | size_t n; |
74 | int rest; | 77 | size_t rest; |
75 | unsigned char mask; | 78 | unsigned char mask; |
76 | unsigned target_byte; | 79 | unsigned target_byte; |
77 | char *s; | 80 | char *s; |
@@ -119,9 +122,9 @@ create_keys (const char *fn, const char *prefix) | |||
119 | s); | 122 | s); |
120 | GNUNET_free (s); | 123 | GNUNET_free (s); |
121 | fprintf (stderr, | 124 | fprintf (stderr, |
122 | "\nattempt %s [%d, %X]\n", | 125 | "\nattempt %s [%u, %X]\n", |
123 | vanity, | 126 | vanity, |
124 | n, | 127 | (unsigned int) n, |
125 | mask); | 128 | mask); |
126 | } | 129 | } |
127 | else | 130 | else |
diff --git a/src/util/resolver_api.c b/src/util/resolver_api.c index 7d7c74ad6..8d2986c7b 100644 --- a/src/util/resolver_api.c +++ b/src/util/resolver_api.c | |||
@@ -1028,7 +1028,10 @@ GNUNET_RESOLVER_local_fqdn_get () | |||
1028 | gai_strerror (ret)); | 1028 | gai_strerror (ret)); |
1029 | return NULL; | 1029 | return NULL; |
1030 | } | 1030 | } |
1031 | rval = GNUNET_strdup (ai->ai_canonname); | 1031 | if (NULL != ai->ai_canonname) |
1032 | rval = GNUNET_strdup (ai->ai_canonname); | ||
1033 | else | ||
1034 | rval = GNUNET_strdup (hostname); | ||
1032 | freeaddrinfo (ai); | 1035 | freeaddrinfo (ai); |
1033 | return rval; | 1036 | return rval; |
1034 | } | 1037 | } |
diff --git a/src/util/test_crypto_ecc_dlog.c b/src/util/test_crypto_ecc_dlog.c index a594e5795..2101b28f1 100644 --- a/src/util/test_crypto_ecc_dlog.c +++ b/src/util/test_crypto_ecc_dlog.c | |||
@@ -22,9 +22,6 @@ | |||
22 | * @file util/test_crypto_ecc_dlog.c | 22 | * @file util/test_crypto_ecc_dlog.c |
23 | * @brief testcase for ECC DLOG calculation | 23 | * @brief testcase for ECC DLOG calculation |
24 | * @author Christian Grothoff | 24 | * @author Christian Grothoff |
25 | * | ||
26 | * TODO: | ||
27 | * - test negative numbers | ||
28 | */ | 25 | */ |
29 | #include "platform.h" | 26 | #include "platform.h" |
30 | #include "gnunet_util_lib.h" | 27 | #include "gnunet_util_lib.h" |
@@ -42,52 +39,132 @@ | |||
42 | /** | 39 | /** |
43 | * Maximum value we test dlog for. | 40 | * Maximum value we test dlog for. |
44 | */ | 41 | */ |
45 | #define MAX_FACT 1000000 | 42 | #define MAX_FACT 100 |
46 | 43 | ||
47 | /** | 44 | /** |
48 | * Maximum memory to use, sqrt(MAX_FACT) is a good choice. | 45 | * Maximum memory to use, sqrt(MAX_FACT) is a good choice. |
49 | */ | 46 | */ |
50 | #define MAX_MEM 1000 | 47 | #define MAX_MEM 10 |
48 | |||
49 | /** | ||
50 | * How many values do we test? | ||
51 | */ | ||
52 | #define TEST_ITER 10 | ||
51 | 53 | ||
54 | /** | ||
55 | * Range of values to use for MATH tests. | ||
56 | */ | ||
57 | #define MATH_MAX 5 | ||
52 | 58 | ||
59 | |||
60 | /** | ||
61 | * Do some DLOG operations for testing. | ||
62 | * | ||
63 | * @param edc context for ECC operations | ||
64 | */ | ||
53 | static void | 65 | static void |
54 | test_dlog (struct GNUNET_CRYPTO_EccDlogContext *edc) | 66 | test_dlog (struct GNUNET_CRYPTO_EccDlogContext *edc) |
55 | { | 67 | { |
56 | gcry_mpi_t fact; | 68 | gcry_mpi_t fact; |
69 | gcry_mpi_t n; | ||
57 | gcry_ctx_t ctx; | 70 | gcry_ctx_t ctx; |
58 | gcry_mpi_point_t q; | 71 | gcry_mpi_point_t q; |
59 | gcry_mpi_point_t g; | 72 | gcry_mpi_point_t g; |
60 | unsigned int i; | 73 | unsigned int i; |
61 | unsigned int x; | 74 | int x; |
75 | int iret; | ||
62 | 76 | ||
63 | GNUNET_assert (0 == gcry_mpi_ec_new (&ctx, NULL, CURVE)); | 77 | GNUNET_assert (0 == gcry_mpi_ec_new (&ctx, NULL, CURVE)); |
64 | g = gcry_mpi_ec_get_point ("g", ctx, 0); | 78 | g = gcry_mpi_ec_get_point ("g", ctx, 0); |
65 | GNUNET_assert (NULL != g); | 79 | GNUNET_assert (NULL != g); |
80 | n = gcry_mpi_ec_get_mpi ("n", ctx, 0); | ||
66 | q = gcry_mpi_point_new (0); | 81 | q = gcry_mpi_point_new (0); |
67 | fact = gcry_mpi_new (0); | 82 | fact = gcry_mpi_new (0); |
68 | for (i=0;i<10;i++) | 83 | for (i=0;i<TEST_ITER;i++) |
69 | { | 84 | { |
85 | fprintf (stderr, "."); | ||
70 | x = GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_WEAK, | 86 | x = GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_WEAK, |
71 | MAX_FACT); | 87 | MAX_FACT); |
72 | gcry_mpi_set_ui (fact, x); | 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 | } | ||
73 | gcry_mpi_ec_mul (q, fact, g, ctx); | 99 | gcry_mpi_ec_mul (q, fact, g, ctx); |
74 | if (x != | 100 | if (x != |
75 | GNUNET_CRYPTO_ecc_dlog (edc, | 101 | (iret = GNUNET_CRYPTO_ecc_dlog (edc, |
76 | q)) | 102 | q))) |
77 | { | 103 | { |
78 | fprintf (stderr, | 104 | fprintf (stderr, |
79 | "DLOG failed for value %u\n", | 105 | "DLOG failed for value %d (%d)\n", |
80 | x); | 106 | x, |
107 | iret); | ||
81 | GNUNET_assert (0); | 108 | GNUNET_assert (0); |
82 | } | 109 | } |
83 | } | 110 | } |
84 | gcry_mpi_release (fact); | 111 | gcry_mpi_release (fact); |
112 | gcry_mpi_release (n); | ||
85 | gcry_mpi_point_release (g); | 113 | gcry_mpi_point_release (g); |
86 | gcry_mpi_point_release (q); | 114 | gcry_mpi_point_release (q); |
87 | gcry_ctx_release (ctx); | 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"); | ||
88 | } | 164 | } |
89 | 165 | ||
90 | 166 | ||
167 | |||
91 | int | 168 | int |
92 | main (int argc, char *argv[]) | 169 | main (int argc, char *argv[]) |
93 | { | 170 | { |
@@ -109,6 +186,7 @@ main (int argc, char *argv[]) | |||
109 | edc = GNUNET_CRYPTO_ecc_dlog_prepare (MAX_FACT, | 186 | edc = GNUNET_CRYPTO_ecc_dlog_prepare (MAX_FACT, |
110 | MAX_MEM); | 187 | MAX_MEM); |
111 | test_dlog (edc); | 188 | test_dlog (edc); |
189 | test_math (edc); | ||
112 | GNUNET_CRYPTO_ecc_dlog_release (edc); | 190 | GNUNET_CRYPTO_ecc_dlog_release (edc); |
113 | return 0; | 191 | return 0; |
114 | } | 192 | } |