gnunet-svn
[Top][All Lists]
Advanced

[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;
 }




reply via email to

[Prev in Thread] Current Thread [Next in Thread]