frosix

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

frost_low.h (11411B)


      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 frost_low.h
     18  * @brief Wrapper of all used functions from the crypto library libsodium
     19  * @author Joel Urech
     20 */
     21 #ifndef FROST_LOW_H
     22 #define FROST_LOW_H
     23 
     24 #include <sodium.h>
     25 
     26 #define FROST_SCALAR_BYTES crypto_core_ristretto255_SCALARBYTES
     27 #define FROST_POINT_BYTES crypto_core_ristretto255_BYTES
     28 
     29 /**
     30  * FROST_Point represents a 'Ristretto' point on Curve25519
     31 */
     32 struct FROST_Point
     33 {
     34   /**
     35    * We only have to save the x-coord of our point in ristretto255-encoding
     36   */
     37   unsigned char xcoord[crypto_core_ristretto255_BYTES];
     38 };
     39 
     40 /**
     41  * FROST_Scalar represents a scalar in the range of [0..L[,
     42  * where L is the order of the ristretto255 group
     43 */
     44 struct FROST_Scalar
     45 {
     46   /**
     47    * The scalar bytes
     48   */
     49   unsigned char scalarbytes[crypto_core_ristretto255_SCALARBYTES];
     50 };
     51 
     52 /**
     53  * Representation of a SHA-512 hash
     54 */
     55 struct FROST_HashCode
     56 {
     57   /**
     58    * 64 bytes
     59   */
     60   unsigned char hashbytes[crypto_hash_sha512_BYTES];
     61 };
     62 
     63 /**
     64  * To construct a hash over more than one input, we need a hash state
     65 */
     66 struct FROST_HashState
     67 {
     68   /**
     69    * The internal hash state of libsodium
     70   */
     71   crypto_hash_sha512_state state;
     72 };
     73 
     74 /**
     75  * Representation of a SHA-256 hash
     76 */
     77 struct FROST_ShortHashCode
     78 {
     79   /**
     80    * 32 bytes
     81   */
     82   unsigned char hashbytes[crypto_hash_sha256_BYTES];
     83 };
     84 
     85 /**
     86  * To construct a hash over more than one input, we need a hash state
     87 */
     88 struct FROST_ShortHashState
     89 {
     90   /**
     91    * The internal hash state of libsodium
     92   */
     93   crypto_hash_sha256_state state;
     94 };
     95 
     96 /**
     97  * Salt to use in computationally intense hashing of a password.
     98 */
     99 struct FROST_PowSalt
    100 {
    101   /**
    102    * 16 bytes
    103   */
    104   unsigned char bytes[crypto_pwhash_SALTBYTES];
    105 };
    106 
    107 
    108 /**
    109  * @brief Initializes the underlying libsodium library.
    110  *
    111  * @result Returns 0 on success, -1 on failure and 1 if the library had already been initialized
    112 */
    113 int
    114 FROST_low_init (void);
    115 
    116 // Points
    117 /**
    118  * @brief Multiplies a point with a scalar
    119  *
    120  * @param[out] result The resulting point
    121  * @param[in] pt Input point
    122  * @param[in] scal Input scalar
    123 */
    124 void
    125 FROST_point_mul_scalar (struct FROST_Point *result,
    126                         const struct FROST_Point *pt,
    127                         const struct FROST_Scalar *scal);
    128 
    129 /**
    130  * @brief Adds two points together
    131  *
    132  * @param[out] result The resulting point
    133  * @param[in] p First point
    134  * @param[in] q Second point
    135 */
    136 void
    137 FROST_point_add_point (struct FROST_Point *result,
    138                        const struct FROST_Point *p,
    139                        const struct FROST_Point *q);
    140 
    141 /**
    142  * @brief Substracts point p from point q
    143  *
    144  * @param[out] result The resulting point
    145  * @param[in] p Point which will be subtracted
    146  * @param[in] q Point to subtract of
    147 */
    148 void
    149 FROST_point_sub_point (struct FROST_Point *result,
    150                        const struct FROST_Point *p,
    151                        const struct FROST_Point *q);
    152 
    153 /**
    154  * @brief Provides the identity element
    155  *
    156  * @param[out] result The identity element
    157 */
    158 void
    159 FROST_point_identity (struct FROST_Point *result);
    160 
    161 // Scalars
    162 /**
    163  * @brief Multiplies the basepoint with a scalar
    164  *
    165  * @param[out] result The resulting point
    166  * @param[in] scal Input scalar
    167 */
    168 void
    169 FROST_base_mul_scalar (struct FROST_Point *result,
    170                        const struct FROST_Scalar *scal);
    171 
    172 /**
    173  * @brief Adds two scalars together
    174  *
    175  * @param[out] result The resulting scalar
    176  * @param[in] xscal First scalar
    177  * @param[in] yscal Second scalar
    178 */
    179 void
    180 FROST_scalar_add_scalar (struct FROST_Scalar *result,
    181                          const struct FROST_Scalar *xscal,
    182                          const struct FROST_Scalar *yscal);
    183 
    184 /**
    185  * @brief Multiplies two scalars
    186  *
    187  * @param[out] result The resulting scalar
    188  * @param[in] xscal First scalar
    189  * @param[in] yscal Second scalar
    190 */
    191 void
    192 FROST_scalar_mul_scalar (struct FROST_Scalar *result,
    193                          const struct FROST_Scalar *xscal,
    194                          const struct FROST_Scalar *yscal);
    195 
    196 /**
    197  * @brief Subtracts yscal from xscal
    198  *
    199  * @param[out] result The resulting scalar
    200  * @param[in] xscal Scalar to substract from
    201  * @param[in] yscal Scalar which will be substracted
    202 */
    203 void
    204 FROST_scalar_sub_scalar (struct FROST_Scalar *result,
    205                          const struct FROST_Scalar *xscal,
    206                          const struct FROST_Scalar *yscal);
    207 
    208 /**
    209  * @brief Returns the multiplicative inverse of scal
    210  *
    211  * @param[out] result The resulting scalar
    212  * @param[in] scal Input scalar
    213 */
    214 void
    215 FROST_scalar_invert (struct FROST_Scalar *result,
    216                      const struct FROST_Scalar *scal);
    217 
    218 // Randomnes
    219 /**
    220  * @brief Provides a random point on Curve25519.
    221  *
    222  * @param[out] result The resulting random point
    223 */
    224 void
    225 FROST_point_random (struct FROST_Point *result);
    226 
    227 /**
    228  * @brief Provides a random scalar in the range of [0..L[.
    229  * L is the order of the ristretto255 group
    230  *
    231  * @param[out] result The resulting random scalar
    232 */
    233 void
    234 FROST_scalar_random (struct FROST_Scalar *result);
    235 
    236 // Hash functions
    237 /**
    238  * @brief Initializes a hash state (needed for more than one input)
    239  *
    240  * @param[out] state The state which has to be initialized
    241 */
    242 void
    243 FROST_hash_init (struct FROST_HashState *state);
    244 
    245 /**
    246  * @brief Allows to hash a byte array of arbitrary length
    247  *
    248  * @param[in,out] state An already initialized hash state has to be provided
    249  * @param[in] msg Pointer to the beginning of the byte array to hash (updates the hash state)
    250  * @param len Length of the byte array to hash
    251 */
    252 void
    253 FROST_hash_fixed_update (struct FROST_HashState *state,
    254                          const void *msg,
    255                          size_t len);
    256 
    257 /**
    258  * @brief Allows to hash a ristretto255 point
    259  *
    260  * @param[in,out] state An already initialized hash state has to be provided
    261  * @param[in] pt The point to hash (updates the hash state)
    262 */
    263 void
    264 FROST_hash_point_update (struct FROST_HashState *state,
    265                          const struct FROST_Point *pt);
    266 
    267 /**
    268  * @brief Allows to hash a hash in form of the struct FROST_HashCode
    269  *
    270  * @param[in,out] state An already initialized hash state has to be provided
    271  * @param[in] hash The hash to hash (updates the hash state)
    272 */
    273 void
    274 FROST_hash_hash_update (struct FROST_HashState *state,
    275                         const struct FROST_HashCode *hash);
    276 
    277 /**
    278  * @brief Allows to hash a scalar
    279  *
    280  * @param[in,out] state An already initialized hash state has to be provided
    281  * @param[in] scal The scalar to hash (updates the hash state)
    282 */
    283 void
    284 FROST_hash_scalar_update (struct FROST_HashState *state,
    285                           const struct FROST_Scalar *scal);
    286 
    287 /**
    288  * @brief Allows to hash an uint8 value
    289  *
    290  * @param[in,out] state An already initialized hash state has to be provided
    291  * @param identifier The uint8 value to hash (updates the hash state)
    292 */
    293 void
    294 FROST_hash_uint8_update (struct FROST_HashState *state,
    295                          const uint8_t identifier);
    296 
    297 /**
    298  * @brief Transforms an updated hash state to a final hash value
    299  *
    300  * @param[in] state An already initialized and with at least one value updated hash state has to be provided
    301  * @param[out] result The resulting hash value (SHA512)
    302 */
    303 void
    304 FROST_hash_final (struct FROST_HashState *state,
    305                   struct FROST_HashCode *result);
    306 
    307 /**
    308  * @brief Maps a hash value to a point on the curve
    309  *
    310  * @param[out] result The resulting point
    311  * @param[in] hash Hash input
    312 */
    313 void
    314 FROST_hash_to_curve (struct FROST_Point *result,
    315                      const struct FROST_HashCode *hash);
    316 
    317 /**
    318  * @brief Reduces a hash value to a scalar in the range of the order of the ristretto255 group
    319  *
    320  * @param[out] result The resulting scalar
    321  * @param[in] hash Hash input
    322 */
    323 void
    324 FROST_hash_to_scalar (struct FROST_Scalar *result,
    325                       const struct FROST_HashCode *hash);
    326 
    327 /**
    328  * FIXME
    329 */
    330 enum GNUNET_GenericReturnValue
    331 FROST_hash_cmp (const struct FROST_HashCode *first,
    332                 const struct FROST_HashCode *second);
    333 
    334 /**
    335  * FIXME
    336 */
    337 void
    338 FROST_short_hash_init (struct FROST_ShortHashState *state);
    339 
    340 /**
    341  *
    342 */
    343 void
    344 FROST_short_hash_update_fixed (struct FROST_ShortHashState *state,
    345                                const void *msg,
    346                                size_t len);
    347 
    348 /**
    349  * FIXME
    350 */
    351 void
    352 FROST_short_hash_final (struct FROST_ShortHashState *state,
    353                         struct FROST_ShortHashCode *result);
    354 
    355 
    356 // Helper functions
    357 /**
    358  * @brief Copies the value of a point
    359  *
    360  * @param[out] destination Point to copy to
    361  * @param[in] origin Point to copy from
    362 */
    363 void
    364 FROST_point_copy_to (struct FROST_Point *destination,
    365                      const struct FROST_Point *origin);
    366 
    367 /**
    368  * @brief Copies the value of a scalar
    369  *
    370  * @param[out] destination Scalar to copy to
    371  * @param[in] origin Scalar to copy from
    372 */
    373 void
    374 FROST_scalar_copy_to (struct FROST_Scalar *destination,
    375                       const struct FROST_Scalar *origin);
    376 
    377 /**
    378  * @brief Sets a FROST_Scalar to 0
    379  *
    380  * @param[out] scal The scalar to set to 0
    381 */
    382 void
    383 FROST_scalar_zero (struct FROST_Scalar *scal);
    384 
    385 /**
    386  * @brief Sets a FROST_Scalar to 1
    387  *
    388  * @param[out] scal The scalar to set to 1
    389 */
    390 void
    391 FROST_scalar_one (struct FROST_Scalar *scal);
    392 
    393 /**
    394  * @brief Sets a FROST_Scalar to a value of an uint8
    395  *
    396  * @param[out] result The resulting scalar
    397  * @param number Uint8 value
    398 */
    399 void
    400 FROST_scalar_set_uint8 (struct FROST_Scalar *result,
    401                         uint8_t number);
    402 
    403 /**
    404  * @brief Compares two point on equality
    405  *
    406  * @param[in] p First point to compare
    407  * @param[in] q Second point to compare
    408  * @return GNUNET_OK if both points are equal, GNUNET_NO otherwise
    409 */
    410 enum GNUNET_GenericReturnValue
    411 FROST_point_cmp (const struct FROST_Point *p,
    412                  const struct FROST_Point *q);
    413 
    414 /**
    415  * @brief Provides a check if the given point is a valid ristretto255-encoded element
    416  *
    417  * @param[in] p Point to validate
    418  * @return GNUNET_OK or GNUNET_NO
    419 */
    420 enum GNUNET_GenericReturnValue
    421 FROST_is_valid_point (const struct FROST_Point *p);
    422 
    423 
    424 /**
    425  * Takes a single high entropy key and derives a scalar, mapped to the curve
    426  * from it.
    427  *
    428  *
    429  * @param[out] subkey The resulting derived key, mapped as a scalar to the curve.
    430  * @param[in] subkey_id Submit a different @a subkey_id to derive a different
    431  * subkey.
    432  * @param[in] masterkey Source of entropy to derive the @a subkey from. Make
    433  * sure to provide 32 bytes of high entropy!
    434 */
    435 void
    436 FROST_kdf_scalar_to_curve (struct FROST_Scalar *subkey,
    437                            uint64_t subkey_id,
    438                            const struct FROST_ShortHashCode *masterkey);
    439 
    440 
    441 /**
    442  * FIXME
    443 */
    444 enum GNUNET_GenericReturnValue
    445 FROST_pow_hash (struct FROST_HashCode *hash,
    446                 const char *answer,
    447                 size_t length,
    448                 const struct FROST_PowSalt *salt,
    449                 uint8_t difficulty);
    450 
    451 #endif