crypto.c (27375B)
1 /* 2 This file is part of TALER 3 Copyright (C) 2014-2022 Taler Systems SA 4 5 TALER is free software; you can redistribute it and/or modify it under the 6 terms of the GNU General Public License as published by the Free Software 7 Foundation; either version 3, or (at your option) any later version. 8 9 TALER is distributed in the hope that it will be useful, but WITHOUT ANY 10 WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR 11 A PARTICULAR PURPOSE. See the GNU General Public License for more details. 12 13 You should have received a copy of the GNU General Public License along with 14 TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> 15 */ 16 /** 17 * @file util/crypto.c 18 * @brief Cryptographic utility functions 19 * @author Sree Harsha Totakura <sreeharsha@totakura.in> 20 * @author Florian Dold 21 * @author Benedikt Mueller 22 * @author Christian Grothoff 23 * @author Özgür Kesim 24 */ 25 #include "taler/platform.h" 26 #include "taler/taler_util.h" 27 #include <gcrypt.h> 28 29 /** 30 * Function called by libgcrypt on serious errors. 31 * Prints an error message and aborts the process. 32 * 33 * @param cls NULL 34 * @param wtf unknown 35 * @param msg error message 36 */ 37 static void 38 fatal_error_handler (void *cls, 39 int wtf, 40 const char *msg) 41 { 42 (void) cls; 43 (void) wtf; 44 fprintf (stderr, 45 "Fatal error in libgcrypt: %s\n", 46 msg); 47 abort (); 48 } 49 50 51 /** 52 * Initialize libgcrypt. 53 */ 54 void __attribute__ ((constructor)) 55 TALER_gcrypt_init () 56 { 57 gcry_set_fatalerror_handler (&fatal_error_handler, 58 NULL); 59 if (! gcry_check_version (NEED_LIBGCRYPT_VERSION)) 60 { 61 fprintf (stderr, 62 "libgcrypt version mismatch\n"); 63 abort (); 64 } 65 /* Disable secure memory (we should never run on a system that 66 even uses swap space for memory). */ 67 gcry_control (GCRYCTL_DISABLE_SECMEM, 0); 68 gcry_control (GCRYCTL_INITIALIZATION_FINISHED, 0); 69 } 70 71 72 enum GNUNET_GenericReturnValue 73 TALER_test_coin_valid (const struct TALER_CoinPublicInfo *coin_public_info, 74 const struct TALER_DenominationPublicKey *denom_pub) 75 { 76 struct TALER_CoinPubHashP c_hash; 77 #if ENABLE_SANITY_CHECKS 78 struct TALER_DenominationHashP d_hash; 79 80 TALER_denom_pub_hash (denom_pub, 81 &d_hash); 82 GNUNET_assert (0 == 83 GNUNET_memcmp (&d_hash, 84 &coin_public_info->denom_pub_hash)); 85 #endif 86 87 TALER_coin_pub_hash (&coin_public_info->coin_pub, 88 coin_public_info->no_age_commitment 89 ? NULL 90 : &coin_public_info->h_age_commitment, 91 &c_hash); 92 93 if (GNUNET_OK != 94 TALER_denom_pub_verify (denom_pub, 95 &coin_public_info->denom_sig, 96 &c_hash)) 97 { 98 GNUNET_log (GNUNET_ERROR_TYPE_WARNING, 99 "coin signature is invalid\n"); 100 return GNUNET_NO; 101 } 102 return GNUNET_YES; 103 } 104 105 106 void 107 TALER_link_derive_transfer_secret ( 108 const struct TALER_CoinSpendPrivateKeyP *coin_priv, 109 const struct TALER_TransferPrivateKeyP *trans_priv, 110 struct TALER_TransferSecretP *ts) 111 { 112 struct TALER_CoinSpendPublicKeyP coin_pub; 113 114 GNUNET_CRYPTO_eddsa_key_get_public (&coin_priv->eddsa_priv, 115 &coin_pub.eddsa_pub); 116 GNUNET_assert (GNUNET_OK == 117 GNUNET_CRYPTO_ecdh_eddsa (&trans_priv->ecdhe_priv, 118 &coin_pub.eddsa_pub, 119 &ts->key)); 120 } 121 122 123 void 124 TALER_link_reveal_transfer_secret ( 125 const struct TALER_TransferPrivateKeyP *trans_priv, 126 const struct TALER_CoinSpendPublicKeyP *coin_pub, 127 struct TALER_TransferSecretP *transfer_secret) 128 { 129 GNUNET_assert (GNUNET_OK == 130 GNUNET_CRYPTO_ecdh_eddsa (&trans_priv->ecdhe_priv, 131 &coin_pub->eddsa_pub, 132 &transfer_secret->key)); 133 } 134 135 136 void 137 TALER_link_recover_transfer_secret ( 138 const struct TALER_TransferPublicKeyP *trans_pub, 139 const struct TALER_CoinSpendPrivateKeyP *coin_priv, 140 struct TALER_TransferSecretP *transfer_secret) 141 { 142 GNUNET_assert (GNUNET_OK == 143 GNUNET_CRYPTO_eddsa_ecdh (&coin_priv->eddsa_priv, 144 &trans_pub->ecdhe_pub, 145 &transfer_secret->key)); 146 } 147 148 149 void 150 TALER_withdraw_expand_secrets ( 151 size_t num_coins, 152 const struct TALER_WithdrawMasterSeedP *seed, 153 struct TALER_PlanchetMasterSecretP secrets[static num_coins]) 154 { 155 _Static_assert (sizeof(seed->seed_data) == sizeof(secrets->key_data)); 156 GNUNET_assert (0 < num_coins); 157 158 if (1 == num_coins) 159 { 160 GNUNET_memcpy (&secrets[0].key_data, 161 &seed->seed_data, 162 sizeof(secrets[0].key_data)); 163 } 164 else 165 { 166 uint32_t be_salt = htonl (num_coins); 167 168 GNUNET_assert (GNUNET_OK == 169 GNUNET_CRYPTO_kdf (secrets, 170 sizeof (*secrets) * num_coins, 171 &be_salt, 172 sizeof (be_salt), 173 seed, 174 sizeof (*seed), 175 "taler-withdraw-secrets", 176 strlen ("taler-withdraw-secrets"), 177 NULL, 0)); 178 } 179 } 180 181 182 void 183 TALER_withdraw_expand_kappa_seed ( 184 const struct TALER_WithdrawMasterSeedP *seed, 185 struct TALER_KappaWithdrawMasterSeedP *seeds) 186 { 187 uint32_t be_salt = htonl (TALER_CNC_KAPPA); 188 189 GNUNET_assert (GNUNET_OK == 190 GNUNET_CRYPTO_kdf (seeds, 191 sizeof (*seeds), 192 &be_salt, 193 sizeof (be_salt), 194 seed, 195 sizeof (*seed), 196 "taler-kappa-seeds", 197 strlen ("taler-kappa-seeds"), 198 NULL, 0)); 199 } 200 201 202 void 203 TALER_planchet_master_setup_random ( 204 struct TALER_PlanchetMasterSecretP *ps) 205 { 206 GNUNET_CRYPTO_random_block (GNUNET_CRYPTO_QUALITY_STRONG, 207 ps, 208 sizeof (*ps)); 209 } 210 211 212 void 213 TALER_withdraw_master_seed_setup_random ( 214 struct TALER_WithdrawMasterSeedP *seed) 215 { 216 GNUNET_CRYPTO_random_block (GNUNET_CRYPTO_QUALITY_STRONG, 217 seed, 218 sizeof (*seed)); 219 } 220 221 222 void 223 TALER_refresh_master_setup_random ( 224 struct TALER_RefreshMasterSecretP *rms) 225 { 226 GNUNET_CRYPTO_random_block (GNUNET_CRYPTO_QUALITY_STRONG, 227 rms, 228 sizeof (*rms)); 229 } 230 231 232 void 233 TALER_transfer_secret_to_planchet_secret ( 234 const struct TALER_TransferSecretP *secret_seed, 235 uint32_t coin_num_salt, 236 struct TALER_PlanchetMasterSecretP *ps) 237 { 238 uint32_t be_salt = htonl (coin_num_salt); 239 240 GNUNET_assert (GNUNET_OK == 241 GNUNET_CRYPTO_kdf (ps, 242 sizeof (*ps), 243 &be_salt, 244 sizeof (be_salt), 245 secret_seed, 246 sizeof (*secret_seed), 247 "taler-coin-derivation", 248 strlen ("taler-coin-derivation"), 249 NULL, 0)); 250 } 251 252 253 void 254 TALER_planchet_secret_to_transfer_priv ( 255 const struct TALER_RefreshMasterSecretP *rms, 256 const struct TALER_CoinSpendPrivateKeyP *old_coin_priv, 257 uint32_t cnc_num, 258 struct TALER_TransferPrivateKeyP *tpriv) 259 { 260 uint32_t be_salt = htonl (cnc_num); 261 262 GNUNET_assert (GNUNET_OK == 263 GNUNET_CRYPTO_kdf (tpriv, 264 sizeof (*tpriv), 265 &be_salt, 266 sizeof (be_salt), 267 old_coin_priv, 268 sizeof (*old_coin_priv), 269 rms, 270 sizeof (*rms), 271 "taler-transfer-priv-derivation", 272 strlen ("taler-transfer-priv-derivation"), 273 NULL, 0)); 274 } 275 276 277 void 278 TALER_cs_withdraw_nonce_derive ( 279 const struct TALER_PlanchetMasterSecretP *ps, 280 struct GNUNET_CRYPTO_CsSessionNonce *nonce) 281 { 282 GNUNET_assert (GNUNET_YES == 283 GNUNET_CRYPTO_kdf (nonce, 284 sizeof (*nonce), 285 "n", 286 strlen ("n"), 287 ps, 288 sizeof(*ps), 289 NULL, 290 0)); 291 } 292 293 294 void 295 TALER_cs_withdraw_seed_to_blinding_seed ( 296 const struct TALER_WithdrawMasterSeedP *seed, 297 struct TALER_BlindingMasterSeedP *blinding_seed) 298 { 299 GNUNET_assert (GNUNET_YES == 300 GNUNET_CRYPTO_kdf (blinding_seed, 301 sizeof (*blinding_seed), 302 "withdraw-blinding", 303 strlen ("withdraw-blinding"), 304 seed, 305 sizeof(*seed), 306 NULL, 307 0)); 308 } 309 310 311 void 312 TALER_cs_refresh_secret_to_blinding_seed ( 313 const struct TALER_RefreshMasterSecretP *secret, 314 struct TALER_BlindingMasterSeedP *blinding_seed) 315 { 316 GNUNET_assert (GNUNET_YES == 317 GNUNET_CRYPTO_kdf (blinding_seed, 318 sizeof (*blinding_seed), 319 "refresh-blinding", 320 strlen ("refresh-blinding"), 321 secret, 322 sizeof(*secret), 323 NULL, 324 0)); 325 } 326 327 328 void 329 TALER_cs_nonce_derive_indexed ( 330 const struct TALER_BlindingMasterSeedP *seed, 331 bool for_melt, 332 uint32_t index, 333 struct GNUNET_CRYPTO_CsSessionNonce *nonce) 334 { 335 uint32_t be_salt = htonl (index); 336 const char *operation = for_melt ? "refresh-n" : "withdraw-n"; 337 338 GNUNET_assert (GNUNET_YES == 339 GNUNET_CRYPTO_kdf (nonce, 340 sizeof (*nonce), 341 &be_salt, 342 sizeof (be_salt), 343 operation, 344 strlen (operation), 345 seed, 346 sizeof(*seed), 347 NULL, 348 0)); 349 } 350 351 352 void 353 TALER_cs_derive_nonces_from_seed ( 354 const struct TALER_BlindingMasterSeedP *seed, 355 bool for_melt, 356 size_t num, 357 const uint32_t indices[static num], 358 struct GNUNET_CRYPTO_CsSessionNonce nonces[static num]) 359 { 360 GNUNET_assert (TALER_MAX_COINS > num); 361 362 for (size_t i = 0; i < num; i++) 363 TALER_cs_nonce_derive_indexed ( 364 seed, 365 for_melt, 366 indices[i], 367 &nonces[i]); 368 } 369 370 371 void 372 TALER_cs_derive_only_cs_blind_nonces_from_seed ( 373 const struct TALER_BlindingMasterSeedP *seed, 374 bool for_melt, 375 size_t num, 376 const uint32_t indices[static num], 377 union GNUNET_CRYPTO_BlindSessionNonce nonces[static num]) 378 { 379 GNUNET_assert (TALER_MAX_COINS > num); 380 381 for (size_t i = 0; i < num; i++) 382 TALER_cs_nonce_derive_indexed ( 383 seed, 384 for_melt, 385 indices[i], 386 &nonces[i].cs_nonce); 387 } 388 389 390 void 391 TALER_cs_refresh_nonce_derive ( 392 const struct TALER_RefreshMasterSecretP *rms, 393 uint32_t coin_num_salt, 394 struct GNUNET_CRYPTO_CsSessionNonce *nonce) 395 { 396 uint32_t be_salt = htonl (coin_num_salt); 397 398 GNUNET_assert (GNUNET_YES == 399 GNUNET_CRYPTO_kdf (nonce, 400 sizeof (*nonce), 401 &be_salt, 402 sizeof (be_salt), 403 "refresh-n", 404 strlen ("refresh-n"), 405 rms, 406 sizeof(*rms), 407 NULL, 408 0)); 409 } 410 411 412 bool 413 TALER_cs_mark_indices ( 414 size_t num, 415 const struct TALER_DenominationPublicKey denoms[static num], 416 bool is_cs[static num]) 417 { 418 bool found = false; 419 for (size_t i = 0; i < num; i++) 420 { 421 switch (denoms[i].bsign_pub_key->cipher) 422 { 423 case GNUNET_CRYPTO_BSA_INVALID: 424 GNUNET_assert (0); 425 break; 426 case GNUNET_CRYPTO_BSA_RSA: 427 is_cs[i] = false; 428 case GNUNET_CRYPTO_BSA_CS: 429 is_cs[i] = true; 430 found = true; 431 } 432 } 433 return found; 434 } 435 436 437 void 438 TALER_cs_derive_blind_nonces_from_seed ( 439 const struct TALER_BlindingMasterSeedP *seed, 440 bool for_melt, 441 size_t num, 442 const bool is_cs[static num], 443 union GNUNET_CRYPTO_BlindSessionNonce nonces[static num]) 444 { 445 for (size_t i = 0; i < num; i++) 446 { 447 if (is_cs[i]) 448 TALER_cs_nonce_derive_indexed ( 449 seed, 450 for_melt, 451 i, 452 &nonces[i].cs_nonce); 453 } 454 } 455 456 457 void 458 TALER_rsa_pub_hash (const struct GNUNET_CRYPTO_RsaPublicKey *rsa, 459 struct TALER_RsaPubHashP *h_rsa) 460 { 461 GNUNET_CRYPTO_rsa_public_key_hash (rsa, 462 &h_rsa->hash); 463 464 } 465 466 467 void 468 TALER_cs_pub_hash (const struct GNUNET_CRYPTO_CsPublicKey *cs, 469 struct TALER_CsPubHashP *h_cs) 470 { 471 GNUNET_CRYPTO_hash (cs, 472 sizeof(*cs), 473 &h_cs->hash); 474 } 475 476 477 enum GNUNET_GenericReturnValue 478 TALER_planchet_prepare ( 479 const struct TALER_DenominationPublicKey *dk, 480 const struct TALER_ExchangeBlindingValues *blinding_values, 481 const union GNUNET_CRYPTO_BlindingSecretP *bks, 482 const union GNUNET_CRYPTO_BlindSessionNonce *nonce, 483 const struct TALER_CoinSpendPrivateKeyP *coin_priv, 484 const struct TALER_AgeCommitmentHashP *ach, 485 struct TALER_CoinPubHashP *c_hash, 486 struct TALER_PlanchetDetail *pd) 487 { 488 struct TALER_CoinSpendPublicKeyP coin_pub; 489 490 GNUNET_assert (blinding_values->blinding_inputs->cipher == 491 dk->bsign_pub_key->cipher); 492 GNUNET_CRYPTO_eddsa_key_get_public (&coin_priv->eddsa_priv, 493 &coin_pub.eddsa_pub); 494 if (GNUNET_OK != 495 TALER_denom_blind (dk, 496 bks, 497 nonce, 498 ach, 499 &coin_pub, 500 blinding_values, 501 c_hash, 502 &pd->blinded_planchet)) 503 { 504 GNUNET_break (0); 505 return GNUNET_SYSERR; 506 } 507 TALER_denom_pub_hash (dk, 508 &pd->denom_pub_hash); 509 return GNUNET_OK; 510 } 511 512 513 void 514 TALER_planchet_detail_free (struct TALER_PlanchetDetail *pd) 515 { 516 TALER_blinded_planchet_free (&pd->blinded_planchet); 517 } 518 519 520 enum GNUNET_GenericReturnValue 521 TALER_planchet_to_coin ( 522 const struct TALER_DenominationPublicKey *dk, 523 const struct TALER_BlindedDenominationSignature *blind_sig, 524 const union GNUNET_CRYPTO_BlindingSecretP *bks, 525 const struct TALER_CoinSpendPrivateKeyP *coin_priv, 526 const struct TALER_AgeCommitmentHashP *ach, 527 const struct TALER_CoinPubHashP *c_hash, 528 const struct TALER_ExchangeBlindingValues *alg_values, 529 struct TALER_FreshCoin *coin) 530 { 531 if (dk->bsign_pub_key->cipher != 532 blind_sig->blinded_sig->cipher) 533 { 534 GNUNET_break_op (0); 535 return GNUNET_SYSERR; 536 } 537 if (dk->bsign_pub_key->cipher != 538 alg_values->blinding_inputs->cipher) 539 { 540 GNUNET_break_op (0); 541 return GNUNET_SYSERR; 542 } 543 if (GNUNET_OK != 544 TALER_denom_sig_unblind (&coin->sig, 545 blind_sig, 546 bks, 547 c_hash, 548 alg_values, 549 dk)) 550 { 551 GNUNET_break_op (0); 552 return GNUNET_SYSERR; 553 } 554 if (GNUNET_OK != 555 TALER_denom_pub_verify (dk, 556 &coin->sig, 557 c_hash)) 558 { 559 GNUNET_break_op (0); 560 TALER_denom_sig_free (&coin->sig); 561 return GNUNET_SYSERR; 562 } 563 564 coin->coin_priv = *coin_priv; 565 coin->h_age_commitment = ach; 566 return GNUNET_OK; 567 } 568 569 570 void 571 TALER_refresh_get_commitment (struct TALER_RefreshCommitmentP *rc, 572 uint32_t kappa, 573 const struct TALER_RefreshMasterSecretP *rms, 574 uint32_t num_new_coins, 575 const struct TALER_RefreshCommitmentEntry *rcs, 576 const struct TALER_CoinSpendPublicKeyP *coin_pub, 577 const struct TALER_Amount *amount_with_fee) 578 { 579 struct GNUNET_HashContext *hash_context; 580 581 hash_context = GNUNET_CRYPTO_hash_context_start (); 582 if (NULL != rms) 583 GNUNET_CRYPTO_hash_context_read (hash_context, 584 rms, 585 sizeof (*rms)); 586 /* first, iterate over transfer public keys for hash_context */ 587 for (unsigned int i = 0; i<kappa; i++) 588 { 589 GNUNET_CRYPTO_hash_context_read (hash_context, 590 &rcs[i].transfer_pub, 591 sizeof (struct TALER_TransferPublicKeyP)); 592 } 593 /* next, add all of the hashes from the denomination keys to the 594 hash_context */ 595 for (unsigned int i = 0; i<num_new_coins; i++) 596 { 597 struct TALER_DenominationHashP denom_hash; 598 599 /* The denomination keys should / must all be identical regardless 600 of what offset we use, so we use [0]. */ 601 GNUNET_assert (kappa > 0); /* sanity check */ 602 TALER_denom_pub_hash (rcs[0].new_coins[i].dk, 603 &denom_hash); 604 GNUNET_CRYPTO_hash_context_read (hash_context, 605 &denom_hash, 606 sizeof (denom_hash)); 607 } 608 609 /* next, add public key of coin and amount being refreshed */ 610 { 611 struct TALER_AmountNBO melt_amountn; 612 613 GNUNET_CRYPTO_hash_context_read (hash_context, 614 coin_pub, 615 sizeof (struct TALER_CoinSpendPublicKeyP)); 616 TALER_amount_hton (&melt_amountn, 617 amount_with_fee); 618 GNUNET_CRYPTO_hash_context_read (hash_context, 619 &melt_amountn, 620 sizeof (struct TALER_AmountNBO)); 621 } 622 623 /* finally, add all the envelopes */ 624 for (unsigned int i = 0; i<kappa; i++) 625 { 626 const struct TALER_RefreshCommitmentEntry *rce = &rcs[i]; 627 628 for (unsigned int j = 0; j<num_new_coins; j++) 629 { 630 const struct TALER_RefreshCoinData *rcd = &rce->new_coins[j]; 631 632 TALER_blinded_planchet_hash_ (&rcd->blinded_planchet, 633 hash_context); 634 } 635 } 636 637 /* Conclude */ 638 GNUNET_CRYPTO_hash_context_finish (hash_context, 639 &rc->session_hash); 640 } 641 642 643 void 644 TALER_refresh_get_commitment_v27 ( 645 struct TALER_RefreshCommitmentP *rc, 646 const struct TALER_PublicRefreshMasterSeedP *refresh_seed, 647 const struct TALER_BlindingMasterSeedP *blinding_seed, 648 const struct TALER_KappaHashBlindedPlanchetsP *k_bps_h, 649 const struct TALER_CoinSpendPublicKeyP *coin_pub, 650 const struct TALER_Amount *amount_with_fee) 651 { 652 struct GNUNET_HashContext *hash_context; 653 654 hash_context = GNUNET_CRYPTO_hash_context_start (); 655 656 /* First, the refresh master seed (from which the nonces, then signatures 657 and finally private keys of the fresh coins are derived from) */ 658 GNUNET_assert (NULL != refresh_seed); 659 GNUNET_CRYPTO_hash_context_read (hash_context, 660 refresh_seed, 661 sizeof (*refresh_seed)); 662 663 /* Then, in case of CS denominations, the blinding_seed from which all 664 nonces are derived from, and therefore public R-values */ 665 { 666 struct TALER_BlindingMasterSeedP blanko = {0}; 667 const struct TALER_BlindingMasterSeedP *pbms = &blanko; 668 669 if (NULL != blinding_seed) 670 pbms = blinding_seed; 671 GNUNET_CRYPTO_hash_context_read (hash_context, 672 pbms, 673 sizeof(*pbms)); 674 } 675 676 /* Next, add public key of coin and amount being refreshed */ 677 { 678 struct TALER_AmountNBO melt_amountn; 679 680 GNUNET_CRYPTO_hash_context_read (hash_context, 681 coin_pub, 682 sizeof (struct TALER_CoinSpendPublicKeyP)); 683 TALER_amount_hton (&melt_amountn, 684 amount_with_fee); 685 GNUNET_CRYPTO_hash_context_read (hash_context, 686 &melt_amountn, 687 sizeof (struct TALER_AmountNBO)); 688 } 689 690 /* Finally, add all the hashes of the blinded coins 691 * (containing information about denominations), depths first */ 692 for (unsigned int k = 0; k<TALER_CNC_KAPPA; k++) 693 GNUNET_CRYPTO_hash_context_read (hash_context, 694 &k_bps_h->tuple[k], 695 sizeof(k_bps_h->tuple[k])); 696 697 /* Conclude */ 698 GNUNET_CRYPTO_hash_context_finish (hash_context, 699 &rc->session_hash); 700 } 701 702 703 void 704 TALER_refresh_master_secret_to_refresh_seed ( 705 const struct TALER_RefreshMasterSecretP *rms, 706 struct TALER_PublicRefreshMasterSeedP *r_seed) 707 { 708 GNUNET_assert (GNUNET_OK == 709 GNUNET_CRYPTO_kdf (r_seed, 710 sizeof (*r_seed), 711 "refresh-seed", 712 strlen ("refresh-seed"), 713 rms, 714 sizeof (*rms), 715 NULL, 0)); 716 } 717 718 719 void 720 TALER_refresh_expand_kappa_nonces ( 721 const struct TALER_PublicRefreshMasterSeedP *refresh_seed, 722 struct TALER_KappaPublicRefreshNoncesP *kappa_nonces) 723 { 724 GNUNET_assert (GNUNET_OK == 725 GNUNET_CRYPTO_kdf (kappa_nonces, 726 sizeof (*kappa_nonces), 727 "refresh-kappa-nonces", 728 strlen ("refresh-kappa-nonces"), 729 refresh_seed, 730 sizeof (*refresh_seed), 731 NULL, 0)); 732 } 733 734 735 void 736 TALER_refresh_signature_to_secrets ( 737 const struct TALER_PrivateRefreshNonceSignatureP *sig, 738 size_t num_secrets, 739 struct TALER_PlanchetMasterSecretP secrets[static num_secrets]) 740 { 741 GNUNET_assert (GNUNET_YES == 742 GNUNET_CRYPTO_kdf (secrets, 743 sizeof (*secrets) * num_secrets, 744 "refresh-planchet-secret", 745 strlen ("refresh-planchet-secret"), 746 sig, 747 sizeof(*sig), 748 NULL, 749 0)); 750 } 751 752 753 void 754 TALER_coin_pub_hash (const struct TALER_CoinSpendPublicKeyP *coin_pub, 755 const struct TALER_AgeCommitmentHashP *ach, 756 struct TALER_CoinPubHashP *coin_h) 757 { 758 if (TALER_AgeCommitmentHashP_isNullOrZero (ach)) 759 { 760 /* No age commitment was set */ 761 GNUNET_CRYPTO_hash (&coin_pub->eddsa_pub, 762 sizeof (struct GNUNET_CRYPTO_EcdsaPublicKey), 763 &coin_h->hash); 764 } 765 else 766 { 767 /* Coin comes with age commitment. Take the hash of the age commitment 768 * into account */ 769 struct GNUNET_HashContext *hash_context; 770 771 hash_context = GNUNET_CRYPTO_hash_context_start (); 772 773 GNUNET_CRYPTO_hash_context_read ( 774 hash_context, 775 &coin_pub->eddsa_pub, 776 sizeof(struct GNUNET_CRYPTO_EcdsaPublicKey)); 777 778 GNUNET_CRYPTO_hash_context_read ( 779 hash_context, 780 ach, 781 sizeof(struct TALER_AgeCommitmentHashP)); 782 783 GNUNET_CRYPTO_hash_context_finish ( 784 hash_context, 785 &coin_h->hash); 786 } 787 } 788 789 790 void 791 TALER_coin_ev_hash (const struct TALER_BlindedPlanchet *blinded_planchet, 792 const struct TALER_DenominationHashP *denom_hash, 793 struct TALER_BlindedCoinHashP *bch) 794 { 795 struct GNUNET_HashContext *hash_context; 796 797 hash_context = GNUNET_CRYPTO_hash_context_start (); 798 GNUNET_CRYPTO_hash_context_read (hash_context, 799 denom_hash, 800 sizeof(*denom_hash)); 801 TALER_blinded_planchet_hash_ (blinded_planchet, 802 hash_context); 803 GNUNET_CRYPTO_hash_context_finish (hash_context, 804 &bch->hash); 805 } 806 807 808 GNUNET_NETWORK_STRUCT_BEGIN 809 /** 810 * Structure we hash to compute the group key for 811 * a denomination group. 812 */ 813 struct DenominationGroupP 814 { 815 /** 816 * Value of coins in this denomination group. 817 */ 818 struct TALER_AmountNBO value; 819 820 /** 821 * Fee structure for all coins in the group. 822 */ 823 struct TALER_DenomFeeSetNBOP fees; 824 825 /** 826 * Age mask for the denomiation, in NBO. 827 */ 828 uint32_t age_mask GNUNET_PACKED; 829 830 /** 831 * Cipher used for the denomination, in NBO. 832 */ 833 uint32_t cipher GNUNET_PACKED; 834 }; 835 GNUNET_NETWORK_STRUCT_END 836 837 838 void 839 TALER_denomination_group_get_key ( 840 const struct TALER_DenominationGroup *dg, 841 struct GNUNET_HashCode *key) 842 { 843 struct DenominationGroupP dgp = { 844 .age_mask = htonl (dg->age_mask.bits), 845 .cipher = htonl (dg->cipher) 846 }; 847 848 TALER_amount_hton (&dgp.value, 849 &dg->value); 850 TALER_denom_fee_set_hton (&dgp.fees, 851 &dg->fees); 852 GNUNET_CRYPTO_hash (&dgp, 853 sizeof (dgp), 854 key); 855 } 856 857 858 void 859 TALER_kyc_measure_authorization_hash ( 860 const struct TALER_AccountAccessTokenP *access_token, 861 uint64_t row, 862 uint32_t offset, 863 struct TALER_KycMeasureAuthorizationHashP *mah) 864 { 865 uint64_t be64 = GNUNET_htonll (row); 866 uint32_t be32 = htonl ((uint32_t) offset); 867 868 GNUNET_assert ( 869 GNUNET_YES == 870 GNUNET_CRYPTO_kdf (mah, 871 sizeof (*mah), 872 &be64, 873 sizeof (be64), 874 access_token, 875 sizeof (*access_token), 876 &be32, 877 sizeof (be32), 878 NULL, 879 0)); 880 } 881 882 883 void 884 TALER_merchant_instance_auth_hash_with_salt ( 885 struct TALER_MerchantAuthenticationHashP *auth_hash, 886 struct TALER_MerchantAuthenticationSaltP *salt, 887 const char *passphrase) 888 { 889 GNUNET_assert (GNUNET_YES == 890 GNUNET_CRYPTO_kdf (auth_hash, 891 sizeof (*auth_hash), 892 salt, 893 sizeof (*salt), 894 passphrase, 895 strlen (passphrase), 896 "merchant-instance-auth", 897 strlen ("merchant-instance-auth"), 898 NULL, 899 0)); 900 } 901 902 903 /* end of crypto.c */