diff --git a/BLSCrypto.cpp b/BLSCrypto.cpp index 9a31ca9b..cd1ba0ca 100644 --- a/BLSCrypto.cpp +++ b/BLSCrypto.cpp @@ -29,10 +29,7 @@ #include "third_party/intel/create_enclave.h" -#include "bls.h" -#include - -#include "BLSPrivateKeyShareSGX.h" +#include #include "sgxwallet_common.h" @@ -40,7 +37,7 @@ #include "SGXException.h" #include "third_party/spdlog/spdlog.h" #include "common.h" -#include "SGXWalletServer.h" +#include "SGXWalletServer.hpp" #include "SEKManager.h" #include "LevelDB.h" @@ -49,7 +46,7 @@ #include "CryptoTools.h" -string *FqToString(libff::alt_bn128_Fq *_fq) { +shared_ptr FqToString(libff::alt_bn128_Fq *_fq) { CHECK_STATE(_fq); @@ -63,7 +60,7 @@ string *FqToString(libff::alt_bn128_Fq *_fq) { mpz_get_str(arr, 10, t); mpz_clear(t); - return new string(arr); + return make_shared(string(arr)); } bool sign_aes(const char *_encryptedKeyHex, const char *_hashHex, size_t _t, size_t _n, char *_sig) { @@ -80,21 +77,18 @@ bool sign_aes(const char *_encryptedKeyHex, const char *_hashHex, size_t _t, siz throw SGXException(SIGN_AES_INVALID_HASH, string(__FUNCTION__) + ":Invalid hash"); } - shared_ptr obj; - obj = make_shared(signatures::Bls(_t, _n)); + shared_ptr obj; + obj = make_shared(libBLS::Bls(_t, _n)); pair hash_with_hint = obj->HashtoG1withHint(hash); - string *xStr = FqToString(&(hash_with_hint.first.X)); + shared_ptr xStr = FqToString(&(hash_with_hint.first.X)); CHECK_STATE(xStr); - string *yStr = FqToString(&(hash_with_hint.first.Y)); + shared_ptr yStr = FqToString(&(hash_with_hint.first.Y)); - if (yStr == nullptr) { - delete xStr; - BOOST_THROW_EXCEPTION(runtime_error("Null yStr")); - } + CHECK_STATE(yStr); vector errMsg(BUF_LEN, 0); @@ -103,9 +97,6 @@ bool sign_aes(const char *_encryptedKeyHex, const char *_hashHex, size_t _t, siz 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); @@ -125,7 +116,7 @@ bool sign_aes(const char *_encryptedKeyHex, const char *_hashHex, size_t _t, siz HANDLE_TRUSTED_FUNCTION_ERROR(status, errStatus, errMsg.data()); - string hint = BLSutils::ConvertToString(hash_with_hint.first.Y) + ":" + hash_with_hint.second; + string hint = libBLS::ThresholdUtils::fieldElementToString(hash_with_hint.first.Y) + ":" + hash_with_hint.second; string sig = signature; @@ -143,6 +134,102 @@ bool bls_sign(const char *_encryptedKeyHex, const char *_hashHex, size_t _t, siz return sign_aes(_encryptedKeyHex, _hashHex, _t, _n, _sig); } +bool popProveSGX( const char* encryptedKeyHex, char* prove ) { + CHECK_STATE(encryptedKeyHex); + + SAFE_UINT8_BUF(encryptedKey, BUF_LEN); + + size_t sz = 0; + + if (!hex2carray(encryptedKeyHex, &sz, encryptedKey, BUF_LEN)) { + BOOST_THROW_EXCEPTION(invalid_argument("Invalid hex encrypted key")); + } + + sgx_status_t status = SGX_SUCCESS; + + vector errMsg(BUF_LEN, 0); + + int errStatus = 0; + + SAFE_CHAR_BUF(pubKey, 320) + + status = trustedGetBlsPubKey(eid, &errStatus, errMsg.data(), encryptedKey, sz, pubKey); + + HANDLE_TRUSTED_FUNCTION_ERROR(status, errStatus, errMsg.data()); + + vector pubKeyVect = splitString(pubKey, ':'); + + spdlog::debug("pub key is "); + for (int i = 0; i < 4; i++) + spdlog::debug("{}", pubKeyVect.at(i)); + + libff::alt_bn128_G2 publicKey; + publicKey.Z = libff::alt_bn128_Fq2::one(); + publicKey.X.c0 = libff::alt_bn128_Fq(pubKeyVect[0].c_str()); + publicKey.X.c1 = libff::alt_bn128_Fq(pubKeyVect[1].c_str()); + publicKey.Y.c0 = libff::alt_bn128_Fq(pubKeyVect[2].c_str()); + publicKey.Y.c1 = libff::alt_bn128_Fq(pubKeyVect[3].c_str()); + + pair hashPublicKeyWithHint = libBLS::Bls::HashPublicKeyToG1WithHint( publicKey ); + + hashPublicKeyWithHint.first.to_affine_coordinates(); + + shared_ptr xStr = FqToString(&(hashPublicKeyWithHint.first.X)); + + CHECK_STATE(xStr); + + shared_ptr yStr = FqToString(&(hashPublicKeyWithHint.first.Y)); + + CHECK_STATE(yStr); + + SAFE_CHAR_BUF(xStrArg, BUF_LEN);SAFE_CHAR_BUF(yStrArg, BUF_LEN); + + strncpy(xStrArg, xStr->c_str(), BUF_LEN); + strncpy(yStrArg, yStr->c_str(), BUF_LEN); + + errStatus = 0; + + status = trustedBlsSignMessage(eid, &errStatus, errMsg.data(), encryptedKey, sz, xStrArg, yStrArg, prove); + + HANDLE_TRUSTED_FUNCTION_ERROR(status, errStatus, errMsg.data()); + + string hint = libBLS::ThresholdUtils::fieldElementToString(hashPublicKeyWithHint.first.Y) + ":" + hashPublicKeyWithHint.second; + + string _prove = prove; + + _prove.append(":"); + _prove.append(hint); + + strncpy(prove, _prove.c_str(), BUF_LEN); + + return true; +} + +bool generateBLSPrivateKeyAggegated(const char* blsKeyName) { + CHECK_STATE(blsKeyName); + + vector errMsg(BUF_LEN, 0); + int errStatus = 0; + + int exportable = 0; + + uint64_t encBlsLen = 0; + + sgx_status_t status = SGX_SUCCESS; + + SAFE_UINT8_BUF(encrBlsKey, BUF_LEN) + + status = trustedGenerateBLSKey(eid, &errStatus, errMsg.data(), &exportable, encrBlsKey, &encBlsLen); + + HANDLE_TRUSTED_FUNCTION_ERROR(status, errStatus, errMsg.data()); + + vector hexBLSKey = carray2Hex(encrBlsKey, encBlsLen); + + SGXWalletServer::writeDataToDB(blsKeyName, hexBLSKey.data()); + + return true; +} + string encryptBLSKeyShare2Hex(int *errStatus, char *err_string, const char *_key) { CHECK_STATE(errStatus); CHECK_STATE(err_string); diff --git a/BLSCrypto.h b/BLSCrypto.h index 4cfd3007..f945c771 100644 --- a/BLSCrypto.h +++ b/BLSCrypto.h @@ -32,11 +32,20 @@ #include "stddef.h" #include "stdint.h" +#include #include #include +#include "bls.h" + EXTERNC bool bls_sign(const char* encryptedKeyHex, const char* hashHex, size_t t, size_t n, char* _sig); +EXTERNC bool popProveSGX( const char* encryptedKeyHex, char* _prove ); + +EXTERNC bool generateBLSPrivateKeyAggegated(const char* blsKeyName); + +std::shared_ptr FqToString(libff::alt_bn128_Fq *_fq); + std::string encryptBLSKeyShare2Hex(int *errStatus, char *err_string, const char *_key); #endif //SGXWALLET_BLSCRYPTO_H diff --git a/BLSPrivateKeyShareSGX.cpp b/BLSPrivateKeyShareSGX.cpp index c22127f1..6b1d583d 100644 --- a/BLSPrivateKeyShareSGX.cpp +++ b/BLSPrivateKeyShareSGX.cpp @@ -23,7 +23,7 @@ #include "BLSSigShare.h" #include "BLSSignature.h" -#include "BLSutils.h" +#include #include "third_party/spdlog/spdlog.h" #include "common.h" @@ -37,37 +37,15 @@ #include "SEKManager.h" #include "BLSPrivateKeyShareSGX.h" -string *stringFromFq(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); - - char *tmp = mpz_get_str(arr, 10, t); - - mpz_clear(t); - - return new string(tmp); -} - -string *stringFromG1(libff::alt_bn128_G1 *_g1) { +shared_ptr stringFromG1(libff::alt_bn128_G1 *_g1) { CHECK_STATE(_g1); - auto sX = stringFromFq(&_g1->X); - auto sY = stringFromFq(&_g1->Y); - auto sZ = stringFromFq(&_g1->Z); + auto sX = FqToString(&_g1->X); + auto sY = FqToString(&_g1->Y); + auto sZ = FqToString(&_g1->Z); - auto sG1 = new string(*sX + ":" + *sY + ":" + *sZ); - - delete (sX); - delete (sY); - delete (sZ); + auto sG1 = make_shared(*sX + ":" + *sY + ":" + *sZ); return sG1; } @@ -100,28 +78,24 @@ BLSPrivateKeyShareSGX::BLSPrivateKeyShareSGX( string BLSPrivateKeyShareSGX::signWithHelperSGXstr( shared_ptr > hash_byte_arr, size_t _signerIndex) { - shared_ptr obj; + shared_ptr obj; CHECK_STATE(hash_byte_arr) - obj = make_shared( - signatures::Bls(requiredSigners, totalSigners)); + obj = make_shared( libBLS::Bls(requiredSigners, totalSigners)); pair hash_with_hint = obj->HashtoG1withHint(hash_byte_arr); int errStatus = 0; - string *xStr = stringFromFq(&(hash_with_hint.first.X)); + shared_ptr xStr = FqToString(&(hash_with_hint.first.X)); CHECK_STATE(xStr); - string *yStr = stringFromFq(&(hash_with_hint.first.Y)); + shared_ptr yStr = FqToString(&(hash_with_hint.first.Y)); - if (yStr == nullptr) { - delete xStr; - BOOST_THROW_EXCEPTION(runtime_error("Null yStr")); - } + CHECK_STATE(yStr); vector errMsg(BUF_LEN, 0); @@ -130,9 +104,6 @@ string BLSPrivateKeyShareSGX::signWithHelperSGXstr( 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); @@ -159,7 +130,7 @@ string BLSPrivateKeyShareSGX::signWithHelperSGXstr( BOOST_THROW_EXCEPTION(runtime_error("Signature is too short:" + to_string(sigLen))); } - string hint = BLSutils::ConvertToString(hash_with_hint.first.Y) + ":" + + string hint = libBLS::ThresholdUtils::fieldElementToString(hash_with_hint.first.Y) + ":" + hash_with_hint.second; string sig = signature; diff --git a/CryptoTools.cpp b/CryptoTools.cpp index 9b05ad2a..d3f05d11 100644 --- a/CryptoTools.cpp +++ b/CryptoTools.cpp @@ -86,4 +86,25 @@ bool hex2carray(const char *_hex, uint64_t *_bin_len, } return true; -} \ No newline at end of file +} + +vector splitString(const char *coeffs, const char symbol) { + CHECK_STATE(coeffs); + std::string str(coeffs); + std::string delim; + delim.push_back(symbol); + vector G2Strings; + 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()) { + std::string coeff(token.c_str()); + G2Strings.push_back(coeff); + } + prev = pos + delim.length(); + } while (pos < str.length() && prev < str.length()); + + return G2Strings; +} diff --git a/CryptoTools.h b/CryptoTools.h index 9eed91ac..e9f35976 100644 --- a/CryptoTools.h +++ b/CryptoTools.h @@ -42,4 +42,6 @@ EXTERNC std::vector carray2Hex(const unsigned char *d, uint64_t _len); EXTERNC bool hex2carray(const char * _hex, uint64_t *_bin_len, uint8_t* _bin, uint64_t _max_length ); +std::vector splitString(const char* coeffs, const char symbol); + #endif // SGXWALLET_CRYPTOTOOLS_H diff --git a/DKGCrypto.cpp b/DKGCrypto.cpp index 72bcb1f4..9b2aa3fc 100644 --- a/DKGCrypto.cpp +++ b/DKGCrypto.cpp @@ -36,27 +36,6 @@ #include "SEKManager.h" #include "DKGCrypto.h" -vector splitString(const char *coeffs, const char symbol) { - CHECK_STATE(coeffs); - string str(coeffs); - string delim; - delim.push_back(symbol); - vector G2_strings; - size_t prev = 0, pos = 0; - do { - pos = str.find(delim, prev); - if (pos == string::npos) pos = str.length(); - string token = str.substr(prev, pos - prev); - if (!token.empty()) { - string coeff(token.c_str()); - G2_strings.push_back(coeff); - } - prev = pos + delim.length(); - } while (pos < str.length() && prev < str.length()); - - return G2_strings; -} - template string ConvertToString(T field_elem, int base = 10) { mpz_t t; diff --git a/DKGCrypto.h b/DKGCrypto.h index c76b01e7..7d43482c 100644 --- a/DKGCrypto.h +++ b/DKGCrypto.h @@ -37,8 +37,6 @@ vector > get_verif_vect(const string& encryptedPolyHex, int t); vector > getVerificationVectorMult(const std::string& encryptedPolyHex, int t, int n, size_t ind); -vector splitString(const char* coeffs, const char symbol); - string getSecretShares(const string& _polyName, const char* _encryptedPolyHex, const vector& _publicKeys, int _t, int _n); string getSecretSharesV2(const string& _polyName, const char* _encryptedPolyHex, const vector& _publicKeys, int _t, int _n); diff --git a/DockerfileBase b/DockerfileBase index 044a4d58..c6c5d52d 100644 --- a/DockerfileBase +++ b/DockerfileBase @@ -1,6 +1,8 @@ FROM ubuntu:18.04 -RUN apt-get update && apt-get install -y \ +RUN apt-get update && apt-get install software-properties-common -y && \ + add-apt-repository ppa:ubuntu-toolchain-r/test && \ + apt-get update && apt-get install -y \ autoconf \ automake \ build-essential \ @@ -23,7 +25,14 @@ RUN apt-get update && apt-get install -y \ libssl1.1 \ make \ module-init-tools \ - unzip + unzip \ + gcc-9 g++-9 + +RUN update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-9 9 && \ + update-alternatives --install /usr/bin/g++ g++ /usr/bin/g++-9 9 && \ + update-alternatives --install /usr/bin/gcov gcov /usr/bin/gcov-9 9 && \ + update-alternatives --install /usr/bin/gcov-dump gcov-dump /usr/bin/gcov-dump-9 9 && \ + update-alternatives --install /usr/bin/gcov-tool gcov-tool /usr/bin/gcov-tool-9 9 RUN git clone -b sgx_2.13 --depth 1 https://github.com/intel/linux-sgx diff --git a/LevelDB.cpp b/LevelDB.cpp index 00b5fe71..505c5fd0 100644 --- a/LevelDB.cpp +++ b/LevelDB.cpp @@ -127,7 +127,7 @@ uint64_t LevelDB::visitKeys(LevelDB::KeyVisitor *_visitor, uint64_t _maxKeysToVi uint64_t readCounter = 0; - leveldb::Iterator *it = db->NewIterator(readOptions); + shared_ptr it( db->NewIterator(readOptions) ); for (it->SeekToFirst(); it->Valid(); it->Next()) { _visitor->visitDBKey(it->key().data()); readCounter++; @@ -136,8 +136,6 @@ uint64_t LevelDB::visitKeys(LevelDB::KeyVisitor *_visitor, uint64_t _maxKeysToVi } } - delete it; - return readCounter; } @@ -145,7 +143,7 @@ std::vector LevelDB::writeKeysToVector1(uint64_t _maxKeysToVisit){ uint64_t readCounter = 0; std::vector keys; - leveldb::Iterator *it = db->NewIterator(readOptions); + shared_ptr it( db->NewIterator(readOptions) ); for (it->SeekToFirst(); it->Valid(); it->Next()) { string cur_key(it->key().data(), it->key().size()); keys.push_back(cur_key); @@ -155,8 +153,6 @@ std::vector LevelDB::writeKeysToVector1(uint64_t _maxKeysToVisit){ } } - delete it; - return keys; } diff --git a/SGXWalletServer.cpp b/SGXWalletServer.cpp index bc74a4d3..c55e64ff 100644 --- a/SGXWalletServer.cpp +++ b/SGXWalletServer.cpp @@ -982,6 +982,28 @@ SGXWalletServer::createBLSPrivateKeyV2Impl(const string &_blsKeyName, const stri RETURN_SUCCESS(result); } +Json::Value SGXWalletServer::generateBLSPrivateKeyImpl(const string& blsKeyName) { + spdlog::info("Entering {}", __FUNCTION__); + INIT_RESULT(result) + + try { + if (!checkName(blsKeyName, "BLS_KEY")) { + throw SGXException(GENERATE_BLS_KEY_INVALID_NAME, string(__FUNCTION__) + ":Invalid BLSKey name"); + } + + bool res = generateBLSPrivateKeyAggegated(blsKeyName.c_str()); + if (res) { + spdlog::info("BLS AGGREGATED KEY CREATED "); + } else { + throw SGXException(INVALID_CREATE_BLS_AGGREGATED_KEY, + string(__FUNCTION__) + ":Error while creating BLS aggregated key"); + } + + } HANDLE_SGX_EXCEPTION(result) + + RETURN_SUCCESS(result); +} + Json::Value SGXWalletServer::getDecryptionSharesImpl(const std::string& blsKeyName, const Json::Value& publicDecryptionValues) { spdlog::info("Entering {}", __FUNCTION__); INIT_RESULT(result) @@ -1014,6 +1036,29 @@ Json::Value SGXWalletServer::getDecryptionSharesImpl(const std::string& blsKeyNa RETURN_SUCCESS(result) } +Json::Value SGXWalletServer::popProveImpl( const std::string& blsKeyName ) { + spdlog::info("Entering {}", __FUNCTION__); + INIT_RESULT(result) + + vector prove(BUF_LEN, 0); + + try { + if (!checkName(blsKeyName, "BLS_KEY")) { + throw SGXException(POP_PROVE_INVALID_KEY_NAME, string(__FUNCTION__) + ":Invalid BLSKey name"); + } + + shared_ptr encryptedKeyHexPtr = readFromDb(blsKeyName); + + if (!popProveSGX(encryptedKeyHexPtr->c_str(), prove.data())) { + throw SGXException(COULD_NOT_CREATE_POP_PROVE, ":Could not create popProve "); + } + } HANDLE_SGX_EXCEPTION(result) + + result["popProve"] = string(prove.data()); + + RETURN_SUCCESS(result) +} + Json::Value SGXWalletServer::generateDKGPoly(const string &_polyName, int _t) { return generateDKGPolyImpl(_polyName, _t); } @@ -1114,10 +1159,18 @@ SGXWalletServer::createBLSPrivateKeyV2(const string &blsKeyName, const string &e return createBLSPrivateKeyV2Impl(blsKeyName, ethKeyName, polyName, SecretShare, t, n); } +Json::Value SGXWalletServer::generateBLSPrivateKey(const string& blsKeyName) { + return generateBLSPrivateKeyImpl(blsKeyName); +} + Json::Value SGXWalletServer::getDecryptionShares(const std::string& blsKeyName, const Json::Value& publicDecryptionValues) { return getDecryptionSharesImpl(blsKeyName, publicDecryptionValues); } +Json::Value SGXWalletServer::popProve( const std::string& blsKeyName ) { + return popProveImpl( blsKeyName ); +} + shared_ptr SGXWalletServer::readFromDb(const string &name, const string &prefix) { auto dataStr = checkDataFromDb(prefix + name); diff --git a/SGXWalletServer.hpp b/SGXWalletServer.hpp index c11c1af4..070032fd 100644 --- a/SGXWalletServer.hpp +++ b/SGXWalletServer.hpp @@ -91,6 +91,8 @@ class SGXWalletServer : public AbstractStubServer { createBLSPrivateKey(const string &blsKeyName, const string ðKeyName, const string &polyName, const string &SecretShare, int t, int n); + virtual Json::Value generateBLSPrivateKey( const string& blsKeyName ); + virtual Json::Value getBLSPublicKeyShare(const string &blsKeyName); virtual Json::Value calculateAllBLSPublicKeys(const Json::Value& publicShares, int t, int n); @@ -115,6 +117,8 @@ class SGXWalletServer : public AbstractStubServer { virtual Json::Value getDecryptionShares(const std::string& blsKeyName, const Json::Value& publicDecryptionValues); + virtual Json::Value popProve( const std::string& blsKeyName ); + static shared_ptr readFromDb(const string &name, const string &prefix = ""); static shared_ptr checkDataFromDb(const string &name, const string &prefix = ""); @@ -173,8 +177,12 @@ class SGXWalletServer : public AbstractStubServer { static Json::Value createBLSPrivateKeyV2Impl(const std::string& blsKeyName, const std::string& ethKeyName, const std::string& polyName, const std::string & SecretShare, int t, int n); + static Json::Value generateBLSPrivateKeyImpl( const string& blsKeyName ); + static Json::Value getDecryptionSharesImpl(const std::string& KeyName, const Json::Value& publicDecryptionValues); + static Json::Value popProveImpl( const std::string& blsKeyName ); + static void printDB(); static void initHttpServer(); diff --git a/TECrypto.cpp b/TECrypto.cpp index 2dc0bb34..71aedbac 100644 --- a/TECrypto.cpp +++ b/TECrypto.cpp @@ -37,7 +37,7 @@ #include "TECrypto.h" #include "CryptoTools.h" -#include +#include vector calculateDecryptionShare(const string& encryptedKeyShare, const string& publicDecryptionValue) { @@ -64,7 +64,7 @@ vector calculateDecryptionShare(const string& encryptedKeyShare, HANDLE_TRUSTED_FUNCTION_ERROR(status, errStatus, errMsg.data()); - auto splitted_share = BLSutils::SplitString(std::make_shared(decryptionShare), ":"); + auto splittedShare = libBLS::ThresholdUtils::SplitString(std::make_shared(decryptionShare), ":"); - return *splitted_share; -} \ No newline at end of file + return *splittedShare; +} diff --git a/TestUtils.cpp b/TestUtils.cpp index 86b9ccb3..f6be3a27 100644 --- a/TestUtils.cpp +++ b/TestUtils.cpp @@ -62,12 +62,12 @@ using namespace std; default_random_engine TestUtils::randGen((unsigned int) time(0)); -string TestUtils::stringFromFr(libff::alt_bn128_Fr &el) { +string TestUtils::stringFromFr(libff::alt_bn128_Fr &el, size_t base) { mpz_t t; mpz_init(t); el.as_bigint().to_mpz(t); char arr[mpz_sizeinbase(t, 10) + 2]; - mpz_get_str(arr, 10, t); + mpz_get_str(arr, base, t); mpz_clear(t); return string(arr); @@ -632,7 +632,7 @@ void TestUtils::doDKG(StubClient &c, int n, int t, shared_ptr commonSig = sigShareSet.merge(); - CHECK_STATE(blsPublicKey.VerifySigWithHelper(hash_arr, commonSig, t, n)); + CHECK_STATE(blsPublicKey.VerifySigWithHelper(hash_arr, commonSig)); for (auto&& i : _ecdsaKeyNames) cerr << i << endl; @@ -719,9 +719,9 @@ void TestUtils::doDKGV2(StubClient &c, int n, int t, string hash = SAMPLE_HASH; - auto hash_arr = make_shared>(); + auto hashArr = make_shared>(); uint64_t binLen; - if (!hex2carray(hash.c_str(), &binLen, hash_arr->data(), 32)) { + if (!hex2carray(hash.c_str(), &binLen, hashArr->data(), 32)) { throw SGXException(TEST_INVALID_HEX, "Invalid hash"); } @@ -768,12 +768,12 @@ void TestUtils::doDKGV2(StubClient &c, int n, int t, auto pubKey = pubKeyShares[i+1]; - CHECK_STATE(pubKey->VerifySigWithHelper(hash_arr, make_shared(sig), t, n)); + CHECK_STATE(pubKey->VerifySigWithHelper(hashArr, make_shared(sig), t, n)); } shared_ptr commonSig = sigShareSet.merge(); - CHECK_STATE(blsPublicKey.VerifySigWithHelper(hash_arr, commonSig, t, n)); + CHECK_STATE(blsPublicKey.VerifySigWithHelper(hashArr, commonSig)); for (auto&& i : _ecdsaKeyNames) cerr << i << endl; @@ -861,9 +861,9 @@ void TestUtils::doZMQBLS(shared_ptr _zmqClient, StubClient &c, int n, string hash = SAMPLE_HASH; - auto hash_arr = make_shared>(); + auto hashArr = make_shared>(); uint64_t binLen; - if (!hex2carray(hash.c_str(), &binLen, hash_arr->data(), 32)) { + if (!hex2carray(hash.c_str(), &binLen, hashArr->data(), 32)) { throw SGXException(TEST_INVALID_HEX, "Invalid hash"); } @@ -908,12 +908,12 @@ void TestUtils::doZMQBLS(shared_ptr _zmqClient, StubClient &c, int n, auto pubKey = pubKeyShares[i+1]; - CHECK_STATE(pubKey->VerifySigWithHelper(hash_arr, make_shared(sig), t, n)); + CHECK_STATE(pubKey->VerifySigWithHelper(hashArr, make_shared(sig), t, n)); } shared_ptr commonSig = sigShareSet.merge(); - CHECK_STATE(blsPublicKey.VerifySigWithHelper(hash_arr, commonSig, t, n)); + CHECK_STATE(blsPublicKey.VerifySigWithHelper(hashArr, commonSig)); for (auto&& i : _ecdsaKeyNames) cerr << i << endl; diff --git a/TestUtils.h b/TestUtils.h index 9c004d63..03a988b6 100644 --- a/TestUtils.h +++ b/TestUtils.h @@ -50,7 +50,7 @@ class TestUtils { public: static default_random_engine randGen; - static string stringFromFr(libff::alt_bn128_Fr &el); + static string stringFromFr(libff::alt_bn128_Fr &el, size_t base = 10); static string convertDecToHex(string dec, int numBytes = 32); diff --git a/VERSION b/VERSION index b1fd0f76..f8e233b2 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -1.83.0 \ No newline at end of file +1.9.0 diff --git a/abstractstubserver.h b/abstractstubserver.h index 1be018b7..f07e92d7 100644 --- a/abstractstubserver.h +++ b/abstractstubserver.h @@ -64,6 +64,9 @@ class AbstractStubServer : public jsonrpc::AbstractServer this->bindAndAddMethod(jsonrpc::Procedure("createBLSPrivateKeyV2", jsonrpc::PARAMS_BY_NAME, jsonrpc::JSON_OBJECT, "blsKeyName",jsonrpc::JSON_STRING, "ethKeyName",jsonrpc::JSON_STRING, "polyName", jsonrpc::JSON_STRING, "secretShare",jsonrpc::JSON_STRING,"t", jsonrpc::JSON_INTEGER,"n",jsonrpc::JSON_INTEGER, NULL), &AbstractStubServer::createBLSPrivateKeyV2I); this->bindAndAddMethod(jsonrpc::Procedure("getDecryptionShares", jsonrpc::PARAMS_BY_NAME, jsonrpc::JSON_OBJECT, "blsKeyName",jsonrpc::JSON_STRING,"publicDecryptionValues",jsonrpc::JSON_ARRAY, NULL), &AbstractStubServer::getDecryptionSharesI); + + this->bindAndAddMethod(jsonrpc::Procedure("popProve", jsonrpc::PARAMS_BY_NAME, jsonrpc::JSON_OBJECT, "blsKeyName",jsonrpc::JSON_STRING, NULL), &AbstractStubServer::popProveI); + this->bindAndAddMethod(jsonrpc::Procedure("generateBLSPrivateKey", jsonrpc::PARAMS_BY_NAME, jsonrpc::JSON_OBJECT, "blsKeyName",jsonrpc::JSON_STRING, NULL), &AbstractStubServer::generateBLSPrivateKeyI); } inline virtual void importBLSKeyShareI(const Json::Value &request, Json::Value &response) @@ -133,7 +136,6 @@ class AbstractStubServer : public jsonrpc::AbstractServer response = this->isPolyExists(request["polyName"].asString()); } - inline virtual void getServerStatusI(const Json::Value &request, Json::Value &response) { (void)request; @@ -168,6 +170,16 @@ class AbstractStubServer : public jsonrpc::AbstractServer response = this->getDecryptionShares(request["blsKeyName"].asString(), request["publicDecryptionValues"]); } + inline virtual void popProveI(const Json::Value &request, Json::Value &response) + { + response = this->popProve(request["blsKeyName"].asString()); + } + + inline virtual void generateBLSPrivateKeyI(const Json::Value &request, Json::Value &response) + { + response = this->generateBLSPrivateKey(request["blsKeyName"].asString()); + } + virtual Json::Value importBLSKeyShare(const std::string& keyShare, const std::string& keyShareName) = 0; virtual Json::Value blsSignMessageHash(const std::string& keyShareName, const std::string& messageHash, int t, int n ) = 0; virtual Json::Value importECDSAKey(const std::string& keyShare, const std::string& keyShareName) = 0; @@ -195,6 +207,9 @@ class AbstractStubServer : public jsonrpc::AbstractServer virtual Json::Value createBLSPrivateKeyV2(const std::string& blsKeyName, const std::string& ethKeyName, const std::string& polyName, const std::string & SecretShare, int t, int n) = 0; virtual Json::Value getDecryptionShares(const std::string& KeyName, const Json::Value& publicDecryptionValues) = 0; + + virtual Json::Value popProve(const std::string& blsKeyName) = 0; + virtual Json::Value generateBLSPrivateKey(const std::string& blsKeyName) = 0; }; #endif //JSONRPC_CPP_STUB_ABSTRACTSTUBSERVER_H_ diff --git a/libBLS b/libBLS index 75972a81..d9f468fa 160000 --- a/libBLS +++ b/libBLS @@ -1 +1 @@ -Subproject commit 75972a810b8b1422004443028beedfef2288be50 +Subproject commit d9f468fae5a99d7a1d13974dc2a58626b4120e63 diff --git a/secure_enclave/AESUtils.c b/secure_enclave/AESUtils.c index ae501607..c2a2c983 100644 --- a/secure_enclave/AESUtils.c +++ b/secure_enclave/AESUtils.c @@ -84,26 +84,26 @@ int AES_encrypt(char *message, uint8_t *encr_message, uint64_t encrBufLen, unsig return status; } -int AES_decrypt(uint8_t *encr_message, uint64_t length, char *message, uint64_t msgLen, +int AES_decrypt(uint8_t *encrMessage, uint64_t length, char *message, uint64_t msgLen, uint8_t *type, uint8_t* exportable){ if (!message) { - LOG_ERROR("Null message in AES_encrypt"); + LOG_ERROR("Null message in AES_decrypt"); return -1; } - if (!encr_message) { - LOG_ERROR("Null encr message in AES_encrypt"); + if (!encrMessage) { + LOG_ERROR("Null encr message in AES_decrypt"); return -2; } if (!type) { - LOG_ERROR("Null type in AES_encrypt"); + LOG_ERROR("Null type in AES_decrypt"); return -3; } if (!exportable) { - LOG_ERROR("Null exportable in AES_encrypt"); + LOG_ERROR("Null exportable in AES_decrypt"); return -4; } @@ -121,11 +121,11 @@ int AES_decrypt(uint8_t *encr_message, uint64_t length, char *message, uint64_t } sgx_status_t status = sgx_rijndael128GCM_decrypt(&(AES_key[512]), - encr_message + SGX_AESGCM_MAC_SIZE + SGX_AESGCM_IV_SIZE, len, + encrMessage + SGX_AESGCM_MAC_SIZE + SGX_AESGCM_IV_SIZE, len, (unsigned char*) message, - encr_message + SGX_AESGCM_MAC_SIZE, SGX_AESGCM_IV_SIZE, + encrMessage + SGX_AESGCM_MAC_SIZE, SGX_AESGCM_IV_SIZE, NULL, 0, - (sgx_aes_gcm_128bit_tag_t *)encr_message); + (sgx_aes_gcm_128bit_tag_t *)encrMessage); *type = message[0]; *exportable = message[1]; diff --git a/secure_enclave/DHDkg.c b/secure_enclave/DHDkg.c index 4ad57786..bbac8cb0 100644 --- a/secure_enclave/DHDkg.c +++ b/secure_enclave/DHDkg.c @@ -332,7 +332,7 @@ int xor_decrypt_v2(char *key, char *cypher, char *message) { return ret; } -int hash_key(char* key, char* hashed_key) { +int hash_key(char* key, char* hashedKey, int length, bool isConvertNeeded) { int ret = -1; if (!key) { @@ -340,18 +340,22 @@ int hash_key(char* key, char* hashed_key) { return ret; } - if (!hashed_key) { + if (!hashedKey) { LOG_ERROR("hash_key: null hashed_key"); return ret; } - uint8_t key_to_hash[33]; - uint64_t len; - if (!hex2carray(key, &len, key_to_hash)) { - return ret; - } + if (isConvertNeeded) { + uint8_t key_to_hash[length + 1]; + uint64_t len; + if (!hex2carray(key, &len, key_to_hash)) { + return ret; + } - ret = sgx_sha256_msg(key_to_hash, ECDSA_BIN_LEN - 1, (uint8_t*)hashed_key); + ret = sgx_sha256_msg(key_to_hash, length, (uint8_t*)hashedKey); + } else { + ret = sgx_sha256_msg((uint8_t*)key, length, (uint8_t*)hashedKey); + } return ret; } diff --git a/secure_enclave/DHDkg.h b/secure_enclave/DHDkg.h index e4e5ec6f..7bf4c06f 100644 --- a/secure_enclave/DHDkg.h +++ b/secure_enclave/DHDkg.h @@ -36,6 +36,6 @@ int xor_decrypt(char* key, char* cypher, char* message); int xor_decrypt_v2(char* key, char* cypher, char* message); -int hash_key(char* key, char* hashed_key); +int hash_key(char* key, char* hashedKey, int length, bool isConvertNeeded); #endif //SGXD_DRIVE_KEY_DKG_H diff --git a/secure_enclave/DKGUtils.cpp b/secure_enclave/DKGUtils.cpp index aeb5e5fb..45512a8a 100644 --- a/secure_enclave/DKGUtils.cpp +++ b/secure_enclave/DKGUtils.cpp @@ -136,6 +136,56 @@ string ConvertG2ToString(const libff::alt_bn128_G2 &elem, int base = 10, const s return result; } +string ConvertG1ToString(const libff::alt_bn128_G1 &elem, int base = 10, const string &delim = ":") { + + string result = ""; + + try { + + result += ConvertToString(elem.X); + result += delim; + result += ConvertToString(elem.Y); + + return result; + + } catch (exception &e) { + LOG_ERROR(e.what()); + return result; + } catch (...) { + LOG_ERROR("Unknown throwable"); + return result; + } + + return result; +} + +libff::alt_bn128_G1 stringToG1(const char* elem) { + string str(elem); + + libff::alt_bn128_G1 result = libff::alt_bn128_G1::zero(); + + try { + int pos = str.find(":", 0); + if (pos == string::npos) + pos = str.length(); + result.X = libff::alt_bn128_Fq(str.substr(0, pos).c_str()); + result.Y = libff::alt_bn128_Fq(str.substr(pos, string::npos).c_str()); + + if ( str.find(":", pos) != string::npos ) + return result; + + return result; + } catch (exception &e) { + LOG_ERROR(e.what()); + return result; + } catch (...) { + LOG_ERROR("Unknown throwable"); + return result; + } + + return result; +} + vector SplitStringToFr(const char *coeffs, const char symbol) { vector result; string str(coeffs); diff --git a/secure_enclave/EnclaveCommon.h b/secure_enclave/EnclaveCommon.h index ae275a9b..38611aaa 100644 --- a/secure_enclave/EnclaveCommon.h +++ b/secure_enclave/EnclaveCommon.h @@ -41,7 +41,7 @@ EXTERNC bool enclave_sign(const char *_keyString, const char* _hashXString, cons EXTERNC int char2int(char _input); -EXTERNC void carray2Hex(const unsigned char *d, int _len, char* _hexArray); +EXTERNC void carray2Hex(const unsigned char *d, int _len, char* _hexArray); EXTERNC bool hex2carray(const char * _hex, uint64_t *_bin_len, uint8_t* _bin ); EXTERNC bool hex2carray2(const char * _hex, uint64_t *_bin_len, diff --git a/secure_enclave/HKDF.c b/secure_enclave/HKDF.c new file mode 100644 index 00000000..a327f059 --- /dev/null +++ b/secure_enclave/HKDF.c @@ -0,0 +1,112 @@ +/* + 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 . + + @file HKDF.c + @author Oleh Nikolaiev + @date 2023 +*/ + +#include +#include +#include +#include +#include +#include + +#ifdef USER_SPACE +#include +#else + +#include <../tgmp-build/include/sgx_tgmp.h> + +#endif + +#include "EnclaveCommon.h" +#include "EnclaveConstants.h" + +int hkdfExtract(char* salt, char* seed, char* prk) { + int ret = -1; + + if (!salt) { + LOG_ERROR("hkdfExtract: null salt"); + return ret; + } + + if (!seed) { + LOG_ERROR("hkdfExtract: null seed"); + return ret; + } + + if (!prk) { + LOG_ERROR("hkdfExtract: null prk"); + return ret; + } + + ret = sgx_hmac_sha256_msg((unsigned char*)salt, ECDSA_BIN_LEN - 1, seed, ECDSA_BIN_LEN, prk, ECDSA_BIN_LEN - 1); + + return ret; +} + +int hkdfExpand(char* prk, char* keyInfo, int length, char* okm) { + int ret = -1; + + if (!prk) { + LOG_ERROR("hkdfExpand: null prk"); + return ret; + } + + if (!keyInfo) { + LOG_ERROR("hkdfExpand: null key_info"); + return ret; + } + + if (!okm) { + LOG_ERROR("hkdfExpand: null okm"); + return ret; + } + + int n = ceil(length / (ECDSA_BIN_LEN - 1)); + + SAFE_CHAR_BUF(t, BUF_LEN); + SAFE_CHAR_BUF(tmp, BUF_LEN); + for (int i = 0; i < n; ++i) { + char hex[4] = "0x01"; + snprintf(hex + 3, 1, "%d", i + 1); + SAFE_CHAR_BUF(toHash, BUF_LEN); + if (i > 0) { + strncat(toHash, tmp, ECDSA_BIN_LEN - 1); + } + strncat(toHash, keyInfo, ECDSA_BIN_LEN - 1); + strncat(toHash, hex, 4); + + ret = sgx_hmac_sha256_msg(prk, ECDSA_BIN_LEN - 1, toHash, ECDSA_BIN_LEN, tmp, ECDSA_BIN_LEN - 1); + if (ret != 0) { + return ret; + } + + for (int j = 0; j < ECDSA_BIN_LEN - 1; ++j) { + t[(ECDSA_BIN_LEN - 1) * i + j] = tmp[j]; + } + } + + for (int i = 0; i < length; ++i) { + okm[i] = t[i]; + } + + return ret; +} diff --git a/secure_enclave/HKDF.h b/secure_enclave/HKDF.h new file mode 100644 index 00000000..9acfc785 --- /dev/null +++ b/secure_enclave/HKDF.h @@ -0,0 +1,31 @@ +/* + 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 . + + @file HKDF.h + @author Oleh Nikolaiev + @date 2023 +*/ + +#ifndef SGX_HKDF_H +#define SGX_HKDF_H + +int hkdfExtract(char* salt, char* seed, char* prk); + +int hkdfExpand(char* prk, char* keyInfo, int length, char* okm); + +#endif // SGX_HKDF_H diff --git a/secure_enclave/Makefile.am b/secure_enclave/Makefile.am index d81e848b..24834ac4 100644 --- a/secure_enclave/Makefile.am +++ b/secure_enclave/Makefile.am @@ -83,7 +83,7 @@ CLEANFILES+= secure_enclave_t.c secure_enclave_t.h secure_enclave_SOURCES = secure_enclave_t.c secure_enclave_t.h \ secure_enclave.c \ - Curves.c NumberTheory.c Point.c Signature.c DHDkg.c AESUtils.c \ + Curves.c NumberTheory.c Point.c Signature.c DHDkg.c HKDF.c AESUtils.c \ DKGUtils.cpp TEUtils.cpp EnclaveCommon.cpp DomainParameters.cpp ../third_party/SCIPR/libff/algebra/curves/alt_bn128/alt_bn128_init.cpp \ ../third_party/SCIPR/libff/algebra/curves/alt_bn128/alt_bn128_g2.cpp \ ../third_party/SCIPR/libff/algebra/curves/alt_bn128/alt_bn128_g1.cpp $(ENCLAVE_KEY) $(ENCLAVE_CONFIG) diff --git a/secure_enclave/secure_enclave.c b/secure_enclave/secure_enclave.c index 78b84a5d..2516b57f 100644 --- a/secure_enclave/secure_enclave.c +++ b/secure_enclave/secure_enclave.c @@ -53,6 +53,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include "Signature.h" #include "Curves.h" #include "DHDkg.h" +#include "HKDF.h" #include "AESUtils.h" #include "TEUtils.h" @@ -913,52 +914,52 @@ void trustedGetEncryptedSecretShare(int *errStatus, char *errString, } void trustedGetEncryptedSecretShareV2(int *errStatus, char *errString, - uint8_t *_encrypted_poly, uint64_t _enc_len, - uint8_t *encrypted_skey, uint64_t *dec_len, - char *result_str, char *s_shareG2, char *pub_keyB, uint8_t _t, uint8_t _n, + uint8_t *_encryptedPoly, uint64_t _encLen, + uint8_t *encryptedSkey, uint64_t *decLen, + char *resultStr, char *secretShareG2, char *pubKeyB, uint8_t _t, uint8_t _n, uint8_t ind) { LOG_INFO(__FUNCTION__); INIT_ERROR_STATE - uint64_t enc_len; + uint64_t encLen; int status; - CHECK_STATE(encrypted_skey); - CHECK_STATE(result_str); - CHECK_STATE(s_shareG2); - CHECK_STATE(pub_keyB); + CHECK_STATE(encryptedSkey); + CHECK_STATE(resultStr); + CHECK_STATE(secretShareG2); + CHECK_STATE(pubKeyB); LOG_DEBUG(__FUNCTION__); - trustedSetEncryptedDkgPoly(&status, errString, _encrypted_poly, _enc_len); + trustedSetEncryptedDkgPoly(&status, errString, _encryptedPoly, _encLen); CHECK_STATUS2("trustedSetEncryptedDkgPoly failed with status %d "); SAFE_CHAR_BUF(skey, BUF_LEN); - SAFE_CHAR_BUF(pub_key_x, BUF_LEN); - SAFE_CHAR_BUF(pub_key_y, BUF_LEN); + SAFE_CHAR_BUF(pubKeyX, BUF_LEN); + SAFE_CHAR_BUF(pubKeyY, BUF_LEN); int is_exportable = 1; - trustedGenerateEcdsaKey(&status, errString, &is_exportable, encrypted_skey, &enc_len, pub_key_x, pub_key_y); + trustedGenerateEcdsaKey(&status, errString, &is_exportable, encryptedSkey, &encLen, pubKeyX, pubKeyY); CHECK_STATUS("trustedGenerateEcdsaKey failed"); uint8_t type = 0; uint8_t exportable = 0; - status = AES_decrypt(encrypted_skey, enc_len, skey, BUF_LEN, &type, &exportable); + status = AES_decrypt(encryptedSkey, encLen, skey, BUF_LEN, &type, &exportable); skey[ECDSA_SKEY_LEN - 1] = 0; CHECK_STATUS2("AES_decrypt failed (in trustedGetEncryptedSecretShareAES) with status %d"); - *dec_len = enc_len; + *decLen = encLen; - SAFE_CHAR_BUF(common_key, BUF_LEN); + SAFE_CHAR_BUF(commonKey, BUF_LEN); - status = gen_session_key(skey, pub_keyB, common_key); + status = gen_session_key(skey, pubKeyB, commonKey); CHECK_STATUS("gen_session_key failed") @@ -967,22 +968,22 @@ void trustedGetEncryptedSecretShareV2(int *errStatus, char *errString, status = calc_secret_share(getThreadLocalDecryptedDkgPoly(), s_share, _t, _n, ind); CHECK_STATUS("calc secret share failed") - status = calc_secret_shareG2(s_share, s_shareG2); + status = calc_secret_shareG2(s_share, secretShareG2); CHECK_STATUS("invalid decr secret share"); - SAFE_CHAR_BUF(derived_key, BUF_LEN); - status = hash_key(common_key, derived_key); + SAFE_CHAR_BUF(derivedKey, BUF_LEN); + status = hash_key(commonKey, derivedKey, ECDSA_BIN_LEN - 1, true); CHECK_STATUS("hash key failed") - derived_key[ECDSA_BIN_LEN - 1] = 0; + derivedKey[ECDSA_BIN_LEN - 1] = 0; SAFE_CHAR_BUF(cypher, BUF_LEN); - status = xor_encrypt_v2(derived_key, s_share, cypher); + status = xor_encrypt_v2(derivedKey, s_share, cypher); CHECK_STATUS("xor_encrypt failed") - strncpy(result_str, cypher, strlen(cypher)); - strncpy(result_str + strlen(cypher), pub_key_x, strlen(pub_key_x)); - strncpy(result_str + strlen(pub_key_x) + strlen(pub_key_y), pub_key_y, strlen(pub_key_y)); + strncpy(resultStr, cypher, strlen(cypher)); + strncpy(resultStr + strlen(cypher), pubKeyX, strlen(pubKeyX)); + strncpy(resultStr + strlen(pubKeyX) + strlen(pubKeyY), pubKeyY, strlen(pubKeyY)); SET_SUCCESS @@ -1075,14 +1076,14 @@ void trustedDkgVerify(int *errStatus, char *errString, const char *public_shares LOG_INFO("SGX call completed"); } -void trustedDkgVerifyV2(int *errStatus, char *errString, const char *public_shares, const char *s_share, - uint8_t *encryptedPrivateKey, uint64_t enc_len, unsigned _t, int _ind, int *result) { +void trustedDkgVerifyV2(int *errStatus, char *errString, const char *publicShares, const char *secretShare, + uint8_t *encryptedPrivateKey, uint64_t encLen, unsigned _t, int _ind, int *result) { LOG_INFO(__FUNCTION__); INIT_ERROR_STATE - CHECK_STATE(public_shares); - CHECK_STATE(s_share); + CHECK_STATE(publicShares); + CHECK_STATE(secretShare); CHECK_STATE(encryptedPrivateKey); SAFE_CHAR_BUF(skey,BUF_LEN); @@ -1093,36 +1094,36 @@ void trustedDkgVerifyV2(int *errStatus, char *errString, const char *public_shar uint8_t type = 0; uint8_t exportable = 0; - int status = AES_decrypt(encryptedPrivateKey, enc_len, skey, BUF_LEN, + int status = AES_decrypt(encryptedPrivateKey, encLen, skey, BUF_LEN, &type, &exportable); CHECK_STATUS2("AES_decrypt failed (in trustedDkgVerifyAES) with status %d"); - SAFE_CHAR_BUF(encr_sshare, BUF_LEN); + SAFE_CHAR_BUF(encrSshare, BUF_LEN); - strncpy(encr_sshare, s_share, ECDSA_SKEY_LEN - 1); + strncpy(encrSshare, secretShare, ECDSA_SKEY_LEN - 1); - SAFE_CHAR_BUF(common_key, BUF_LEN); + SAFE_CHAR_BUF(commonKey, BUF_LEN); - status = session_key_recover(skey, s_share, common_key); + status = session_key_recover(skey, secretShare, commonKey); CHECK_STATUS("session_key_recover failed"); - SAFE_CHAR_BUF(derived_key, BUF_LEN); - status = hash_key(common_key, derived_key); + SAFE_CHAR_BUF(derivedKey, BUF_LEN); + status = hash_key(commonKey, derivedKey, ECDSA_BIN_LEN - 1, true); CHECK_STATUS("hash key failed") - derived_key[ECDSA_BIN_LEN - 1] = 0; + derivedKey[ECDSA_BIN_LEN - 1] = 0; - SAFE_CHAR_BUF(decr_sshare, BUF_LEN); + SAFE_CHAR_BUF(decrSshare, BUF_LEN); - status = xor_decrypt_v2(derived_key, encr_sshare, decr_sshare); + status = xor_decrypt_v2(derivedKey, encrSshare, decrSshare); CHECK_STATUS("xor_decrypt failed") - status = mpz_set_str(s, decr_sshare, 16); + status = mpz_set_str(s, decrSshare, 16); CHECK_STATUS("invalid decr secret share"); - *result = Verification(public_shares, s, _t, _ind); + *result = Verification(publicShares, s, _t, _ind); SET_SUCCESS clean: @@ -1235,17 +1236,17 @@ void trustedCreateBlsKey(int *errStatus, char *errString, const char *s_shares, LOG_INFO("SGX call completed"); } -void trustedCreateBlsKeyV2(int *errStatus, char *errString, const char *s_shares, - uint8_t *encryptedPrivateKey, uint64_t key_len, uint8_t *encr_bls_key, - uint64_t *enc_bls_key_len) { +void trustedCreateBlsKeyV2(int *errStatus, char *errString, const char *secretShares, + uint8_t *encryptedPrivateKey, uint64_t keyLen, uint8_t *encrBlsKey, + uint64_t *encBlsKeyLen) { LOG_INFO(__FUNCTION__); INIT_ERROR_STATE - CHECK_STATE(s_shares); + CHECK_STATE(secretShares); CHECK_STATE(encryptedPrivateKey); - CHECK_STATE(encr_bls_key); + CHECK_STATE(encrBlsKey); SAFE_CHAR_BUF(skey, BUF_LEN); @@ -1257,87 +1258,87 @@ void trustedCreateBlsKeyV2(int *errStatus, char *errString, const char *s_shares mpz_init(q); mpz_set_str(q, "21888242871839275222246405745257275088548364400416034343698204186575808495617", 10); - mpz_t bls_key; - mpz_init(bls_key); + mpz_t blsKey; + mpz_init(blsKey); uint8_t type = 0; uint8_t exportable = 0; - int status = AES_decrypt(encryptedPrivateKey, key_len, skey, BUF_LEN, + int status = AES_decrypt(encryptedPrivateKey, keyLen, skey, BUF_LEN, &type, &exportable); CHECK_STATUS2("aes decrypt failed with status %d"); skey[ECDSA_SKEY_LEN - 1] = 0; - int num_shares = strlen(s_shares) / 192; + int numShares = strlen(secretShares) / 192; - for (int i = 0; i < num_shares; i++) { - SAFE_CHAR_BUF(encr_sshare, 65); - strncpy(encr_sshare, s_shares + 192 * i, 64); - encr_sshare[64] = 0; + for (int i = 0; i < numShares; i++) { + SAFE_CHAR_BUF(encrSecretShare, 65); + strncpy(encrSecretShare, secretShares + 192 * i, 64); + encrSecretShare[64] = 0; - SAFE_CHAR_BUF(s_share, 193); - strncpy(s_share, s_shares + 192 * i, 192); - s_share[192] = 0; + SAFE_CHAR_BUF(secretShare, 193); + strncpy(secretShare, secretShares + 192 * i, 192); + secretShare[192] = 0; - SAFE_CHAR_BUF(common_key, 65); + SAFE_CHAR_BUF(commonKey, 65); - status = session_key_recover(skey, s_share, common_key); + status = session_key_recover(skey, secretShare, commonKey); CHECK_STATUS("session_key_recover failed"); - common_key[64] = 0; + commonKey[64] = 0; - SAFE_CHAR_BUF(derived_key, BUF_LEN); - status = hash_key(common_key, derived_key); + SAFE_CHAR_BUF(derivedKey, BUF_LEN); + status = hash_key(commonKey, derivedKey, ECDSA_BIN_LEN - 1, true); CHECK_STATUS("hash key failed") - derived_key[ECDSA_BIN_LEN - 1] = 0; + derivedKey[ECDSA_BIN_LEN - 1] = 0; - SAFE_CHAR_BUF(decr_sshare, 65); + SAFE_CHAR_BUF(decrSecretShare, 65); - status = xor_decrypt_v2(derived_key, encr_sshare, decr_sshare); + status = xor_decrypt_v2(derivedKey, encrSecretShare, decrSecretShare); CHECK_STATUS("xor_decrypt failed"); - decr_sshare[64] = 0; + decrSecretShare[64] = 0; - mpz_t decr_secret_share; - mpz_init(decr_secret_share); - if (mpz_set_str(decr_secret_share, decr_sshare, 16) == -1) { + mpz_t decryptedSecretShare; + mpz_init(decryptedSecretShare); + if (mpz_set_str(decryptedSecretShare, decrSecretShare, 16) == -1) { *errStatus = 111; snprintf(errString, BUF_LEN, "invalid decrypted secret share"); LOG_ERROR(errString); - mpz_clear(decr_secret_share); + mpz_clear(decryptedSecretShare); goto clean; } - mpz_addmul_ui(sum, decr_secret_share, 1); - mpz_clear(decr_secret_share); + mpz_addmul_ui(sum, decryptedSecretShare, 1); + mpz_clear(decryptedSecretShare); } - mpz_mod(bls_key, sum, q); + mpz_mod(blsKey, sum, q); - SAFE_CHAR_BUF(key_share, BLS_KEY_LENGTH); + SAFE_CHAR_BUF(keyShare, BLS_KEY_LENGTH); - SAFE_CHAR_BUF(arr_skey_str, BUF_LEN); + SAFE_CHAR_BUF(arrSkeyStr, BUF_LEN); - mpz_get_str(arr_skey_str, 16, bls_key); - int n_zeroes = 64 - strlen(arr_skey_str); - for (int i = 0; i < n_zeroes; i++) { - key_share[i] = '0'; + mpz_get_str(arrSkeyStr, 16, blsKey); + int nZeroes = 64 - strlen(arrSkeyStr); + for (int i = 0; i < nZeroes; i++) { + keyShare[i] = '0'; } - strncpy(key_share + n_zeroes, arr_skey_str, 65 - n_zeroes); - key_share[BLS_KEY_LENGTH - 1] = 0; + strncpy(keyShare + nZeroes, arrSkeyStr, 65 - nZeroes); + keyShare[BLS_KEY_LENGTH - 1] = 0; - status = AES_encrypt(key_share, encr_bls_key, BUF_LEN, BLS, NON_EXPORTABLE, enc_bls_key_len); + status = AES_encrypt(keyShare, encrBlsKey, BUF_LEN, BLS, NON_EXPORTABLE, encBlsKeyLen); CHECK_STATUS2("aes encrypt bls private key failed with status %d "); SET_SUCCESS clean: - mpz_clear(bls_key); + mpz_clear(blsKey); mpz_clear(sum); mpz_clear(q); LOG_INFO(__FUNCTION__ ); @@ -1407,3 +1408,127 @@ void trustedGetDecryptionShare( int *errStatus, char* errString, uint8_t* encryp clean: ; } + +void trustedGenerateBLSKey(int *errStatus, char *errString, int *isExportable, + uint8_t *encryptedPrivateKey, uint64_t *encLen) { + LOG_INFO(__FUNCTION__); + INIT_ERROR_STATE + + CHECK_STATE(encryptedPrivateKey); + + RANDOM_CHAR_BUF(randChar, 32); + + mpz_t seed; + mpz_init(seed); + + mpz_import(seed, 32, 1, sizeof(randChar[0]), 0, 0, randChar); + + SAFE_CHAR_BUF(ikm, mpz_sizeinbase(seed, 16) + 2); + + mpz_get_str(ikm, 16, seed); + + mpz_t q; + mpz_init(q); + mpz_set_str(q, "21888242871839275222246405745257275088548364400416034343698204186575808495617", 10); + + mpz_t skey; + mpz_init(skey); + + mpz_set_ui(skey, 0); + + char salt[39] = "424c532d5349472d4b455947454e2d53414c54"; // "BLS-SIG-KEYGEN-SALT" hexademical + + int L = 48; // math.ceil(3*math.ceil(math.log2(q))/16) + char l[2] = "30"; // octet L + + int k = 0; + while (mpz_cmp_ui(skey, 0) == 0) { + SAFE_CHAR_BUF(saltHashed, BUF_LEN); + int len = strnlen(salt, 39); + int status; + if (len > ECDSA_BIN_LEN - 1) + status = hash_key(salt, saltHashed, len, true); + else + status = hash_key(salt, saltHashed, len, false); + CHECK_STATUS("hash key failed") + + SAFE_CHAR_BUF(ikmConcat, BUF_LEN); + strncat(ikmConcat, ikm, ECDSA_BIN_LEN - 1); + ikmConcat[ECDSA_BIN_LEN - 1] = '\0'; + + SAFE_CHAR_BUF(octetStr0, 2); + octetStr0[0] = '0'; + octetStr0[1] = '\0'; + + strncat(ikmConcat, octetStr0, 1); + ikmConcat[ECDSA_BIN_LEN] = '\0'; + + SAFE_CHAR_BUF(prk, BUF_LEN); + status = hkdfExtract(saltHashed, ikmConcat, prk); + CHECK_STATUS("hkdfExtract failed"); + prk[ECDSA_BIN_LEN - 1] = '\0'; + + SAFE_CHAR_BUF(okm, BUF_LEN); + status = hkdfExpand(prk, l, L, okm); + CHECK_STATUS("hkdfExpand failed"); + + SAFE_CHAR_BUF(blsKey, BUF_LEN); + carray2Hex((unsigned char*)okm, ECDSA_BIN_LEN - 1, blsKey); + + if (mpz_set_str(skey, blsKey, 16) == -1) { + *errStatus = 111; + snprintf(errString, BUF_LEN, "error in mpz_set_str"); + LOG_ERROR(errString); + + goto clean; + } + + mpz_mod(skey, skey, q); + + if (mpz_cmp_ui(skey, 0) == 0) { + for (int i = 0; i < ECDSA_BIN_LEN - 1; ++i) { + salt[i] = saltHashed[i]; + } + salt[ECDSA_BIN_LEN - 1] = '\0'; + } + } + + mpz_mod(skey, seed, q); + + SAFE_CHAR_BUF(blsKey, BLS_KEY_LENGTH); + + SAFE_CHAR_BUF(arrSkeyStr, BUF_LEN); + + if (mpz_get_str(arrSkeyStr, 16, skey) == -1) { + *errStatus = 111; + snprintf(errString, BUF_LEN, "error in mpz_get_str"); + LOG_ERROR(errString); + + goto clean; + } + + int nZeroes = 64 - strlen(arrSkeyStr); + for (int i = 0; i < nZeroes; i++) { + blsKey[i] = '0'; + } + strncpy(blsKey + nZeroes, arrSkeyStr, 65 - nZeroes); + blsKey[BLS_KEY_LENGTH - 1] = 0; + + int status; + if (isExportable) { + status = AES_encrypt(blsKey, encryptedPrivateKey, BUF_LEN, BLS, EXPORTABLE, encLen); + } else { + status = AES_encrypt(blsKey, encryptedPrivateKey, BUF_LEN, BLS, NON_EXPORTABLE, encLen); + } + + CHECK_STATUS2("aes encrypt bls private key failed with status %d "); + + SET_SUCCESS + clean: + + mpz_clear(seed); + mpz_clear(skey); + mpz_clear(q); + LOG_INFO(__FUNCTION__ ); + LOG_INFO("SGX call completed"); +} diff --git a/secure_enclave/secure_enclave.edl b/secure_enclave/secure_enclave.edl index 82cf6e64..e802a690 100644 --- a/secure_enclave/secure_enclave.edl +++ b/secure_enclave/secure_enclave.edl @@ -187,7 +187,15 @@ enclave { [in, count = 320] const char* public_decryption_value, uint64_t key_len, [out, count = 320] char* decrption_share); - }; + + public void trustedGenerateBLSKey( + [out] int *errStatus, + [out, count = SMALL_BUF_SIZE] char* errString, + [in, count = 1] int *isExportable, + [out, count = SMALL_BUF_SIZE] uint8_t* encryptedKey, + [out] uint64_t *encLen + ); + }; untrusted { include "gmp.h" diff --git a/sgxwallet_common.h b/sgxwallet_common.h index cbc4bd43..6022e3ec 100644 --- a/sgxwallet_common.h +++ b/sgxwallet_common.h @@ -187,6 +187,10 @@ extern bool autoconfirm; #define INVALID_DECRYPTION_VALUE_FORMAT -114 #define INVALID_KEY_FORMAT -115 #define KEY_ALREADY_REGISTERED -116 +#define POP_PROVE_INVALID_KEY_NAME -117 +#define COULD_NOT_CREATE_POP_PROVE -118 +#define GENERATE_BLS_KEY_INVALID_NAME -119 +#define INVALID_CREATE_BLS_AGGREGATED_KEY -120 #define SGX_ENCLAVE_ERROR -666 diff --git a/stubclient.h b/stubclient.h index 7a5cf703..3b4255c7 100644 --- a/stubclient.h +++ b/stubclient.h @@ -202,6 +202,17 @@ class StubClient : public jsonrpc::Client throw jsonrpc::JsonRpcException(jsonrpc::Errors::ERROR_CLIENT_INVALID_RESPONSE, result.toStyledString()); } + Json::Value generateBLSPrivateKey(const std::string& blsKeyName) { + Json::Value p; + p["blsKeyName"] = blsKeyName; + + Json::Value result = this->CallMethod("generateBLSPrivateKey", p); + if (result.isObject()) + return result; + else + throw jsonrpc::JsonRpcException(jsonrpc::Errors::ERROR_CLIENT_INVALID_RESPONSE, result.toStyledString()); + } + Json::Value getBLSPublicKeyShare(const std::string & blsKeyName) { Json::Value p; @@ -248,13 +259,24 @@ class StubClient : public jsonrpc::Client p["t"] = t; p["n"] = n; p["ind"] = ind; - Json::Value result = this->CallMethod("complaintResponse",p); + Json::Value result = this->CallMethod("complaintResponse", p); if (result.isObject()) return result; else throw jsonrpc::JsonRpcException(jsonrpc::Errors::ERROR_CLIENT_INVALID_RESPONSE, result.toStyledString()); } + Json::Value popProve(const std::string& blsKeyName) { + Json::Value p; + p["blsKeyName"] = blsKeyName; + + Json::Value result = this->CallMethod("popProve", p); + if (result.isObject()) + return result; + else + throw jsonrpc::JsonRpcException(jsonrpc::Errors::ERROR_CLIENT_INVALID_RESPONSE, result.toStyledString()); + } + Json::Value multG2(const std::string & x) { Json::Value p; diff --git a/testw.cpp b/testw.cpp index 7f240561..fc4ed289 100644 --- a/testw.cpp +++ b/testw.cpp @@ -359,7 +359,7 @@ TEST_CASE_METHOD(TestFixture, "DKG AES public shares test", "[dkg-aes-pub-shares REQUIRE(status == SGX_SUCCESS); REQUIRE(errStatus == SGX_SUCCESS); - signatures::Dkg dkgObj(t, n); + libBLS::Dkg dkgObj(t, n); vector poly = TestUtils::splitStringToFr(secret.data(), colon); vector pubSharesDkg = dkgObj.VerificationVector(poly); @@ -947,7 +947,7 @@ TEST_CASE_METHOD(TestFixture, "AES_DKG V2 test", "[aes-dkg-v2]") { shared_ptr commonSig = sigShareSet.merge(); BLSPublicKey common_public(make_shared < map < size_t, shared_ptr < BLSPublicKeyShare >>>(coeffs_pkeys_map), t, n); - REQUIRE(common_public.VerifySigWithHelper(hash_arr, commonSig, t, n)); + REQUIRE(common_public.VerifySigWithHelper(hash_arr, commonSig)); } TEST_CASE_METHOD(TestFixture, "AES_DKG V2 ZMQ test", "[aes-dkg-v2-zmq]") { @@ -1097,7 +1097,7 @@ TEST_CASE_METHOD(TestFixture, "AES_DKG V2 ZMQ test", "[aes-dkg-v2-zmq]") { shared_ptr commonSig = sigShareSet.merge(); BLSPublicKey common_public(make_shared < map < size_t, shared_ptr < BLSPublicKeyShare >>>(coeffs_pkeys_map), t, n); - REQUIRE(common_public.VerifySigWithHelper(hash_arr, commonSig, t, n)); + REQUIRE(common_public.VerifySigWithHelper(hash_arr, commonSig)); } TEST_CASE_METHOD(TestFixture, "AES encrypt/decrypt", "[aes-encrypt-decrypt]") { @@ -1338,6 +1338,149 @@ TEST_CASE_METHOD(TestFixture, "Test decryption share for threshold encryption vi REQUIRE( share2 == key * decryption_value2 ); } +TEST_CASE_METHOD(TestFixture, "Test generated bls key decrypt", "[bls-aggregated-key-decrypt]") { + vector errMsg(BUF_LEN, 0); + int errStatus = 0; + + int exportable = 1; + + uint64_t encBlsLen = 0; + + sgx_status_t status = SGX_SUCCESS; + + SAFE_UINT8_BUF(encrBlsKey, BUF_LEN) + + status = trustedGenerateBLSKey(eid, &errStatus, errMsg.data(), &exportable, encrBlsKey, &encBlsLen); + + REQUIRE(status == 0); + REQUIRE(errStatus == 0); + + vector decrKey(BUF_LEN, 0); + status = trustedDecryptKey(eid, &errStatus, errMsg.data(), encrBlsKey, encBlsLen, decrKey.data()); + + REQUIRE(status == 0); + REQUIRE(errStatus == 0); + + mpz_t blsKey; + mpz_init(blsKey); + REQUIRE(mpz_set_str(blsKey, decrKey.data(), 16) == 0); + + mpz_t q; + mpz_init(q); + mpz_set_str(q, "21888242871839275222246405745257275088548364400416034343698204186575808495617", 10); + + REQUIRE(mpz_cmp_ui(blsKey, 0) > 0); + REQUIRE(mpz_cmp(blsKey, q) < 0); + + SAFE_UINT8_BUF(encrBlsKeySecond, BUF_LEN) + + status = trustedGenerateBLSKey(eid, &errStatus, errMsg.data(), &exportable, encrBlsKeySecond, &encBlsLen); + + vector decrKeySecond(BUF_LEN, 0); + status = trustedDecryptKey(eid, &errStatus, errMsg.data(), encrBlsKeySecond, encBlsLen, decrKeySecond.data()); + + mpz_t blsKeySecond; + mpz_init(blsKeySecond); + mpz_set_str(blsKeySecond, decrKeySecond.data(), 16); + + REQUIRE( mpz_cmp(blsKey, blsKeySecond) != 0); +} + +TEST_CASE_METHOD(TestFixture, "Test key generation for bls aggregated signatures scheme", "[bls-aggregated-key-generation]") { + HttpClient htp(RPC_ENDPOINT); + StubClient c(htp, JSONRPC_CLIENT_V2); + + std::string name = "BLS_KEY:SCHAIN_ID:123456789:NODE_ID:0:DKG_ID:0"; + auto response = c.generateBLSPrivateKey(name); + + REQUIRE( response["status"] == 0 ); +} + +TEST_CASE_METHOD(TestFixture, "Test key generation for bls aggregated signatures scheme via zmq", "[bls-aggregated-key-generation-zmq]") { + auto client = make_shared(ZMQ_IP, ZMQ_PORT, true, "./sgx_data/cert_data/rootCA.pem", + "./sgx_data/cert_data/rootCA.key"); + + std::string name = "BLS_KEY:SCHAIN_ID:123456789:NODE_ID:0:DKG_ID:0"; + + REQUIRE( client->generateBLSPrivateKey(name) ); +} + +TEST_CASE_METHOD(TestFixture, "Test message signing for bls aggregated signatures scheme", "[bls-aggregated-signing]") { + HttpClient htp(RPC_ENDPOINT); + StubClient c(htp, JSONRPC_CLIENT_V2); + + std::string name = "BLS_KEY:SCHAIN_ID:123456789:NODE_ID:0:DKG_ID:0"; + auto response = c.generateBLSPrivateKey(name); + REQUIRE( response["status"] == 0 ); + + string hash = SAMPLE_HASH; + response = c.blsSignMessageHash(name, hash, 1, 1); + REQUIRE( response["status"] == 0 ); +} + +TEST_CASE_METHOD(TestFixture, "Test message signing for bls aggregated signatures scheme via zmq", "[bls-aggregated-signing-zmq]") { + auto client = make_shared(ZMQ_IP, ZMQ_PORT, true, "./sgx_data/cert_data/rootCA.pem", + "./sgx_data/cert_data/rootCA.key"); + + std::string name = "BLS_KEY:SCHAIN_ID:123456789:NODE_ID:0:DKG_ID:0"; + REQUIRE( client->generateBLSPrivateKey(name) ); + + string hash = SAMPLE_HASH; + string signature = client->blsSignMessageHash(name, hash, 1, 1); + REQUIRE( !signature.empty() ); +} + +TEST_CASE_METHOD(TestFixture, "Test pop prove for bls aggregated signatures scheme", "[bls-aggregated-pop-prove]") { + HttpClient htp(RPC_ENDPOINT); + StubClient c(htp, JSONRPC_CLIENT_V2); + + std::string name = "BLS_KEY:SCHAIN_ID:123456789:NODE_ID:0:DKG_ID:0"; + + libff::alt_bn128_Fr key = libff::alt_bn128_Fr::random_element(); + while (key == libff::alt_bn128_Fr::zero()) { + key = libff::alt_bn128_Fr::random_element(); + } + + std::string keyStr = TestUtils::stringFromFr(key, 16); + auto response = c.importBLSKeyShare(keyStr, name); + REQUIRE(response["status"] == 0); + + libff::alt_bn128_G1 popProveLocal = libBLS::Bls::PopProve(key); + + response = c.popProve(name); + REQUIRE(response["status"] == 0); + shared_ptr sigSharePtr = make_shared(response["popProve"].asString()); + BLSSigShare sig(sigSharePtr, 1, 1, 1); + libff::alt_bn128_G1 popProveEnclave = *sig.getSigShare(); + + REQUIRE( popProveLocal == popProveEnclave ); +} + +TEST_CASE_METHOD(TestFixture, "Test pop prove for bls aggregated signatures scheme via zmq", "[bls-aggregated-pop-prove-zmq]") { + auto client = make_shared(ZMQ_IP, ZMQ_PORT, true, "./sgx_data/cert_data/rootCA.pem", + "./sgx_data/cert_data/rootCA.key"); + + std::string name = "BLS_KEY:SCHAIN_ID:123456789:NODE_ID:0:DKG_ID:0"; + + libff::alt_bn128_Fr key = libff::alt_bn128_Fr::random_element(); + while (key == libff::alt_bn128_Fr::zero()) { + key = libff::alt_bn128_Fr::random_element(); + } + + std::string keyStr = TestUtils::stringFromFr(key, 16); + auto response = client->importBLSKeyShare(keyStr, name); + REQUIRE(response); + + libff::alt_bn128_G1 popProveLocal = libBLS::Bls::PopProve(key); + + std::string pop_prove_response = client->popProve(name); + shared_ptr sigSharePtr = make_shared(pop_prove_response); + BLSSigShare sig(sigSharePtr, 1, 1, 1); + libff::alt_bn128_G1 popProveEnclave = *sig.getSigShare(); + + REQUIRE( popProveLocal == popProveEnclave ); +} + TEST_CASE_METHOD(TestFixtureZMQSign, "ZMQ-ecdsa", "[zmq-ecdsa]") { HttpClient htp(RPC_ENDPOINT); StubClient c(htp, JSONRPC_CLIENT_V2); diff --git a/testw.py b/testw.py index ed4e8c62..82b27186 100755 --- a/testw.py +++ b/testw.py @@ -64,7 +64,14 @@ "[aes-dkg-v2]", "[aes-dkg-v2-zmq]", "[te-decryption-share]", - "[te-decryption-share-zmq]" + "[te-decryption-share-zmq]", + "[bls-aggregated-key-decrypt]", + "[bls-aggregated-key-generation]", + "[bls-aggregated-key-generation-zmq]", + "[bls-aggregated-signing]", + "[bls-aggregated-signing-zmq]", + "[bls-aggregated-pop-prove]", + "[bls-aggregated-pop-prove-zmq]" ] diff --git a/zmq_src/ReqMessage.cpp b/zmq_src/ReqMessage.cpp index c174dd19..1d11c810 100644 --- a/zmq_src/ReqMessage.cpp +++ b/zmq_src/ReqMessage.cpp @@ -273,3 +273,26 @@ Json::Value GetDecryptionShareReqMessage::process() { result["type"] = ZMQMessage::GET_DECRYPTION_SHARE_RSP; return result; } + +Json::Value generateBLSPrivateKeyReqMessage::process() { + auto blsKeyName = getStringRapid("blsKeyName"); + auto result = SGXWalletServer::generateBLSPrivateKeyImpl(blsKeyName); + if (checkKeyOwnership && result["status"] == 0) { + auto cert = getStringRapid("cert"); + spdlog::info("Cert {} creates key {}", cert, blsKeyName); + addKeyByOwner(blsKeyName, cert); + } + result["type"] = ZMQMessage::GENERATE_BLS_PRIVATE_KEY_RSP; + return result; +} + + +Json::Value popProveReqMessage::process() { + auto blsKeyName = getStringRapid("blsKeyName"); + if (checkKeyOwnership && !isKeyByOwner(blsKeyName, getStringRapid("cert"))) { + throw std::invalid_argument("Only owner of the key can access it"); + } + auto result = SGXWalletServer::popProveImpl(blsKeyName); + result["type"] = ZMQMessage::POP_PROVE_RSP; + return result; +} diff --git a/zmq_src/ReqMessage.h b/zmq_src/ReqMessage.h index cb1815fc..cdff18d7 100644 --- a/zmq_src/ReqMessage.h +++ b/zmq_src/ReqMessage.h @@ -185,4 +185,18 @@ class GetDecryptionShareReqMessage : public ZMQMessage { virtual Json::Value process(); }; +class generateBLSPrivateKeyReqMessage : public ZMQMessage { +public: + generateBLSPrivateKeyReqMessage(shared_ptr& _d) : ZMQMessage(_d) {}; + + virtual Json::Value process(); +}; + +class popProveReqMessage : public ZMQMessage { +public: + popProveReqMessage(shared_ptr& _d) : ZMQMessage(_d) {}; + + virtual Json::Value process(); +}; + #endif //SGXWALLET_REQMESSAGE_H diff --git a/zmq_src/RspMessage.cpp b/zmq_src/RspMessage.cpp index 61840678..2cd108dc 100644 --- a/zmq_src/RspMessage.cpp +++ b/zmq_src/RspMessage.cpp @@ -114,3 +114,11 @@ Json::Value deleteBLSKeyRspMessage::process() { Json::Value GetDecryptionShareRspMessage::process() { assert(false); } + +Json::Value generateBLSPrivateKeyRspMessage::process() { + assert(false); +} + +Json::Value popProveRspMessage::process() { + assert(false); +} diff --git a/zmq_src/RspMessage.h b/zmq_src/RspMessage.h index 2d2c6c84..628a4862 100644 --- a/zmq_src/RspMessage.h +++ b/zmq_src/RspMessage.h @@ -259,4 +259,22 @@ class GetDecryptionShareRspMessage : public ZMQMessage { } }; +class generateBLSPrivateKeyRspMessage : public ZMQMessage { +public: + generateBLSPrivateKeyRspMessage(shared_ptr& _d) : ZMQMessage(_d) {}; + + virtual Json::Value process(); +}; + +class popProveRspMessage : public ZMQMessage { +public: + popProveRspMessage(shared_ptr& _d) : ZMQMessage(_d) {}; + + virtual Json::Value process(); + + std::string getPopProve() { + return getStringRapid("popProve"); + } +}; + #endif //SGXWALLET_RSPMESSAGE_H diff --git a/zmq_src/ZMQClient.cpp b/zmq_src/ZMQClient.cpp index 40ab3c3b..530a58cb 100644 --- a/zmq_src/ZMQClient.cpp +++ b/zmq_src/ZMQClient.cpp @@ -39,7 +39,6 @@ shared_ptr ZMQClient::doRequestReply(Json::Value &_req) { - Json::FastWriter fastWriter; if (sign) { @@ -62,7 +61,6 @@ shared_ptr ZMQClient::doRequestReply(Json::Value &_req) { auto resultStr = doZmqRequestReply(reqStr); try { - CHECK_STATE(resultStr.size() > 5) CHECK_STATE(resultStr.front() == '{') CHECK_STATE(resultStr.back() == '}') @@ -78,7 +76,6 @@ shared_ptr ZMQClient::doRequestReply(Json::Value &_req) { } string ZMQClient::doZmqRequestReply(string &_req) { - stringstream request; shared_ptr clientSocket = nullptr; @@ -126,7 +123,6 @@ string ZMQClient::readFileIntoString(const string &_fileName) { } void ZMQClient::verifySig(EVP_PKEY* _pubkey, const string& _str, const string& _sig) { - CHECK_STATE(_pubkey); CHECK_STATE(!_str.empty()); @@ -162,7 +158,6 @@ void ZMQClient::verifySig(EVP_PKEY* _pubkey, const string& _str, const string& _ } string ZMQClient::signString(EVP_PKEY* _pkey, const string& _str) { - CHECK_STATE(_pkey); CHECK_STATE(!_str.empty()); @@ -201,7 +196,6 @@ string ZMQClient::signString(EVP_PKEY* _pkey, const string& _str) { } pair ZMQClient::readPublicKeyFromCertStr(const string& _certStr) { - CHECK_STATE(!_certStr.empty()) BIO *bo = BIO_new(BIO_s_mem()); @@ -220,7 +214,6 @@ pair ZMQClient::readPublicKeyFromCertStr(const string& _certSt ZMQClient::ZMQClient(const string &ip, uint16_t port, bool _sign, const string &_certFileName, const string &_certKeyName) : ctx(1), sign(_sign), certKeyName(_certKeyName), certFileName(_certFileName) { - spdlog::info("Initing ZMQClient. Sign:{} ", _sign); if (sign) { @@ -507,6 +500,25 @@ Json::Value ZMQClient::getDecryptionShares(const string& blsKeyName, const Json: return result->getShare(); } +bool ZMQClient::generateBLSPrivateKey(const string& blsKeyName) { + Json::Value p; + p["blsKeyName"] = blsKeyName; + p["type"] = ZMQMessage::GENERATE_BLS_PRIVATE_KEY_REQ; + auto result = dynamic_pointer_cast(doRequestReply(p)); + CHECK_STATE(result); + return result->getStatus() == 0; +} + +std::string ZMQClient::popProve(const string& blsKeyName) { + Json::Value p; + p["blsKeyName"] = blsKeyName; + p["type"] = ZMQMessage::POP_PROVE_REQ; + auto result = dynamic_pointer_cast(doRequestReply(p)); + CHECK_STATE(result); + CHECK_STATE(result->getStatus() == 0); + return result->getPopProve(); +} + uint64_t ZMQClient::getProcessID() { return syscall(__NR_gettid); } diff --git a/zmq_src/ZMQClient.h b/zmq_src/ZMQClient.h index e06223d2..28b936ab 100644 --- a/zmq_src/ZMQClient.h +++ b/zmq_src/ZMQClient.h @@ -76,7 +76,7 @@ class ZMQClient { void reconnect(); - static pair readPublicKeyFromCertStr(const string& _cert); + static pair readPublicKeyFromCertStr(const string& _cert); static string signString(EVP_PKEY* _pkey, const string& _str); @@ -105,6 +105,10 @@ class ZMQClient { bool createBLSPrivateKey(const string& blsKeyName, const string& ethKeyName, const string& polyName, const string& secretShare, int t, int n); + + string popProve(const string& blsKeyName); + + bool generateBLSPrivateKey(const string& blsKeyName); Json::Value getBLSPublicKey(const string& blsKeyName); diff --git a/zmq_src/ZMQMessage.cpp b/zmq_src/ZMQMessage.cpp index 82fb8c00..6ff3891a 100644 --- a/zmq_src/ZMQMessage.cpp +++ b/zmq_src/ZMQMessage.cpp @@ -77,7 +77,6 @@ string ZMQMessage::getStringRapid(const char *_name) { shared_ptr ZMQMessage::parse(const char *_msg, size_t _size, bool _isRequest, bool _verifySig, bool _checkKeyOwnership) { - CHECK_STATE(_msg); CHECK_STATE2(_size > 5, ZMQ_INVALID_MESSAGE_SIZE); // CHECK NULL TERMINATED @@ -230,6 +229,12 @@ shared_ptr ZMQMessage::buildRequest(string &_type, shared_ptr (_d); break; + case ENUM_GENERATE_BLS_PRIVATE_KEY_REQ: + ret = make_shared(_d); + break; + case ENUM_POP_PROVE_REQ: + ret = make_shared(_d); + break; default: break; } @@ -314,6 +319,12 @@ shared_ptr ZMQMessage::buildResponse(string &_type, shared_ptr (_d); break; + case ENUM_GENERATE_BLS_PRIVATE_KEY_RSP: + ret = make_shared(_d); + break; + case ENUM_POP_PROVE_RSP: + ret = make_shared(_d); + break; default: break; } @@ -347,7 +358,8 @@ const std::map ZMQMessage::requests{ {CREATE_BLS_PRIVATE_REQ, 10}, {GET_BLS_PUBLIC_REQ, 11}, {GET_ALL_BLS_PUBLIC_REQ, 12}, {COMPLAINT_RESPONSE_REQ, 13}, {MULT_G2_REQ, 14}, {IS_POLY_EXISTS_REQ, 15}, {GET_SERVER_STATUS_REQ, 16}, {GET_SERVER_VERSION_REQ, 17}, {DELETE_BLS_KEY_REQ, 18}, - {GET_DECRYPTION_SHARE_REQ, 19} + {GET_DECRYPTION_SHARE_REQ, 19}, {GENERATE_BLS_PRIVATE_KEY_REQ, 20}, + {POP_PROVE_REQ, 21} }; const std::map ZMQMessage::responses { @@ -357,5 +369,6 @@ const std::map ZMQMessage::responses { {CREATE_BLS_PRIVATE_RSP, 10}, {GET_BLS_PUBLIC_RSP, 11}, {GET_ALL_BLS_PUBLIC_RSP, 12}, {COMPLAINT_RESPONSE_RSP, 13}, {MULT_G2_RSP, 14}, {IS_POLY_EXISTS_RSP, 15}, {GET_SERVER_STATUS_RSP, 16}, {GET_SERVER_VERSION_RSP, 17}, {DELETE_BLS_KEY_RSP, 18}, - {GET_DECRYPTION_SHARE_RSP, 19} + {GET_DECRYPTION_SHARE_RSP, 19}, {GENERATE_BLS_PRIVATE_KEY_RSP, 20}, + {POP_PROVE_RSP, 21} }; diff --git a/zmq_src/ZMQMessage.h b/zmq_src/ZMQMessage.h index 45051634..552bb188 100644 --- a/zmq_src/ZMQMessage.h +++ b/zmq_src/ZMQMessage.h @@ -101,6 +101,10 @@ class ZMQMessage { static constexpr const char *DELETE_BLS_KEY_RSP = "deleteBLSKeyRsp"; static constexpr const char *GET_DECRYPTION_SHARE_REQ = "getDecryptionShareReq"; static constexpr const char *GET_DECRYPTION_SHARE_RSP = "getDecryptionShareRsp"; + static constexpr const char *GENERATE_BLS_PRIVATE_KEY_REQ = "generateBLSPrivateKeyReq"; + static constexpr const char *GENERATE_BLS_PRIVATE_KEY_RSP = "generateBLSPrivateKeyRsp"; + static constexpr const char *POP_PROVE_REQ = "popProveReq"; + static constexpr const char *POP_PROVE_RSP = "popProveRsp"; static const std::map requests; static const std::map responses; @@ -108,11 +112,13 @@ class ZMQMessage { enum Requests { ENUM_BLS_SIGN_REQ, ENUM_ECDSA_SIGN_REQ, ENUM_IMPORT_BLS_REQ, ENUM_IMPORT_ECDSA_REQ, ENUM_GENERATE_ECDSA_REQ, ENUM_GET_PUBLIC_ECDSA_REQ, ENUM_GENERATE_DKG_POLY_REQ, ENUM_GET_VV_REQ, ENUM_GET_SECRET_SHARE_REQ, ENUM_DKG_VERIFY_REQ, ENUM_CREATE_BLS_PRIVATE_REQ, ENUM_GET_BLS_PUBLIC_REQ, ENUM_GET_ALL_BLS_PUBLIC_REQ, ENUM_COMPLAINT_RESPONSE_REQ, ENUM_MULT_G2_REQ, ENUM_IS_POLY_EXISTS_REQ, - ENUM_GET_SERVER_STATUS_REQ, ENUM_GET_SERVER_VERSION_REQ, ENUM_DELETE_BLS_KEY_REQ, ENUM_GET_DECRYPTION_SHARE_REQ }; + ENUM_GET_SERVER_STATUS_REQ, ENUM_GET_SERVER_VERSION_REQ, ENUM_DELETE_BLS_KEY_REQ, ENUM_GET_DECRYPTION_SHARE_REQ, + ENUM_GENERATE_BLS_PRIVATE_KEY_REQ, ENUM_POP_PROVE_REQ }; enum Responses { ENUM_BLS_SIGN_RSP, ENUM_ECDSA_SIGN_RSP, ENUM_IMPORT_BLS_RSP, ENUM_IMPORT_ECDSA_RSP, ENUM_GENERATE_ECDSA_RSP, ENUM_GET_PUBLIC_ECDSA_RSP, ENUM_GENERATE_DKG_POLY_RSP, ENUM_GET_VV_RSP, ENUM_GET_SECRET_SHARE_RSP, ENUM_DKG_VERIFY_RSP, ENUM_CREATE_BLS_PRIVATE_RSP, ENUM_GET_BLS_PUBLIC_RSP, ENUM_GET_ALL_BLS_PUBLIC_RSP, ENUM_COMPLAINT_RESPONSE_RSP, ENUM_MULT_G2_RSP, ENUM_IS_POLY_EXISTS_RSP, - ENUM_GET_SERVER_STATUS_RSP, ENUM_GET_SERVER_VERSION_RSP, ENUM_DELETE_BLS_KEY_RSP, ENUM_GET_DECRYPTION_SHARE_RSP }; + ENUM_GET_SERVER_STATUS_RSP, ENUM_GET_SERVER_VERSION_RSP, ENUM_DELETE_BLS_KEY_RSP, ENUM_GET_DECRYPTION_SHARE_RSP, + ENUM_GENERATE_BLS_PRIVATE_KEY_RSP, ENUM_POP_PROVE_RSP }; explicit ZMQMessage(shared_ptr &_d) : d(_d) {};