diff options
author | Christian Grothoff <christian@grothoff.org> | 2019-06-14 19:18:01 +0200 |
---|---|---|
committer | Christian Grothoff <christian@grothoff.org> | 2019-06-14 19:18:12 +0200 |
commit | ce2f5491241f0fd46ebfb4563b5d020717898613 (patch) | |
tree | 3e52ccb600869d23d78194b041edbefef58c9866 /src/util/crypto_ecc.c | |
parent | 2a7c0cbbc0e81baef36446683c7e220eca1760c6 (diff) | |
download | gnunet-ce2f5491241f0fd46ebfb4563b5d020717898613.tar.gz gnunet-ce2f5491241f0fd46ebfb4563b5d020717898613.zip |
add option to display private keys
Diffstat (limited to 'src/util/crypto_ecc.c')
-rw-r--r-- | src/util/crypto_ecc.c | 511 |
1 files changed, 290 insertions, 221 deletions
diff --git a/src/util/crypto_ecc.c b/src/util/crypto_ecc.c index 339180dff..ff9080345 100644 --- a/src/util/crypto_ecc.c +++ b/src/util/crypto_ecc.c | |||
@@ -39,18 +39,29 @@ | |||
39 | */ | 39 | */ |
40 | #define CURVE "Ed25519" | 40 | #define CURVE "Ed25519" |
41 | 41 | ||
42 | #define LOG(kind,...) GNUNET_log_from (kind, "util-crypto-ecc", __VA_ARGS__) | 42 | #define LOG(kind, ...) GNUNET_log_from (kind, "util-crypto-ecc", __VA_ARGS__) |
43 | 43 | ||
44 | #define LOG_STRERROR(kind,syscall) GNUNET_log_from_strerror (kind, "util-crypto-ecc", syscall) | 44 | #define LOG_STRERROR(kind, syscall) \ |
45 | GNUNET_log_from_strerror (kind, "util-crypto-ecc", syscall) | ||
45 | 46 | ||
46 | #define LOG_STRERROR_FILE(kind,syscall,filename) GNUNET_log_from_strerror_file (kind, "util-crypto-ecc", syscall, filename) | 47 | #define LOG_STRERROR_FILE(kind, syscall, filename) \ |
48 | GNUNET_log_from_strerror_file (kind, "util-crypto-ecc", syscall, filename) | ||
47 | 49 | ||
48 | /** | 50 | /** |
49 | * Log an error message at log-level 'level' that indicates | 51 | * Log an error message at log-level 'level' that indicates |
50 | * a failure of the command 'cmd' with the message given | 52 | * a failure of the command 'cmd' with the message given |
51 | * by gcry_strerror(rc). | 53 | * by gcry_strerror(rc). |
52 | */ | 54 | */ |
53 | #define LOG_GCRY(level, cmd, rc) do { LOG(level, _("`%s' failed at %s:%d with error: %s\n"), cmd, __FILE__, __LINE__, gcry_strerror(rc)); } while(0) | 55 | #define LOG_GCRY(level, cmd, rc) \ |
56 | do \ | ||
57 | { \ | ||
58 | LOG (level, \ | ||
59 | _ ("`%s' failed at %s:%d with error: %s\n"), \ | ||
60 | cmd, \ | ||
61 | __FILE__, \ | ||
62 | __LINE__, \ | ||
63 | gcry_strerror (rc)); \ | ||
64 | } while (0) | ||
54 | 65 | ||
55 | 66 | ||
56 | /** | 67 | /** |
@@ -63,7 +74,7 @@ | |||
63 | * @return 0 on success | 74 | * @return 0 on success |
64 | */ | 75 | */ |
65 | static int | 76 | static int |
66 | key_from_sexp (gcry_mpi_t * array, | 77 | key_from_sexp (gcry_mpi_t *array, |
67 | gcry_sexp_t sexp, | 78 | gcry_sexp_t sexp, |
68 | const char *topname, | 79 | const char *topname, |
69 | const char *elems) | 80 | const char *elems) |
@@ -95,7 +106,7 @@ key_from_sexp (gcry_mpi_t * array, | |||
95 | array[i] = NULL; | 106 | array[i] = NULL; |
96 | } | 107 | } |
97 | gcry_sexp_release (list); | 108 | gcry_sexp_release (list); |
98 | return 3; /* required parameter not found */ | 109 | return 3; /* required parameter not found */ |
99 | } | 110 | } |
100 | array[idx] = gcry_sexp_nth_mpi (l2, 1, GCRYMPI_FMT_USG); | 111 | array[idx] = gcry_sexp_nth_mpi (l2, 1, GCRYMPI_FMT_USG); |
101 | gcry_sexp_release (l2); | 112 | gcry_sexp_release (l2); |
@@ -107,7 +118,7 @@ key_from_sexp (gcry_mpi_t * array, | |||
107 | array[i] = NULL; | 118 | array[i] = NULL; |
108 | } | 119 | } |
109 | gcry_sexp_release (list); | 120 | gcry_sexp_release (list); |
110 | return 4; /* required parameter is invalid */ | 121 | return 4; /* required parameter is invalid */ |
111 | } | 122 | } |
112 | } | 123 | } |
113 | gcry_sexp_release (list); | 124 | gcry_sexp_release (list); |
@@ -128,10 +139,12 @@ decode_private_ecdsa_key (const struct GNUNET_CRYPTO_EcdsaPrivateKey *priv) | |||
128 | gcry_sexp_t result; | 139 | gcry_sexp_t result; |
129 | int rc; | 140 | int rc; |
130 | 141 | ||
131 | rc = gcry_sexp_build (&result, NULL, | 142 | rc = gcry_sexp_build (&result, |
132 | "(private-key(ecc(curve \"" CURVE "\")" | 143 | NULL, |
144 | "(private-key(ecc(curve \"" CURVE "\")" | ||
133 | "(d %b)))", | 145 | "(d %b)))", |
134 | (int) sizeof (priv->d), priv->d); | 146 | (int) sizeof (priv->d), |
147 | priv->d); | ||
135 | if (0 != rc) | 148 | if (0 != rc) |
136 | { | 149 | { |
137 | LOG_GCRY (GNUNET_ERROR_TYPE_ERROR, "gcry_sexp_build", rc); | 150 | LOG_GCRY (GNUNET_ERROR_TYPE_ERROR, "gcry_sexp_build", rc); |
@@ -161,10 +174,12 @@ decode_private_eddsa_key (const struct GNUNET_CRYPTO_EddsaPrivateKey *priv) | |||
161 | gcry_sexp_t result; | 174 | gcry_sexp_t result; |
162 | int rc; | 175 | int rc; |
163 | 176 | ||
164 | rc = gcry_sexp_build (&result, NULL, | 177 | rc = gcry_sexp_build (&result, |
165 | "(private-key(ecc(curve \"" CURVE "\")" | 178 | NULL, |
179 | "(private-key(ecc(curve \"" CURVE "\")" | ||
166 | "(flags eddsa)(d %b)))", | 180 | "(flags eddsa)(d %b)))", |
167 | (int)sizeof (priv->d), priv->d); | 181 | (int) sizeof (priv->d), |
182 | priv->d); | ||
168 | if (0 != rc) | 183 | if (0 != rc) |
169 | { | 184 | { |
170 | LOG_GCRY (GNUNET_ERROR_TYPE_ERROR, "gcry_sexp_build", rc); | 185 | LOG_GCRY (GNUNET_ERROR_TYPE_ERROR, "gcry_sexp_build", rc); |
@@ -194,10 +209,12 @@ decode_private_ecdhe_key (const struct GNUNET_CRYPTO_EcdhePrivateKey *priv) | |||
194 | gcry_sexp_t result; | 209 | gcry_sexp_t result; |
195 | int rc; | 210 | int rc; |
196 | 211 | ||
197 | rc = gcry_sexp_build (&result, NULL, | 212 | rc = gcry_sexp_build (&result, |
198 | "(private-key(ecc(curve \"" CURVE "\")" | 213 | NULL, |
214 | "(private-key(ecc(curve \"" CURVE "\")" | ||
199 | "(d %b)))", | 215 | "(d %b)))", |
200 | (int)sizeof (priv->d), priv->d); | 216 | (int) sizeof (priv->d), |
217 | priv->d); | ||
201 | if (0 != rc) | 218 | if (0 != rc) |
202 | { | 219 | { |
203 | LOG_GCRY (GNUNET_ERROR_TYPE_ERROR, "gcry_sexp_build", rc); | 220 | LOG_GCRY (GNUNET_ERROR_TYPE_ERROR, "gcry_sexp_build", rc); |
@@ -221,8 +238,9 @@ decode_private_ecdhe_key (const struct GNUNET_CRYPTO_EcdhePrivateKey *priv) | |||
221 | * @param pub where to write the public key | 238 | * @param pub where to write the public key |
222 | */ | 239 | */ |
223 | void | 240 | void |
224 | GNUNET_CRYPTO_ecdsa_key_get_public (const struct GNUNET_CRYPTO_EcdsaPrivateKey *priv, | 241 | GNUNET_CRYPTO_ecdsa_key_get_public ( |
225 | struct GNUNET_CRYPTO_EcdsaPublicKey *pub) | 242 | const struct GNUNET_CRYPTO_EcdsaPrivateKey *priv, |
243 | struct GNUNET_CRYPTO_EcdsaPublicKey *pub) | ||
226 | { | 244 | { |
227 | gcry_sexp_t sexp; | 245 | gcry_sexp_t sexp; |
228 | gcry_ctx_t ctx; | 246 | gcry_ctx_t ctx; |
@@ -251,8 +269,9 @@ GNUNET_CRYPTO_ecdsa_key_get_public (const struct GNUNET_CRYPTO_EcdsaPrivateKey * | |||
251 | * @param pub where to write the public key | 269 | * @param pub where to write the public key |
252 | */ | 270 | */ |
253 | void | 271 | void |
254 | GNUNET_CRYPTO_eddsa_key_get_public (const struct GNUNET_CRYPTO_EddsaPrivateKey *priv, | 272 | GNUNET_CRYPTO_eddsa_key_get_public ( |
255 | struct GNUNET_CRYPTO_EddsaPublicKey *pub) | 273 | const struct GNUNET_CRYPTO_EddsaPrivateKey *priv, |
274 | struct GNUNET_CRYPTO_EddsaPublicKey *pub) | ||
256 | { | 275 | { |
257 | gcry_sexp_t sexp; | 276 | gcry_sexp_t sexp; |
258 | gcry_ctx_t ctx; | 277 | gcry_ctx_t ctx; |
@@ -281,8 +300,9 @@ GNUNET_CRYPTO_eddsa_key_get_public (const struct GNUNET_CRYPTO_EddsaPrivateKey * | |||
281 | * @param pub where to write the public key | 300 | * @param pub where to write the public key |
282 | */ | 301 | */ |
283 | void | 302 | void |
284 | GNUNET_CRYPTO_ecdhe_key_get_public (const struct GNUNET_CRYPTO_EcdhePrivateKey *priv, | 303 | GNUNET_CRYPTO_ecdhe_key_get_public ( |
285 | struct GNUNET_CRYPTO_EcdhePublicKey *pub) | 304 | const struct GNUNET_CRYPTO_EcdhePrivateKey *priv, |
305 | struct GNUNET_CRYPTO_EcdhePublicKey *pub) | ||
286 | { | 306 | { |
287 | gcry_sexp_t sexp; | 307 | gcry_sexp_t sexp; |
288 | gcry_ctx_t ctx; | 308 | gcry_ctx_t ctx; |
@@ -311,7 +331,8 @@ GNUNET_CRYPTO_ecdhe_key_get_public (const struct GNUNET_CRYPTO_EcdhePrivateKey * | |||
311 | * @return string representing @a pub | 331 | * @return string representing @a pub |
312 | */ | 332 | */ |
313 | char * | 333 | char * |
314 | GNUNET_CRYPTO_ecdsa_public_key_to_string (const struct GNUNET_CRYPTO_EcdsaPublicKey *pub) | 334 | GNUNET_CRYPTO_ecdsa_public_key_to_string ( |
335 | const struct GNUNET_CRYPTO_EcdsaPublicKey *pub) | ||
315 | { | 336 | { |
316 | char *pubkeybuf; | 337 | char *pubkeybuf; |
317 | size_t keylen = (sizeof (struct GNUNET_CRYPTO_EcdsaPublicKey)) * 8; | 338 | size_t keylen = (sizeof (struct GNUNET_CRYPTO_EcdsaPublicKey)) * 8; |
@@ -321,10 +342,11 @@ GNUNET_CRYPTO_ecdsa_public_key_to_string (const struct GNUNET_CRYPTO_EcdsaPublic | |||
321 | keylen += 5 - keylen % 5; | 342 | keylen += 5 - keylen % 5; |
322 | keylen /= 5; | 343 | keylen /= 5; |
323 | pubkeybuf = GNUNET_malloc (keylen + 1); | 344 | pubkeybuf = GNUNET_malloc (keylen + 1); |
324 | end = GNUNET_STRINGS_data_to_string ((unsigned char *) pub, | 345 | end = |
325 | sizeof (struct GNUNET_CRYPTO_EcdsaPublicKey), | 346 | GNUNET_STRINGS_data_to_string ((unsigned char *) pub, |
326 | pubkeybuf, | 347 | sizeof (struct GNUNET_CRYPTO_EcdsaPublicKey), |
327 | keylen); | 348 | pubkeybuf, |
349 | keylen); | ||
328 | if (NULL == end) | 350 | if (NULL == end) |
329 | { | 351 | { |
330 | GNUNET_free (pubkeybuf); | 352 | GNUNET_free (pubkeybuf); |
@@ -342,7 +364,8 @@ GNUNET_CRYPTO_ecdsa_public_key_to_string (const struct GNUNET_CRYPTO_EcdsaPublic | |||
342 | * @return string representing @a pub | 364 | * @return string representing @a pub |
343 | */ | 365 | */ |
344 | char * | 366 | char * |
345 | GNUNET_CRYPTO_eddsa_public_key_to_string (const struct GNUNET_CRYPTO_EddsaPublicKey *pub) | 367 | GNUNET_CRYPTO_eddsa_public_key_to_string ( |
368 | const struct GNUNET_CRYPTO_EddsaPublicKey *pub) | ||
346 | { | 369 | { |
347 | char *pubkeybuf; | 370 | char *pubkeybuf; |
348 | size_t keylen = (sizeof (struct GNUNET_CRYPTO_EddsaPublicKey)) * 8; | 371 | size_t keylen = (sizeof (struct GNUNET_CRYPTO_EddsaPublicKey)) * 8; |
@@ -352,10 +375,11 @@ GNUNET_CRYPTO_eddsa_public_key_to_string (const struct GNUNET_CRYPTO_EddsaPublic | |||
352 | keylen += 5 - keylen % 5; | 375 | keylen += 5 - keylen % 5; |
353 | keylen /= 5; | 376 | keylen /= 5; |
354 | pubkeybuf = GNUNET_malloc (keylen + 1); | 377 | pubkeybuf = GNUNET_malloc (keylen + 1); |
355 | end = GNUNET_STRINGS_data_to_string ((unsigned char *) pub, | 378 | end = |
356 | sizeof (struct GNUNET_CRYPTO_EddsaPublicKey), | 379 | GNUNET_STRINGS_data_to_string ((unsigned char *) pub, |
357 | pubkeybuf, | 380 | sizeof (struct GNUNET_CRYPTO_EddsaPublicKey), |
358 | keylen); | 381 | pubkeybuf, |
382 | keylen); | ||
359 | if (NULL == end) | 383 | if (NULL == end) |
360 | { | 384 | { |
361 | GNUNET_free (pubkeybuf); | 385 | GNUNET_free (pubkeybuf); |
@@ -373,7 +397,8 @@ GNUNET_CRYPTO_eddsa_public_key_to_string (const struct GNUNET_CRYPTO_EddsaPublic | |||
373 | * @return string representing @a pub | 397 | * @return string representing @a pub |
374 | */ | 398 | */ |
375 | char * | 399 | char * |
376 | GNUNET_CRYPTO_eddsa_private_key_to_string (const struct GNUNET_CRYPTO_EddsaPrivateKey *priv) | 400 | GNUNET_CRYPTO_eddsa_private_key_to_string ( |
401 | const struct GNUNET_CRYPTO_EddsaPrivateKey *priv) | ||
377 | { | 402 | { |
378 | char *privkeybuf; | 403 | char *privkeybuf; |
379 | size_t keylen = (sizeof (struct GNUNET_CRYPTO_EddsaPrivateKey)) * 8; | 404 | size_t keylen = (sizeof (struct GNUNET_CRYPTO_EddsaPrivateKey)) * 8; |
@@ -384,9 +409,43 @@ GNUNET_CRYPTO_eddsa_private_key_to_string (const struct GNUNET_CRYPTO_EddsaPriva | |||
384 | keylen /= 5; | 409 | keylen /= 5; |
385 | privkeybuf = GNUNET_malloc (keylen + 1); | 410 | privkeybuf = GNUNET_malloc (keylen + 1); |
386 | end = GNUNET_STRINGS_data_to_string ((unsigned char *) priv, | 411 | end = GNUNET_STRINGS_data_to_string ((unsigned char *) priv, |
387 | sizeof (struct GNUNET_CRYPTO_EddsaPrivateKey), | 412 | sizeof ( |
388 | privkeybuf, | 413 | struct GNUNET_CRYPTO_EddsaPrivateKey), |
389 | keylen); | 414 | privkeybuf, |
415 | keylen); | ||
416 | if (NULL == end) | ||
417 | { | ||
418 | GNUNET_free (privkeybuf); | ||
419 | return NULL; | ||
420 | } | ||
421 | *end = '\0'; | ||
422 | return privkeybuf; | ||
423 | } | ||
424 | |||
425 | |||
426 | /** | ||
427 | * Convert a private key to a string. | ||
428 | * | ||
429 | * @param priv key to convert | ||
430 | * @return string representing @a priv | ||
431 | */ | ||
432 | char * | ||
433 | GNUNET_CRYPTO_ecdsa_private_key_to_string ( | ||
434 | const struct GNUNET_CRYPTO_EcdsaPrivateKey *priv) | ||
435 | { | ||
436 | char *privkeybuf; | ||
437 | size_t keylen = (sizeof (struct GNUNET_CRYPTO_EcdsaPrivateKey)) * 8; | ||
438 | char *end; | ||
439 | |||
440 | if (keylen % 5 > 0) | ||
441 | keylen += 5 - keylen % 5; | ||
442 | keylen /= 5; | ||
443 | privkeybuf = GNUNET_malloc (keylen + 1); | ||
444 | end = GNUNET_STRINGS_data_to_string ((unsigned char *) priv, | ||
445 | sizeof ( | ||
446 | struct GNUNET_CRYPTO_EcdsaPrivateKey), | ||
447 | privkeybuf, | ||
448 | keylen); | ||
390 | if (NULL == end) | 449 | if (NULL == end) |
391 | { | 450 | { |
392 | GNUNET_free (privkeybuf); | 451 | GNUNET_free (privkeybuf); |
@@ -406,9 +465,10 @@ GNUNET_CRYPTO_eddsa_private_key_to_string (const struct GNUNET_CRYPTO_EddsaPriva | |||
406 | * @return #GNUNET_OK on success | 465 | * @return #GNUNET_OK on success |
407 | */ | 466 | */ |
408 | int | 467 | int |
409 | GNUNET_CRYPTO_ecdsa_public_key_from_string (const char *enc, | 468 | GNUNET_CRYPTO_ecdsa_public_key_from_string ( |
410 | size_t enclen, | 469 | const char *enc, |
411 | struct GNUNET_CRYPTO_EcdsaPublicKey *pub) | 470 | size_t enclen, |
471 | struct GNUNET_CRYPTO_EcdsaPublicKey *pub) | ||
412 | { | 472 | { |
413 | size_t keylen = (sizeof (struct GNUNET_CRYPTO_EcdsaPublicKey)) * 8; | 473 | size_t keylen = (sizeof (struct GNUNET_CRYPTO_EcdsaPublicKey)) * 8; |
414 | 474 | ||
@@ -419,9 +479,11 @@ GNUNET_CRYPTO_ecdsa_public_key_from_string (const char *enc, | |||
419 | return GNUNET_SYSERR; | 479 | return GNUNET_SYSERR; |
420 | 480 | ||
421 | if (GNUNET_OK != | 481 | if (GNUNET_OK != |
422 | GNUNET_STRINGS_string_to_data (enc, enclen, | 482 | GNUNET_STRINGS_string_to_data (enc, |
423 | pub, | 483 | enclen, |
424 | sizeof (struct GNUNET_CRYPTO_EcdsaPublicKey))) | 484 | pub, |
485 | sizeof ( | ||
486 | struct GNUNET_CRYPTO_EcdsaPublicKey))) | ||
425 | return GNUNET_SYSERR; | 487 | return GNUNET_SYSERR; |
426 | return GNUNET_OK; | 488 | return GNUNET_OK; |
427 | } | 489 | } |
@@ -436,9 +498,10 @@ GNUNET_CRYPTO_ecdsa_public_key_from_string (const char *enc, | |||
436 | * @return #GNUNET_OK on success | 498 | * @return #GNUNET_OK on success |
437 | */ | 499 | */ |
438 | int | 500 | int |
439 | GNUNET_CRYPTO_eddsa_public_key_from_string (const char *enc, | 501 | GNUNET_CRYPTO_eddsa_public_key_from_string ( |
440 | size_t enclen, | 502 | const char *enc, |
441 | struct GNUNET_CRYPTO_EddsaPublicKey *pub) | 503 | size_t enclen, |
504 | struct GNUNET_CRYPTO_EddsaPublicKey *pub) | ||
442 | { | 505 | { |
443 | size_t keylen = (sizeof (struct GNUNET_CRYPTO_EddsaPublicKey)) * 8; | 506 | size_t keylen = (sizeof (struct GNUNET_CRYPTO_EddsaPublicKey)) * 8; |
444 | 507 | ||
@@ -449,9 +512,11 @@ GNUNET_CRYPTO_eddsa_public_key_from_string (const char *enc, | |||
449 | return GNUNET_SYSERR; | 512 | return GNUNET_SYSERR; |
450 | 513 | ||
451 | if (GNUNET_OK != | 514 | if (GNUNET_OK != |
452 | GNUNET_STRINGS_string_to_data (enc, enclen, | 515 | GNUNET_STRINGS_string_to_data (enc, |
453 | pub, | 516 | enclen, |
454 | sizeof (struct GNUNET_CRYPTO_EddsaPublicKey))) | 517 | pub, |
518 | sizeof ( | ||
519 | struct GNUNET_CRYPTO_EddsaPublicKey))) | ||
455 | return GNUNET_SYSERR; | 520 | return GNUNET_SYSERR; |
456 | return GNUNET_OK; | 521 | return GNUNET_OK; |
457 | } | 522 | } |
@@ -466,9 +531,10 @@ GNUNET_CRYPTO_eddsa_public_key_from_string (const char *enc, | |||
466 | * @return #GNUNET_OK on success | 531 | * @return #GNUNET_OK on success |
467 | */ | 532 | */ |
468 | int | 533 | int |
469 | GNUNET_CRYPTO_eddsa_private_key_from_string (const char *enc, | 534 | GNUNET_CRYPTO_eddsa_private_key_from_string ( |
470 | size_t enclen, | 535 | const char *enc, |
471 | struct GNUNET_CRYPTO_EddsaPrivateKey *priv) | 536 | size_t enclen, |
537 | struct GNUNET_CRYPTO_EddsaPrivateKey *priv) | ||
472 | { | 538 | { |
473 | size_t keylen = (sizeof (struct GNUNET_CRYPTO_EddsaPrivateKey)) * 8; | 539 | size_t keylen = (sizeof (struct GNUNET_CRYPTO_EddsaPrivateKey)) * 8; |
474 | 540 | ||
@@ -479,13 +545,14 @@ GNUNET_CRYPTO_eddsa_private_key_from_string (const char *enc, | |||
479 | return GNUNET_SYSERR; | 545 | return GNUNET_SYSERR; |
480 | 546 | ||
481 | if (GNUNET_OK != | 547 | if (GNUNET_OK != |
482 | GNUNET_STRINGS_string_to_data (enc, enclen, | 548 | GNUNET_STRINGS_string_to_data (enc, |
549 | enclen, | ||
483 | priv, | 550 | priv, |
484 | sizeof (struct GNUNET_CRYPTO_EddsaPrivateKey))) | 551 | sizeof ( |
552 | struct GNUNET_CRYPTO_EddsaPrivateKey))) | ||
485 | return GNUNET_SYSERR; | 553 | return GNUNET_SYSERR; |
486 | #if CRYPTO_BUG | 554 | #if CRYPTO_BUG |
487 | if (GNUNET_OK != | 555 | if (GNUNET_OK != check_eddsa_key (priv)) |
488 | check_eddsa_key (priv)) | ||
489 | { | 556 | { |
490 | GNUNET_break (0); | 557 | GNUNET_break (0); |
491 | return GNUNET_OK; | 558 | return GNUNET_OK; |
@@ -545,8 +612,7 @@ GNUNET_CRYPTO_ecdhe_key_create () | |||
545 | struct GNUNET_CRYPTO_EcdhePrivateKey *priv; | 612 | struct GNUNET_CRYPTO_EcdhePrivateKey *priv; |
546 | 613 | ||
547 | priv = GNUNET_new (struct GNUNET_CRYPTO_EcdhePrivateKey); | 614 | priv = GNUNET_new (struct GNUNET_CRYPTO_EcdhePrivateKey); |
548 | if (GNUNET_OK != | 615 | if (GNUNET_OK != GNUNET_CRYPTO_ecdhe_key_create2 (priv)) |
549 | GNUNET_CRYPTO_ecdhe_key_create2 (priv)) | ||
550 | { | 616 | { |
551 | GNUNET_free (priv); | 617 | GNUNET_free (priv); |
552 | return NULL; | 618 | return NULL; |
@@ -577,7 +643,8 @@ GNUNET_CRYPTO_ecdhe_key_create2 (struct GNUNET_CRYPTO_EcdhePrivateKey *pk) | |||
577 | disables an expensive key testing routine. We do not want to run | 643 | disables an expensive key testing routine. We do not want to run |
578 | the expensive check for ECDHE, as we generate TONS of keys to | 644 | the expensive check for ECDHE, as we generate TONS of keys to |
579 | use for a very short time. */ | 645 | use for a very short time. */ |
580 | if (0 != (rc = gcry_sexp_build (&s_keyparam, NULL, | 646 | if (0 != (rc = gcry_sexp_build (&s_keyparam, |
647 | NULL, | ||
581 | "(genkey(ecc(curve \"" CURVE "\")" | 648 | "(genkey(ecc(curve \"" CURVE "\")" |
582 | "(flags eddsa no-keytest)))"))) | 649 | "(flags eddsa no-keytest)))"))) |
583 | { | 650 | { |
@@ -631,7 +698,8 @@ GNUNET_CRYPTO_ecdsa_key_create () | |||
631 | 698 | ||
632 | BENCHMARK_START (ecdsa_key_create); | 699 | BENCHMARK_START (ecdsa_key_create); |
633 | 700 | ||
634 | if (0 != (rc = gcry_sexp_build (&s_keyparam, NULL, | 701 | if (0 != (rc = gcry_sexp_build (&s_keyparam, |
702 | NULL, | ||
635 | "(genkey(ecc(curve \"" CURVE "\")" | 703 | "(genkey(ecc(curve \"" CURVE "\")" |
636 | "(flags)))"))) | 704 | "(flags)))"))) |
637 | { | 705 | { |
@@ -686,9 +754,10 @@ GNUNET_CRYPTO_eddsa_key_create () | |||
686 | BENCHMARK_START (eddsa_key_create); | 754 | BENCHMARK_START (eddsa_key_create); |
687 | 755 | ||
688 | #if CRYPTO_BUG | 756 | #if CRYPTO_BUG |
689 | again: | 757 | again: |
690 | #endif | 758 | #endif |
691 | if (0 != (rc = gcry_sexp_build (&s_keyparam, NULL, | 759 | if (0 != (rc = gcry_sexp_build (&s_keyparam, |
760 | NULL, | ||
692 | "(genkey(ecc(curve \"" CURVE "\")" | 761 | "(genkey(ecc(curve \"" CURVE "\")" |
693 | "(flags eddsa)))"))) | 762 | "(flags eddsa)))"))) |
694 | { | 763 | { |
@@ -722,8 +791,7 @@ GNUNET_CRYPTO_eddsa_key_create () | |||
722 | gcry_mpi_release (d); | 791 | gcry_mpi_release (d); |
723 | 792 | ||
724 | #if CRYPTO_BUG | 793 | #if CRYPTO_BUG |
725 | if (GNUNET_OK != | 794 | if (GNUNET_OK != check_eddsa_key (priv)) |
726 | check_eddsa_key (priv)) | ||
727 | { | 795 | { |
728 | GNUNET_break (0); | 796 | GNUNET_break (0); |
729 | GNUNET_free (priv); | 797 | GNUNET_free (priv); |
@@ -755,8 +823,8 @@ GNUNET_CRYPTO_ecdsa_key_get_anonymous () | |||
755 | if (once) | 823 | if (once) |
756 | return &anonymous; | 824 | return &anonymous; |
757 | GNUNET_CRYPTO_mpi_print_unsigned (anonymous.d, | 825 | GNUNET_CRYPTO_mpi_print_unsigned (anonymous.d, |
758 | sizeof (anonymous.d), | 826 | sizeof (anonymous.d), |
759 | GCRYMPI_CONST_ONE); | 827 | GCRYMPI_CONST_ONE); |
760 | once = 1; | 828 | once = 1; |
761 | return &anonymous; | 829 | return &anonymous; |
762 | } | 830 | } |
@@ -779,31 +847,27 @@ data_to_eddsa_value (const struct GNUNET_CRYPTO_EccSignaturePurpose *purpose) | |||
779 | #if 1 | 847 | #if 1 |
780 | struct GNUNET_HashCode hc; | 848 | struct GNUNET_HashCode hc; |
781 | 849 | ||
782 | GNUNET_CRYPTO_hash (purpose, | 850 | GNUNET_CRYPTO_hash (purpose, ntohl (purpose->size), &hc); |
783 | ntohl (purpose->size), | 851 | if (0 != (rc = gcry_sexp_build (&data, |
784 | &hc); | 852 | NULL, |
785 | if (0 != (rc = gcry_sexp_build (&data, NULL, | 853 | "(data(flags eddsa)(hash-algo %s)(value %b))", |
786 | "(data(flags eddsa)(hash-algo %s)(value %b))", | 854 | "sha512", |
787 | "sha512", | 855 | (int) sizeof (hc), |
788 | (int)sizeof (hc), | 856 | &hc))) |
789 | &hc))) | ||
790 | { | 857 | { |
791 | LOG_GCRY (GNUNET_ERROR_TYPE_ERROR, | 858 | LOG_GCRY (GNUNET_ERROR_TYPE_ERROR, "gcry_sexp_build", rc); |
792 | "gcry_sexp_build", | ||
793 | rc); | ||
794 | return NULL; | 859 | return NULL; |
795 | } | 860 | } |
796 | #else | 861 | #else |
797 | GNUNET_CRYPTO_hash (purpose, ntohl (purpose->size), &hc); | 862 | GNUNET_CRYPTO_hash (purpose, ntohl (purpose->size), &hc); |
798 | if (0 != (rc = gcry_sexp_build (&data, NULL, | 863 | if (0 != (rc = gcry_sexp_build (&data, |
799 | "(data(flags eddsa)(hash-algo %s)(value %b))", | 864 | NULL, |
800 | "sha512", | 865 | "(data(flags eddsa)(hash-algo %s)(value %b))", |
801 | ntohl (purpose->size), | 866 | "sha512", |
802 | purpose))) | 867 | ntohl (purpose->size), |
868 | purpose))) | ||
803 | { | 869 | { |
804 | LOG_GCRY (GNUNET_ERROR_TYPE_ERROR, | 870 | LOG_GCRY (GNUNET_ERROR_TYPE_ERROR, "gcry_sexp_build", rc); |
805 | "gcry_sexp_build", | ||
806 | rc); | ||
807 | return NULL; | 871 | return NULL; |
808 | } | 872 | } |
809 | #endif | 873 | #endif |
@@ -828,29 +892,26 @@ data_to_ecdsa_value (const struct GNUNET_CRYPTO_EccSignaturePurpose *purpose) | |||
828 | #if 1 | 892 | #if 1 |
829 | struct GNUNET_HashCode hc; | 893 | struct GNUNET_HashCode hc; |
830 | 894 | ||
831 | GNUNET_CRYPTO_hash (purpose, | 895 | GNUNET_CRYPTO_hash (purpose, ntohl (purpose->size), &hc); |
832 | ntohl (purpose->size), | 896 | if (0 != (rc = gcry_sexp_build (&data, |
833 | &hc); | 897 | NULL, |
834 | if (0 != (rc = gcry_sexp_build (&data, NULL, | 898 | "(data(flags rfc6979)(hash %s %b))", |
835 | "(data(flags rfc6979)(hash %s %b))", | 899 | "sha512", |
836 | "sha512", | 900 | (int) sizeof (hc), |
837 | (int)sizeof (hc), &hc))) | 901 | &hc))) |
838 | { | 902 | { |
839 | LOG_GCRY (GNUNET_ERROR_TYPE_ERROR, | 903 | LOG_GCRY (GNUNET_ERROR_TYPE_ERROR, "gcry_sexp_build", rc); |
840 | "gcry_sexp_build", | ||
841 | rc); | ||
842 | return NULL; | 904 | return NULL; |
843 | } | 905 | } |
844 | #else | 906 | #else |
845 | if (0 != (rc = gcry_sexp_build (&data, NULL, | 907 | if (0 != (rc = gcry_sexp_build (&data, |
846 | "(data(flags rfc6979)(hash %s %b))", | 908 | NULL, |
847 | "sha512", | 909 | "(data(flags rfc6979)(hash %s %b))", |
848 | ntohl (purpose->size), | 910 | "sha512", |
849 | purpose))) | 911 | ntohl (purpose->size), |
912 | purpose))) | ||
850 | { | 913 | { |
851 | LOG_GCRY (GNUNET_ERROR_TYPE_ERROR, | 914 | LOG_GCRY (GNUNET_ERROR_TYPE_ERROR, "gcry_sexp_build", rc); |
852 | "gcry_sexp_build", | ||
853 | rc); | ||
854 | return NULL; | 915 | return NULL; |
855 | } | 916 | } |
856 | #endif | 917 | #endif |
@@ -867,9 +928,10 @@ data_to_ecdsa_value (const struct GNUNET_CRYPTO_EccSignaturePurpose *purpose) | |||
867 | * @return #GNUNET_SYSERR on error, #GNUNET_OK on success | 928 | * @return #GNUNET_SYSERR on error, #GNUNET_OK on success |
868 | */ | 929 | */ |
869 | int | 930 | int |
870 | GNUNET_CRYPTO_ecdsa_sign (const struct GNUNET_CRYPTO_EcdsaPrivateKey *priv, | 931 | GNUNET_CRYPTO_ecdsa_sign ( |
871 | const struct GNUNET_CRYPTO_EccSignaturePurpose *purpose, | 932 | const struct GNUNET_CRYPTO_EcdsaPrivateKey *priv, |
872 | struct GNUNET_CRYPTO_EcdsaSignature *sig) | 933 | const struct GNUNET_CRYPTO_EccSignaturePurpose *purpose, |
934 | struct GNUNET_CRYPTO_EcdsaSignature *sig) | ||
873 | { | 935 | { |
874 | gcry_sexp_t priv_sexp; | 936 | gcry_sexp_t priv_sexp; |
875 | gcry_sexp_t sig_sexp; | 937 | gcry_sexp_t sig_sexp; |
@@ -884,8 +946,10 @@ GNUNET_CRYPTO_ecdsa_sign (const struct GNUNET_CRYPTO_EcdsaPrivateKey *priv, | |||
884 | if (0 != (rc = gcry_pk_sign (&sig_sexp, data, priv_sexp))) | 946 | if (0 != (rc = gcry_pk_sign (&sig_sexp, data, priv_sexp))) |
885 | { | 947 | { |
886 | LOG (GNUNET_ERROR_TYPE_WARNING, | 948 | LOG (GNUNET_ERROR_TYPE_WARNING, |
887 | _("ECC signing failed at %s:%d: %s\n"), __FILE__, | 949 | _ ("ECC signing failed at %s:%d: %s\n"), |
888 | __LINE__, gcry_strerror (rc)); | 950 | __FILE__, |
951 | __LINE__, | ||
952 | gcry_strerror (rc)); | ||
889 | gcry_sexp_release (data); | 953 | gcry_sexp_release (data); |
890 | gcry_sexp_release (priv_sexp); | 954 | gcry_sexp_release (priv_sexp); |
891 | return GNUNET_SYSERR; | 955 | return GNUNET_SYSERR; |
@@ -902,12 +966,8 @@ GNUNET_CRYPTO_ecdsa_sign (const struct GNUNET_CRYPTO_EcdsaPrivateKey *priv, | |||
902 | return GNUNET_SYSERR; | 966 | return GNUNET_SYSERR; |
903 | } | 967 | } |
904 | gcry_sexp_release (sig_sexp); | 968 | gcry_sexp_release (sig_sexp); |
905 | GNUNET_CRYPTO_mpi_print_unsigned (sig->r, | 969 | GNUNET_CRYPTO_mpi_print_unsigned (sig->r, sizeof (sig->r), rs[0]); |
906 | sizeof (sig->r), | 970 | GNUNET_CRYPTO_mpi_print_unsigned (sig->s, sizeof (sig->s), rs[1]); |
907 | rs[0]); | ||
908 | GNUNET_CRYPTO_mpi_print_unsigned (sig->s, | ||
909 | sizeof (sig->s), | ||
910 | rs[1]); | ||
911 | gcry_mpi_release (rs[0]); | 971 | gcry_mpi_release (rs[0]); |
912 | gcry_mpi_release (rs[1]); | 972 | gcry_mpi_release (rs[1]); |
913 | 973 | ||
@@ -926,9 +986,10 @@ GNUNET_CRYPTO_ecdsa_sign (const struct GNUNET_CRYPTO_EcdsaPrivateKey *priv, | |||
926 | * @return #GNUNET_SYSERR on error, #GNUNET_OK on success | 986 | * @return #GNUNET_SYSERR on error, #GNUNET_OK on success |
927 | */ | 987 | */ |
928 | int | 988 | int |
929 | GNUNET_CRYPTO_eddsa_sign (const struct GNUNET_CRYPTO_EddsaPrivateKey *priv, | 989 | GNUNET_CRYPTO_eddsa_sign ( |
930 | const struct GNUNET_CRYPTO_EccSignaturePurpose *purpose, | 990 | const struct GNUNET_CRYPTO_EddsaPrivateKey *priv, |
931 | struct GNUNET_CRYPTO_EddsaSignature *sig) | 991 | const struct GNUNET_CRYPTO_EccSignaturePurpose *purpose, |
992 | struct GNUNET_CRYPTO_EddsaSignature *sig) | ||
932 | { | 993 | { |
933 | gcry_sexp_t priv_sexp; | 994 | gcry_sexp_t priv_sexp; |
934 | gcry_sexp_t sig_sexp; | 995 | gcry_sexp_t sig_sexp; |
@@ -943,8 +1004,10 @@ GNUNET_CRYPTO_eddsa_sign (const struct GNUNET_CRYPTO_EddsaPrivateKey *priv, | |||
943 | if (0 != (rc = gcry_pk_sign (&sig_sexp, data, priv_sexp))) | 1004 | if (0 != (rc = gcry_pk_sign (&sig_sexp, data, priv_sexp))) |
944 | { | 1005 | { |
945 | LOG (GNUNET_ERROR_TYPE_WARNING, | 1006 | LOG (GNUNET_ERROR_TYPE_WARNING, |
946 | _("EdDSA signing failed at %s:%d: %s\n"), __FILE__, | 1007 | _ ("EdDSA signing failed at %s:%d: %s\n"), |
947 | __LINE__, gcry_strerror (rc)); | 1008 | __FILE__, |
1009 | __LINE__, | ||
1010 | gcry_strerror (rc)); | ||
948 | gcry_sexp_release (data); | 1011 | gcry_sexp_release (data); |
949 | gcry_sexp_release (priv_sexp); | 1012 | gcry_sexp_release (priv_sexp); |
950 | return GNUNET_SYSERR; | 1013 | return GNUNET_SYSERR; |
@@ -982,10 +1045,11 @@ GNUNET_CRYPTO_eddsa_sign (const struct GNUNET_CRYPTO_EddsaPrivateKey *priv, | |||
982 | * @returns #GNUNET_OK if ok, #GNUNET_SYSERR if invalid | 1045 | * @returns #GNUNET_OK if ok, #GNUNET_SYSERR if invalid |
983 | */ | 1046 | */ |
984 | int | 1047 | int |
985 | GNUNET_CRYPTO_ecdsa_verify (uint32_t purpose, | 1048 | GNUNET_CRYPTO_ecdsa_verify ( |
986 | const struct GNUNET_CRYPTO_EccSignaturePurpose *validate, | 1049 | uint32_t purpose, |
987 | const struct GNUNET_CRYPTO_EcdsaSignature *sig, | 1050 | const struct GNUNET_CRYPTO_EccSignaturePurpose *validate, |
988 | const struct GNUNET_CRYPTO_EcdsaPublicKey *pub) | 1051 | const struct GNUNET_CRYPTO_EcdsaSignature *sig, |
1052 | const struct GNUNET_CRYPTO_EcdsaPublicKey *pub) | ||
989 | { | 1053 | { |
990 | gcry_sexp_t data; | 1054 | gcry_sexp_t data; |
991 | gcry_sexp_t sig_sexpr; | 1055 | gcry_sexp_t sig_sexpr; |
@@ -995,21 +1059,26 @@ GNUNET_CRYPTO_ecdsa_verify (uint32_t purpose, | |||
995 | BENCHMARK_START (ecdsa_verify); | 1059 | BENCHMARK_START (ecdsa_verify); |
996 | 1060 | ||
997 | if (purpose != ntohl (validate->purpose)) | 1061 | if (purpose != ntohl (validate->purpose)) |
998 | return GNUNET_SYSERR; /* purpose mismatch */ | 1062 | return GNUNET_SYSERR; /* purpose mismatch */ |
999 | 1063 | ||
1000 | /* build s-expression for signature */ | 1064 | /* build s-expression for signature */ |
1001 | if (0 != (rc = gcry_sexp_build (&sig_sexpr, NULL, | 1065 | if (0 != (rc = gcry_sexp_build (&sig_sexpr, |
1002 | "(sig-val(ecdsa(r %b)(s %b)))", | 1066 | NULL, |
1003 | (int) sizeof (sig->r), sig->r, | 1067 | "(sig-val(ecdsa(r %b)(s %b)))", |
1004 | (int) sizeof (sig->s), sig->s))) | 1068 | (int) sizeof (sig->r), |
1069 | sig->r, | ||
1070 | (int) sizeof (sig->s), | ||
1071 | sig->s))) | ||
1005 | { | 1072 | { |
1006 | LOG_GCRY (GNUNET_ERROR_TYPE_ERROR, "gcry_sexp_build", rc); | 1073 | LOG_GCRY (GNUNET_ERROR_TYPE_ERROR, "gcry_sexp_build", rc); |
1007 | return GNUNET_SYSERR; | 1074 | return GNUNET_SYSERR; |
1008 | } | 1075 | } |
1009 | data = data_to_ecdsa_value (validate); | 1076 | data = data_to_ecdsa_value (validate); |
1010 | if (0 != (rc = gcry_sexp_build (&pub_sexpr, NULL, | 1077 | if (0 != (rc = gcry_sexp_build (&pub_sexpr, |
1078 | NULL, | ||
1011 | "(public-key(ecc(curve " CURVE ")(q %b)))", | 1079 | "(public-key(ecc(curve " CURVE ")(q %b)))", |
1012 | (int) sizeof (pub->q_y), pub->q_y))) | 1080 | (int) sizeof (pub->q_y), |
1081 | pub->q_y))) | ||
1013 | { | 1082 | { |
1014 | gcry_sexp_release (data); | 1083 | gcry_sexp_release (data); |
1015 | gcry_sexp_release (sig_sexpr); | 1084 | gcry_sexp_release (sig_sexpr); |
@@ -1022,8 +1091,10 @@ GNUNET_CRYPTO_ecdsa_verify (uint32_t purpose, | |||
1022 | if (0 != rc) | 1091 | if (0 != rc) |
1023 | { | 1092 | { |
1024 | LOG (GNUNET_ERROR_TYPE_INFO, | 1093 | LOG (GNUNET_ERROR_TYPE_INFO, |
1025 | _("ECDSA signature verification failed at %s:%d: %s\n"), __FILE__, | 1094 | _ ("ECDSA signature verification failed at %s:%d: %s\n"), |
1026 | __LINE__, gcry_strerror (rc)); | 1095 | __FILE__, |
1096 | __LINE__, | ||
1097 | gcry_strerror (rc)); | ||
1027 | BENCHMARK_END (ecdsa_verify); | 1098 | BENCHMARK_END (ecdsa_verify); |
1028 | return GNUNET_SYSERR; | 1099 | return GNUNET_SYSERR; |
1029 | } | 1100 | } |
@@ -1032,7 +1103,6 @@ GNUNET_CRYPTO_ecdsa_verify (uint32_t purpose, | |||
1032 | } | 1103 | } |
1033 | 1104 | ||
1034 | 1105 | ||
1035 | |||
1036 | /** | 1106 | /** |
1037 | * Verify signature. | 1107 | * Verify signature. |
1038 | * | 1108 | * |
@@ -1043,10 +1113,11 @@ GNUNET_CRYPTO_ecdsa_verify (uint32_t purpose, | |||
1043 | * @returns #GNUNET_OK if ok, #GNUNET_SYSERR if invalid | 1113 | * @returns #GNUNET_OK if ok, #GNUNET_SYSERR if invalid |
1044 | */ | 1114 | */ |
1045 | int | 1115 | int |
1046 | GNUNET_CRYPTO_eddsa_verify (uint32_t purpose, | 1116 | GNUNET_CRYPTO_eddsa_verify ( |
1047 | const struct GNUNET_CRYPTO_EccSignaturePurpose *validate, | 1117 | uint32_t purpose, |
1048 | const struct GNUNET_CRYPTO_EddsaSignature *sig, | 1118 | const struct GNUNET_CRYPTO_EccSignaturePurpose *validate, |
1049 | const struct GNUNET_CRYPTO_EddsaPublicKey *pub) | 1119 | const struct GNUNET_CRYPTO_EddsaSignature *sig, |
1120 | const struct GNUNET_CRYPTO_EddsaPublicKey *pub) | ||
1050 | { | 1121 | { |
1051 | gcry_sexp_t data; | 1122 | gcry_sexp_t data; |
1052 | gcry_sexp_t sig_sexpr; | 1123 | gcry_sexp_t sig_sexpr; |
@@ -1056,21 +1127,27 @@ GNUNET_CRYPTO_eddsa_verify (uint32_t purpose, | |||
1056 | BENCHMARK_START (eddsa_verify); | 1127 | BENCHMARK_START (eddsa_verify); |
1057 | 1128 | ||
1058 | if (purpose != ntohl (validate->purpose)) | 1129 | if (purpose != ntohl (validate->purpose)) |
1059 | return GNUNET_SYSERR; /* purpose mismatch */ | 1130 | return GNUNET_SYSERR; /* purpose mismatch */ |
1060 | 1131 | ||
1061 | /* build s-expression for signature */ | 1132 | /* build s-expression for signature */ |
1062 | if (0 != (rc = gcry_sexp_build (&sig_sexpr, NULL, | 1133 | if (0 != (rc = gcry_sexp_build (&sig_sexpr, |
1063 | "(sig-val(eddsa(r %b)(s %b)))", | 1134 | NULL, |
1064 | (int)sizeof (sig->r), sig->r, | 1135 | "(sig-val(eddsa(r %b)(s %b)))", |
1065 | (int)sizeof (sig->s), sig->s))) | 1136 | (int) sizeof (sig->r), |
1137 | sig->r, | ||
1138 | (int) sizeof (sig->s), | ||
1139 | sig->s))) | ||
1066 | { | 1140 | { |
1067 | LOG_GCRY (GNUNET_ERROR_TYPE_ERROR, "gcry_sexp_build", rc); | 1141 | LOG_GCRY (GNUNET_ERROR_TYPE_ERROR, "gcry_sexp_build", rc); |
1068 | return GNUNET_SYSERR; | 1142 | return GNUNET_SYSERR; |
1069 | } | 1143 | } |
1070 | data = data_to_eddsa_value (validate); | 1144 | data = data_to_eddsa_value (validate); |
1071 | if (0 != (rc = gcry_sexp_build (&pub_sexpr, NULL, | 1145 | if (0 != (rc = gcry_sexp_build (&pub_sexpr, |
1072 | "(public-key(ecc(curve " CURVE ")(flags eddsa)(q %b)))", | 1146 | NULL, |
1073 | (int)sizeof (pub->q_y), pub->q_y))) | 1147 | "(public-key(ecc(curve " CURVE |
1148 | ")(flags eddsa)(q %b)))", | ||
1149 | (int) sizeof (pub->q_y), | ||
1150 | pub->q_y))) | ||
1074 | { | 1151 | { |
1075 | gcry_sexp_release (data); | 1152 | gcry_sexp_release (data); |
1076 | gcry_sexp_release (sig_sexpr); | 1153 | gcry_sexp_release (sig_sexpr); |
@@ -1083,8 +1160,10 @@ GNUNET_CRYPTO_eddsa_verify (uint32_t purpose, | |||
1083 | if (0 != rc) | 1160 | if (0 != rc) |
1084 | { | 1161 | { |
1085 | LOG (GNUNET_ERROR_TYPE_INFO, | 1162 | LOG (GNUNET_ERROR_TYPE_INFO, |
1086 | _("EdDSA signature verification failed at %s:%d: %s\n"), __FILE__, | 1163 | _ ("EdDSA signature verification failed at %s:%d: %s\n"), |
1087 | __LINE__, gcry_strerror (rc)); | 1164 | __FILE__, |
1165 | __LINE__, | ||
1166 | gcry_strerror (rc)); | ||
1088 | BENCHMARK_END (eddsa_verify); | 1167 | BENCHMARK_END (eddsa_verify); |
1089 | return GNUNET_SYSERR; | 1168 | return GNUNET_SYSERR; |
1090 | } | 1169 | } |
@@ -1118,9 +1197,11 @@ GNUNET_CRYPTO_ecc_ecdh (const struct GNUNET_CRYPTO_EcdhePrivateKey *priv, | |||
1118 | BENCHMARK_START (ecc_ecdh); | 1197 | BENCHMARK_START (ecc_ecdh); |
1119 | 1198 | ||
1120 | /* first, extract the q = dP value from the public key */ | 1199 | /* first, extract the q = dP value from the public key */ |
1121 | if (0 != gcry_sexp_build (&pub_sexpr, NULL, | 1200 | if (0 != gcry_sexp_build (&pub_sexpr, |
1201 | NULL, | ||
1122 | "(public-key(ecc(curve " CURVE ")(q %b)))", | 1202 | "(public-key(ecc(curve " CURVE ")(q %b)))", |
1123 | (int)sizeof (pub->q_y), pub->q_y)) | 1203 | (int) sizeof (pub->q_y), |
1204 | pub->q_y)) | ||
1124 | return GNUNET_SYSERR; | 1205 | return GNUNET_SYSERR; |
1125 | GNUNET_assert (0 == gcry_mpi_ec_new (&ctx, pub_sexpr, NULL)); | 1206 | GNUNET_assert (0 == gcry_mpi_ec_new (&ctx, pub_sexpr, NULL)); |
1126 | gcry_sexp_release (pub_sexpr); | 1207 | gcry_sexp_release (pub_sexpr); |
@@ -1153,12 +1234,9 @@ GNUNET_CRYPTO_ecc_ecdh (const struct GNUNET_CRYPTO_EcdhePrivateKey *priv, | |||
1153 | as that does not include the sign bit; x should be a 255-bit | 1234 | as that does not include the sign bit; x should be a 255-bit |
1154 | value, so with the sign it should fit snugly into the 256-bit | 1235 | value, so with the sign it should fit snugly into the 256-bit |
1155 | xbuf */ | 1236 | xbuf */ |
1156 | GNUNET_assert (0 == | 1237 | GNUNET_assert ( |
1157 | gcry_mpi_print (GCRYMPI_FMT_STD, xbuf, rsize, &rsize, | 1238 | 0 == gcry_mpi_print (GCRYMPI_FMT_STD, xbuf, rsize, &rsize, result_x)); |
1158 | result_x)); | 1239 | GNUNET_CRYPTO_hash (xbuf, rsize, key_material); |
1159 | GNUNET_CRYPTO_hash (xbuf, | ||
1160 | rsize, | ||
1161 | key_material); | ||
1162 | gcry_mpi_release (result_x); | 1240 | gcry_mpi_release (result_x); |
1163 | BENCHMARK_END (ecc_ecdh); | 1241 | BENCHMARK_END (ecc_ecdh); |
1164 | return GNUNET_OK; | 1242 | return GNUNET_OK; |
@@ -1177,22 +1255,26 @@ GNUNET_CRYPTO_ecc_ecdh (const struct GNUNET_CRYPTO_EcdhePrivateKey *priv, | |||
1177 | */ | 1255 | */ |
1178 | static gcry_mpi_t | 1256 | static gcry_mpi_t |
1179 | derive_h (const struct GNUNET_CRYPTO_EcdsaPublicKey *pub, | 1257 | derive_h (const struct GNUNET_CRYPTO_EcdsaPublicKey *pub, |
1180 | const char *label, | 1258 | const char *label, |
1181 | const char *context) | 1259 | const char *context) |
1182 | { | 1260 | { |
1183 | gcry_mpi_t h; | 1261 | gcry_mpi_t h; |
1184 | struct GNUNET_HashCode hc; | 1262 | struct GNUNET_HashCode hc; |
1185 | static const char *const salt = "key-derivation"; | 1263 | static const char *const salt = "key-derivation"; |
1186 | 1264 | ||
1187 | GNUNET_CRYPTO_kdf (&hc, sizeof (hc), | 1265 | GNUNET_CRYPTO_kdf (&hc, |
1188 | salt, strlen (salt), | 1266 | sizeof (hc), |
1189 | pub, sizeof (*pub), | 1267 | salt, |
1190 | label, strlen (label), | 1268 | strlen (salt), |
1191 | context, strlen (context), | 1269 | pub, |
1192 | NULL, 0); | 1270 | sizeof (*pub), |
1193 | GNUNET_CRYPTO_mpi_scan_unsigned (&h, | 1271 | label, |
1194 | (unsigned char *) &hc, | 1272 | strlen (label), |
1195 | sizeof (hc)); | 1273 | context, |
1274 | strlen (context), | ||
1275 | NULL, | ||
1276 | 0); | ||
1277 | GNUNET_CRYPTO_mpi_scan_unsigned (&h, (unsigned char *) &hc, sizeof (hc)); | ||
1196 | return h; | 1278 | return h; |
1197 | } | 1279 | } |
1198 | 1280 | ||
@@ -1210,9 +1292,10 @@ derive_h (const struct GNUNET_CRYPTO_EcdsaPublicKey *pub, | |||
1210 | * @return derived private key | 1292 | * @return derived private key |
1211 | */ | 1293 | */ |
1212 | struct GNUNET_CRYPTO_EcdsaPrivateKey * | 1294 | struct GNUNET_CRYPTO_EcdsaPrivateKey * |
1213 | GNUNET_CRYPTO_ecdsa_private_key_derive (const struct GNUNET_CRYPTO_EcdsaPrivateKey *priv, | 1295 | GNUNET_CRYPTO_ecdsa_private_key_derive ( |
1214 | const char *label, | 1296 | const struct GNUNET_CRYPTO_EcdsaPrivateKey *priv, |
1215 | const char *context) | 1297 | const char *label, |
1298 | const char *context) | ||
1216 | { | 1299 | { |
1217 | struct GNUNET_CRYPTO_EcdsaPublicKey pub; | 1300 | struct GNUNET_CRYPTO_EcdsaPublicKey pub; |
1218 | struct GNUNET_CRYPTO_EcdsaPrivateKey *ret; | 1301 | struct GNUNET_CRYPTO_EcdsaPrivateKey *ret; |
@@ -1228,9 +1311,7 @@ GNUNET_CRYPTO_ecdsa_private_key_derive (const struct GNUNET_CRYPTO_EcdsaPrivateK | |||
1228 | GNUNET_CRYPTO_ecdsa_key_get_public (priv, &pub); | 1311 | GNUNET_CRYPTO_ecdsa_key_get_public (priv, &pub); |
1229 | 1312 | ||
1230 | h = derive_h (&pub, label, context); | 1313 | h = derive_h (&pub, label, context); |
1231 | GNUNET_CRYPTO_mpi_scan_unsigned (&x, | 1314 | GNUNET_CRYPTO_mpi_scan_unsigned (&x, priv->d, sizeof (priv->d)); |
1232 | priv->d, | ||
1233 | sizeof (priv->d)); | ||
1234 | d = gcry_mpi_new (256); | 1315 | d = gcry_mpi_new (256); |
1235 | gcry_mpi_mulm (d, h, x, n); | 1316 | gcry_mpi_mulm (d, h, x, n); |
1236 | gcry_mpi_release (h); | 1317 | gcry_mpi_release (h); |
@@ -1255,10 +1336,11 @@ GNUNET_CRYPTO_ecdsa_private_key_derive (const struct GNUNET_CRYPTO_EcdsaPrivateK | |||
1255 | * @param result where to write the derived public key | 1336 | * @param result where to write the derived public key |
1256 | */ | 1337 | */ |
1257 | void | 1338 | void |
1258 | GNUNET_CRYPTO_ecdsa_public_key_derive (const struct GNUNET_CRYPTO_EcdsaPublicKey *pub, | 1339 | GNUNET_CRYPTO_ecdsa_public_key_derive ( |
1259 | const char *label, | 1340 | const struct GNUNET_CRYPTO_EcdsaPublicKey *pub, |
1260 | const char *context, | 1341 | const char *label, |
1261 | struct GNUNET_CRYPTO_EcdsaPublicKey *result) | 1342 | const char *context, |
1343 | struct GNUNET_CRYPTO_EcdsaPublicKey *result) | ||
1262 | { | 1344 | { |
1263 | gcry_ctx_t ctx; | 1345 | gcry_ctx_t ctx; |
1264 | gcry_mpi_t q_y; | 1346 | gcry_mpi_t q_y; |
@@ -1273,7 +1355,7 @@ GNUNET_CRYPTO_ecdsa_public_key_derive (const struct GNUNET_CRYPTO_EcdsaPublicKey | |||
1273 | /* obtain point 'q' from original public key. The provided 'q' is | 1355 | /* obtain point 'q' from original public key. The provided 'q' is |
1274 | compressed thus we first store it in the context and then get it | 1356 | compressed thus we first store it in the context and then get it |
1275 | back as a (decompresssed) point. */ | 1357 | back as a (decompresssed) point. */ |
1276 | q_y = gcry_mpi_set_opaque_copy (NULL, pub->q_y, 8*sizeof (pub->q_y)); | 1358 | q_y = gcry_mpi_set_opaque_copy (NULL, pub->q_y, 8 * sizeof (pub->q_y)); |
1277 | GNUNET_assert (NULL != q_y); | 1359 | GNUNET_assert (NULL != q_y); |
1278 | GNUNET_assert (0 == gcry_mpi_ec_set_mpi ("q", q_y, ctx)); | 1360 | GNUNET_assert (0 == gcry_mpi_ec_set_mpi ("q", q_y, ctx)); |
1279 | gcry_mpi_release (q_y); | 1361 | gcry_mpi_release (q_y); |
@@ -1298,9 +1380,7 @@ GNUNET_CRYPTO_ecdsa_public_key_derive (const struct GNUNET_CRYPTO_EcdsaPublicKey | |||
1298 | gcry_mpi_point_release (v); | 1380 | gcry_mpi_point_release (v); |
1299 | q_y = gcry_mpi_ec_get_mpi ("q@eddsa", ctx, 0); | 1381 | q_y = gcry_mpi_ec_get_mpi ("q@eddsa", ctx, 0); |
1300 | GNUNET_assert (q_y); | 1382 | GNUNET_assert (q_y); |
1301 | GNUNET_CRYPTO_mpi_print_unsigned (result->q_y, | 1383 | GNUNET_CRYPTO_mpi_print_unsigned (result->q_y, sizeof (result->q_y), q_y); |
1302 | sizeof (result->q_y), | ||
1303 | q_y); | ||
1304 | gcry_mpi_release (q_y); | 1384 | gcry_mpi_release (q_y); |
1305 | gcry_ctx_release (ctx); | 1385 | gcry_ctx_release (ctx); |
1306 | } | 1386 | } |
@@ -1313,17 +1393,16 @@ GNUNET_CRYPTO_ecdsa_public_key_derive (const struct GNUNET_CRYPTO_EcdsaPublicKey | |||
1313 | * @param length number of bytes in @a buffer | 1393 | * @param length number of bytes in @a buffer |
1314 | */ | 1394 | */ |
1315 | static void | 1395 | static void |
1316 | reverse_buffer (unsigned char *buffer, | 1396 | reverse_buffer (unsigned char *buffer, size_t length) |
1317 | size_t length) | ||
1318 | { | 1397 | { |
1319 | unsigned char tmp; | 1398 | unsigned char tmp; |
1320 | size_t i; | 1399 | size_t i; |
1321 | 1400 | ||
1322 | for (i=0; i < length/2; i++) | 1401 | for (i = 0; i < length / 2; i++) |
1323 | { | 1402 | { |
1324 | tmp = buffer[i]; | 1403 | tmp = buffer[i]; |
1325 | buffer[i] = buffer[length-1-i]; | 1404 | buffer[i] = buffer[length - 1 - i]; |
1326 | buffer[length-1-i] = tmp; | 1405 | buffer[length - 1 - i] = tmp; |
1327 | } | 1406 | } |
1328 | } | 1407 | } |
1329 | 1408 | ||
@@ -1352,29 +1431,22 @@ eddsa_d_to_a (gcry_mpi_t d) | |||
1352 | memset (digest, 0, sizeof digest); | 1431 | memset (digest, 0, sizeof digest); |
1353 | memset (hvec, 0, sizeof hvec); | 1432 | memset (hvec, 0, sizeof hvec); |
1354 | rawmpilen = sizeof (rawmpi); | 1433 | rawmpilen = sizeof (rawmpi); |
1355 | GNUNET_assert (0 == | 1434 | GNUNET_assert ( |
1356 | gcry_mpi_print (GCRYMPI_FMT_USG, | 1435 | 0 == gcry_mpi_print (GCRYMPI_FMT_USG, rawmpi, rawmpilen, &rawmpilen, d)); |
1357 | rawmpi, rawmpilen, &rawmpilen, | ||
1358 | d)); | ||
1359 | hvec[0].data = digest; | 1436 | hvec[0].data = digest; |
1360 | hvec[0].off = 0; | 1437 | hvec[0].off = 0; |
1361 | hvec[0].len = b > rawmpilen ? (b - rawmpilen) : 0; | 1438 | hvec[0].len = b > rawmpilen ? (b - rawmpilen) : 0; |
1362 | hvec[1].data = rawmpi; | 1439 | hvec[1].data = rawmpi; |
1363 | hvec[1].off = 0; | 1440 | hvec[1].off = 0; |
1364 | hvec[1].len = rawmpilen; | 1441 | hvec[1].len = rawmpilen; |
1365 | GNUNET_assert (0 == | 1442 | GNUNET_assert ( |
1366 | gcry_md_hash_buffers (GCRY_MD_SHA512, | 1443 | 0 == gcry_md_hash_buffers (GCRY_MD_SHA512, 0 /* flags */, digest, hvec, 2)); |
1367 | 0 /* flags */, | ||
1368 | digest, | ||
1369 | hvec, 2)); | ||
1370 | /* Compute the A value. */ | 1444 | /* Compute the A value. */ |
1371 | reverse_buffer (digest, 32); /* Only the first half of the hash. */ | 1445 | reverse_buffer (digest, 32); /* Only the first half of the hash. */ |
1372 | digest[0] = (digest[0] & 0x7f) | 0x40; | 1446 | digest[0] = (digest[0] & 0x7f) | 0x40; |
1373 | digest[31] &= 0xf8; | 1447 | digest[31] &= 0xf8; |
1374 | 1448 | ||
1375 | GNUNET_CRYPTO_mpi_scan_unsigned (&a, | 1449 | GNUNET_CRYPTO_mpi_scan_unsigned (&a, digest, 32); |
1376 | digest, | ||
1377 | 32); | ||
1378 | return a; | 1450 | return a; |
1379 | } | 1451 | } |
1380 | 1452 | ||
@@ -1410,12 +1482,9 @@ point_to_hash (gcry_mpi_point_t result, | |||
1410 | as that does not include the sign bit; x should be a 255-bit | 1482 | as that does not include the sign bit; x should be a 255-bit |
1411 | value, so with the sign it should fit snugly into the 256-bit | 1483 | value, so with the sign it should fit snugly into the 256-bit |
1412 | xbuf */ | 1484 | xbuf */ |
1413 | GNUNET_assert (0 == | 1485 | GNUNET_assert ( |
1414 | gcry_mpi_print (GCRYMPI_FMT_STD, xbuf, rsize, &rsize, | 1486 | 0 == gcry_mpi_print (GCRYMPI_FMT_STD, xbuf, rsize, &rsize, result_x)); |
1415 | result_x)); | 1487 | GNUNET_CRYPTO_hash (xbuf, rsize, key_material); |
1416 | GNUNET_CRYPTO_hash (xbuf, | ||
1417 | rsize, | ||
1418 | key_material); | ||
1419 | gcry_mpi_release (result_x); | 1488 | gcry_mpi_release (result_x); |
1420 | return GNUNET_OK; | 1489 | return GNUNET_OK; |
1421 | } | 1490 | } |
@@ -1447,9 +1516,11 @@ GNUNET_CRYPTO_eddsa_ecdh (const struct GNUNET_CRYPTO_EddsaPrivateKey *priv, | |||
1447 | BENCHMARK_START (eddsa_ecdh); | 1516 | BENCHMARK_START (eddsa_ecdh); |
1448 | 1517 | ||
1449 | /* first, extract the q = dP value from the public key */ | 1518 | /* first, extract the q = dP value from the public key */ |
1450 | if (0 != gcry_sexp_build (&pub_sexpr, NULL, | 1519 | if (0 != gcry_sexp_build (&pub_sexpr, |
1520 | NULL, | ||
1451 | "(public-key(ecc(curve " CURVE ")(q %b)))", | 1521 | "(public-key(ecc(curve " CURVE ")(q %b)))", |
1452 | (int)sizeof (pub->q_y), pub->q_y)) | 1522 | (int) sizeof (pub->q_y), |
1523 | pub->q_y)) | ||
1453 | return GNUNET_SYSERR; | 1524 | return GNUNET_SYSERR; |
1454 | GNUNET_assert (0 == gcry_mpi_ec_new (&ctx, pub_sexpr, NULL)); | 1525 | GNUNET_assert (0 == gcry_mpi_ec_new (&ctx, pub_sexpr, NULL)); |
1455 | gcry_sexp_release (pub_sexpr); | 1526 | gcry_sexp_release (pub_sexpr); |
@@ -1468,9 +1539,7 @@ GNUNET_CRYPTO_eddsa_ecdh (const struct GNUNET_CRYPTO_EddsaPrivateKey *priv, | |||
1468 | gcry_mpi_point_release (q); | 1539 | gcry_mpi_point_release (q); |
1469 | gcry_mpi_release (a); | 1540 | gcry_mpi_release (a); |
1470 | 1541 | ||
1471 | ret = point_to_hash (result, | 1542 | ret = point_to_hash (result, ctx, key_material); |
1472 | ctx, | ||
1473 | key_material); | ||
1474 | gcry_mpi_point_release (result); | 1543 | gcry_mpi_point_release (result); |
1475 | gcry_ctx_release (ctx); | 1544 | gcry_ctx_release (ctx); |
1476 | BENCHMARK_END (eddsa_ecdh); | 1545 | BENCHMARK_END (eddsa_ecdh); |
@@ -1503,9 +1572,11 @@ GNUNET_CRYPTO_ecdsa_ecdh (const struct GNUNET_CRYPTO_EcdsaPrivateKey *priv, | |||
1503 | BENCHMARK_START (ecdsa_ecdh); | 1572 | BENCHMARK_START (ecdsa_ecdh); |
1504 | 1573 | ||
1505 | /* first, extract the q = dP value from the public key */ | 1574 | /* first, extract the q = dP value from the public key */ |
1506 | if (0 != gcry_sexp_build (&pub_sexpr, NULL, | 1575 | if (0 != gcry_sexp_build (&pub_sexpr, |
1576 | NULL, | ||
1507 | "(public-key(ecc(curve " CURVE ")(q %b)))", | 1577 | "(public-key(ecc(curve " CURVE ")(q %b)))", |
1508 | (int)sizeof (pub->q_y), pub->q_y)) | 1578 | (int) sizeof (pub->q_y), |
1579 | pub->q_y)) | ||
1509 | return GNUNET_SYSERR; | 1580 | return GNUNET_SYSERR; |
1510 | GNUNET_assert (0 == gcry_mpi_ec_new (&ctx, pub_sexpr, NULL)); | 1581 | GNUNET_assert (0 == gcry_mpi_ec_new (&ctx, pub_sexpr, NULL)); |
1511 | gcry_sexp_release (pub_sexpr); | 1582 | gcry_sexp_release (pub_sexpr); |
@@ -1521,9 +1592,7 @@ GNUNET_CRYPTO_ecdsa_ecdh (const struct GNUNET_CRYPTO_EcdsaPrivateKey *priv, | |||
1521 | gcry_mpi_release (d); | 1592 | gcry_mpi_release (d); |
1522 | 1593 | ||
1523 | /* finally, convert point to string for hashing */ | 1594 | /* finally, convert point to string for hashing */ |
1524 | ret = point_to_hash (result, | 1595 | ret = point_to_hash (result, ctx, key_material); |
1525 | ctx, | ||
1526 | key_material); | ||
1527 | gcry_mpi_point_release (result); | 1596 | gcry_mpi_point_release (result); |
1528 | gcry_ctx_release (ctx); | 1597 | gcry_ctx_release (ctx); |
1529 | BENCHMARK_END (ecdsa_ecdh); | 1598 | BENCHMARK_END (ecdsa_ecdh); |
@@ -1531,7 +1600,6 @@ GNUNET_CRYPTO_ecdsa_ecdh (const struct GNUNET_CRYPTO_EcdsaPrivateKey *priv, | |||
1531 | } | 1600 | } |
1532 | 1601 | ||
1533 | 1602 | ||
1534 | |||
1535 | /** | 1603 | /** |
1536 | * @ingroup crypto | 1604 | * @ingroup crypto |
1537 | * Derive key material from a EdDSA public key and a private ECDH key. | 1605 | * Derive key material from a EdDSA public key and a private ECDH key. |
@@ -1557,9 +1625,11 @@ GNUNET_CRYPTO_ecdh_eddsa (const struct GNUNET_CRYPTO_EcdhePrivateKey *priv, | |||
1557 | BENCHMARK_START (ecdh_eddsa); | 1625 | BENCHMARK_START (ecdh_eddsa); |
1558 | 1626 | ||
1559 | /* first, extract the q = dP value from the public key */ | 1627 | /* first, extract the q = dP value from the public key */ |
1560 | if (0 != gcry_sexp_build (&pub_sexpr, NULL, | 1628 | if (0 != gcry_sexp_build (&pub_sexpr, |
1629 | NULL, | ||
1561 | "(public-key(ecc(curve " CURVE ")(q %b)))", | 1630 | "(public-key(ecc(curve " CURVE ")(q %b)))", |
1562 | (int)sizeof (pub->q_y), pub->q_y)) | 1631 | (int) sizeof (pub->q_y), |
1632 | pub->q_y)) | ||
1563 | return GNUNET_SYSERR; | 1633 | return GNUNET_SYSERR; |
1564 | GNUNET_assert (0 == gcry_mpi_ec_new (&ctx, pub_sexpr, NULL)); | 1634 | GNUNET_assert (0 == gcry_mpi_ec_new (&ctx, pub_sexpr, NULL)); |
1565 | gcry_sexp_release (pub_sexpr); | 1635 | gcry_sexp_release (pub_sexpr); |
@@ -1575,9 +1645,7 @@ GNUNET_CRYPTO_ecdh_eddsa (const struct GNUNET_CRYPTO_EcdhePrivateKey *priv, | |||
1575 | gcry_mpi_release (d); | 1645 | gcry_mpi_release (d); |
1576 | 1646 | ||
1577 | /* finally, convert point to string for hashing */ | 1647 | /* finally, convert point to string for hashing */ |
1578 | ret = point_to_hash (result, | 1648 | ret = point_to_hash (result, ctx, key_material); |
1579 | ctx, | ||
1580 | key_material); | ||
1581 | gcry_mpi_point_release (result); | 1649 | gcry_mpi_point_release (result); |
1582 | gcry_ctx_release (ctx); | 1650 | gcry_ctx_release (ctx); |
1583 | BENCHMARK_END (ecdh_eddsa); | 1651 | BENCHMARK_END (ecdh_eddsa); |
@@ -1600,7 +1668,8 @@ GNUNET_CRYPTO_ecdh_ecdsa (const struct GNUNET_CRYPTO_EcdhePrivateKey *priv, | |||
1600 | struct GNUNET_HashCode *key_material) | 1668 | struct GNUNET_HashCode *key_material) |
1601 | { | 1669 | { |
1602 | return GNUNET_CRYPTO_ecdh_eddsa (priv, | 1670 | return GNUNET_CRYPTO_ecdh_eddsa (priv, |
1603 | (const struct GNUNET_CRYPTO_EddsaPublicKey *)pub, | 1671 | (const struct GNUNET_CRYPTO_EddsaPublicKey *) |
1672 | pub, | ||
1604 | key_material); | 1673 | key_material); |
1605 | } | 1674 | } |
1606 | 1675 | ||