donau

Donation authority for GNU Taler (experimental)
Log | Files | Refs | Submodules | README | LICENSE

donau_crypto.c (9023B)


      1 /*
      2   This file is part of TALER
      3   Copyright (C) 2024 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 util/donau_crypto.c
     18  * @brief Cryptographic utility functions
     19  * @author Lukas Matyja
     20  */
     21 #include "donau_config.h"
     22 #include <taler/taler_util.h>
     23 #include "donau_util.h"
     24 #include <gcrypt.h>
     25 
     26 GNUNET_NETWORK_STRUCT_BEGIN
     27 /**
     28  * Structure we hash to compute the group key for
     29  * a donation unit group.
     30  */
     31 struct DonationUnitGroupP
     32 {
     33   /**
     34    * Value of coins in this donation unit group.
     35    */
     36   struct TALER_AmountNBO value;
     37 
     38   /**
     39    * Cipher used for the donation unit, in NBO.
     40    */
     41   uint32_t cipher GNUNET_PACKED;
     42 };
     43 GNUNET_NETWORK_STRUCT_END
     44 
     45 
     46 void
     47 DONAU_donation_unit_group_get_key (
     48   const struct DONAU_DonationUnitGroup *dg,
     49   struct GNUNET_HashCode *key)
     50 {
     51   struct DonationUnitGroupP dgp = {
     52     .cipher = htonl (dg->cipher)
     53   };
     54 
     55   TALER_amount_hton (&dgp.value,
     56                      &dg->value);
     57   GNUNET_CRYPTO_hash (&dgp,
     58                       sizeof (dgp),
     59                       key);
     60 }
     61 
     62 
     63 int
     64 DONAU_donation_unit_pub_cmp (
     65   const struct DONAU_DonationUnitPublicKey *donation_unit1,
     66   const struct DONAU_DonationUnitPublicKey *donation_unit2)
     67 {
     68   if (donation_unit1->bsign_pub_key->cipher !=
     69       donation_unit2->bsign_pub_key->cipher)
     70     return (donation_unit1->bsign_pub_key->cipher >
     71             donation_unit2->bsign_pub_key->cipher) ? 1 : -1;
     72   return GNUNET_CRYPTO_bsign_pub_cmp (donation_unit1->bsign_pub_key,
     73                                       donation_unit2->bsign_pub_key);
     74 }
     75 
     76 
     77 void
     78 DONAU_donation_unit_pub_deep_copy (
     79   struct DONAU_DonationUnitPublicKey *donation_unit_dst,
     80   const struct DONAU_DonationUnitPublicKey *donation_unit_src)
     81 {
     82   donation_unit_dst->bsign_pub_key
     83     = GNUNET_CRYPTO_bsign_pub_incref (donation_unit_src->bsign_pub_key);
     84 }
     85 
     86 
     87 void
     88 DONAU_donation_unit_pub_free (
     89   struct DONAU_DonationUnitPublicKey *donation_unit_pub)
     90 {
     91   if (NULL != donation_unit_pub->bsign_pub_key)
     92   {
     93     GNUNET_CRYPTO_blind_sign_pub_decref (donation_unit_pub->bsign_pub_key);
     94     donation_unit_pub->bsign_pub_key = NULL;
     95   }
     96 }
     97 
     98 
     99 void
    100 DONAU_blinded_donation_unit_sig_free (
    101   struct DONAU_BlindedDonationUnitSignature *du_sig)
    102 {
    103   if (NULL != du_sig->blinded_sig)
    104   {
    105     GNUNET_CRYPTO_blinded_sig_decref (du_sig->blinded_sig);
    106     du_sig->blinded_sig = NULL;
    107   }
    108 }
    109 
    110 
    111 void
    112 DONAU_donation_unit_pub_hash (
    113   const struct DONAU_DonationUnitPublicKey *donation_unit_pub,
    114   struct DONAU_DonationUnitHashP *donation_unit_hash
    115   )
    116 {
    117   struct GNUNET_CRYPTO_BlindSignPublicKey *bsp
    118     = donation_unit_pub->bsign_pub_key;
    119 
    120   switch (bsp->cipher)
    121   {
    122   case GNUNET_CRYPTO_BSA_RSA:
    123     /* Important: this MUST match the way the RSA-secmod does the
    124        hashing of the public keys (see donau-httpd_keys.c) */
    125     GNUNET_CRYPTO_rsa_public_key_hash (bsp->details.rsa_public_key,
    126                                        &donation_unit_hash->hash);
    127     break;
    128   case GNUNET_CRYPTO_BSA_CS:
    129     /* Important: this MUST match the way the CS-secmod does the
    130        hashing of the public keys (see donau-httpd_keys.c) */
    131     GNUNET_CRYPTO_hash (&bsp->details.cs_public_key,
    132                         sizeof(bsp->details.cs_public_key),
    133                         &donation_unit_hash->hash);
    134     break;
    135   default:
    136     GNUNET_assert (0);
    137   }
    138 }
    139 
    140 
    141 void
    142 DONAU_unique_donor_id_hash (
    143   const struct DONAU_HashDonorTaxId *h_donor_tax_id,
    144   const struct DONAU_UniqueDonorIdentifierNonce *nonce,
    145   struct DONAU_UniqueDonorIdentifierHashP *h_udi)
    146 {
    147   struct GNUNET_HashContext *hash_context;
    148 
    149   hash_context = GNUNET_CRYPTO_hash_context_start ();
    150   GNUNET_CRYPTO_hash_context_read (
    151     hash_context,
    152     h_donor_tax_id,
    153     sizeof(struct DONAU_HashDonorTaxId));
    154   GNUNET_CRYPTO_hash_context_read (
    155     hash_context,
    156     nonce,
    157     sizeof(struct DONAU_UniqueDonorIdentifierNonce));
    158   GNUNET_CRYPTO_hash_context_finish (
    159     hash_context,
    160     &h_udi->hash);
    161 }
    162 
    163 
    164 enum GNUNET_GenericReturnValue
    165 DONAU_donation_receipt_verify (
    166   const struct DONAU_DonationUnitPublicKey *donation_unit_pub,
    167   const struct DONAU_UniqueDonorIdentifierHashP *h_udi,
    168   const struct DONAU_DonationUnitSignature *donation_unit_sig)
    169 {
    170   return GNUNET_CRYPTO_blind_sig_verify (donation_unit_pub->bsign_pub_key,
    171                                          donation_unit_sig->unblinded_sig,
    172                                          h_udi,
    173                                          sizeof (*h_udi));
    174 }
    175 
    176 
    177 enum GNUNET_GenericReturnValue
    178 DONAU_donation_unit_blind (
    179   const struct DONAU_DonationUnitPublicKey *du_pub,
    180   const union GNUNET_CRYPTO_BlindingSecretP *budi_secret,
    181   const union GNUNET_CRYPTO_BlindSessionNonce *cs_nonce,
    182   const struct DONAU_UniqueDonorIdentifierNonce *udi_nonce,// message
    183   const struct DONAU_HashDonorTaxId *h_tax_id, // message
    184   const struct DONAU_BatchIssueValues *alg_values,
    185   struct DONAU_UniqueDonorIdentifierHashP *udi_hash,
    186   struct DONAU_BlindedUniqueDonorIdentifier *budi)
    187 {
    188   DONAU_unique_donor_id_hash (
    189     h_tax_id,
    190     udi_nonce,
    191     udi_hash);
    192 
    193   budi->blinded_message
    194     = GNUNET_CRYPTO_message_blind_to_sign (du_pub->bsign_pub_key,
    195                                            budi_secret,
    196                                            cs_nonce,
    197                                            udi_hash,
    198                                            sizeof (*udi_hash),
    199                                            alg_values->blinding_inputs);
    200   if (NULL == budi->blinded_message)
    201     return GNUNET_SYSERR;
    202   return GNUNET_OK;
    203 }
    204 
    205 
    206 enum GNUNET_GenericReturnValue
    207 DONAU_donation_unit_sig_unblind (
    208   struct DONAU_DonationUnitSignature *du_sig,
    209   const struct DONAU_BlindedDonationUnitSignature *blind_du_sig,
    210   const union GNUNET_CRYPTO_BlindingSecretP *budi_secret,
    211   const struct DONAU_UniqueDonorIdentifierHashP *udi_hash,
    212   const struct DONAU_BatchIssueValues *alg_values,
    213   const struct DONAU_DonationUnitPublicKey *du_pub)
    214 {
    215   du_sig->unblinded_sig
    216     = GNUNET_CRYPTO_blind_sig_unblind (blind_du_sig->blinded_sig,
    217                                        budi_secret,
    218                                        udi_hash,
    219                                        sizeof (*udi_hash),
    220                                        alg_values->blinding_inputs,
    221                                        du_pub->bsign_pub_key);
    222   if (NULL == du_sig->unblinded_sig)
    223   {
    224     GNUNET_break_op (0);
    225     return GNUNET_SYSERR;
    226   }
    227   return GNUNET_OK;
    228 }
    229 
    230 
    231 void
    232 DONAU_budi_secret_create (
    233   const struct DONAU_BudiMasterSecretP *ps,
    234   const struct DONAU_BatchIssueValues *alg_values,
    235   union GNUNET_CRYPTO_BlindingSecretP *bks)
    236 {
    237   const struct GNUNET_CRYPTO_BlindingInputValues *bi =
    238     alg_values->blinding_inputs;
    239 
    240   switch (bi->cipher)
    241   {
    242   case GNUNET_CRYPTO_BSA_INVALID:
    243     GNUNET_break (0);
    244     return;
    245   case GNUNET_CRYPTO_BSA_RSA:
    246     GNUNET_assert (GNUNET_YES ==
    247                    GNUNET_CRYPTO_kdf (&bks->rsa_bks,
    248                                       sizeof (bks->rsa_bks),
    249                                       "bks",
    250                                       strlen ("bks"),
    251                                       ps,
    252                                       sizeof(*ps),
    253                                       NULL,
    254                                       0));
    255     return;
    256   case GNUNET_CRYPTO_BSA_CS:
    257     GNUNET_assert (GNUNET_YES ==
    258                    GNUNET_CRYPTO_kdf (&bks->nonce,
    259                                       sizeof (bks->nonce),
    260                                       "bseed",
    261                                       strlen ("bseed"),
    262                                       ps,
    263                                       sizeof(*ps),
    264                                       &bi->details.cs_values,
    265                                       sizeof(bi->details.cs_values),
    266                                       NULL,
    267                                       0));
    268     return;
    269   }
    270   GNUNET_assert (0);
    271 }
    272 
    273 
    274 const struct DONAU_BatchIssueValues *
    275 DONAU_donation_unit_ewv_rsa_singleton ()
    276 {
    277   static struct GNUNET_CRYPTO_BlindingInputValues bi = {
    278     .cipher = GNUNET_CRYPTO_BSA_RSA
    279   };
    280   static struct DONAU_BatchIssueValues alg_values = {
    281     .blinding_inputs = &bi
    282   };
    283   return &alg_values;
    284 }
    285 
    286 
    287 void
    288 DONAU_donation_unit_ewv_copy (struct DONAU_BatchIssueValues *bi_dst,
    289                               const struct DONAU_BatchIssueValues *bi_src)
    290 {
    291   if (bi_src == DONAU_donation_unit_ewv_rsa_singleton ())
    292   {
    293     *bi_dst = *bi_src;
    294     return;
    295   }
    296   bi_dst->blinding_inputs
    297     = GNUNET_CRYPTO_blinding_input_values_incref (bi_src->blinding_inputs);
    298 }