exchange

Base system with REST service to issue digital coins, run by the payment service provider
Log | Files | Refs | Submodules | README | LICENSE

denom.c (13494B)


      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 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   memset (denom_pub,
     34           0,
     35           sizeof (*denom_pub));
     36   memset (denom_priv,
     37           0,
     38           sizeof (*denom_priv));
     39   va_start (ap,
     40             cipher);
     41   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   va_end (ap);
     47   return ret;
     48 }
     49 
     50 
     51 enum GNUNET_GenericReturnValue
     52 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     = GNUNET_CRYPTO_blind_sign (denom_priv->bsign_priv_key,
     59                                 for_melt ? "rm" : "rw",
     60                                 blinded_planchet->blinded_message);
     61   if (NULL == denom_sig->blinded_sig)
     62     return GNUNET_SYSERR;
     63   return GNUNET_OK;
     64 }
     65 
     66 
     67 enum GNUNET_GenericReturnValue
     68 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     = GNUNET_CRYPTO_blind_sig_unblind (bdenom_sig->blinded_sig,
     78                                        bks,
     79                                        c_hash,
     80                                        sizeof (*c_hash),
     81                                        alg_values->blinding_inputs,
     82                                        denom_pub->bsign_pub_key);
     83   if (NULL == denom_sig->unblinded_sig)
     84   {
     85     GNUNET_break_op (0);
     86     return GNUNET_SYSERR;
     87   }
     88   return GNUNET_OK;
     89 }
     90 
     91 
     92 void
     93 TALER_denom_pub_hash (const struct TALER_DenominationPublicKey *denom_pub,
     94                       struct TALER_DenominationHashP *denom_hash)
     95 {
     96   struct GNUNET_CRYPTO_BlindSignPublicKey *bsp
     97     = denom_pub->bsign_pub_key;
     98   uint32_t opt[2] = {
     99     htonl (denom_pub->age_mask.bits),
    100     htonl ((uint32_t) bsp->cipher)
    101   };
    102   struct GNUNET_HashContext *hc;
    103 
    104   hc = GNUNET_CRYPTO_hash_context_start ();
    105   GNUNET_CRYPTO_hash_context_read (hc,
    106                                    opt,
    107                                    sizeof (opt));
    108   switch (bsp->cipher)
    109   {
    110   case GNUNET_CRYPTO_BSA_RSA:
    111     {
    112       void *buf;
    113       size_t blen;
    114 
    115       blen = GNUNET_CRYPTO_rsa_public_key_encode (
    116         bsp->details.rsa_public_key,
    117         &buf);
    118       GNUNET_CRYPTO_hash_context_read (hc,
    119                                        buf,
    120                                        blen);
    121       GNUNET_free (buf);
    122     }
    123     break;
    124   case GNUNET_CRYPTO_BSA_CS:
    125     GNUNET_CRYPTO_hash_context_read (hc,
    126                                      &bsp->details.cs_public_key,
    127                                      sizeof(bsp->details.cs_public_key));
    128     break;
    129   default:
    130     GNUNET_assert (0);
    131   }
    132   GNUNET_CRYPTO_hash_context_finish (hc,
    133                                      &denom_hash->hash);
    134 }
    135 
    136 
    137 const struct TALER_ExchangeBlindingValues *
    138 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   return &alg_values;
    147 }
    148 
    149 
    150 enum GNUNET_GenericReturnValue
    151 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   TALER_coin_pub_hash (coin_pub,
    162                        ach,
    163                        c_hash);
    164   blinded_planchet->blinded_message
    165     = GNUNET_CRYPTO_message_blind_to_sign (dk->bsign_pub_key,
    166                                            coin_bks,
    167                                            nonce,
    168                                            c_hash,
    169                                            sizeof (*c_hash),
    170                                            alg_values->blinding_inputs);
    171   if (NULL == blinded_planchet->blinded_message)
    172     return GNUNET_SYSERR;
    173   return GNUNET_OK;
    174 }
    175 
    176 
    177 enum GNUNET_GenericReturnValue
    178 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   return GNUNET_CRYPTO_blind_sig_verify (denom_pub->bsign_pub_key,
    183                                          denom_sig->unblinded_sig,
    184                                          c_hash,
    185                                          sizeof (*c_hash));
    186 }
    187 
    188 
    189 void
    190 TALER_denom_pub_free (struct TALER_DenominationPublicKey *denom_pub)
    191 {
    192   if (NULL != denom_pub->bsign_pub_key)
    193   {
    194     GNUNET_CRYPTO_blind_sign_pub_decref (denom_pub->bsign_pub_key);
    195     denom_pub->bsign_pub_key = NULL;
    196   }
    197 }
    198 
    199 
    200 void
    201 TALER_denom_priv_free (struct TALER_DenominationPrivateKey *denom_priv)
    202 {
    203   if (NULL != denom_priv->bsign_priv_key)
    204   {
    205     GNUNET_CRYPTO_blind_sign_priv_decref (denom_priv->bsign_priv_key);
    206     denom_priv->bsign_priv_key = NULL;
    207   }
    208 }
    209 
    210 
    211 void
    212 TALER_denom_sig_free (struct TALER_DenominationSignature *denom_sig)
    213 {
    214   if (NULL != denom_sig->unblinded_sig)
    215   {
    216     GNUNET_CRYPTO_unblinded_sig_decref (denom_sig->unblinded_sig);
    217     denom_sig->unblinded_sig = NULL;
    218   }
    219 }
    220 
    221 
    222 void
    223 TALER_blinded_denom_sig_free (
    224   struct TALER_BlindedDenominationSignature *denom_sig)
    225 {
    226   if (NULL != denom_sig->blinded_sig)
    227   {
    228     GNUNET_CRYPTO_blinded_sig_decref (denom_sig->blinded_sig);
    229     denom_sig->blinded_sig = NULL;
    230   }
    231 }
    232 
    233 
    234 void
    235 TALER_denom_ewv_free (struct TALER_ExchangeBlindingValues *ewv)
    236 {
    237   if (ewv == TALER_denom_ewv_rsa_singleton ())
    238     return;
    239   if (ewv->blinding_inputs ==
    240       TALER_denom_ewv_rsa_singleton ()->blinding_inputs)
    241   {
    242     ewv->blinding_inputs = NULL;
    243     return;
    244   }
    245   if (NULL != ewv->blinding_inputs)
    246   {
    247     GNUNET_CRYPTO_blinding_input_values_decref (ewv->blinding_inputs);
    248     ewv->blinding_inputs = NULL;
    249   }
    250 }
    251 
    252 
    253 void
    254 TALER_denom_ewv_copy (struct TALER_ExchangeBlindingValues *bi_dst,
    255                       const struct TALER_ExchangeBlindingValues *bi_src)
    256 {
    257   if (bi_src == TALER_denom_ewv_rsa_singleton ())
    258   {
    259     *bi_dst = *bi_src;
    260     return;
    261   }
    262   bi_dst->blinding_inputs
    263     = GNUNET_CRYPTO_blinding_input_values_incref (bi_src->blinding_inputs);
    264 }
    265 
    266 
    267 void
    268 TALER_denom_pub_copy (struct TALER_DenominationPublicKey *denom_dst,
    269                       const struct TALER_DenominationPublicKey *denom_src)
    270 {
    271   denom_dst->age_mask = denom_src->age_mask;
    272   denom_dst->bsign_pub_key
    273     = GNUNET_CRYPTO_bsign_pub_incref (denom_src->bsign_pub_key);
    274 }
    275 
    276 
    277 void
    278 TALER_denom_sig_copy (struct TALER_DenominationSignature *denom_dst,
    279                       const struct TALER_DenominationSignature *denom_src)
    280 {
    281   denom_dst->unblinded_sig
    282     = GNUNET_CRYPTO_ub_sig_incref (denom_src->unblinded_sig);
    283 }
    284 
    285 
    286 void
    287 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     = GNUNET_CRYPTO_blind_sig_incref (denom_src->blinded_sig);
    293 }
    294 
    295 
    296 int
    297 TALER_denom_pub_cmp (const struct TALER_DenominationPublicKey *denom1,
    298                      const struct TALER_DenominationPublicKey *denom2)
    299 {
    300   if (denom1->bsign_pub_key->cipher !=
    301       denom2->bsign_pub_key->cipher)
    302     return (denom1->bsign_pub_key->cipher >
    303             denom2->bsign_pub_key->cipher) ? 1 : -1;
    304   if (denom1->age_mask.bits != denom2->age_mask.bits)
    305     return (denom1->age_mask.bits > denom2->age_mask.bits) ? 1 : -1;
    306   return GNUNET_CRYPTO_bsign_pub_cmp (denom1->bsign_pub_key,
    307                                       denom2->bsign_pub_key);
    308 }
    309 
    310 
    311 int
    312 TALER_denom_sig_cmp (const struct TALER_DenominationSignature *sig1,
    313                      const struct TALER_DenominationSignature *sig2)
    314 {
    315   return GNUNET_CRYPTO_ub_sig_cmp (sig1->unblinded_sig,
    316                                    sig1->unblinded_sig);
    317 }
    318 
    319 
    320 int
    321 TALER_blinded_planchet_cmp (
    322   const struct TALER_BlindedPlanchet *bp1,
    323   const struct TALER_BlindedPlanchet *bp2)
    324 {
    325   return GNUNET_CRYPTO_blinded_message_cmp (bp1->blinded_message,
    326                                             bp2->blinded_message);
    327 }
    328 
    329 
    330 int
    331 TALER_blinded_denom_sig_cmp (
    332   const struct TALER_BlindedDenominationSignature *sig1,
    333   const struct TALER_BlindedDenominationSignature *sig2)
    334 {
    335   return GNUNET_CRYPTO_blind_sig_cmp (sig1->blinded_sig,
    336                                       sig1->blinded_sig);
    337 }
    338 
    339 
    340 void
    341 TALER_blinded_planchet_hash_ (const struct TALER_BlindedPlanchet *bp,
    342                               struct GNUNET_HashContext *hash_context)
    343 {
    344   const struct GNUNET_CRYPTO_BlindedMessage *bm = bp->blinded_message;
    345   uint32_t cipher = htonl (bm->cipher);
    346 
    347   GNUNET_CRYPTO_hash_context_read (hash_context,
    348                                    &cipher,
    349                                    sizeof (cipher));
    350   switch (bm->cipher)
    351   {
    352   case GNUNET_CRYPTO_BSA_INVALID:
    353     GNUNET_break (0);
    354     return;
    355   case GNUNET_CRYPTO_BSA_RSA:
    356     GNUNET_CRYPTO_hash_context_read (
    357       hash_context,
    358       bm->details.rsa_blinded_message.blinded_msg,
    359       bm->details.rsa_blinded_message.blinded_msg_size);
    360     return;
    361   case GNUNET_CRYPTO_BSA_CS:
    362     GNUNET_CRYPTO_hash_context_read (
    363       hash_context,
    364       &bm->details.cs_blinded_message,
    365       sizeof (bm->details.cs_blinded_message));
    366     return;
    367   }
    368   GNUNET_assert (0);
    369 }
    370 
    371 
    372 void
    373 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   const struct GNUNET_CRYPTO_BlindingInputValues *bi =
    379     alg_values->blinding_inputs;
    380 
    381   switch (bi->cipher)
    382   {
    383   case GNUNET_CRYPTO_BSA_INVALID:
    384     GNUNET_break (0);
    385     return;
    386   case GNUNET_CRYPTO_BSA_RSA:
    387     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     return;
    396   case GNUNET_CRYPTO_BSA_CS:
    397     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     return;
    407   }
    408   GNUNET_assert (0);
    409 }
    410 
    411 
    412 void
    413 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   const struct GNUNET_CRYPTO_BlindingInputValues *bi
    419     = alg_values->blinding_inputs;
    420 
    421   switch (bi->cipher)
    422   {
    423   case GNUNET_CRYPTO_BSA_INVALID:
    424     GNUNET_break (0);
    425     memset (coin_priv,
    426             0,
    427             sizeof (*coin_priv));
    428     return;
    429   case GNUNET_CRYPTO_BSA_RSA:
    430     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     return;
    439   case GNUNET_CRYPTO_BSA_CS:
    440     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     return;
    450   }
    451   GNUNET_assert (0);
    452 }
    453 
    454 
    455 void
    456 TALER_blinded_planchet_free (struct TALER_BlindedPlanchet *blinded_planchet)
    457 {
    458   if (NULL != blinded_planchet->blinded_message)
    459   {
    460     GNUNET_CRYPTO_blinded_message_decref (blinded_planchet->blinded_message);
    461     blinded_planchet->blinded_message = NULL;
    462   }
    463 }
    464 
    465 
    466 /* end of denom.c */