summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChristian Grothoff <christian@grothoff.org>2021-04-18 21:11:08 +0200
committerChristian Grothoff <christian@grothoff.org>2021-04-18 21:11:08 +0200
commit75cfa6370bc902765c26b50bb858c9a5bc1e8e48 (patch)
treefdadaf6e2736ad79c9f79576bf9a056ea9d0a6f5
parent5ec7af75ea9f8ed86cf28a8efed9a917345d1681 (diff)
SCALARPRODUCT: migrating logic from libgcrypt to libsodium (#6818).
-rw-r--r--src/include/gnunet_crypto_lib.h132
-rw-r--r--src/include/gnunet_scalarproduct_service.h50
-rw-r--r--src/scalarproduct/Makefile.am4
-rw-r--r--src/scalarproduct/gnunet-service-scalarproduct-ecc_alice.c297
-rw-r--r--src/scalarproduct/gnunet-service-scalarproduct-ecc_bob.c131
-rwxr-xr-xsrc/scalarproduct/perf_scalarproduct.sh19
-rw-r--r--src/scalarproduct/scalarproduct_api.c50
-rw-r--r--src/scalarproduct/test_ecc_scalarproduct.c211
-rwxr-xr-xsrc/scalarproduct/test_scalarproduct_negative.sh3
-rw-r--r--src/util/Makefile.am3
-rw-r--r--src/util/crypto_ecc_dlog.c525
-rw-r--r--src/util/perf_crypto_ecc_dlog.c118
-rw-r--r--src/util/test_crypto_ecc_dlog.c141
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;
@@ -413,51 +413,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
@@ -32,35 +32,6 @@
/**
- * 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.
*/
struct GNUNET_CRYPTO_EccDlogContext
@@ -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");
}