exchange

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

denom.c (14196B)


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