BLSPrivateKeyShareSGX.cpp 5.07 KB
Newer Older
1 2 3
/*
  Copyright (C) 2018-2019 SKALE Labs

4
  This file is part of sgxwallet.
5

6
  sgxwallet is free software: you can redistribute it and/or modify
7 8 9 10
  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.

11
  sgxwallet is distributed in the hope that it will be useful,
12 13 14 15 16
  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
17
  along with sgxwallet.  If not, see <https://www.gnu.org/licenses/>.
18 19

  @file BLSPrivateKeyShare.cpp
kladko's avatar
kladko committed
20
  @author Stan Kladko
21 22 23 24 25 26 27 28
  @date 2019
*/

#include "BLSSigShare.h"
#include "BLSSignature.h"
#include "BLSutils.h"

#include "secure_enclave_u.h"
29 30
#include "sgxwallet_common.h"
#include "sgxwallet.h"
31

32
#include "BLSCrypto.h"
kladkogex's avatar
kladkogex committed
33
#include "ServerInit.h"
kladko's avatar
kladko committed
34
#include "common.h"
35

36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90
#include "BLSPrivateKeyShareSGX.h"

std::string *stringFromFq(libff::alt_bn128_Fq*_fq) {
  mpz_t t;
  mpz_init(t);

  _fq->as_bigint().to_mpz(t);

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

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

  return new std::string(tmp);
}

std::string *stringFromG1(libff::alt_bn128_G1 *_g1) {
  auto sX = stringFromFq(&_g1->X);
  auto sY = stringFromFq(&_g1->Y);
  auto sZ = stringFromFq(&_g1->Z);

  auto sG1 = new std::string(*sX + ":" +  *sY + ":" + *sZ);

  delete(sX);
  delete(sY);
  delete(sZ);

  return sG1;
}

BLSPrivateKeyShareSGX::BLSPrivateKeyShareSGX(
    shared_ptr<string> _encryptedKeyHex, size_t _requiredSigners,
    size_t _totalSigners) {
  requiredSigners = _requiredSigners;
  totalSigners = _totalSigners;

  if (requiredSigners > totalSigners) {
    throw std::invalid_argument("requiredSigners > totalSigners");
  }

  if (totalSigners == 0) {
    throw std::invalid_argument("totalSigners == 0");
  }

  if (_encryptedKeyHex == nullptr) {
    throw std::invalid_argument("Null key");
  }

  if (_encryptedKeyHex->size() > 2 * MAX_ENCRYPTED_KEY_LENGTH) {
    throw std::invalid_argument("Encrypted key size too long");
  }

  encryptedKeyHex = _encryptedKeyHex;
}

91
std::string BLSPrivateKeyShareSGX::signWithHelperSGXstr(
92 93 94 95 96
    std::shared_ptr<std::array<uint8_t, 32>> hash_byte_arr,
    size_t _signerIndex) {
  shared_ptr<signatures::Bls> obj;

  if (hash_byte_arr == nullptr) {
97
    std::cerr << "Hash is null" << std::endl;
98 99 100 101 102 103 104 105 106 107 108 109 110 111
    BOOST_THROW_EXCEPTION(runtime_error("Hash is null"));
  }

  obj = make_shared<signatures::Bls>(
      signatures::Bls(requiredSigners, totalSigners));

  std::pair<libff::alt_bn128_G1, std::string> hash_with_hint =
      obj->HashtoG1withHint(hash_byte_arr);

  int errStatus = 0;

  string* xStr = stringFromFq(&(hash_with_hint.first.X));

  if (xStr == nullptr) {
112
    std::cerr << "Null xStr" << std::endl;
113 114 115 116 117
    BOOST_THROW_EXCEPTION(runtime_error("Null xStr"));
  }

  string* yStr = stringFromFq(&(hash_with_hint.first.Y));

118
  if (yStr == nullptr) {
119
    std::cerr << "Null yStr" << std::endl;
120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137
    BOOST_THROW_EXCEPTION(runtime_error("Null yStr"));
  }

  char errMsg[BUF_LEN];
  memset(errMsg, 0, BUF_LEN);

  char xStrArg[BUF_LEN];
  char yStrArg[BUF_LEN];
  char signature [BUF_LEN];

  memset(xStrArg, 0, BUF_LEN);
  memset(yStrArg, 0, BUF_LEN);

  strncpy(xStrArg, xStr->c_str(), BUF_LEN);
  strncpy(yStrArg, yStr->c_str(), BUF_LEN);

  size_t sz = 0;

138 139 140 141 142
  uint8_t encryptedKey[BUF_LEN];

  bool result = hex2carray(encryptedKeyHex->c_str(), &sz, encryptedKey);

  if (!result) {
143
    cerr << "Invalid hex encrypted key" << endl;
144 145 146
    BOOST_THROW_EXCEPTION(std::invalid_argument("Invalid hex encrypted key"));
  }

kladkogex's avatar
kladkogex committed
147 148
  cerr << "Key is " + *encryptedKeyHex << endl;

149
  sgx_status_t status =
150
      trustedBlsSignMessage(eid, &errStatus, errMsg, encryptedKey,
151 152
                       encryptedKeyHex->size() / 2, xStrArg, yStrArg, signature);

153
  printf("sig is: %s\n", signature);
154

155
  if (status != SGX_SUCCESS) {
156
    gmp_printf("SGX enclave call to trustedBlsSignMessage failed: 0x%04x\n", status);
157
    BOOST_THROW_EXCEPTION(runtime_error("SGX enclave call  to trustedBlsSignMessage failed"));
158 159 160
  }

  if (errStatus != 0) {
161
    BOOST_THROW_EXCEPTION(runtime_error("Enclave trustedBlsSignMessage failed:" + to_string(errStatus) + ":" + errMsg ));
162 163 164
    return nullptr;
  }

kladkogex's avatar
kladkogex committed
165 166 167
  int sigLen;

  if ((sigLen = strnlen(signature, 10)) < 10) {
168
     BOOST_THROW_EXCEPTION(runtime_error("Signature is too short:" + to_string(sigLen)));
kladkogex's avatar
kladkogex committed
169 170
  }

171 172 173 174 175 176 177 178
  std::string hint = BLSutils::ConvertToString(hash_with_hint.first.Y) + ":" +
                     hash_with_hint.second;

  std::string sig = signature;

  sig.append(":");
  sig.append(hint);

179 180 181
  delete xStr;
  delete yStr;

182 183 184 185 186 187 188
  return sig;
}

std::shared_ptr<BLSSigShare> BLSPrivateKeyShareSGX::signWithHelperSGX(
    std::shared_ptr<std::array<uint8_t, 32>> hash_byte_arr,
    size_t _signerIndex) {
  std::string signature = signWithHelperSGXstr(hash_byte_arr, _signerIndex);
kladkogex's avatar
kladkogex committed
189

190 191 192 193
  auto sig = make_shared<string>(signature);

  std::shared_ptr<BLSSigShare> s = std::make_shared<BLSSigShare>(sig, _signerIndex, requiredSigners,
  totalSigners);
194

195
  return s;
196
}