/* 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 */ #include <memory> #include "libff/algebra/curves/alt_bn128/alt_bn128_init.hpp" #include "leveldb/db.h" #include <jsonrpccpp/server/connectors/httpserver.h> #include "third_party/intel/create_enclave.h" #include "bls.h" #include <bls/BLSutils.h> #include "BLSPrivateKeyShareSGX.h" #include "sgxwallet_common.h" #include "sgxwallet.h" #include "SGXException.h" #include "third_party/spdlog/spdlog.h" #include "common.h" #include "SGXWalletServer.h" #include "SEKManager.h" #include "LevelDB.h" #include "ServerInit.h" #include "BLSCrypto.h" #include "CryptoTools.h" string *FqToString(libff::alt_bn128_Fq *_fq) { CHECK_STATE(_fq); mpz_t t; mpz_init(t); _fq->as_bigint().to_mpz(t); SAFE_CHAR_BUF(arr, mpz_sizeinbase(t, 10) + 2); mpz_get_str(arr, 10, t); mpz_clear(t); return new string(arr); } bool sign_aes(const char *_encryptedKeyHex, const char *_hashHex, size_t _t, size_t _n, char *_sig) { CHECK_STATE(_encryptedKeyHex); CHECK_STATE(_hashHex); CHECK_STATE(_sig); auto hash = make_shared < array < uint8_t, 32 >> (); uint64_t binLen; if (!hex2carray(_hashHex, &binLen, hash->data(), hash->size())) { throw SGXException(SIGN_AES_INVALID_HASH, string(__FUNCTION__) + ":Invalid hash"); } shared_ptr <signatures::Bls> obj; obj = make_shared<signatures::Bls>(signatures::Bls(_t, _n)); pair <libff::alt_bn128_G1, string> hash_with_hint = obj->HashtoG1withHint(hash); string *xStr = FqToString(&(hash_with_hint.first.X)); CHECK_STATE(xStr); string *yStr = FqToString(&(hash_with_hint.first.Y)); if (yStr == nullptr) { delete xStr; BOOST_THROW_EXCEPTION(runtime_error("Null yStr")); } vector<char> errMsg(BUF_LEN, 0); SAFE_CHAR_BUF(xStrArg, BUF_LEN);SAFE_CHAR_BUF(yStrArg, BUF_LEN);SAFE_CHAR_BUF(signature, BUF_LEN); strncpy(xStrArg, xStr->c_str(), BUF_LEN); strncpy(yStrArg, yStr->c_str(), BUF_LEN); delete xStr; delete yStr; size_t sz = 0; SAFE_UINT8_BUF(encryptedKey, BUF_LEN); bool result = hex2carray(_encryptedKeyHex, &sz, encryptedKey, BUF_LEN); if (!result) { BOOST_THROW_EXCEPTION(invalid_argument("Invalid hex encrypted key")); } int errStatus = 0; sgx_status_t status = SGX_SUCCESS; status = trustedBlsSignMessage(eid, &errStatus, errMsg.data(), encryptedKey, sz, xStrArg, yStrArg, signature); HANDLE_TRUSTED_FUNCTION_ERROR(status, errStatus, errMsg.data()); string hint = BLSutils::ConvertToString(hash_with_hint.first.Y) + ":" + hash_with_hint.second; string sig = signature; sig.append(":"); sig.append(hint); strncpy(_sig, sig.c_str(), BUF_LEN); return true; } bool bls_sign(const char *_encryptedKeyHex, const char *_hashHex, size_t _t, size_t _n, char *_sig) { CHECK_STATE(_encryptedKeyHex); CHECK_STATE(_hashHex); return sign_aes(_encryptedKeyHex, _hashHex, _t, _n, _sig); } string encryptBLSKeyShare2Hex(int *errStatus, char *err_string, const char *_key) { CHECK_STATE(errStatus); CHECK_STATE(err_string); CHECK_STATE(_key); auto keyArray = make_shared < vector < char >> (BUF_LEN, 0); auto encryptedKey = make_shared < vector < uint8_t >> (BUF_LEN, 0); vector<char> errMsg(BUF_LEN, 0); strncpy(keyArray->data(), _key, BUF_LEN); *errStatus = 0; uint64_t encryptedLen = 0; sgx_status_t status = SGX_SUCCESS; status = trustedEncryptKey(eid, errStatus, errMsg.data(), keyArray->data(), encryptedKey->data(), &encryptedLen); HANDLE_TRUSTED_FUNCTION_ERROR(status, *errStatus, errMsg.data()); vector<char> resultBuf = carray2Hex(encryptedKey->data(), encryptedLen); return string(resultBuf.begin(), resultBuf.end()); }