[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[GNUnet-SVN] r36048 - in gnunet/src: include peerstore util
From: |
gnunet |
Subject: |
[GNUnet-SVN] r36048 - in gnunet/src: include peerstore util |
Date: |
Mon, 6 Jul 2015 16:22:52 +0200 |
Author: grothoff
Date: 2015-07-06 16:22:51 +0200 (Mon, 06 Jul 2015)
New Revision: 36048
Modified:
gnunet/src/include/gnunet_crypto_lib.h
gnunet/src/peerstore/gnunet-service-peerstore.c
gnunet/src/peerstore/test_peerstore_api_sync.c
gnunet/src/util/crypto_ecc_dlog.c
gnunet/src/util/crypto_paillier.c
gnunet/src/util/gnunet-ecc.c
gnunet/src/util/resolver_api.c
gnunet/src/util/test_crypto_ecc_dlog.c
Log:
-fix non-deterministic peerstore sync failure
Modified: gnunet/src/include/gnunet_crypto_lib.h
===================================================================
--- gnunet/src/include/gnunet_crypto_lib.h 2015-07-03 09:35:27 UTC (rev
36047)
+++ gnunet/src/include/gnunet_crypto_lib.h 2015-07-06 14:22:51 UTC (rev
36048)
@@ -1297,20 +1297,100 @@
unsigned int mem);
-
/**
* Calculate ECC discrete logarithm for small factors.
+ * Opposite of #GNUNET_CRYPTO_ecc_dexp().
*
* @param dlc precalculated values, determine range of factors
* @param input point on the curve to factor
* @return `dlc->max` if dlog failed, otherwise the factor
*/
-unsigned int
+int
GNUNET_CRYPTO_ecc_dlog (struct GNUNET_CRYPTO_EccDlogContext *edc,
gcry_mpi_point_t input);
/**
+ * Multiply the generator g of the elliptic curve by @a val
+ * to obtain the point on the curve representing @a val.
+ * Afterwards, point addition will correspond to integer
+ * addition. #GNUNET_CRYPTO_ecc_dlog() can be used to
+ * convert a point back to an integer (as long as the
+ * integer is smaller than the MAX of the @a edc context).
+ *
+ * @param edc calculation context for ECC operations
+ * @param val value to encode into a point
+ * @return representation of the value as an ECC point,
+ * must be freed using #GNUNET_CRYPTO_ecc_free()
+ */
+gcry_mpi_point_t
+GNUNET_CRYPTO_ecc_dexp (struct GNUNET_CRYPTO_EccDlogContext *edc,
+ int val);
+
+
+/**
+ * Multiply the generator g of the elliptic curve by @a val
+ * to obtain the point on the curve representing @a val.
+ *
+ * @param edc calculation context for ECC operations
+ * @param val (positive) value to encode into a point
+ * @return representation of the value as an ECC point,
+ * must be freed using #GNUNET_CRYPTO_ecc_free()
+ */
+gcry_mpi_point_t
+GNUNET_CRYPTO_ecc_dexp_mpi (struct GNUNET_CRYPTO_EccDlogContext *edc,
+ gcry_mpi_t val);
+
+
+/**
+ * Add two points on the elliptic curve.
+ *
+ * @param edc calculation context for ECC operations
+ * @param a some value
+ * @param b some value
+ * @return @a a + @a b, must be freed using #GNUNET_CRYPTO_ecc_free()
+ */
+gcry_mpi_point_t
+GNUNET_CRYPTO_ecc_add (struct GNUNET_CRYPTO_EccDlogContext *edc,
+ gcry_mpi_point_t a,
+ gcry_mpi_point_t b);
+
+
+/**
+ * Obtain a random point on the curve and its
+ * additive inverse. Both returned values
+ * must be freed using #GNUNET_CRYPTO_ecc_free().
+ *
+ * @param edc calculation context for ECC operations
+ * @param[out] r set to a random point on the curve
+ * @param[out] r_inv set to the additive inverse of @a r
+ */
+void
+GNUNET_CRYPTO_ecc_rnd (struct GNUNET_CRYPTO_EccDlogContext *edc,
+ gcry_mpi_point_t *r,
+ gcry_mpi_point_t *r_inv);
+
+
+/**
+ * Generate a random value mod n.
+ *
+ * @param edc ECC context
+ * @return random value mod n.
+ */
+gcry_mpi_t
+GNUNET_CRYPTO_ecc_random_mod_n (struct GNUNET_CRYPTO_EccDlogContext *edc);
+
+
+/**
+ * Free a point value returned by the API.
+ *
+ * @param p point to free
+ */
+void
+GNUNET_CRYPTO_ecc_free (gcry_mpi_point_t p);
+
+
+/**
* Release precalculated values.
*
* @param dlc dlog context
Modified: gnunet/src/peerstore/gnunet-service-peerstore.c
===================================================================
--- gnunet/src/peerstore/gnunet-service-peerstore.c 2015-07-03 09:35:27 UTC
(rev 36047)
+++ gnunet/src/peerstore/gnunet-service-peerstore.c 2015-07-06 14:22:51 UTC
(rev 36048)
@@ -1,6 +1,6 @@
/*
This file is part of GNUnet.
- Copyright (C)
+ Copyright (C) 2014, 2015 GNUnet e.V.
GNUnet is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published
Modified: gnunet/src/peerstore/test_peerstore_api_sync.c
===================================================================
--- gnunet/src/peerstore/test_peerstore_api_sync.c 2015-07-03 09:35:27 UTC
(rev 36047)
+++ gnunet/src/peerstore/test_peerstore_api_sync.c 2015-07-06 14:22:51 UTC
(rev 36048)
@@ -1,6 +1,6 @@
/*
This file is part of GNUnet.
- Copyright (C)
+ Copyright (C) 2015 GNUnet e.V.
GNUnet is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published
@@ -19,7 +19,11 @@
*/
/**
* @file peerstore/test_peerstore_api_sync.c
- * @brief testcase for peerstore sync before disconnect feature
+ * @brief testcase for peerstore sync-on-disconnect feature. Stores
+ * a value just before disconnecting, and then checks that
+ * this value is actually stored.
+ * @author Omar Tarabai
+ * @author Christian Grothoff (minor fix, comments)
*/
#include "platform.h"
#include "gnunet_util_lib.h"
@@ -26,19 +30,58 @@
#include "gnunet_testing_lib.h"
#include "gnunet_peerstore_service.h"
-static int ok = 1;
+/**
+ * Overall result, 0 for success.
+ */
+static int ok = 404;
+/**
+ * Configuration we use.
+ */
static const struct GNUNET_CONFIGURATION_Handle *cfg;
+/**
+ * handle to talk to the peerstore.
+ */
static struct GNUNET_PEERSTORE_Handle *h;
-static char *subsystem = "test_peerstore_api_sync";
+/**
+ * Subsystem we store the value for.
+ */
+static const char *subsystem = "test_peerstore_api_sync";
+
+/**
+ * Fake PID under which we store the value.
+ */
static struct GNUNET_PeerIdentity pid;
-static char *key = "test_peerstore_api_store_key";
-static char *val = "test_peerstore_api_store_val";
+/**
+ * Test key we're storing the test value under.
+ */
+static const char *key = "test_peerstore_api_store_key";
+
+/**
+ * Test value we are storing.
+ */
+static const char *val = "test_peerstore_api_store_val";
+
+
+/**
+ * Function that should be called with the result of the
+ * lookup, and finally once with NULL to signal the end
+ * of the iteration.
+ *
+ * Upon the first call, we set "ok" to success. On the
+ * second call (end of iteration) we terminate the test.
+ *
+ * @param cls NULL
+ * @param record the information stored in the peerstore
+ * @param emsg any error message
+ * @return #GNUNET_YES (all good, continue)
+ */
static int
-iterate_cb (void *cls, const struct GNUNET_PEERSTORE_Record *record,
+iterate_cb (void *cls,
+ const struct GNUNET_PEERSTORE_Record *record,
const char *emsg)
{
const char *rec_val;
@@ -46,7 +89,8 @@
GNUNET_break (NULL == emsg);
if (NULL == record)
{
- GNUNET_PEERSTORE_disconnect (h, GNUNET_NO);
+ GNUNET_PEERSTORE_disconnect (h,
+ GNUNET_NO);
GNUNET_SCHEDULER_shutdown ();
return GNUNET_YES;
}
@@ -57,25 +101,68 @@
}
+/**
+ * Run the 2nd stage of the test where we fetch the
+ * data that should have been stored.
+ *
+ * @param cls NULL
+ * @param tc unused
+ */
static void
+test_cont (void *cls,
+ const struct GNUNET_SCHEDULER_TaskContext *tc)
+{
+ h = GNUNET_PEERSTORE_connect (cfg);
+ GNUNET_PEERSTORE_iterate (h,
+ subsystem,
+ &pid, key,
+ GNUNET_TIME_UNIT_FOREVER_REL,
+ &iterate_cb, NULL);
+}
+
+
+/**
+ * Actually run the test.
+ */
+static void
test1 ()
{
- GNUNET_PEERSTORE_store (h, subsystem, &pid, key, val, strlen (val) + 1,
+ h = GNUNET_PEERSTORE_connect (cfg);
+ GNUNET_PEERSTORE_store (h,
+ subsystem,
+ &pid,
+ key,
+ val, strlen (val) + 1,
GNUNET_TIME_UNIT_FOREVER_ABS,
- GNUNET_PEERSTORE_STOREOPTION_REPLACE, NULL, NULL);
- GNUNET_PEERSTORE_disconnect (h, GNUNET_YES);
- h = GNUNET_PEERSTORE_connect (cfg);
- GNUNET_PEERSTORE_iterate (h, subsystem, &pid, key,
- GNUNET_TIME_UNIT_FOREVER_REL, &iterate_cb, NULL);
+ GNUNET_PEERSTORE_STOREOPTION_REPLACE,
+ NULL, NULL);
+ GNUNET_PEERSTORE_disconnect (h,
+ GNUNET_YES);
+ h = NULL;
+ /* We need to wait a little bit to give the disconnect
+ a chance to actually finish the operation; otherwise,
+ the test may fail non-deterministically if the new
+ connection is faster than the cleanup routine of the
+ old one. */
+ GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_SECONDS,
+ &test_cont,
+ NULL);
}
+/**
+ * Initialize globals and launch the test.
+ *
+ * @param cls NULL
+ * @param c configuration to use
+ * @param peer handle to our peer (unused)
+ */
static void
-run (void *cls, const struct GNUNET_CONFIGURATION_Handle *c,
+run (void *cls,
+ const struct GNUNET_CONFIGURATION_Handle *c,
struct GNUNET_TESTING_Peer *peer)
{
cfg = c;
- h = GNUNET_PEERSTORE_connect (cfg);
GNUNET_assert (NULL != h);
memset (&pid, 1, sizeof (pid));
test1 ();
@@ -86,10 +173,16 @@
main (int argc, char *argv[])
{
if (0 !=
- GNUNET_TESTING_service_run ("test-gnunet-peerstore", "peerstore",
- "test_peerstore_api_data.conf", &run, NULL))
+ GNUNET_TESTING_service_run ("test-gnunet-peerstore-sync",
+ "peerstore",
+ "test_peerstore_api_data.conf",
+ &run, NULL))
return 1;
+ if (0 != ok)
+ fprintf (stderr,
+ "Test failed: %d\n",
+ ok).
return ok;
}
-/* end of test_peerstore_api_store.c */
+/* end of test_peerstore_api_sync.c */
Modified: gnunet/src/util/crypto_ecc_dlog.c
===================================================================
--- gnunet/src/util/crypto_ecc_dlog.c 2015-07-03 09:35:27 UTC (rev 36047)
+++ gnunet/src/util/crypto_ecc_dlog.c 2015-07-06 14:22:51 UTC (rev 36048)
@@ -20,11 +20,10 @@
/**
* @file util/crypto_ecc_dlog.c
- * @brief ECC discreate logarithm for small values
+ * @brief ECC addition and discreate logarithm for small values.
+ * Allows us to use ECC for computations as long as the
+ * result is relativey small.
* @author Christian Grothoff
- *
- * TODO:
- * - support negative factors
*/
#include "platform.h"
#include <gcrypt.h>
@@ -66,9 +65,27 @@
*/
struct GNUNET_CRYPTO_EccDlogContext
{
+ /**
+ * Maximum absolute value the calculation supports.
+ */
unsigned int max;
+
+ /**
+ * How much memory should we use (relates to the number of entries in the
map).
+ */
unsigned int mem;
+
+ /**
+ * Map mapping points (here "interpreted" as EdDSA public keys) to
+ * a "void * = long" which corresponds to the numeric value of the
+ * point. As NULL is used to represent "unknown", the actual value
+ * represented by the entry in the map is the "long" minus @e max.
+ */
struct GNUNET_CONTAINER_MultiPeerMap *map;
+
+ /**
+ * Context to use for operations on the elliptic curve.
+ */
gcry_ctx_t ctx;
};
@@ -91,8 +108,10 @@
struct GNUNET_PeerIdentity key;
gcry_mpi_point_t gKi;
gcry_mpi_t fact;
+ gcry_mpi_t n;
unsigned int i;
+ GNUNET_assert (max < INT32_MAX);
edc = GNUNET_new (struct GNUNET_CRYPTO_EccDlogContext);
edc->max = max;
edc->mem = mem;
@@ -115,10 +134,25 @@
GNUNET_assert (GNUNET_OK ==
GNUNET_CONTAINER_multipeermap_put (edc->map,
&key,
- (void*) (long) i + 1,
+ (void*) (long) i + max,
GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY));
}
+ /* negative values */
+ n = gcry_mpi_ec_get_mpi ("n", edc->ctx, 1);
+ for (i=1;i<mem;i++)
+ {
+ gcry_mpi_set_ui (fact, i * K);
+ gcry_mpi_sub (fact, n, fact);
+ gcry_mpi_ec_mul (gKi, fact, g, edc->ctx);
+ extract_pk (gKi, edc->ctx, &key);
+ GNUNET_assert (GNUNET_OK ==
+ GNUNET_CONTAINER_multipeermap_put (edc->map,
+ &key,
+ (void*) (long) max - i,
+
GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY));
+ }
gcry_mpi_release (fact);
+ gcry_mpi_release (n);
gcry_mpi_point_release (gKi);
gcry_mpi_point_release (g);
return edc;
@@ -132,7 +166,7 @@
* @param input point on the curve to factor
* @return `edc->max` if dlog failed, otherwise the factor
*/
-unsigned int
+int
GNUNET_CRYPTO_ecc_dlog (struct GNUNET_CRYPTO_EccDlogContext *edc,
gcry_mpi_point_t input)
{
@@ -141,7 +175,7 @@
struct GNUNET_PeerIdentity key;
gcry_mpi_point_t q;
unsigned int i;
- unsigned int res;
+ int res;
void *retp;
g = gcry_mpi_ec_get_point ("g", edc->ctx, 0);
@@ -159,10 +193,10 @@
&key);
if (NULL != retp)
{
- res = (((long) retp) - 1) * K - i;
- fprintf (stderr,
- "Got DLOG %u\n",
- res);
+ res = (((long) retp) - edc->max) * K - i;
+ /* we continue the loop here to make the implementation
+ "constant-time". If we do not care about this, we could just
+ 'break' here and do fewer operations... */
}
if (i == edc->max/edc->mem)
break;
@@ -180,6 +214,40 @@
/**
+ * Generate a random value mod n.
+ *
+ * @param edc ECC context
+ * @return random value mod n.
+ */
+gcry_mpi_t
+GNUNET_CRYPTO_ecc_random_mod_n (struct GNUNET_CRYPTO_EccDlogContext *edc)
+{
+ gcry_mpi_t n;
+ unsigned int highbit;
+ gcry_mpi_t r;
+
+ n = gcry_mpi_ec_get_mpi ("n", edc->ctx, 1);
+
+ /* check public key for number of bits, bail out if key is all zeros */
+ highbit = 256; /* Curve25519 */
+ while ( (! gcry_mpi_test_bit (n, highbit)) &&
+ (0 != highbit) )
+ highbit--;
+ GNUNET_assert (0 != highbit);
+ /* generate fact < n (without bias) */
+ GNUNET_assert (NULL != (r = gcry_mpi_new (0)));
+ do {
+ gcry_mpi_randomize (r,
+ highbit + 1,
+ GCRY_STRONG_RANDOM);
+ }
+ while (gcry_mpi_cmp (r, n) >= 0);
+ gcry_mpi_release (n);
+ return r;
+}
+
+
+/**
* Release precalculated values.
*
* @param edc dlog context
@@ -191,6 +259,147 @@
GNUNET_CONTAINER_multipeermap_destroy (edc->map);
GNUNET_free (edc);
}
+
+
+/**
+ * Multiply the generator g of the elliptic curve by @a val
+ * to obtain the point on the curve representing @a val.
+ * Afterwards, point addition will correspond to integer
+ * addition. #GNUNET_CRYPTO_ecc_dlog() can be used to
+ * convert a point back to an integer (as long as the
+ * integer is smaller than the MAX of the @a edc context).
+ *
+ * @param edc calculation context for ECC operations
+ * @param val value to encode into a point
+ * @return representation of the value as an ECC point,
+ * must be freed using #GNUNET_CRYPTO_ecc_free()
+ */
+gcry_mpi_point_t
+GNUNET_CRYPTO_ecc_dexp (struct GNUNET_CRYPTO_EccDlogContext *edc,
+ int val)
+{
+ gcry_mpi_t fact;
+ gcry_mpi_t n;
+ gcry_mpi_point_t g;
+ gcry_mpi_point_t r;
+
+ g = gcry_mpi_ec_get_point ("g", edc->ctx, 0);
+ GNUNET_assert (NULL != g);
+ fact = gcry_mpi_new (0);
+ if (val < 0)
+ {
+ n = gcry_mpi_ec_get_mpi ("n", edc->ctx, 1);
+ gcry_mpi_set_ui (fact, - val);
+ gcry_mpi_sub (fact, n, fact);
+ gcry_mpi_release (n);
+ }
+ else
+ {
+ gcry_mpi_set_ui (fact, val);
+ }
+ r = gcry_mpi_point_new (0);
+ gcry_mpi_ec_mul (r, fact, g, edc->ctx);
+ gcry_mpi_release (fact);
+ gcry_mpi_point_release (g);
+ return r;
+}
+
+
+/**
+ * Multiply the generator g of the elliptic curve by @a val
+ * to obtain the point on the curve representing @a val.
+ *
+ * @param edc calculation context for ECC operations
+ * @param val (positive) value to encode into a point
+ * @return representation of the value as an ECC point,
+ * must be freed using #GNUNET_CRYPTO_ecc_free()
+ */
+gcry_mpi_point_t
+GNUNET_CRYPTO_ecc_dexp_mpi (struct GNUNET_CRYPTO_EccDlogContext *edc,
+ gcry_mpi_t val)
+{
+ gcry_mpi_point_t g;
+ gcry_mpi_point_t r;
+
+ g = gcry_mpi_ec_get_point ("g", edc->ctx, 0);
+ GNUNET_assert (NULL != g);
+ r = gcry_mpi_point_new (0);
+ gcry_mpi_ec_mul (r, val, g, edc->ctx);
+ gcry_mpi_point_release (g);
+ return r;
+}
+
+
+/**
+ * Add two points on the elliptic curve.
+ *
+ * @param edc calculation context for ECC operations
+ * @param a some value
+ * @param b some value
+ * @return @a a + @a b, must be freed using #GNUNET_CRYPTO_ecc_free()
+ */
+gcry_mpi_point_t
+GNUNET_CRYPTO_ecc_add (struct GNUNET_CRYPTO_EccDlogContext *edc,
+ gcry_mpi_point_t a,
+ gcry_mpi_point_t b)
+{
+ gcry_mpi_point_t r;
+ r = gcry_mpi_point_new (0);
+ gcry_mpi_ec_add (r, a, b, edc->ctx);
+ return r;
+}
+
+
+/**
+ * Obtain a random point on the curve and its
+ * additive inverse. Both returned values
+ * must be freed using #GNUNET_CRYPTO_ecc_free().
+ *
+ * @param edc calculation context for ECC operations
+ * @param[out] r set to a random point on the curve
+ * @param[out] r_inv set to the additive inverse of @a r
+ */
+void
+GNUNET_CRYPTO_ecc_rnd (struct GNUNET_CRYPTO_EccDlogContext *edc,
+ gcry_mpi_point_t *r,
+ gcry_mpi_point_t *r_inv)
+{
+ gcry_mpi_t fact;
+ gcry_mpi_t n;
+ gcry_mpi_point_t g;
+
+ fact = GNUNET_CRYPTO_ecc_random_mod_n (edc);
+
+ /* calculate 'r' */
+ g = gcry_mpi_ec_get_point ("g", edc->ctx, 0);
+ GNUNET_assert (NULL != g);
+ *r = gcry_mpi_point_new (0);
+ gcry_mpi_ec_mul (*r, fact, g, edc->ctx);
+
+ /* calculate 'r_inv' */
+ n = gcry_mpi_ec_get_mpi ("n", edc->ctx, 1);
+ gcry_mpi_sub (fact, n, fact); /* fact = n - fact = - fact */
+ *r_inv = gcry_mpi_point_new (0);
+ gcry_mpi_ec_mul (*r_inv, fact, g, edc->ctx);
+
+ gcry_mpi_release (n);
+ gcry_mpi_release (fact);
+ gcry_mpi_point_release (g);
+}
+
+
+/**
+ * Free a point value returned by the API.
+ *
+ * @param p point to free
+ */
+void
+GNUNET_CRYPTO_ecc_free (gcry_mpi_point_t p)
+{
+ gcry_mpi_point_release (p);
+}
+
+
/* end of crypto_ecc_dlog.c */
Modified: gnunet/src/util/crypto_paillier.c
===================================================================
--- gnunet/src/util/crypto_paillier.c 2015-07-03 09:35:27 UTC (rev 36047)
+++ gnunet/src/util/crypto_paillier.c 2015-07-06 14:22:51 UTC (rev 36048)
@@ -269,7 +269,7 @@
}
/* generate r < n (without bias) */
- GNUNET_assert (0 != (r = gcry_mpi_new (0)));
+ GNUNET_assert (NULL != (r = gcry_mpi_new (0)));
do {
gcry_mpi_randomize (r, highbit + 1, GCRY_STRONG_RANDOM);
}
Modified: gnunet/src/util/gnunet-ecc.c
===================================================================
--- gnunet/src/util/gnunet-ecc.c 2015-07-03 09:35:27 UTC (rev 36047)
+++ gnunet/src/util/gnunet-ecc.c 2015-07-06 14:22:51 UTC (rev 36048)
@@ -28,6 +28,9 @@
#include "gnunet_testing_lib.h"
#include <gcrypt.h>
+/**
+ * Number of characters a Base32-encoded public key requires.
+ */
#define KEY_STR_LEN sizeof(struct GNUNET_CRYPTO_EddsaPublicKey)*8/5+1
/**
@@ -69,9 +72,9 @@
struct GNUNET_CRYPTO_EddsaPrivateKey *pk;
struct GNUNET_CRYPTO_EddsaPublicKey target_pub;
static char vanity[KEY_STR_LEN + 1];
- int len;
- int n;
- int rest;
+ size_t len;
+ size_t n;
+ size_t rest;
unsigned char mask;
unsigned target_byte;
char *s;
@@ -119,9 +122,9 @@
s);
GNUNET_free (s);
fprintf (stderr,
- "\nattempt %s [%d, %X]\n",
+ "\nattempt %s [%u, %X]\n",
vanity,
- n,
+ (unsigned int) n,
mask);
}
else
Modified: gnunet/src/util/resolver_api.c
===================================================================
--- gnunet/src/util/resolver_api.c 2015-07-03 09:35:27 UTC (rev 36047)
+++ gnunet/src/util/resolver_api.c 2015-07-06 14:22:51 UTC (rev 36048)
@@ -1028,7 +1028,10 @@
gai_strerror (ret));
return NULL;
}
- rval = GNUNET_strdup (ai->ai_canonname);
+ if (NULL != ai->ai_canonname)
+ rval = GNUNET_strdup (ai->ai_canonname);
+ else
+ rval = GNUNET_strdup (hostname);
freeaddrinfo (ai);
return rval;
}
Modified: gnunet/src/util/test_crypto_ecc_dlog.c
===================================================================
--- gnunet/src/util/test_crypto_ecc_dlog.c 2015-07-03 09:35:27 UTC (rev
36047)
+++ gnunet/src/util/test_crypto_ecc_dlog.c 2015-07-06 14:22:51 UTC (rev
36048)
@@ -22,9 +22,6 @@
* @file util/test_crypto_ecc_dlog.c
* @brief testcase for ECC DLOG calculation
* @author Christian Grothoff
- *
- * TODO:
- * - test negative numbers
*/
#include "platform.h"
#include "gnunet_util_lib.h"
@@ -42,52 +39,132 @@
/**
* Maximum value we test dlog for.
*/
-#define MAX_FACT 1000000
+#define MAX_FACT 100
/**
* Maximum memory to use, sqrt(MAX_FACT) is a good choice.
*/
-#define MAX_MEM 1000
+#define MAX_MEM 10
+/**
+ * How many values do we test?
+ */
+#define TEST_ITER 10
+/**
+ * Range of values to use for MATH tests.
+ */
+#define MATH_MAX 5
+
+
+/**
+ * Do some DLOG operations for testing.
+ *
+ * @param edc context for ECC operations
+ */
static void
test_dlog (struct GNUNET_CRYPTO_EccDlogContext *edc)
{
gcry_mpi_t fact;
+ gcry_mpi_t n;
gcry_ctx_t ctx;
gcry_mpi_point_t q;
gcry_mpi_point_t g;
unsigned int i;
- unsigned int x;
+ int x;
+ int iret;
GNUNET_assert (0 == gcry_mpi_ec_new (&ctx, NULL, CURVE));
g = gcry_mpi_ec_get_point ("g", ctx, 0);
GNUNET_assert (NULL != g);
+ n = gcry_mpi_ec_get_mpi ("n", ctx, 0);
q = gcry_mpi_point_new (0);
fact = gcry_mpi_new (0);
- for (i=0;i<10;i++)
+ for (i=0;i<TEST_ITER;i++)
{
+ fprintf (stderr, ".");
x = GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_WEAK,
MAX_FACT);
- gcry_mpi_set_ui (fact, x);
+ if (0 == GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_WEAK,
+ 2))
+ {
+ gcry_mpi_set_ui (fact, x);
+ gcry_mpi_sub (fact, n, fact);
+ x = - x;
+ }
+ else
+ {
+ gcry_mpi_set_ui (fact, x);
+ }
gcry_mpi_ec_mul (q, fact, g, ctx);
if (x !=
- GNUNET_CRYPTO_ecc_dlog (edc,
- q))
+ (iret = GNUNET_CRYPTO_ecc_dlog (edc,
+ q)))
{
fprintf (stderr,
- "DLOG failed for value %u\n",
- x);
+ "DLOG failed for value %d (%d)\n",
+ x,
+ iret);
GNUNET_assert (0);
}
}
gcry_mpi_release (fact);
+ gcry_mpi_release (n);
gcry_mpi_point_release (g);
gcry_mpi_point_release (q);
gcry_ctx_release (ctx);
+ fprintf (stderr, "\n");
}
+/**
+ * Do some arithmetic operations for testing.
+ *
+ * @param edc context for ECC operations
+ */
+static void
+test_math (struct GNUNET_CRYPTO_EccDlogContext *edc)
+{
+ int i;
+ int j;
+ gcry_mpi_point_t ip;
+ gcry_mpi_point_t jp;
+ gcry_mpi_point_t r;
+ gcry_mpi_point_t ir;
+ gcry_mpi_point_t irj;
+ gcry_mpi_point_t r_inv;
+ gcry_mpi_point_t sum;
+
+ for (i=-MATH_MAX;i<MATH_MAX;i++)
+ {
+ ip = GNUNET_CRYPTO_ecc_dexp (edc, i);
+ for (j=-MATH_MAX;j<MATH_MAX;j++)
+ {
+ fprintf (stderr, ".");
+ jp = GNUNET_CRYPTO_ecc_dexp (edc, j);
+ GNUNET_CRYPTO_ecc_rnd (edc,
+ &r,
+ &r_inv);
+ ir = GNUNET_CRYPTO_ecc_add (edc, ip, r);
+ irj = GNUNET_CRYPTO_ecc_add (edc, ir, jp);
+ sum = GNUNET_CRYPTO_ecc_add (edc, irj, r_inv);
+ GNUNET_assert (i + j ==
+ GNUNET_CRYPTO_ecc_dlog (edc,
+ sum));
+ GNUNET_CRYPTO_ecc_free (jp);
+ GNUNET_CRYPTO_ecc_free (ir);
+ GNUNET_CRYPTO_ecc_free (irj);
+ GNUNET_CRYPTO_ecc_free (r);
+ GNUNET_CRYPTO_ecc_free (r_inv);
+ GNUNET_CRYPTO_ecc_free (sum);
+ }
+ GNUNET_CRYPTO_ecc_free (ip);
+ }
+ fprintf (stderr, "\n");
+}
+
+
+
int
main (int argc, char *argv[])
{
@@ -109,6 +186,7 @@
edc = GNUNET_CRYPTO_ecc_dlog_prepare (MAX_FACT,
MAX_MEM);
test_dlog (edc);
+ test_math (edc);
GNUNET_CRYPTO_ecc_dlog_release (edc);
return 0;
}
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [GNUnet-SVN] r36048 - in gnunet/src: include peerstore util,
gnunet <=