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