keygen.h (9542B)
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 include/keygen.h 18 * @brief frosix api to create a key pair in a distributed key generation 19 * process. 20 * @author Joel Urech 21 */ 22 #ifndef FROST_KEYGEN_H 23 #define FROST_KEYGEN_H 24 25 #include "frost_high.h" 26 27 /** 28 * A commitment for a single share in a dkg. 29 */ 30 struct FROST_DkgShareCommitment 31 { 32 /** 33 * Our commitment is g^'share' 34 */ 35 struct FROST_Point sc; 36 }; 37 38 /** 39 * A zero knowledge proof of the secret at x-coord 0 in our polynomial. 40 * In principle it is a Schnorr signature. 41 */ 42 struct FROST_DkgZkp 43 { 44 /** 45 * The nonce of our zkp. 46 */ 47 struct FROST_Point r; 48 /** 49 * Proof of knowing the secret value. 50 */ 51 struct FROST_Scalar z; 52 }; 53 54 /** 55 * In the first round of the distributed key generation process, 56 * every participant has to send a special commitment to all other. 57 * This structs contains all needed data for this commitment. 58 */ 59 struct FROST_DkgCommitment 60 { 61 /** 62 * Unique identifier of the participant, must be greater than 0 and less than 255. 63 */ 64 uint8_t identifier; 65 /** 66 * A pointer to an array of commitments. 67 * The number of commitments depends on the choosen threshold value, 68 * which can vary between 2 and 253. To initialize this struct, 69 * call FROST_initialize_dkg_commitment(). 70 */ 71 struct FROST_DkgShareCommitment *share_comm; 72 /** 73 * The length of the commitment array 74 */ 75 uint8_t shares_commitments_length; 76 /** 77 * A zero knowledge proof of the underlying secret value. 78 */ 79 struct FROST_DkgZkp zkp; 80 }; 81 82 /** 83 * 84 */ 85 86 /** 87 * Representation of a distributed key generation secret share (not the final key share!). 88 * This struct will be used in the second and third round of the distributed key generation 89 * process. 90 */ 91 struct FROST_DkgShare 92 { 93 /** 94 * Unique identifier of the participant, must be greater than 0 and less than 255 95 */ 96 uint8_t identifier; 97 /** 98 * A secret value, which is intended only for a particular participant. 99 * It has to match one of the commitments from round 1! 100 */ 101 struct FROST_Scalar share; 102 }; 103 104 /** 105 * FIXME 106 */ 107 struct FROST_DkgContextString 108 { 109 /** 110 * FIXME 111 */ 112 struct FROST_ShortHashCode con_str; 113 }; 114 115 /** 116 * Trusted dealer should only be used for testing purposes. 117 * It creates key material using only local entropy. 118 * 119 * @param[out] key_pairs An array with the resulting key material and this 120 * array contains a key pair for every participant. 121 * @param[in] num_of_participants In how many parts should the secret key get 122 * divided? This is also the length of the `key_pairs` array. 123 * @param[in] threshold How many participants have to participate in the 124 * signing process? The threshold value also determines one of the big security 125 * parameters of our system. Do not choose it too low! 126 */ 127 void 128 FROST_trusted_dealer_keygen (struct FROST_KeyPair key_pairs[], 129 uint8_t num_of_participants, 130 uint8_t threshold); 131 132 133 /** 134 * Checks if the provided params are valid. 135 * 136 * @param[in] identifier unique identifier of the participant in the group 137 * @param[in] threshold threshold value to create a valid signature 138 * @param[in] num_of_participant total number of participant 139 * @return GNUNET_OK or GNUNET_NO 140 */ 141 enum GNUNET_GenericReturnValue 142 FROST_validate_dkg_params (uint8_t identifier, 143 uint8_t threshold, 144 uint8_t num_of_participants); 145 146 /** 147 * Call this function always before starting a dkg. 148 * It will initialize the struct `FROST_DkgCommitment`, which contains an array 149 * of length `threshold`. 150 * 151 * @param[out] dkg_commitment The commitment which should be initialized. 152 * @param[in] my_index Unique identifier of the participant, must be greater 153 * than 0 and less than 255. 154 * @param[in] threshold How many participants have to participate in the 155 * signing process? The threshold value also fixes the length of the inner 156 * array. 157 * @return GNUNET_OK or GNUNET_NO 158 */ 159 enum GNUNET_GenericReturnValue 160 FROST_initialize_dkg_commitment (struct FROST_DkgCommitment *dkg_commitment, 161 uint8_t my_index, 162 uint8_t threshold); 163 164 /** 165 * Every participant first do a trusted dealer on his own and commits to each 166 * of the t-1 generated values. 167 * Additionally, every participant has to compute a zero knowledge proof of 168 * the underlying secret (y-value of x=0). As a result, this function returns 169 * a commitment, which should then be send to all other participants. 170 * Do not send the dkg shares now! 171 * 172 * @a context_string should be the hash of the received context_string, 173 * concatenated with the secret provider salt and other values like the salted 174 * hash of the authentication method and the salted hash of the authentication 175 * data. 176 * 177 * @param[in,out] dkg_commitment This struct must first be initialized with 178 * FROST_initialize_dkg_commitment. After calling FROST_keygen_begin, the inner 179 * array will be filled with a commitment to each of the t-1 share values. 180 * @param[out] dkg_shares This are the precomputed shares, one share for each 181 * participant. The length of this array MUST be 'num_of_participants - 1'. 182 * @param[in] context_string Source of entropy to derive all 'rnd' values. 183 * @param[in] addtional_data There is the possibility to include additional 184 * data in form of a hash in the zero knowledge proof. NULL possible. 185 * @param[in] my_index Unique identifier of the participant, must be greater 186 * than 0 and less than 255. 187 * @param[in] num_of_participants How many participants are participating in 188 * the distributed key generation process? 189 * @param[in] threshold How many participants have to participate in the 190 * signing process? 191 * @return GNUNET_OK or GNUNET_NO 192 */ 193 enum GNUNET_GenericReturnValue 194 FROST_keygen_begin (struct FROST_DkgCommitment *dkg_commitment, 195 struct FROST_DkgShare dkg_shares[], 196 const struct FROST_DkgContextString *context_string, 197 const struct FROST_HashCode *additional_data, 198 uint8_t my_index, 199 uint8_t num_of_participants, 200 uint8_t threshold); 201 202 /** 203 * After receiving all commitments from all other participants, they have to be 204 * validated. This means, that every value will be checked if it is a correctly 205 * encoded ristretto255 element. Additionally the included zero knowledge proof 206 * has to be validated too. 207 * 208 * @param[in] dkg_commitment A sorted list of all commitments. 209 * @param[in] num_of_participants How many participants are participating in 210 * the distributed key generation process? 211 * @return GNUNET_OK or GNUNET_NO 212 */ 213 enum GNUNET_GenericReturnValue 214 FROST_keygen_validate_commitment ( 215 const struct FROST_DkgCommitment *dkg_commitment, 216 const struct FROST_HashCode *additional_data, 217 uint8_t num_of_participants); 218 219 /** 220 * Finally send to each participant his share and receive from each participant 221 * a share. 222 * This shares has to be verified against the previously received commitments. 223 * 224 * @param[in] commitment The dkg commitment, including all share commitments 225 * @param[in] share The share we validate with the dkg commitment 226 * @param[in] my_index What is my identifier number? 227 * @return GNUNET_OK or GNUNET_NO 228 */ 229 enum GNUNET_GenericReturnValue 230 FROST_keygen_validate_share ( 231 const struct FROST_DkgCommitment *commitment, 232 const struct FROST_DkgShare *share, 233 uint8_t my_index); 234 235 /** 236 * With all these shares, this function computes the individual key pair and 237 * derives the group public key from the commitments. 238 * 239 * @param[out] key_pair The resulting key material, keep it safe and secure! 240 * @param[in] my_index Unique identifier of the participant, must be greater 241 * than 0 and less than 255. 242 * @param[in] shares The precomputed shares, received one share from each 243 * participant. 244 * @param[in] commitments The previously received and already validated 245 * commitments. There has to be a corresponding value to each of the received 246 * shares. 247 * @param[in] num_of_participants How many participants are participating in 248 * the distributed key generation process? 249 */ 250 void 251 FROST_keygen_finalize (struct FROST_KeyPair *key_pair, 252 uint8_t my_index, 253 const struct FROST_DkgShare shares[], 254 const struct FROST_DkgCommitment commitments[], 255 uint8_t num_of_participants); 256 257 /** 258 * Counterpart to the initializing function of the struct dkg commitment. 259 * This function frees allocated space. 260 * 261 * @param[in,out] dkg_commitment The struct which was initialized with 262 * `FROST_initialize_dkg_commitment` at the beginning of the dkg process. 263 * @param[in] length Number of commitments elements. 264 */ 265 void 266 FROST_free_dkg_commitment (struct FROST_DkgCommitment dkg_commitments[], 267 size_t length); 268 269 #endif