aboutsummaryrefslogtreecommitdiff
path: root/src/util/crypto_ecc.c
diff options
context:
space:
mode:
authorChristian Grothoff <christian@grothoff.org>2013-09-24 06:27:24 +0000
committerChristian Grothoff <christian@grothoff.org>2013-09-24 06:27:24 +0000
commit1a9a16c0e9a9b290ecab1d59928a2c670097ee72 (patch)
tree071c6c4322ef40b8731f3e8c7aa243965b157107 /src/util/crypto_ecc.c
parent76173b3bb145469b830b388a15107d500c9e819b (diff)
downloadgnunet-1a9a16c0e9a9b290ecab1d59928a2c670097ee72.tar.gz
gnunet-1a9a16c0e9a9b290ecab1d59928a2c670097ee72.zip
-fix doxygen
Diffstat (limited to 'src/util/crypto_ecc.c')
-rw-r--r--src/util/crypto_ecc.c167
1 files changed, 58 insertions, 109 deletions
diff --git a/src/util/crypto_ecc.c b/src/util/crypto_ecc.c
index e393ad1e5..153b8f7f2 100644
--- a/src/util/crypto_ecc.c
+++ b/src/util/crypto_ecc.c
@@ -35,10 +35,8 @@
35 * structs that use 256 bits, so using a bigger curve will require 35 * structs that use 256 bits, so using a bigger curve will require
36 * changes that break stuff badly. The name of the curve given here 36 * changes that break stuff badly. The name of the curve given here
37 * must be agreed by all peers and be supported by libgcrypt. 37 * must be agreed by all peers and be supported by libgcrypt.
38 *
39 * NOTE: this will change to Curve25519 before GNUnet 0.10.0.
40 */ 38 */
41#define CURVE "NIST P-256" 39#define CURVE "Ed25519"
42 40
43#define LOG(kind,...) GNUNET_log_from (kind, "util", __VA_ARGS__) 41#define LOG(kind,...) GNUNET_log_from (kind, "util", __VA_ARGS__)
44 42
@@ -199,7 +197,7 @@ decode_private_key (const struct GNUNET_CRYPTO_EccPrivateKey *priv)
199 priv->d, 197 priv->d,
200 sizeof (priv->d)); 198 sizeof (priv->d));
201 rc = gcry_sexp_build (&result, NULL, 199 rc = gcry_sexp_build (&result, NULL,
202 "(private-key(ecdsa(curve \"" CURVE "\")(d %m)))", 200 "(private-key(ecc(curve \"" CURVE "\")(d %m)))",
203 d); 201 d);
204 gcry_mpi_release (d); 202 gcry_mpi_release (d);
205 if (0 != rc) 203 if (0 != rc)
@@ -219,68 +217,6 @@ decode_private_key (const struct GNUNET_CRYPTO_EccPrivateKey *priv)
219 217
220 218
221/** 219/**
222 * Initialize public key struct from the respective point
223 * on the curve.
224 *
225 * @param q point on curve
226 * @param pub public key struct to initialize
227 * @param ctx context to use for ECC operations
228 */
229static void
230point_to_public_sign_key (gcry_mpi_point_t q,
231 gcry_ctx_t ctx,
232 struct GNUNET_CRYPTO_EccPublicSignKey *pub)
233{
234 gcry_mpi_t q_x;
235 gcry_mpi_t q_y;
236
237 q_x = gcry_mpi_new (256);
238 q_y = gcry_mpi_new (256);
239 if (gcry_mpi_ec_get_affine (q_x, q_y, q, ctx))
240 {
241 LOG_GCRY (GNUNET_ERROR_TYPE_ERROR, "get_affine failed", 0);
242 return;
243 }
244
245 mpi_print (pub->q_x, sizeof (pub->q_x), q_x);
246 mpi_print (pub->q_y, sizeof (pub->q_y), q_y);
247 gcry_mpi_release (q_x);
248 gcry_mpi_release (q_y);
249}
250
251
252/**
253 * Initialize public key struct from the respective point
254 * on the curve.
255 *
256 * @param q point on curve
257 * @param pub public key struct to initialize
258 * @param ctx context to use for ECC operations
259 */
260static void
261point_to_public_encrypt_key (gcry_mpi_point_t q,
262 gcry_ctx_t ctx,
263 struct GNUNET_CRYPTO_EccPublicEncryptKey *pub)
264{
265 gcry_mpi_t q_x;
266 gcry_mpi_t q_y;
267
268 q_x = gcry_mpi_new (256);
269 q_y = gcry_mpi_new (256);
270 if (gcry_mpi_ec_get_affine (q_x, q_y, q, ctx))
271 {
272 LOG_GCRY (GNUNET_ERROR_TYPE_ERROR, "get_affine failed", 0);
273 return;
274 }
275
276 mpi_print (pub->q_x, sizeof (pub->q_x), q_x);
277 mpi_print (pub->q_y, sizeof (pub->q_y), q_y);
278 gcry_mpi_release (q_x);
279 gcry_mpi_release (q_y);
280}
281
282
283/**
284 * Extract the public key for the given private key. 220 * Extract the public key for the given private key.
285 * 221 *
286 * @param priv the private key 222 * @param priv the private key
@@ -292,16 +228,22 @@ GNUNET_CRYPTO_ecc_key_get_public_for_signature (const struct GNUNET_CRYPTO_EccPr
292{ 228{
293 gcry_sexp_t sexp; 229 gcry_sexp_t sexp;
294 gcry_ctx_t ctx; 230 gcry_ctx_t ctx;
295 gcry_mpi_point_t q; 231 gcry_mpi_t q_y;
296 232
297 sexp = decode_private_key (priv); 233 sexp = decode_private_key (priv);
234 gcry_sexp_dump (sexp);
298 GNUNET_assert (NULL != sexp); 235 GNUNET_assert (NULL != sexp);
299 GNUNET_assert (0 == gcry_mpi_ec_new (&ctx, sexp, NULL)); 236 GNUNET_assert (0 == gcry_mpi_ec_new (&ctx, sexp, NULL));
300 gcry_sexp_release (sexp); 237 gcry_sexp_release (sexp);
301 q = gcry_mpi_ec_get_point ("q", ctx, 0); 238 if (NULL == (q_y = gcry_mpi_ec_get_mpi ("y", ctx, 0)))
302 point_to_public_sign_key (q, ctx, pub); 239 {
240 LOG_GCRY (GNUNET_ERROR_TYPE_ERROR,
241 "gcry_mpi_ec_get_mpi failed", 0);
242 return;
243 }
244 mpi_print (pub->q_y, sizeof (pub->q_y), q_y);
303 gcry_ctx_release (ctx); 245 gcry_ctx_release (ctx);
304 gcry_mpi_point_release (q); 246 // gcry_mpi_release (q_y); /* needed? we set copy to 0... */
305} 247}
306 248
307 249
@@ -317,16 +259,20 @@ GNUNET_CRYPTO_ecc_key_get_public_for_encryption (const struct GNUNET_CRYPTO_EccP
317{ 259{
318 gcry_sexp_t sexp; 260 gcry_sexp_t sexp;
319 gcry_ctx_t ctx; 261 gcry_ctx_t ctx;
320 gcry_mpi_point_t q; 262 gcry_mpi_t q_x;
321 263
322 sexp = decode_private_key (priv); 264 sexp = decode_private_key (priv);
323 GNUNET_assert (NULL != sexp); 265 GNUNET_assert (NULL != sexp);
324 GNUNET_assert (0 == gcry_mpi_ec_new (&ctx, sexp, NULL)); 266 GNUNET_assert (0 == gcry_mpi_ec_new (&ctx, sexp, NULL));
325 gcry_sexp_release (sexp); 267 gcry_sexp_release (sexp);
326 q = gcry_mpi_ec_get_point ("q", ctx, 0); 268 if (NULL == (q_x = gcry_mpi_ec_get_mpi ("x", ctx, 0)))
327 point_to_public_encrypt_key (q, ctx, pub); 269 {
270 LOG_GCRY (GNUNET_ERROR_TYPE_ERROR,
271 "gcry_mpi_ec_get_mpi failed", 0);
272 return;
273 }
274 mpi_print (pub->q_x, sizeof (pub->q_x), q_x);
328 gcry_ctx_release (ctx); 275 gcry_ctx_release (ctx);
329 gcry_mpi_point_release (q);
330} 276}
331 277
332 278
@@ -401,22 +347,13 @@ static gcry_sexp_t
401decode_public_sign_key (const struct GNUNET_CRYPTO_EccPublicSignKey *pub) 347decode_public_sign_key (const struct GNUNET_CRYPTO_EccPublicSignKey *pub)
402{ 348{
403 gcry_sexp_t pub_sexp; 349 gcry_sexp_t pub_sexp;
404 gcry_mpi_t q_x;
405 gcry_mpi_t q_y; 350 gcry_mpi_t q_y;
406 gcry_mpi_point_t q;
407 gcry_ctx_t ctx; 351 gcry_ctx_t ctx;
408 352
409 mpi_scan (&q_x, pub->q_x, sizeof (pub->q_x));
410 mpi_scan (&q_y, pub->q_y, sizeof (pub->q_y)); 353 mpi_scan (&q_y, pub->q_y, sizeof (pub->q_y));
411 q = gcry_mpi_point_new (256);
412 gcry_mpi_point_set (q, q_x, q_y, GCRYMPI_CONST_ONE);
413 gcry_mpi_release (q_x);
414 gcry_mpi_release (q_y);
415
416 /* initialize 'ctx' with 'q' */
417 GNUNET_assert (0 == gcry_mpi_ec_new (&ctx, NULL, CURVE)); 354 GNUNET_assert (0 == gcry_mpi_ec_new (&ctx, NULL, CURVE));
418 gcry_mpi_ec_set_point ("q", q, ctx); 355 gcry_mpi_ec_set_mpi ("y", q_y, ctx);
419 gcry_mpi_point_release (q); 356 gcry_mpi_release (q_y);
420 357
421 /* convert 'ctx' to 'sexp' */ 358 /* convert 'ctx' to 'sexp' */
422 GNUNET_assert (0 == gcry_pubkey_get_sexp (&pub_sexp, GCRY_PK_GET_PUBKEY, ctx)); 359 GNUNET_assert (0 == gcry_pubkey_get_sexp (&pub_sexp, GCRY_PK_GET_PUBKEY, ctx));
@@ -453,7 +390,7 @@ GNUNET_CRYPTO_ecc_key_create ()
453 int rc; 390 int rc;
454 391
455 if (0 != (rc = gcry_sexp_build (&s_keyparam, NULL, 392 if (0 != (rc = gcry_sexp_build (&s_keyparam, NULL,
456 "(genkey(ecdsa(curve \"" CURVE "\")))"))) 393 "(genkey(ecc(curve \"" CURVE "\")))")))
457 { 394 {
458 LOG_GCRY (GNUNET_ERROR_TYPE_ERROR, "gcry_sexp_build", rc); 395 LOG_GCRY (GNUNET_ERROR_TYPE_ERROR, "gcry_sexp_build", rc);
459 return NULL; 396 return NULL;
@@ -777,7 +714,7 @@ data_to_pkcs1 (const struct GNUNET_CRYPTO_EccSignaturePurpose *purpose)
777 714
778 GNUNET_CRYPTO_hash (purpose, ntohl (purpose->size), &hc); 715 GNUNET_CRYPTO_hash (purpose, ntohl (purpose->size), &hc);
779 if (0 != (rc = gcry_sexp_build (&data, NULL, 716 if (0 != (rc = gcry_sexp_build (&data, NULL,
780 "(data(flags rfc6979)(hash %s %b))", 717 "(data(flags eddsa)(hash %s %b))",
781 "sha512", 718 "sha512",
782 sizeof (hc), 719 sizeof (hc),
783 &hc))) 720 &hc)))
@@ -869,7 +806,7 @@ GNUNET_CRYPTO_ecc_verify (uint32_t purpose,
869 mpi_scan (&r, sig->r, sizeof (sig->r)); 806 mpi_scan (&r, sig->r, sizeof (sig->r));
870 mpi_scan (&s, sig->s, sizeof (sig->s)); 807 mpi_scan (&s, sig->s, sizeof (sig->s));
871 if (0 != (rc = gcry_sexp_build (&sig_sexpr, NULL, 808 if (0 != (rc = gcry_sexp_build (&sig_sexpr, NULL,
872 "(sig-val(ecdsa(r %m)(s %m)))", 809 "(sig-val(eddsa(r %m)(s %m)))",
873 r, s))) 810 r, s)))
874 { 811 {
875 LOG_GCRY (GNUNET_ERROR_TYPE_ERROR, "gcry_sexp_build", rc); 812 LOG_GCRY (GNUNET_ERROR_TYPE_ERROR, "gcry_sexp_build", rc);
@@ -913,21 +850,15 @@ decode_public_encrypt_key (const struct GNUNET_CRYPTO_EccPublicEncryptKey *pub)
913{ 850{
914 gcry_sexp_t pub_sexp; 851 gcry_sexp_t pub_sexp;
915 gcry_mpi_t q_x; 852 gcry_mpi_t q_x;
916 gcry_mpi_t q_y;
917 gcry_mpi_point_t q;
918 gcry_ctx_t ctx; 853 gcry_ctx_t ctx;
854 int rc;
919 855
920 mpi_scan (&q_x, pub->q_x, sizeof (pub->q_x)); 856 mpi_scan (&q_x, pub->q_x, sizeof (pub->q_x));
921 mpi_scan (&q_y, pub->q_y, sizeof (pub->q_y)); 857 /* initialize 'ctx' with 'x' */
922 q = gcry_mpi_point_new (256);
923 gcry_mpi_point_set (q, q_x, q_y, GCRYMPI_CONST_ONE);
924 gcry_mpi_release (q_x);
925 gcry_mpi_release (q_y);
926
927 /* initialize 'ctx' with 'q' */
928 GNUNET_assert (0 == gcry_mpi_ec_new (&ctx, NULL, CURVE)); 858 GNUNET_assert (0 == gcry_mpi_ec_new (&ctx, NULL, CURVE));
929 gcry_mpi_ec_set_point ("q", q, ctx); 859 if (0 != (rc = gcry_mpi_ec_set_mpi ("x", q_x, ctx)))
930 gcry_mpi_point_release (q); 860 LOG_GCRY (GNUNET_ERROR_TYPE_ERROR, "gcry_mpi_ec_set_mpi", rc);
861 gcry_mpi_release (q_x);
931 862
932 /* convert 'ctx' to 'sexp' */ 863 /* convert 'ctx' to 'sexp' */
933 GNUNET_assert (0 == gcry_pubkey_get_sexp (&pub_sexp, GCRY_PK_GET_PUBKEY, ctx)); 864 GNUNET_assert (0 == gcry_pubkey_get_sexp (&pub_sexp, GCRY_PK_GET_PUBKEY, ctx));
@@ -957,6 +888,7 @@ GNUNET_CRYPTO_ecc_ecdh (const struct GNUNET_CRYPTO_EccPrivateKey *priv,
957 gcry_mpi_t result_x; 888 gcry_mpi_t result_x;
958 gcry_mpi_t result_y; 889 gcry_mpi_t result_y;
959 unsigned char xbuf[256 / 8]; 890 unsigned char xbuf[256 / 8];
891 int rc;
960 892
961 /* first, extract the q = dP value from the public key */ 893 /* first, extract the q = dP value from the public key */
962 if (! (pub_sexpr = decode_public_encrypt_key (pub))) 894 if (! (pub_sexpr = decode_public_encrypt_key (pub)))
@@ -964,6 +896,11 @@ GNUNET_CRYPTO_ecc_ecdh (const struct GNUNET_CRYPTO_EccPrivateKey *priv,
964 GNUNET_assert (0 == gcry_mpi_ec_new (&ctx, pub_sexpr, NULL)); 896 GNUNET_assert (0 == gcry_mpi_ec_new (&ctx, pub_sexpr, NULL));
965 gcry_sexp_release (pub_sexpr); 897 gcry_sexp_release (pub_sexpr);
966 q = gcry_mpi_ec_get_point ("q", ctx, 0); 898 q = gcry_mpi_ec_get_point ("q", ctx, 0);
899 if (NULL == q)
900 {
901 LOG_GCRY (GNUNET_ERROR_TYPE_ERROR, "gcry_mpi_ec_get_point", 0);
902 return GNUNET_SYSERR;
903 }
967 904
968 /* second, extract the d value from our private key */ 905 /* second, extract the d value from our private key */
969 mpi_scan (&d, priv->d, sizeof (priv->d)); 906 mpi_scan (&d, priv->d, sizeof (priv->d));
@@ -977,9 +914,9 @@ GNUNET_CRYPTO_ecc_ecdh (const struct GNUNET_CRYPTO_EccPrivateKey *priv,
977 /* finally, convert point to string for hashing */ 914 /* finally, convert point to string for hashing */
978 result_x = gcry_mpi_new (256); 915 result_x = gcry_mpi_new (256);
979 result_y = gcry_mpi_new (256); 916 result_y = gcry_mpi_new (256);
980 if (gcry_mpi_ec_get_affine (result_x, result_y, result, ctx)) 917 if (0 != (rc = gcry_mpi_ec_get_affine (result_x, result_y, result, ctx)))
981 { 918 {
982 LOG_GCRY (GNUNET_ERROR_TYPE_ERROR, "get_affine failed", 0); 919 LOG_GCRY (GNUNET_ERROR_TYPE_ERROR, "gcry_mpi_ec_get_affine", rc);
983 gcry_mpi_point_release (result); 920 gcry_mpi_point_release (result);
984 gcry_ctx_release (ctx); 921 gcry_ctx_release (ctx);
985 return GNUNET_SYSERR; 922 return GNUNET_SYSERR;
@@ -1087,37 +1024,49 @@ GNUNET_CRYPTO_ecc_public_key_derive (const struct GNUNET_CRYPTO_EccPublicSignKey
1087 gcry_mpi_t h; 1024 gcry_mpi_t h;
1088 gcry_mpi_t n; 1025 gcry_mpi_t n;
1089 gcry_mpi_t h_mod_n; 1026 gcry_mpi_t h_mod_n;
1090 gcry_mpi_t q_x;
1091 gcry_mpi_t q_y; 1027 gcry_mpi_t q_y;
1092 gcry_mpi_point_t q; 1028 gcry_mpi_point_t q;
1093 gcry_mpi_point_t v; 1029 gcry_mpi_point_t v;
1030 int rc;
1094 1031
1095 GNUNET_assert (0 == gcry_mpi_ec_new (&ctx, NULL, CURVE)); 1032 GNUNET_assert (0 == gcry_mpi_ec_new (&ctx, NULL, CURVE));
1096 1033
1097 /* obtain point 'q' from original public key */ 1034 /* obtain point 'y' from original public key */
1098 mpi_scan (&q_x, pub->q_x, sizeof (pub->q_x));
1099 mpi_scan (&q_y, pub->q_y, sizeof (pub->q_y)); 1035 mpi_scan (&q_y, pub->q_y, sizeof (pub->q_y));
1100 1036 if (0 != (rc = gcry_mpi_ec_set_mpi ("y", q_y, ctx)))
1101 q = gcry_mpi_point_new (0); 1037 {
1102 gcry_mpi_point_set (q, q_x, q_y, GCRYMPI_CONST_ONE); 1038 LOG_GCRY (GNUNET_ERROR_TYPE_ERROR, "gcry_mpi_ec_set_mpi", rc);
1103 gcry_mpi_release (q_x); 1039 GNUNET_assert (0);
1040 }
1104 gcry_mpi_release (q_y); 1041 gcry_mpi_release (q_y);
1105 1042
1106 /* calulcate h_mod_n = h % n */ 1043 /* calulcate h_mod_n = h % n */
1107 h = derive_h (pub, label, context); 1044 h = derive_h (pub, label, context);
1108 n = gcry_mpi_ec_get_mpi ("n", ctx, 1); 1045 n = gcry_mpi_ec_get_mpi ("n", ctx, 1);
1046 GNUNET_assert (NULL != n);
1109 h_mod_n = gcry_mpi_new (256); 1047 h_mod_n = gcry_mpi_new (256);
1110 gcry_mpi_mod (h_mod_n, h, n); 1048 gcry_mpi_mod (h_mod_n, h, n);
1111 /* calculate v = h_mod_n * q */ 1049 /* calculate v = h_mod_n * q */
1112 v = gcry_mpi_point_new (0); 1050 v = gcry_mpi_point_new (0);
1051 q = gcry_mpi_ec_get_point ("q", ctx, 0);
1052 GNUNET_assert (NULL != q);
1113 gcry_mpi_ec_mul (v, h_mod_n, q, ctx); 1053 gcry_mpi_ec_mul (v, h_mod_n, q, ctx);
1114 gcry_mpi_release (h_mod_n); 1054 gcry_mpi_release (h_mod_n);
1115 gcry_mpi_release (h); 1055 gcry_mpi_release (h);
1116 gcry_mpi_release (n); 1056 gcry_mpi_release (n);
1117 gcry_mpi_point_release (q); 1057 gcry_mpi_point_release (q);
1118 /* convert point 'v' to public key that we return */ 1058 /* convert point 'v' to public key that we return */
1119 point_to_public_sign_key (v, ctx, result); 1059 if (0 != (rc = gcry_mpi_ec_set_point ("q", v, ctx)))
1060 LOG_GCRY (GNUNET_ERROR_TYPE_ERROR, "gcry_mpi_ec_set_point", rc);
1120 gcry_mpi_point_release (v); 1061 gcry_mpi_point_release (v);
1062 if (NULL == (q_y = gcry_mpi_ec_get_mpi ("y", ctx, 0)))
1063 {
1064 LOG_GCRY (GNUNET_ERROR_TYPE_ERROR,
1065 "gcry_mpi_ec_get_mpi", 0);
1066 GNUNET_assert (0);
1067 }
1068 mpi_print (result->q_y, sizeof (result->q_y), q_y);
1069 // gcry_mpi_release (q_y); /* needed? we set copy to 0... */
1121 gcry_ctx_release (ctx); 1070 gcry_ctx_release (ctx);
1122} 1071}
1123 1072