gnunet-svn
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[gnunet] 01/02: SCALARPRODUCT: migrating logic from libgcrypt to libsodi


From: gnunet
Subject: [gnunet] 01/02: SCALARPRODUCT: migrating logic from libgcrypt to libsodium (#6818).
Date: Sun, 18 Apr 2021 21:15:11 +0200

This is an automated email from the git hooks/post-receive script.

grothoff pushed a commit to branch master
in repository gnunet.

commit 75cfa6370bc902765c26b50bb858c9a5bc1e8e48
Author: Christian Grothoff <christian@grothoff.org>
AuthorDate: Sun Apr 18 21:11:08 2021 +0200

    SCALARPRODUCT: migrating logic from libgcrypt to libsodium (#6818).
---
 src/include/gnunet_crypto_lib.h                    | 132 +++---
 src/include/gnunet_scalarproduct_service.h         |  50 +-
 src/scalarproduct/Makefile.am                      |   4 +-
 .../gnunet-service-scalarproduct-ecc_alice.c       | 297 ++++++------
 .../gnunet-service-scalarproduct-ecc_bob.c         | 131 ++---
 src/scalarproduct/perf_scalarproduct.sh            |  19 +-
 src/scalarproduct/scalarproduct_api.c              |  50 +-
 src/scalarproduct/test_ecc_scalarproduct.c         | 211 +++++----
 src/scalarproduct/test_scalarproduct_negative.sh   |   3 +
 src/util/Makefile.am                               |   3 +-
 src/util/crypto_ecc_dlog.c                         | 525 +++++++--------------
 src/util/perf_crypto_ecc_dlog.c                    | 118 ++---
 src/util/test_crypto_ecc_dlog.c                    | 141 +++---
 13 files changed, 767 insertions(+), 917 deletions(-)

diff --git a/src/include/gnunet_crypto_lib.h b/src/include/gnunet_crypto_lib.h
index d01457b4a..2a552e212 100644
--- a/src/include/gnunet_crypto_lib.h
+++ b/src/include/gnunet_crypto_lib.h
@@ -1443,9 +1443,16 @@ struct GNUNET_CRYPTO_EccPoint
    * Q consists of an x- and a y-value, each mod p (256 bits), given
    * here in affine coordinates and Ed25519 standard compact format.
    */
-  unsigned char q_y[256 / 8];
+  unsigned char v[256 / 8];
 };
 
+/**
+ * A ECC scalar for use in point multiplications
+ */
+struct GNUNET_CRYPTO_EccScalar
+{
+  unsigned char v[256 / 8];
+};
 
 /**
  * Do pre-calculation for ECC discrete logarithm for small factors.
@@ -1455,7 +1462,8 @@ struct GNUNET_CRYPTO_EccPoint
  * @return NULL on error
  */
 struct GNUNET_CRYPTO_EccDlogContext *
-GNUNET_CRYPTO_ecc_dlog_prepare (unsigned int max, unsigned int mem);
+GNUNET_CRYPTO_ecc_dlog_prepare (unsigned int max,
+                                unsigned int mem);
 
 
 /**
@@ -1468,7 +1476,7 @@ GNUNET_CRYPTO_ecc_dlog_prepare (unsigned int max, 
unsigned int mem);
  */
 int
 GNUNET_CRYPTO_ecc_dlog (struct GNUNET_CRYPTO_EccDlogContext *edc,
-                        gcry_mpi_point_t input);
+                        const struct GNUNET_CRYPTO_EccPoint *input);
 
 
 /**
@@ -1479,138 +1487,107 @@ GNUNET_CRYPTO_ecc_dlog (struct 
GNUNET_CRYPTO_EccDlogContext *edc,
  * 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()
+ * @param r where to write the point (must be allocated)
  */
-gcry_mpi_point_t
-GNUNET_CRYPTO_ecc_dexp (struct GNUNET_CRYPTO_EccDlogContext *edc, int val);
+void
+GNUNET_CRYPTO_ecc_dexp (int val,
+                        struct GNUNET_CRYPTO_EccPoint*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()
+ * @param r where to write the point (must be allocated)
+ * @return #GNUNET_OK on success.
  */
-gcry_mpi_point_t
-GNUNET_CRYPTO_ecc_dexp_mpi (struct GNUNET_CRYPTO_EccDlogContext *edc,
-                            gcry_mpi_t val);
+enum GNUNET_GenericReturnValue
+GNUNET_CRYPTO_ecc_dexp_mpi (const struct GNUNET_CRYPTO_EccScalar *val,
+                            struct GNUNET_CRYPTO_EccPoint *r);
 
 
 /**
  * Multiply the point @a p on the elliptic curve by @a val.
  *
- * @param edc calculation context for ECC operations
  * @param p point to multiply
  * @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_pmul_mpi (struct GNUNET_CRYPTO_EccDlogContext *edc,
-                            gcry_mpi_point_t p,
-                            gcry_mpi_t val);
-
-
-/**
- * Convert point value to binary representation.
- *
- * @param edc calculation context for ECC operations
- * @param point computational point representation
- * @param[out] bin binary point representation
- */
-void
-GNUNET_CRYPTO_ecc_point_to_bin (struct GNUNET_CRYPTO_EccDlogContext *edc,
-                                gcry_mpi_point_t point,
-                                struct GNUNET_CRYPTO_EccPoint *bin);
-
-
-/**
- * Convert binary representation of a point to computational representation.
- *
- * @param edc calculation context for ECC operations
- * @param bin binary point representation
- * @return computational representation
+ * @param r where to write the point (must be allocated)
+ * @return #GNUNET_OK on success.
  */
-gcry_mpi_point_t
-GNUNET_CRYPTO_ecc_bin_to_point (struct GNUNET_CRYPTO_EccDlogContext *edc,
-                                const struct GNUNET_CRYPTO_EccPoint *bin);
+enum GNUNET_GenericReturnValue
+GNUNET_CRYPTO_ecc_pmul_mpi (const struct GNUNET_CRYPTO_EccPoint *p,
+                            const struct GNUNET_CRYPTO_EccScalar *val,
+                            struct GNUNET_CRYPTO_EccPoint *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()
+ * @param r where to write the point (must be allocated)
+ * @return #GNUNET_OK on success.
  */
-gcry_mpi_point_t
-GNUNET_CRYPTO_ecc_add (struct GNUNET_CRYPTO_EccDlogContext *edc,
-                       gcry_mpi_point_t a,
-                       gcry_mpi_point_t b);
+enum GNUNET_GenericReturnValue
+GNUNET_CRYPTO_ecc_add (const struct GNUNET_CRYPTO_EccPoint *a,
+                       const struct GNUNET_CRYPTO_EccPoint *b,
+                       struct GNUNET_CRYPTO_EccPoint *r);
 
 
 /**
  * Obtain a random point on the curve and its
- * additive inverse. Both returned values
- * must be freed using #GNUNET_CRYPTO_ecc_free().
+ * additive inverse.
  *
- * @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
+ * @return #GNUNET_OK on success.
  */
-void
-GNUNET_CRYPTO_ecc_rnd (struct GNUNET_CRYPTO_EccDlogContext *edc,
-                       gcry_mpi_point_t *r,
-                       gcry_mpi_point_t *r_inv);
+enum GNUNET_GenericReturnValue
+GNUNET_CRYPTO_ecc_rnd (struct GNUNET_CRYPTO_EccPoint *r,
+                       struct GNUNET_CRYPTO_EccPoint *r_inv);
 
 
 /**
  * Obtain a random scalar for point multiplication on the curve and
- * its multiplicative inverse.
+ * its additive inverse.
  *
- * @param edc calculation context for ECC operations
  * @param[out] r set to a random scalar on the curve
- * @param[out] r_inv set to the multiplicative inverse of @a r
+ * @param[out] r_neg set to the negation of @a
  */
 void
-GNUNET_CRYPTO_ecc_rnd_mpi (struct GNUNET_CRYPTO_EccDlogContext *edc,
-                           gcry_mpi_t *r,
-                           gcry_mpi_t *r_inv);
+GNUNET_CRYPTO_ecc_rnd_mpi (struct GNUNET_CRYPTO_EccScalar *r,
+                           struct GNUNET_CRYPTO_EccScalar *r_neg);
 
 
 /**
  * Generate a random value mod n.
  *
- * @param edc ECC context
- * @return random value mod n.
+ * @param[out] r random value mod n.
  */
-gcry_mpi_t
-GNUNET_CRYPTO_ecc_random_mod_n (struct GNUNET_CRYPTO_EccDlogContext *edc);
+void
+GNUNET_CRYPTO_ecc_random_mod_n (struct GNUNET_CRYPTO_EccScalar*r);
 
 
 /**
- * Free a point value returned by the API.
+ * Release precalculated values.
  *
- * @param p point to free
+ * @param dlc dlog context
  */
 void
-GNUNET_CRYPTO_ecc_free (gcry_mpi_point_t p);
+GNUNET_CRYPTO_ecc_dlog_release (struct GNUNET_CRYPTO_EccDlogContext *dlc);
 
 
 /**
- * Release precalculated values.
+ * Create a scalar from int value.
  *
- * @param dlc dlog context
+ * @param val the int value
+ * @param[out] r where to write the salar
  */
 void
-GNUNET_CRYPTO_ecc_dlog_release (struct GNUNET_CRYPTO_EccDlogContext *dlc);
+GNUNET_CRYPTO_ecc_scalar_from_int (int64_t val,
+                                   struct GNUNET_CRYPTO_EccScalar *r);
 
 
 /**
@@ -1643,6 +1620,7 @@ GNUNET_CRYPTO_eddsa_ecdh (const struct 
GNUNET_CRYPTO_EddsaPrivateKey *priv,
                           const struct GNUNET_CRYPTO_EcdhePublicKey *pub,
                           struct GNUNET_HashCode *key_material);
 
+
 /**
  * @ingroup crypto
  * Derive key material from a ECDH public key and a private ECDSA key.
@@ -1937,7 +1915,9 @@ GNUNET_CRYPTO_ecdsa_public_key_derive (
  * @param val value to write to @a buf
  */
 void
-GNUNET_CRYPTO_mpi_print_unsigned (void *buf, size_t size, gcry_mpi_t val);
+GNUNET_CRYPTO_mpi_print_unsigned (void *buf,
+                                  size_t size,
+                                  gcry_mpi_t val);
 
 
 /**
diff --git a/src/include/gnunet_scalarproduct_service.h 
b/src/include/gnunet_scalarproduct_service.h
index b12a19a2f..1d775f659 100644
--- a/src/include/gnunet_scalarproduct_service.h
+++ b/src/include/gnunet_scalarproduct_service.h
@@ -17,7 +17,6 @@
 
      SPDX-License-Identifier: AGPL3.0-or-later
  */
-
 /**
  * @author Christian M. Fuchs
  * @author Gaurav Kukreja
@@ -118,10 +117,9 @@ GNUNET_NETWORK_STRUCT_END
  * @param status Status of the request
  */
 typedef void
-(*GNUNET_SCALARPRODUCT_ContinuationWithStatus) (void *cls,
-                                                enum
-                                                
GNUNET_SCALARPRODUCT_ResponseStatus
-                                                status);
+(*GNUNET_SCALARPRODUCT_ContinuationWithStatus) (
+  void *cls,
+  enum GNUNET_SCALARPRODUCT_ResponseStatus status);
 
 
 /**
@@ -132,10 +130,10 @@ typedef void
  * @param result result of the computation
  */
 typedef void
-(*GNUNET_SCALARPRODUCT_DatumProcessor) (void *cls,
-                                        enum 
GNUNET_SCALARPRODUCT_ResponseStatus
-                                        status,
-                                        gcry_mpi_t result);
+(*GNUNET_SCALARPRODUCT_DatumProcessor) (
+  void *cls,
+  enum GNUNET_SCALARPRODUCT_ResponseStatus status,
+  gcry_mpi_t result);
 
 
 /**
@@ -157,16 +155,14 @@ struct GNUNET_SCALARPRODUCT_ComputationHandle;
  * @return a new handle for this computation
  */
 struct GNUNET_SCALARPRODUCT_ComputationHandle *
-GNUNET_SCALARPRODUCT_start_computation (const struct
-                                        GNUNET_CONFIGURATION_Handle *cfg,
-                                        const struct
-                                        GNUNET_HashCode *session_key,
-                                        const struct GNUNET_PeerIdentity *peer,
-                                        const struct
-                                        GNUNET_SCALARPRODUCT_Element *elements,
-                                        uint32_t element_count,
-                                        GNUNET_SCALARPRODUCT_DatumProcessor 
cont,
-                                        void *cont_cls);
+GNUNET_SCALARPRODUCT_start_computation (
+  const struct GNUNET_CONFIGURATION_Handle *cfg,
+  const struct GNUNET_HashCode *session_key,
+  const struct GNUNET_PeerIdentity *peer,
+  const struct GNUNET_SCALARPRODUCT_Element *elements,
+  uint32_t element_count,
+  GNUNET_SCALARPRODUCT_DatumProcessor cont,
+  void *cont_cls);
 
 
 /**
@@ -181,15 +177,13 @@ GNUNET_SCALARPRODUCT_start_computation (const struct
  * @return a new handle for this computation
  */
 struct GNUNET_SCALARPRODUCT_ComputationHandle *
-GNUNET_SCALARPRODUCT_accept_computation (const struct
-                                         GNUNET_CONFIGURATION_Handle *cfg,
-                                         const struct GNUNET_HashCode *key,
-                                         const struct
-                                         GNUNET_SCALARPRODUCT_Element 
*elements,
-                                         uint32_t element_count,
-                                         
GNUNET_SCALARPRODUCT_ContinuationWithStatus
-                                         cont,
-                                         void *cont_cls);
+GNUNET_SCALARPRODUCT_accept_computation (
+  const struct GNUNET_CONFIGURATION_Handle *cfg,
+  const struct GNUNET_HashCode *key,
+  const struct GNUNET_SCALARPRODUCT_Element *elements,
+  uint32_t element_count,
+  GNUNET_SCALARPRODUCT_ContinuationWithStatus cont,
+  void *cont_cls);
 
 
 /**
diff --git a/src/scalarproduct/Makefile.am b/src/scalarproduct/Makefile.am
index f3448725a..cf05e8377 100644
--- a/src/scalarproduct/Makefile.am
+++ b/src/scalarproduct/Makefile.am
@@ -63,6 +63,7 @@ gnunet_service_scalarproduct_ecc_alice_LDADD = \
   $(top_builddir)/src/cadet/libgnunetcadet.la \
   $(top_builddir)/src/seti/libgnunetseti.la \
   $(LIBGCRYPT_LIBS) \
+  -lsodium \
   -lgcrypt \
   $(GN_LIBINTL)
 
@@ -74,6 +75,7 @@ gnunet_service_scalarproduct_ecc_bob_LDADD = \
   $(top_builddir)/src/cadet/libgnunetcadet.la \
   $(top_builddir)/src/seti/libgnunetseti.la \
   $(LIBGCRYPT_LIBS) \
+  -lsodium \
   -lgcrypt \
   $(GN_LIBINTL)
 
@@ -111,4 +113,4 @@ test_ecc_scalarproduct_SOURCES = \
  test_ecc_scalarproduct.c
 test_ecc_scalarproduct_LDADD = \
   $(top_builddir)/src/util/libgnunetutil.la \
-  -lgcrypt
+  -lsodium
diff --git a/src/scalarproduct/gnunet-service-scalarproduct-ecc_alice.c 
b/src/scalarproduct/gnunet-service-scalarproduct-ecc_alice.c
index 447451aef..e33d589be 100644
--- a/src/scalarproduct/gnunet-service-scalarproduct-ecc_alice.c
+++ b/src/scalarproduct/gnunet-service-scalarproduct-ecc_alice.c
@@ -1,6 +1,6 @@
 /*
      This file is part of GNUnet.
-     Copyright (C) 2013-2017 GNUnet e.V.
+     Copyright (C) 2013-2017, 2021 GNUnet e.V.
 
      GNUnet is free software: you can redistribute it and/or modify it
      under the terms of the GNU Affero General Public License as published
@@ -69,7 +69,7 @@ struct MpiElement
   /**
    * a_i value, not disclosed to Bob.
    */
-  gcry_mpi_t value;
+  int64_t value;
 };
 
 
@@ -138,9 +138,9 @@ struct AliceServiceSession
   struct MpiElement *sorted_elements;
 
   /**
-   * The computed scalar
+   * The computed scalar product. INT_MAX if the computation failed.
    */
-  gcry_mpi_t product;
+  int product;
 
   /**
    * How many elements we were supplied with from the client (total
@@ -190,12 +190,12 @@ static struct GNUNET_CRYPTO_EccDlogContext *edc;
 /**
  * Alice's private key ('a').
  */
-static gcry_mpi_t my_privkey;
+static struct GNUNET_CRYPTO_EccScalar my_privkey;
 
 /**
  * Inverse of Alice's private key ('a_inv').
  */
-static gcry_mpi_t my_privkey_inv;
+static struct GNUNET_CRYPTO_EccScalar my_privkey_inv;
 
 /**
  * Handle to the CADET service.
@@ -212,7 +212,9 @@ static struct GNUNET_CADET_Handle *my_cadet;
  * @return #GNUNET_OK (continue to iterate)
  */
 static int
-free_element_cb (void *cls, const struct GNUNET_HashCode *key, void *value)
+free_element_cb (void *cls,
+                 const struct GNUNET_HashCode *key,
+                 void *value)
 {
   struct GNUNET_SCALARPRODUCT_Element *e = value;
 
@@ -229,8 +231,6 @@ free_element_cb (void *cls, const struct GNUNET_HashCode 
*key, void *value)
 static void
 destroy_service_session (struct AliceServiceSession *s)
 {
-  unsigned int i;
-
   if (GNUNET_YES == s->in_destroy)
     return;
   s->in_destroy = GNUNET_YES;
@@ -261,7 +261,8 @@ destroy_service_session (struct AliceServiceSession *s)
   }
   if (NULL != s->intersection_op)
   {
-    LOG (GNUNET_ERROR_TYPE_DEBUG, "Set intersection, op still ongoing!\n");
+    LOG (GNUNET_ERROR_TYPE_DEBUG,
+         "Set intersection, op still ongoing!\n");
     GNUNET_SETI_operation_cancel (s->intersection_op);
     s->intersection_op = NULL;
   }
@@ -272,16 +273,9 @@ destroy_service_session (struct AliceServiceSession *s)
   }
   if (NULL != s->sorted_elements)
   {
-    for (i = 0; i < s->used_element_count; i++)
-      gcry_mpi_release (s->sorted_elements[i].value);
     GNUNET_free (s->sorted_elements);
     s->sorted_elements = NULL;
   }
-  if (NULL != s->product)
-  {
-    gcry_mpi_release (s->product);
-    s->product = NULL;
-  }
   GNUNET_free (s);
 }
 
@@ -305,10 +299,12 @@ prepare_client_end_notification (struct 
AliceServiceSession *session)
     "Sending session-end notification with status %d to client for session 
%s\n",
     session->status,
     GNUNET_h2s (&session->session_id));
-  e = GNUNET_MQ_msg (msg, GNUNET_MESSAGE_TYPE_SCALARPRODUCT_RESULT);
+  e = GNUNET_MQ_msg (msg,
+                     GNUNET_MESSAGE_TYPE_SCALARPRODUCT_RESULT);
   msg->product_length = htonl (0);
   msg->status = htonl (session->status);
-  GNUNET_MQ_send (session->client_mq, e);
+  GNUNET_MQ_send (session->client_mq,
+                  e);
 }
 
 
@@ -327,41 +323,41 @@ transmit_client_response (struct AliceServiceSession *s)
   size_t product_length = 0;
   int32_t range;
   gcry_error_t rc;
-  int sign;
   gcry_mpi_t value;
 
-  if (NULL == s->product)
+  if (INT_MAX == s->product)
   {
     GNUNET_break (0);
     prepare_client_end_notification (s);
     return;
   }
-  value = gcry_mpi_new (0);
-  sign = gcry_mpi_cmp_ui (s->product, 0);
-  if (0 > sign)
+  value = gcry_mpi_new (32);
+  if (0 > s->product)
   {
     range = -1;
-    gcry_mpi_sub (value, value, s->product);
+    gcry_mpi_set_ui (value,
+                     -s->product);
   }
-  else if (0 < sign)
+  else if (0 < s->product)
   {
     range = 1;
-    gcry_mpi_add (value, value, s->product);
+    gcry_mpi_set_ui (value,
+                     s->product);
   }
   else
   {
     /* result is exactly zero */
     range = 0;
   }
-  gcry_mpi_release (s->product);
-  s->product = NULL;
-
-  if ((0 != range) && (0 != (rc = gcry_mpi_aprint (GCRYMPI_FMT_STD,
-                                                   &product_exported,
-                                                   &product_length,
-                                                   value))))
+  if ( (0 != range) &&
+       (0 != (rc = gcry_mpi_aprint (GCRYMPI_FMT_STD,
+                                    &product_exported,
+                                    &product_length,
+                                    value))))
   {
-    LOG_GCRY (GNUNET_ERROR_TYPE_ERROR, "gcry_mpi_scan", rc);
+    LOG_GCRY (GNUNET_ERROR_TYPE_ERROR,
+              "gcry_mpi_scan",
+              rc);
     prepare_client_end_notification (s);
     return;
   }
@@ -374,10 +370,13 @@ transmit_client_response (struct AliceServiceSession *s)
   msg->product_length = htonl (product_length);
   if (NULL != product_exported)
   {
-    GNUNET_memcpy (&msg[1], product_exported, product_length);
+    GNUNET_memcpy (&msg[1],
+                   product_exported,
+                   product_length);
     GNUNET_free (product_exported);
   }
-  GNUNET_MQ_send (s->client_mq, e);
+  GNUNET_MQ_send (s->client_mq,
+                  e);
   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
               "Sent result to client, session %s has ended!\n",
               GNUNET_h2s (&s->session_id));
@@ -394,7 +393,8 @@ transmit_client_response (struct AliceServiceSession *s)
  * @param channel connection to the other end (henceforth invalid)
  */
 static void
-cb_channel_destruction (void *cls, const struct GNUNET_CADET_Channel *channel)
+cb_channel_destruction (void *cls,
+                        const struct GNUNET_CADET_Channel *channel)
 {
   struct AliceServiceSession *s = cls;
 
@@ -412,51 +412,6 @@ cb_channel_destruction (void *cls, const struct 
GNUNET_CADET_Channel *channel)
 }
 
 
-/**
- * Compute our scalar product, done by Alice
- *
- * @param session the session associated with this computation
- * @param prod_g_i_b_i value from Bob
- * @param prod_h_i_b_i value from Bob
- * @return product as MPI, never NULL
- */
-static gcry_mpi_t
-compute_scalar_product (struct AliceServiceSession *session,
-                        gcry_mpi_point_t prod_g_i_b_i,
-                        gcry_mpi_point_t prod_h_i_b_i)
-{
-  gcry_mpi_point_t g_i_b_i_a_inv;
-  gcry_mpi_point_t g_ai_bi;
-  int ai_bi;
-  gcry_mpi_t ret;
-
-  g_i_b_i_a_inv =
-    GNUNET_CRYPTO_ecc_pmul_mpi (edc, prod_g_i_b_i, my_privkey_inv);
-  g_ai_bi = GNUNET_CRYPTO_ecc_add (edc, g_i_b_i_a_inv, prod_h_i_b_i);
-  gcry_mpi_point_release (g_i_b_i_a_inv);
-  ai_bi = GNUNET_CRYPTO_ecc_dlog (edc, g_ai_bi);
-  gcry_mpi_point_release (g_ai_bi);
-  if (INT_MAX == ai_bi)
-  {
-    /* result too big */
-    GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
-                "Scalar product result out of range\n");
-    return NULL;
-  }
-  ret = gcry_mpi_new (0);
-  if (ai_bi > 0)
-  {
-    gcry_mpi_set_ui (ret, ai_bi);
-  }
-  else
-  {
-    gcry_mpi_set_ui (ret, -ai_bi);
-    gcry_mpi_neg (ret, ret);
-  }
-  return ret;
-}
-
-
 /**
  * Handle a response we got from another service we wanted to
  * calculate a scalarproduct with.
@@ -469,8 +424,6 @@ handle_bobs_cryptodata_message (void *cls,
                                 const struct EccBobCryptodataMessage *msg)
 {
   struct AliceServiceSession *s = cls;
-  gcry_mpi_point_t prod_g_i_b_i;
-  gcry_mpi_point_t prod_h_i_b_i;
   uint32_t contained;
 
   contained = ntohl (msg->contained_element_count);
@@ -494,16 +447,33 @@ handle_bobs_cryptodata_message (void *cls,
     destroy_service_session (s);
     return;
   }
-
   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
               "Received %u crypto values from Bob\n",
               (unsigned int) contained);
   GNUNET_CADET_receive_done (s->channel);
-  prod_g_i_b_i = GNUNET_CRYPTO_ecc_bin_to_point (edc, &msg->prod_g_i_b_i);
-  prod_h_i_b_i = GNUNET_CRYPTO_ecc_bin_to_point (edc, &msg->prod_h_i_b_i);
-  s->product = compute_scalar_product (s, prod_g_i_b_i, prod_h_i_b_i);
-  gcry_mpi_point_release (prod_g_i_b_i);
-  gcry_mpi_point_release (prod_h_i_b_i);
+  {
+    struct GNUNET_CRYPTO_EccPoint g_i_b_i_a_inv;
+    struct GNUNET_CRYPTO_EccPoint g_ai_bi;
+
+    GNUNET_assert (
+      GNUNET_OK ==
+      GNUNET_CRYPTO_ecc_pmul_mpi (&msg->prod_g_i_b_i,
+                                  &my_privkey_inv,
+                                  &g_i_b_i_a_inv));
+    GNUNET_assert (
+      GNUNET_OK ==
+      GNUNET_CRYPTO_ecc_add (&g_i_b_i_a_inv,
+                             &msg->prod_h_i_b_i,
+                             &g_ai_bi));
+    s->product = GNUNET_CRYPTO_ecc_dlog (edc,
+                                         &g_ai_bi);
+    if (INT_MAX == s->product)
+    {
+      /* result too big */
+      GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+                  "Scalar product result out of range\n");
+    }
+  }
   transmit_client_response (s);
 }
 
@@ -517,20 +487,15 @@ handle_bobs_cryptodata_message (void *cls,
  * @param value the `struct GNUNET_SCALARPRODUCT_Element *`
  */
 static int
-copy_element_cb (void *cls, const struct GNUNET_HashCode *key, void *value)
+copy_element_cb (void *cls,
+                 const struct GNUNET_HashCode *key,
+                 void *value)
 {
   struct AliceServiceSession *s = cls;
   struct GNUNET_SCALARPRODUCT_Element *e = value;
-  gcry_mpi_t mval;
-  int64_t val;
 
-  mval = gcry_mpi_new (0);
-  val = (int64_t) GNUNET_ntohll (e->value);
-  if (0 > val)
-    gcry_mpi_sub_ui (mval, mval, -val);
-  else
-    gcry_mpi_add_ui (mval, mval, val);
-  s->sorted_elements[s->used_element_count].value = mval;
+  s->sorted_elements[s->used_element_count].value = (int64_t) GNUNET_ntohll (
+    e->value);
   s->sorted_elements[s->used_element_count].key = &e->key;
   s->used_element_count++;
   return GNUNET_OK;
@@ -545,12 +510,14 @@ copy_element_cb (void *cls, const struct GNUNET_HashCode 
*key, void *value)
  * @return -1 for a < b, 0 for a=b, 1 for a > b.
  */
 static int
-element_cmp (const void *a, const void *b)
+element_cmp (const void *a,
+             const void *b)
 {
   const struct MpiElement *ma = a;
   const struct MpiElement *mb = b;
 
-  return GNUNET_CRYPTO_hash_cmp (ma->key, mb->key);
+  return GNUNET_CRYPTO_hash_cmp (ma->key,
+                                 mb->key);
 }
 
 
@@ -576,9 +543,8 @@ send_alices_cryptodata_message (struct AliceServiceSession 
*s)
   struct EccAliceCryptodataMessage *msg;
   struct GNUNET_MQ_Envelope *e;
   struct GNUNET_CRYPTO_EccPoint *payload;
-  gcry_mpi_t r_ia;
-  gcry_mpi_t r_ia_ai;
-  unsigned int i;
+  struct GNUNET_CRYPTO_EccScalar r_ia;
+  struct GNUNET_CRYPTO_EccScalar r_ia_ai;
   unsigned int off;
   unsigned int todo_count;
 
@@ -614,31 +580,53 @@ send_alices_cryptodata_message (struct 
AliceServiceSession *s)
                            
GNUNET_MESSAGE_TYPE_SCALARPRODUCT_ECC_ALICE_CRYPTODATA);
     msg->contained_element_count = htonl (todo_count);
     payload = (struct GNUNET_CRYPTO_EccPoint *) &msg[1];
-    r_ia = gcry_mpi_new (0);
-    r_ia_ai = gcry_mpi_new (0);
-    for (i = off; i < off + todo_count; i++)
+    for (unsigned int i = off; i < off + todo_count; i++)
     {
-      gcry_mpi_t r_i;
-      gcry_mpi_point_t g_i;
-      gcry_mpi_point_t h_i;
-
-      r_i = GNUNET_CRYPTO_ecc_random_mod_n (edc);
-      g_i = GNUNET_CRYPTO_ecc_dexp_mpi (edc, r_i);
+      struct GNUNET_CRYPTO_EccScalar r_i;
+      struct GNUNET_CRYPTO_EccPoint g_i;
+      struct GNUNET_CRYPTO_EccPoint h_i;
+
+      /* r_i = random() mod n */
+      GNUNET_CRYPTO_ecc_random_mod_n (&r_i);
+      /* g_i = g^{r_i} */
+      GNUNET_assert (GNUNET_OK ==
+                     GNUNET_CRYPTO_ecc_dexp_mpi (&r_i,
+                                                 &g_i));
       /* r_ia = r_i * a */
-      gcry_mpi_mul (r_ia, r_i, my_privkey);
-      gcry_mpi_release (r_i);
+      crypto_core_ed25519_scalar_mul (r_ia.v,
+                                      r_i.v,
+                                      my_privkey.v);
       /* r_ia_ai = r_ia + a_i */
-      gcry_mpi_add (r_ia_ai, r_ia, s->sorted_elements[i].value);
-      h_i = GNUNET_CRYPTO_ecc_dexp_mpi (edc, r_ia_ai);
-      GNUNET_CRYPTO_ecc_point_to_bin (edc, g_i, &payload[(i - off) * 2]);
-      GNUNET_CRYPTO_ecc_point_to_bin (edc, h_i, &payload[(i - off) * 2 + 1]);
-      gcry_mpi_point_release (g_i);
-      gcry_mpi_point_release (h_i);
+      {
+        int64_t val = s->sorted_elements[i].value;
+        struct GNUNET_CRYPTO_EccScalar vali;
+
+        GNUNET_assert (INT64_MIN != val);
+        GNUNET_CRYPTO_ecc_scalar_from_int (val > 0 ? val : -val,
+                                           &vali);
+        if (val > 0)
+          crypto_core_ed25519_scalar_add (r_ia_ai.v,
+                                          r_ia.v,
+                                          vali.v);
+        else
+          crypto_core_ed25519_scalar_sub (r_ia_ai.v,
+                                          r_ia.v,
+                                          vali.v);
+      }
+      /* h_i = g^{r_ia_ai} */
+      GNUNET_assert (GNUNET_OK ==
+                     GNUNET_CRYPTO_ecc_dexp_mpi (&r_ia_ai,
+                                                 &h_i));
+      memcpy (&payload[(i - off) * 2],
+              &g_i,
+              sizeof (g_i));
+      memcpy (&payload[(i - off) * 2 + 1],
+              &h_i,
+              sizeof (h_i));
     }
-    gcry_mpi_release (r_ia);
-    gcry_mpi_release (r_ia_ai);
     off += todo_count;
-    GNUNET_MQ_send (s->cadet_mq, e);
+    GNUNET_MQ_send (s->cadet_mq,
+                    e);
   }
 }
 
@@ -740,16 +728,17 @@ cb_intersection_request_alice (void *cls,
   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
               "Received intersection request from %s!\n",
               GNUNET_i2s (other_peer));
-  if (0 != GNUNET_memcmp (other_peer, &s->peer))
+  if (0 != GNUNET_memcmp (other_peer,
+                          &s->peer))
   {
     GNUNET_break_op (0);
     return;
   }
-  s->intersection_op = GNUNET_SETI_accept (request,
-                                           (struct
-                                            GNUNET_SETI_Option[]){ { 0 } },
-                                           &cb_intersection_element_removed,
-                                           s);
+  s->intersection_op
+    = GNUNET_SETI_accept (request,
+                          (struct GNUNET_SETI_Option[]){ { 0 } },
+                          &cb_intersection_element_removed,
+                          s);
   if (NULL == s->intersection_op)
   {
     GNUNET_break (0);
@@ -757,7 +746,9 @@ cb_intersection_request_alice (void *cls,
     prepare_client_end_notification (s);
     return;
   }
-  if (GNUNET_OK != GNUNET_SETI_commit (s->intersection_op, 
s->intersection_set))
+  if (GNUNET_OK !=
+      GNUNET_SETI_commit (s->intersection_op,
+                          s->intersection_set))
   {
     GNUNET_break (0);
     s->status = GNUNET_SCALARPRODUCT_STATUS_FAILURE;
@@ -775,12 +766,13 @@ cb_intersection_request_alice (void *cls,
 static void
 client_request_complete_alice (struct AliceServiceSession *s)
 {
-  struct GNUNET_MQ_MessageHandler cadet_handlers[] =
-  { GNUNET_MQ_hd_fixed_size (bobs_cryptodata_message,
+  struct GNUNET_MQ_MessageHandler cadet_handlers[] = {
+    GNUNET_MQ_hd_fixed_size (bobs_cryptodata_message,
                              
GNUNET_MESSAGE_TYPE_SCALARPRODUCT_ECC_BOB_CRYPTODATA,
                              struct EccBobCryptodataMessage,
                              s),
-    GNUNET_MQ_handler_end () };
+    GNUNET_MQ_handler_end ()
+  };
   struct EccServiceRequestMessage *msg;
   struct GNUNET_MQ_Envelope *e;
   struct GNUNET_HashCode set_sid;
@@ -982,17 +974,17 @@ handle_alice_client_message (void *cls,
   s->session_id = msg->session_key;
   elements = (const struct GNUNET_SCALARPRODUCT_Element *) &msg[1];
   s->intersected_elements =
-    GNUNET_CONTAINER_multihashmap_create (s->total, GNUNET_YES);
+    GNUNET_CONTAINER_multihashmap_create (s->total,
+                                          GNUNET_YES);
   s->intersection_set = GNUNET_SETI_create (cfg);
   for (uint32_t i = 0; i < contained_count; i++)
   {
     if (0 == GNUNET_ntohll (elements[i].value))
       continue;
     elem = GNUNET_new (struct GNUNET_SCALARPRODUCT_Element);
-    GNUNET_memcpy (elem,
-                   &elements[i],
-                   sizeof(struct GNUNET_SCALARPRODUCT_Element));
-    if (GNUNET_SYSERR == GNUNET_CONTAINER_multihashmap_put (
+    *elem = elements[i];
+    if (GNUNET_SYSERR ==
+        GNUNET_CONTAINER_multihashmap_put (
           s->intersected_elements,
           &elem->key,
           elem,
@@ -1006,7 +998,10 @@ handle_alice_client_message (void *cls,
     set_elem.data = &elem->key;
     set_elem.size = sizeof(elem->key);
     set_elem.element_type = 0;
-    GNUNET_SETI_add_element (s->intersection_set, &set_elem, NULL, NULL);
+    GNUNET_SETI_add_element (s->intersection_set,
+                             &set_elem,
+                             NULL,
+                             NULL);
     s->used_element_count++;
   }
   GNUNET_SERVICE_client_continue (s->client);
@@ -1017,7 +1012,8 @@ handle_alice_client_message (void *cls,
                 "Received partial client request, waiting for more!\n");
     return;
   }
-  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Launching computation\n");
+  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+              "Launching computation\n");
   client_request_complete_alice (s);
 }
 
@@ -1031,7 +1027,8 @@ handle_alice_client_message (void *cls,
 static void
 shutdown_task (void *cls)
 {
-  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Shutting down, initiating cleanup.\n");
+  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+              "Shutting down, initiating cleanup.\n");
   // FIXME: we have to cut our connections to CADET first!
   if (NULL != my_cadet)
   {
@@ -1109,17 +1106,21 @@ run (void *cls,
      struct GNUNET_SERVICE_Handle *service)
 {
   cfg = c;
-  edc = GNUNET_CRYPTO_ecc_dlog_prepare (MAX_RESULT, MAX_RAM);
+  edc = GNUNET_CRYPTO_ecc_dlog_prepare (MAX_RESULT,
+                                        MAX_RAM);
   /* Select a random 'a' value for Alice */
-  GNUNET_CRYPTO_ecc_rnd_mpi (edc, &my_privkey, &my_privkey_inv);
+  GNUNET_CRYPTO_ecc_rnd_mpi (&my_privkey,
+                             &my_privkey_inv);
   my_cadet = GNUNET_CADET_connect (cfg);
   if (NULL == my_cadet)
   {
-    GNUNET_log (GNUNET_ERROR_TYPE_ERROR, _ ("Connect to CADET failed\n"));
+    GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+                _ ("Connect to CADET failed\n"));
     GNUNET_SCHEDULER_shutdown ();
     return;
   }
-  GNUNET_SCHEDULER_add_shutdown (&shutdown_task, NULL);
+  GNUNET_SCHEDULER_add_shutdown (&shutdown_task,
+                                 NULL);
 }
 
 
diff --git a/src/scalarproduct/gnunet-service-scalarproduct-ecc_bob.c 
b/src/scalarproduct/gnunet-service-scalarproduct-ecc_bob.c
index 4c835d52a..02a62c164 100644
--- a/src/scalarproduct/gnunet-service-scalarproduct-ecc_bob.c
+++ b/src/scalarproduct/gnunet-service-scalarproduct-ecc_bob.c
@@ -1,6 +1,6 @@
 /*
      This file is part of GNUnet.
-     Copyright (C) 2013-2017 GNUnet e.V.
+     Copyright (C) 2013-2017, 2021 GNUnet e.V.
 
      GNUnet is free software: you can redistribute it and/or modify it
      under the terms of the GNU Affero General Public License as published
@@ -54,7 +54,7 @@ struct MpiElement
   /**
    * Value represented (a).
    */
-  gcry_mpi_t value;
+  int64_t value;
 };
 
 
@@ -104,12 +104,12 @@ struct BobServiceSession
   /**
    * Product of the g_i^{b_i}
    */
-  gcry_mpi_point_t prod_g_i_b_i;
+  struct GNUNET_CRYPTO_EccPoint prod_g_i_b_i;
 
   /**
    * Product of the h_i^{b_i}
    */
-  gcry_mpi_point_t prod_h_i_b_i;
+  struct GNUNET_CRYPTO_EccPoint prod_h_i_b_i;
 
   /**
    * How many elements will be supplied in total from the client.
@@ -213,8 +213,6 @@ free_element_cb (void *cls,
 static void
 destroy_service_session (struct BobServiceSession *s)
 {
-  unsigned int i;
-
   if (GNUNET_YES == s->in_destroy)
     return;
   s->in_destroy = GNUNET_YES;
@@ -245,21 +243,9 @@ destroy_service_session (struct BobServiceSession *s)
   }
   if (NULL != s->sorted_elements)
   {
-    for (i = 0; i < s->used_element_count; i++)
-      gcry_mpi_release (s->sorted_elements[i].value);
     GNUNET_free (s->sorted_elements);
     s->sorted_elements = NULL;
   }
-  if (NULL != s->prod_g_i_b_i)
-  {
-    gcry_mpi_point_release (s->prod_g_i_b_i);
-    s->prod_g_i_b_i = NULL;
-  }
-  if (NULL != s->prod_h_i_b_i)
-  {
-    gcry_mpi_point_release (s->prod_h_i_b_i);
-    s->prod_h_i_b_i = NULL;
-  }
   if (NULL != s->port)
   {
     GNUNET_CADET_close_port (s->port);
@@ -364,14 +350,8 @@ transmit_bobs_cryptodata_message (struct BobServiceSession 
*s)
   e = GNUNET_MQ_msg (msg,
                      GNUNET_MESSAGE_TYPE_SCALARPRODUCT_ECC_BOB_CRYPTODATA);
   msg->contained_element_count = htonl (2);
-  if (NULL != s->prod_g_i_b_i)
-    GNUNET_CRYPTO_ecc_point_to_bin (edc,
-                                    s->prod_g_i_b_i,
-                                    &msg->prod_g_i_b_i);
-  if (NULL != s->prod_h_i_b_i)
-    GNUNET_CRYPTO_ecc_point_to_bin (edc,
-                                    s->prod_h_i_b_i,
-                                    &msg->prod_h_i_b_i);
+  msg->prod_g_i_b_i = s->prod_g_i_b_i;
+  msg->prod_h_i_b_i = s->prod_h_i_b_i;
   GNUNET_MQ_notify_sent (e,
                          &bob_cadet_done_cb,
                          s);
@@ -384,10 +364,9 @@ transmit_bobs_cryptodata_message (struct BobServiceSession 
*s)
  * Iterator to copy over messages from the hash map
  * into an array for sorting.
  *
- * @param cls the `struct BobServiceSession *`
+ * @param cls the `struct AliceServiceSession *`
  * @param key the key (unused)
  * @param value the `struct GNUNET_SCALARPRODUCT_Element *`
- * TODO: code duplication with Alice!
  */
 static int
 copy_element_cb (void *cls,
@@ -396,17 +375,10 @@ copy_element_cb (void *cls,
 {
   struct BobServiceSession *s = cls;
   struct GNUNET_SCALARPRODUCT_Element *e = value;
-  gcry_mpi_t mval;
-  int64_t val;
-
-  mval = gcry_mpi_new (0);
-  val = (int64_t) GNUNET_ntohll (e->value);
-  if (0 > val)
-    gcry_mpi_sub_ui (mval, mval, -val);
-  else
-    gcry_mpi_add_ui (mval, mval, val);
-  s->sorted_elements [s->used_element_count].value = mval;
-  s->sorted_elements [s->used_element_count].key = &e->key;
+
+  s->sorted_elements[s->used_element_count].value = (int64_t) GNUNET_ntohll (
+    e->value);
+  s->sorted_elements[s->used_element_count].key = &e->key;
   s->used_element_count++;
   return GNUNET_OK;
 }
@@ -490,13 +462,10 @@ handle_alices_cryptodata_message (void *cls,
   const struct GNUNET_CRYPTO_EccPoint *payload;
   uint32_t contained_elements;
   unsigned int max;
-  unsigned int i;
-  const struct MpiElement *b_i;
-  gcry_mpi_point_t tmp;
-  gcry_mpi_point_t g_i;
-  gcry_mpi_point_t h_i;
-  gcry_mpi_point_t g_i_b_i;
-  gcry_mpi_point_t h_i_b_i;
+  const struct GNUNET_CRYPTO_EccPoint *g_i;
+  const struct GNUNET_CRYPTO_EccPoint *h_i;
+  struct GNUNET_CRYPTO_EccPoint g_i_b_i;
+  struct GNUNET_CRYPTO_EccPoint h_i_b_i;
 
   contained_elements = ntohl (msg->contained_element_count);
   max = GNUNET_CONTAINER_multihashmap_size (s->intersected_elements);
@@ -522,21 +491,29 @@ handle_alices_cryptodata_message (void *cls,
               (unsigned int) contained_elements);
   payload = (const struct GNUNET_CRYPTO_EccPoint *) &msg[1];
 
-  for (i = 0; i < contained_elements; i++)
+  for (unsigned int i = 0; i < contained_elements; i++)
   {
-    b_i = &s->sorted_elements[i + s->cadet_received_element_count];
-    g_i = GNUNET_CRYPTO_ecc_bin_to_point (edc,
-                                          &payload[i * 2]);
-    g_i_b_i = GNUNET_CRYPTO_ecc_pmul_mpi (edc,
-                                          g_i,
-                                          b_i->value);
-    gcry_mpi_point_release (g_i);
-    h_i = GNUNET_CRYPTO_ecc_bin_to_point (edc,
-                                          &payload[i * 2 + 1]);
-    h_i_b_i = GNUNET_CRYPTO_ecc_pmul_mpi (edc,
-                                          h_i,
-                                          b_i->value);
-    gcry_mpi_point_release (h_i);
+    int64_t val = s->sorted_elements[i + 
s->cadet_received_element_count].value;
+    struct GNUNET_CRYPTO_EccScalar vali;
+
+    GNUNET_assert (INT64_MIN != val);
+    GNUNET_CRYPTO_ecc_scalar_from_int (val > 0 ? val : -val,
+                                       &vali);
+    if (val < 0)
+      crypto_core_ed25519_scalar_negate (vali.v,
+                                         vali.v);
+    g_i = &payload[i * 2];
+    /* g_i_b_i = g_i^vali */
+    GNUNET_assert (GNUNET_OK ==
+                   GNUNET_CRYPTO_ecc_pmul_mpi (g_i,
+                                               &vali,
+                                               &g_i_b_i));
+    h_i = &payload[i * 2 + 1];
+    /* h_i_b_i = h_i^vali */
+    GNUNET_assert (GNUNET_OK ==
+                   GNUNET_CRYPTO_ecc_pmul_mpi (h_i,
+                                               &vali,
+                                               &h_i_b_i));
     if (0 == i + s->cadet_received_element_count)
     {
       /* first iteration, nothing to add */
@@ -546,18 +523,14 @@ handle_alices_cryptodata_message (void *cls,
     else
     {
       /* further iterations, cummulate resulting value */
-      tmp = GNUNET_CRYPTO_ecc_add (edc,
-                                   s->prod_g_i_b_i,
-                                   g_i_b_i);
-      gcry_mpi_point_release (s->prod_g_i_b_i);
-      gcry_mpi_point_release (g_i_b_i);
-      s->prod_g_i_b_i = tmp;
-      tmp = GNUNET_CRYPTO_ecc_add (edc,
-                                   s->prod_h_i_b_i,
-                                   h_i_b_i);
-      gcry_mpi_point_release (s->prod_h_i_b_i);
-      gcry_mpi_point_release (h_i_b_i);
-      s->prod_h_i_b_i = tmp;
+      GNUNET_assert (GNUNET_OK ==
+                     GNUNET_CRYPTO_ecc_add (&s->prod_g_i_b_i,
+                                            &g_i_b_i,
+                                            &s->prod_g_i_b_i));
+      GNUNET_assert (GNUNET_OK ==
+                     GNUNET_CRYPTO_ecc_add (&s->prod_h_i_b_i,
+                                            &h_i_b_i,
+                                            &s->prod_h_i_b_i));
     }
   }
   s->cadet_received_element_count += contained_elements;
@@ -747,10 +720,9 @@ cb_channel_incoming (void *cls,
  * @return #GNUNET_OK if @a msg is well-formed
  */
 static int
-check_bob_client_message_multipart (void *cls,
-                                    const struct
-                                    ComputationBobCryptodataMultipartMessage *
-                                    msg)
+check_bob_client_message_multipart (
+  void *cls,
+  const struct ComputationBobCryptodataMultipartMessage *msg)
 {
   struct BobServiceSession *s = cls;
   uint32_t contained_count;
@@ -781,10 +753,9 @@ check_bob_client_message_multipart (void *cls,
  * @param msg the actual message
  */
 static void
-handle_bob_client_message_multipart (void *cls,
-                                     const struct
-                                     ComputationBobCryptodataMultipartMessage *
-                                     msg)
+handle_bob_client_message_multipart (
+  void *cls,
+  const struct ComputationBobCryptodataMultipartMessage *msg)
 {
   struct BobServiceSession *s = cls;
   uint32_t contained_count;
diff --git a/src/scalarproduct/perf_scalarproduct.sh 
b/src/scalarproduct/perf_scalarproduct.sh
index a7935873e..b15465c9a 100755
--- a/src/scalarproduct/perf_scalarproduct.sh
+++ b/src/scalarproduct/perf_scalarproduct.sh
@@ -1,7 +1,7 @@
 #!/bin/bash
 # Computes a simple scalar product, with configurable vector size.
 #
-# Some results (wall-clock for Alice+Bob, single-core, i7):
+# Some results (wall-clock for Alice+Bob, single-core, i7, libgcrypt):
 # SIZE   2048-H(s)  2048-O(s)    1024-O(s)      ECC-2^20-H(s)  ECC-2^28-H(s)
 #  25     10          14            3              2               29
 #  50     17          21            5              2               29
@@ -11,8 +11,21 @@
 # 800                304           32             OOR              33
 
 # Bandwidth (including set intersection):
-#              RSA-2048       ECC
-# 800:         3846 kb       70 kb
+#              RSA-1024       RSA-2048       ECC
+# 800:           629 kb        1234 kb       65 kb
+#
+# LIBSODIUM, AMD Threadripper 1950:
+#
+# SIZE              2048-O(s)    1024-O(s)      ECC-2^20-H(s)  ECC-2^28-H(s)
+#  25                 4.3          0.7             0.129          4.233
+#  50                 7.7          1.2             0.143          4.267
+# 100                10.3          2.4             0.163          4.282
+# 200                19.8          3.0             0.192          4.326
+# 400                35.9          6.0             0.253          4.358
+# 800                73.7         12.6             0.379          4.533
+
+#
+#
 # Configure benchmark size:
 SIZE=800
 #
diff --git a/src/scalarproduct/scalarproduct_api.c 
b/src/scalarproduct/scalarproduct_api.c
index b2a90c222..4ac39614a 100644
--- a/src/scalarproduct/scalarproduct_api.c
+++ b/src/scalarproduct/scalarproduct_api.c
@@ -42,14 +42,10 @@
  * @param status processing status code
  */
 typedef void
-(*GNUNET_SCALARPRODUCT_ResponseMessageHandler) (struct
-                                                
GNUNET_SCALARPRODUCT_ComputationHandle
-                                                *h,
-                                                const struct
-                                                ClientResponseMessage *msg,
-                                                enum
-                                                
GNUNET_SCALARPRODUCT_ResponseStatus
-                                                status);
+(*GNUNET_SCALARPRODUCT_ResponseMessageHandler) (
+  struct GNUNET_SCALARPRODUCT_ComputationHandle *h,
+  const struct ClientResponseMessage *msg,
+  enum GNUNET_SCALARPRODUCT_ResponseStatus status);
 
 
 /**
@@ -172,13 +168,12 @@ check_unique (const struct GNUNET_SCALARPRODUCT_Element 
*elements,
               uint32_t element_count)
 {
   struct GNUNET_CONTAINER_MultiHashMap *map;
-  uint32_t i;
   int ok;
 
   ok = GNUNET_OK;
   map = GNUNET_CONTAINER_multihashmap_create (2 * element_count,
                                               GNUNET_YES);
-  for (i = 0; i < element_count; i++)
+  for (uint32_t i = 0; i < element_count; i++)
     if (GNUNET_OK !=
         GNUNET_CONTAINER_multihashmap_put (map,
                                            &elements[i].key,
@@ -227,16 +222,13 @@ mq_error_handler (void *cls,
  * @return a new handle for this computation
  */
 struct GNUNET_SCALARPRODUCT_ComputationHandle *
-GNUNET_SCALARPRODUCT_accept_computation (const struct
-                                         GNUNET_CONFIGURATION_Handle *cfg,
-                                         const struct
-                                         GNUNET_HashCode *session_key,
-                                         const struct
-                                         GNUNET_SCALARPRODUCT_Element 
*elements,
-                                         uint32_t element_count,
-                                         
GNUNET_SCALARPRODUCT_ContinuationWithStatus
-                                         cont,
-                                         void *cont_cls)
+GNUNET_SCALARPRODUCT_accept_computation (
+  const struct GNUNET_CONFIGURATION_Handle *cfg,
+  const struct GNUNET_HashCode *session_key,
+  const struct GNUNET_SCALARPRODUCT_Element *elements,
+  uint32_t element_count,
+  GNUNET_SCALARPRODUCT_ContinuationWithStatus cont,
+  void *cont_cls)
 {
   struct GNUNET_SCALARPRODUCT_ComputationHandle *h
     = GNUNET_new (struct GNUNET_SCALARPRODUCT_ComputationHandle);
@@ -389,16 +381,14 @@ process_result_message (struct 
GNUNET_SCALARPRODUCT_ComputationHandle *h,
  * @return a new handle for this computation
  */
 struct GNUNET_SCALARPRODUCT_ComputationHandle *
-GNUNET_SCALARPRODUCT_start_computation (const struct
-                                        GNUNET_CONFIGURATION_Handle *cfg,
-                                        const struct
-                                        GNUNET_HashCode *session_key,
-                                        const struct GNUNET_PeerIdentity *peer,
-                                        const struct
-                                        GNUNET_SCALARPRODUCT_Element *elements,
-                                        uint32_t element_count,
-                                        GNUNET_SCALARPRODUCT_DatumProcessor 
cont,
-                                        void *cont_cls)
+GNUNET_SCALARPRODUCT_start_computation (
+  const struct GNUNET_CONFIGURATION_Handle *cfg,
+  const struct GNUNET_HashCode *session_key,
+  const struct GNUNET_PeerIdentity *peer,
+  const struct GNUNET_SCALARPRODUCT_Element *elements,
+  uint32_t element_count,
+  GNUNET_SCALARPRODUCT_DatumProcessor cont,
+  void *cont_cls)
 {
   struct GNUNET_SCALARPRODUCT_ComputationHandle *h
     = GNUNET_new (struct GNUNET_SCALARPRODUCT_ComputationHandle);
diff --git a/src/scalarproduct/test_ecc_scalarproduct.c 
b/src/scalarproduct/test_ecc_scalarproduct.c
index eced3ef6a..85460cb05 100644
--- a/src/scalarproduct/test_ecc_scalarproduct.c
+++ b/src/scalarproduct/test_ecc_scalarproduct.c
@@ -45,20 +45,12 @@ test_sp (const unsigned int *avec,
          const unsigned int *bvec)
 {
   unsigned int len;
-  unsigned int i;
-  gcry_mpi_t a;
-  gcry_mpi_t a_inv;
-  gcry_mpi_t ri;
-  gcry_mpi_t val;
-  gcry_mpi_t ria;
-  gcry_mpi_t tmp;
-  gcry_mpi_point_t *g;
-  gcry_mpi_point_t *h;
-  gcry_mpi_point_t pg;
-  gcry_mpi_point_t ph;
-  gcry_mpi_point_t pgi;
-  gcry_mpi_point_t gsp;
-  int sp;
+  struct GNUNET_CRYPTO_EccScalar a;
+  struct GNUNET_CRYPTO_EccScalar a_neg;
+  struct GNUNET_CRYPTO_EccPoint *g;
+  struct GNUNET_CRYPTO_EccPoint *h;
+  struct GNUNET_CRYPTO_EccPoint pg;
+  struct GNUNET_CRYPTO_EccPoint ph;
 
   /* determine length */
   for (len = 0; 0 != avec[len]; len++)
@@ -67,90 +59,133 @@ test_sp (const unsigned int *avec,
     return 0;
 
   /* Alice */
-  GNUNET_CRYPTO_ecc_rnd_mpi (edc,
-                             &a, &a_inv);
+  GNUNET_CRYPTO_ecc_rnd_mpi (&a,
+                             &a_neg);
   g = GNUNET_new_array (len,
-                        gcry_mpi_point_t);
+                        struct GNUNET_CRYPTO_EccPoint);
   h = GNUNET_new_array (len,
-                        gcry_mpi_point_t);
-  ria = gcry_mpi_new (0);
-  tmp = gcry_mpi_new (0);
-  for (i = 0; i < len; i++)
+                        struct GNUNET_CRYPTO_EccPoint);
+  for (unsigned int i = 0; i < len; i++)
   {
-    ri = GNUNET_CRYPTO_ecc_random_mod_n (edc);
-    g[i] = GNUNET_CRYPTO_ecc_dexp_mpi (edc,
-                                       ri);
-    /* ria = ri * a */
-    gcry_mpi_mul (ria,
-                  ri,
-                  a);
+    struct GNUNET_CRYPTO_EccScalar tmp;
+    struct GNUNET_CRYPTO_EccScalar ri;
+    struct GNUNET_CRYPTO_EccScalar ria;
+
+    GNUNET_CRYPTO_ecc_random_mod_n (&ri);
+    GNUNET_assert (GNUNET_OK ==
+                   GNUNET_CRYPTO_ecc_dexp_mpi (&ri,
+                                               &g[i]));
+    /* ria = ri * a mod L, where L is the order of the main subgroup */
+    crypto_core_ed25519_scalar_mul (ria.v,
+                                    ri.v,
+                                    a.v);
     /* tmp = ria + avec[i] */
-    gcry_mpi_add_ui (tmp,
-                     ria,
-                     avec[i]);
-    h[i] = GNUNET_CRYPTO_ecc_dexp_mpi (edc,
-                                       tmp);
+    {
+      int64_t val = avec[i];
+      struct GNUNET_CRYPTO_EccScalar vali;
+
+      GNUNET_assert (INT64_MIN != val);
+      GNUNET_CRYPTO_ecc_scalar_from_int (val > 0 ? val : -val,
+                                         &vali);
+      if (val > 0)
+        crypto_core_ed25519_scalar_add (tmp.v,
+                                        ria.v,
+                                        vali.v);
+      else
+        crypto_core_ed25519_scalar_sub (tmp.v,
+                                        ria.v,
+                                        vali.v);
+    }
+    /* h[i] = g^tmp = g^{ria + avec[i]} */
+    GNUNET_assert (GNUNET_OK ==
+                   GNUNET_CRYPTO_ecc_dexp_mpi (&tmp,
+                                               &h[i]));
   }
-  gcry_mpi_release (ria);
-  gcry_mpi_release (tmp);
 
   /* Bob */
-  val = gcry_mpi_new (0);
-  gcry_mpi_set_ui (val, bvec[0]);
-  pg = GNUNET_CRYPTO_ecc_pmul_mpi (edc,
-                                   g[0],
-                                   val);
-  ph = GNUNET_CRYPTO_ecc_pmul_mpi (edc,
-                                   h[0],
-                                   val);
-  for (i = 1; i < len; i++)
+  for (unsigned int i = 0; i < len; i++)
   {
-    gcry_mpi_point_t m;
-    gcry_mpi_point_t tmp;
-
-    gcry_mpi_set_ui (val, bvec[i]);
-    m = GNUNET_CRYPTO_ecc_pmul_mpi (edc,
-                                    g[i],
-                                    val);
-    tmp = GNUNET_CRYPTO_ecc_add (edc,
-                                 m,
-                                 pg);
-    gcry_mpi_point_release (m);
-    gcry_mpi_point_release (pg);
-    gcry_mpi_point_release (g[i]);
-    pg = tmp;
-
-    m = GNUNET_CRYPTO_ecc_pmul_mpi (edc,
-                                    h[i],
-                                    val);
-    tmp = GNUNET_CRYPTO_ecc_add (edc,
-                                 m,
-                                 ph);
-    gcry_mpi_point_release (m);
-    gcry_mpi_point_release (ph);
-    gcry_mpi_point_release (h[i]);
-    ph = tmp;
+    struct GNUNET_CRYPTO_EccPoint gm;
+    struct GNUNET_CRYPTO_EccPoint hm;
+
+    {
+      int64_t val = bvec[i];
+      struct GNUNET_CRYPTO_EccScalar vali;
+
+      GNUNET_assert (INT64_MIN != val);
+      GNUNET_CRYPTO_ecc_scalar_from_int (val > 0 ? val : -val,
+                                         &vali);
+      if (val < 0)
+        crypto_core_ed25519_scalar_negate (vali.v,
+                                           vali.v);
+      /* gm = g[i]^vali */
+      GNUNET_assert (GNUNET_OK ==
+                     GNUNET_CRYPTO_ecc_pmul_mpi (&g[i],
+                                                 &vali,
+                                                 &gm));
+      /* hm = h[i]^vali */
+      GNUNET_assert (GNUNET_OK ==
+                     GNUNET_CRYPTO_ecc_pmul_mpi (&h[i],
+                                                 &vali,
+                                                 &hm));
+    }
+    if (0 != i)
+    {
+      /* pg += gm */
+      GNUNET_assert (GNUNET_OK ==
+                     GNUNET_CRYPTO_ecc_add (&gm,
+                                            &pg,
+                                            &pg));
+      /* ph += hm */
+      GNUNET_assert (GNUNET_OK ==
+                     GNUNET_CRYPTO_ecc_add (&hm,
+                                            &ph,
+                                            &ph));
+    }
+    else
+    {
+      pg = gm;
+      ph = hm;
+    }
   }
-  gcry_mpi_release (val);
   GNUNET_free (g);
   GNUNET_free (h);
 
   /* Alice */
-  pgi = GNUNET_CRYPTO_ecc_pmul_mpi (edc,
-                                    pg,
-                                    a_inv);
-  gsp = GNUNET_CRYPTO_ecc_add (edc,
-                               pgi,
-                               ph);
-  gcry_mpi_point_release (pgi);
-  gcry_mpi_point_release (ph);
-  sp = GNUNET_CRYPTO_ecc_dlog (edc,
-                               gsp);
-  gcry_mpi_point_release (gsp);
-  return sp;
+  {
+    struct GNUNET_CRYPTO_EccPoint pgi;
+    struct GNUNET_CRYPTO_EccPoint gsp;
+
+    /* pgi = pg^inv */
+    GNUNET_assert (GNUNET_OK ==
+                   GNUNET_CRYPTO_ecc_pmul_mpi (&pg,
+                                               &a_neg,
+                                               &pgi));
+    /* gsp = pgi + ph */
+    GNUNET_assert (GNUNET_OK ==
+                   GNUNET_CRYPTO_ecc_add (&pgi,
+                                          &ph,
+                                          &gsp));
+    return GNUNET_CRYPTO_ecc_dlog (edc,
+                                   &gsp);
+  }
 }
 
 
+/**
+ * Macro that checks that @a want is equal to @a have and
+ * if not returns with a failure code.
+ */
+#define CHECK(want,have) do { \
+    if (want != have) {         \
+      GNUNET_break (0);         \
+      GNUNET_log (GNUNET_ERROR_TYPE_ERROR, \
+                  "Wanted %d, got %d\n", want, have);   \
+      GNUNET_CRYPTO_ecc_dlog_release (edc); \
+      return 1; \
+    } } while (0)
+
+
 int
 main (int argc, char *argv[])
 {
@@ -163,12 +198,12 @@ main (int argc, char *argv[])
                     "WARNING",
                     NULL);
   edc = GNUNET_CRYPTO_ecc_dlog_prepare (128, 128);
-  GNUNET_assert (2 == test_sp (v11, v11));
-  GNUNET_assert (4 == test_sp (v22, v11));
-  GNUNET_assert (8 == test_sp (v35, v11));
-  GNUNET_assert (26 == test_sp (v35, v24));
-  GNUNET_assert (26 == test_sp (v24, v35));
-  GNUNET_assert (16 == test_sp (v22, v35));
+  CHECK (2, test_sp (v11, v11));
+  CHECK (4, test_sp (v22, v11));
+  CHECK (8, test_sp (v35, v11));
+  CHECK (26, test_sp (v35, v24));
+  CHECK (26, test_sp (v24, v35));
+  CHECK (16, test_sp (v22, v35));
   GNUNET_CRYPTO_ecc_dlog_release (edc);
   return 0;
 }
diff --git a/src/scalarproduct/test_scalarproduct_negative.sh 
b/src/scalarproduct/test_scalarproduct_negative.sh
index b08e4527f..459406836 100755
--- a/src/scalarproduct/test_scalarproduct_negative.sh
+++ b/src/scalarproduct/test_scalarproduct_negative.sh
@@ -5,6 +5,9 @@ INPUTALICE="-k CCC -e 'AB,10;RO,-3;FL,-3;LOL,1;'"
 INPUTBOB="-k CCC -e 'BC,-20000;RO,1000;FL,100;LOL,24;'"
 
 # necessary to make the testing prefix deterministic, so we can access the 
config files
+unset XDG_DATA_HOME
+unset XDG_CONFIG_HOME
+
 PREFIX=/tmp/test-scalarproduct`date +%H%M%S`
 
 # where can we find the peers config files?
diff --git a/src/util/Makefile.am b/src/util/Makefile.am
index e2614e5e3..f05fc7bf7 100644
--- a/src/util/Makefile.am
+++ b/src/util/Makefile.am
@@ -460,6 +460,7 @@ if HAVE_NOLIBGCRYPT19
 test_crypto_ecc_dlog_SOURCES = \
  test_crypto_ecc_dlog.c
 test_crypto_ecc_dlog_LDADD = \
+ -lsodium \
  libgnunetutil.la \
  $(LIBGCRYPT_LIBS)
 endif
@@ -610,7 +611,7 @@ perf_crypto_ecc_dlog_SOURCES = \
  perf_crypto_ecc_dlog.c
 perf_crypto_ecc_dlog_LDADD = \
  libgnunetutil.la \
- -lgcrypt
+ -lsodium
 endif
 
 perf_crypto_rsa_SOURCES = \
diff --git a/src/util/crypto_ecc_dlog.c b/src/util/crypto_ecc_dlog.c
index 408d64e58..916acd9dd 100644
--- a/src/util/crypto_ecc_dlog.c
+++ b/src/util/crypto_ecc_dlog.c
@@ -31,35 +31,6 @@
 #include "gnunet_container_lib.h"
 
 
-/**
- * Name of the curve we are using.  Note that we have hard-coded
- * structs that use 256 bits, so using a bigger curve will require
- * changes that break stuff badly.  The name of the curve given here
- * must be agreed by all peers and be supported by libgcrypt.
- */
-#define CURVE "Ed25519"
-
-
-/**
- *
- */
-static void
-extract_pk (gcry_mpi_point_t pt,
-            gcry_ctx_t ctx,
-            struct GNUNET_PeerIdentity *pid)
-{
-  gcry_mpi_t q_y;
-
-  GNUNET_assert (0 == gcry_mpi_ec_set_point ("q", pt, ctx));
-  q_y = gcry_mpi_ec_get_mpi ("q@eddsa", ctx, 0);
-  GNUNET_assert (q_y);
-  GNUNET_CRYPTO_mpi_print_unsigned (pid->public_key.q_y,
-                                    sizeof(pid->public_key.q_y),
-                                    q_y);
-  gcry_mpi_release (q_y);
-}
-
-
 /**
  * Internal structure used to cache pre-calculated values for DLOG calculation.
  */
@@ -90,160 +61,105 @@ struct GNUNET_CRYPTO_EccDlogContext
 };
 
 
-/**
- * Convert point value to binary representation.
- *
- * @param edc calculation context for ECC operations
- * @param point computational point representation
- * @param[out] bin binary point representation
- */
-void
-GNUNET_CRYPTO_ecc_point_to_bin (struct GNUNET_CRYPTO_EccDlogContext *edc,
-                                gcry_mpi_point_t point,
-                                struct GNUNET_CRYPTO_EccPoint *bin)
-{
-  gcry_mpi_t q_y;
-
-  GNUNET_assert (0 == gcry_mpi_ec_set_point ("q", point, edc->ctx));
-  q_y = gcry_mpi_ec_get_mpi ("q@eddsa", edc->ctx, 0);
-  GNUNET_assert (q_y);
-  GNUNET_CRYPTO_mpi_print_unsigned (bin->q_y,
-                                    sizeof(bin->q_y),
-                                    q_y);
-  gcry_mpi_release (q_y);
-}
-
-
-/**
- * Convert binary representation of a point to computational representation.
- *
- * @param edc calculation context for ECC operations
- * @param bin binary point representation
- * @return computational representation
- */
-gcry_mpi_point_t
-GNUNET_CRYPTO_ecc_bin_to_point (struct GNUNET_CRYPTO_EccDlogContext *edc,
-                                const struct GNUNET_CRYPTO_EccPoint *bin)
-{
-  gcry_sexp_t pub_sexpr;
-  gcry_ctx_t ctx;
-  gcry_mpi_point_t q;
-
-  (void) edc;
-  if (0 != gcry_sexp_build (&pub_sexpr, NULL,
-                            "(public-key(ecc(curve " CURVE ")(q %b)))",
-                            (int) sizeof(bin->q_y),
-                            bin->q_y))
-  {
-    GNUNET_break (0);
-    return NULL;
-  }
-  GNUNET_assert (0 == gcry_mpi_ec_new (&ctx, pub_sexpr, NULL));
-  gcry_sexp_release (pub_sexpr);
-  q = gcry_mpi_ec_get_point ("q", ctx, 0);
-  gcry_ctx_release (ctx);
-  return q;
-}
-
-
-/**
- * Do pre-calculation for ECC discrete logarithm for small factors.
- *
- * @param max maximum value the factor can be
- * @param mem memory to use (should be smaller than @a max), must not be zero.
- * @return NULL on error
- */
 struct GNUNET_CRYPTO_EccDlogContext *
 GNUNET_CRYPTO_ecc_dlog_prepare (unsigned int max,
                                 unsigned int mem)
 {
   struct GNUNET_CRYPTO_EccDlogContext *edc;
-  unsigned int K = ((max + (mem - 1)) / mem);
-  gcry_mpi_point_t g;
-  struct GNUNET_PeerIdentity key;
-  gcry_mpi_point_t gKi;
-  gcry_mpi_t fact;
-  gcry_mpi_t n;
-  unsigned int i;
+  int K = ((max + (mem - 1)) / mem);
 
   GNUNET_assert (max < INT32_MAX);
   edc = GNUNET_new (struct GNUNET_CRYPTO_EccDlogContext);
   edc->max = max;
   edc->mem = mem;
-
   edc->map = GNUNET_CONTAINER_multipeermap_create (mem * 2,
                                                    GNUNET_NO);
-
-  GNUNET_assert (0 == gcry_mpi_ec_new (&edc->ctx,
-                                       NULL,
-                                       CURVE));
-  g = gcry_mpi_ec_get_point ("g", edc->ctx, 0);
-  GNUNET_assert (NULL != g);
-  fact = gcry_mpi_new (0);
-  gKi = gcry_mpi_point_new (0);
-  for (i = 0; i <= mem; i++)
+  for (int i = -(int) mem; i <= (int) mem; i++)
   {
-    gcry_mpi_set_ui (fact, i * K);
-    gcry_mpi_ec_mul (gKi, fact, g, edc->ctx);
-    extract_pk (gKi, edc->ctx, &key);
+    struct GNUNET_CRYPTO_EccScalar Ki;
+    struct GNUNET_PeerIdentity key;
+
+    GNUNET_CRYPTO_ecc_scalar_from_int (K * i,
+                                       &Ki);
+    if (0 == i) /* libsodium does not like to multiply with zero */
+      GNUNET_assert (
+        0 ==
+        crypto_core_ed25519_sub ((unsigned char *) &key,
+                                 (unsigned char *) &key,
+                                 (unsigned char *) &key));
+    else
+      GNUNET_assert (
+        0 ==
+        crypto_scalarmult_ed25519_base_noclamp ((unsigned char*) &key,
+                                                Ki.v));
+    GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+                "K*i: %d (mem=%u, i=%d) => %s\n",
+                K * i,
+                mem,
+                i,
+                GNUNET_i2s (&key));
     GNUNET_assert (GNUNET_OK ==
                    GNUNET_CONTAINER_multipeermap_put (edc->map,
                                                       &key,
                                                       (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;
 }
 
 
-/**
- * Calculate ECC discrete logarithm for small factors.
- *
- * @param edc precalculated values, determine range of factors
- * @param input point on the curve to factor
- * @return INT_MAX if dlog failed, otherwise the factor
- */
 int
 GNUNET_CRYPTO_ecc_dlog (struct GNUNET_CRYPTO_EccDlogContext *edc,
-                        gcry_mpi_point_t input)
+                        const struct GNUNET_CRYPTO_EccPoint *input)
 {
   unsigned int K = ((edc->max + (edc->mem - 1)) / edc->mem);
-  gcry_mpi_point_t g;
-  struct GNUNET_PeerIdentity key;
-  gcry_mpi_point_t q;
-  unsigned int i;
   int res;
-  void *retp;
-
-  g = gcry_mpi_ec_get_point ("g", edc->ctx, 0);
-  GNUNET_assert (NULL != g);
-  q = gcry_mpi_point_new (0);
+  struct GNUNET_CRYPTO_EccPoint g;
+  struct GNUNET_CRYPTO_EccPoint q;
+  struct GNUNET_CRYPTO_EccPoint nq;
 
+  {
+    struct GNUNET_CRYPTO_EccScalar fact;
+
+    memset (&fact,
+            0,
+            sizeof (fact));
+    sodium_increment (fact.v,
+                      sizeof (fact.v));
+    GNUNET_assert (0 ==
+                   crypto_scalarmult_ed25519_base_noclamp (g.v,
+                                                           fact.v));
+  }
+  /* make compiler happy: initialize q and nq, technically not needed! */
+  memset (&q,
+          0,
+          sizeof (q));
+  memset (&nq,
+          0,
+          sizeof (nq));
   res = INT_MAX;
-  for (i = 0; i <= edc->max / edc->mem; i++)
+  for (unsigned int i = 0; i <= edc->max / edc->mem; i++)
   {
+    struct GNUNET_PeerIdentity key;
+    void *retp;
+
+    GNUNET_assert (sizeof (key) == crypto_scalarmult_BYTES);
     if (0 == i)
-      extract_pk (input, edc->ctx, &key);
+    {
+      memcpy (&key,
+              input,
+              sizeof (key));
+    }
     else
-      extract_pk (q, edc->ctx, &key);
+    {
+      memcpy (&key,
+              &q,
+              sizeof (key));
+    }
+    GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+                "Trying offset i=%u): %s\n",
+                i,
+                GNUNET_i2s (&key));
     retp = GNUNET_CONTAINER_multipeermap_get (edc->map,
                                               &key);
     if (NULL != retp)
@@ -257,248 +173,163 @@ GNUNET_CRYPTO_ecc_dlog (struct 
GNUNET_CRYPTO_EccDlogContext *edc,
       break;
     /* q = q + g */
     if (0 == i)
-      gcry_mpi_ec_add (q, input, g, edc->ctx);
+    {
+      GNUNET_assert (0 ==
+                     crypto_core_ed25519_add (q.v,
+                                              input->v,
+                                              g.v));
+    }
     else
-      gcry_mpi_ec_add (q, q, g, edc->ctx);
+    {
+      GNUNET_assert (0 ==
+                     crypto_core_ed25519_add (q.v,
+                                              q.v,
+                                              g.v));
+    }
   }
-  gcry_mpi_point_release (g);
-  gcry_mpi_point_release (q);
-
   return res;
 }
 
 
-/**
- * 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)
+void
+GNUNET_CRYPTO_ecc_random_mod_n (struct GNUNET_CRYPTO_EccScalar *r)
 {
-  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;
+  crypto_core_ed25519_scalar_random (r->v);
 }
 
 
-/**
- * Release precalculated values.
- *
- * @param edc dlog context
- */
 void
 GNUNET_CRYPTO_ecc_dlog_release (struct GNUNET_CRYPTO_EccDlogContext *edc)
 {
-  gcry_ctx_release (edc->ctx);
   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)
+void
+GNUNET_CRYPTO_ecc_dexp (int val,
+                        struct GNUNET_CRYPTO_EccPoint *r)
 {
-  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;
+  struct GNUNET_CRYPTO_EccScalar fact;
+
+  GNUNET_CRYPTO_ecc_scalar_from_int (val,
+                                     &fact);
+  crypto_scalarmult_ed25519_base_noclamp (r->v,
+                                          fact.v);
 }
 
 
-/**
- * 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)
+enum GNUNET_GenericReturnValue
+GNUNET_CRYPTO_ecc_dexp_mpi (const struct GNUNET_CRYPTO_EccScalar *val,
+                            struct GNUNET_CRYPTO_EccPoint *r)
 {
-  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;
+  if (0 ==
+      crypto_scalarmult_ed25519_base_noclamp (r->v,
+                                              val->v))
+    return GNUNET_OK;
+  return GNUNET_SYSERR;
 }
 
 
-/**
- * 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)
+enum GNUNET_GenericReturnValue
+GNUNET_CRYPTO_ecc_add (const struct GNUNET_CRYPTO_EccPoint *a,
+                       const struct GNUNET_CRYPTO_EccPoint *b,
+                       struct GNUNET_CRYPTO_EccPoint *r)
 {
-  gcry_mpi_point_t r;
-
-  r = gcry_mpi_point_new (0);
-  gcry_mpi_ec_add (r, a, b, edc->ctx);
-  return r;
+  if (0 ==
+      crypto_core_ed25519_add (r->v,
+                               a->v,
+                               b->v))
+    return GNUNET_OK;
+  return GNUNET_SYSERR;
 }
 
 
-/**
- * Multiply the point @a p on the elliptic curve by @a val.
- *
- * @param edc calculation context for ECC operations
- * @param p point to multiply
- * @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_pmul_mpi (struct GNUNET_CRYPTO_EccDlogContext *edc,
-                            gcry_mpi_point_t p,
-                            gcry_mpi_t val)
+enum GNUNET_GenericReturnValue
+GNUNET_CRYPTO_ecc_pmul_mpi (const struct GNUNET_CRYPTO_EccPoint *p,
+                            const struct GNUNET_CRYPTO_EccScalar *val,
+                            struct GNUNET_CRYPTO_EccPoint *r)
 {
-  gcry_mpi_point_t r;
-
-  r = gcry_mpi_point_new (0);
-  gcry_mpi_ec_mul (r, val, p, edc->ctx);
-  return r;
+  if (0 ==
+      crypto_scalarmult_ed25519_noclamp (r->v,
+                                         val->v,
+                                         p->v))
+    return GNUNET_OK;
+  return GNUNET_SYSERR;
 }
 
 
-/**
- * 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)
+enum GNUNET_GenericReturnValue
+GNUNET_CRYPTO_ecc_rnd (struct GNUNET_CRYPTO_EccPoint *r,
+                       struct GNUNET_CRYPTO_EccPoint *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);
+  struct GNUNET_CRYPTO_EccScalar s;
+  unsigned char inv_s[crypto_scalarmult_ed25519_SCALARBYTES];
+
+  GNUNET_CRYPTO_ecc_random_mod_n (&s);
+  if (0 !=
+      crypto_scalarmult_ed25519_base_noclamp (r->v,
+                                              s.v))
+    return GNUNET_SYSERR;
+  crypto_core_ed25519_scalar_negate (inv_s,
+                                     s.v);
+  if (0 !=
+      crypto_scalarmult_ed25519_base_noclamp (r_inv->v,
+                                              inv_s))
+    return GNUNET_SYSERR;
+  return GNUNET_OK;
 }
 
 
-/**
- * Obtain a random scalar for point multiplication on the curve and
- * its multiplicative inverse.
- *
- * @param edc calculation context for ECC operations
- * @param[out] r set to a random scalar on the curve
- * @param[out] r_inv set to the multiplicative inverse of @a r
- */
 void
-GNUNET_CRYPTO_ecc_rnd_mpi (struct GNUNET_CRYPTO_EccDlogContext *edc,
-                           gcry_mpi_t *r,
-                           gcry_mpi_t *r_inv)
+GNUNET_CRYPTO_ecc_rnd_mpi (struct GNUNET_CRYPTO_EccScalar *r,
+                           struct GNUNET_CRYPTO_EccScalar *r_neg)
 {
-  gcry_mpi_t n;
-
-  *r = GNUNET_CRYPTO_ecc_random_mod_n (edc);
-  /* r_inv = n - r = - r */
-  *r_inv = gcry_mpi_new (0);
-  n = gcry_mpi_ec_get_mpi ("n", edc->ctx, 1);
-  gcry_mpi_sub (*r_inv, n, *r);
+  GNUNET_CRYPTO_ecc_random_mod_n (r);
+  crypto_core_ed25519_scalar_negate (r_neg->v,
+                                     r->v);
 }
 
 
-/**
- * Free a point value returned by the API.
- *
- * @param p point to free
- */
 void
-GNUNET_CRYPTO_ecc_free (gcry_mpi_point_t p)
+GNUNET_CRYPTO_ecc_scalar_from_int (int64_t val,
+                                   struct GNUNET_CRYPTO_EccScalar *r)
 {
-  gcry_mpi_point_release (p);
+  unsigned char fact[crypto_scalarmult_ed25519_SCALARBYTES];
+  uint64_t valBe;
+
+  GNUNET_assert (sizeof (*r) == sizeof (fact));
+  if (val < 0)
+  {
+    if (INT64_MIN == val)
+      valBe = GNUNET_htonll ((uint64_t) INT64_MAX);
+    else
+      valBe = GNUNET_htonll ((uint64_t) (-val));
+  }
+  else
+  {
+    valBe = GNUNET_htonll ((uint64_t) val);
+  }
+  memset (fact,
+          0,
+          sizeof (fact));
+  for (unsigned int i = 0; i < sizeof (val); i++)
+    fact[i] = ((unsigned char*) &valBe)[sizeof (val) - 1 - i];
+  if (val < 0)
+  {
+    if (INT64_MIN == val)
+      /* See above: fact is one too small, increment now that we can */
+      sodium_increment (fact,
+                        sizeof (fact));
+    crypto_core_ed25519_scalar_negate (r->v,
+                                       fact);
+  }
+  else
+  {
+    memcpy (r,
+            fact,
+            sizeof (fact));
+  }
 }
 
 
diff --git a/src/util/perf_crypto_ecc_dlog.c b/src/util/perf_crypto_ecc_dlog.c
index 8a0e4676b..f32ffbd67 100644
--- a/src/util/perf_crypto_ecc_dlog.c
+++ b/src/util/perf_crypto_ecc_dlog.c
@@ -52,72 +52,88 @@
  */
 #define TEST_ITER 10
 
-/**
- * Range of values to use for MATH tests.
- */
-#define MATH_MAX 500000
-
 
 /**
  * Do some DLOG operations for testing.
  *
  * @param edc context for ECC operations
- * @param do_dlog #GNUNET_YES if we want to actually do the bencharked 
operation
+ * @param do_dlog true if we want to actually do the bencharked operation
  */
 static void
 test_dlog (struct GNUNET_CRYPTO_EccDlogContext *edc,
-           int do_dlog)
+           bool do_dlog)
 {
-  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;
-  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 < TEST_ITER; i++)
+  for (unsigned int i = 0; i < TEST_ITER; i++)
   {
+    struct GNUNET_CRYPTO_EccScalar fact;
+    struct GNUNET_CRYPTO_EccScalar n;
+    struct GNUNET_CRYPTO_EccPoint q;
+    int x;
+
     fprintf (stderr, ".");
     x = GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_WEAK,
                                   MAX_FACT);
+    memset (&n,
+            0,
+            sizeof (n));
+    for (unsigned int j = 0; j < x; j++)
+      sodium_increment (n.v,
+                        sizeof (n.v));
     if (0 == GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_WEAK,
                                        2))
     {
-      gcry_mpi_set_ui (fact, x);
-      gcry_mpi_sub (fact, n, fact);
+      GNUNET_log (GNUNET_ERROR_TYPE_INFO,
+                  "Trying negative %d\n",
+                  -x);
+      crypto_core_ed25519_scalar_negate (fact.v,
+                                         n.v);
       x = -x;
     }
     else
     {
-      gcry_mpi_set_ui (fact, x);
+      GNUNET_log (GNUNET_ERROR_TYPE_INFO,
+                  "Trying positive %d\n",
+                  x);
+      fact = n;
     }
-    gcry_mpi_ec_mul (q, fact, g, ctx);
-    if ((GNUNET_YES == do_dlog) &&
-        (x !=
-         (iret = GNUNET_CRYPTO_ecc_dlog (edc,
-                                         q))))
+    if (0 == x)
     {
-      fprintf (stderr,
-               "DLOG failed for value %d (%d)\n",
-               x,
-               iret);
-      GNUNET_assert (0);
+      /* libsodium does not like to multiply with zero; make sure
+         'q' is a valid point (g) first, then use q = q - q to get
+         the product with zero */
+      sodium_increment (fact.v,
+                        sizeof (fact.v));
+      GNUNET_assert (0 ==
+                     crypto_scalarmult_ed25519_base_noclamp (q.v,
+                                                             fact.v));
+      GNUNET_assert (
+        0 ==
+        crypto_core_ed25519_sub (q.v,
+                                 q.v,
+                                 q.v));
+    }
+    else
+      GNUNET_assert (0 ==
+                     crypto_scalarmult_ed25519_base_noclamp (q.v,
+                                                             fact.v));
+    if (do_dlog)
+    {
+      int iret;
+
+      if (x !=
+          (iret = GNUNET_CRYPTO_ecc_dlog (edc,
+                                          &q)))
+      {
+        GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+                    "DLOG failed for value %d (got: %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");
+  fprintf (stderr,
+           "\n");
 }
 
 
@@ -128,17 +144,6 @@ main (int argc, char *argv[])
   struct GNUNET_TIME_Absolute start;
   struct GNUNET_TIME_Relative delta;
 
-  if (! gcry_check_version ("1.6.0"))
-  {
-    fprintf (stderr,
-             _
-             (
-               "libgcrypt has not the expected version (version %s is 
required).\n"),
-             "1.6.0");
-    return 0;
-  }
-  if (getenv ("GNUNET_GCRYPT_DEBUG"))
-    gcry_control (GCRYCTL_SET_DEBUG_FLAGS, 1u, 0);
   GNUNET_log_setup ("perf-crypto-ecc-dlog",
                     "WARNING",
                     NULL);
@@ -154,10 +159,10 @@ main (int argc, char *argv[])
             (start).rel_value_us / 1000LL, "ms/op");
   start = GNUNET_TIME_absolute_get ();
   /* first do a baseline run without the DLOG */
-  test_dlog (edc, GNUNET_NO);
+  test_dlog (edc, false);
   delta = GNUNET_TIME_absolute_get_duration (start);
   start = GNUNET_TIME_absolute_get ();
-  test_dlog (edc, GNUNET_YES);
+  test_dlog (edc, true);
   delta = GNUNET_TIME_relative_subtract (GNUNET_TIME_absolute_get_duration (
                                            start),
                                          delta);
@@ -165,7 +170,8 @@ main (int argc, char *argv[])
           TEST_ITER,
           GNUNET_STRINGS_relative_time_to_string (delta,
                                                   GNUNET_YES));
-  GAUGER ("UTIL", "ECC DLOG operations",
+  GAUGER ("UTIL",
+          "ECC DLOG operations",
           delta.rel_value_us / 1000LL / TEST_ITER,
           "ms/op");
 
diff --git a/src/util/test_crypto_ecc_dlog.c b/src/util/test_crypto_ecc_dlog.c
index a2c02a94e..51f290d51 100644
--- a/src/util/test_crypto_ecc_dlog.c
+++ b/src/util/test_crypto_ecc_dlog.c
@@ -49,7 +49,7 @@
 /**
  * How many values do we test?
  */
-#define TEST_ITER 10
+#define TEST_ITER 100
 
 /**
  * Range of values to use for MATH tests.
@@ -65,55 +65,76 @@
 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;
-  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 < TEST_ITER; i++)
+  for (unsigned int i = 0; i < TEST_ITER; i++)
   {
+    struct GNUNET_CRYPTO_EccScalar fact;
+    struct GNUNET_CRYPTO_EccScalar n;
+    struct GNUNET_CRYPTO_EccPoint q;
+    int x;
+
     fprintf (stderr, ".");
     x = GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_WEAK,
                                   MAX_FACT);
+    memset (&n,
+            0,
+            sizeof (n));
+    for (unsigned int j = 0; j < x; j++)
+      sodium_increment (n.v,
+                        sizeof (n.v));
     if (0 == GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_WEAK,
                                        2))
     {
-      gcry_mpi_set_ui (fact, x);
-      gcry_mpi_sub (fact, n, fact);
+      GNUNET_log (GNUNET_ERROR_TYPE_INFO,
+                  "Trying negative %d\n",
+                  -x);
+      crypto_core_ed25519_scalar_negate (fact.v,
+                                         n.v);
       x = -x;
     }
     else
     {
-      gcry_mpi_set_ui (fact, x);
+      GNUNET_log (GNUNET_ERROR_TYPE_INFO,
+                  "Trying positive %d\n",
+                  x);
+      fact = n;
     }
-    gcry_mpi_ec_mul (q, fact, g, ctx);
-    if (x !=
-        (iret = GNUNET_CRYPTO_ecc_dlog (edc,
-                                        q)))
+    if (0 == x)
     {
-      fprintf (stderr,
-               "DLOG failed for value %d (%d)\n",
-               x,
-               iret);
-      GNUNET_assert (0);
+      /* libsodium does not like to multiply with zero; make sure
+         'q' is a valid point (g) first, then use q = q - q to get
+         the product with zero */
+      sodium_increment (fact.v,
+                        sizeof (fact.v));
+      GNUNET_assert (0 ==
+                     crypto_scalarmult_ed25519_base_noclamp (q.v,
+                                                             fact.v));
+      GNUNET_assert (
+        0 ==
+        crypto_core_ed25519_sub (q.v,
+                                 q.v,
+                                 q.v));
+    }
+    else
+      GNUNET_assert (0 ==
+                     crypto_scalarmult_ed25519_base_noclamp (q.v,
+                                                             fact.v));
+    {
+      int iret;
+
+      if (x !=
+          (iret = GNUNET_CRYPTO_ecc_dlog (edc,
+                                          &q)))
+      {
+        GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+                    "DLOG failed for value %d (got: %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");
+  fprintf (stderr,
+           "\n");
 }
 
 
@@ -127,38 +148,40 @@ 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;
+  struct GNUNET_CRYPTO_EccPoint ip;
+  struct GNUNET_CRYPTO_EccPoint jp;
+  struct GNUNET_CRYPTO_EccPoint r;
+  struct GNUNET_CRYPTO_EccPoint ir;
+  struct GNUNET_CRYPTO_EccPoint irj;
+  struct GNUNET_CRYPTO_EccPoint r_inv;
+  struct GNUNET_CRYPTO_EccPoint sum;
 
   for (i = -MATH_MAX; i < MATH_MAX; i++)
   {
-    ip = GNUNET_CRYPTO_ecc_dexp (edc, i);
+    GNUNET_CRYPTO_ecc_dexp (i, &ip);
     for (j = -MATH_MAX; j < MATH_MAX; j++)
     {
       fprintf (stderr, ".");
-      jp = GNUNET_CRYPTO_ecc_dexp (edc, j);
-      GNUNET_CRYPTO_ecc_rnd (edc,
-                             &r,
+      GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+                  "%d + %d\n",
+                  i,
+                  j);
+      GNUNET_CRYPTO_ecc_dexp (j, &jp);
+      GNUNET_CRYPTO_ecc_rnd (&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_add (&ip, &r, &ir);
+      GNUNET_CRYPTO_ecc_add (&ir, &jp, &irj);
+      GNUNET_CRYPTO_ecc_add (&irj, &r_inv, &sum);
+      int res = GNUNET_CRYPTO_ecc_dlog (edc, &sum);
+      if (i + j != res)
+      {
+        GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+                    "Got %d, expected %d\n",
+                    res,
+                    i + j);
+        // GNUNET_assert (0);
+      }
     }
-    GNUNET_CRYPTO_ecc_free (ip);
   }
   fprintf (stderr, "\n");
 }

-- 
To stop receiving notification emails like this one, please contact
gnunet@gnunet.org.



reply via email to

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