LCOV - code coverage report
Current view: top level - util - denom.c (source / functions) Coverage Total Hit
Test: coverage.info Lines: 82.1 % 168 138
Test Date: 2026-04-14 15:39:31 Functions: 87.5 % 24 21

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

Generated by: LCOV version 2.0-1