aboutsummaryrefslogtreecommitdiff
path: root/src/util/crypto_ecc_dlog.c
diff options
context:
space:
mode:
authorChristian Grothoff <christian@grothoff.org>2015-09-05 17:02:45 +0000
committerChristian Grothoff <christian@grothoff.org>2015-09-05 17:02:45 +0000
commit59df216f6ad04e9131ee4fa43e14055252a71651 (patch)
tree337c13e7843379446d826e34a63a2d0297d29c6e /src/util/crypto_ecc_dlog.c
parentaff9093b9a8874c841763d5ea8d4adc2197e861e (diff)
downloadgnunet-59df216f6ad04e9131ee4fa43e14055252a71651.tar.gz
gnunet-59df216f6ad04e9131ee4fa43e14055252a71651.zip
adding bin_to_point and point_to_bin functions for GNUNET_CRYPTO_ecc API
Diffstat (limited to 'src/util/crypto_ecc_dlog.c')
-rw-r--r--src/util/crypto_ecc_dlog.c100
1 files changed, 77 insertions, 23 deletions
diff --git a/src/util/crypto_ecc_dlog.c b/src/util/crypto_ecc_dlog.c
index 3a2a91532..13ee1e6be 100644
--- a/src/util/crypto_ecc_dlog.c
+++ b/src/util/crypto_ecc_dlog.c
@@ -45,11 +45,11 @@
45 */ 45 */
46static void 46static void
47extract_pk (gcry_mpi_point_t pt, 47extract_pk (gcry_mpi_point_t pt,
48 gcry_ctx_t ctx, 48 gcry_ctx_t ctx,
49 struct GNUNET_PeerIdentity *pid) 49 struct GNUNET_PeerIdentity *pid)
50{ 50{
51 gcry_mpi_t q_y; 51 gcry_mpi_t q_y;
52 52
53 GNUNET_assert (0 == gcry_mpi_ec_set_point ("q", pt, ctx)); 53 GNUNET_assert (0 == gcry_mpi_ec_set_point ("q", pt, ctx));
54 q_y = gcry_mpi_ec_get_mpi ("q@eddsa", ctx, 0); 54 q_y = gcry_mpi_ec_get_mpi ("q@eddsa", ctx, 0);
55 GNUNET_assert (q_y); 55 GNUNET_assert (q_y);
@@ -63,7 +63,7 @@ extract_pk (gcry_mpi_point_t pt,
63/** 63/**
64 * Internal structure used to cache pre-calculated values for DLOG calculation. 64 * Internal structure used to cache pre-calculated values for DLOG calculation.
65 */ 65 */
66struct GNUNET_CRYPTO_EccDlogContext 66struct GNUNET_CRYPTO_EccDlogContext
67{ 67{
68 /** 68 /**
69 * Maximum absolute value the calculation supports. 69 * Maximum absolute value the calculation supports.
@@ -92,8 +92,63 @@ struct GNUNET_CRYPTO_EccDlogContext
92 92
93 93
94/** 94/**
95 * Convert point value to binary representation.
96 *
97 * @param edc calculation context for ECC operations
98 * @param point computational point representation
99 * @param[out] bin binary point representation
100 */
101void
102GNUNET_CRYPTO_ecc_point_to_bin (struct GNUNET_CRYPTO_EccDlogContext *edc,
103 gcry_mpi_point_t point,
104 struct GNUNET_CRYPTO_EccPoint *bin)
105{
106 gcry_mpi_t q_y;
107
108 GNUNET_assert (0 == gcry_mpi_ec_set_point ("q", point, edc->ctx));
109 q_y = gcry_mpi_ec_get_mpi ("q@eddsa", edc->ctx, 0);
110 GNUNET_assert (q_y);
111 GNUNET_CRYPTO_mpi_print_unsigned (bin->q_y,
112 sizeof (bin->q_y),
113 q_y);
114 gcry_mpi_release (q_y);
115}
116
117
118/**
119 * Convert binary representation of a point to computational representation.
120 *
121 * @param edc calculation context for ECC operations
122 * @param bin binary point representation
123 * @return computational representation
124 */
125gcry_mpi_point_t
126GNUNET_CRYPTO_ecc_bin_to_point (struct GNUNET_CRYPTO_EccDlogContext *edc,
127 const struct GNUNET_CRYPTO_EccPoint *bin)
128{
129 gcry_sexp_t pub_sexpr;
130 gcry_ctx_t ctx;
131 gcry_mpi_point_t q;
132
133 if (0 != gcry_sexp_build (&pub_sexpr, NULL,
134 "(public-key(ecc(curve " CURVE ")(q %b)))",
135 (int) sizeof (bin->q_y),
136 bin->q_y))
137 {
138 GNUNET_break (0);
139 return NULL;
140 }
141 GNUNET_assert (0 == gcry_mpi_ec_new (&ctx, pub_sexpr, NULL));
142 gcry_sexp_release (pub_sexpr);
143 q = gcry_mpi_ec_get_point ("q", ctx, 0);
144 gcry_ctx_release (ctx);
145 return q;
146}
147
148
149/**
95 * Do pre-calculation for ECC discrete logarithm for small factors. 150 * Do pre-calculation for ECC discrete logarithm for small factors.
96 * 151 *
97 * @param max maximum value the factor can be 152 * @param max maximum value the factor can be
98 * @param mem memory to use (should be smaller than @a max), must not be zero. 153 * @param mem memory to use (should be smaller than @a max), must not be zero.
99 * @return @a max if dlog failed, otherwise the factor 154 * @return @a max if dlog failed, otherwise the factor
@@ -119,8 +174,8 @@ GNUNET_CRYPTO_ecc_dlog_prepare (unsigned int max,
119 edc->map = GNUNET_CONTAINER_multipeermap_create (mem * 2, 174 edc->map = GNUNET_CONTAINER_multipeermap_create (mem * 2,
120 GNUNET_NO); 175 GNUNET_NO);
121 176
122 GNUNET_assert (0 == gcry_mpi_ec_new (&edc->ctx, 177 GNUNET_assert (0 == gcry_mpi_ec_new (&edc->ctx,
123 NULL, 178 NULL,
124 CURVE)); 179 CURVE));
125 g = gcry_mpi_ec_get_point ("g", edc->ctx, 0); 180 g = gcry_mpi_ec_get_point ("g", edc->ctx, 0);
126 GNUNET_assert (NULL != g); 181 GNUNET_assert (NULL != g);
@@ -161,7 +216,7 @@ GNUNET_CRYPTO_ecc_dlog_prepare (unsigned int max,
161 216
162/** 217/**
163 * Calculate ECC discrete logarithm for small factors. 218 * Calculate ECC discrete logarithm for small factors.
164 * 219 *
165 * @param edc precalculated values, determine range of factors 220 * @param edc precalculated values, determine range of factors
166 * @param input point on the curve to factor 221 * @param input point on the curve to factor
167 * @return `edc->max` if dlog failed, otherwise the factor 222 * @return `edc->max` if dlog failed, otherwise the factor
@@ -181,7 +236,7 @@ GNUNET_CRYPTO_ecc_dlog (struct GNUNET_CRYPTO_EccDlogContext *edc,
181 g = gcry_mpi_ec_get_point ("g", edc->ctx, 0); 236 g = gcry_mpi_ec_get_point ("g", edc->ctx, 0);
182 GNUNET_assert (NULL != g); 237 GNUNET_assert (NULL != g);
183 q = gcry_mpi_point_new (0); 238 q = gcry_mpi_point_new (0);
184 239
185 res = edc->max; 240 res = edc->max;
186 for (i=0;i<=edc->max/edc->mem;i++) 241 for (i=0;i<=edc->max/edc->mem;i++)
187 { 242 {
@@ -204,7 +259,7 @@ GNUNET_CRYPTO_ecc_dlog (struct GNUNET_CRYPTO_EccDlogContext *edc,
204 if (0 == i) 259 if (0 == i)
205 gcry_mpi_ec_add (q, input, g, edc->ctx); 260 gcry_mpi_ec_add (q, input, g, edc->ctx);
206 else 261 else
207 gcry_mpi_ec_add (q, q, g, edc->ctx); 262 gcry_mpi_ec_add (q, q, g, edc->ctx);
208 } 263 }
209 gcry_mpi_point_release (g); 264 gcry_mpi_point_release (g);
210 gcry_mpi_point_release (q); 265 gcry_mpi_point_release (q);
@@ -237,11 +292,11 @@ GNUNET_CRYPTO_ecc_random_mod_n (struct GNUNET_CRYPTO_EccDlogContext *edc)
237 /* generate fact < n (without bias) */ 292 /* generate fact < n (without bias) */
238 GNUNET_assert (NULL != (r = gcry_mpi_new (0))); 293 GNUNET_assert (NULL != (r = gcry_mpi_new (0)));
239 do { 294 do {
240 gcry_mpi_randomize (r, 295 gcry_mpi_randomize (r,
241 highbit + 1, 296 highbit + 1,
242 GCRY_STRONG_RANDOM); 297 GCRY_STRONG_RANDOM);
243 } 298 }
244 while (gcry_mpi_cmp (r, n) >= 0); 299 while (gcry_mpi_cmp (r, n) >= 0);
245 gcry_mpi_release (n); 300 gcry_mpi_release (n);
246 return r; 301 return r;
247} 302}
@@ -265,10 +320,10 @@ GNUNET_CRYPTO_ecc_dlog_release (struct GNUNET_CRYPTO_EccDlogContext *edc)
265 * Multiply the generator g of the elliptic curve by @a val 320 * Multiply the generator g of the elliptic curve by @a val
266 * to obtain the point on the curve representing @a val. 321 * to obtain the point on the curve representing @a val.
267 * Afterwards, point addition will correspond to integer 322 * Afterwards, point addition will correspond to integer
268 * addition. #GNUNET_CRYPTO_ecc_dlog() can be used to 323 * addition. #GNUNET_CRYPTO_ecc_dlog() can be used to
269 * convert a point back to an integer (as long as the 324 * convert a point back to an integer (as long as the
270 * integer is smaller than the MAX of the @a edc context). 325 * integer is smaller than the MAX of the @a edc context).
271 * 326 *
272 * @param edc calculation context for ECC operations 327 * @param edc calculation context for ECC operations
273 * @param val value to encode into a point 328 * @param val value to encode into a point
274 * @return representation of the value as an ECC point, 329 * @return representation of the value as an ECC point,
@@ -308,7 +363,7 @@ GNUNET_CRYPTO_ecc_dexp (struct GNUNET_CRYPTO_EccDlogContext *edc,
308/** 363/**
309 * Multiply the generator g of the elliptic curve by @a val 364 * Multiply the generator g of the elliptic curve by @a val
310 * to obtain the point on the curve representing @a val. 365 * to obtain the point on the curve representing @a val.
311 * 366 *
312 * @param edc calculation context for ECC operations 367 * @param edc calculation context for ECC operations
313 * @param val (positive) value to encode into a point 368 * @param val (positive) value to encode into a point
314 * @return representation of the value as an ECC point, 369 * @return representation of the value as an ECC point,
@@ -332,7 +387,7 @@ GNUNET_CRYPTO_ecc_dexp_mpi (struct GNUNET_CRYPTO_EccDlogContext *edc,
332 387
333/** 388/**
334 * Add two points on the elliptic curve. 389 * Add two points on the elliptic curve.
335 * 390 *
336 * @param edc calculation context for ECC operations 391 * @param edc calculation context for ECC operations
337 * @param a some value 392 * @param a some value
338 * @param b some value 393 * @param b some value
@@ -344,7 +399,7 @@ GNUNET_CRYPTO_ecc_add (struct GNUNET_CRYPTO_EccDlogContext *edc,
344 gcry_mpi_point_t b) 399 gcry_mpi_point_t b)
345{ 400{
346 gcry_mpi_point_t r; 401 gcry_mpi_point_t r;
347 402
348 r = gcry_mpi_point_new (0); 403 r = gcry_mpi_point_new (0);
349 gcry_mpi_ec_add (r, a, b, edc->ctx); 404 gcry_mpi_ec_add (r, a, b, edc->ctx);
350 return r; 405 return r;
@@ -355,7 +410,7 @@ GNUNET_CRYPTO_ecc_add (struct GNUNET_CRYPTO_EccDlogContext *edc,
355 * Obtain a random point on the curve and its 410 * Obtain a random point on the curve and its
356 * additive inverse. Both returned values 411 * additive inverse. Both returned values
357 * must be freed using #GNUNET_CRYPTO_ecc_free(). 412 * must be freed using #GNUNET_CRYPTO_ecc_free().
358 * 413 *
359 * @param edc calculation context for ECC operations 414 * @param edc calculation context for ECC operations
360 * @param[out] r set to a random point on the curve 415 * @param[out] r set to a random point on the curve
361 * @param[out] r_inv set to the additive inverse of @a r 416 * @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,
380 /* calculate 'r_inv' */ 435 /* calculate 'r_inv' */
381 n = gcry_mpi_ec_get_mpi ("n", edc->ctx, 1); 436 n = gcry_mpi_ec_get_mpi ("n", edc->ctx, 1);
382 gcry_mpi_sub (fact, n, fact); /* fact = n - fact = - fact */ 437 gcry_mpi_sub (fact, n, fact); /* fact = n - fact = - fact */
383 *r_inv = gcry_mpi_point_new (0); 438 *r_inv = gcry_mpi_point_new (0);
384 gcry_mpi_ec_mul (*r_inv, fact, g, edc->ctx); 439 gcry_mpi_ec_mul (*r_inv, fact, g, edc->ctx);
385 440
386 gcry_mpi_release (n); 441 gcry_mpi_release (n);
387 gcry_mpi_release (fact); 442 gcry_mpi_release (fact);
388 gcry_mpi_point_release (g); 443 gcry_mpi_point_release (g);
389} 444}
390 445
391 446
392/** 447/**
393 * Free a point value returned by the API. 448 * Free a point value returned by the API.
394 * 449 *
395 * @param p point to free 450 * @param p point to free
396 */ 451 */
397void 452void
@@ -400,6 +455,5 @@ GNUNET_CRYPTO_ecc_free (gcry_mpi_point_t p)
400 gcry_mpi_point_release (p); 455 gcry_mpi_point_release (p);
401} 456}
402 457
403
404/* end of crypto_ecc_dlog.c */
405 458
459/* end of crypto_ecc_dlog.c */