frosix

Multiparty signature service (experimental)
Log | Files | Refs | README | LICENSE

frosix_crypto.c (9789B)


      1 /*
      2   This file is part of Frosix
      3   Copyright (C) 2022, 2023 Joel Urech
      4 
      5   Frosix is free software; you can redistribute it and/or modify it under the
      6   terms of the GNU Affero General Public License as published by the Free Software
      7   Foundation; either version 3, or (at your option) any later version.
      8 
      9   Frosix 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 Affero General Public License for more details.
     12 
     13   You should have received a copy of the GNU Affero General Public License along with
     14   Frosix; see the file COPYING.  If not, see <http://www.gnu.org/licenses/>
     15 */
     16 /**
     17  * @file util/frosix_crypto.c
     18  * @brief helper functions for various tasks
     19  * @author Joel Urech
     20  */
     21 
     22 #include "frosix_crypto.h"
     23 #include "frost_low.h"
     24 #include "frost_high.h"
     25 
     26 enum GNUNET_GenericReturnValue
     27 FROSIX_secretbox_keydata (struct FROSIX_KeyDataEncrypted *ciphertext,
     28                           const struct FROSIX_KeyDataRaw *plaintext,
     29                           const struct FROSIX_EncryptionNonceP *nonce,
     30                           const struct FROSIX_EncryptionKey *key)
     31 {
     32   if (0 == crypto_secretbox_easy (ciphertext->bytes,
     33                                   plaintext->bytes,
     34                                   sizeof (plaintext->bytes),
     35                                   nonce->bytes,
     36                                   key->bytes))
     37     return GNUNET_OK;
     38   return GNUNET_NO;
     39 }
     40 
     41 
     42 enum GNUNET_GenericReturnValue
     43 FROSIX_secretbox_keydata_open (struct FROSIX_KeyDataRaw *plaintext,
     44                                const struct FROSIX_KeyDataEncrypted *ciphertext,
     45                                const struct FROSIX_EncryptionNonceP *nonce,
     46                                const struct FROSIX_EncryptionKey *key)
     47 {
     48   if (0 == crypto_secretbox_open_easy (plaintext->bytes,
     49                                        ciphertext->bytes,
     50                                        sizeof (ciphertext->bytes),
     51                                        nonce->bytes,
     52                                        key->bytes))
     53     return GNUNET_OK;
     54   return GNUNET_NO;
     55 }
     56 
     57 
     58 void
     59 FROSIX_secretbox_nonce_randombytes (struct FROSIX_EncryptionNonceP *nonce)
     60 {
     61   randombytes_buf (nonce,
     62                    sizeof (nonce->bytes));
     63 }
     64 
     65 
     66 void
     67 FROSIX_hash_encryption_key (struct FROST_HashCode *enc_key_hash,
     68                             const struct FROSIX_EncryptionKey *enc_key)
     69 {
     70   struct FROST_HashState enc_key_state;
     71   FROST_hash_init (&enc_key_state);
     72   FROST_hash_fixed_update (&enc_key_state,
     73                            enc_key,
     74                            sizeof (*enc_key));
     75   FROST_hash_final (&enc_key_state,
     76                     enc_key_hash);
     77 }
     78 
     79 void
     80 FROSIX_compute_auth_hash (struct FROSIX_ChallengeHashP *auth_hash,
     81                           const char *auth_data,
     82                           const struct GNUNET_HashCode *auth_nonce)
     83 {
     84   struct GNUNET_HashContext *h_ctx = GNUNET_CRYPTO_hash_context_start ();
     85   GNUNET_CRYPTO_hash_context_read (h_ctx,
     86                                    auth_data,
     87                                    strlen (auth_data));
     88   GNUNET_CRYPTO_hash_context_read (h_ctx,
     89                                    auth_nonce,
     90                                    sizeof (*auth_nonce));
     91   GNUNET_CRYPTO_hash_context_read (h_ctx,
     92                                    "FROSIX",
     93                                    strlen ("FROSIX"));
     94   GNUNET_CRYPTO_hash_context_finish (h_ctx,
     95                                      &auth_hash->hash);
     96 }
     97 
     98 
     99 void
    100 FROSIX_compute_challenge_request_id (
    101   struct FROSIX_ChallengeRequestIdP *request_id,
    102   const struct FROSIX_EncryptionKey *enc_key,
    103   const struct FROST_MessageHash *message_hash)
    104 {
    105   /* id = H (encryption_key ||
    106            message_hash ||
    107            "FROSIX-SIG") */
    108   struct FROST_HashState hs;
    109 
    110   FROST_hash_init (&hs);
    111   FROST_hash_fixed_update (&hs,
    112                            enc_key,
    113                            sizeof (*enc_key));
    114   FROST_hash_fixed_update (&hs,
    115                            message_hash,
    116                            sizeof (*message_hash));
    117   FROST_hash_fixed_update (&hs,
    118                            "FROSIX-AUTH",
    119                            strlen ("FROSIX-AUTH"));
    120   FROST_hash_final (&hs,
    121                     &request_id->id);
    122 }
    123 
    124 
    125 void
    126 FROSIX_compute_signature_request_id (
    127   struct FROSIX_SigRequestIdP *request_id,
    128   const struct FROST_HashCode *enc_key_hash,
    129   const struct FROST_MessageHash *message_hash)
    130 {
    131   /* id = H (H(encryption_key) ||
    132            message_hash ||
    133            "FROSIX-SIG") */
    134   struct FROST_HashState hs;
    135 
    136   FROST_hash_init (&hs);
    137   FROST_hash_fixed_update (&hs,
    138                            enc_key_hash,
    139                            sizeof (*enc_key_hash));
    140   FROST_hash_fixed_update (&hs,
    141                            message_hash,
    142                            sizeof (*message_hash));
    143   FROST_hash_fixed_update (&hs,
    144                            "FROSIX-SIG",
    145                            strlen ("FROSIX-SIG"));
    146   FROST_hash_final (&hs,
    147                     &request_id->id);
    148 }
    149 
    150 void
    151 FROSIX_compute_dkg_request_id (
    152   struct FROSIX_DkgRequestIdP *request_id,
    153   const struct FROSIX_DkgContextStringP *context_string,
    154   const struct FROSIX_ChallengeHashP *challenge_hash,
    155   const struct FROSIX_ProviderSaltP *provider_salt,
    156   uint8_t provider_index,
    157   uint8_t num_of_participants,
    158   uint8_t threshold)
    159 {
    160   struct FROST_HashState check_id_state;
    161 
    162   FROST_hash_init (&check_id_state);
    163   FROST_hash_hash_update (&check_id_state,
    164                           &context_string->hash);
    165   FROST_hash_fixed_update (&check_id_state,
    166                            &challenge_hash->hash,
    167                            sizeof (*challenge_hash));
    168   FROST_hash_uint8_update (&check_id_state,
    169                            provider_index);
    170   FROST_hash_uint8_update (&check_id_state,
    171                            num_of_participants);
    172   FROST_hash_uint8_update (&check_id_state,
    173                            threshold);
    174   FROST_hash_fixed_update (&check_id_state,
    175                            provider_salt,
    176                            sizeof (*provider_salt));
    177   FROST_hash_fixed_update (&check_id_state,
    178                            "FROSIX-DKG-ID",
    179                            strlen ("FROSIX-DKG-ID"));
    180   FROST_hash_final (&check_id_state,
    181                     &request_id->id);
    182 }
    183 
    184 
    185 enum GNUNET_GenericReturnValue
    186 FROSIX_gnunet_hash_cmp (const struct GNUNET_HashCode *hc1,
    187                         const struct GNUNET_HashCode *hc2)
    188 {
    189   if (0 == GNUNET_CRYPTO_hash_cmp (hc1,
    190                                    hc2))
    191     return GNUNET_OK;
    192   return GNUNET_NO;
    193 }
    194 
    195 void
    196 FROSIX_compute_challenge_id (struct FROSIX_ChallengeIdP *challenge_id,
    197                              const struct FROST_HashCode *enc_key_hash,
    198                              const struct FROST_MessageHash *mh)
    199 {
    200   struct GNUNET_HashContext *hc = GNUNET_CRYPTO_hash_context_start ();
    201   GNUNET_CRYPTO_hash_context_read (hc,
    202                                    enc_key_hash,
    203                                    sizeof (*enc_key_hash));
    204   GNUNET_CRYPTO_hash_context_read (hc,
    205                                    mh,
    206                                    sizeof (*mh));
    207   GNUNET_CRYPTO_hash_context_read (hc,
    208                                    "FROSIX",
    209                                    strlen ("FROSIX"));
    210   GNUNET_CRYPTO_hash_context_finish (hc,
    211                                      &challenge_id->hash);
    212 }
    213 
    214 void
    215 FROSIX_hash_answer (uint64_t code,
    216                     struct GNUNET_HashCode *hashed_code)
    217 {
    218   char cbuf[40];
    219 
    220   GNUNET_snprintf (cbuf,
    221                    sizeof (cbuf),
    222                    "%llu",
    223                    (unsigned long long) code);
    224   GNUNET_CRYPTO_hash (cbuf,
    225                       strlen (cbuf),
    226                       hashed_code);
    227   GNUNET_log (GNUNET_ERROR_TYPE_INFO,
    228               "Hashed answer %llu to %s\n",
    229               (unsigned long long) code,
    230               GNUNET_h2s (hashed_code));
    231 }
    232 
    233 
    234 void
    235 FROSIX_nonce_to_pow_salt (struct FROST_PowSalt *salt,
    236                           const struct GNUNET_HashCode *nonce)
    237 {
    238   GNUNET_CRYPTO_kdf (salt,
    239                      sizeof (*salt),
    240                      "FROSIX",
    241                      strlen ("FROSIX"),
    242                      nonce,
    243                      sizeof (*nonce),
    244                      NULL,
    245                      0);
    246 }
    247 
    248 void
    249 FROSIX_hash_pow (struct GNUNET_HashCode *hash,
    250                  struct GNUNET_CRYPTO_Edx25519PrivateKey *priv,
    251                  struct GNUNET_CRYPTO_Edx25519PublicKey *pub,
    252                  const struct GNUNET_HashCode *nonce,
    253                  const char *auth_answer,
    254                  unsigned int amplifier)
    255 {
    256   /* get salt */
    257   struct FROST_PowSalt salt;
    258   FROSIX_nonce_to_pow_salt (&salt,
    259                             nonce);
    260 
    261   /* make big calculation*/
    262   struct FROST_HashCode hashed_answer;
    263   FROST_pow_hash (&hashed_answer,
    264                   auth_answer,
    265                   strlen (auth_answer),
    266                   &salt,
    267                   amplifier);
    268 
    269   /* with the seed, get the private key */
    270   GNUNET_CRYPTO_edx25519_key_create_from_seed (&hashed_answer,
    271                                                sizeof (hashed_answer),
    272                                                priv);
    273 
    274   /* and the public key */
    275   GNUNET_CRYPTO_edx25519_key_get_public (priv,
    276                                          pub);
    277 
    278   /* hash public key */
    279   struct GNUNET_HashContext *hc = GNUNET_CRYPTO_hash_context_start ();
    280   GNUNET_CRYPTO_hash_context_read (hc,
    281                                    pub,
    282                                    sizeof (*pub));
    283   GNUNET_CRYPTO_hash_context_read (hc,
    284                                    "FROSIX",
    285                                    strlen ("FROSIX"));
    286   GNUNET_CRYPTO_hash_context_finish (hc,
    287                                      hash);
    288 }