diff options
author | Christian Grothoff <christian@grothoff.org> | 2013-08-07 21:27:39 +0000 |
---|---|---|
committer | Christian Grothoff <christian@grothoff.org> | 2013-08-07 21:27:39 +0000 |
commit | 86032069a343d87fe79c8cb7d05a975dc81c2d70 (patch) | |
tree | ba80da3a173977890ca03c55793ee64bde3d8d73 /src/util/crypto_ecc.c | |
parent | 1fb28e00ee7b770049328a9d880b00f553599e9a (diff) | |
download | gnunet-86032069a343d87fe79c8cb7d05a975dc81c2d70.tar.gz gnunet-86032069a343d87fe79c8cb7d05a975dc81c2d70.zip |
-testcase for new ECC crypto functions
Diffstat (limited to 'src/util/crypto_ecc.c')
-rw-r--r-- | src/util/crypto_ecc.c | 115 |
1 files changed, 38 insertions, 77 deletions
diff --git a/src/util/crypto_ecc.c b/src/util/crypto_ecc.c index 122c1857d..1569c6a23 100644 --- a/src/util/crypto_ecc.c +++ b/src/util/crypto_ecc.c | |||
@@ -203,19 +203,18 @@ decode_private_key (const struct GNUNET_CRYPTO_EccPrivateKey *priv) | |||
203 | { | 203 | { |
204 | gcry_sexp_t result; | 204 | gcry_sexp_t result; |
205 | gcry_mpi_t d; | 205 | gcry_mpi_t d; |
206 | size_t erroff; | ||
207 | int rc; | 206 | int rc; |
208 | 207 | ||
209 | mpi_scan (&d, | 208 | mpi_scan (&d, |
210 | priv->d, | 209 | priv->d, |
211 | sizeof (priv->d)); | 210 | sizeof (priv->d)); |
212 | rc = gcry_sexp_build (&result, &erroff, | 211 | rc = gcry_sexp_build (&result, NULL, |
213 | "(private-key(ecdsa(curve \"" CURVE "\")(d %m)))", | 212 | "(private-key(ecdsa(curve \"" CURVE "\")(d %m)))", |
214 | d); | 213 | d); |
215 | gcry_mpi_release (d); | 214 | gcry_mpi_release (d); |
216 | if (0 != rc) | 215 | if (0 != rc) |
217 | { | 216 | { |
218 | LOG_GCRY (GNUNET_ERROR_TYPE_ERROR, "gcry_sexp_build", rc); /* erroff gives more info */ | 217 | LOG_GCRY (GNUNET_ERROR_TYPE_ERROR, "gcry_sexp_build", rc); |
219 | GNUNET_assert (0); | 218 | GNUNET_assert (0); |
220 | } | 219 | } |
221 | #if EXTRA_CHECKS | 220 | #if EXTRA_CHECKS |
@@ -244,7 +243,7 @@ point_to_public_key (gcry_mpi_point_t q, | |||
244 | { | 243 | { |
245 | gcry_mpi_t q_x; | 244 | gcry_mpi_t q_x; |
246 | gcry_mpi_t q_y; | 245 | gcry_mpi_t q_y; |
247 | 246 | ||
248 | q_x = gcry_mpi_new (256); | 247 | q_x = gcry_mpi_new (256); |
249 | q_y = gcry_mpi_new (256); | 248 | q_y = gcry_mpi_new (256); |
250 | if (gcry_mpi_ec_get_affine (q_x, q_y, q, ctx)) | 249 | if (gcry_mpi_ec_get_affine (q_x, q_y, q, ctx)) |
@@ -272,15 +271,10 @@ GNUNET_CRYPTO_ecc_key_get_public (const struct GNUNET_CRYPTO_EccPrivateKey *priv | |||
272 | gcry_sexp_t sexp; | 271 | gcry_sexp_t sexp; |
273 | gcry_ctx_t ctx; | 272 | gcry_ctx_t ctx; |
274 | gcry_mpi_point_t q; | 273 | gcry_mpi_point_t q; |
275 | int rc; | ||
276 | 274 | ||
277 | sexp = decode_private_key (priv); | 275 | sexp = decode_private_key (priv); |
278 | GNUNET_assert (NULL != sexp); | 276 | GNUNET_assert (NULL != sexp); |
279 | if (0 != (rc = gcry_mpi_ec_new (&ctx, sexp, NULL))) | 277 | GNUNET_assert (0 == gcry_mpi_ec_new (&ctx, sexp, NULL)); |
280 | { | ||
281 | LOG_GCRY (GNUNET_ERROR_TYPE_ERROR, "gcry_mpi_ec_new", rc); /* erroff gives more info */ | ||
282 | return; | ||
283 | } | ||
284 | gcry_sexp_release (sexp); | 278 | gcry_sexp_release (sexp); |
285 | q = gcry_mpi_ec_get_point ("q", ctx, 0); | 279 | q = gcry_mpi_ec_get_point ("q", ctx, 0); |
286 | point_to_public_key (q, ctx, pub); | 280 | point_to_public_key (q, ctx, pub); |
@@ -364,7 +358,6 @@ decode_public_key (const struct GNUNET_CRYPTO_EccPublicKey *pub) | |||
364 | gcry_mpi_t q_y; | 358 | gcry_mpi_t q_y; |
365 | gcry_mpi_point_t q; | 359 | gcry_mpi_point_t q; |
366 | gcry_ctx_t ctx; | 360 | gcry_ctx_t ctx; |
367 | int rc; | ||
368 | 361 | ||
369 | mpi_scan (&q_x, pub->q_x, sizeof (pub->q_x)); | 362 | mpi_scan (&q_x, pub->q_x, sizeof (pub->q_x)); |
370 | mpi_scan (&q_y, pub->q_y, sizeof (pub->q_y)); | 363 | mpi_scan (&q_y, pub->q_y, sizeof (pub->q_y)); |
@@ -373,24 +366,13 @@ decode_public_key (const struct GNUNET_CRYPTO_EccPublicKey *pub) | |||
373 | gcry_mpi_release (q_x); | 366 | gcry_mpi_release (q_x); |
374 | gcry_mpi_release (q_y); | 367 | gcry_mpi_release (q_y); |
375 | 368 | ||
376 | /* create basic ECC context */ | ||
377 | if (0 != (rc = gcry_mpi_ec_new (&ctx, NULL, CURVE))) | ||
378 | { | ||
379 | LOG_GCRY (GNUNET_ERROR_TYPE_ERROR, "gcry_mpi_ec_new", rc); /* erroff gives more info */ | ||
380 | gcry_mpi_point_release (q); | ||
381 | return NULL; | ||
382 | } | ||
383 | /* initialize 'ctx' with 'q' */ | 369 | /* initialize 'ctx' with 'q' */ |
370 | GNUNET_assert (0 == gcry_mpi_ec_new (&ctx, NULL, CURVE)); | ||
384 | gcry_mpi_ec_set_point ("q", q, ctx); | 371 | gcry_mpi_ec_set_point ("q", q, ctx); |
385 | gcry_mpi_point_release (q); | 372 | gcry_mpi_point_release (q); |
386 | 373 | ||
387 | /* convert 'ctx' to 'sexp' */ | 374 | /* convert 'ctx' to 'sexp' */ |
388 | if (0 != (rc = gcry_pubkey_get_sexp (&pub_sexp, GCRY_PK_GET_PUBKEY, ctx))) | 375 | GNUNET_assert (0 == gcry_pubkey_get_sexp (&pub_sexp, GCRY_PK_GET_PUBKEY, ctx)); |
389 | { | ||
390 | LOG_GCRY (GNUNET_ERROR_TYPE_ERROR, "gcry_sexp_from_context", rc); | ||
391 | gcry_ctx_release (ctx); | ||
392 | return NULL; | ||
393 | } | ||
394 | gcry_ctx_release (ctx); | 376 | gcry_ctx_release (ctx); |
395 | return pub_sexp; | 377 | return pub_sexp; |
396 | } | 378 | } |
@@ -438,7 +420,7 @@ GNUNET_CRYPTO_ecc_key_create () | |||
438 | return NULL; | 420 | return NULL; |
439 | } | 421 | } |
440 | gcry_sexp_release (priv_sexp); | 422 | gcry_sexp_release (priv_sexp); |
441 | priv = GNUNET_malloc (sizeof (struct GNUNET_CRYPTO_EccPrivateKey)); | 423 | priv = GNUNET_new (struct GNUNET_CRYPTO_EccPrivateKey); |
442 | mpi_print (priv->d, sizeof (priv->d), d); | 424 | mpi_print (priv->d, sizeof (priv->d), d); |
443 | gcry_mpi_release (d); | 425 | gcry_mpi_release (d); |
444 | return priv; | 426 | return priv; |
@@ -521,7 +503,7 @@ GNUNET_CRYPTO_ecc_key_create_from_file (const char *filename) | |||
521 | GNUNET_DISK_PERM_USER_WRITE); | 503 | GNUNET_DISK_PERM_USER_WRITE); |
522 | if (NULL == fd) | 504 | if (NULL == fd) |
523 | { | 505 | { |
524 | if (errno == EEXIST) | 506 | if (EEXIST == errno) |
525 | { | 507 | { |
526 | if (GNUNET_YES != GNUNET_DISK_file_test (filename)) | 508 | if (GNUNET_YES != GNUNET_DISK_file_test (filename)) |
527 | { | 509 | { |
@@ -538,7 +520,6 @@ GNUNET_CRYPTO_ecc_key_create_from_file (const char *filename) | |||
538 | return NULL; | 520 | return NULL; |
539 | } | 521 | } |
540 | cnt = 0; | 522 | cnt = 0; |
541 | |||
542 | while (GNUNET_YES != | 523 | while (GNUNET_YES != |
543 | GNUNET_DISK_file_lock (fd, 0, | 524 | GNUNET_DISK_file_lock (fd, 0, |
544 | sizeof (struct GNUNET_CRYPTO_EccPrivateKey), | 525 | sizeof (struct GNUNET_CRYPTO_EccPrivateKey), |
@@ -816,7 +797,6 @@ GNUNET_CRYPTO_ecc_verify (uint32_t purpose, | |||
816 | gcry_sexp_t data; | 797 | gcry_sexp_t data; |
817 | gcry_sexp_t sig_sexpr; | 798 | gcry_sexp_t sig_sexpr; |
818 | gcry_sexp_t pub_sexpr; | 799 | gcry_sexp_t pub_sexpr; |
819 | size_t erroff; | ||
820 | int rc; | 800 | int rc; |
821 | gcry_mpi_t r; | 801 | gcry_mpi_t r; |
822 | gcry_mpi_t s; | 802 | gcry_mpi_t s; |
@@ -827,7 +807,8 @@ GNUNET_CRYPTO_ecc_verify (uint32_t purpose, | |||
827 | /* build s-expression for signature */ | 807 | /* build s-expression for signature */ |
828 | mpi_scan (&r, sig->r, sizeof (sig->r)); | 808 | mpi_scan (&r, sig->r, sizeof (sig->r)); |
829 | mpi_scan (&s, sig->s, sizeof (sig->s)); | 809 | mpi_scan (&s, sig->s, sizeof (sig->s)); |
830 | if (0 != (rc = gcry_sexp_build (&sig_sexpr, &erroff, "(sig-val(ecdsa(r %m)(s %m)))", | 810 | if (0 != (rc = gcry_sexp_build (&sig_sexpr, NULL, |
811 | "(sig-val(ecdsa(r %m)(s %m)))", | ||
831 | r, s))) | 812 | r, s))) |
832 | { | 813 | { |
833 | LOG_GCRY (GNUNET_ERROR_TYPE_ERROR, "gcry_sexp_build", rc); | 814 | LOG_GCRY (GNUNET_ERROR_TYPE_ERROR, "gcry_sexp_build", rc); |
@@ -873,9 +854,9 @@ GNUNET_CRYPTO_ecc_ecdh (const struct GNUNET_CRYPTO_EccPrivateKey *priv, | |||
873 | struct GNUNET_HashCode *key_material) | 854 | struct GNUNET_HashCode *key_material) |
874 | { | 855 | { |
875 | size_t slen; | 856 | size_t slen; |
876 | size_t erroff; | 857 | unsigned char sdata_buf[2048]; /* big enough to print |
877 | int rc; | 858 | dh-shared-secret as |
878 | unsigned char sdata_buf[2048]; /* big enough to print dh-shared-secret as S-expression */ | 859 | S-expression */ |
879 | gcry_mpi_point_t result; | 860 | gcry_mpi_point_t result; |
880 | gcry_mpi_point_t q; | 861 | gcry_mpi_point_t q; |
881 | gcry_mpi_t d; | 862 | gcry_mpi_t d; |
@@ -884,34 +865,19 @@ GNUNET_CRYPTO_ecc_ecdh (const struct GNUNET_CRYPTO_EccPrivateKey *priv, | |||
884 | gcry_sexp_t ecdh_sexp; | 865 | gcry_sexp_t ecdh_sexp; |
885 | gcry_mpi_t result_x; | 866 | gcry_mpi_t result_x; |
886 | gcry_mpi_t result_y; | 867 | gcry_mpi_t result_y; |
868 | int rc; | ||
887 | 869 | ||
888 | /* first, extract the q = dP value from the public key */ | 870 | /* first, extract the q = dP value from the public key */ |
889 | if (! (pub_sexpr = decode_public_key (pub))) | 871 | if (! (pub_sexpr = decode_public_key (pub))) |
890 | return GNUNET_SYSERR; | 872 | return GNUNET_SYSERR; |
891 | if (0 != (rc = gcry_mpi_ec_new (&ctx, pub_sexpr, NULL))) | 873 | GNUNET_assert (0 == gcry_mpi_ec_new (&ctx, pub_sexpr, NULL)); |
892 | { | ||
893 | LOG_GCRY (GNUNET_ERROR_TYPE_ERROR, "gcry_mpi_ec_new", rc); /* erroff gives more info */ | ||
894 | return GNUNET_SYSERR; | ||
895 | } | ||
896 | gcry_sexp_release (pub_sexpr); | 874 | gcry_sexp_release (pub_sexpr); |
897 | q = gcry_mpi_ec_get_point ("q", ctx, 0); | 875 | q = gcry_mpi_ec_get_point ("q", ctx, 0); |
898 | gcry_ctx_release (ctx); | ||
899 | 876 | ||
900 | /* second, extract the d value from our private key */ | 877 | /* second, extract the d value from our private key */ |
901 | mpi_scan (&d, priv->d, sizeof (priv->d)); | 878 | mpi_scan (&d, priv->d, sizeof (priv->d)); |
902 | 879 | ||
903 | /* create a new context for definitively the correct curve; | ||
904 | theoretically the 'public_key' might not use the right curve */ | ||
905 | if (0 != (rc = gcry_mpi_ec_new (&ctx, NULL, CURVE))) | ||
906 | { | ||
907 | LOG_GCRY (GNUNET_ERROR_TYPE_ERROR, "gcry_mpi_ec_new", rc); /* erroff gives more info */ | ||
908 | gcry_mpi_release (d); | ||
909 | gcry_mpi_point_release (q); | ||
910 | return GNUNET_SYSERR; | ||
911 | } | ||
912 | |||
913 | /* then call the 'multiply' function, to compute the product */ | 880 | /* then call the 'multiply' function, to compute the product */ |
914 | GNUNET_assert (NULL != ctx); | ||
915 | result = gcry_mpi_point_new (0); | 881 | result = gcry_mpi_point_new (0); |
916 | gcry_mpi_ec_mul (result, d, q, ctx); | 882 | gcry_mpi_ec_mul (result, d, q, ctx); |
917 | gcry_mpi_point_release (q); | 883 | gcry_mpi_point_release (q); |
@@ -929,12 +895,12 @@ GNUNET_CRYPTO_ecc_ecdh (const struct GNUNET_CRYPTO_EccPrivateKey *priv, | |||
929 | } | 895 | } |
930 | gcry_mpi_point_release (result); | 896 | gcry_mpi_point_release (result); |
931 | gcry_ctx_release (ctx); | 897 | gcry_ctx_release (ctx); |
932 | if (0 != (rc = gcry_sexp_build (&ecdh_sexp, &erroff, | 898 | if (0 != (rc = gcry_sexp_build (&ecdh_sexp, NULL, |
933 | "(dh-shared-secret (x %m)(y %m))", | 899 | "(dh-shared-secret (x %m)(y %m))", |
934 | result_x, | 900 | result_x, |
935 | result_y))) | 901 | result_y))) |
936 | { | 902 | { |
937 | LOG_GCRY (GNUNET_ERROR_TYPE_ERROR, "gcry_sexp_build", rc); /* erroff gives more info */ | 903 | LOG_GCRY (GNUNET_ERROR_TYPE_ERROR, "gcry_sexp_build", rc); |
938 | gcry_mpi_release (result_x); | 904 | gcry_mpi_release (result_x); |
939 | gcry_mpi_release (result_y); | 905 | gcry_mpi_release (result_y); |
940 | return GNUNET_SYSERR; | 906 | return GNUNET_SYSERR; |
@@ -998,24 +964,17 @@ GNUNET_CRYPTO_ecc_key_derive (const struct GNUNET_CRYPTO_EccPrivateKey *priv, | |||
998 | gcry_mpi_t x; | 964 | gcry_mpi_t x; |
999 | gcry_mpi_t d; | 965 | gcry_mpi_t d; |
1000 | gcry_mpi_t n; | 966 | gcry_mpi_t n; |
1001 | int rc; | 967 | gcry_ctx_t ctx; |
1002 | 968 | ||
969 | GNUNET_assert (0 == gcry_mpi_ec_new (&ctx, NULL, CURVE)); | ||
970 | n = gcry_mpi_ec_get_mpi ("n", ctx, 0 /* no copy */); | ||
1003 | GNUNET_CRYPTO_ecc_key_get_public (priv, &pub); | 971 | GNUNET_CRYPTO_ecc_key_get_public (priv, &pub); |
1004 | h = derive_h (&pub, label); | 972 | h = derive_h (&pub, label); |
1005 | mpi_scan (&x, priv->d, sizeof (priv->d)); | 973 | mpi_scan (&x, priv->d, sizeof (priv->d)); |
1006 | /* initialize 'n' from P-256; hex copied from libgcrypt code */ | ||
1007 | if (0 != (rc = gcry_mpi_scan (&n, GCRYMPI_FMT_HEX, | ||
1008 | "0xffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632551", 0, NULL))) | ||
1009 | { | ||
1010 | LOG_GCRY (GNUNET_ERROR_TYPE_ERROR, "gcry_mpi_scan", rc); | ||
1011 | gcry_mpi_release (h); | ||
1012 | return NULL; | ||
1013 | } | ||
1014 | d = gcry_mpi_new (256); | 974 | d = gcry_mpi_new (256); |
1015 | gcry_mpi_mulm (d, h, x, n); | 975 | gcry_mpi_mulm (d, h, x, n); |
1016 | gcry_mpi_release (h); | 976 | gcry_mpi_release (h); |
1017 | gcry_mpi_release (x); | 977 | gcry_mpi_release (x); |
1018 | gcry_mpi_release (n); | ||
1019 | ret = GNUNET_new (struct GNUNET_CRYPTO_EccPrivateKey); | 978 | ret = GNUNET_new (struct GNUNET_CRYPTO_EccPrivateKey); |
1020 | mpi_print (ret->d, sizeof (ret->d), d); | 979 | mpi_print (ret->d, sizeof (ret->d), d); |
1021 | gcry_mpi_release (d); | 980 | gcry_mpi_release (d); |
@@ -1036,36 +995,38 @@ GNUNET_CRYPTO_ecc_public_key_derive (const struct GNUNET_CRYPTO_EccPublicKey *pu | |||
1036 | const char *label, | 995 | const char *label, |
1037 | struct GNUNET_CRYPTO_EccPublicKey *result) | 996 | struct GNUNET_CRYPTO_EccPublicKey *result) |
1038 | { | 997 | { |
1039 | gcry_mpi_t h; | ||
1040 | gcry_ctx_t ctx; | 998 | gcry_ctx_t ctx; |
999 | gcry_mpi_t h; | ||
1000 | gcry_mpi_t n; | ||
1001 | gcry_mpi_t h_mod_n; | ||
1041 | gcry_mpi_t q_x; | 1002 | gcry_mpi_t q_x; |
1042 | gcry_mpi_t q_y; | 1003 | gcry_mpi_t q_y; |
1043 | gcry_mpi_point_t q; | 1004 | gcry_mpi_point_t q; |
1044 | gcry_mpi_point_t v; | 1005 | gcry_mpi_point_t v; |
1045 | int rc; | ||
1046 | 1006 | ||
1047 | h = derive_h (pub, label); | 1007 | GNUNET_assert (0 == gcry_mpi_ec_new (&ctx, NULL, CURVE)); |
1008 | |||
1009 | /* obtain point 'q' from original public key */ | ||
1048 | mpi_scan (&q_x, pub->q_x, sizeof (pub->q_x)); | 1010 | mpi_scan (&q_x, pub->q_x, sizeof (pub->q_x)); |
1049 | mpi_scan (&q_y, pub->q_y, sizeof (pub->q_y)); | 1011 | mpi_scan (&q_y, pub->q_y, sizeof (pub->q_y)); |
1050 | q = gcry_mpi_point_new (256); | 1012 | |
1013 | q = gcry_mpi_point_new (0); | ||
1051 | gcry_mpi_point_set (q, q_x, q_y, GCRYMPI_CONST_ONE); | 1014 | gcry_mpi_point_set (q, q_x, q_y, GCRYMPI_CONST_ONE); |
1052 | gcry_mpi_release (q_x); | 1015 | gcry_mpi_release (q_x); |
1053 | gcry_mpi_release (q_y); | 1016 | gcry_mpi_release (q_y); |
1054 | 1017 | ||
1055 | /* create basic ECC context */ | 1018 | /* calulcate h_mod_n = h % n */ |
1056 | if (0 != (rc = gcry_mpi_ec_new (&ctx, NULL, CURVE))) | 1019 | h = derive_h (pub, label); |
1057 | { | 1020 | n = gcry_mpi_ec_get_mpi ("n", ctx, 0 /* no copy */); |
1058 | LOG_GCRY (GNUNET_ERROR_TYPE_ERROR, "gcry_mpi_ec_new", rc); | 1021 | h_mod_n = gcry_mpi_new (256); |
1059 | gcry_mpi_point_release (q); | 1022 | gcry_mpi_mod (h_mod_n, h, n); |
1060 | gcry_mpi_release (h); | 1023 | /* calculate v = h_mod_n * q */ |
1061 | return; | 1024 | v = gcry_mpi_point_new (0); |
1062 | } | 1025 | gcry_mpi_ec_mul (v, h_mod_n, q, ctx); |
1063 | v = gcry_mpi_point_new (256); | 1026 | gcry_mpi_release (h_mod_n); |
1064 | /* we could calculate 'h mod n' here first, but hopefully | ||
1065 | libgcrypt is smart enough to do that for us... */ | ||
1066 | gcry_mpi_ec_mul (v, h, q, ctx); | ||
1067 | gcry_mpi_release (h); | 1027 | gcry_mpi_release (h); |
1068 | gcry_mpi_point_release (q); | 1028 | gcry_mpi_point_release (q); |
1029 | /* convert point 'v' to public key that we return */ | ||
1069 | point_to_public_key (v, ctx, result); | 1030 | point_to_public_key (v, ctx, result); |
1070 | gcry_mpi_point_release (v); | 1031 | gcry_mpi_point_release (v); |
1071 | gcry_ctx_release (ctx); | 1032 | gcry_ctx_release (ctx); |