/*
This file is part of GNUnet.
- Copyright (C) 2012, 2013, 2015 Christian Grothoff (and other contributing authors)
+ Copyright (C) 2012, 2013, 2015 GNUnet e.V.
GNUnet is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published
*/
static void
extract_pk (gcry_mpi_point_t pt,
- gcry_ctx_t ctx,
- struct GNUNET_PeerIdentity *pid)
+ 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);
/**
* Internal structure used to cache pre-calculated values for DLOG calculation.
*/
-struct GNUNET_CRYPTO_EccDlogContext
+struct GNUNET_CRYPTO_EccDlogContext
{
/**
* Maximum absolute value the calculation supports.
};
+/**
+ * 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;
+
+ 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 @a max if dlog failed, otherwise the factor
+ * @return NULL on error
*/
struct GNUNET_CRYPTO_EccDlogContext *
GNUNET_CRYPTO_ecc_dlog_prepare (unsigned int max,
edc->map = GNUNET_CONTAINER_multipeermap_create (mem * 2,
GNUNET_NO);
- GNUNET_assert (0 == gcry_mpi_ec_new (&edc->ctx,
- NULL,
+ 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);
/**
* Calculate ECC discrete logarithm for small factors.
- *
+ *
* @param edc precalculated values, determine range of factors
* @param input point on the curve to factor
- * @return `edc->max` if dlog failed, otherwise the factor
+ * @return INT_MAX if dlog failed, otherwise the factor
*/
int
GNUNET_CRYPTO_ecc_dlog (struct GNUNET_CRYPTO_EccDlogContext *edc,
g = gcry_mpi_ec_get_point ("g", edc->ctx, 0);
GNUNET_assert (NULL != g);
q = gcry_mpi_point_new (0);
-
- res = edc->max;
+
+ res = INT_MAX;
for (i=0;i<=edc->max/edc->mem;i++)
{
if (0 == i)
if (0 == i)
gcry_mpi_ec_add (q, input, g, edc->ctx);
else
- gcry_mpi_ec_add (q, q, g, edc->ctx);
+ gcry_mpi_ec_add (q, q, g, edc->ctx);
}
gcry_mpi_point_release (g);
gcry_mpi_point_release (q);
/* generate fact < n (without bias) */
GNUNET_assert (NULL != (r = gcry_mpi_new (0)));
do {
- gcry_mpi_randomize (r,
+ gcry_mpi_randomize (r,
highbit + 1,
GCRY_STRONG_RANDOM);
}
- while (gcry_mpi_cmp (r, n) >= 0);
+ while (gcry_mpi_cmp (r, n) >= 0);
gcry_mpi_release (n);
return r;
}
* 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
+ * 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,
/**
* 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,
/**
* Add two points on the elliptic curve.
- *
+ *
* @param edc calculation context for ECC operations
* @param a some value
* @param b some value
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
/* 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);
+ *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
gcry_mpi_point_release (p);
}
-
-/* end of crypto_ecc_dlog.c */
+/* end of crypto_ecc_dlog.c */