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-10-10 19:45:21 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           35 : 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           35 :   memset (denom_pub,
      34              :           0,
      35              :           sizeof (*denom_pub));
      36           35 :   memset (denom_priv,
      37              :           0,
      38              :           sizeof (*denom_priv));
      39           35 :   va_start (ap,
      40              :             cipher);
      41           35 :   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           35 :   va_end (ap);
      47           35 :   return ret;
      48              : }
      49              : 
      50              : 
      51              : enum GNUNET_GenericReturnValue
      52           32 : 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           32 :     = GNUNET_CRYPTO_blind_sign (denom_priv->bsign_priv_key,
      59              :                                 for_melt ? "rm" : "rw",
      60           32 :                                 blinded_planchet->blinded_message);
      61           32 :   if (NULL == denom_sig->blinded_sig)
      62              :   {
      63            0 :     GNUNET_break (0);
      64            0 :     return GNUNET_SYSERR;
      65              :   }
      66           32 :   return GNUNET_OK;
      67              : }
      68              : 
      69              : 
      70              : enum GNUNET_GenericReturnValue
      71          334 : 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          668 :     = GNUNET_CRYPTO_blind_sig_unblind (bdenom_sig->blinded_sig,
      81              :                                        bks,
      82              :                                        c_hash,
      83              :                                        sizeof (*c_hash),
      84          334 :                                        alg_values->blinding_inputs,
      85          334 :                                        denom_pub->bsign_pub_key);
      86          334 :   if (NULL == denom_sig->unblinded_sig)
      87              :   {
      88            0 :     GNUNET_break_op (0);
      89            0 :     return GNUNET_SYSERR;
      90              :   }
      91          334 :   return GNUNET_OK;
      92              : }
      93              : 
      94              : 
      95              : void
      96         7006 : TALER_denom_pub_hash (const struct TALER_DenominationPublicKey *denom_pub,
      97              :                       struct TALER_DenominationHashP *denom_hash)
      98              : {
      99         7006 :   struct GNUNET_CRYPTO_BlindSignPublicKey *bsp
     100              :     = denom_pub->bsign_pub_key;
     101         7006 :   uint32_t opt[2] = {
     102         7006 :     htonl (denom_pub->age_mask.bits),
     103         7006 :     htonl ((uint32_t) bsp->cipher)
     104              :   };
     105              :   struct GNUNET_HashContext *hc;
     106              : 
     107         7006 :   hc = GNUNET_CRYPTO_hash_context_start ();
     108         7006 :   GNUNET_CRYPTO_hash_context_read (hc,
     109              :                                    opt,
     110              :                                    sizeof (opt));
     111         7006 :   switch (bsp->cipher)
     112              :   {
     113         3760 :   case GNUNET_CRYPTO_BSA_RSA:
     114              :     {
     115              :       void *buf;
     116              :       size_t blen;
     117              : 
     118         3760 :       blen = GNUNET_CRYPTO_rsa_public_key_encode (
     119         3760 :         bsp->details.rsa_public_key,
     120              :         &buf);
     121         3760 :       GNUNET_CRYPTO_hash_context_read (hc,
     122              :                                        buf,
     123              :                                        blen);
     124         3760 :       GNUNET_free (buf);
     125              :     }
     126         3760 :     break;
     127         3246 :   case GNUNET_CRYPTO_BSA_CS:
     128         3246 :     GNUNET_CRYPTO_hash_context_read (hc,
     129         3246 :                                      &bsp->details.cs_public_key,
     130              :                                      sizeof(bsp->details.cs_public_key));
     131         3246 :     break;
     132            0 :   default:
     133            0 :     GNUNET_assert (0);
     134              :   }
     135         7006 :   GNUNET_CRYPTO_hash_context_finish (hc,
     136              :                                      &denom_hash->hash);
     137         7006 : }
     138              : 
     139              : 
     140              : const struct TALER_ExchangeBlindingValues *
     141         1940 : 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         1940 :   return &alg_values;
     150              : }
     151              : 
     152              : 
     153              : enum GNUNET_GenericReturnValue
     154         1678 : 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         1678 :   TALER_coin_pub_hash (coin_pub,
     165              :                        ach,
     166              :                        c_hash);
     167              :   blinded_planchet->blinded_message
     168         3356 :     = GNUNET_CRYPTO_message_blind_to_sign (dk->bsign_pub_key,
     169              :                                            coin_bks,
     170              :                                            nonce,
     171              :                                            c_hash,
     172              :                                            sizeof (*c_hash),
     173         1678 :                                            alg_values->blinding_inputs);
     174         1678 :   if (NULL == blinded_planchet->blinded_message)
     175              :   {
     176            0 :     GNUNET_break_op (0);
     177            0 :     return GNUNET_SYSERR;
     178              :   }
     179         1678 :   return GNUNET_OK;
     180              : }
     181              : 
     182              : 
     183              : enum GNUNET_GenericReturnValue
     184          740 : 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         1480 :   return GNUNET_CRYPTO_blind_sig_verify (denom_pub->bsign_pub_key,
     189          740 :                                          denom_sig->unblinded_sig,
     190              :                                          c_hash,
     191              :                                          sizeof (*c_hash));
     192              : }
     193              : 
     194              : 
     195              : void
     196         7328 : TALER_denom_pub_free (struct TALER_DenominationPublicKey *denom_pub)
     197              : {
     198         7328 :   if (NULL != denom_pub->bsign_pub_key)
     199              :   {
     200         7328 :     GNUNET_CRYPTO_blind_sign_pub_decref (denom_pub->bsign_pub_key);
     201         7328 :     denom_pub->bsign_pub_key = NULL;
     202              :   }
     203         7328 : }
     204              : 
     205              : 
     206              : void
     207           67 : TALER_denom_priv_free (struct TALER_DenominationPrivateKey *denom_priv)
     208              : {
     209           67 :   if (NULL != denom_priv->bsign_priv_key)
     210              :   {
     211           67 :     GNUNET_CRYPTO_blind_sign_priv_decref (denom_priv->bsign_priv_key);
     212           67 :     denom_priv->bsign_priv_key = NULL;
     213              :   }
     214           67 : }
     215              : 
     216              : 
     217              : void
     218         1013 : TALER_denom_sig_free (struct TALER_DenominationSignature *denom_sig)
     219              : {
     220         1013 :   if (NULL != denom_sig->unblinded_sig)
     221              :   {
     222          994 :     GNUNET_CRYPTO_unblinded_sig_decref (denom_sig->unblinded_sig);
     223          994 :     denom_sig->unblinded_sig = NULL;
     224              :   }
     225         1013 : }
     226              : 
     227              : 
     228              : void
     229         3040 : TALER_blinded_denom_sig_free (
     230              :   struct TALER_BlindedDenominationSignature *denom_sig)
     231              : {
     232         3040 :   if (NULL != denom_sig->blinded_sig)
     233              :   {
     234         2776 :     GNUNET_CRYPTO_blinded_sig_decref (denom_sig->blinded_sig);
     235         2776 :     denom_sig->blinded_sig = NULL;
     236              :   }
     237         3040 : }
     238              : 
     239              : 
     240              : void
     241          624 : TALER_denom_ewv_free (struct TALER_ExchangeBlindingValues *ewv)
     242              : {
     243          624 :   if (ewv == TALER_denom_ewv_rsa_singleton ())
     244            0 :     return;
     245         1248 :   if (ewv->blinding_inputs ==
     246          624 :       TALER_denom_ewv_rsa_singleton ()->blinding_inputs)
     247              :   {
     248          244 :     ewv->blinding_inputs = NULL;
     249          244 :     return;
     250              :   }
     251          380 :   if (NULL != ewv->blinding_inputs)
     252              :   {
     253          362 :     GNUNET_CRYPTO_blinding_input_values_decref (ewv->blinding_inputs);
     254          362 :     ewv->blinding_inputs = NULL;
     255              :   }
     256              : }
     257              : 
     258              : 
     259              : void
     260          476 : TALER_denom_ewv_copy (struct TALER_ExchangeBlindingValues *bi_dst,
     261              :                       const struct TALER_ExchangeBlindingValues *bi_src)
     262              : {
     263          476 :   if (bi_src == TALER_denom_ewv_rsa_singleton ())
     264              :   {
     265          146 :     *bi_dst = *bi_src;
     266          146 :     return;
     267              :   }
     268              :   bi_dst->blinding_inputs
     269          330 :     = GNUNET_CRYPTO_blinding_input_values_incref (bi_src->blinding_inputs);
     270              : }
     271              : 
     272              : 
     273              : void
     274         2720 : TALER_denom_pub_copy (struct TALER_DenominationPublicKey *denom_dst,
     275              :                       const struct TALER_DenominationPublicKey *denom_src)
     276              : {
     277         2720 :   denom_dst->age_mask = denom_src->age_mask;
     278              :   denom_dst->bsign_pub_key
     279         2720 :     = GNUNET_CRYPTO_bsign_pub_incref (denom_src->bsign_pub_key);
     280         2720 : }
     281              : 
     282              : 
     283              : void
     284          250 : TALER_denom_sig_copy (struct TALER_DenominationSignature *denom_dst,
     285              :                       const struct TALER_DenominationSignature *denom_src)
     286              : {
     287              :   denom_dst->unblinded_sig
     288          250 :     = GNUNET_CRYPTO_ub_sig_incref (denom_src->unblinded_sig);
     289          250 : }
     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        11167 : TALER_denom_pub_cmp (const struct TALER_DenominationPublicKey *denom1,
     304              :                      const struct TALER_DenominationPublicKey *denom2)
     305              : {
     306        11167 :   if (denom1->bsign_pub_key->cipher !=
     307        11167 :       denom2->bsign_pub_key->cipher)
     308            0 :     return (denom1->bsign_pub_key->cipher >
     309            0 :             denom2->bsign_pub_key->cipher) ? 1 : -1;
     310        11167 :   if (denom1->age_mask.bits != denom2->age_mask.bits)
     311         5688 :     return (denom1->age_mask.bits > denom2->age_mask.bits) ? 1 : -1;
     312         5479 :   return GNUNET_CRYPTO_bsign_pub_cmp (denom1->bsign_pub_key,
     313         5479 :                                       denom2->bsign_pub_key);
     314              : }
     315              : 
     316              : 
     317              : int
     318            5 : TALER_denom_sig_cmp (const struct TALER_DenominationSignature *sig1,
     319              :                      const struct TALER_DenominationSignature *sig2)
     320              : {
     321           10 :   return GNUNET_CRYPTO_ub_sig_cmp (sig1->unblinded_sig,
     322            5 :                                    sig2->unblinded_sig);
     323              : }
     324              : 
     325              : 
     326              : int
     327         2273 : TALER_blinded_planchet_cmp (
     328              :   const struct TALER_BlindedPlanchet *bp1,
     329              :   const struct TALER_BlindedPlanchet *bp2)
     330              : {
     331         4546 :   return GNUNET_CRYPTO_blinded_message_cmp (bp1->blinded_message,
     332         2273 :                                             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         2227 : TALER_blinded_planchet_hash_ (const struct TALER_BlindedPlanchet *bp,
     348              :                               struct GNUNET_HashContext *hash_context)
     349              : {
     350         2227 :   const struct GNUNET_CRYPTO_BlindedMessage *bm = bp->blinded_message;
     351         2227 :   uint32_t cipher = htonl (bm->cipher);
     352              : 
     353         2227 :   GNUNET_CRYPTO_hash_context_read (hash_context,
     354              :                                    &cipher,
     355              :                                    sizeof (cipher));
     356         2227 :   switch (bm->cipher)
     357              :   {
     358            0 :   case GNUNET_CRYPTO_BSA_INVALID:
     359            0 :     GNUNET_break (0);
     360         2227 :     return;
     361         1126 :   case GNUNET_CRYPTO_BSA_RSA:
     362         1126 :     GNUNET_CRYPTO_hash_context_read (
     363              :       hash_context,
     364         1126 :       bm->details.rsa_blinded_message.blinded_msg,
     365         1126 :       bm->details.rsa_blinded_message.blinded_msg_size);
     366         1126 :     return;
     367         1101 :   case GNUNET_CRYPTO_BSA_CS:
     368         1101 :     GNUNET_CRYPTO_hash_context_read (
     369              :       hash_context,
     370         1101 :       &bm->details.cs_blinded_message,
     371              :       sizeof (bm->details.cs_blinded_message));
     372         1101 :     return;
     373              :   }
     374            0 :   GNUNET_assert (0);
     375              : }
     376              : 
     377              : 
     378              : void
     379         1529 : 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         1529 :   const struct GNUNET_CRYPTO_BlindingInputValues *bi =
     385              :     alg_values->blinding_inputs;
     386              : 
     387         1529 :   switch (bi->cipher)
     388              :   {
     389            0 :   case GNUNET_CRYPTO_BSA_INVALID:
     390            0 :     GNUNET_break (0);
     391            0 :     return;
     392          784 :   case GNUNET_CRYPTO_BSA_RSA:
     393          784 :     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          784 :     return;
     402          745 :   case GNUNET_CRYPTO_BSA_CS:
     403          745 :     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          745 :     return;
     413              :   }
     414            0 :   GNUNET_assert (0);
     415              : }
     416              : 
     417              : 
     418              : void
     419         1505 : 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         1505 :   const struct GNUNET_CRYPTO_BlindingInputValues *bi
     425              :     = alg_values->blinding_inputs;
     426              : 
     427         1505 :   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          760 :   case GNUNET_CRYPTO_BSA_RSA:
     436          760 :     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          760 :     return;
     445          745 :   case GNUNET_CRYPTO_BSA_CS:
     446          745 :     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          745 :     return;
     456              :   }
     457            0 :   GNUNET_assert (0);
     458              : }
     459              : 
     460              : 
     461              : void
     462         2265 : TALER_blinded_planchet_free (struct TALER_BlindedPlanchet *blinded_planchet)
     463              : {
     464         2265 :   if (NULL != blinded_planchet->blinded_message)
     465              :   {
     466         2264 :     GNUNET_CRYPTO_blinded_message_decref (blinded_planchet->blinded_message);
     467         2264 :     blinded_planchet->blinded_message = NULL;
     468              :   }
     469         2265 : }
     470              : 
     471              : 
     472              : /* end of denom.c */
        

Generated by: LCOV version 2.0-1