+
+/**
+ * Multiply the generator g of the elliptic curve by @a val
+ * to obtain the point on the curve representing @a val.
+ * Afterwards, point addition will correspond to integer
+ * addition. #GNUNET_CRYPTO_ecc_dlog() can be used to
+ * convert a point back to an integer (as long as the
+ * integer is smaller than the MAX of the @a edc context).
+ *
+ * @param edc calculation context for ECC operations
+ * @param val value to encode into a point
+ * @return representation of the value as an ECC point,
+ * must be freed using #GNUNET_CRYPTO_ecc_free()
+ */
+gcry_mpi_point_t
+GNUNET_CRYPTO_ecc_dexp (struct GNUNET_CRYPTO_EccDlogContext *edc,
+ int val)
+{
+ gcry_mpi_t fact;
+ gcry_mpi_t n;
+ gcry_mpi_point_t g;
+ gcry_mpi_point_t r;
+
+ g = gcry_mpi_ec_get_point ("g", edc->ctx, 0);
+ GNUNET_assert (NULL != g);
+ fact = gcry_mpi_new (0);
+ if (val < 0)
+ {
+ n = gcry_mpi_ec_get_mpi ("n", edc->ctx, 1);
+ gcry_mpi_set_ui (fact, - val);
+ gcry_mpi_sub (fact, n, fact);
+ gcry_mpi_release (n);
+ }
+ else
+ {
+ gcry_mpi_set_ui (fact, val);
+ }
+ r = gcry_mpi_point_new (0);
+ gcry_mpi_ec_mul (r, fact, g, edc->ctx);
+ gcry_mpi_release (fact);
+ gcry_mpi_point_release (g);
+ return r;
+}
+
+
+/**
+ * Multiply the generator g of the elliptic curve by @a val
+ * to obtain the point on the curve representing @a val.
+ *
+ * @param edc calculation context for ECC operations
+ * @param val (positive) value to encode into a point
+ * @return representation of the value as an ECC point,
+ * must be freed using #GNUNET_CRYPTO_ecc_free()
+ */
+gcry_mpi_point_t
+GNUNET_CRYPTO_ecc_dexp_mpi (struct GNUNET_CRYPTO_EccDlogContext *edc,
+ gcry_mpi_t val)
+{
+ gcry_mpi_point_t g;
+ gcry_mpi_point_t r;
+
+ g = gcry_mpi_ec_get_point ("g", edc->ctx, 0);
+ GNUNET_assert (NULL != g);
+ r = gcry_mpi_point_new (0);
+ gcry_mpi_ec_mul (r, val, g, edc->ctx);
+ gcry_mpi_point_release (g);
+ return r;
+}
+
+
+/**
+ * Add two points on the elliptic curve.
+ *
+ * @param edc calculation context for ECC operations
+ * @param a some value
+ * @param b some value
+ * @return @a a + @a b, must be freed using #GNUNET_CRYPTO_ecc_free()
+ */
+gcry_mpi_point_t
+GNUNET_CRYPTO_ecc_add (struct GNUNET_CRYPTO_EccDlogContext *edc,
+ gcry_mpi_point_t a,
+ gcry_mpi_point_t b)
+{
+ gcry_mpi_point_t r;
+
+ r = gcry_mpi_point_new (0);
+ gcry_mpi_ec_add (r, a, b, edc->ctx);
+ return r;
+}
+
+
+/**
+ * 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)
+{
+ gcry_mpi_point_t r;
+
+ r = gcry_mpi_point_new (0);
+ gcry_mpi_ec_mul (r, val, p, edc->ctx);
+ return r;
+}
+
+
+/**
+ * Obtain a random point on the curve and its
+ * additive inverse. Both returned values
+ * must be freed using #GNUNET_CRYPTO_ecc_free().
+ *
+ * @param edc calculation context for ECC operations
+ * @param[out] r set to a random point on the curve
+ * @param[out] r_inv set to the additive inverse of @a r
+ */
+void
+GNUNET_CRYPTO_ecc_rnd (struct GNUNET_CRYPTO_EccDlogContext *edc,
+ gcry_mpi_point_t *r,
+ gcry_mpi_point_t *r_inv)
+{
+ gcry_mpi_t fact;
+ gcry_mpi_t n;
+ gcry_mpi_point_t g;
+
+ fact = GNUNET_CRYPTO_ecc_random_mod_n (edc);
+
+ /* calculate 'r' */
+ g = gcry_mpi_ec_get_point ("g", edc->ctx, 0);
+ GNUNET_assert (NULL != g);
+ *r = gcry_mpi_point_new (0);
+ gcry_mpi_ec_mul (*r, fact, g, edc->ctx);
+
+ /* calculate 'r_inv' */
+ n = gcry_mpi_ec_get_mpi ("n", edc->ctx, 1);
+ gcry_mpi_sub (fact, n, fact); /* fact = n - fact = - fact */
+ *r_inv = gcry_mpi_point_new (0);
+ gcry_mpi_ec_mul (*r_inv, fact, g, edc->ctx);
+
+ gcry_mpi_release (n);
+ gcry_mpi_release (fact);
+ gcry_mpi_point_release (g);
+}
+
+
+/**
+ * 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)
+{
+ 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);
+}
+
+
+/**
+ * Free a point value returned by the API.
+ *
+ * @param p point to free
+ */
+void
+GNUNET_CRYPTO_ecc_free (gcry_mpi_point_t p)
+{
+ gcry_mpi_point_release (p);
+}
+
+
+/* end of crypto_ecc_dlog.c */