exchange

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

crypto.c (23604B)


      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 "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_hkdf_gnunet (
    170                      secrets,
    171                      sizeof (*secrets) * num_coins,
    172                      &be_salt,
    173                      sizeof (be_salt),
    174                      seed,
    175                      sizeof (*seed),
    176                      GNUNET_CRYPTO_kdf_arg_string ("taler-withdraw-secrets")));
    177   }
    178 }
    179 
    180 
    181 void
    182 TALER_withdraw_expand_kappa_seed (
    183   const struct TALER_WithdrawMasterSeedP *seed,
    184   struct TALER_KappaWithdrawMasterSeedP *seeds)
    185 {
    186   uint32_t be_salt = htonl (TALER_CNC_KAPPA);
    187 
    188   GNUNET_assert (GNUNET_OK ==
    189                  GNUNET_CRYPTO_hkdf_gnunet (
    190                    seeds,
    191                    sizeof (*seeds),
    192                    &be_salt,
    193                    sizeof (be_salt),
    194                    seed,
    195                    sizeof (*seed),
    196                    GNUNET_CRYPTO_kdf_arg_string ("taler-kappa-seeds")));
    197 }
    198 
    199 
    200 void
    201 TALER_planchet_master_setup_random (
    202   struct TALER_PlanchetMasterSecretP *ps)
    203 {
    204   GNUNET_CRYPTO_random_block (ps,
    205                               sizeof (*ps));
    206 }
    207 
    208 
    209 void
    210 TALER_withdraw_master_seed_setup_random (
    211   struct TALER_WithdrawMasterSeedP *seed)
    212 {
    213   GNUNET_CRYPTO_random_block (seed,
    214                               sizeof (*seed));
    215 }
    216 
    217 
    218 void
    219 TALER_refresh_master_setup_random (
    220   struct TALER_PublicRefreshMasterSeedP *rms)
    221 {
    222   GNUNET_CRYPTO_random_block (rms,
    223                               sizeof (*rms));
    224 }
    225 
    226 
    227 void
    228 TALER_transfer_secret_to_planchet_secret (
    229   const struct TALER_TransferSecretP *secret_seed,
    230   uint32_t coin_num_salt,
    231   struct TALER_PlanchetMasterSecretP *ps)
    232 {
    233   uint32_t be_salt = htonl (coin_num_salt);
    234 
    235   GNUNET_assert (GNUNET_OK ==
    236                  GNUNET_CRYPTO_hkdf_gnunet (
    237                    ps,
    238                    sizeof (*ps),
    239                    &be_salt,
    240                    sizeof (be_salt),
    241                    secret_seed,
    242                    sizeof (*secret_seed),
    243                    GNUNET_CRYPTO_kdf_arg_string ("taler-coin-derivation")));
    244 }
    245 
    246 
    247 void
    248 TALER_cs_withdraw_seed_to_blinding_seed (
    249   const struct TALER_WithdrawMasterSeedP *seed,
    250   struct TALER_BlindingMasterSeedP *blinding_seed)
    251 {
    252   GNUNET_assert (GNUNET_YES ==
    253                  GNUNET_CRYPTO_hkdf_gnunet (
    254                    blinding_seed,
    255                    sizeof (*blinding_seed),
    256                    "withdraw-blinding",
    257                    strlen ("withdraw-blinding"),
    258                    seed,
    259                    sizeof(*seed)));
    260 }
    261 
    262 
    263 void
    264 TALER_cs_refresh_seed_to_blinding_seed (
    265   const struct TALER_PublicRefreshMasterSeedP *seed,
    266   const struct TALER_CoinSpendPrivateKeyP *coin_priv,
    267   struct TALER_BlindingMasterSeedP *blinding_seed)
    268 {
    269   GNUNET_assert (GNUNET_YES ==
    270                  GNUNET_CRYPTO_hkdf_gnunet (
    271                    blinding_seed,
    272                    sizeof (*blinding_seed),
    273                    "refresh-blinding",
    274                    strlen ("refresh-blinding"),
    275                    coin_priv,
    276                    sizeof (*coin_priv),
    277                    GNUNET_CRYPTO_kdf_arg_auto (seed)));
    278 }
    279 
    280 
    281 void
    282 TALER_cs_nonce_derive_indexed (
    283   const struct TALER_BlindingMasterSeedP *seed,
    284   bool for_melt,
    285   uint32_t index,
    286   struct GNUNET_CRYPTO_CsSessionNonce *nonce)
    287 {
    288   uint32_t be_salt = htonl (index);
    289   const char *operation = for_melt ? "refresh-n" : "withdraw-n";
    290 
    291   GNUNET_assert (GNUNET_YES ==
    292                  GNUNET_CRYPTO_hkdf_gnunet (
    293                    nonce,
    294                    sizeof (*nonce),
    295                    &be_salt,
    296                    sizeof (be_salt),
    297                    operation,
    298                    strlen (operation),
    299                    GNUNET_CRYPTO_kdf_arg_auto (seed)));
    300 }
    301 
    302 
    303 void
    304 TALER_cs_derive_nonces_from_seed (
    305   const struct TALER_BlindingMasterSeedP *seed,
    306   bool for_melt,
    307   size_t num,
    308   const uint32_t indices[static num],
    309   struct GNUNET_CRYPTO_CsSessionNonce nonces[static num])
    310 {
    311   GNUNET_assert (TALER_MAX_COINS >= num);
    312 
    313   for (size_t i = 0; i < num; i++)
    314     TALER_cs_nonce_derive_indexed (
    315       seed,
    316       for_melt,
    317       indices[i],
    318       &nonces[i]);
    319 }
    320 
    321 
    322 void
    323 TALER_cs_derive_only_cs_blind_nonces_from_seed (
    324   const struct TALER_BlindingMasterSeedP *seed,
    325   bool for_melt,
    326   size_t num,
    327   const uint32_t indices[static num],
    328   union GNUNET_CRYPTO_BlindSessionNonce nonces[static num])
    329 {
    330   GNUNET_assert (TALER_MAX_COINS >= num);
    331 
    332   for (size_t i = 0; i < num; i++)
    333     TALER_cs_nonce_derive_indexed (
    334       seed,
    335       for_melt,
    336       indices[i],
    337       &nonces[i].cs_nonce);
    338 }
    339 
    340 
    341 void
    342 TALER_cs_derive_blind_nonces_from_seed (
    343   const struct TALER_BlindingMasterSeedP *seed,
    344   bool for_melt,
    345   size_t num,
    346   const bool is_cs[static num],
    347   union GNUNET_CRYPTO_BlindSessionNonce nonces[static num])
    348 {
    349   for (size_t i = 0; i < num; i++)
    350   {
    351     if (is_cs[i])
    352       TALER_cs_nonce_derive_indexed (
    353         seed,
    354         for_melt,
    355         i,
    356         &nonces[i].cs_nonce);
    357   }
    358 }
    359 
    360 
    361 void
    362 TALER_rsa_pub_hash (const struct GNUNET_CRYPTO_RsaPublicKey *rsa,
    363                     struct TALER_RsaPubHashP *h_rsa)
    364 {
    365   GNUNET_CRYPTO_rsa_public_key_hash (rsa,
    366                                      &h_rsa->hash);
    367 
    368 }
    369 
    370 
    371 void
    372 TALER_cs_pub_hash (const struct GNUNET_CRYPTO_CsPublicKey *cs,
    373                    struct TALER_CsPubHashP *h_cs)
    374 {
    375   GNUNET_CRYPTO_hash (cs,
    376                       sizeof(*cs),
    377                       &h_cs->hash);
    378 }
    379 
    380 
    381 enum GNUNET_GenericReturnValue
    382 TALER_planchet_prepare (
    383   const struct TALER_DenominationPublicKey *dk,
    384   const struct TALER_ExchangeBlindingValues *blinding_values,
    385   const union GNUNET_CRYPTO_BlindingSecretP *bks,
    386   const union GNUNET_CRYPTO_BlindSessionNonce *nonce,
    387   const struct TALER_CoinSpendPrivateKeyP *coin_priv,
    388   const struct TALER_AgeCommitmentHashP *ach,
    389   struct TALER_CoinPubHashP *c_hash,
    390   struct TALER_PlanchetDetail *pd)
    391 {
    392   struct TALER_CoinSpendPublicKeyP coin_pub;
    393 
    394   GNUNET_assert (blinding_values->blinding_inputs->cipher ==
    395                  dk->bsign_pub_key->cipher);
    396   GNUNET_CRYPTO_eddsa_key_get_public (&coin_priv->eddsa_priv,
    397                                       &coin_pub.eddsa_pub);
    398   if (GNUNET_OK !=
    399       TALER_denom_blind (dk,
    400                          bks,
    401                          nonce,
    402                          ach,
    403                          &coin_pub,
    404                          blinding_values,
    405                          c_hash,
    406                          &pd->blinded_planchet))
    407   {
    408     GNUNET_break (0);
    409     return GNUNET_SYSERR;
    410   }
    411   TALER_denom_pub_hash (dk,
    412                         &pd->denom_pub_hash);
    413   return GNUNET_OK;
    414 }
    415 
    416 
    417 void
    418 TALER_planchet_detail_free (struct TALER_PlanchetDetail *pd)
    419 {
    420   TALER_blinded_planchet_free (&pd->blinded_planchet);
    421 }
    422 
    423 
    424 enum GNUNET_GenericReturnValue
    425 TALER_planchet_to_coin (
    426   const struct TALER_DenominationPublicKey *dk,
    427   const struct TALER_BlindedDenominationSignature *blind_sig,
    428   const union GNUNET_CRYPTO_BlindingSecretP *bks,
    429   const struct TALER_CoinSpendPrivateKeyP *coin_priv,
    430   const struct TALER_AgeCommitmentHashP *ach,
    431   const struct TALER_CoinPubHashP *c_hash,
    432   const struct TALER_ExchangeBlindingValues *alg_values,
    433   struct TALER_FreshCoin *coin)
    434 {
    435   if (dk->bsign_pub_key->cipher !=
    436       blind_sig->blinded_sig->cipher)
    437   {
    438     GNUNET_break_op (0);
    439     return GNUNET_SYSERR;
    440   }
    441   if (dk->bsign_pub_key->cipher !=
    442       alg_values->blinding_inputs->cipher)
    443   {
    444     GNUNET_break_op (0);
    445     return GNUNET_SYSERR;
    446   }
    447   if (GNUNET_OK !=
    448       TALER_denom_sig_unblind (&coin->sig,
    449                                blind_sig,
    450                                bks,
    451                                c_hash,
    452                                alg_values,
    453                                dk))
    454   {
    455     GNUNET_break_op (0);
    456     return GNUNET_SYSERR;
    457   }
    458   if (GNUNET_OK !=
    459       TALER_denom_pub_verify (dk,
    460                               &coin->sig,
    461                               c_hash))
    462   {
    463     GNUNET_break_op (0);
    464     TALER_denom_sig_free (&coin->sig);
    465     return GNUNET_SYSERR;
    466   }
    467 
    468   coin->coin_priv = *coin_priv;
    469   coin->h_age_commitment = ach;
    470   return GNUNET_OK;
    471 }
    472 
    473 
    474 // FIXME-Oec: k_tpbs is dead in the code below!
    475 void
    476 TALER_refresh_get_commitment (
    477   struct TALER_RefreshCommitmentP *rc,
    478   const struct TALER_PublicRefreshMasterSeedP *refresh_seed,
    479   const struct TALER_BlindingMasterSeedP *blinding_seed,
    480   const struct TALER_KappaTransferPublicKeys *k_tpbs,
    481   const struct TALER_KappaHashBlindedPlanchetsP *k_bps_h,
    482   const struct TALER_CoinSpendPublicKeyP *coin_pub,
    483   const struct TALER_Amount *amount_with_fee)
    484 {
    485   struct GNUNET_HashContext *hash_context;
    486 
    487   hash_context = GNUNET_CRYPTO_hash_context_start ();
    488 
    489   /* First, the refresh master seed (from which the nonces, then signatures
    490      and finally private keys of the fresh coins are derived from) */
    491   GNUNET_assert (NULL != refresh_seed);
    492   GNUNET_CRYPTO_hash_context_read (hash_context,
    493                                    refresh_seed,
    494                                    sizeof (*refresh_seed));
    495 
    496   /* Then, in case of CS denominations, the blinding_seed from which all
    497      nonces are derived from, and therefore public R-values */
    498   {
    499     struct TALER_BlindingMasterSeedP blanko = {0};
    500     const struct TALER_BlindingMasterSeedP *pbms = &blanko;
    501 
    502     if (NULL != blinding_seed)
    503       pbms = blinding_seed;
    504     GNUNET_CRYPTO_hash_context_read (hash_context,
    505                                      pbms,
    506                                      sizeof(*pbms));
    507   }
    508 
    509   /* Next, add public key of coin and amount being refreshed */
    510   {
    511     struct TALER_AmountNBO melt_amountn;
    512 
    513     GNUNET_CRYPTO_hash_context_read (hash_context,
    514                                      coin_pub,
    515                                      sizeof (struct TALER_CoinSpendPublicKeyP));
    516     TALER_amount_hton (&melt_amountn,
    517                        amount_with_fee);
    518     GNUNET_CRYPTO_hash_context_read (hash_context,
    519                                      &melt_amountn,
    520                                      sizeof (struct TALER_AmountNBO));
    521   }
    522 
    523   /* Finally, add all the hashes of the blinded coins
    524    * (containing information about denominations), depths first */
    525   for (unsigned int k = 0; k<TALER_CNC_KAPPA; k++)
    526     GNUNET_CRYPTO_hash_context_read (hash_context,
    527                                      &k_bps_h->tuple[k],
    528                                      sizeof(k_bps_h->tuple[k]));
    529 
    530   /* Conclude */
    531   GNUNET_CRYPTO_hash_context_finish (hash_context,
    532                                      &rc->session_hash);
    533 }
    534 
    535 
    536 void
    537 TALER_refresh_expand_seed_to_kappa_batch_seeds (
    538   const struct TALER_PublicRefreshMasterSeedP *refresh_master_seed,
    539   const struct TALER_CoinSpendPrivateKeyP *coin_priv,
    540   struct TALER_KappaPrivateRefreshBatchSeedsP *kappa_batch_seeds)
    541 {
    542   GNUNET_assert (GNUNET_OK ==
    543                  GNUNET_CRYPTO_hkdf_gnunet (
    544                    kappa_batch_seeds,
    545                    sizeof (*kappa_batch_seeds),
    546                    "refresh-batch-seeds",
    547                    strlen ("refresh-batch-seeds"),
    548                    refresh_master_seed,
    549                    sizeof (*refresh_master_seed),
    550                    GNUNET_CRYPTO_kdf_arg_auto (coin_priv)));
    551 }
    552 
    553 
    554 void
    555 TALER_refresh_expand_batch_seed_to_transfer_private_keys (
    556   const struct TALER_PrivateRefreshBatchSeedP *batch_seed,
    557   size_t num_transfer_pks,
    558   struct TALER_TransferPrivateKeyP transfer_pks[num_transfer_pks])
    559 {
    560   GNUNET_assert (GNUNET_OK ==
    561                  GNUNET_CRYPTO_hkdf_gnunet (
    562                    transfer_pks,
    563                    sizeof (*transfer_pks) * num_transfer_pks,
    564                    "refresh-transfer-private-keys",
    565                    strlen ("refresh-transfer-private-keys"),
    566                    batch_seed,
    567                    sizeof (*batch_seed)));
    568 }
    569 
    570 
    571 void
    572 TALER_refresh_expand_batch_seed_to_transfer_secrets (
    573   const struct TALER_PrivateRefreshBatchSeedP *batch_seed,
    574   const struct TALER_CoinSpendPublicKeyP *coin_pub,
    575   size_t num_transfer_secrets,
    576   struct TALER_TransferSecretP transfer_secrets[num_transfer_secrets])
    577 {
    578   struct TALER_TransferPrivateKeyP transfer_pks[num_transfer_secrets];
    579 
    580   TALER_refresh_expand_batch_seed_to_transfer_private_keys (
    581     batch_seed,
    582     num_transfer_secrets,
    583     transfer_pks);
    584 
    585   for (size_t i = 0; i < num_transfer_secrets; i++)
    586   {
    587     TALER_link_reveal_transfer_secret (
    588       &transfer_pks[i],
    589       coin_pub,
    590       &transfer_secrets[i]);
    591   }
    592 }
    593 
    594 
    595 void
    596 TALER_refresh_expand_batch_seed_to_planchet_master_secrets (
    597   const struct TALER_PrivateRefreshBatchSeedP *batch_seed,
    598   const struct TALER_CoinSpendPublicKeyP *coin_pub,
    599   size_t num_planchet_secrets,
    600   struct TALER_PlanchetMasterSecretP planchet_secrets[num_planchet_secrets])
    601 {
    602   struct TALER_TransferPrivateKeyP transfer_pks[num_planchet_secrets];
    603   struct TALER_TransferSecretP transfer_secrets[num_planchet_secrets];
    604 
    605   TALER_refresh_expand_batch_seed_to_transfer_private_keys (
    606     batch_seed,
    607     num_planchet_secrets,
    608     transfer_pks);
    609 
    610   for (size_t i = 0; i < num_planchet_secrets; i++)
    611   {
    612     TALER_link_reveal_transfer_secret (
    613       &transfer_pks[i],
    614       coin_pub,
    615       &transfer_secrets[i]);
    616 
    617     TALER_transfer_secret_to_planchet_secret (
    618       &transfer_secrets[i],
    619       i,
    620       &planchet_secrets[i]);
    621   }
    622 }
    623 
    624 
    625 void
    626 TALER_refresh_expand_batch_seed_to_transfer_data (
    627   const struct TALER_PrivateRefreshBatchSeedP *batch_seed,
    628   const struct TALER_CoinSpendPublicKeyP *coin_pub,
    629   size_t num,
    630   struct TALER_PlanchetMasterSecretP planchet_secrets[num],
    631   struct TALER_TransferPublicKeyP transfer_pubs[num])
    632 {
    633   struct TALER_TransferPrivateKeyP transfer_pks[num];
    634   struct TALER_TransferSecretP transfer_secrets[num];
    635 
    636   TALER_refresh_expand_batch_seed_to_transfer_private_keys (
    637     batch_seed,
    638     num,
    639     transfer_pks);
    640 
    641   for (size_t i = 0; i < num; i++)
    642   {
    643     TALER_link_reveal_transfer_secret (
    644       &transfer_pks[i],
    645       coin_pub,
    646       &transfer_secrets[i]);
    647 
    648     TALER_transfer_secret_to_planchet_secret (
    649       &transfer_secrets[i],
    650       i,
    651       &planchet_secrets[i]);
    652 
    653     GNUNET_CRYPTO_ecdhe_key_get_public (
    654       &transfer_pks[i].ecdhe_priv,
    655       &transfer_pubs[i].ecdhe_pub);
    656   }
    657 }
    658 
    659 
    660 void
    661 TALER_refresh_expand_kappa_nonces_v27 (
    662   const struct TALER_PublicRefreshMasterSeedP *refresh_seed,
    663   struct TALER_KappaPublicRefreshNoncesP *kappa_nonces)
    664 {
    665   GNUNET_assert (GNUNET_OK ==
    666                  GNUNET_CRYPTO_hkdf_gnunet (
    667                    kappa_nonces,
    668                    sizeof (*kappa_nonces),
    669                    "refresh-kappa-nonces",
    670                    strlen ("refresh-kappa-nonces"),
    671                    refresh_seed,
    672                    sizeof (*refresh_seed)));
    673 }
    674 
    675 
    676 void
    677 TALER_refresh_signature_to_secrets_v27 (
    678   const struct TALER_PrivateRefreshNonceSignatureP *sig,
    679   size_t num_secrets,
    680   struct TALER_PlanchetMasterSecretP secrets[static num_secrets])
    681 {
    682   GNUNET_assert (GNUNET_YES ==
    683                  GNUNET_CRYPTO_hkdf_gnunet (
    684                    secrets,
    685                    sizeof (*secrets) * num_secrets,
    686                    "refresh-planchet-secret",
    687                    strlen ("refresh-planchet-secret"),
    688                    sig,
    689                    sizeof(*sig)));
    690 }
    691 
    692 
    693 void
    694 TALER_coin_pub_hash (const struct TALER_CoinSpendPublicKeyP *coin_pub,
    695                      const struct TALER_AgeCommitmentHashP *ach,
    696                      struct TALER_CoinPubHashP *coin_h)
    697 {
    698   if (TALER_AgeCommitmentHashP_isNullOrZero (ach))
    699   {
    700     /* No age commitment was set */
    701     GNUNET_CRYPTO_hash (&coin_pub->eddsa_pub,
    702                         sizeof (coin_pub->eddsa_pub),
    703                         &coin_h->hash);
    704   }
    705   else
    706   {
    707     /* Coin comes with age commitment.  Take the hash of the age commitment
    708      * into account */
    709     struct GNUNET_HashContext *hash_context;
    710 
    711     hash_context = GNUNET_CRYPTO_hash_context_start ();
    712 
    713     GNUNET_CRYPTO_hash_context_read (
    714       hash_context,
    715       &coin_pub->eddsa_pub,
    716       sizeof(coin_pub->eddsa_pub));
    717 
    718     GNUNET_CRYPTO_hash_context_read (
    719       hash_context,
    720       ach,
    721       sizeof(struct TALER_AgeCommitmentHashP));
    722 
    723     GNUNET_CRYPTO_hash_context_finish (
    724       hash_context,
    725       &coin_h->hash);
    726   }
    727 }
    728 
    729 
    730 void
    731 TALER_coin_ev_hash (const struct TALER_BlindedPlanchet *blinded_planchet,
    732                     const struct TALER_DenominationHashP *denom_hash,
    733                     struct TALER_BlindedCoinHashP *bch)
    734 {
    735   struct GNUNET_HashContext *hash_context;
    736 
    737   hash_context = GNUNET_CRYPTO_hash_context_start ();
    738   GNUNET_CRYPTO_hash_context_read (hash_context,
    739                                    denom_hash,
    740                                    sizeof(*denom_hash));
    741   TALER_blinded_planchet_hash_ (blinded_planchet,
    742                                 hash_context);
    743   GNUNET_CRYPTO_hash_context_finish (hash_context,
    744                                      &bch->hash);
    745 }
    746 
    747 
    748 GNUNET_NETWORK_STRUCT_BEGIN
    749 /**
    750  * Structure we hash to compute the group key for
    751  * a denomination group.
    752  */
    753 struct DenominationGroupP
    754 {
    755   /**
    756    * Value of coins in this denomination group.
    757    */
    758   struct TALER_AmountNBO value;
    759 
    760   /**
    761    * Fee structure for all coins in the group.
    762    */
    763   struct TALER_DenomFeeSetNBOP fees;
    764 
    765   /**
    766    * Age mask for the denomiation, in NBO.
    767    */
    768   uint32_t age_mask GNUNET_PACKED;
    769 
    770   /**
    771    * Cipher used for the denomination, in NBO.
    772    */
    773   uint32_t cipher GNUNET_PACKED;
    774 };
    775 GNUNET_NETWORK_STRUCT_END
    776 
    777 
    778 void
    779 TALER_denomination_group_get_key (
    780   const struct TALER_DenominationGroup *dg,
    781   struct GNUNET_HashCode *key)
    782 {
    783   struct DenominationGroupP dgp = {
    784     .age_mask = htonl (dg->age_mask.bits),
    785     .cipher = htonl (dg->cipher)
    786   };
    787 
    788   TALER_amount_hton (&dgp.value,
    789                      &dg->value);
    790   TALER_denom_fee_set_hton (&dgp.fees,
    791                             &dg->fees);
    792   GNUNET_CRYPTO_hash (&dgp,
    793                       sizeof (dgp),
    794                       key);
    795 }
    796 
    797 
    798 void
    799 TALER_kyc_measure_authorization_hash (
    800   const struct TALER_AccountAccessTokenP *access_token,
    801   uint64_t row,
    802   uint32_t offset,
    803   struct TALER_KycMeasureAuthorizationHashP *mah)
    804 {
    805   uint64_t be64 = GNUNET_htonll (row);
    806   uint32_t be32 = htonl ((uint32_t) offset);
    807 
    808   GNUNET_assert (
    809     GNUNET_YES ==
    810     GNUNET_CRYPTO_hkdf_gnunet (
    811       mah,
    812       sizeof (*mah),
    813       &be64,
    814       sizeof (be64),
    815       access_token,
    816       sizeof (*access_token),
    817       GNUNET_CRYPTO_kdf_arg_auto (&be32)));
    818 }
    819 
    820 
    821 void
    822 TALER_merchant_instance_auth_hash_with_salt (
    823   struct TALER_MerchantAuthenticationHashP *auth_hash,
    824   struct TALER_MerchantAuthenticationSaltP *salt,
    825   const char *passphrase)
    826 {
    827   GNUNET_assert (GNUNET_YES ==
    828                  GNUNET_CRYPTO_hkdf_gnunet (
    829                    auth_hash,
    830                    sizeof (*auth_hash),
    831                    salt,
    832                    sizeof (*salt),
    833                    passphrase,
    834                    strlen (passphrase),
    835                    GNUNET_CRYPTO_kdf_arg_string ("merchant-instance-auth")));
    836 }
    837 
    838 
    839 /* end of crypto.c */