exchange

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

denom.c (13557B)


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