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