gnunet

Main GNUnet Logic
Log | Files | Refs | Submodules | README | LICENSE

commit 59df216f6ad04e9131ee4fa43e14055252a71651
parent aff9093b9a8874c841763d5ea8d4adc2197e861e
Author: Christian Grothoff <christian@grothoff.org>
Date:   Sat,  5 Sep 2015 17:02:45 +0000

adding bin_to_point and point_to_bin functions for GNUNET_CRYPTO_ecc API

Diffstat:
Msrc/include/gnunet_crypto_lib.h | 56++++++++++++++++++++++++++++++++++++++++++++++++--------
Msrc/util/crypto_ecc.c | 10+++++-----
Msrc/util/crypto_ecc_dlog.c | 100+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++------------------
3 files changed, 130 insertions(+), 36 deletions(-)

diff --git a/src/include/gnunet_crypto_lib.h b/src/include/gnunet_crypto_lib.h @@ -1285,9 +1285,24 @@ GNUNET_CRYPTO_cmp_peer_identity (const struct GNUNET_PeerIdentity *first, */ struct GNUNET_CRYPTO_EccDlogContext; + +/** + * Point on a curve (always for Curve25519) encoded in a format suitable + * for network transmission (ECDH), see http://cr.yp.to/ecdh.html. + */ +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]; +}; + + /** * 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 @@ -1300,7 +1315,7 @@ GNUNET_CRYPTO_ecc_dlog_prepare (unsigned int max, /** * Calculate ECC discrete logarithm for small factors. * Opposite of #GNUNET_CRYPTO_ecc_dexp(). - * + * * @param dlc precalculated values, determine range of factors * @param input point on the curve to factor * @return `dlc->max` if dlog failed, otherwise the factor @@ -1314,10 +1329,10 @@ GNUNET_CRYPTO_ecc_dlog (struct GNUNET_CRYPTO_EccDlogContext *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 + * 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, @@ -1331,7 +1346,7 @@ GNUNET_CRYPTO_ecc_dexp (struct GNUNET_CRYPTO_EccDlogContext *edc, /** * 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, @@ -1343,8 +1358,33 @@ GNUNET_CRYPTO_ecc_dexp_mpi (struct GNUNET_CRYPTO_EccDlogContext *edc, /** + * 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 + */ +gcry_mpi_point_t +GNUNET_CRYPTO_ecc_bin_to_point (struct GNUNET_CRYPTO_EccDlogContext *edc, + const struct GNUNET_CRYPTO_EccPoint *bin); + + +/** * Add two points on the elliptic curve. - * + * * @param edc calculation context for ECC operations * @param a some value * @param b some value @@ -1360,7 +1400,7 @@ GNUNET_CRYPTO_ecc_add (struct GNUNET_CRYPTO_EccDlogContext *edc, * 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 @@ -1383,7 +1423,7 @@ GNUNET_CRYPTO_ecc_random_mod_n (struct GNUNET_CRYPTO_EccDlogContext *edc); /** * Free a point value returned by the API. - * + * * @param p point to free */ void diff --git a/src/util/crypto_ecc.c b/src/util/crypto_ecc.c @@ -130,7 +130,7 @@ decode_private_ecdsa_key (const struct GNUNET_CRYPTO_EcdsaPrivateKey *priv) rc = gcry_sexp_build (&result, NULL, "(private-key(ecc(curve \"" CURVE "\")" "(d %b)))", - (int)sizeof (priv->d), priv->d); + (int) sizeof (priv->d), priv->d); if (0 != rc) { LOG_GCRY (GNUNET_ERROR_TYPE_ERROR, "gcry_sexp_build", rc); @@ -855,16 +855,16 @@ GNUNET_CRYPTO_ecdsa_verify (uint32_t purpose, /* build s-expression for signature */ if (0 != (rc = gcry_sexp_build (&sig_sexpr, NULL, "(sig-val(ecdsa(r %b)(s %b)))", - (int)sizeof (sig->r), sig->r, - (int)sizeof (sig->s), sig->s))) + (int) sizeof (sig->r), sig->r, + (int) sizeof (sig->s), sig->s))) { LOG_GCRY (GNUNET_ERROR_TYPE_ERROR, "gcry_sexp_build", rc); return GNUNET_SYSERR; } data = data_to_ecdsa_value (validate); if (0 != (rc = gcry_sexp_build (&pub_sexpr, NULL, - "(public-key(ecc(curve " CURVE ")(q %b)))", - (int)sizeof (pub->q_y), pub->q_y))) + "(public-key(ecc(curve " CURVE ")(q %b)))", + (int) sizeof (pub->q_y), pub->q_y))) { gcry_sexp_release (data); gcry_sexp_release (sig_sexpr); diff --git a/src/util/crypto_ecc_dlog.c b/src/util/crypto_ecc_dlog.c @@ -45,11 +45,11 @@ */ 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); @@ -63,7 +63,7 @@ extract_pk (gcry_mpi_point_t pt, /** * 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. @@ -92,8 +92,63 @@ 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; + + 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 @@ -119,8 +174,8 @@ 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); @@ -161,7 +216,7 @@ GNUNET_CRYPTO_ecc_dlog_prepare (unsigned int max, /** * 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 @@ -181,7 +236,7 @@ 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; for (i=0;i<=edc->max/edc->mem;i++) { @@ -204,7 +259,7 @@ GNUNET_CRYPTO_ecc_dlog (struct GNUNET_CRYPTO_EccDlogContext *edc, 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); @@ -237,11 +292,11 @@ GNUNET_CRYPTO_ecc_random_mod_n (struct GNUNET_CRYPTO_EccDlogContext *edc) /* 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; } @@ -265,10 +320,10 @@ GNUNET_CRYPTO_ecc_dlog_release (struct GNUNET_CRYPTO_EccDlogContext *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 + * 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, @@ -308,7 +363,7 @@ GNUNET_CRYPTO_ecc_dexp (struct GNUNET_CRYPTO_EccDlogContext *edc, /** * 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, @@ -332,7 +387,7 @@ GNUNET_CRYPTO_ecc_dexp_mpi (struct GNUNET_CRYPTO_EccDlogContext *edc, /** * Add two points on the elliptic curve. - * + * * @param edc calculation context for ECC operations * @param a some value * @param b some value @@ -344,7 +399,7 @@ GNUNET_CRYPTO_ecc_add (struct GNUNET_CRYPTO_EccDlogContext *edc, 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; @@ -355,7 +410,7 @@ GNUNET_CRYPTO_ecc_add (struct GNUNET_CRYPTO_EccDlogContext *edc, * 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 @@ -380,18 +435,18 @@ GNUNET_CRYPTO_ecc_rnd (struct GNUNET_CRYPTO_EccDlogContext *edc, /* 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); } - + /** * Free a point value returned by the API. - * + * * @param p point to free */ void @@ -400,6 +455,5 @@ GNUNET_CRYPTO_ecc_free (gcry_mpi_point_t p) gcry_mpi_point_release (p); } - -/* end of crypto_ecc_dlog.c */ +/* end of crypto_ecc_dlog.c */