keygen_common.c (5074B)
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 keygen_common.c 18 * @brief Implementation of some functions which are used several times in different steps 19 * of the distributed key generation process. 20 * @author Joel Urech 21 */ 22 #include "keygen.h" 23 #include "keygen_common.h" 24 #include "frost_low.h" 25 26 27 /** 28 * @brief Generates commitments for each of the provided coefficients 29 * 30 * @param[out] dkg_commitment The resulting commitment to the polynomial 31 * @param[in] secret The secret value of the polynomial at coordiante x=0 32 * @param[in] coefficients All generated coefficients of the polynomial 33 * @param[in] coefficients_len Length of array coefficients 34 */ 35 static void 36 generate_commitments (struct FROST_DkgCommitment *dkg_commitment, 37 const struct FROST_DkgSecretKey *secret, 38 const struct FROST_Coefficient coefficients[], 39 uint8_t coefficients_len) 40 { 41 // Generate commitments 42 FROST_base_mul_scalar (&dkg_commitment->share_comm[0].sc, 43 &secret->sk); 44 45 for (int i = 0; i < coefficients_len; i++) 46 { 47 FROST_base_mul_scalar (&dkg_commitment->share_comm[i + 1].sc, 48 &coefficients[i].coeff); 49 } 50 } 51 52 53 void 54 FROST_generate_dkg_challenge_ (struct FROST_DkgChallenge *challenge, 55 uint8_t generator_index, 56 const struct FROST_DkgShareCommitment *s_pub, 57 const struct FROST_DkgZkp *zkp, 58 const struct FROST_HashCode *additional_data) 59 { 60 struct FROST_HashState state; 61 struct FROST_HashCode hash; 62 FROST_hash_init (&state); 63 FROST_hash_uint8_update (&state, 64 generator_index); 65 FROST_hash_point_update (&state, 66 &s_pub->sc); 67 FROST_hash_point_update (&state, 68 &zkp->r); 69 if (NULL != additional_data) /* additional data is optional */ 70 { 71 FROST_hash_hash_update (&state, 72 additional_data); 73 } 74 FROST_hash_fixed_update (&state, 75 "DKG-Challenge", 76 strlen ("DKG-Challenge")); 77 FROST_hash_final (&state, 78 &hash); 79 FROST_hash_to_scalar (&challenge->c, 80 &hash); 81 } 82 83 84 void 85 FROST_generate_shares_ (struct FROST_DkgShare shares[], 86 struct FROST_DkgCommitment *dkg_commitment, 87 const struct FROST_DkgSecretKey *secret, 88 const struct FROST_ShortHashCode *coeff_masterkey, 89 uint8_t num_of_participants, 90 uint8_t threshold) 91 { 92 uint8_t numcoeffs = threshold - 1; 93 94 // Sample t-1 participants values 95 struct FROST_Coefficient coefficients[numcoeffs]; 96 97 for (uint8_t i = 0; i < numcoeffs; i++) 98 { 99 if (NULL == coeff_masterkey) 100 { 101 FROST_scalar_random (&coefficients[i].coeff); 102 } 103 else { 104 // Derive new subkey 105 FROST_kdf_scalar_to_curve (&coefficients[i].coeff, 106 i + 1, /* id '0' is our secret! */ 107 coeff_masterkey); 108 } 109 } 110 111 // Horner's method to evaluate the polynomial at the point x=share_index 112 // [1 ... n] (i must not be 0) 113 for (uint8_t i = 1; i <= num_of_participants; i++) 114 { 115 struct FROST_Scalar share_index; 116 struct FROST_Scalar value; 117 FROST_scalar_set_uint8 (&share_index, 118 i); 119 FROST_scalar_zero (&value); 120 121 // ]t-1 ... 0] => [t-2 ... 0] 122 for (int j = numcoeffs - 1; j >= 0; j--) 123 { 124 // Add coeff and multiply with share_index 125 FROST_scalar_add_scalar (&value, 126 &value, 127 &coefficients[j].coeff); 128 FROST_scalar_mul_scalar (&value, 129 &value, 130 &share_index); 131 } 132 133 // Add secret as the *constant* yi (*x^0) 134 FROST_scalar_add_scalar (&shares[i - 1].share, 135 &value, 136 &secret->sk); 137 138 // set participant identifier 139 shares[i - 1].identifier = i; 140 } 141 142 // We have no commitments with trusted dealer 143 if (NULL != dkg_commitment) 144 { 145 generate_commitments (dkg_commitment, 146 secret, 147 coefficients, 148 numcoeffs); 149 } 150 }