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-01-09 13:26:54 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/platform.h"
      22              : #include "taler/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        41446 : TALER_denom_pub_hash (const struct TALER_DenominationPublicKey *denom_pub,
      95              :                       struct TALER_DenominationHashP *denom_hash)
      96              : {
      97        41446 :   struct GNUNET_CRYPTO_BlindSignPublicKey *bsp
      98              :     = denom_pub->bsign_pub_key;
      99        41446 :   uint32_t opt[2] = {
     100        41446 :     htonl (denom_pub->age_mask.bits),
     101        41446 :     htonl ((uint32_t) bsp->cipher)
     102              :   };
     103              :   struct GNUNET_HashContext *hc;
     104              : 
     105        41446 :   hc = GNUNET_CRYPTO_hash_context_start ();
     106        41446 :   GNUNET_CRYPTO_hash_context_read (hc,
     107              :                                    opt,
     108              :                                    sizeof (opt));
     109        41446 :   switch (bsp->cipher)
     110              :   {
     111        21046 :   case GNUNET_CRYPTO_BSA_RSA:
     112              :     {
     113              :       void *buf;
     114              :       size_t blen;
     115              : 
     116        21046 :       blen = GNUNET_CRYPTO_rsa_public_key_encode (
     117        21046 :         bsp->details.rsa_public_key,
     118              :         &buf);
     119        21046 :       GNUNET_CRYPTO_hash_context_read (hc,
     120              :                                        buf,
     121              :                                        blen);
     122        21046 :       GNUNET_free (buf);
     123              :     }
     124        21046 :     break;
     125        20400 :   case GNUNET_CRYPTO_BSA_CS:
     126        20400 :     GNUNET_CRYPTO_hash_context_read (hc,
     127        20400 :                                      &bsp->details.cs_public_key,
     128              :                                      sizeof(bsp->details.cs_public_key));
     129        20400 :     break;
     130            0 :   default:
     131            0 :     GNUNET_assert (0);
     132              :   }
     133        41446 :   GNUNET_CRYPTO_hash_context_finish (hc,
     134              :                                      &denom_hash->hash);
     135        41446 : }
     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         1442 : 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_AgeCommitmentHashP *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         1442 :   TALER_coin_pub_hash (coin_pub,
     163              :                        ach,
     164              :                        c_hash);
     165              :   blinded_planchet->blinded_message
     166         2884 :     = GNUNET_CRYPTO_message_blind_to_sign (dk->bsign_pub_key,
     167              :                                            coin_bks,
     168              :                                            nonce,
     169              :                                            c_hash,
     170              :                                            sizeof (*c_hash),
     171         1442 :                                            alg_values->blinding_inputs);
     172         1442 :   if (NULL == blinded_planchet->blinded_message)
     173            0 :     return GNUNET_SYSERR;
     174         1442 :   return GNUNET_OK;
     175              : }
     176              : 
     177              : 
     178              : enum GNUNET_GenericReturnValue
     179          507 : 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         1014 :   return GNUNET_CRYPTO_blind_sig_verify (denom_pub->bsign_pub_key,
     184          507 :                                          denom_sig->unblinded_sig,
     185              :                                          c_hash,
     186              :                                          sizeof (*c_hash));
     187              : }
     188              : 
     189              : 
     190              : void
     191        54332 : TALER_denom_pub_free (struct TALER_DenominationPublicKey *denom_pub)
     192              : {
     193        54332 :   if (NULL != denom_pub->bsign_pub_key)
     194              :   {
     195        54332 :     GNUNET_CRYPTO_blind_sign_pub_decref (denom_pub->bsign_pub_key);
     196        54332 :     denom_pub->bsign_pub_key = NULL;
     197              :   }
     198        54332 : }
     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          612 : TALER_denom_sig_free (struct TALER_DenominationSignature *denom_sig)
     214              : {
     215          612 :   if (NULL != denom_sig->unblinded_sig)
     216              :   {
     217          603 :     GNUNET_CRYPTO_unblinded_sig_decref (denom_sig->unblinded_sig);
     218          603 :     denom_sig->unblinded_sig = NULL;
     219              :   }
     220          612 : }
     221              : 
     222              : 
     223              : void
     224         2848 : TALER_blinded_denom_sig_free (
     225              :   struct TALER_BlindedDenominationSignature *denom_sig)
     226              : {
     227         2848 :   if (NULL != denom_sig->blinded_sig)
     228              :   {
     229         2518 :     GNUNET_CRYPTO_blinded_sig_decref (denom_sig->blinded_sig);
     230         2518 :     denom_sig->blinded_sig = NULL;
     231              :   }
     232         2848 : }
     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        14449 : TALER_denom_pub_copy (struct TALER_DenominationPublicKey *denom_dst,
     270              :                       const struct TALER_DenominationPublicKey *denom_src)
     271              : {
     272        14449 :   denom_dst->age_mask = denom_src->age_mask;
     273              :   denom_dst->bsign_pub_key
     274        14449 :     = GNUNET_CRYPTO_bsign_pub_incref (denom_src->bsign_pub_key);
     275        14449 : }
     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      2810745 : TALER_denom_pub_cmp (const struct TALER_DenominationPublicKey *denom1,
     299              :                      const struct TALER_DenominationPublicKey *denom2)
     300              : {
     301      2810745 :   if (denom1->bsign_pub_key->cipher !=
     302      2810745 :       denom2->bsign_pub_key->cipher)
     303            0 :     return (denom1->bsign_pub_key->cipher >
     304            0 :             denom2->bsign_pub_key->cipher) ? 1 : -1;
     305      2810745 :   if (denom1->age_mask.bits != denom2->age_mask.bits)
     306      1408785 :     return (denom1->age_mask.bits > denom2->age_mask.bits) ? 1 : -1;
     307      1401960 :   return GNUNET_CRYPTO_bsign_pub_cmp (denom1->bsign_pub_key,
     308      1401960 :                                       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         2063 : TALER_blinded_planchet_cmp (
     323              :   const struct TALER_BlindedPlanchet *bp1,
     324              :   const struct TALER_BlindedPlanchet *bp2)
     325              : {
     326         4126 :   return GNUNET_CRYPTO_blinded_message_cmp (bp1->blinded_message,
     327         2063 :                                             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         1671 : TALER_blinded_planchet_hash_ (const struct TALER_BlindedPlanchet *bp,
     343              :                               struct GNUNET_HashContext *hash_context)
     344              : {
     345         1671 :   const struct GNUNET_CRYPTO_BlindedMessage *bm = bp->blinded_message;
     346         1671 :   uint32_t cipher = htonl (bm->cipher);
     347              : 
     348         1671 :   GNUNET_CRYPTO_hash_context_read (hash_context,
     349              :                                    &cipher,
     350              :                                    sizeof (cipher));
     351         1671 :   switch (bm->cipher)
     352              :   {
     353            0 :   case GNUNET_CRYPTO_BSA_INVALID:
     354            0 :     GNUNET_break (0);
     355         1671 :     return;
     356          847 :   case GNUNET_CRYPTO_BSA_RSA:
     357          847 :     GNUNET_CRYPTO_hash_context_read (
     358              :       hash_context,
     359          847 :       bm->details.rsa_blinded_message.blinded_msg,
     360          847 :       bm->details.rsa_blinded_message.blinded_msg_size);
     361          847 :     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         1162 : 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         1162 :   const struct GNUNET_CRYPTO_BlindingInputValues *bi =
     380              :     alg_values->blinding_inputs;
     381              : 
     382         1162 :   switch (bi->cipher)
     383              :   {
     384            0 :   case GNUNET_CRYPTO_BSA_INVALID:
     385            0 :     GNUNET_break (0);
     386            0 :     return;
     387          598 :   case GNUNET_CRYPTO_BSA_RSA:
     388          598 :     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          598 :     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         1138 : 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         1138 :   const struct GNUNET_CRYPTO_BlindingInputValues *bi
     423              :     = alg_values->blinding_inputs;
     424              : 
     425         1138 :   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          574 :   case GNUNET_CRYPTO_BSA_RSA:
     434          574 :     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          574 :     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         1899 : TALER_blinded_planchet_free (struct TALER_BlindedPlanchet *blinded_planchet)
     464              : {
     465         1899 :   if (NULL != blinded_planchet->blinded_message)
     466              :   {
     467         1899 :     GNUNET_CRYPTO_blinded_message_decref (blinded_planchet->blinded_message);
     468         1899 :     blinded_planchet->blinded_message = NULL;
     469              :   }
     470         1899 : }
     471              : 
     472              : 
     473              : /* end of denom.c */
        

Generated by: LCOV version 2.0-1