LCOV - code coverage report
Current view: top level - util - denom.c (source / functions) Coverage Total Hit
Test: coverage.info Lines: 82.9 % 170 141
Test Date: 2026-09-11 18:55:36 Functions: 91.7 % 24 22

            Line data    Source code
       1              : /*
       2              :   This file is part of TALER
       3              :   Copyright (C) 2021, 2022, 2023 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 denom.c
      18              :  * @brief denomination utility functions
      19              :  * @author Christian Grothoff
      20              :  */
      21              : #include "taler/taler_util.h"
      22              : 
      23              : 
      24              : enum GNUNET_GenericReturnValue
      25           33 : TALER_denom_priv_create (struct TALER_DenominationPrivateKey *denom_priv,
      26              :                          struct TALER_DenominationPublicKey *denom_pub,
      27              :                          enum GNUNET_CRYPTO_BlindSignatureAlgorithm cipher,
      28              :                          ...)
      29              : {
      30              :   enum GNUNET_GenericReturnValue ret;
      31              :   va_list ap;
      32              : 
      33           33 :   memset (denom_pub,
      34              :           0,
      35              :           sizeof (*denom_pub));
      36           33 :   memset (denom_priv,
      37              :           0,
      38              :           sizeof (*denom_priv));
      39           33 :   va_start (ap,
      40              :             cipher);
      41           33 :   ret = GNUNET_CRYPTO_blind_sign_keys_create_va (
      42              :     &denom_priv->bsign_priv_key,
      43              :     &denom_pub->bsign_pub_key,
      44              :     cipher,
      45              :     ap);
      46           33 :   va_end (ap);
      47           33 :   return ret;
      48              : }
      49              : 
      50              : 
      51              : enum GNUNET_GenericReturnValue
      52           28 : TALER_denom_sign_blinded (struct TALER_BlindedDenominationSignature *denom_sig,
      53              :                           const struct TALER_DenominationPrivateKey *denom_priv,
      54              :                           bool for_melt,
      55              :                           const struct TALER_BlindedPlanchet *blinded_planchet)
      56              : {
      57              :   denom_sig->blinded_sig
      58           28 :     = GNUNET_CRYPTO_blind_sign (denom_priv->bsign_priv_key,
      59              :                                 for_melt ? "rm" : "rw",
      60           28 :                                 blinded_planchet->blinded_message);
      61           28 :   if (NULL == denom_sig->blinded_sig)
      62              :   {
      63            0 :     GNUNET_break (0);
      64            0 :     return GNUNET_SYSERR;
      65              :   }
      66           28 :   return GNUNET_OK;
      67              : }
      68              : 
      69              : 
      70              : enum GNUNET_GenericReturnValue
      71          288 : TALER_denom_sig_unblind (
      72              :   struct TALER_DenominationSignature *denom_sig,
      73              :   const struct TALER_BlindedDenominationSignature *bdenom_sig,
      74              :   const union GNUNET_CRYPTO_BlindingSecretP *bks,
      75              :   const struct TALER_CoinPubHashP *c_hash,
      76              :   const struct TALER_ExchangeBlindingValues *alg_values,
      77              :   const struct TALER_DenominationPublicKey *denom_pub)
      78              : {
      79              :   denom_sig->unblinded_sig
      80          576 :     = GNUNET_CRYPTO_blind_sig_unblind (bdenom_sig->blinded_sig,
      81              :                                        bks,
      82              :                                        c_hash,
      83              :                                        sizeof (*c_hash),
      84          288 :                                        alg_values->blinding_inputs,
      85          288 :                                        denom_pub->bsign_pub_key);
      86          288 :   if (NULL == denom_sig->unblinded_sig)
      87              :   {
      88            0 :     GNUNET_break_op (0);
      89            0 :     return GNUNET_SYSERR;
      90              :   }
      91          288 :   return GNUNET_OK;
      92              : }
      93              : 
      94              : 
      95              : void
      96         4683 : TALER_denom_pub_hash (const struct TALER_DenominationPublicKey *denom_pub,
      97              :                       struct TALER_DenominationHashP *denom_hash)
      98              : {
      99         4683 :   struct GNUNET_CRYPTO_BlindSignPublicKey *bsp
     100              :     = denom_pub->bsign_pub_key;
     101         4683 :   uint32_t opt[2] = {
     102         4683 :     htonl (denom_pub->age_mask.bits),
     103         4683 :     htonl ((uint32_t) bsp->cipher)
     104              :   };
     105              :   struct GNUNET_HashContext *hc;
     106              : 
     107         4683 :   hc = GNUNET_CRYPTO_hash_context_start ();
     108         4683 :   GNUNET_CRYPTO_hash_context_read (hc,
     109              :                                    opt,
     110              :                                    sizeof (opt));
     111         4683 :   switch (bsp->cipher)
     112              :   {
     113         2584 :   case GNUNET_CRYPTO_BSA_RSA:
     114              :     {
     115              :       void *buf;
     116              :       size_t blen;
     117              : 
     118         2584 :       blen = GNUNET_CRYPTO_rsa_public_key_encode (
     119         2584 :         bsp->details.rsa_public_key,
     120              :         &buf);
     121         2584 :       GNUNET_CRYPTO_hash_context_read (hc,
     122              :                                        buf,
     123              :                                        blen);
     124         2584 :       GNUNET_free (buf);
     125              :     }
     126         2584 :     break;
     127         2099 :   case GNUNET_CRYPTO_BSA_CS:
     128         2099 :     GNUNET_CRYPTO_hash_context_read (hc,
     129         2099 :                                      &bsp->details.cs_public_key,
     130              :                                      sizeof(bsp->details.cs_public_key));
     131         2099 :     break;
     132            0 :   default:
     133            0 :     GNUNET_assert (0);
     134              :   }
     135         4683 :   GNUNET_CRYPTO_hash_context_finish (hc,
     136              :                                      &denom_hash->hash);
     137         4683 : }
     138              : 
     139              : 
     140              : const struct TALER_ExchangeBlindingValues *
     141         1432 : TALER_denom_ewv_rsa_singleton ()
     142              : {
     143              :   static struct GNUNET_CRYPTO_BlindingInputValues bi = {
     144              :     .cipher = GNUNET_CRYPTO_BSA_RSA
     145              :   };
     146              :   static struct TALER_ExchangeBlindingValues alg_values = {
     147              :     .blinding_inputs = &bi
     148              :   };
     149         1432 :   return &alg_values;
     150              : }
     151              : 
     152              : 
     153              : enum GNUNET_GenericReturnValue
     154         1375 : TALER_denom_blind (
     155              :   const struct TALER_DenominationPublicKey *dk,
     156              :   const union GNUNET_CRYPTO_BlindingSecretP *coin_bks,
     157              :   const union GNUNET_CRYPTO_BlindSessionNonce *nonce,
     158              :   const struct TALER_AgeCommitmentHashP *ach,
     159              :   const struct TALER_CoinSpendPublicKeyP *coin_pub,
     160              :   const struct TALER_ExchangeBlindingValues *alg_values,
     161              :   struct TALER_CoinPubHashP *c_hash,
     162              :   struct TALER_BlindedPlanchet *blinded_planchet)
     163              : {
     164         1375 :   TALER_coin_pub_hash (coin_pub,
     165              :                        ach,
     166              :                        c_hash);
     167              :   blinded_planchet->blinded_message
     168         2750 :     = GNUNET_CRYPTO_message_blind_to_sign (dk->bsign_pub_key,
     169              :                                            coin_bks,
     170              :                                            nonce,
     171              :                                            c_hash,
     172              :                                            sizeof (*c_hash),
     173         1375 :                                            alg_values->blinding_inputs);
     174         1375 :   if (NULL == blinded_planchet->blinded_message)
     175              :   {
     176            0 :     GNUNET_break_op (0);
     177            0 :     return GNUNET_SYSERR;
     178              :   }
     179         1375 :   return GNUNET_OK;
     180              : }
     181              : 
     182              : 
     183              : enum GNUNET_GenericReturnValue
     184          507 : TALER_denom_pub_verify (const struct TALER_DenominationPublicKey *denom_pub,
     185              :                         const struct TALER_DenominationSignature *denom_sig,
     186              :                         const struct TALER_CoinPubHashP *c_hash)
     187              : {
     188         1014 :   return GNUNET_CRYPTO_blind_sig_verify (denom_pub->bsign_pub_key,
     189          507 :                                          denom_sig->unblinded_sig,
     190              :                                          c_hash,
     191              :                                          sizeof (*c_hash));
     192              : }
     193              : 
     194              : 
     195              : void
     196         4285 : TALER_denom_pub_free (struct TALER_DenominationPublicKey *denom_pub)
     197              : {
     198         4285 :   if (NULL != denom_pub->bsign_pub_key)
     199              :   {
     200         4285 :     GNUNET_CRYPTO_blind_sign_pub_decref (denom_pub->bsign_pub_key);
     201         4285 :     denom_pub->bsign_pub_key = NULL;
     202              :   }
     203         4285 : }
     204              : 
     205              : 
     206              : void
     207           61 : TALER_denom_priv_free (struct TALER_DenominationPrivateKey *denom_priv)
     208              : {
     209           61 :   if (NULL != denom_priv->bsign_priv_key)
     210              :   {
     211           61 :     GNUNET_CRYPTO_blind_sign_priv_decref (denom_priv->bsign_priv_key);
     212           61 :     denom_priv->bsign_priv_key = NULL;
     213              :   }
     214           61 : }
     215              : 
     216              : 
     217              : void
     218          671 : TALER_denom_sig_free (struct TALER_DenominationSignature *denom_sig)
     219              : {
     220          671 :   if (NULL != denom_sig->unblinded_sig)
     221              :   {
     222          662 :     GNUNET_CRYPTO_unblinded_sig_decref (denom_sig->unblinded_sig);
     223          662 :     denom_sig->unblinded_sig = NULL;
     224              :   }
     225          671 : }
     226              : 
     227              : 
     228              : void
     229         2807 : TALER_blinded_denom_sig_free (
     230              :   struct TALER_BlindedDenominationSignature *denom_sig)
     231              : {
     232         2807 :   if (NULL != denom_sig->blinded_sig)
     233              :   {
     234         2543 :     GNUNET_CRYPTO_blinded_sig_decref (denom_sig->blinded_sig);
     235         2543 :     denom_sig->blinded_sig = NULL;
     236              :   }
     237         2807 : }
     238              : 
     239              : 
     240              : void
     241          462 : TALER_denom_ewv_free (struct TALER_ExchangeBlindingValues *ewv)
     242              : {
     243          462 :   if (ewv == TALER_denom_ewv_rsa_singleton ())
     244            0 :     return;
     245          924 :   if (ewv->blinding_inputs ==
     246          462 :       TALER_denom_ewv_rsa_singleton ()->blinding_inputs)
     247              :   {
     248          182 :     ewv->blinding_inputs = NULL;
     249          182 :     return;
     250              :   }
     251          280 :   if (NULL != ewv->blinding_inputs)
     252              :   {
     253          269 :     GNUNET_CRYPTO_blinding_input_values_decref (ewv->blinding_inputs);
     254          269 :     ewv->blinding_inputs = NULL;
     255              :   }
     256              : }
     257              : 
     258              : 
     259              : void
     260          353 : TALER_denom_ewv_copy (struct TALER_ExchangeBlindingValues *bi_dst,
     261              :                       const struct TALER_ExchangeBlindingValues *bi_src)
     262              : {
     263          353 :   if (bi_src == TALER_denom_ewv_rsa_singleton ())
     264              :   {
     265          113 :     *bi_dst = *bi_src;
     266          113 :     return;
     267              :   }
     268              :   bi_dst->blinding_inputs
     269          240 :     = GNUNET_CRYPTO_blinding_input_values_incref (bi_src->blinding_inputs);
     270              : }
     271              : 
     272              : 
     273              : void
     274         1474 : TALER_denom_pub_copy (struct TALER_DenominationPublicKey *denom_dst,
     275              :                       const struct TALER_DenominationPublicKey *denom_src)
     276              : {
     277         1474 :   denom_dst->age_mask = denom_src->age_mask;
     278              :   denom_dst->bsign_pub_key
     279         1474 :     = GNUNET_CRYPTO_bsign_pub_incref (denom_src->bsign_pub_key);
     280         1474 : }
     281              : 
     282              : 
     283              : void
     284          174 : TALER_denom_sig_copy (struct TALER_DenominationSignature *denom_dst,
     285              :                       const struct TALER_DenominationSignature *denom_src)
     286              : {
     287              :   denom_dst->unblinded_sig
     288          174 :     = GNUNET_CRYPTO_ub_sig_incref (denom_src->unblinded_sig);
     289          174 : }
     290              : 
     291              : 
     292              : void
     293            0 : TALER_blinded_denom_sig_copy (
     294              :   struct TALER_BlindedDenominationSignature *denom_dst,
     295              :   const struct TALER_BlindedDenominationSignature *denom_src)
     296              : {
     297              :   denom_dst->blinded_sig
     298            0 :     = GNUNET_CRYPTO_blind_sig_incref (denom_src->blinded_sig);
     299            0 : }
     300              : 
     301              : 
     302              : int
     303         9644 : TALER_denom_pub_cmp (const struct TALER_DenominationPublicKey *denom1,
     304              :                      const struct TALER_DenominationPublicKey *denom2)
     305              : {
     306         9644 :   if (denom1->bsign_pub_key->cipher !=
     307         9644 :       denom2->bsign_pub_key->cipher)
     308            0 :     return (denom1->bsign_pub_key->cipher >
     309            0 :             denom2->bsign_pub_key->cipher) ? 1 : -1;
     310         9644 :   if (denom1->age_mask.bits != denom2->age_mask.bits)
     311         4968 :     return (denom1->age_mask.bits > denom2->age_mask.bits) ? 1 : -1;
     312         4676 :   return GNUNET_CRYPTO_bsign_pub_cmp (denom1->bsign_pub_key,
     313         4676 :                                       denom2->bsign_pub_key);
     314              : }
     315              : 
     316              : 
     317              : int
     318            2 : TALER_denom_sig_cmp (const struct TALER_DenominationSignature *sig1,
     319              :                      const struct TALER_DenominationSignature *sig2)
     320              : {
     321            4 :   return GNUNET_CRYPTO_ub_sig_cmp (sig1->unblinded_sig,
     322            2 :                                    sig2->unblinded_sig);
     323              : }
     324              : 
     325              : 
     326              : int
     327         2063 : TALER_blinded_planchet_cmp (
     328              :   const struct TALER_BlindedPlanchet *bp1,
     329              :   const struct TALER_BlindedPlanchet *bp2)
     330              : {
     331         4126 :   return GNUNET_CRYPTO_blinded_message_cmp (bp1->blinded_message,
     332         2063 :                                             bp2->blinded_message);
     333              : }
     334              : 
     335              : 
     336              : int
     337            0 : TALER_blinded_denom_sig_cmp (
     338              :   const struct TALER_BlindedDenominationSignature *sig1,
     339              :   const struct TALER_BlindedDenominationSignature *sig2)
     340              : {
     341            0 :   return GNUNET_CRYPTO_blind_sig_cmp (sig1->blinded_sig,
     342            0 :                                       sig2->blinded_sig);
     343              : }
     344              : 
     345              : 
     346              : void
     347         1671 : TALER_blinded_planchet_hash_ (const struct TALER_BlindedPlanchet *bp,
     348              :                               struct GNUNET_HashContext *hash_context)
     349              : {
     350         1671 :   const struct GNUNET_CRYPTO_BlindedMessage *bm = bp->blinded_message;
     351         1671 :   uint32_t cipher = htonl (bm->cipher);
     352              : 
     353         1671 :   GNUNET_CRYPTO_hash_context_read (hash_context,
     354              :                                    &cipher,
     355              :                                    sizeof (cipher));
     356         1671 :   switch (bm->cipher)
     357              :   {
     358            0 :   case GNUNET_CRYPTO_BSA_INVALID:
     359            0 :     GNUNET_break (0);
     360         1671 :     return;
     361          847 :   case GNUNET_CRYPTO_BSA_RSA:
     362          847 :     GNUNET_CRYPTO_hash_context_read (
     363              :       hash_context,
     364          847 :       bm->details.rsa_blinded_message.blinded_msg,
     365          847 :       bm->details.rsa_blinded_message.blinded_msg_size);
     366          847 :     return;
     367          824 :   case GNUNET_CRYPTO_BSA_CS:
     368          824 :     GNUNET_CRYPTO_hash_context_read (
     369              :       hash_context,
     370          824 :       &bm->details.cs_blinded_message,
     371              :       sizeof (bm->details.cs_blinded_message));
     372          824 :     return;
     373              :   }
     374            0 :   GNUNET_assert (0);
     375              : }
     376              : 
     377              : 
     378              : void
     379         1162 : TALER_planchet_blinding_secret_create (
     380              :   const struct TALER_PlanchetMasterSecretP *ps,
     381              :   const struct TALER_ExchangeBlindingValues *alg_values,
     382              :   union GNUNET_CRYPTO_BlindingSecretP *bks)
     383              : {
     384         1162 :   const struct GNUNET_CRYPTO_BlindingInputValues *bi =
     385              :     alg_values->blinding_inputs;
     386              : 
     387         1162 :   switch (bi->cipher)
     388              :   {
     389            0 :   case GNUNET_CRYPTO_BSA_INVALID:
     390            0 :     GNUNET_break (0);
     391            0 :     return;
     392          598 :   case GNUNET_CRYPTO_BSA_RSA:
     393          598 :     GNUNET_assert (GNUNET_YES ==
     394              :                    GNUNET_CRYPTO_hkdf_gnunet (
     395              :                      &bks->rsa_bks,
     396              :                      sizeof (bks->rsa_bks),
     397              :                      "bks",
     398              :                      strlen ("bks"),
     399              :                      ps,
     400              :                      sizeof(*ps)));
     401          598 :     return;
     402          564 :   case GNUNET_CRYPTO_BSA_CS:
     403          564 :     GNUNET_assert (GNUNET_YES ==
     404              :                    GNUNET_CRYPTO_hkdf_gnunet (
     405              :                      &bks->nonce,
     406              :                      sizeof (bks->nonce),
     407              :                      "bseed",
     408              :                      strlen ("bseed"),
     409              :                      ps,
     410              :                      sizeof(*ps),
     411              :                      GNUNET_CRYPTO_kdf_arg_auto (&bi->details.cs_values)));
     412          564 :     return;
     413              :   }
     414            0 :   GNUNET_assert (0);
     415              : }
     416              : 
     417              : 
     418              : void
     419         1138 : TALER_planchet_setup_coin_priv (
     420              :   const struct TALER_PlanchetMasterSecretP *ps,
     421              :   const struct TALER_ExchangeBlindingValues *alg_values,
     422              :   struct TALER_CoinSpendPrivateKeyP *coin_priv)
     423              : {
     424         1138 :   const struct GNUNET_CRYPTO_BlindingInputValues *bi
     425              :     = alg_values->blinding_inputs;
     426              : 
     427         1138 :   switch (bi->cipher)
     428              :   {
     429            0 :   case GNUNET_CRYPTO_BSA_INVALID:
     430            0 :     GNUNET_break (0);
     431            0 :     memset (coin_priv,
     432              :             0,
     433              :             sizeof (*coin_priv));
     434            0 :     return;
     435          574 :   case GNUNET_CRYPTO_BSA_RSA:
     436          574 :     GNUNET_assert (GNUNET_YES ==
     437              :                    GNUNET_CRYPTO_hkdf_gnunet (
     438              :                      coin_priv,
     439              :                      sizeof (*coin_priv),
     440              :                      "coin",
     441              :                      strlen ("coin"),
     442              :                      ps,
     443              :                      sizeof(*ps)));
     444          574 :     return;
     445          564 :   case GNUNET_CRYPTO_BSA_CS:
     446          564 :     GNUNET_assert (GNUNET_YES ==
     447              :                    GNUNET_CRYPTO_hkdf_gnunet (
     448              :                      coin_priv,
     449              :                      sizeof (*coin_priv),
     450              :                      "coin",
     451              :                      strlen ("coin"),
     452              :                      ps,
     453              :                      sizeof(*ps),
     454              :                      GNUNET_CRYPTO_kdf_arg_auto (&bi->details.cs_values)));
     455          564 :     return;
     456              :   }
     457            0 :   GNUNET_assert (0);
     458              : }
     459              : 
     460              : 
     461              : void
     462         1832 : TALER_blinded_planchet_free (struct TALER_BlindedPlanchet *blinded_planchet)
     463              : {
     464         1832 :   if (NULL != blinded_planchet->blinded_message)
     465              :   {
     466         1832 :     GNUNET_CRYPTO_blinded_message_decref (blinded_planchet->blinded_message);
     467         1832 :     blinded_planchet->blinded_message = NULL;
     468              :   }
     469         1832 : }
     470              : 
     471              : 
     472              : /* end of denom.c */
        

Generated by: LCOV version 2.0-1