diff options
-rw-r--r-- | src/include/gnunet_crypto_lib.h | 84 | ||||
-rw-r--r-- | src/peerstore/gnunet-service-peerstore.c | 2 | ||||
-rw-r--r-- | src/peerstore/test_peerstore_api_sync.c | 131 | ||||
-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 |
8 files changed, 518 insertions, 52 deletions
diff --git a/src/include/gnunet_crypto_lib.h b/src/include/gnunet_crypto_lib.h index 3ee8ea5a7..38a3ab3b6 100644 --- a/src/include/gnunet_crypto_lib.h +++ b/src/include/gnunet_crypto_lib.h | |||
@@ -1297,20 +1297,100 @@ GNUNET_CRYPTO_ecc_dlog_prepare (unsigned int max, | |||
1297 | unsigned int mem); | 1297 | unsigned int mem); |
1298 | 1298 | ||
1299 | 1299 | ||
1300 | |||
1301 | /** | 1300 | /** |
1302 | * Calculate ECC discrete logarithm for small factors. | 1301 | * Calculate ECC discrete logarithm for small factors. |
1302 | * Opposite of #GNUNET_CRYPTO_ecc_dexp(). | ||
1303 | * | 1303 | * |
1304 | * @param dlc precalculated values, determine range of factors | 1304 | * @param dlc precalculated values, determine range of factors |
1305 | * @param input point on the curve to factor | 1305 | * @param input point on the curve to factor |
1306 | * @return `dlc->max` if dlog failed, otherwise the factor | 1306 | * @return `dlc->max` if dlog failed, otherwise the factor |
1307 | */ | 1307 | */ |
1308 | unsigned int | 1308 | int |
1309 | GNUNET_CRYPTO_ecc_dlog (struct GNUNET_CRYPTO_EccDlogContext *edc, | 1309 | GNUNET_CRYPTO_ecc_dlog (struct GNUNET_CRYPTO_EccDlogContext *edc, |
1310 | gcry_mpi_point_t input); | 1310 | gcry_mpi_point_t input); |
1311 | 1311 | ||
1312 | 1312 | ||
1313 | /** | 1313 | /** |
1314 | * Multiply the generator g of the elliptic curve by @a val | ||
1315 | * to obtain the point on the curve representing @a val. | ||
1316 | * Afterwards, point addition will correspond to integer | ||
1317 | * addition. #GNUNET_CRYPTO_ecc_dlog() can be used to | ||
1318 | * convert a point back to an integer (as long as the | ||
1319 | * integer is smaller than the MAX of the @a edc context). | ||
1320 | * | ||
1321 | * @param edc calculation context for ECC operations | ||
1322 | * @param val value to encode into a point | ||
1323 | * @return representation of the value as an ECC point, | ||
1324 | * must be freed using #GNUNET_CRYPTO_ecc_free() | ||
1325 | */ | ||
1326 | gcry_mpi_point_t | ||
1327 | GNUNET_CRYPTO_ecc_dexp (struct GNUNET_CRYPTO_EccDlogContext *edc, | ||
1328 | int val); | ||
1329 | |||
1330 | |||
1331 | /** | ||
1332 | * Multiply the generator g of the elliptic curve by @a val | ||
1333 | * to obtain the point on the curve representing @a val. | ||
1334 | * | ||
1335 | * @param edc calculation context for ECC operations | ||
1336 | * @param val (positive) value to encode into a point | ||
1337 | * @return representation of the value as an ECC point, | ||
1338 | * must be freed using #GNUNET_CRYPTO_ecc_free() | ||
1339 | */ | ||
1340 | gcry_mpi_point_t | ||
1341 | GNUNET_CRYPTO_ecc_dexp_mpi (struct GNUNET_CRYPTO_EccDlogContext *edc, | ||
1342 | gcry_mpi_t val); | ||
1343 | |||
1344 | |||
1345 | /** | ||
1346 | * Add two points on the elliptic curve. | ||
1347 | * | ||
1348 | * @param edc calculation context for ECC operations | ||
1349 | * @param a some value | ||
1350 | * @param b some value | ||
1351 | * @return @a a + @a b, must be freed using #GNUNET_CRYPTO_ecc_free() | ||
1352 | */ | ||
1353 | gcry_mpi_point_t | ||
1354 | GNUNET_CRYPTO_ecc_add (struct GNUNET_CRYPTO_EccDlogContext *edc, | ||
1355 | gcry_mpi_point_t a, | ||
1356 | gcry_mpi_point_t b); | ||
1357 | |||
1358 | |||
1359 | /** | ||
1360 | * Obtain a random point on the curve and its | ||
1361 | * additive inverse. Both returned values | ||
1362 | * must be freed using #GNUNET_CRYPTO_ecc_free(). | ||
1363 | * | ||
1364 | * @param edc calculation context for ECC operations | ||
1365 | * @param[out] r set to a random point on the curve | ||
1366 | * @param[out] r_inv set to the additive inverse of @a r | ||
1367 | */ | ||
1368 | void | ||
1369 | GNUNET_CRYPTO_ecc_rnd (struct GNUNET_CRYPTO_EccDlogContext *edc, | ||
1370 | gcry_mpi_point_t *r, | ||
1371 | gcry_mpi_point_t *r_inv); | ||
1372 | |||
1373 | |||
1374 | /** | ||
1375 | * Generate a random value mod n. | ||
1376 | * | ||
1377 | * @param edc ECC context | ||
1378 | * @return random value mod n. | ||
1379 | */ | ||
1380 | gcry_mpi_t | ||
1381 | GNUNET_CRYPTO_ecc_random_mod_n (struct GNUNET_CRYPTO_EccDlogContext *edc); | ||
1382 | |||
1383 | |||
1384 | /** | ||
1385 | * Free a point value returned by the API. | ||
1386 | * | ||
1387 | * @param p point to free | ||
1388 | */ | ||
1389 | void | ||
1390 | GNUNET_CRYPTO_ecc_free (gcry_mpi_point_t p); | ||
1391 | |||
1392 | |||
1393 | /** | ||
1314 | * Release precalculated values. | 1394 | * Release precalculated values. |
1315 | * | 1395 | * |
1316 | * @param dlc dlog context | 1396 | * @param dlc dlog context |
diff --git a/src/peerstore/gnunet-service-peerstore.c b/src/peerstore/gnunet-service-peerstore.c index 99facb0cc..f680c5d14 100644 --- a/src/peerstore/gnunet-service-peerstore.c +++ b/src/peerstore/gnunet-service-peerstore.c | |||
@@ -1,6 +1,6 @@ | |||
1 | /* | 1 | /* |
2 | This file is part of GNUnet. | 2 | This file is part of GNUnet. |
3 | Copyright (C) | 3 | Copyright (C) 2014, 2015 GNUnet e.V. |
4 | 4 | ||
5 | GNUnet is free software; you can redistribute it and/or modify | 5 | GNUnet is free software; you can redistribute it and/or modify |
6 | it under the terms of the GNU General Public License as published | 6 | it under the terms of the GNU General Public License as published |
diff --git a/src/peerstore/test_peerstore_api_sync.c b/src/peerstore/test_peerstore_api_sync.c index 2b2d34374..f53aad544 100644 --- a/src/peerstore/test_peerstore_api_sync.c +++ b/src/peerstore/test_peerstore_api_sync.c | |||
@@ -1,6 +1,6 @@ | |||
1 | /* | 1 | /* |
2 | This file is part of GNUnet. | 2 | This file is part of GNUnet. |
3 | Copyright (C) | 3 | Copyright (C) 2015 GNUnet e.V. |
4 | 4 | ||
5 | GNUnet is free software; you can redistribute it and/or modify | 5 | GNUnet is free software; you can redistribute it and/or modify |
6 | it under the terms of the GNU General Public License as published | 6 | it under the terms of the GNU General Public License as published |
@@ -19,26 +19,69 @@ | |||
19 | */ | 19 | */ |
20 | /** | 20 | /** |
21 | * @file peerstore/test_peerstore_api_sync.c | 21 | * @file peerstore/test_peerstore_api_sync.c |
22 | * @brief testcase for peerstore sync before disconnect feature | 22 | * @brief testcase for peerstore sync-on-disconnect feature. Stores |
23 | * a value just before disconnecting, and then checks that | ||
24 | * this value is actually stored. | ||
25 | * @author Omar Tarabai | ||
26 | * @author Christian Grothoff (minor fix, comments) | ||
23 | */ | 27 | */ |
24 | #include "platform.h" | 28 | #include "platform.h" |
25 | #include "gnunet_util_lib.h" | 29 | #include "gnunet_util_lib.h" |
26 | #include "gnunet_testing_lib.h" | 30 | #include "gnunet_testing_lib.h" |
27 | #include "gnunet_peerstore_service.h" | 31 | #include "gnunet_peerstore_service.h" |
28 | 32 | ||
29 | static int ok = 1; | 33 | /** |
34 | * Overall result, 0 for success. | ||
35 | */ | ||
36 | static int ok = 404; | ||
30 | 37 | ||
38 | /** | ||
39 | * Configuration we use. | ||
40 | */ | ||
31 | static const struct GNUNET_CONFIGURATION_Handle *cfg; | 41 | static const struct GNUNET_CONFIGURATION_Handle *cfg; |
32 | 42 | ||
43 | /** | ||
44 | * handle to talk to the peerstore. | ||
45 | */ | ||
33 | static struct GNUNET_PEERSTORE_Handle *h; | 46 | static struct GNUNET_PEERSTORE_Handle *h; |
34 | 47 | ||
35 | static char *subsystem = "test_peerstore_api_sync"; | 48 | /** |
49 | * Subsystem we store the value for. | ||
50 | */ | ||
51 | static const char *subsystem = "test_peerstore_api_sync"; | ||
52 | |||
53 | /** | ||
54 | * Fake PID under which we store the value. | ||
55 | */ | ||
36 | static struct GNUNET_PeerIdentity pid; | 56 | static struct GNUNET_PeerIdentity pid; |
37 | static char *key = "test_peerstore_api_store_key"; | ||
38 | static char *val = "test_peerstore_api_store_val"; | ||
39 | 57 | ||
58 | /** | ||
59 | * Test key we're storing the test value under. | ||
60 | */ | ||
61 | static const char *key = "test_peerstore_api_store_key"; | ||
62 | |||
63 | /** | ||
64 | * Test value we are storing. | ||
65 | */ | ||
66 | static const char *val = "test_peerstore_api_store_val"; | ||
67 | |||
68 | |||
69 | /** | ||
70 | * Function that should be called with the result of the | ||
71 | * lookup, and finally once with NULL to signal the end | ||
72 | * of the iteration. | ||
73 | * | ||
74 | * Upon the first call, we set "ok" to success. On the | ||
75 | * second call (end of iteration) we terminate the test. | ||
76 | * | ||
77 | * @param cls NULL | ||
78 | * @param record the information stored in the peerstore | ||
79 | * @param emsg any error message | ||
80 | * @return #GNUNET_YES (all good, continue) | ||
81 | */ | ||
40 | static int | 82 | static int |
41 | iterate_cb (void *cls, const struct GNUNET_PEERSTORE_Record *record, | 83 | iterate_cb (void *cls, |
84 | const struct GNUNET_PEERSTORE_Record *record, | ||
42 | const char *emsg) | 85 | const char *emsg) |
43 | { | 86 | { |
44 | const char *rec_val; | 87 | const char *rec_val; |
@@ -46,7 +89,8 @@ iterate_cb (void *cls, const struct GNUNET_PEERSTORE_Record *record, | |||
46 | GNUNET_break (NULL == emsg); | 89 | GNUNET_break (NULL == emsg); |
47 | if (NULL == record) | 90 | if (NULL == record) |
48 | { | 91 | { |
49 | GNUNET_PEERSTORE_disconnect (h, GNUNET_NO); | 92 | GNUNET_PEERSTORE_disconnect (h, |
93 | GNUNET_NO); | ||
50 | GNUNET_SCHEDULER_shutdown (); | 94 | GNUNET_SCHEDULER_shutdown (); |
51 | return GNUNET_YES; | 95 | return GNUNET_YES; |
52 | } | 96 | } |
@@ -57,25 +101,68 @@ iterate_cb (void *cls, const struct GNUNET_PEERSTORE_Record *record, | |||
57 | } | 101 | } |
58 | 102 | ||
59 | 103 | ||
104 | /** | ||
105 | * Run the 2nd stage of the test where we fetch the | ||
106 | * data that should have been stored. | ||
107 | * | ||
108 | * @param cls NULL | ||
109 | * @param tc unused | ||
110 | */ | ||
111 | static void | ||
112 | test_cont (void *cls, | ||
113 | const struct GNUNET_SCHEDULER_TaskContext *tc) | ||
114 | { | ||
115 | h = GNUNET_PEERSTORE_connect (cfg); | ||
116 | GNUNET_PEERSTORE_iterate (h, | ||
117 | subsystem, | ||
118 | &pid, key, | ||
119 | GNUNET_TIME_UNIT_FOREVER_REL, | ||
120 | &iterate_cb, NULL); | ||
121 | } | ||
122 | |||
123 | |||
124 | /** | ||
125 | * Actually run the test. | ||
126 | */ | ||
60 | static void | 127 | static void |
61 | test1 () | 128 | test1 () |
62 | { | 129 | { |
63 | GNUNET_PEERSTORE_store (h, subsystem, &pid, key, val, strlen (val) + 1, | ||
64 | GNUNET_TIME_UNIT_FOREVER_ABS, | ||
65 | GNUNET_PEERSTORE_STOREOPTION_REPLACE, NULL, NULL); | ||
66 | GNUNET_PEERSTORE_disconnect (h, GNUNET_YES); | ||
67 | h = GNUNET_PEERSTORE_connect (cfg); | 130 | h = GNUNET_PEERSTORE_connect (cfg); |
68 | GNUNET_PEERSTORE_iterate (h, subsystem, &pid, key, | 131 | GNUNET_PEERSTORE_store (h, |
69 | GNUNET_TIME_UNIT_FOREVER_REL, &iterate_cb, NULL); | 132 | subsystem, |
133 | &pid, | ||
134 | key, | ||
135 | val, strlen (val) + 1, | ||
136 | GNUNET_TIME_UNIT_FOREVER_ABS, | ||
137 | GNUNET_PEERSTORE_STOREOPTION_REPLACE, | ||
138 | NULL, NULL); | ||
139 | GNUNET_PEERSTORE_disconnect (h, | ||
140 | GNUNET_YES); | ||
141 | h = NULL; | ||
142 | /* We need to wait a little bit to give the disconnect | ||
143 | a chance to actually finish the operation; otherwise, | ||
144 | the test may fail non-deterministically if the new | ||
145 | connection is faster than the cleanup routine of the | ||
146 | old one. */ | ||
147 | GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_SECONDS, | ||
148 | &test_cont, | ||
149 | NULL); | ||
70 | } | 150 | } |
71 | 151 | ||
72 | 152 | ||
153 | /** | ||
154 | * Initialize globals and launch the test. | ||
155 | * | ||
156 | * @param cls NULL | ||
157 | * @param c configuration to use | ||
158 | * @param peer handle to our peer (unused) | ||
159 | */ | ||
73 | static void | 160 | static void |
74 | run (void *cls, const struct GNUNET_CONFIGURATION_Handle *c, | 161 | run (void *cls, |
162 | const struct GNUNET_CONFIGURATION_Handle *c, | ||
75 | struct GNUNET_TESTING_Peer *peer) | 163 | struct GNUNET_TESTING_Peer *peer) |
76 | { | 164 | { |
77 | cfg = c; | 165 | cfg = c; |
78 | h = GNUNET_PEERSTORE_connect (cfg); | ||
79 | GNUNET_assert (NULL != h); | 166 | GNUNET_assert (NULL != h); |
80 | memset (&pid, 1, sizeof (pid)); | 167 | memset (&pid, 1, sizeof (pid)); |
81 | test1 (); | 168 | test1 (); |
@@ -86,10 +173,16 @@ int | |||
86 | main (int argc, char *argv[]) | 173 | main (int argc, char *argv[]) |
87 | { | 174 | { |
88 | if (0 != | 175 | if (0 != |
89 | GNUNET_TESTING_service_run ("test-gnunet-peerstore", "peerstore", | 176 | GNUNET_TESTING_service_run ("test-gnunet-peerstore-sync", |
90 | "test_peerstore_api_data.conf", &run, NULL)) | 177 | "peerstore", |
178 | "test_peerstore_api_data.conf", | ||
179 | &run, NULL)) | ||
91 | return 1; | 180 | return 1; |
181 | if (0 != ok) | ||
182 | fprintf (stderr, | ||
183 | "Test failed: %d\n", | ||
184 | ok). | ||
92 | return ok; | 185 | return ok; |
93 | } | 186 | } |
94 | 187 | ||
95 | /* end of test_peerstore_api_store.c */ | 188 | /* end of test_peerstore_api_sync.c */ |
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 | } |