aboutsummaryrefslogtreecommitdiff
path: root/src
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
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')
-rw-r--r--src/include/gnunet_crypto_lib.h56
-rw-r--r--src/util/crypto_ecc.c10
-rw-r--r--src/util/crypto_ecc_dlog.c100
3 files changed, 130 insertions, 36 deletions
diff --git a/src/include/gnunet_crypto_lib.h b/src/include/gnunet_crypto_lib.h
index eb28b8ffd..0acced362 100644
--- 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,
1285 */ 1285 */
1286struct GNUNET_CRYPTO_EccDlogContext; 1286struct GNUNET_CRYPTO_EccDlogContext;
1287 1287
1288
1289/**
1290 * Point on a curve (always for Curve25519) encoded in a format suitable
1291 * for network transmission (ECDH), see http://cr.yp.to/ecdh.html.
1292 */
1293struct GNUNET_CRYPTO_EccPoint
1294{
1295 /**
1296 * Q consists of an x- and a y-value, each mod p (256 bits), given
1297 * here in affine coordinates and Ed25519 standard compact format.
1298 */
1299 unsigned char q_y[256 / 8];
1300};
1301
1302
1288/** 1303/**
1289 * Do pre-calculation for ECC discrete logarithm for small factors. 1304 * Do pre-calculation for ECC discrete logarithm for small factors.
1290 * 1305 *
1291 * @param max maximum value the factor can be 1306 * @param max maximum value the factor can be
1292 * @param mem memory to use (should be smaller than @a max), must not be zero. 1307 * @param mem memory to use (should be smaller than @a max), must not be zero.
1293 * @return @a max if dlog failed, otherwise the factor 1308 * @return @a max if dlog failed, otherwise the factor
@@ -1300,7 +1315,7 @@ GNUNET_CRYPTO_ecc_dlog_prepare (unsigned int max,
1300/** 1315/**
1301 * Calculate ECC discrete logarithm for small factors. 1316 * Calculate ECC discrete logarithm for small factors.
1302 * Opposite of #GNUNET_CRYPTO_ecc_dexp(). 1317 * Opposite of #GNUNET_CRYPTO_ecc_dexp().
1303 * 1318 *
1304 * @param dlc precalculated values, determine range of factors 1319 * @param dlc precalculated values, determine range of factors
1305 * @param input point on the curve to factor 1320 * @param input point on the curve to factor
1306 * @return `dlc->max` if dlog failed, otherwise the factor 1321 * @return `dlc->max` if dlog failed, otherwise the factor
@@ -1314,10 +1329,10 @@ GNUNET_CRYPTO_ecc_dlog (struct GNUNET_CRYPTO_EccDlogContext *edc,
1314 * Multiply the generator g of the elliptic curve by @a val 1329 * Multiply the generator g of the elliptic curve by @a val
1315 * to obtain the point on the curve representing @a val. 1330 * to obtain the point on the curve representing @a val.
1316 * Afterwards, point addition will correspond to integer 1331 * Afterwards, point addition will correspond to integer
1317 * addition. #GNUNET_CRYPTO_ecc_dlog() can be used to 1332 * addition. #GNUNET_CRYPTO_ecc_dlog() can be used to
1318 * convert a point back to an integer (as long as the 1333 * convert a point back to an integer (as long as the
1319 * integer is smaller than the MAX of the @a edc context). 1334 * integer is smaller than the MAX of the @a edc context).
1320 * 1335 *
1321 * @param edc calculation context for ECC operations 1336 * @param edc calculation context for ECC operations
1322 * @param val value to encode into a point 1337 * @param val value to encode into a point
1323 * @return representation of the value as an ECC point, 1338 * @return representation of the value as an ECC point,
@@ -1331,7 +1346,7 @@ GNUNET_CRYPTO_ecc_dexp (struct GNUNET_CRYPTO_EccDlogContext *edc,
1331/** 1346/**
1332 * Multiply the generator g of the elliptic curve by @a val 1347 * Multiply the generator g of the elliptic curve by @a val
1333 * to obtain the point on the curve representing @a val. 1348 * to obtain the point on the curve representing @a val.
1334 * 1349 *
1335 * @param edc calculation context for ECC operations 1350 * @param edc calculation context for ECC operations
1336 * @param val (positive) value to encode into a point 1351 * @param val (positive) value to encode into a point
1337 * @return representation of the value as an ECC point, 1352 * @return representation of the value as an ECC point,
@@ -1343,8 +1358,33 @@ GNUNET_CRYPTO_ecc_dexp_mpi (struct GNUNET_CRYPTO_EccDlogContext *edc,
1343 1358
1344 1359
1345/** 1360/**
1361 * Convert point value to binary representation.
1362 *
1363 * @param edc calculation context for ECC operations
1364 * @param point computational point representation
1365 * @param[out] bin binary point representation
1366 */
1367void
1368GNUNET_CRYPTO_ecc_point_to_bin (struct GNUNET_CRYPTO_EccDlogContext *edc,
1369 gcry_mpi_point_t point,
1370 struct GNUNET_CRYPTO_EccPoint *bin);
1371
1372
1373/**
1374 * Convert binary representation of a point to computational representation.
1375 *
1376 * @param edc calculation context for ECC operations
1377 * @param bin binary point representation
1378 * @return computational representation
1379 */
1380gcry_mpi_point_t
1381GNUNET_CRYPTO_ecc_bin_to_point (struct GNUNET_CRYPTO_EccDlogContext *edc,
1382 const struct GNUNET_CRYPTO_EccPoint *bin);
1383
1384
1385/**
1346 * Add two points on the elliptic curve. 1386 * Add two points on the elliptic curve.
1347 * 1387 *
1348 * @param edc calculation context for ECC operations 1388 * @param edc calculation context for ECC operations
1349 * @param a some value 1389 * @param a some value
1350 * @param b some value 1390 * @param b some value
@@ -1360,7 +1400,7 @@ GNUNET_CRYPTO_ecc_add (struct GNUNET_CRYPTO_EccDlogContext *edc,
1360 * Obtain a random point on the curve and its 1400 * Obtain a random point on the curve and its
1361 * additive inverse. Both returned values 1401 * additive inverse. Both returned values
1362 * must be freed using #GNUNET_CRYPTO_ecc_free(). 1402 * must be freed using #GNUNET_CRYPTO_ecc_free().
1363 * 1403 *
1364 * @param edc calculation context for ECC operations 1404 * @param edc calculation context for ECC operations
1365 * @param[out] r set to a random point on the curve 1405 * @param[out] r set to a random point on the curve
1366 * @param[out] r_inv set to the additive inverse of @a r 1406 * @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);
1383 1423
1384/** 1424/**
1385 * Free a point value returned by the API. 1425 * Free a point value returned by the API.
1386 * 1426 *
1387 * @param p point to free 1427 * @param p point to free
1388 */ 1428 */
1389void 1429void
diff --git a/src/util/crypto_ecc.c b/src/util/crypto_ecc.c
index 7449d0392..bcc04fea5 100644
--- 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)
130 rc = gcry_sexp_build (&result, NULL, 130 rc = gcry_sexp_build (&result, NULL,
131 "(private-key(ecc(curve \"" CURVE "\")" 131 "(private-key(ecc(curve \"" CURVE "\")"
132 "(d %b)))", 132 "(d %b)))",
133 (int)sizeof (priv->d), priv->d); 133 (int) sizeof (priv->d), priv->d);
134 if (0 != rc) 134 if (0 != rc)
135 { 135 {
136 LOG_GCRY (GNUNET_ERROR_TYPE_ERROR, "gcry_sexp_build", rc); 136 LOG_GCRY (GNUNET_ERROR_TYPE_ERROR, "gcry_sexp_build", rc);
@@ -855,16 +855,16 @@ GNUNET_CRYPTO_ecdsa_verify (uint32_t purpose,
855 /* build s-expression for signature */ 855 /* build s-expression for signature */
856 if (0 != (rc = gcry_sexp_build (&sig_sexpr, NULL, 856 if (0 != (rc = gcry_sexp_build (&sig_sexpr, NULL,
857 "(sig-val(ecdsa(r %b)(s %b)))", 857 "(sig-val(ecdsa(r %b)(s %b)))",
858 (int)sizeof (sig->r), sig->r, 858 (int) sizeof (sig->r), sig->r,
859 (int)sizeof (sig->s), sig->s))) 859 (int) sizeof (sig->s), sig->s)))
860 { 860 {
861 LOG_GCRY (GNUNET_ERROR_TYPE_ERROR, "gcry_sexp_build", rc); 861 LOG_GCRY (GNUNET_ERROR_TYPE_ERROR, "gcry_sexp_build", rc);
862 return GNUNET_SYSERR; 862 return GNUNET_SYSERR;
863 } 863 }
864 data = data_to_ecdsa_value (validate); 864 data = data_to_ecdsa_value (validate);
865 if (0 != (rc = gcry_sexp_build (&pub_sexpr, NULL, 865 if (0 != (rc = gcry_sexp_build (&pub_sexpr, NULL,
866 "(public-key(ecc(curve " CURVE ")(q %b)))", 866 "(public-key(ecc(curve " CURVE ")(q %b)))",
867 (int)sizeof (pub->q_y), pub->q_y))) 867 (int) sizeof (pub->q_y), pub->q_y)))
868 { 868 {
869 gcry_sexp_release (data); 869 gcry_sexp_release (data);
870 gcry_sexp_release (sig_sexpr); 870 gcry_sexp_release (sig_sexpr);
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 */