/* 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 testw.cpp @author Stan Kladko @date 2020 */ #include <dkg/dkg.h> #include <jsonrpccpp/server/connectors/httpserver.h> #include <libff/algebra/curves/alt_bn128/alt_bn128_pp.hpp> #include <dkg/dkg.h> #include "sgxwallet_common.h" #include "third_party/intel/create_enclave.h" #include "secure_enclave_u.h" #include "secure_enclave/DHDkg.h" #include "third_party/intel/sgx_detect.h" #include <gmp.h> #include <sgx_urts.h> #include <stdio.h> #include <jsonrpccpp/client/connectors/httpclient.h> #include <sgx_tcrypto.h> #include "BLSCrypto.h" #include "CryptoTools.h" #include "ServerInit.h" #include "DKGCrypto.h" #include "SGXException.h" #include "LevelDB.h" #include "SGXWalletServer.hpp" #define CATCH_CONFIG_MAIN #include "catch.hpp" #include "stubclient.h" #include "BLSSigShare.h" #include "BLSSigShareSet.h" #include "BLSPublicKeyShare.h" #include "BLSPublicKey.h" #include "SEKManager.h" #include <thread> #include "common.h" #include "SGXRegistrationServer.h" #include "SGXWalletServer.h" #include "zmq_src/ZMQClient.h" #include "zmq_src/ZMQServer.h" #include "sgxwallet.h" #include "TestUtils.h" #include "testw.h" #define PRINT_SRC_LINE cerr << "Executing line " << to_string(__LINE__) << endl; using namespace jsonrpc; using namespace std; class TestFixture { public: TestFixture() { TestUtils::resetDB(); setOptions(L_INFO, false, true); initAll(L_INFO, false, false, true, false, true); } ~TestFixture() { ZMQServer::exitZMQServer(); TestUtils::destroyEnclave(); } }; class TestFixtureHTTPS { public: TestFixtureHTTPS() { TestUtils::resetDB(); setOptions(L_INFO, true, true); initAll(L_INFO, false, true, true, false, true); } ~TestFixtureHTTPS() { ZMQServer::exitZMQServer(); TestUtils::destroyEnclave(); } }; class TestFixtureZMQSign { public: TestFixtureZMQSign() { TestUtils::resetDB(); setOptions(L_INFO, false, true); initAll(L_INFO, false, true, true, false, false); } ~TestFixtureZMQSign() { ZMQServer::exitZMQServer(); TestUtils::destroyEnclave(); } }; class TestFixtureNoResetFromBackup { public: TestFixtureNoResetFromBackup() { setFullOptions(L_INFO, false, true, true); initAll(L_INFO, false, false, true, false, true); } ~TestFixtureNoResetFromBackup() { sleep(3); ZMQServer::exitZMQServer(); TestUtils::destroyEnclave(); } }; class TestFixtureNoReset { public: TestFixtureNoReset() { setOptions(L_INFO, false, true); initAll(L_INFO, false, false, true, false, true); } ~TestFixtureNoReset() { ZMQServer::exitZMQServer(); TestUtils::destroyEnclave(); } }; TEST_CASE_METHOD(TestFixture, "ECDSA AES keygen and signature test", "[ecdsa-aes-key-sig-gen]") { vector<char> errMsg(BUF_LEN, 0); int errStatus = 0; vector <uint8_t> encrPrivKey(BUF_LEN, 0); vector<char> pubKeyX(BUF_LEN, 0); vector<char> pubKeyY(BUF_LEN, 0); uint64_t encLen = 0; int exportable = 0; PRINT_SRC_LINE auto status = trustedGenerateEcdsaKey(eid, &errStatus, errMsg.data(), &exportable, encrPrivKey.data(), &encLen, pubKeyX.data(), pubKeyY.data()); REQUIRE(status == SGX_SUCCESS); REQUIRE(errStatus == SGX_SUCCESS); string hex = SAMPLE_HEX_HASH; vector<char> signatureR(BUF_LEN, 0); vector<char> signatureS(BUF_LEN, 0); uint8_t signatureV = 0; for (int i = 0; i < 50; i++) { PRINT_SRC_LINE status = trustedEcdsaSign(eid, &errStatus, errMsg.data(), encrPrivKey.data(), encLen, hex.data(), signatureR.data(), signatureS.data(), &signatureV, 16); REQUIRE(status == SGX_SUCCESS); REQUIRE(errStatus == SGX_SUCCESS); } } TEST_CASE_METHOD(TestFixture, "ECDSA AES key gen", "[ecdsa-aes-key-gen]") { vector<char> errMsg(BUF_LEN, 0); int errStatus = 0; vector <uint8_t> encrPrivKey(BUF_LEN, 0); vector<char> pubKeyX(BUF_LEN, 0); vector<char> pubKeyY(BUF_LEN, 0); uint64_t encLen = 0; int exportable = 0; PRINT_SRC_LINE auto status = trustedGenerateEcdsaKey(eid, &errStatus, errMsg.data(), &exportable, encrPrivKey.data(), &encLen, pubKeyX.data(), pubKeyY.data()); REQUIRE(status == SGX_SUCCESS); REQUIRE(errStatus == SGX_SUCCESS); } TEST_CASE_METHOD(TestFixture, "ECDSA AES get public key", "[ecdsa-aes-get-pub-key]") { int errStatus = 0; vector<char> errMsg(BUF_LEN, 0); vector <uint8_t> encPrivKey(BUF_LEN, 0); vector<char> pubKeyX(BUF_LEN, 0); vector<char> pubKeyY(BUF_LEN, 0); uint64_t encLen = 0; int exportable = 0; PRINT_SRC_LINE auto status = trustedGenerateEcdsaKey(eid, &errStatus, errMsg.data(), &exportable, encPrivKey.data(), &encLen, pubKeyX.data(), pubKeyY.data()); REQUIRE(status == SGX_SUCCESS); REQUIRE(errStatus == SGX_SUCCESS); vector<char> receivedPubKeyX(BUF_LEN, 0); vector<char> receivedPubKeyY(BUF_LEN, 0); PRINT_SRC_LINE status = trustedGetPublicEcdsaKey(eid, &errStatus, errMsg.data(), encPrivKey.data(), encLen, receivedPubKeyX.data(), receivedPubKeyY.data()); REQUIRE(status == SGX_SUCCESS); REQUIRE(errStatus == SGX_SUCCESS); } /* Do later TEST_CASE_METHOD("BLS key encrypt/decrypt", "[bls-key-encrypt-decrypt]") { resetDB(); setOptions(false, false, false, true); initAll(0, false, true); //init_enclave(); int errStatus = -1; vector<char> errMsg(BUF_LEN, 0); char *encryptedKey = TestUtils::encryptTestKey(); REQUIRE(encryptedKey != nullptr); char *plaintextKey = decryptBLSKeyShareFromHex(&errStatus, errMsg.data(), encryptedKey); free(encryptedKey); REQUIRE(errStatus == 0); REQUIRE(strcmp(plaintextKey, TEST_BLS_KEY_SHARE) == 0); printf("Decrypt key completed with status: %d %s \n", errStatus, errMsg.data()); printf("Decrypted key len %d\n", (int) strlen(plaintextKey)); printf("Decrypted key: %s\n", plaintextKey); free(plaintextKey); } */ string genECDSAKeyAPI(StubClient &_c) { Json::Value genKey = _c.generateECDSAKey(); CHECK_STATE(genKey["status"].asInt() == 0); auto keyName = genKey["keyName"].asString(); CHECK_STATE(keyName.size() == ECDSA_KEY_NAME_SIZE); return keyName; } TEST_CASE_METHOD(TestFixture, "ECDSA key gen API", "[ecdsa-key-gen-api]") { HttpClient client(RPC_ENDPOINT); StubClient c(client, JSONRPC_CLIENT_V2); for (int i = 0; i <= 20; i++) { try { PRINT_SRC_LINE auto keyName = genECDSAKeyAPI(c); PRINT_SRC_LINE Json::Value sig = c.ecdsaSignMessageHash(16, keyName, SAMPLE_HASH); REQUIRE(sig["status"].asInt() == 0); Json::Value getPubKey = c.getPublicECDSAKey(keyName); REQUIRE(getPubKey["status"].asInt() == 0); } catch (JsonRpcException &e) { cerr << e.what() << endl; throw; } } auto keyName = genECDSAKeyAPI(c); Json::Value sig = c.ecdsaSignMessageHash(10, keyName, SAMPLE_HASH); for (int i = 0; i <= 20; i++) { try { PRINT_SRC_LINE auto keyName = genECDSAKeyAPI(c); PRINT_SRC_LINE Json::Value sig = c.ecdsaSignMessageHash(10, keyName, SAMPLE_HASH); REQUIRE(sig["status"].asInt() == 0); PRINT_SRC_LINE Json::Value getPubKey = c.getPublicECDSAKey(keyName); REQUIRE(getPubKey["status"].asInt() == 0); } catch (JsonRpcException &e) { cerr << e.what() << endl; throw; } } } TEST_CASE_METHOD(TestFixture, "BLS key encrypt", "[bls-key-encrypt]") { auto key = TestUtils::encryptTestKey(); REQUIRE(key); sleep(3); } TEST_CASE_METHOD(TestFixture, "DKG AES gen test", "[dkg-aes-gen]") { vector <uint8_t> encryptedDKGSecret(BUF_LEN, 0); vector<char> errMsg(BUF_LEN, 0); int errStatus = 0; uint64_t encLen = 0; PRINT_SRC_LINE auto status = trustedGenDkgSecret(eid, &errStatus, errMsg.data(), encryptedDKGSecret.data(), &encLen, 32); REQUIRE(status == SGX_SUCCESS); REQUIRE(errStatus == SGX_SUCCESS); vector<char> secret(BUF_LEN, 0); vector<char> errMsg1(BUF_LEN, 0); status = trustedDecryptDkgSecret(eid, &errStatus, errMsg1.data(), encryptedDKGSecret.data(), encLen, (uint8_t *) secret.data()); REQUIRE(status == SGX_SUCCESS); REQUIRE(errStatus == SGX_SUCCESS); sleep(3); } TEST_CASE_METHOD(TestFixture, "DKG AES public shares test", "[dkg-aes-pub-shares]") { vector <uint8_t> encryptedDKGSecret(BUF_LEN, 0); vector<char> errMsg(BUF_LEN, 0); int errStatus = 0; uint64_t encLen = 0; unsigned t = 32, n = 32; PRINT_SRC_LINE auto status = trustedGenDkgSecret(eid, &errStatus, errMsg.data(), encryptedDKGSecret.data(), &encLen, n); REQUIRE(status == SGX_SUCCESS); REQUIRE(errStatus == SGX_SUCCESS); vector<char> errMsg1(BUF_LEN, 0); char colon = ':'; vector<char> pubShares(10000, 0); PRINT_SRC_LINE status = trustedGetPublicShares(eid, &errStatus, errMsg1.data(), encryptedDKGSecret.data(), encLen, pubShares.data(), t); REQUIRE(status == SGX_SUCCESS); REQUIRE(errStatus == SGX_SUCCESS); vector <string> g2Strings = splitString(pubShares.data(), ','); vector <libff::alt_bn128_G2> pubSharesG2; for (u_int64_t i = 0; i < g2Strings.size(); i++) { vector <string> coeffStr = splitString(g2Strings.at(i).c_str(), ':'); pubSharesG2.push_back(TestUtils::vectStringToG2(coeffStr)); } vector<char> secret(BUF_LEN, 0); PRINT_SRC_LINE status = trustedDecryptDkgSecret(eid, &errStatus, errMsg1.data(), encryptedDKGSecret.data(), encLen, (uint8_t *) secret.data()); REQUIRE(status == SGX_SUCCESS); REQUIRE(errStatus == SGX_SUCCESS); signatures::Dkg dkgObj(t, n); vector <libff::alt_bn128_Fr> poly = TestUtils::splitStringToFr(secret.data(), colon); vector <libff::alt_bn128_G2> pubSharesDkg = dkgObj.VerificationVector(poly); for (uint32_t i = 0; i < pubSharesDkg.size(); i++) { libff::alt_bn128_G2 el = pubSharesDkg.at(i); el.to_affine_coordinates(); } REQUIRE(pubSharesG2 == pubSharesDkg); } TEST_CASE_METHOD(TestFixture, "DKG AES encrypted secret shares test", "[dkg-aes-encr-sshares]") { vector<char> errMsg(BUF_LEN, 0); vector<char> result(BUF_LEN, 0); int errStatus = 0; uint64_t encLen = 0; vector <uint8_t> encryptedDKGSecret(BUF_LEN, 0); PRINT_SRC_LINE auto status = trustedGenDkgSecret(eid, &errStatus, errMsg.data(), encryptedDKGSecret.data(), &encLen, 2); REQUIRE(status == SGX_SUCCESS); REQUIRE(errStatus == SGX_SUCCESS); vector <uint8_t> encrPRDHKey(BUF_LEN, 0); string pub_keyB = SAMPLE_PUBLIC_KEY_B; vector<char> s_shareG2(BUF_LEN, 0); PRINT_SRC_LINE status = trustedGetEncryptedSecretShare(eid, &errStatus, errMsg.data(), encryptedDKGSecret.data(), encLen, encrPRDHKey.data(), &encLen, result.data(), s_shareG2.data(), (char *) pub_keyB.data(), 2, 2, 1); REQUIRE(status == SGX_SUCCESS); REQUIRE(errStatus == SGX_SUCCESS); } TEST_CASE_METHOD(TestFixture, "DKG AES encrypted secret shares version 2 test", "[dkg-aes-encr-sshares-v2]") { vector<char> errMsg(BUF_LEN, 0); vector<char> result(BUF_LEN, 0); int errStatus = 0; uint64_t encLen = 0; vector <uint8_t> encryptedDKGSecret(BUF_LEN, 0); PRINT_SRC_LINE auto status = trustedGenDkgSecret(eid, &errStatus, errMsg.data(), encryptedDKGSecret.data(), &encLen, 2); REQUIRE(status == SGX_SUCCESS); REQUIRE(errStatus == SGX_SUCCESS); vector <uint8_t> encrPRDHKey(BUF_LEN, 0); string pub_keyB = SAMPLE_PUBLIC_KEY_B; vector<char> s_shareG2(BUF_LEN, 0); PRINT_SRC_LINE status = trustedGetEncryptedSecretShareV2(eid, &errStatus, errMsg.data(), encryptedDKGSecret.data(), encLen, encrPRDHKey.data(), &encLen, result.data(), s_shareG2.data(), (char *) pub_keyB.data(), 2, 2, 1); REQUIRE(status == SGX_SUCCESS); REQUIRE(errStatus == SGX_SUCCESS); } /* * ( "verification test", "[verify]" ) { char* pubshares = "0d72c21fc5a43452ad5f36699822309149ce6ce2cdce50dafa896e873f1b8ddd12f65a2e9c39c617a1f695f076b33b236b47ed773901fc2762f8b6f63277f5e30d7080be8e98c97f913d1920357f345dc0916c1fcb002b7beb060aa8b6b473a011bfafe9f8a5d8ea4c643ca4101e5119adbef5ae64f8dfb39cd10f1e69e31c591858d7eaca25b4c412fe909ca87ca7aadbf6d97d32d9b984e93d436f13d43ec31f40432cc750a64ac239cad6b8f78c1f1dd37427e4ff8c1cc4fe1c950fcbcec10ebfd79e0c19d0587adafe6db4f3c63ea9a329724a8804b63a9422e6898c0923209e828facf3a073254ec31af4231d999ba04eb5b7d1e0056d742a65b766f2f3"; char *sec_share = "11592366544581417165283270001305852351194685098958224535357729125789505948557"; mpz_t sshare; mpz_init(sshare); mpz_set_str(sshare, "11592366544581417165283270001305852351194685098958224535357729125789505948557", 10); int result = Verification(pubshares, sshare, 2, 0); REQUIRE(result == 1); }*/ TEST_CASE_METHOD(TestFixture, "DKG_BLS test", "[dkg-bls]") { HttpClient client(RPC_ENDPOINT); StubClient c(client, JSONRPC_CLIENT_V2); vector <string> ecdsaKeyNames; vector <string> blsKeyNames; int schainID = TestUtils::randGen(); int dkgID = TestUtils::randGen(); PRINT_SRC_LINE TestUtils::doDKG(c, 4, 1, ecdsaKeyNames, blsKeyNames, schainID, dkgID); REQUIRE(blsKeyNames.size() == 4); schainID = TestUtils::randGen(); dkgID = TestUtils::randGen(); TestUtils::doDKG(c, 16, 5, ecdsaKeyNames, blsKeyNames, schainID, dkgID); } TEST_CASE_METHOD(TestFixture, "DKG_BLS V2 test", "[dkg-bls-v2]") { HttpClient client(RPC_ENDPOINT); StubClient c(client, JSONRPC_CLIENT_V2); vector <string> ecdsaKeyNames; vector <string> blsKeyNames; int schainID = TestUtils::randGen(); int dkgID = TestUtils::randGen(); PRINT_SRC_LINE TestUtils::doDKGV2(c, 4, 1, ecdsaKeyNames, blsKeyNames, schainID, dkgID); REQUIRE(blsKeyNames.size() == 4); schainID = TestUtils::randGen(); dkgID = TestUtils::randGen(); TestUtils::doDKGV2(c, 16, 5, ecdsaKeyNames, blsKeyNames, schainID, dkgID); } TEST_CASE_METHOD(TestFixture, "DKG_BLS ZMQ test", "[dkgblszmq]") { HttpClient client(RPC_ENDPOINT); StubClient c(client, JSONRPC_CLIENT_V2); string ip = ZMQ_IP; string empty = ""; auto zmqClient = make_shared<ZMQClient>(ip, ZMQ_PORT, false, empty, empty); vector <string> ecdsaKeyNames; vector <string> blsKeyNames; int schainID = TestUtils::randGen(); int dkgID = TestUtils::randGen(); PRINT_SRC_LINE TestUtils::doZMQBLS(zmqClient,c, 4, 1, ecdsaKeyNames, blsKeyNames, schainID, dkgID); REQUIRE(blsKeyNames.size() == 4); schainID = TestUtils::randGen(); dkgID = TestUtils::randGen(); TestUtils::doZMQBLS(zmqClient, c, 16, 5, ecdsaKeyNames, blsKeyNames, schainID, dkgID); } TEST_CASE_METHOD(TestFixture, "Delete Bls Key", "[delete-bls-key]") { HttpClient client(RPC_ENDPOINT); StubClient c(client, 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( "6507625568967977077291849236396320012317305261598035438182864059942098934847"); std::string key_str = TestUtils::stringFromFr(key); auto response = c.importBLSKeyShare(key_str, name); REQUIRE(response["status"] != 0); key_str = "0xe632f7fde2c90a073ec43eaa90dca7b82476bf28815450a11191484934b9c3f"; response = c.importBLSKeyShare(key_str, name); REQUIRE(response["status"] == 0); REQUIRE(c.blsSignMessageHash(name, SAMPLE_HASH, 1, 1)["status"] == 0); REQUIRE(c.deleteBlsKey(name)["deleted"] == true); } TEST_CASE_METHOD(TestFixture, "Delete Bls Key Zmq", "[delete-bls-key-zmq]") { auto client = make_shared<ZMQClient>(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( "6507625568967977077291849236396320012317305261598035438182864059942098934847"); std::string key_str = TestUtils::stringFromFr(key); REQUIRE(!client->importBLSKeyShare(key_str, name)); key_str = "0xe632f7fde2c90a073ec43eaa90dca7b82476bf28815450a11191484934b9c3f"; REQUIRE(client->importBLSKeyShare(key_str, name)); REQUIRE_NOTHROW(client->blsSignMessageHash(name, SAMPLE_HASH, 1, 1)); REQUIRE(client->deleteBLSKey(name)); } TEST_CASE_METHOD(TestFixture, "Import ECDSA Key", "[import-ecdsa-key]") { HttpClient client(RPC_ENDPOINT); StubClient c(client, JSONRPC_CLIENT_V2); std::string name = "NEK:abcdef"; auto response = c.importECDSAKey("6507625568967977077291849236396320012317305261598035438182864059942098934847", name); REQUIRE(response["status"] != 0); string key_str = "0xe632f7fde2c90a073ec43eaa90dca7b82476bf28815450a11191484934b9c3f"; response = c.importECDSAKey(key_str, name); REQUIRE(response["status"] == 0); REQUIRE(c.ecdsaSignMessageHash(16, name, SAMPLE_HASH)["status"] == 0); } TEST_CASE_METHOD(TestFixture, "Import ECDSA Key Zmq", "[import-ecdsa-key-zmq]") { auto client = make_shared<ZMQClient>(ZMQ_IP, ZMQ_PORT, true, "./sgx_data/cert_data/rootCA.pem", "./sgx_data/cert_data/rootCA.key"); std::string name = "NEK:abcdef"; REQUIRE_THROWS(client->importECDSAKey("6507625568967977077291849236396320012317305261598035438182864059942098934847", name)); string key_str = "0xe632f7fde2c90a073ec43eaa90dca7b82476bf28815450a11191484934b9c3f"; string response = client->importECDSAKey(key_str, name); REQUIRE(response == client->getECDSAPublicKey(name)); REQUIRE_NOTHROW(client->ecdsaSignMessageHash(16, name, SAMPLE_HASH)); } TEST_CASE_METHOD(TestFixture, "Backup Key", "[backup-key]") { HttpClient client(RPC_ENDPOINT); StubClient c(client, JSONRPC_CLIENT_V2); std::ifstream sek_file("sgx_data/sgxwallet_backup_key.txt"); REQUIRE(sek_file.good()); std::string sek; sek_file >> sek; REQUIRE(sek.size() == 32); sleep(3); } TEST_CASE_METHOD(TestFixture, "Get ServerStatus", "[get-server-status]") { HttpClient client(RPC_ENDPOINT); StubClient c(client, JSONRPC_CLIENT_V2); REQUIRE(c.getServerStatus()["status"] == 0); sleep(3); } TEST_CASE_METHOD(TestFixture, "Get ServerStatusZmq", "[get-server-status-zmq]") { auto client = make_shared<ZMQClient>(ZMQ_IP, ZMQ_PORT, true, "./sgx_data/cert_data/rootCA.pem", "./sgx_data/cert_data/rootCA.key"); REQUIRE_NOTHROW(client->getServerStatus()); sleep(3); } TEST_CASE_METHOD(TestFixture, "Get ServerVersion", "[get-server-version]") { HttpClient client(RPC_ENDPOINT); StubClient c(client, JSONRPC_CLIENT_V2); REQUIRE(c.getServerVersion()["version"] == SGXWalletServer::getVersion()); sleep(3); } TEST_CASE_METHOD(TestFixture, "Get ServerVersionZmq", "[get-server-version-zmq]") { auto client = make_shared<ZMQClient>(ZMQ_IP, ZMQ_PORT, true, "./sgx_data/cert_data/rootCA.pem", "./sgx_data/cert_data/rootCA.key"); REQUIRE(client->getServerVersion() == SGXWalletServer::getVersion()); sleep(3); } TEST_CASE_METHOD(TestFixtureHTTPS, "Cert request sign", "[cert-sign]") { PRINT_SRC_LINE REQUIRE_NOTHROW(SGXRegistrationServer::getServer()); PRINT_SRC_LINE string csrFile = "insecure-samples/yourdomain.csr"; ifstream infile(csrFile); infile.exceptions(std::ifstream::failbit | std::ifstream::badbit); ostringstream ss; ss << infile.rdbuf(); infile.close(); PRINT_SRC_LINE auto result = SGXRegistrationServer::getServer()->SignCertificate(ss.str()); REQUIRE(result["status"] == 0); PRINT_SRC_LINE result = SGXRegistrationServer::getServer()->SignCertificate("Haha"); REQUIRE(result["status"] != 0); } TEST_CASE_METHOD(TestFixture, "DKG API V2 test", "[dkg-api-v2]") { HttpClient client(RPC_ENDPOINT); StubClient c(client, JSONRPC_CLIENT_V2); string polyName = SAMPLE_POLY_NAME; PRINT_SRC_LINE Json::Value genPoly = c.generateDKGPoly(polyName, 2); REQUIRE(genPoly["status"].asInt() == 0); Json::Value publicKeys; publicKeys.append(SAMPLE_DKG_PUB_KEY_1); publicKeys.append(SAMPLE_DKG_PUB_KEY_2); // wrongName Json::Value genPolyWrongName = c.generateDKGPoly("poly", 2); REQUIRE(genPolyWrongName["status"].asInt() != 0); Json::Value verifVectWrongName = c.getVerificationVector("poly", 2); REQUIRE(verifVectWrongName["status"].asInt() != 0); Json::Value secretSharesWrongName = c.getSecretShareV2("poly", publicKeys, 2, 2); REQUIRE(secretSharesWrongName["status"].asInt() != 0); // wrong_t Json::Value genPolyWrong_t = c.generateDKGPoly(polyName, 33); REQUIRE(genPolyWrong_t["status"].asInt() != 0); Json::Value verifVectWrong_t = c.getVerificationVector(polyName, 1); REQUIRE(verifVectWrong_t["status"].asInt() != 0); Json::Value secretSharesWrong_t = c.getSecretShareV2(polyName, publicKeys, 3, 3); REQUIRE(secretSharesWrong_t["status"].asInt() != 0); Json::Value publicKeys1; publicKeys1.append(SAMPLE_DKG_PUB_KEY_1); Json::Value secretSharesWrong_n = c.getSecretShareV2(polyName, publicKeys1, 2, 1); REQUIRE(secretSharesWrong_n["status"].asInt() != 0); //wrong number of publicKeys Json::Value secretSharesWrongPkeys = c.getSecretShareV2(polyName, publicKeys, 2, 3); REQUIRE(secretSharesWrongPkeys["status"].asInt() != 0); //wrong verif Json::Value Skeys = c.getSecretShareV2(polyName, publicKeys, 2, 2); REQUIRE_NOTHROW(c.getSecretShare(polyName, publicKeys, 2, 2)); REQUIRE(Skeys == c.getSecretShare(polyName, publicKeys, 2, 2)); Json::Value verifVect = c.getVerificationVector(polyName, 2); REQUIRE_NOTHROW(c.getVerificationVector(polyName, 2)); REQUIRE(verifVect == c.getVerificationVector(polyName, 2)); Json::Value verificationWrongSkeys = c.dkgVerificationV2("", "", "", 2, 2, 1); REQUIRE(verificationWrongSkeys["status"].asInt() != 0); } TEST_CASE_METHOD(TestFixture, "DKG API V2 ZMQ test", "[dkg-api-v2-zmq]") { auto client = make_shared<ZMQClient>(ZMQ_IP, ZMQ_PORT, true, "./sgx_data/cert_data/rootCA.pem", "./sgx_data/cert_data/rootCA.key"); string polyName = SAMPLE_POLY_NAME; PRINT_SRC_LINE REQUIRE(client->generateDKGPoly(polyName, 2)); Json::Value publicKeys; publicKeys.append(SAMPLE_DKG_PUB_KEY_1); publicKeys.append(SAMPLE_DKG_PUB_KEY_2); // wrongName REQUIRE(!client->generateDKGPoly("poly", 2)); REQUIRE_THROWS(client->getVerificationVector("poly", 2)); REQUIRE_THROWS(client->getSecretShare("poly", publicKeys, 2, 2)); // wrong_t REQUIRE(!client->generateDKGPoly(polyName, 33)); REQUIRE_THROWS(client->getVerificationVector(polyName, 0)); REQUIRE_THROWS(client->getSecretShare(polyName, publicKeys, 3, 3)); Json::Value publicKeys1; publicKeys1.append(SAMPLE_DKG_PUB_KEY_1); REQUIRE_THROWS(client->getSecretShare(polyName, publicKeys1, 2, 1)); //wrong number of publicKeys REQUIRE_THROWS(client->getSecretShare(polyName, publicKeys, 2, 3)); //wrong verif string Skeys = client->getSecretShare(polyName, publicKeys, 2, 2); REQUIRE_NOTHROW(client->getSecretShare(polyName, publicKeys, 2, 2)); REQUIRE(Skeys == client->getSecretShare(polyName, publicKeys, 2, 2)); Json::Value verifVect = client->getVerificationVector(polyName, 2); REQUIRE_NOTHROW(client->getVerificationVector(polyName, 2)); REQUIRE(verifVect == client->getVerificationVector(polyName, 2)); REQUIRE_THROWS(client->dkgVerification("", "", "", 2, 2, 1)); } TEST_CASE_METHOD(TestFixture, "PolyExists test", "[dkg-poly-exists]") { HttpClient client(RPC_ENDPOINT); StubClient c(client, JSONRPC_CLIENT_V2); string polyName = SAMPLE_POLY_NAME; PRINT_SRC_LINE Json::Value genPoly = c.generateDKGPoly(polyName, 2); REQUIRE(genPoly["status"] == 0); PRINT_SRC_LINE Json::Value polyExists = c.isPolyExists(polyName); REQUIRE(polyExists["status"] == 0); REQUIRE(polyExists["IsExist"].asBool()); PRINT_SRC_LINE Json::Value polyDoesNotExist = c.isPolyExists("Vasya"); REQUIRE(!polyDoesNotExist["IsExist"].asBool()); } TEST_CASE_METHOD(TestFixture, "PolyExistsZmq test", "[dkg-poly-exists-zmq]") { auto client = make_shared<ZMQClient>(ZMQ_IP, ZMQ_PORT, true, "./sgx_data/cert_data/rootCA.pem", "./sgx_data/cert_data/rootCA.key"); string polyName = SAMPLE_POLY_NAME; REQUIRE_NOTHROW(client->generateDKGPoly(polyName, 2)); bool polyExists = client->isPolyExists(polyName); REQUIRE(polyExists); bool polyDoesNotExist = client->isPolyExists("Vasya"); REQUIRE(!polyDoesNotExist); } TEST_CASE_METHOD(TestFixture, "AES_DKG V2 test", "[aes-dkg-v2]") { HttpClient client(RPC_ENDPOINT); StubClient c(client, JSONRPC_CLIENT_V2); int n = 2, t = 2; Json::Value ethKeys[n]; Json::Value verifVects[n]; Json::Value pubEthKeys; Json::Value secretShares[n]; Json::Value pubBLSKeys[n]; Json::Value blsSigShares[n]; vector <string> pubShares(n); vector <string> polyNames(n); int schainID = TestUtils::randGen(); int dkgID = TestUtils::randGen(); for (uint8_t i = 0; i < n; i++) { PRINT_SRC_LINE ethKeys[i] = c.generateECDSAKey(); REQUIRE(ethKeys[i]["status"] == 0); string polyName = "POLY:SCHAIN_ID:" + to_string(schainID) + ":NODE_ID:" + to_string(i) + ":DKG_ID:" + to_string(dkgID); REQUIRE(ethKeys[i]["status"] == 0); auto response = c.generateDKGPoly(polyName, t); REQUIRE(response["status"] == 0); polyNames[i] = polyName; PRINT_SRC_LINE verifVects[i] = c.getVerificationVector(polyName, t); REQUIRE(verifVects[i]["status"] == 0); pubEthKeys.append(ethKeys[i]["publicKey"]); } for (uint8_t i = 0; i < n; i++) { PRINT_SRC_LINE secretShares[i] = c.getSecretShareV2(polyNames[i], pubEthKeys, t, n); REQUIRE(secretShares[i]["status"] == 0); for (uint8_t k = 0; k < t; k++) for (uint8_t j = 0; j < 4; j++) { string pubShare = verifVects[i]["verificationVector"][k][j].asString(); pubShares[i] += TestUtils::convertDecToHex(pubShare); } } int k = 0; vector <string> secShares(n); for (int i = 0; i < n; i++) for (int j = 0; j < n; j++) { string secretShare = secretShares[i]["secretShare"].asString().substr(192 * j, 192); secShares[i] += secretShares[j]["secretShare"].asString().substr(192 * i, 192); PRINT_SRC_LINE Json::Value verif = c.dkgVerificationV2(pubShares[i], ethKeys[j]["keyName"].asString(), secretShare, t, n, j); REQUIRE(verif["status"] == 0); bool res = verif["result"].asBool(); k++; REQUIRE(res); } Json::Value complaintResponse = c.complaintResponse(polyNames[1], t, n, 0); REQUIRE(complaintResponse["status"] == 0); string dhKey = complaintResponse["dhKey"].asString(); string shareG2 = complaintResponse["share*G2"].asString(); string secretShare = secretShares[1]["secretShare"].asString().substr(0, 192); vector<char> message(65, 0); SAFE_CHAR_BUF(encr_sshare, BUF_LEN) strncpy(encr_sshare, pubEthKeys[0].asString().c_str(), 128); SAFE_CHAR_BUF(common_key, BUF_LEN); REQUIRE(sessionKeyRecoverDH(dhKey.c_str(), encr_sshare, common_key) == 0); uint8_t key_to_hash[33]; uint64_t len; REQUIRE( hex2carray(common_key, &len, key_to_hash, 64) ); auto hashed_key = cryptlite::sha256::hash_hex(string((char*)key_to_hash, 32)); SAFE_CHAR_BUF(derived_key, 33) uint64_t key_length; REQUIRE(hex2carray(&hashed_key[0], &key_length, (uint8_t *) derived_key, 33)); SAFE_CHAR_BUF(encr_sshare_check, BUF_LEN) strncpy(encr_sshare_check, secretShare.c_str(), ECDSA_SKEY_LEN - 1); REQUIRE(xorDecryptDHV2(derived_key, encr_sshare_check, message) == 0); mpz_t hex_share; mpz_init(hex_share); mpz_set_str(hex_share, message.data(), 16); libff::alt_bn128_Fr share(hex_share); libff::alt_bn128_G2 decrypted_share_G2 = share * libff::alt_bn128_G2::one(); decrypted_share_G2.to_affine_coordinates(); mpz_clear(hex_share); REQUIRE(convertG2ToString(decrypted_share_G2) == shareG2); Json::Value verificationVectorMult = complaintResponse["verificationVectorMult"]; libff::alt_bn128_G2 verificationValue = libff::alt_bn128_G2::zero(); for (int i = 0; i < t; ++i) { libff::alt_bn128_G2 value; value.Z = libff::alt_bn128_Fq2::one(); value.X.c0 = libff::alt_bn128_Fq(verificationVectorMult[i][0].asCString()); value.X.c1 = libff::alt_bn128_Fq(verificationVectorMult[i][1].asCString()); value.Y.c0 = libff::alt_bn128_Fq(verificationVectorMult[i][2].asCString()); value.Y.c1 = libff::alt_bn128_Fq(verificationVectorMult[i][3].asCString()); verificationValue = verificationValue + value; } verificationValue.to_affine_coordinates(); REQUIRE(verificationValue == decrypted_share_G2); BLSSigShareSet sigShareSet(t, n); string hash = SAMPLE_HASH; auto hash_arr = make_shared < array < uint8_t, 32 > > (); uint64_t binLen; if (!hex2carray(hash.c_str(), &binLen, hash_arr->data(), 32)) { throw SGXException(TEST_INVALID_HEX, "Invalid hash"); } map <size_t, shared_ptr<BLSPublicKeyShare>> coeffs_pkeys_map; for (int i = 0; i < t; i++) { string endName = polyNames[i].substr(4); string blsName = "BLS_KEY" + polyNames[i].substr(4); auto response = c.createBLSPrivateKeyV2(blsName, ethKeys[i]["keyName"].asString(), polyNames[i], secShares[i], t, n); REQUIRE(response["status"] == 0); PRINT_SRC_LINE pubBLSKeys[i] = c.getBLSPublicKeyShare(blsName); REQUIRE(pubBLSKeys[i]["status"] == 0); string hash = SAMPLE_HASH; blsSigShares[i] = c.blsSignMessageHash(blsName, hash, t, n); REQUIRE(blsSigShares[i]["status"] == 0); shared_ptr <string> sig_share_ptr = make_shared<string>(blsSigShares[i]["signatureShare"].asString()); BLSSigShare sig(sig_share_ptr, i + 1, t, n); sigShareSet.addSigShare(make_shared<BLSSigShare>(sig)); vector <string> pubKey_vect; for (uint8_t j = 0; j < 4; j++) { pubKey_vect.push_back(pubBLSKeys[i]["blsPublicKeyShare"][j].asString()); } BLSPublicKeyShare pubKey(make_shared < vector < string >> (pubKey_vect), t, n); PRINT_SRC_LINE REQUIRE(pubKey.VerifySigWithHelper(hash_arr, make_shared<BLSSigShare>(sig), t, n)); coeffs_pkeys_map[i + 1] = make_shared<BLSPublicKeyShare>(pubKey); } shared_ptr <BLSSignature> 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)); } TEST_CASE_METHOD(TestFixture, "AES_DKG V2 ZMQ test", "[aes-dkg-v2-zmq]") { auto client = make_shared<ZMQClient>(ZMQ_IP, ZMQ_PORT, true, "./sgx_data/cert_data/rootCA.pem", "./sgx_data/cert_data/rootCA.key"); int n = 2, t = 2; vector<string> ethKeys(n); Json::Value verifVects[n]; Json::Value pubEthKeys; vector<string> secretShares(n); Json::Value pubBLSKeys[n]; vector<string> blsSigShares(n); vector<string> pubShares(n); vector<string> polyNames(n); int schainID = TestUtils::randGen(); int dkgID = TestUtils::randGen(); for (uint8_t i = 0; i < n; i++) { auto generatedKey = client->generateECDSAKey(); ethKeys[i] = generatedKey.second; string polyName = "POLY:SCHAIN_ID:" + to_string(schainID) + ":NODE_ID:" + to_string(i) + ":DKG_ID:" + to_string(dkgID); CHECK_STATE(client->generateDKGPoly(polyName, t)); polyNames[i] = polyName; verifVects[i] = client->getVerificationVector(polyName, t); pubEthKeys.append(generatedKey.first); } for (uint8_t i = 0; i < n; i++) { secretShares[i] = client->getSecretShare(polyNames[i], pubEthKeys, t, n); for (uint8_t k = 0; k < t; k++) { for (uint8_t j = 0; j < 4; j++) { string pubShare = verifVects[i][k][j].asString(); pubShares[i] += TestUtils::convertDecToHex(pubShare); } } } int k = 0; vector <string> secShares(n); for (int i = 0; i < n; i++) for (int j = 0; j < n; j++) { string secretShare = secretShares[i].substr(192 * j, 192); secShares[i] += secretShares[j].substr(192 * i, 192); REQUIRE(client->dkgVerification(pubShares[i], ethKeys[j], secretShare, t, n, j)); k++; } auto complaintResponse = client->complaintResponse(polyNames[1], t, n, 0); string dhKey = std::get<0>(complaintResponse); string shareG2 = std::get<1>(complaintResponse); string secretShare = secretShares[1].substr(0, 192); vector<char> message(65, 0); SAFE_CHAR_BUF(encr_sshare, BUF_LEN) strncpy(encr_sshare, pubEthKeys[0].asString().c_str(), 128); SAFE_CHAR_BUF(common_key, BUF_LEN); REQUIRE(sessionKeyRecoverDH(dhKey.c_str(), encr_sshare, common_key) == 0); uint8_t key_to_hash[33]; uint64_t len; REQUIRE( hex2carray(common_key, &len, key_to_hash, 64) ); auto hashed_key = cryptlite::sha256::hash_hex(string((char*)key_to_hash, 32)); SAFE_CHAR_BUF(derived_key, 33) uint64_t key_length; REQUIRE(hex2carray(&hashed_key[0], &key_length, (uint8_t *) derived_key, 33)); SAFE_CHAR_BUF(encr_sshare_check, BUF_LEN) strncpy(encr_sshare_check, secretShare.c_str(), ECDSA_SKEY_LEN - 1); REQUIRE(xorDecryptDHV2(derived_key, encr_sshare_check, message) == 0); mpz_t hex_share; mpz_init(hex_share); mpz_set_str(hex_share, message.data(), 16); libff::alt_bn128_Fr share(hex_share); libff::alt_bn128_G2 decrypted_share_G2 = share * libff::alt_bn128_G2::one(); decrypted_share_G2.to_affine_coordinates(); mpz_clear(hex_share); REQUIRE(convertG2ToString(decrypted_share_G2) == shareG2); Json::Value verificationVectorMult = std::get<2>(complaintResponse); libff::alt_bn128_G2 verificationValue = libff::alt_bn128_G2::zero(); for (int i = 0; i < t; ++i) { libff::alt_bn128_G2 value; value.Z = libff::alt_bn128_Fq2::one(); value.X.c0 = libff::alt_bn128_Fq(verificationVectorMult[i][0].asCString()); value.X.c1 = libff::alt_bn128_Fq(verificationVectorMult[i][1].asCString()); value.Y.c0 = libff::alt_bn128_Fq(verificationVectorMult[i][2].asCString()); value.Y.c1 = libff::alt_bn128_Fq(verificationVectorMult[i][3].asCString()); verificationValue = verificationValue + value; } verificationValue.to_affine_coordinates(); REQUIRE(verificationValue == decrypted_share_G2); BLSSigShareSet sigShareSet(t, n); string hash = SAMPLE_HASH; auto hash_arr = make_shared < array < uint8_t, 32 > > (); uint64_t binLen; if (!hex2carray(hash.c_str(), &binLen, hash_arr->data(), 32)) { throw SGXException(TEST_INVALID_HEX, "Invalid hash"); } map <size_t, shared_ptr<BLSPublicKeyShare>> coeffs_pkeys_map; for (int i = 0; i < t; i++) { string blsName = "BLS_KEY" + polyNames[i].substr(4); REQUIRE(client->createBLSPrivateKey(blsName, ethKeys[i], polyNames[i], secShares[i], t, n)); pubBLSKeys[i] = client->getBLSPublicKey(blsName); string hash = SAMPLE_HASH; blsSigShares[i] = client->blsSignMessageHash(blsName, hash, t, n); REQUIRE(blsSigShares[i].length() > 0); shared_ptr <string> sig_share_ptr = make_shared<string>(blsSigShares[i]); BLSSigShare sig(sig_share_ptr, i + 1, t, n); sigShareSet.addSigShare(make_shared<BLSSigShare>(sig)); vector <string> pubKey_vect; for (uint8_t j = 0; j < 4; j++) { pubKey_vect.push_back(pubBLSKeys[i][j].asString()); } BLSPublicKeyShare pubKey(make_shared < vector < string >> (pubKey_vect), t, n); REQUIRE(pubKey.VerifySigWithHelper(hash_arr, make_shared<BLSSigShare>(sig), t, n)); coeffs_pkeys_map[i + 1] = make_shared<BLSPublicKeyShare>(pubKey); } shared_ptr <BLSSignature> 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)); } TEST_CASE_METHOD(TestFixture, "AES encrypt/decrypt", "[aes-encrypt-decrypt]") { int errStatus = 0; vector<char> errMsg(BUF_LEN, 0); uint64_t encLen; string key = SAMPLE_AES_KEY; vector <uint8_t> encrypted_key(BUF_LEN, 0); PRINT_SRC_LINE auto status = trustedEncryptKey(eid, &errStatus, errMsg.data(), key.c_str(), encrypted_key.data(), &encLen); REQUIRE(status == 0); REQUIRE(errStatus == 0); vector<char> decr_key(BUF_LEN, 0); PRINT_SRC_LINE status = trustedDecryptKey(eid, &errStatus, errMsg.data(), encrypted_key.data(), encLen, decr_key.data()); REQUIRE(status == 0); REQUIRE(key.compare(decr_key.data()) == 0); REQUIRE(errStatus == 0); sleep(3); } TEST_CASE_METHOD(TestFixture, "Exportable / non-exportable keys", "[exportable-nonexportable-keys]") { int errStatus = 0; vector<char> errMsg(BUF_LEN, 0); vector <uint8_t> encPrivKey(BUF_LEN, 0); vector<char> pubKeyX(BUF_LEN, 0); vector<char> pubKeyY(BUF_LEN, 0); uint64_t encLen = 0; int exportable = 0; auto status = trustedGenerateEcdsaKey(eid, &errStatus, errMsg.data(), &exportable, encPrivKey.data(), &encLen, pubKeyX.data(), pubKeyY.data()); vector<char> decrypted_key(BUF_LEN, 0); status = trustedDecryptKey(eid, &errStatus, errMsg.data(), encPrivKey.data(), encLen, decrypted_key.data()); REQUIRE( errStatus == -11 ); exportable = 1; encPrivKey.clear(); errMsg.clear(); pubKeyX.clear(); pubKeyY.clear(); status = trustedGenerateEcdsaKey(eid, &errStatus, errMsg.data(), &exportable, encPrivKey.data(), &encLen, pubKeyX.data(), pubKeyY.data()); decrypted_key.clear(); status = trustedDecryptKey(eid, &errStatus, errMsg.data(), encPrivKey.data(), encLen, decrypted_key.data()); REQUIRE( errStatus == 0 ); REQUIRE( status == SGX_SUCCESS ); string key = SAMPLE_AES_KEY; vector <uint8_t> encrypted_key(BUF_LEN, 0); status = trustedEncryptKey(eid, &errStatus, errMsg.data(), key.c_str(), encrypted_key.data(), &encLen); REQUIRE(status == 0); REQUIRE(errStatus == 0); vector<char> decr_key(BUF_LEN, 0); PRINT_SRC_LINE status = trustedDecryptKey(eid, &errStatus, errMsg.data(), encrypted_key.data(), encLen, decr_key.data()); REQUIRE(status == 0); REQUIRE(key.compare(decr_key.data()) == 0); REQUIRE(errStatus == 0); sleep(3); } TEST_CASE_METHOD(TestFixture, "Many threads ecdsa dkg v2 bls", "[many-threads-crypto-v2]") { vector <thread> threads; int num_threads = 4; for (int i = 0; i < num_threads; i++) { threads.push_back(thread(TestUtils::sendRPCRequestV2)); } for (auto &thread : threads) { thread.join(); } } TEST_CASE_METHOD(TestFixture, "Many threads ecdsa dkg v2 bls zmq", "[many-threads-crypto-v2-zmq]") { vector <thread> threads; int num_threads = 4; for (int i = 0; i < num_threads; i++) { threads.push_back(thread(TestUtils::sendRPCRequestZMQ)); } for (auto &thread : threads) { thread.join(); } } TEST_CASE_METHOD(TestFixture, "First run", "[first-run]") { HttpClient client(RPC_ENDPOINT); StubClient c(client, JSONRPC_CLIENT_V2); try { PRINT_SRC_LINE auto keyName = genECDSAKeyAPI(c); ofstream namefile("/tmp/keyname"); namefile << keyName; PRINT_SRC_LINE } catch (JsonRpcException &e) { cerr << e.what() << endl; throw; } sleep(3); } TEST_CASE_METHOD(TestFixtureNoReset, "Second run", "[second-run]") { HttpClient client(RPC_ENDPOINT); StubClient c(client, JSONRPC_CLIENT_V2); try { PRINT_SRC_LINE string keyName; ifstream namefile("/tmp/keyname"); getline(namefile, keyName); Json::Value sig = c.ecdsaSignMessageHash(16, keyName, SAMPLE_HASH); REQUIRE(sig["status"].asInt() == 0); Json::Value getPubKey = c.getPublicECDSAKey(keyName); REQUIRE(getPubKey["status"].asInt() == 0); } catch (JsonRpcException &e) { cerr << e.what() << endl; throw; } } TEST_CASE_METHOD(TestFixture, "Test decryption share for threshold encryption", "[te-decryption-share]") { HttpClient client(RPC_ENDPOINT); StubClient c(client, JSONRPC_CLIENT_V2); std::string key_str = "0xe632f7fde2c90a073ec43eaa90dca7b82476bf28815450a11191484934b9c3f"; std::string name = "BLS_KEY:SCHAIN_ID:123456789:NODE_ID:0:DKG_ID:0"; c.importBLSKeyShare(key_str, name); // the same key writtn in decimal libff::alt_bn128_Fr key = libff::alt_bn128_Fr( "6507625568967977077291849236396320012317305261598035438182864059942098934847"); libff::alt_bn128_G2 decryption_value1 = libff::alt_bn128_G2::random_element(); libff::alt_bn128_G2 decryption_value2 = libff::alt_bn128_G2::random_element(); decryption_value1.to_affine_coordinates(); decryption_value2.to_affine_coordinates(); auto decrytion_value_str1 = convertG2ToString( decryption_value1, ':' ); auto decrytion_value_str2 = convertG2ToString( decryption_value2, ':' ); Json::Value publicDecryptionValues; publicDecryptionValues["publicDecryptionValues"][0] = decrytion_value_str1; publicDecryptionValues["publicDecryptionValues"][1] = decrytion_value_str2; auto decryptionShares = c.getDecryptionShares( name, publicDecryptionValues ); auto decryption_share1 = decryptionShares["decryptionShares"][0]; auto decryption_share2 = decryptionShares["decryptionShares"][1]; libff::alt_bn128_G2 share1; share1.Z = libff::alt_bn128_Fq2::one(); share1.X.c0 = libff::alt_bn128_Fq( decryption_share1[0].asCString() ); share1.X.c1 = libff::alt_bn128_Fq( decryption_share1[1].asCString() ); share1.Y.c0 = libff::alt_bn128_Fq( decryption_share1[2].asCString() ); share1.Y.c1 = libff::alt_bn128_Fq( decryption_share1[3].asCString() ); REQUIRE( share1 == key * decryption_value1 ); libff::alt_bn128_G2 share2; share2.Z = libff::alt_bn128_Fq2::one(); share2.X.c0 = libff::alt_bn128_Fq( decryption_share2[0].asCString() ); share2.X.c1 = libff::alt_bn128_Fq( decryption_share2[1].asCString() ); share2.Y.c0 = libff::alt_bn128_Fq( decryption_share2[2].asCString() ); share2.Y.c1 = libff::alt_bn128_Fq( decryption_share2[3].asCString() ); REQUIRE( share2 == key * decryption_value2 ); } TEST_CASE_METHOD(TestFixture, "Test decryption share for threshold encryption via zmq", "[te-decryption-share-zmq]") { auto client = make_shared<ZMQClient>(ZMQ_IP, ZMQ_PORT, true, "./sgx_data/cert_data/rootCA.pem", "./sgx_data/cert_data/rootCA.key"); std::string key_str = "0xe632f7fde2c90a073ec43eaa90dca7b82476bf28815450a11191484934b9c3f"; std::string name = "BLS_KEY:SCHAIN_ID:123456789:NODE_ID:0:DKG_ID:0"; client->importBLSKeyShare(key_str, name); // the same key writtn in decimal libff::alt_bn128_Fr key = libff::alt_bn128_Fr( "6507625568967977077291849236396320012317305261598035438182864059942098934847"); libff::alt_bn128_G2 decryption_value1 = libff::alt_bn128_G2::random_element(); libff::alt_bn128_G2 decryption_value2 = libff::alt_bn128_G2::random_element(); decryption_value1.to_affine_coordinates(); decryption_value2.to_affine_coordinates(); auto decrytion_value_str1 = convertG2ToString( decryption_value1, ':' ); auto decrytion_value_str2 = convertG2ToString( decryption_value2, ':' ); Json::Value publicDecryptionValues; publicDecryptionValues["publicDecryptionValues"][0] = decrytion_value_str1; publicDecryptionValues["publicDecryptionValues"][1] = decrytion_value_str2; auto decryptionShares = client->getDecryptionShares( name, publicDecryptionValues ); auto decryption_share1 = decryptionShares[0]; auto decryption_share2 = decryptionShares[1]; libff::alt_bn128_G2 share1; share1.Z = libff::alt_bn128_Fq2::one(); share1.X.c0 = libff::alt_bn128_Fq( decryption_share1[0].asCString() ); share1.X.c1 = libff::alt_bn128_Fq( decryption_share1[1].asCString() ); share1.Y.c0 = libff::alt_bn128_Fq( decryption_share1[2].asCString() ); share1.Y.c1 = libff::alt_bn128_Fq( decryption_share1[3].asCString() ); REQUIRE( share1 == key * decryption_value1 ); libff::alt_bn128_G2 share2; share2.Z = libff::alt_bn128_Fq2::one(); share2.X.c0 = libff::alt_bn128_Fq( decryption_share2[0].asCString() ); share2.X.c1 = libff::alt_bn128_Fq( decryption_share2[1].asCString() ); share2.Y.c0 = libff::alt_bn128_Fq( decryption_share2[2].asCString() ); share2.Y.c1 = libff::alt_bn128_Fq( decryption_share2[3].asCString() ); REQUIRE( share2 == key * decryption_value2 ); } TEST_CASE_METHOD(TestFixtureZMQSign, "ZMQ-ecdsa", "[zmq-ecdsa]") { HttpClient htp(RPC_ENDPOINT); StubClient c(htp, JSONRPC_CLIENT_V2); auto client = make_shared<ZMQClient>(ZMQ_IP, ZMQ_PORT, true, "./sgx_data/cert_data/rootCA.pem", "./sgx_data/cert_data/rootCA.key"); string keyName = ""; PRINT_SRC_LINE keyName = genECDSAKeyAPI(c); int end = 10000000; string sh = string(SAMPLE_HASH); std::vector <std::thread> workers; PRINT_SRC_LINE for (int j = 0; j < 2; j++) { workers.push_back(std::thread([client, sh, keyName, end, j]() { CHECK_STATE(client); for (int i = (j * 2000); i < (j * 2000) + 1000; i++) { auto hash = sh.substr(0, sh.size() - 8) + to_string(end + i); auto sig = client->ecdsaSignMessageHash(16, keyName, hash); REQUIRE(sig.size() > 10); } })); }; std::for_each(workers.begin(), workers.end(), []( std::thread &t) { t.join(); }); PRINT_SRC_LINE } TEST_CASE_METHOD(TestFixtureNoResetFromBackup, "Backup restore", "[backup-restore]") {}