Unverified Commit bede0e8e authored by kladko's avatar kladko

SKALE-2341 Added tags for older commits

parent 6e432708
...@@ -327,8 +327,8 @@ char* encryptBLSKeyShare2Hex(int *errStatus, char *err_string, const char *_key) ...@@ -327,8 +327,8 @@ char* encryptBLSKeyShare2Hex(int *errStatus, char *err_string, const char *_key)
status = encrypt_key_aes(eid, errStatus, errMsg->data(), keyArray->data(), encryptedKey->data(), &encryptedLen); status = encrypt_key_aes(eid, errStatus, errMsg->data(), keyArray->data(), encryptedKey->data(), &encryptedLen);
if (printDebugInfo) { if (printDebugInfo) {
spdlog::info("errStatus is {}",*errStatus); spdlog::debug("errStatus is {}",*errStatus);
spdlog::info(" errMsg is ", errMsg->data() ); spdlog::debug(" errMsg is ", errMsg->data() );
} }
if (status != SGX_SUCCESS) { if (status != SGX_SUCCESS) {
......
...@@ -92,8 +92,8 @@ string gen_dkg_poly( int _t){ ...@@ -92,8 +92,8 @@ string gen_dkg_poly( int _t){
} }
if (printDebugInfo) { if (printDebugInfo) {
spdlog::info("gen_dkg_secret, status {}", err_status, " err msg ", errMsg.data()); spdlog::debug("gen_dkg_secret, status {}", err_status, " err msg ", errMsg.data());
spdlog::info("in DKGCrypto encr len is {}", enc_len); spdlog::debug("in DKGCrypto encr len is {}", enc_len);
} }
uint64_t length = DKG_MAX_SEALED_LEN; uint64_t length = DKG_MAX_SEALED_LEN;
...@@ -120,7 +120,7 @@ vector <vector<string>> get_verif_vect(const char* encryptedPolyHex, int t, int ...@@ -120,7 +120,7 @@ vector <vector<string>> get_verif_vect(const char* encryptedPolyHex, int t, int
if (printDebugInfo) { if (printDebugInfo) {
// cerr << "got encr poly " << encryptedPolyHex << endl; // cerr << "got encr poly " << encryptedPolyHex << endl;
spdlog::info("got encr poly size {}", char_traits<char>::length(encryptedPolyHex)); spdlog::debug("got encr poly size {}", char_traits<char>::length(encryptedPolyHex));
} }
char* public_shares = (char*)calloc(10000, 1); char* public_shares = (char*)calloc(10000, 1);
...@@ -139,8 +139,8 @@ vector <vector<string>> get_verif_vect(const char* encryptedPolyHex, int t, int ...@@ -139,8 +139,8 @@ vector <vector<string>> get_verif_vect(const char* encryptedPolyHex, int t, int
if (printDebugInfo) { if (printDebugInfo) {
//cerr << "hex_encr_poly is " << encryptedPolyHex << std::endl; //cerr << "hex_encr_poly is " << encryptedPolyHex << std::endl;
spdlog::info("hex_encr_poly length is {}", strlen(encryptedPolyHex)); spdlog::debug("hex_encr_poly length is {}", strlen(encryptedPolyHex));
spdlog::info("enc len {}", enc_len); spdlog::debug("enc len {}", enc_len);
// cerr << "encr raw poly: " << endl; // cerr << "encr raw poly: " << endl;
// for ( int i = 0 ; i < 3050; i++) // for ( int i = 0 ; i < 3050; i++)
// printf(" %d ", encr_dkg_poly[i] ); // printf(" %d ", encr_dkg_poly[i] );
...@@ -159,13 +159,13 @@ vector <vector<string>> get_verif_vect(const char* encryptedPolyHex, int t, int ...@@ -159,13 +159,13 @@ vector <vector<string>> get_verif_vect(const char* encryptedPolyHex, int t, int
} }
if (printDebugInfo) { if (printDebugInfo) {
spdlog::info("err msg is {}", errMsg1); spdlog::debug("err msg is {}", errMsg1);
spdlog::info("public_shares:"); spdlog::debug("public_shares:");
spdlog::info("{}", public_shares); spdlog::debug("{}", public_shares);
// cerr << "public_shares:" << endl; // cerr << "public_shares:" << endl;
// cerr << public_shares << endl; // cerr << public_shares << endl;
spdlog::info("get_public_shares status: {}", err_status); spdlog::debug("get_public_shares status: {}", err_status);
//printf("\nget_public_shares status: %d error %s \n\n", err_status, errMsg1); //printf("\nget_public_shares status: %d error %s \n\n", err_status, errMsg1);
} }
...@@ -227,7 +227,7 @@ string get_secret_shares(const string& polyName, const char* encryptedPolyHex, c ...@@ -227,7 +227,7 @@ string get_secret_shares(const string& polyName, const char* encryptedPolyHex, c
strncpy(pubKeyB, pub_keyB.c_str(), 128); strncpy(pubKeyB, pub_keyB.c_str(), 128);
pubKeyB[128] = 0; pubKeyB[128] = 0;
if (printDebugInfo) { if (printDebugInfo) {
spdlog::info("pubKeyB is {}", pub_keyB); spdlog::debug("pubKeyB is {}", pub_keyB);
} }
if (!encryptKeys) if (!encryptKeys)
...@@ -240,14 +240,14 @@ string get_secret_shares(const string& polyName, const char* encryptedPolyHex, c ...@@ -240,14 +240,14 @@ string get_secret_shares(const string& polyName, const char* encryptedPolyHex, c
throw RPCException(-666, errMsg1); throw RPCException(-666, errMsg1);
} }
if (printDebugInfo) { if (printDebugInfo) {
spdlog::info("cur_share is {}", cur_share); spdlog::debug("cur_share is {}", cur_share);
} }
result += cur_share; result += cur_share;
//uint32_t enc_len = BUF_LEN; //uint32_t enc_len = BUF_LEN;
if (printDebugInfo) { if (printDebugInfo) {
spdlog::info("dec len is {}", dec_len); spdlog::debug("dec len is {}", dec_len);
} }
...@@ -261,14 +261,14 @@ string get_secret_shares(const string& polyName, const char* encryptedPolyHex, c ...@@ -261,14 +261,14 @@ string get_secret_shares(const string& polyName, const char* encryptedPolyHex, c
string shareG2_name = "shareG2_" + polyName + "_" + to_string(i) + ":"; string shareG2_name = "shareG2_" + polyName + "_" + to_string(i) + ":";
if (printDebugInfo) { if (printDebugInfo) {
spdlog::info("name to write to db is {}", dhKeyName); spdlog::debug("name to write to db is {}", dhKeyName);
spdlog::info("name to write to db is {}", shareG2_name); spdlog::debug("name to write to db is {}", shareG2_name);
spdlog::info("s_shareG2: {}", s_shareG2); spdlog::debug("s_shareG2: {}", s_shareG2);
} }
SGXWalletServer::writeDataToDB(shareG2_name, s_shareG2); SGXWalletServer::writeDataToDB(shareG2_name, s_shareG2);
if (printDebugInfo) { if (printDebugInfo) {
spdlog::info("errMsg: {}", errMsg1); spdlog::debug("errMsg: {}", errMsg1);
// cerr << "iteration " << i <<" result length is " << result.length() << endl ; // cerr << "iteration " << i <<" result length is " << result.length() << endl ;
// cerr << "iteration " << i <<" share length is " << strlen(cur_share) << endl; // cerr << "iteration " << i <<" share length is " << strlen(cur_share) << endl;
// cerr << "iteration " << i <<" share is " << cur_share << endl; // cerr << "iteration " << i <<" share is " << cur_share << endl;
...@@ -300,7 +300,7 @@ bool VerifyShares(const char* publicShares, const char* encr_sshare, const char ...@@ -300,7 +300,7 @@ bool VerifyShares(const char* publicShares, const char* encr_sshare, const char
cerr << "dec_key_len " << dec_key_len << endl; cerr << "dec_key_len " << dec_key_len << endl;
cerr << "encr_sshare length is " << strlen(encr_sshare) << endl; cerr << "encr_sshare length is " << strlen(encr_sshare) << endl;
//cerr << "public shares " << publicShares << endl; //cerr << "public shares " << publicShares << endl;
spdlog::info("publicShares length is {}", char_traits<char>::length(publicShares)); spdlog::debug("publicShares length is {}", char_traits<char>::length(publicShares));
} }
char pshares[8193]; char pshares[8193];
memset(pshares, 0, 8193); memset(pshares, 0, 8193);
...@@ -317,8 +317,8 @@ bool VerifyShares(const char* publicShares, const char* encr_sshare, const char ...@@ -317,8 +317,8 @@ bool VerifyShares(const char* publicShares, const char* encr_sshare, const char
} }
if (printDebugInfo) { if (printDebugInfo) {
spdlog::info("errMsg1: {}", errMsg1); spdlog::debug("errMsg1: {}", errMsg1);
spdlog::info("result is: {}", result); spdlog::debug("result is: {}", result);
} }
//free(errMsg1); //free(errMsg1);
...@@ -328,7 +328,7 @@ bool VerifyShares(const char* publicShares, const char* encr_sshare, const char ...@@ -328,7 +328,7 @@ bool VerifyShares(const char* publicShares, const char* encr_sshare, const char
bool CreateBLSShare( const string& blsKeyName, const char * s_shares, const char * encryptedKeyHex){ bool CreateBLSShare( const string& blsKeyName, const char * s_shares, const char * encryptedKeyHex){
if (printDebugInfo) { if (printDebugInfo) {
spdlog::info("ENTER CreateBLSShare"); spdlog::debug("ENTER CreateBLSShare");
} }
// char* errMsg1 = (char*) calloc(1024,1); // char* errMsg1 = (char*) calloc(1024,1);
char errMsg1[BUF_LEN]; char errMsg1[BUF_LEN];
...@@ -367,8 +367,8 @@ bool CreateBLSShare( const string& blsKeyName, const char * s_shares, const char ...@@ -367,8 +367,8 @@ bool CreateBLSShare( const string& blsKeyName, const char * s_shares, const char
// cerr << "BEFORE WRITE BLS KEY TO DB" << endl; // cerr << "BEFORE WRITE BLS KEY TO DB" << endl;
SGXWalletServer::writeDataToDB(blsKeyName, hexBLSKey); SGXWalletServer::writeDataToDB(blsKeyName, hexBLSKey);
if (printDebugInfo) { if (printDebugInfo) {
spdlog::info("hexBLSKey length is {}", char_traits<char>::length(hexBLSKey)); spdlog::debug("hexBLSKey length is {}", char_traits<char>::length(hexBLSKey));
spdlog::info("bls key {}", blsKeyName, " is ", hexBLSKey ); spdlog::debug("bls key {}", blsKeyName, " is ", hexBLSKey );
} }
//free(hexBLSKey); //free(hexBLSKey);
return true; return true;
...@@ -390,7 +390,7 @@ vector<string> GetBLSPubKey(const char * encryptedKeyHex){ ...@@ -390,7 +390,7 @@ vector<string> GetBLSPubKey(const char * encryptedKeyHex){
char pub_key[320]; char pub_key[320];
if (printDebugInfo) { if (printDebugInfo) {
spdlog::info("dec_key_len is {}", dec_key_len); spdlog::debug("dec_key_len is {}", dec_key_len);
} }
if (!encryptKeys) if (!encryptKeys)
...@@ -404,10 +404,10 @@ vector<string> GetBLSPubKey(const char * encryptedKeyHex){ ...@@ -404,10 +404,10 @@ vector<string> GetBLSPubKey(const char * encryptedKeyHex){
vector<string> pub_key_vect = SplitString(pub_key, ':'); vector<string> pub_key_vect = SplitString(pub_key, ':');
if (printDebugInfo) { if (printDebugInfo) {
spdlog::info("errMsg1 is {}", errMsg1); spdlog::debug("errMsg1 is {}", errMsg1);
spdlog::info("pub key is "); spdlog::debug("pub key is ");
for (int i = 0; i < 4; i++) for (int i = 0; i < 4; i++)
spdlog::info("{}", pub_key_vect.at(i)); spdlog::debug("{}", pub_key_vect.at(i));
} }
return pub_key_vect; return pub_key_vect;
} }
...@@ -420,7 +420,7 @@ string decrypt_DHKey(const string& polyName, int ind){ ...@@ -420,7 +420,7 @@ string decrypt_DHKey(const string& polyName, int ind){
string DH_key_name = polyName + "_" + to_string(ind) + ":"; string DH_key_name = polyName + "_" + to_string(ind) + ":";
shared_ptr<string> hexEncrKey_ptr = SGXWalletServer::readFromDb(DH_key_name, "DKG_DH_KEY_"); shared_ptr<string> hexEncrKey_ptr = SGXWalletServer::readFromDb(DH_key_name, "DKG_DH_KEY_");
if (printDebugInfo) { if (printDebugInfo) {
spdlog::info("encr DH key is {}", *hexEncrKey_ptr); spdlog::debug("encr DH key is {}", *hexEncrKey_ptr);
} }
vector<char> hexEncrKey(2 * BUF_LEN, 0); vector<char> hexEncrKey(2 * BUF_LEN, 0);
...@@ -431,8 +431,8 @@ string decrypt_DHKey(const string& polyName, int ind){ ...@@ -431,8 +431,8 @@ string decrypt_DHKey(const string& polyName, int ind){
throw RPCException(INVALID_HEX, "Invalid hexEncrKey"); throw RPCException(INVALID_HEX, "Invalid hexEncrKey");
} }
if (printDebugInfo) { if (printDebugInfo) {
spdlog::info("encr DH key length is {}", DH_enc_len); spdlog::debug("encr DH key length is {}", DH_enc_len);
spdlog::info("hex encr DH key length is {}", hexEncrKey_ptr->length()); spdlog::debug("hex encr DH key length is {}", hexEncrKey_ptr->length());
} }
char DHKey[ECDSA_SKEY_LEN]; char DHKey[ECDSA_SKEY_LEN];
......
This diff is collapsed.
...@@ -35,11 +35,13 @@ ...@@ -35,11 +35,13 @@
#define EXTERNC #define EXTERNC
#endif*/ #endif*/
std::vector<std::string> gen_ecdsa_key(); using namespace std;
std::string get_ecdsa_pubkey(const char* encryptedKeyHex); vector<string> genECDSAKey();
std::vector<std::string> ecdsa_sign_hash(const char* encryptedKeyHex, const char* hashHex, int base); string getECDSAPubKey(const char* _encryptedKeyHex);
vector<string> ecdsaSignHash(const char* encryptedKeyHex, const char* hashHex, int base);
#endif //SGXD_ECDSACRYPTO_H #endif //SGXD_ECDSACRYPTO_H
...@@ -63,7 +63,7 @@ std::shared_ptr<string> LevelDB::readString(const string &_key) { ...@@ -63,7 +63,7 @@ std::shared_ptr<string> LevelDB::readString(const string &_key) {
auto status = db->Get(readOptions, _key, &*result); auto status = db->Get(readOptions, _key, &*result);
if (printDebugInfo) { if (printDebugInfo) {
spdlog::info("key to read from db: {}",_key ); spdlog::debug("key to read from db: {}",_key );
//std::cerr << "key to read from db: " << _key << std::endl; //std::cerr << "key to read from db: " << _key << std::endl;
} }
...@@ -84,7 +84,7 @@ void LevelDB::writeString(const string &_key, const string &_value) { ...@@ -84,7 +84,7 @@ void LevelDB::writeString(const string &_key, const string &_value) {
throwExceptionOnError(status); throwExceptionOnError(status);
if (printDebugInfo) { if (printDebugInfo) {
spdlog::info("written key: {}",_key ); spdlog::debug("written key: {}",_key );
// std::cerr << "written key " << _key << std::endl; // std::cerr << "written key " << _key << std::endl;
} }
} }
...@@ -101,7 +101,7 @@ void LevelDB::deleteDHDKGKey (const string &_key) { ...@@ -101,7 +101,7 @@ void LevelDB::deleteDHDKGKey (const string &_key) {
throwExceptionOnError(status); throwExceptionOnError(status);
if (printDebugInfo) { if (printDebugInfo) {
spdlog::info("key deleted: {}",full_key ); spdlog::debug("key deleted: {}",full_key );
//std::cerr << "key deleted " << full_key << std::endl; //std::cerr << "key deleted " << full_key << std::endl;
} }
} }
...@@ -131,7 +131,7 @@ void LevelDB::deleteKey(const string &_key){ ...@@ -131,7 +131,7 @@ void LevelDB::deleteKey(const string &_key){
throwExceptionOnError(status); throwExceptionOnError(status);
if (printDebugInfo) { if (printDebugInfo) {
spdlog::info("key deleted: {}",_key ); spdlog::debug("key deleted: {}",_key );
// std::cerr << "key deleted " << _key << std::endl; // std::cerr << "key deleted " << _key << std::endl;
} }
} }
...@@ -213,14 +213,14 @@ void LevelDB::writeDataUnique(const string & Name, const string &value) { ...@@ -213,14 +213,14 @@ void LevelDB::writeDataUnique(const string & Name, const string &value) {
auto key = Name; auto key = Name;
if (readString(Name) != nullptr) { if (readString(Name) != nullptr) {
spdlog::info("name {}",Name, " already exists"); spdlog::debug("name {}",Name, " already exists");
// std::cerr << "name " << Name << " already exists" << std::endl; // std::cerr << "name " << Name << " already exists" << std::endl;
throw RPCException(KEY_SHARE_ALREADY_EXISTS, "Data with this name already exists"); throw RPCException(KEY_SHARE_ALREADY_EXISTS, "Data with this name already exists");
} }
writeString(key, value); writeString(key, value);
if (printDebugInfo) { if (printDebugInfo) {
spdlog::info("{}",Name, " is written to db"); spdlog::debug("{}",Name, " is written to db");
//std::cerr << Name << " is written to db " << std::endl; //std::cerr << Name << " is written to db " << std::endl;
} }
} }
......
...@@ -227,7 +227,7 @@ void enter_SEK(){ ...@@ -227,7 +227,7 @@ void enter_SEK(){
void init_SEK(){ void init_SEK(){
std::shared_ptr<std::string> encr_SEK_ptr = LevelDB::getLevelDb()->readString("SEK"); std::shared_ptr<std::string> encr_SEK_ptr = LevelDB::getLevelDb()->readString("SEK");
if (encr_SEK_ptr == nullptr){ if (encr_SEK_ptr == nullptr){
spdlog::info("SEK was not created yet. Going to create SEK"); spdlog::error("SEK was not created yet. Going to create SEK");
gen_SEK(); gen_SEK();
} }
else{ else{
......
...@@ -252,12 +252,11 @@ Json::Value SGXWalletServer::generateECDSAKeyImpl() { ...@@ -252,12 +252,11 @@ Json::Value SGXWalletServer::generateECDSAKeyImpl() {
result["errorMessage"] = ""; result["errorMessage"] = "";
result["encryptedKey"] = ""; result["encryptedKey"] = "";
spdlog::info("Calling method generateECDSAKey");
vector<string> keys; vector<string> keys;
try { try {
keys = gen_ecdsa_key(); keys = genECDSAKey();
if (keys.size() == 0) { if (keys.size() == 0) {
throw RPCException(UNKNOWN_ERROR, "key was not generated"); throw RPCException(UNKNOWN_ERROR, "key was not generated");
...@@ -351,7 +350,7 @@ Json::Value SGXWalletServer::ecdsaSignMessageHashImpl(int _base, const string &_ ...@@ -351,7 +350,7 @@ Json::Value SGXWalletServer::ecdsaSignMessageHashImpl(int _base, const string &_
shared_ptr<string> key_ptr = readFromDb(_keyName, ""); shared_ptr<string> key_ptr = readFromDb(_keyName, "");
sign_vect = ecdsa_sign_hash(key_ptr->c_str(), cutHash.c_str(), _base); sign_vect = ecdsaSignHash(key_ptr->c_str(), cutHash.c_str(), _base);
if (sign_vect.size() != 3) { if (sign_vect.size() != 3) {
throw RPCException(INVALID_ECSDA_SIGNATURE, "Invalid ecdsa signature"); throw RPCException(INVALID_ECSDA_SIGNATURE, "Invalid ecdsa signature");
} }
...@@ -384,7 +383,7 @@ Json::Value SGXWalletServer::getPublicECDSAKeyImpl(const string &_keyName) { ...@@ -384,7 +383,7 @@ Json::Value SGXWalletServer::getPublicECDSAKeyImpl(const string &_keyName) {
throw RPCException(INVALID_ECDSA_KEY_NAME, "Invalid ECDSA key name"); throw RPCException(INVALID_ECDSA_KEY_NAME, "Invalid ECDSA key name");
} }
shared_ptr<string> keyStr = readFromDb(_keyName); shared_ptr<string> keyStr = readFromDb(_keyName);
publicKey = get_ecdsa_pubkey(keyStr->c_str()); publicKey = getECDSAPubKey(keyStr->c_str());
spdlog::debug("PublicKey {}", publicKey); spdlog::debug("PublicKey {}", publicKey);
spdlog::debug("PublicKey length {}", publicKey.length()); spdlog::debug("PublicKey length {}", publicKey.length());
......
...@@ -78,7 +78,7 @@ void initEnclave() { ...@@ -78,7 +78,7 @@ void initEnclave() {
#endif #endif
if (printDebugInfo) { if (printDebugInfo) {
spdlog::info("SGX_DEBUG_FLAG = {}", SGX_DEBUG_FLAG); spdlog::debug("SGX_DEBUG_FLAG = {}", SGX_DEBUG_FLAG);
} }
status = sgx_create_enclave_search(ENCLAVE_NAME, SGX_DEBUG_FLAG, &token, status = sgx_create_enclave_search(ENCLAVE_NAME, SGX_DEBUG_FLAG, &token,
...@@ -95,7 +95,7 @@ void initEnclave() { ...@@ -95,7 +95,7 @@ void initEnclave() {
exit(1); exit(1);
} }
spdlog::error("Enclave created and started successfully"); spdlog::info("Enclave created and started successfully");
status = tgmp_init(eid); status = tgmp_init(eid);
if (status != SGX_SUCCESS) { if (status != SGX_SUCCESS) {
......
...@@ -68,7 +68,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ...@@ -68,7 +68,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include "stubclient.h" #include "stubclient.h"
#include <jsonrpccpp/client/connectors/httpclient.h> #include <jsonrpccpp/client/connectors/httpclient.h>
default_random_engine rand_gen((unsigned int) time(0)); default_random_engine randGen((unsigned int) time(0));
string stringFromFr(libff::alt_bn128_Fr &el) { string stringFromFr(libff::alt_bn128_Fr &el) {
...@@ -572,8 +572,8 @@ TEST_CASE("BLS_DKG test", "[bls_dkg]") { ...@@ -572,8 +572,8 @@ TEST_CASE("BLS_DKG test", "[bls_dkg]") {
vector<string> pubShares(n); vector<string> pubShares(n);
vector<string> poly_names(n); vector<string> poly_names(n);
int schain_id = rand_gen(); int schain_id = randGen();
int dkg_id = rand_gen(); int dkg_id = randGen();
for (uint8_t i = 0; i < n; i++) { for (uint8_t i = 0; i < n; i++) {
EthKeys[i] = c.generateECDSAKey(); EthKeys[i] = c.generateECDSAKey();
string polyName = string polyName =
...@@ -814,8 +814,8 @@ void SendRPCRequest() { ...@@ -814,8 +814,8 @@ void SendRPCRequest() {
vector<string> pubShares(n); vector<string> pubShares(n);
vector<string> poly_names(n); vector<string> poly_names(n);
int schain_id = rand_gen(); int schain_id = randGen();
int dkg_id = rand_gen(); int dkg_id = randGen();
for (uint8_t i = 0; i < n; i++) { for (uint8_t i = 0; i < n; i++) {
EthKeys[i] = c.generateECDSAKey(); EthKeys[i] = c.generateECDSAKey();
string polyName = string polyName =
...@@ -1093,8 +1093,8 @@ TEST_CASE("AES_DKG test", "[aes_dkg]") { ...@@ -1093,8 +1093,8 @@ TEST_CASE("AES_DKG test", "[aes_dkg]") {
vector<string> pubShares(n); vector<string> pubShares(n);
vector<string> poly_names(n); vector<string> poly_names(n);
int schain_id = rand_gen(); int schain_id = randGen();
int dkg_id = rand_gen(); int dkg_id = randGen();
for (uint8_t i = 0; i < n; i++) { for (uint8_t i = 0; i < n; i++) {
EthKeys[i] = c.generateECDSAKey(); EthKeys[i] = c.generateECDSAKey();
string polyName = string polyName =
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment