exchange

Base system with REST service to issue digital coins, run by the payment service provider
Log | Files | Refs | Submodules | README | LICENSE

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 */