frosix

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

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