BLSCrypto.cpp 7.43 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 BLSCrypto.cpp
    @author Stan Kladko
    @date 2019
*/

24
#include <memory>
25 26 27 28

#include "libff/algebra/curves/alt_bn128/alt_bn128_init.hpp"

#include "bls.h"
29
#include <bls/BLSutils.h>
30

31
#include "leveldb/db.h"
32
#include <jsonrpccpp/server/connectors/httpserver.h>
33
#include "BLSPrivateKeyShareSGX.h"
34

35
#include "sgxwallet_common.h"
36
#include "third_party/intel/create_enclave.h"
37
#include "secure_enclave_u.h"
38
#include "third_party/intel/sgx_detect.h"
39 40
#include <gmp.h>
#include <sgx_urts.h>
41

42
#include "sgxwallet.h"
43

44 45
#include "SGXWalletServer.h"

46
#include "BLSCrypto.h"
kladkogex's avatar
kladkogex committed
47
#include "ServerInit.h"
48

49
#include "SGXException.h"
50

Oleh Nikolaiev's avatar
Oleh Nikolaiev committed
51
#include "third_party/spdlog/spdlog.h"
kladko's avatar
kladko committed
52
#include "common.h"
53

54 55 56 57 58 59 60 61 62 63 64 65 66 67
std::string *FqToString(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);
}

68
int char2int(char _input) {
69 70 71 72 73 74 75
    if (_input >= '0' && _input <= '9')
        return _input - '0';
    if (_input >= 'A' && _input <= 'F')
        return _input - 'A' + 10;
    if (_input >= 'a' && _input <= 'f')
        return _input - 'a' + 10;
    return -1;
76 77
}

78 79 80
void carray2Hex(const unsigned char *d, int _len, char *_hexArray) {
    char hexval[16] = {'0', '1', '2', '3', '4', '5', '6', '7',
                       '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'};
81

82 83 84 85
    for (int j = 0; j < _len; j++) {
        _hexArray[j * 2] = hexval[((d[j] >> 4) & 0xF)];
        _hexArray[j * 2 + 1] = hexval[(d[j]) & 0x0F];
    }
86

87
    _hexArray[_len * 2] = 0;
88 89
}

90
bool hex2carray(const char *_hex, uint64_t *_bin_len, uint8_t *_bin) {
91
    int len = strnlen(_hex, 2 * BUF_LEN);
92

93 94
    if (len == 0 && len % 2 == 1)
        return false;
95

96
    *_bin_len = len / 2;
97

98 99 100
    for (int i = 0; i < len / 2; i++) {
        int high = char2int((char) _hex[i * 2]);
        int low = char2int((char) _hex[i * 2 + 1]);
101

102 103 104
        if (high < 0 || low < 0) {
            return false;
        }
105

106 107
        _bin[i] = (unsigned char) (high * 16 + low);
    }
108

109
    return true;
110 111
}

112 113
bool hex2carray2(const char *_hex, uint64_t *_bin_len,
                 uint8_t *_bin, const int _max_length) {
114
    int len = strnlen(_hex, _max_length);
115 116 117 118 119 120 121

    if (len == 0 && len % 2 == 1)
        return false;

    *_bin_len = len / 2;

    for (int i = 0; i < len / 2; i++) {
122 123
        int high = char2int((char) _hex[i * 2]);
        int low = char2int((char) _hex[i * 2 + 1]);
124 125 126 127 128 129 130 131 132 133

        if (high < 0 || low < 0) {
            return false;
        }

        _bin[i] = (unsigned char) (high * 16 + low);
    }

    return true;
}
134

135 136 137
bool sign(const char *_encryptedKeyHex, const char *_hashHex, size_t _t, size_t _n, size_t _signerIndex,
          char *_sig) {
    auto keyStr = make_shared<string>(_encryptedKeyHex);
138

139
    auto hash = make_shared<array<uint8_t, 32>>();
140

141
    uint64_t binLen;
142

143
    if (!hex2carray(_hashHex, &binLen, hash->data())) {
144
        throw SGXException(INVALID_HEX, "Invalid hash");
145
    }
146

147
    auto keyShare = make_shared<BLSPrivateKeyShareSGX>(keyStr, _t, _n);
148

149
    auto sigShare = keyShare->signWithHelperSGX(hash, _signerIndex);
150

151
    auto sigShareStr = sigShare->toString();
kladkogex's avatar
kladkogex committed
152

153
    strncpy(_sig, sigShareStr->c_str(), BUF_LEN);
kladkogex's avatar
kladkogex committed
154

155
    return true;
156 157
}

158 159 160
bool sign_aes(const char *_encryptedKeyHex, const char *_hashHex, size_t _t, size_t _n, size_t _signerIndex,
              char *_sig) {
    auto hash = make_shared<array<uint8_t, 32>>();
161

162
    uint64_t binLen;
163

164
    if (!hex2carray(_hashHex, &binLen, hash->data())) {
165
        throw SGXException(INVALID_HEX, "Invalid hash");
166
    }
167

168 169
    shared_ptr<signatures::Bls> obj;
    obj = make_shared<signatures::Bls>(signatures::Bls(_t, _n));
170

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

173
    string *xStr = FqToString(&(hash_with_hint.first.X));
174

175 176 177
    if (xStr == nullptr) {
        std::cerr << "Null xStr" << std::endl;
        BOOST_THROW_EXCEPTION(runtime_error("Null xStr"));
178
    }
179

180
    string *yStr = FqToString(&(hash_with_hint.first.Y));
181

182 183
    if (yStr == nullptr) {
        std::cerr << "Null yStr" << std::endl;
Oleh Nikolaiev's avatar
Oleh Nikolaiev committed
184
        delete xStr;
185
        BOOST_THROW_EXCEPTION(runtime_error("Null yStr"));
186
    }
187

188 189 190 191 192 193
    char errMsg[BUF_LEN];
    memset(errMsg, 0, BUF_LEN);

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

195 196 197 198 199
    memset(xStrArg, 0, BUF_LEN);
    memset(yStrArg, 0, BUF_LEN);

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

Oleh Nikolaiev's avatar
Oleh Nikolaiev committed
201 202 203
    delete xStr;
    delete yStr;

204
    size_t sz = 0;
205

206
    uint8_t encryptedKey[BUF_LEN];
207

208
    bool result = hex2carray(_encryptedKeyHex, &sz, encryptedKey);
209

210 211 212 213
    if (!result) {
        cerr << "Invalid hex encrypted key" << endl;
        BOOST_THROW_EXCEPTION(std::invalid_argument("Invalid hex encrypted key"));
    }
214

215 216
    int errStatus = 0;

217
    sgx_status_t status =
218 219
            trustedBlsSignMessageAES(eid, &errStatus, errMsg, encryptedKey,
                                 sz, xStrArg, yStrArg, signature);
220

221
    if (status != SGX_SUCCESS) {
222 223
        cerr << "SGX enclave call to trustedBlsSignMessage failed with status:" << status << std::endl;
        BOOST_THROW_EXCEPTION(runtime_error("SGX enclave call to trustedBlsSignMessage failed"));
224
    }
225

226
    if (errStatus != 0) {
227 228
        cerr << "SGX enclave call to trustedBlsSignMessage failed with errStatus:" << errStatus << std::endl;
        BOOST_THROW_EXCEPTION(runtime_error("SGX enclave call to trustedBlsSignMessage failed"));
229 230
    }

231
    std::string hint = BLSutils::ConvertToString(hash_with_hint.first.Y) + ":" + hash_with_hint.second;
232

233
    std::string sig = signature;
234

235 236
    sig.append(":");
    sig.append(hint);
237

238
    strncpy(_sig, sig.c_str(), BUF_LEN);
239

240
    return true;
241 242
}

243 244
bool bls_sign(const char *_encryptedKeyHex, const char *_hashHex, size_t _t, size_t _n, size_t _signerIndex,
              char *_sig) {
245
    return sign_aes(_encryptedKeyHex, _hashHex, _t, _n, _signerIndex, _sig);
246
}
kladkogex's avatar
kladkogex committed
247

248
std::string encryptBLSKeyShare2Hex(int *errStatus, char *err_string, const char *_key) {
kladko's avatar
kladko committed
249 250 251 252
    auto keyArray = make_shared<vector<char>>(BUF_LEN, 0);
    auto encryptedKey = make_shared<vector<uint8_t>>(BUF_LEN, 0);
    auto errMsg = make_shared<vector<char>>(BUF_LEN, 0);
    strncpy(keyArray->data(), _key, BUF_LEN);
kladkogex's avatar
kladkogex committed
253 254 255 256
    *errStatus = -1;

    unsigned int encryptedLen = 0;

257
    status = trustedEncryptKeyAES(eid, errStatus, errMsg->data(), keyArray->data(), encryptedKey->data(), &encryptedLen);
kladkogex's avatar
kladkogex committed
258

259
    spdlog::debug("errStatus is {}", *errStatus);
260
    spdlog::debug("errMsg is ", errMsg->data());
261

262 263 264 265
    if (*errStatus != 0) {
        throw SGXException(-666, errMsg->data());
    }

kladkogex's avatar
kladkogex committed
266 267 268 269 270
    if (status != SGX_SUCCESS) {
        *errStatus = -1;
        return nullptr;
    }

271
    std::string result(2 * BUF_LEN, '\0');
kladkogex's avatar
kladkogex committed
272

273
    carray2Hex(encryptedKey->data(), encryptedLen, &result.front());
kladkogex's avatar
kladkogex committed
274

275
    return result;
kladkogex's avatar
kladkogex committed
276
}