BLSCrypto.cpp 6.73 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
#include "libff/algebra/curves/alt_bn128/alt_bn128_init.hpp"
26 27 28 29 30 31
#include "leveldb/db.h"
#include <jsonrpccpp/server/connectors/httpserver.h>

#include "third_party/intel/create_enclave.h"


32
#include "bls.h"
33
#include <bls/BLSutils.h>
34

35
#include "BLSPrivateKeyShareSGX.h"
36

37

38 39 40 41 42
#include "sgxwallet_common.h"
#include "sgxwallet.h"
#include "SGXException.h"
#include "third_party/spdlog/spdlog.h"
#include "common.h"
43 44
#include "SGXWalletServer.h"

kladko's avatar
kladko committed
45 46
#include "SEKManager.h"
#include "LevelDB.h"
kladkogex's avatar
kladkogex committed
47
#include "ServerInit.h"
kladko's avatar
kladko committed
48
#include "BLSCrypto.h"
49 50


kladko's avatar
kladko committed
51
string *FqToString(libff::alt_bn128_Fq *_fq) {
52 53 54

    CHECK_STATE(_fq);

55 56 57 58 59
    mpz_t t;
    mpz_init(t);

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

kladko's avatar
kladko committed
60
    SAFE_CHAR_BUF(arr, mpz_sizeinbase(t, 10) + 2);
61

Oleh Nikolaiev's avatar
Oleh Nikolaiev committed
62
    mpz_get_str(arr, 10, t);
63 64
    mpz_clear(t);

kladko's avatar
kladko committed
65
    return new string(arr);
66 67
}

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
vector<char> carray2Hex(const unsigned char *d, uint64_t _len) {
79 80

    CHECK_STATE(d);
81
    vector<char> _hexArray( 2 * _len + 1);
82

83 84
    char hexval[16] = {'0', '1', '2', '3', '4', '5', '6', '7',
                       '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'};
85

kladko's avatar
kladko committed
86
    for (uint64_t j = 0; j < _len; j++) {
87 88 89
        _hexArray[j * 2] = hexval[((d[j] >> 4) & 0xF)];
        _hexArray[j * 2 + 1] = hexval[(d[j]) & 0x0F];
    }
90

91
    _hexArray[_len * 2] = 0;
92 93

    return _hexArray;
94 95 96
}


97
bool hex2carray(const char *_hex, uint64_t *_bin_len,
kladko's avatar
kladko committed
98
                uint8_t *_bin, uint64_t _max_length) {
99 100


101 102 103
    CHECK_STATE(_hex);
    CHECK_STATE(_bin);
    CHECK_STATE(_bin_len)
104 105


kladko's avatar
kladko committed
106
    uint64_t len = strnlen(_hex, 2 * _max_length + 1);
107 108 109

    CHECK_STATE(len != 2 * _max_length + 1);

kladko's avatar
kladko committed
110
    CHECK_STATE(len <= 2 * _max_length);
111

112 113 114 115 116 117

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

    *_bin_len = len / 2;

kladko's avatar
kladko committed
118
    for (uint64_t i = 0; i < len / 2; i++) {
119 120
        int high = char2int((char) _hex[i * 2]);
        int low = char2int((char) _hex[i * 2 + 1]);
121 122 123 124 125 126 127 128 129 130

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

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

    return true;
}
131

132 133
bool sign(const char *_encryptedKeyHex, const char *_hashHex, size_t _t, size_t _n, size_t _signerIndex,
          char *_sig) {
134 135 136 137 138 139


    CHECK_STATE(_encryptedKeyHex);
    CHECK_STATE(_hashHex);
    CHECK_STATE(_sig);

140
    auto keyStr = make_shared<string>(_encryptedKeyHex);
141

kladko's avatar
kladko committed
142 143
    auto hash = make_shared < array < uint8_t,
    32 >> ();
144

145
    uint64_t binLen;
146

147
    if (!hex2carray(_hashHex, &binLen, hash->data(), hash->size())) {
148
        throw SGXException(INVALID_HEX, "Invalid hash");
149
    }
150

151
    auto keyShare = make_shared<BLSPrivateKeyShareSGX>(keyStr, _t, _n);
152

153
    auto sigShare = keyShare->signWithHelperSGX(hash, _signerIndex);
154

155
    auto sigShareStr = sigShare->toString();
kladkogex's avatar
kladkogex committed
156

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

159
    return true;
160 161
}

162
bool sign_aes(const char *_encryptedKeyHex, const char *_hashHex, size_t _t, size_t _n, char *_sig) {
163 164 165 166 167

    CHECK_STATE(_encryptedKeyHex);
    CHECK_STATE(_hashHex);
    CHECK_STATE(_sig);

168
    auto hash = make_shared < array < uint8_t, 32 >> ();
169

170
    uint64_t binLen;
171

172
    if (!hex2carray(_hashHex, &binLen, hash->data(), hash->size())) {
173
        throw SGXException(INVALID_HEX, "Invalid hash");
174
    }
175

kladko's avatar
kladko committed
176
    shared_ptr <signatures::Bls> obj;
177
    obj = make_shared<signatures::Bls>(signatures::Bls(_t, _n));
178

kladko's avatar
kladko committed
179
    pair <libff::alt_bn128_G1, string> hash_with_hint = obj->HashtoG1withHint(hash);
180

181
    string *xStr = FqToString(&(hash_with_hint.first.X));
182

kladko's avatar
kladko committed
183
    CHECK_STATE(xStr);
184

185
    string *yStr = FqToString(&(hash_with_hint.first.Y));
186

187
    if (yStr == nullptr) {
Oleh Nikolaiev's avatar
Oleh Nikolaiev committed
188
        delete xStr;
189
        BOOST_THROW_EXCEPTION(runtime_error("Null yStr"));
190
    }
191

kladko's avatar
kladko committed
192
    vector<char> errMsg(BUF_LEN, 0);
193

kladko's avatar
kladko committed
194
    SAFE_CHAR_BUF(xStrArg, BUF_LEN);SAFE_CHAR_BUF(yStrArg, BUF_LEN);SAFE_CHAR_BUF(signature, BUF_LEN);
195 196 197

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

Oleh Nikolaiev's avatar
Oleh Nikolaiev committed
199 200 201
    delete xStr;
    delete yStr;

202
    size_t sz = 0;
203

kladko's avatar
kladko committed
204
    SAFE_UINT8_BUF(encryptedKey, BUF_LEN);
205

206
    bool result = hex2carray(_encryptedKeyHex, &sz, encryptedKey, BUF_LEN);
207

208
    if (!result) {
kladko's avatar
kladko committed
209
        BOOST_THROW_EXCEPTION(invalid_argument("Invalid hex encrypted key"));
210
    }
211

212
    int errStatus = 0;
kladko's avatar
kladko committed
213 214 215


    sgx_status_t status = SGX_SUCCESS;
kladko's avatar
kladko committed
216

kladko's avatar
kladko committed
217
    RESTART_BEGIN
kladko's avatar
kladko committed
218
            status = trustedBlsSignMessage(eid, &errStatus, errMsg.data(), encryptedKey,
kladko's avatar
kladko committed
219
                                              sz, xStrArg, yStrArg, signature);
kladko's avatar
kladko committed
220
    RESTART_END
kladko's avatar
kladko committed
221

kladko's avatar
kladko committed
222

kladko's avatar
kladko committed
223
    HANDLE_TRUSTED_FUNCTION_ERROR(status, errStatus, errMsg.data());
224

kladko's avatar
kladko committed
225
    string hint = BLSutils::ConvertToString(hash_with_hint.first.Y) + ":" + hash_with_hint.second;
226

kladko's avatar
kladko committed
227
    string sig = signature;
228

229 230
    sig.append(":");
    sig.append(hint);
231

232
    strncpy(_sig, sig.c_str(), BUF_LEN);
233

234
    return true;
235 236
}

237
bool bls_sign(const char *_encryptedKeyHex, const char *_hashHex, size_t _t, size_t _n, char *_sig) {
kladko's avatar
kladko committed
238 239
    CHECK_STATE(_encryptedKeyHex);
    CHECK_STATE(_hashHex);
240
    return sign_aes(_encryptedKeyHex, _hashHex, _t, _n, _sig);
241
}
kladkogex's avatar
kladkogex committed
242

kladko's avatar
kladko committed
243
string encryptBLSKeyShare2Hex(int *errStatus, char *err_string, const char *_key) {
kladko's avatar
kladko committed
244 245 246
    CHECK_STATE(errStatus);
    CHECK_STATE(err_string);
    CHECK_STATE(_key);
kladko's avatar
kladko committed
247 248
    auto keyArray = make_shared < vector < char >> (BUF_LEN, 0);
    auto encryptedKey = make_shared < vector < uint8_t >> (BUF_LEN, 0);
249 250

    vector<char> errMsg(BUF_LEN, 0);
251

252
    strncpy(keyArray->data(), _key, BUF_LEN);
253
    *errStatus = 0;
kladko's avatar
kladko committed
254 255

    uint64_t encryptedLen = 0;
kladkogex's avatar
kladkogex committed
256

kladko's avatar
kladko committed
257
    sgx_status_t status = SGX_SUCCESS;
kladko's avatar
kladko committed
258 259

    RESTART_BEGIN
kladko's avatar
kladko committed
260
        status = trustedEncryptKey(eid, errStatus, errMsg.data(), keyArray->data(), encryptedKey->data(),
kladko's avatar
kladko committed
261
                                      &encryptedLen);
kladko's avatar
kladko committed
262
    RESTART_END_POINTER
kladkogex's avatar
kladkogex committed
263

264
    HANDLE_TRUSTED_FUNCTION_ERROR(status, *errStatus, errMsg.data());
kladkogex's avatar
kladkogex committed
265

266
    vector<char> resultBuf = carray2Hex(encryptedKey->data(), encryptedLen);
kladkogex's avatar
kladkogex committed
267

268
    return string(resultBuf.begin(), resultBuf.end());
kladkogex's avatar
kladkogex committed
269
}