exchange

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

crypto.c (23976B)


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