LCOV - code coverage report
Current view: top level - util - denom.c (source / functions) Hit Total Coverage
Test: coverage.info Lines: 138 168 82.1 %
Date: 2025-06-05 21:03:14 Functions: 21 24 87.5 %

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

Generated by: LCOV version 1.16