frosix

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

frosix_crypto.h (12003B)


      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 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 General Public License for more details.
     12 
     13   You should have received a copy of the GNU General Public License along with
     14   Frosix; see the file COPYING.GPL.  If not, see <http://www.gnu.org/licenses/>
     15 */
     16 /**
     17  * @file include/frosix_crypto.h
     18  * @brief frosix crypto functions
     19  * @author Joel Urech
     20  */
     21 #ifndef FROSIX_CRYPTO_H
     22 #define FROSIX_CRYPTO_H
     23 
     24 #include "frost_low.h"
     25 #include "frost_high.h"
     26 #include <sodium.h>
     27 #include <taler/taler_json_lib.h>
     28 #include <gnunet/gnunet_util_lib.h>
     29 #include <stdbool.h>
     30 
     31 
     32 /*** Frosix Crypto ***/
     33 
     34 /**
     35  * This encryption key is used to encrypt and decrypt the key data stored
     36  * in the provider's database. The encryption key itself is not stored in
     37  * the database and is only saved in the `Frosix Sign Document`.
     38 */
     39 struct FROSIX_EncryptionKey
     40 {
     41   unsigned char bytes[crypto_secretbox_KEYBYTES];
     42 };
     43 
     44 
     45 /**
     46  * Random nonce for the encryption of the key data stored in the provider's
     47  * database. This nonce is also stored in the database.
     48 */
     49 struct FROSIX_EncryptionNonceP
     50 {
     51   unsigned char bytes[crypto_secretbox_NONCEBYTES];
     52 };
     53 
     54 
     55 /**
     56  * Used in Frosix DKG to transmit the secret shares from all providers
     57  * to all providers, without letting the client know what the secret share is.
     58 */
     59 struct FROSIX_EncryptedShareP
     60 {
     61   unsigned char bytes[FROST_SCALAR_BYTES];
     62 };
     63 
     64 
     65 /**
     66  * An ID which is used to identify a challenge.
     67  */
     68 struct FROSIX_ChallengeIdP
     69 {
     70   struct GNUNET_HashCode hash;
     71 };
     72 
     73 
     74 /**
     75  * High entropy context string, used in Frosix DKG as seed
     76  * to derive the commitment.
     77 */
     78 struct FROSIX_DkgContextStringP
     79 {
     80   struct FROST_HashCode hash; // FIXME
     81 };
     82 
     83 
     84 /**
     85  * Hashed authentication data, stored in the provider's database.
     86  * Used to verify the submitted challenge data in order to issue
     87  * a challenge code.
     88 */
     89 struct FROSIX_ChallengeHashP
     90 {
     91   struct GNUNET_HashCode hash;
     92 };
     93 
     94 
     95 /**
     96  * Specifies a salt value provided by an Frosix provider as result
     97  * of an /config request, used for deriving the encryption key,
     98  * the challenge nonce and is part of the Frosix DKG request id.
     99  */
    100 struct FROSIX_ProviderSaltP
    101 {
    102   struct GNUNET_CRYPTO_PowSalt salt;
    103 };
    104 
    105 
    106 /**
    107  * Specifies a nonce, used for salting the hash of the authentication data.
    108  */
    109 struct FROSIX_ChallengeNonce
    110 {
    111   struct GNUNET_HashCode hash;
    112 };
    113 
    114 
    115 /**
    116  * Secret long term source of high entropy of every provider, which is included
    117  * before deriving the commitment in Frosix DKG.
    118 */
    119 struct FROSIX_SecretProviderSaltP
    120 {
    121   struct GNUNET_CRYPTO_PowSalt salt;
    122 };
    123 
    124 
    125 /**
    126  * Provides a struct to sign the result of a Frosix DKG with the providers
    127  * secret signing key.
    128 */
    129 struct FROSIX_DkgKeySignaturePS
    130 {
    131   /**
    132    * Should contain a GNUNET_SIGNATURE_PURPOSE_XXX,
    133    * has `htonl (104)` at the moment.
    134   */
    135   struct GNUNET_CRYPTO_EccSignaturePurpose purpose;
    136 
    137   /**
    138    * The signature is over the resulting public key and...
    139   */
    140   struct FROST_PublicKey public_key;
    141 
    142   /**
    143    * ... the submitted salted authentication hash.
    144   */
    145   struct FROSIX_ChallengeHashP auth_hash;
    146 };
    147 
    148 /**
    149  * Provides a struct to sign the message with from the security question
    150  * derived secret signing key.
    151 */
    152 struct FROSIX_AuthSignaturePS
    153 {
    154   /**
    155    * Should contain a GNUNET_SIGNATURE_PURPOSE_XXX,
    156    * has `htonl (104)` at the moment.
    157   */
    158   struct GNUNET_CRYPTO_EccSignaturePurpose purpose;
    159 
    160   /**
    161    * The signature is over the hash of the message
    162   */
    163   struct FROST_MessageHash mh;
    164 };
    165 
    166 
    167 /*** Frosix DKG ***/
    168 
    169 /**
    170  * Deterministically derived identifier of a HTTP POST request in Frosix DKG,
    171  * transmitted in the URL. The provider has to prove this id against the
    172  * submitted data in the POST request body.
    173 */
    174 struct FROSIX_DkgRequestIdP
    175 {
    176   struct FROST_HashCode id; // FIXME
    177 };
    178 
    179 
    180 /*** Frosix Sign ***/
    181 
    182 /**
    183  * Deterministically derived identifier of a HTTP POST request in FROSIX Sign,
    184  * transmitted in the URL. The provider has to prove this id against the
    185  * submitted data in the POST request body.
    186 */
    187 struct FROSIX_SigRequestIdP
    188 {
    189   struct FROST_HashCode id; // FIXME
    190 };
    191 
    192 
    193 /*** Frosix Challenge ***/
    194 
    195 /**
    196  * Deterministically derived identifier of a HTTP POST request in
    197  * FROSIX Challenge, transmitted in the URL. The provider has to prove this id
    198  * against the submitted data in the POST request body.
    199 */
    200 struct FROSIX_ChallengeRequestIdP
    201 {
    202   struct FROST_HashCode id; // FIXME
    203 };
    204 
    205 
    206 /*** Frosix Database ***/
    207 
    208 /**
    209  * Just a pointer and the number of bytes at the pointers target.
    210  * Is used in Frosix DKG, while storing all other provider's commitment,
    211  * to copy all commitments at one place in memory.
    212  * This struct is also used to load the commitments from the database and copy
    213  * each commitment back in a useful struct.
    214 */
    215 struct FROSIX_DkgCommitmentsRaw
    216 {
    217   void *ptr_commits;
    218   size_t length;
    219 };
    220 
    221 
    222 /**
    223  * Byte array including the secret and the public key, before an encryption
    224  * or right after a decryption.
    225 */
    226 struct FROSIX_KeyDataRaw
    227 {
    228   unsigned char bytes[FROST_POINT_BYTES + FROST_SCALAR_BYTES];
    229 };
    230 
    231 
    232 /**
    233  * Byte array for the encrypted key data before storing in the database
    234  * or to load from the database.
    235 */
    236 struct FROSIX_KeyDataEncrypted
    237 {
    238   unsigned char bytes[crypto_secretbox_MACBYTES
    239                       + sizeof (struct FROSIX_KeyDataRaw)];
    240 };
    241 
    242 
    243 /*** Frosix Payment - not implemented yet ***/
    244 
    245 /**
    246  * Random identifier used to later charge a payment.
    247  */
    248 struct FROSIX_PaymentSecretP
    249 {
    250   uint32_t id[8];
    251 };
    252 
    253 
    254 /**
    255  * Encrypts the key data in a FROSIX DKG to store them
    256  * in the providers database.
    257  *
    258  * @param[out] ciphertext The encrypted data
    259  * @param[in] plaintext Plaintext data to encrypt
    260  * @param[in] nonce Nonce value to use in the symmetric encryption
    261  * @param[in] key The encryption key
    262  * @return #GNUNET_OK if the encryption was successful
    263  *         #GNUNET_NO if there was a problem while encrypting
    264 */
    265 enum GNUNET_GenericReturnValue
    266 FROSIX_secretbox_keydata (struct FROSIX_KeyDataEncrypted *ciphertext,
    267                           const struct FROSIX_KeyDataRaw *plaintext,
    268                           const struct FROSIX_EncryptionNonceP *nonce,
    269                           const struct FROSIX_EncryptionKey *key);
    270 
    271 
    272 /**
    273  * Decrypts encrypted key data from the providers database in Frosix Sign.
    274  *
    275  * @param[out] plaintext The resulting plaintext
    276  * @param[in] ciphertext Encrypted data to decrypt
    277  * @param[in] nonce Nonce value used in the symmetric encryption
    278  * @param[in] key Key which was used to encrypt the data in @e ciphertext
    279  * @return #GNUNET_OK if the decryption was successful
    280  *         #GNUNET_NO otherwise
    281 */
    282 enum GNUNET_GenericReturnValue
    283 FROSIX_secretbox_keydata_open (
    284   struct FROSIX_KeyDataRaw *plaintext,
    285   const struct FROSIX_KeyDataEncrypted *ciphertext,
    286   const struct FROSIX_EncryptionNonceP *nonce,
    287   const struct FROSIX_EncryptionKey *key);
    288 
    289 
    290 /**
    291  * Returns a high entropy nonce to be used in FROSIX_secretbox_keydata.
    292  *
    293  * @param[out] nonce The resulting nonce value
    294 */
    295 void
    296 FROSIX_secretbox_nonce_randombytes (struct FROSIX_EncryptionNonceP *nonce);
    297 
    298 
    299 /**
    300  * Returns the hash of an encryption key. This hash is used as identifier
    301  * in the providers databases.
    302  *
    303  * @param[out] enc_key_hash Hash of the encryption key
    304  * @param[in] enc_key Encryption key to hash
    305 */
    306 void
    307 FROSIX_hash_encryption_key (struct FROST_HashCode *enc_key_hash, // FIXME
    308                             const struct FROSIX_EncryptionKey *enc_key);
    309 
    310 
    311 /**
    312  * Returns the authentication hash, derived from the submitted
    313  * authentication data and the authentication nonce.
    314  *
    315  * @param[out] auth_hash Resulting authentication hash
    316  * @param[in] auth_data Null-terminated string, containing
    317  * the authentication data
    318  * @param[in] auth_nonce Nonce value which should be used to salt
    319  * the resulting hash
    320 */
    321 void
    322 FROSIX_compute_auth_hash (struct FROSIX_ChallengeHashP *auth_hash,
    323                           const char *auth_data,
    324                           const struct GNUNET_HashCode *auth_nonce);
    325 
    326 
    327 /**
    328  * Computes the id of a POST request to /auth-challenge.
    329  *
    330  * @param[out] request_id The resulting request id
    331  * @param[in] enc_key Encryption key -> FIXME Should be hash of enc key
    332  * @param[in] message_hash Hash of message or plaintext message -> FIXME
    333 */
    334 void
    335 FROSIX_compute_challenge_request_id (
    336   struct FROSIX_ChallengeRequestIdP *request_id,
    337   const struct FROSIX_EncryptionKey *enc_key,
    338   const struct FROST_MessageHash *message_hash);
    339 
    340 
    341 /**
    342  * Computes the id of a POST request to /sig-commitment and /sig-share.
    343  *
    344  * @param[out] request_id The resulting request id
    345  * @param[in] enc_key_hash Hash of the encryption key, which was used to$
    346  * encrypt the data stored at the provider
    347  * @param[in] message_hash Hash of message or plaintext message -> FIXME
    348 */
    349 void
    350 FROSIX_compute_signature_request_id (
    351   struct FROSIX_SigRequestIdP *request_id,
    352   const struct FROST_HashCode *enc_key_hash,
    353   const struct FROST_MessageHash *message_hash);
    354 
    355 
    356 /**
    357  * Computes the id of a POST request to /dkg-commitment, /dkg-share
    358  * and /dkg-key.
    359  *
    360  * @param[out] request_id The resulting request id
    361  * @param[in] context_string Main source of entropy for the provider
    362  * @param[in] challenge_hash Salted hash of the authentication data
    363  * @param[in] provider_salt Salt value which we received from a /config request
    364  * @param[in] provider_index Index of the provider in this Frosix DKG
    365  * @param[in] num_of_participants Number of participating providers
    366  * @param[in] threshold Chosen threshold value for this Frosix DKG
    367 */
    368 void
    369 FROSIX_compute_dkg_request_id (
    370   struct FROSIX_DkgRequestIdP *request_id,
    371   const struct FROSIX_DkgContextStringP *context_string,
    372   const struct FROSIX_ChallengeHashP *challenge_hash,
    373   const struct FROSIX_ProviderSaltP *provider_salt,
    374   uint8_t provider_index,
    375   uint8_t num_of_participants,
    376   uint8_t threshold);
    377 
    378 
    379 /**
    380  * Computes an id which is used as identifier to store the challenge
    381  * in the database. -> FIXME should not be in frosix.h
    382  *
    383  * @param[out] challenge_id The resulting request id
    384  * @param[in] enc_key_hash Identifier of the corresponding auth data
    385  * @param[in] mh Hash of the message, to bind a request to a specific message
    386 */
    387 void
    388 FROSIX_compute_challenge_id (struct FROSIX_ChallengeIdP *challenge_id,
    389                              const struct FROST_HashCode *enc_key_hash, // FIXME
    390                              const struct FROST_MessageHash *mh);
    391 
    392 
    393 /**
    394  * Compares two given `struct GNUNET_HashCode`s.
    395  *
    396  * @param[in] hc1 First hash to compare
    397  * @param[in] hc2 Second hash to compare
    398  * @return #GNUNET_OK if the hashes matches
    399  *         #GNUNET_NO otherwise
    400 */
    401 enum GNUNET_GenericReturnValue
    402 FROSIX_gnunet_hash_cmp (const struct GNUNET_HashCode *hc1,
    403                         const struct GNUNET_HashCode *hc2);
    404 
    405 
    406 /**
    407  * Hash a numerical answer to compute the hash value to be submitted
    408  * to the server for verification. Useful for PINs and SMS-TANs and
    409  * other numbers submitted for challenges.
    410  *
    411  * @param code the numeric value to hash
    412  * @param[out] hashed_code the resulting hash value to submit to the Frosix server
    413  */
    414 void
    415 FROSIX_hash_answer (uint64_t code,
    416                     struct GNUNET_HashCode *hashed_code);
    417 
    418 
    419 /**
    420  * FIXME
    421  */
    422 void
    423 FROSIX_nonce_to_pow_salt (struct FROST_PowSalt *salt,
    424                           const struct GNUNET_HashCode *nonce);
    425 
    426 
    427 /**
    428  * FIXME
    429 */
    430 void
    431 FROSIX_hash_pow (struct GNUNET_HashCode *hash,
    432                  struct GNUNET_CRYPTO_Edx25519PrivateKey *priv,
    433                  struct GNUNET_CRYPTO_Edx25519PublicKey *pub,
    434                  const struct GNUNET_HashCode *nonce,
    435                  const char *auth_answer,
    436                  unsigned int amplifier);
    437 
    438 #endif