Link libgnunetblockgroup to libgnunetblock
[oweals/gnunet.git] / src / util / test_crypto_ecc_dlog.c
index a594e5795f4e2d6f164c5b6ae41061bad50646f3..3bddf8efa94d114fae9b2da453f33abc8b35d461 100644 (file)
@@ -1,6 +1,6 @@
 /*
      This file is part of GNUnet.
-     Copyright (C) 2015 Christian Grothoff (and other contributing authors)
+     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
@@ -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"
 /**
  * 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 @@ main (int argc, char *argv[])
   edc = GNUNET_CRYPTO_ecc_dlog_prepare (MAX_FACT,
                                        MAX_MEM);
   test_dlog (edc);
+  test_math (edc);
   GNUNET_CRYPTO_ecc_dlog_release (edc);
   return 0;
 }