DKGUtils.cpp 11.2 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
/*
    Copyright (C) 2019-Present SKALE Labs

    This file is part of sgxwallet.

    sgxwallet is free software: you can redistribute it and/or modify
    it under the terms of the GNU Affero General Public License as published
    by the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    sgxwallet is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU Affero General Public License for more details.

    You should have received a copy of the GNU Affero General Public License
    along with sgxwallet.  If not, see <https://www.gnu.org/licenses/>.

    @file DKGUtils.cpp
    @author Stan Kladko
    @date 2019
*/

24 25
#include "DKGUtils.h"

26
#include <sgx_tgmp.h>
27
#include <../trusted_libff/libff/algebra/curves/alt_bn128/alt_bn128_pp.hpp>
28 29
#include <../trusted_libff/libff/algebra/fields/fp.hpp>

30 31
#include <../trusted_libff/libff/algebra/curves/alt_bn128/alt_bn128_g2.hpp>

32

33
#include "../sgxwallet_common.h"
34 35 36
#include <cstdio>
#include <stdio.h>

37 38 39 40
#include "DH_dkg.h"



41

42

43 44 45 46 47 48 49 50 51 52 53 54 55 56 57
std::string stringFromFr(libff::alt_bn128_Fr& _el) {

    mpz_t t;
    mpz_init(t);

    _el.as_bigint().to_mpz(t);

    char arr[mpz_sizeinbase(t, 10) + 2];

    char *tmp = mpz_get_str(arr, 10, t);
    mpz_clear(t);

    return std::string(tmp);
}

58
template<class T>
59
std::string ConvertToString(T field_elem, int base = 10) {
60 61 62 63 64
  mpz_t t;
  mpz_init(t);

  field_elem.as_bigint().to_mpz(t);

65
  char arr[mpz_sizeinbase (t, base) + 2];
66

67
  char * tmp = mpz_get_str(arr, base, t);
68 69 70 71 72 73 74
  mpz_clear(t);

  std::string output = tmp;

  return output;
}

75 76 77 78 79 80 81 82 83 84 85 86 87
std::string ConvertG2ToString(const libff::alt_bn128_G2 & elem, int base = 10, std::string delim = ":"){
  std::string result;
  result += ConvertToString(elem.X.c0);
  result += delim;
  result += ConvertToString(elem.X.c1);
  result += delim;
  result += ConvertToString(elem.Y.c0);
  result += delim;
  result += ConvertToString(elem.Y.c1);

  return result;
}

svetaro's avatar
svetaro committed
88
std::vector<libff::alt_bn128_Fr> SplitStringToFr(const char* koefs, const char symbol){
89
    std::string str(koefs);
svetaro's avatar
svetaro committed
90 91
    std::string delim;
    delim.push_back(symbol);
92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109
    std::vector<libff::alt_bn128_Fr> tokens;
    size_t prev = 0, pos = 0;
    do
    {
        pos = str.find(delim, prev);
        if (pos == std::string::npos) pos = str.length();
        std::string token = str.substr(prev, pos-prev);
        if (!token.empty()) {
            libff::alt_bn128_Fr koef(token.c_str());
            tokens.push_back(koef);
        }
        prev = pos + delim.length();
    }
    while (pos < str.length() && prev < str.length());

    return tokens;
}

110 111 112 113 114
int gen_dkg_poly( char* secret, unsigned _t ){
  libff::init_alt_bn128_params();
  std::string result;
  for (size_t i = 0; i < _t; ++i) {
     libff::alt_bn128_Fr cur_coef = libff::alt_bn128_Fr::random_element();
115

116 117 118 119 120 121 122 123 124 125 126 127 128
     while (i == _t - 1 && cur_coef == libff::alt_bn128_Fr::zero()) {
       cur_coef = libff::alt_bn128_Fr::random_element();
     }
     result += stringFromFr(cur_coef);
     result += ":";
  }
  strncpy(secret, result.c_str(), result.length() + 1);

  if (strlen(secret) == 0) {
    return 1;
  }

  return 0;
129 130
}

131 132
libff::alt_bn128_Fr PolynomialValue(const std::vector<libff::alt_bn128_Fr>& pol, libff::alt_bn128_Fr point, unsigned _t) {

133

134 135 136
  libff::alt_bn128_Fr value = libff::alt_bn128_Fr::zero();

  libff::alt_bn128_Fr pow = libff::alt_bn128_Fr::one();
137 138 139 140 141 142
  for (unsigned i = 0; i < pol.size(); ++i) {
//    if (i == _t - 1 && pol[i] == libff::alt_bn128_Fr::zero()) {
//        //snprintf(err_string, BUF_LEN,"sgx_unseal_data failed with status
//    }
     value += pol[i] * pow;
     pow *= point;
143 144 145 146 147
  }

  return value;
}

148 149
void calc_secret_shares(const char* decrypted_koefs, char * secret_shares,      // calculates secret shares in base 10 to a string secret_shares,
    unsigned _t, unsigned _n) {                                                 // separated by ":"
150 151 152
  // calculate for each node a list of secret values that will be used for verification
  std::string result;
  char symbol = ':';
svetaro's avatar
svetaro committed
153
  std::vector<libff::alt_bn128_Fr> poly =  SplitStringToFr(decrypted_koefs, symbol);
154

svetaro's avatar
svetaro committed
155
    for (size_t i = 0; i < _n; ++i) {
156
    libff::alt_bn128_Fr secret_share = PolynomialValue(poly, libff::alt_bn128_Fr(i + 1), _t);
svetaro's avatar
svetaro committed
157
    result += ConvertToString(secret_share);//stringFromFr(secret_share);
158 159
    result += ":";
  }
160
  strncpy(secret_shares, result.c_str(), result.length() + 1);
161
  //strncpy(secret_shares, decrypted_koefs, 3650);
162 163
}

164
int calc_secret_share(const char* decrypted_koefs, char * s_share,
165 166 167 168 169
                        unsigned _t, unsigned _n, unsigned ind) {

  libff::init_alt_bn128_params();
  char symbol = ':';
  std::vector<libff::alt_bn128_Fr> poly =  SplitStringToFr(decrypted_koefs, symbol);
170 171 172
  if ( poly.size() != _t){
    return 1;
  }
173 174 175 176 177 178 179

  libff::alt_bn128_Fr secret_share = PolynomialValue(poly, libff::alt_bn128_Fr(ind), _t);
  std::string cur_share = ConvertToString(secret_share, 16);//stringFromFr(secret_share);
  int n_zeroes = 64 - cur_share.size();
  cur_share.insert(0, n_zeroes, '0');

  strncpy(s_share, cur_share.c_str(), cur_share.length() + 1);
180
  return 0;
181 182 183

}

184
void calc_secret_shareG2_old(const char* decrypted_koefs, char * s_shareG2,
185
                                            unsigned _t, unsigned ind){
186

187 188 189
  libff::init_alt_bn128_params();
  char symbol = ':';
  std::vector<libff::alt_bn128_Fr> poly =  SplitStringToFr(decrypted_koefs, symbol);
190 191 192 193
//  if ( poly.size() != _t){
//    //"t != poly.size()" +
//    //strncpy(s_shareG2, std::to_string(poly.size()).c_str(), 18);
//  }
194 195 196 197 198 199 200

  libff::alt_bn128_Fr secret_share = PolynomialValue(poly, libff::alt_bn128_Fr(ind), _t);

  libff::alt_bn128_G2 secret_shareG2 = secret_share * libff::alt_bn128_G2::one();

  std::string secret_shareG2_str = ConvertG2ToString(secret_shareG2);

201 202 203 204
  strncpy(s_shareG2, secret_shareG2_str.c_str(), secret_shareG2_str.length() + 1);
  //strncpy(s_shareG2, decrypted_koefs, 320);
}

205
int calc_secret_shareG2(const char* s_share, char * s_shareG2){
206 207 208 209
  libff::init_alt_bn128_params();

  mpz_t share;
  mpz_init(share);
210 211 212 213
  if (mpz_set_str(share, s_share, 16) == -1){
    mpz_clear(share);
    return 1;
  }
214 215 216 217 218 219 220 221

  char arr[mpz_sizeinbase (share, 10) + 2];
  char * share_str = mpz_get_str(arr, 10, share);

  libff::alt_bn128_Fr secret_share(share_str);

  libff::alt_bn128_G2 secret_shareG2 = secret_share * libff::alt_bn128_G2::one();

222 223
  secret_shareG2.to_affine_coordinates();

224 225 226
  std::string secret_shareG2_str = ConvertG2ToString(secret_shareG2);

  strncpy(s_shareG2, secret_shareG2_str.c_str(), secret_shareG2_str.length() + 1);
227 228

  return 0;
229 230
}

231
int calc_public_shares(const char* decrypted_koefs, char * public_shares,
232
                        unsigned _t) {
233
  libff::init_alt_bn128_params();
234 235 236
  // calculate for each node a list of public shares
  std::string result;
  char symbol = ':';
svetaro's avatar
svetaro committed
237
  std::vector<libff::alt_bn128_Fr> poly =  SplitStringToFr(decrypted_koefs, symbol);
238 239 240
  if (poly.size() != _t){
    return 1;
  }
241
  for (size_t i = 0; i < _t; ++i) {
svetaro's avatar
svetaro committed
242
    libff::alt_bn128_G2 pub_share = poly.at(i) * libff::alt_bn128_G2::one() ;
243
    pub_share.to_affine_coordinates();
244 245
    std::string pub_share_str = ConvertG2ToString(pub_share);
    result += pub_share_str + ",";
246 247
  }
  strncpy(public_shares, result.c_str(), result.length());
248
  return 0;
249 250
}

251 252 253 254 255
//extern "C" int __gmpz_set_str (mpz_ptr, const char *, int);
std::string ConvertHexToDec(std::string hex_str){
  mpz_t dec;
  mpz_init(dec);

256 257 258 259
  if (mpz_set_str(dec, hex_str.c_str(), 16) == -1){
    mpz_clear(dec);
    return "false";
  }
260 261 262 263 264 265 266 267 268 269

  char arr[mpz_sizeinbase (dec, 10) + 2];
  char * result = mpz_get_str(arr, 10, dec);

  mpz_clear(dec);

  return result;
}

int Verification ( char * public_shares, mpz_t decr_secret_share, int _t, int ind ){
270

271
  std::string pub_shares_str = public_shares;
272
  libff::init_alt_bn128_params();
273

274
  std::vector<libff::alt_bn128_G2> pub_shares;
275 276 277
  uint64_t share_length = 256;
  uint8_t coord_length = 64;

278
  for (size_t i = 0; i < _t; ++i) {
279 280 281
    libff::alt_bn128_G2 pub_share;

    uint64_t pos0 = share_length * i;
282 283 284 285 286 287 288 289 290 291 292
    std::string x_c0_str = ConvertHexToDec(pub_shares_str.substr(pos0, coord_length));
    std::string x_c1_str = ConvertHexToDec(pub_shares_str.substr(pos0 + coord_length, coord_length));
    std::string y_c0_str = ConvertHexToDec(pub_shares_str.substr(pos0 + 2 * coord_length, coord_length));
    std::string y_c1_str = ConvertHexToDec(pub_shares_str.substr(pos0 + 3 * coord_length, coord_length));
    if (x_c0_str == "false" || x_c1_str == "false" || y_c0_str == "false" || y_c1_str == "false"){
      return 2;
    }
    pub_share.X.c0 = libff::alt_bn128_Fq(x_c0_str.c_str());
    pub_share.X.c1 = libff::alt_bn128_Fq(x_c1_str.c_str());
    pub_share.Y.c0 = libff::alt_bn128_Fq(y_c0_str.c_str());
    pub_share.Y.c1 = libff::alt_bn128_Fq(y_c1_str.c_str());
293 294 295 296 297 298 299 300 301 302 303 304 305
    pub_share.Z = libff::alt_bn128_Fq2::one();


    //for ( int j = 0; j < 4; j++) {
      //uint64_t pos0 = share_length * j;
      //std::string coord = ConvertHexToDec(pub_shares_str.substr(pos0 + j * coord_length, coord_length));
//      if ( i == 0) {
//        memset(public_shares, 0, strlen(public_shares));
//    std::string coord = ConvertToString(pub_share.Y.c1);
//    strncpy(public_shares, coord.c_str(), coord.length());
//  }
    //}

306 307 308 309 310 311 312 313 314 315 316 317
    pub_shares.push_back(pub_share);
  }

  libff::alt_bn128_G2 val = libff::alt_bn128_G2::zero();
   for (int i = 0; i < _t; ++i) {
    val = val + power(libff::alt_bn128_Fr(ind + 1), i) * pub_shares[i];
  }

  char arr[mpz_sizeinbase (decr_secret_share, 10) + 2];
  char * tmp = mpz_get_str(arr, 10, decr_secret_share);
  libff::alt_bn128_Fr sshare(tmp);

318 319 320
 // strncpy(public_shares, tmp, strlen(tmp));
//  std::string res = ConvertHexToDec("fe43567238abcdef98760");
//  strncpy(public_shares, res.c_str(), res.length());
321 322

  libff::alt_bn128_G2  val2 = sshare * libff::alt_bn128_G2::one();
323

324
   memset(public_shares, 0, strlen(public_shares));
325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342
   strncpy(public_shares, ConvertToString(val2.X.c0).c_str(), ConvertToString(val2.X.c0).length());
   strncpy(public_shares + ConvertToString(val2.X.c0).length(), ":", 1);
  strncpy(public_shares + ConvertToString(val2.X.c0).length() + 1, ConvertToString(val2.X.c1).c_str(), 77);



  val.to_affine_coordinates();
  val2.to_affine_coordinates();
//  strncpy(public_shares + strlen(tmp), ":", 1);
//  strncpy(public_shares + 77 + 1, ConvertToString(val.X.c0).c_str(), 77);
//  strncpy(public_shares + 77 + 78, ":", 1);
//  strncpy(public_shares + 77 + 79, ConvertToString(val2.X.c0).c_str(), 77);
  /*strncpy(public_shares + 77 + 77 + 79, "\n", 1);
  strncpy(public_shares + 144 + 79, ConvertToString(val2.X.c0).c_str(), 77);
  strncpy(public_shares + 144 + 78, ":", 1);
  strncpy(public_shares + 144 + 77, ConvertToString(val2.X.c1).c_str(), 77);*/


343 344

  return (val == sshare * libff::alt_bn128_G2::one());
345 346 347

}

348
int calc_bls_public_key(char* skey_hex, char* pub_key){
349 350 351 352
  libff::init_alt_bn128_params();

  mpz_t skey;
  mpz_init(skey);
353 354 355
  if (mpz_set_str(skey, skey_hex, 16) == -1){
    return 1;
  }
356 357 358 359 360

  char skey_dec[mpz_sizeinbase (skey, 10) + 2];
  char * skey_str = mpz_get_str(skey_dec, 10, skey);

  libff::alt_bn128_Fr bls_skey(skey_dec);
361 362 363 364 365 366 367

  libff::alt_bn128_G2 public_key = bls_skey * libff::alt_bn128_G2::one();
  public_key.to_affine_coordinates();

  std::string result = ConvertG2ToString(public_key);

  strncpy(pub_key, result.c_str(), result.length());
368 369 370 371

  mpz_clear(skey);

  return 0;
372 373 374
}


375 376