gnunet-svn
[Top][All Lists]
Advanced

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

[gnunet] branch master updated (5ec7af75e -> f022b206a)


From: gnunet
Subject: [gnunet] branch master updated (5ec7af75e -> f022b206a)
Date: Sun, 18 Apr 2021 21:15:10 +0200

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

grothoff pushed a change to branch master
in repository gnunet.

    from 5ec7af75e - fixed format for configure.ac git version
     new 75cfa6370 SCALARPRODUCT: migrating logic from libgcrypt to libsodium 
(#6818).
     new f022b206a -unconditionally compile scalarproduct again

The 2 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.


Summary of changes:
 src/Makefile.am                                    |   6 +-
 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 +++---
 14 files changed, 768 insertions(+), 922 deletions(-)

diff --git a/src/Makefile.am b/src/Makefile.am
index 564923e28..d8a869acb 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -45,10 +45,6 @@ if HAVE_POSTGRESQL
  POSTGRES_DIR = pq
 endif
 
-if HAVE_NOLIBGCRYPT19
-  SCALARPRODUCT_DIR = scalarproduct
-endif
-
 REST_DIR = rest
 
 
@@ -97,7 +93,7 @@ SUBDIRS = \
   seti \
   setu \
   consensus \
-  $(SCALARPRODUCT_DIR) \
+  scalarproduct \
   revocation \
   vpn \
   gns \
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]