frosix

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

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 }