//subtract Keys (subtracts curve points) //AB = A - B where A, B are curve points void subKeys(key & AB, const key &A, const key &B) { ge_p3 B2, A2; CHECK_AND_ASSERT_THROW_MES(ge_frombytes_vartime(&B2, B.bytes) == 0, "ge_frombytes_vartime failed at "+boost::lexical_cast<std::string>(__LINE__)); CHECK_AND_ASSERT_THROW_MES(ge_frombytes_vartime(&A2, A.bytes) == 0, "ge_frombytes_vartime failed at "+boost::lexical_cast<std::string>(__LINE__)); ge_cached tmp2; ge_p3_to_cached(&tmp2, &B2); ge_p1p1 tmp3; ge_sub(&tmp3, &A2, &tmp2); ge_p1p1_to_p3(&A2, &tmp3); ge_p3_tobytes(AB.bytes, &A2); }
void set_msg_addr(t_message * msg, const boost::optional<std::vector<uint32_t>> & path = boost::none, const boost::optional<cryptonote::network_type> & network_type = boost::none) { CHECK_AND_ASSERT_THROW_MES(msg, "Message is null"); msg->clear_address_n(); if (path){ for(auto x : path.get()){ msg->add_address_n(x); } } else { ensure_derivation_path(); for (unsigned int i : DEFAULT_BIP44_PATH) { msg->add_address_n(i); } for (unsigned int i : m_wallet_deriv_path) { msg->add_address_n(i); } } if (network_type){ msg->set_network_type(static_cast<uint32_t>(network_type.get())); } else { msg->set_network_type(static_cast<uint32_t>(this->network_type)); } }
//does a * P where a is a scalar and P is an arbitrary point void scalarmultKey(key & aP, const key &P, const key &a) { ge_p3 A; ge_p2 R; CHECK_AND_ASSERT_THROW_MES(ge_frombytes_vartime(&A, P.bytes) == 0, "ge_frombytes_vartime failed at "+boost::lexical_cast<std::string>(__LINE__)); ge_scalarmult(&R, a.bytes, &A); ge_tobytes(aP.bytes, &R); }
//addKeys3 //aAbB = a*A + b*B where a, b are scalars, A, B are curve points //B must be input after applying "precomp" void addKeys3(key &aAbB, const key &a, const key &A, const key &b, const ge_dsmp B) { ge_p2 rv; ge_p3 A2; CHECK_AND_ASSERT_THROW_MES(ge_frombytes_vartime(&A2, A.bytes) == 0, "ge_frombytes_vartime failed at "+boost::lexical_cast<std::string>(__LINE__)); ge_double_scalarmult_precomp_vartime(&rv, a.bytes, &A2, b.bytes, B); ge_tobytes(aAbB.bytes, &rv); }
//addKeys2 //aGbB = aG + bB where a, b are scalars, G is the basepoint and B is a point void addKeys2(key &aGbB, const key &a, const key &b, const key & B) { ge_p2 rv; ge_p3 B2; CHECK_AND_ASSERT_THROW_MES(ge_frombytes_vartime(&B2, B.bytes) == 0, "ge_frombytes_vartime failed at "+boost::lexical_cast<std::string>(__LINE__)); ge_double_scalarmult_base_vartime(&rv, b.bytes, &B2, a.bytes); ge_tobytes(aGbB.bytes, &rv); }
//Computes aH where H= toPoint(cn_fast_hash(G)), G the basepoint key scalarmultH(const key & a) { ge_p3 A; ge_p2 R; CHECK_AND_ASSERT_THROW_MES(ge_frombytes_vartime(&A, H.bytes) == 0, "ge_frombytes_vartime failed at "+boost::lexical_cast<std::string>(__LINE__)); ge_scalarmult(&R, a.bytes, &A); key aP; ge_tobytes(aP.bytes, &R); return aP; }
//Generates a vector of secret key //Mainly used in testing keyV skvGen(size_t rows ) { CHECK_AND_ASSERT_THROW_MES(rows > 0, "0 keys requested"); keyV rv(rows); size_t i = 0; for (i = 0 ; i < rows ; i++) { skGen(rv[i]); } return rv; }
//Generates a vector of secret key //Mainly used in testing keyV skvGen(size_t rows ) { CHECK_AND_ASSERT_THROW_MES(rows > 0, "0 keys requested"); keyV rv(rows); size_t i = 0; crypto::rand(rows * sizeof(key), (uint8_t*)&rv[0]); for (i = 0 ; i < rows ; i++) { sc_reduce32(rv[i].bytes); } return rv; }
key hashToPointSimple(const key & hh) { key pointk; ge_p1p1 point2; ge_p2 point; ge_p3 res; key h = cn_fast_hash(hh); CHECK_AND_ASSERT_THROW_MES(ge_frombytes_vartime(&res, h.bytes) == 0, "ge_frombytes_vartime failed at "+boost::lexical_cast<std::string>(__LINE__)); ge_p3_to_p2(&point, &res); ge_mul8(&point2, &point); ge_p1p1_to_p3(&res, &point2); ge_p3_tobytes(pointk.bytes, &res); return pointk; }
// methods: connection_basic::connection_basic(boost::asio::ip::tcp::socket&& socket, boost::shared_ptr<socket_stats> stats) : m_stats(std::move(stats)), mI( new connection_basic_pimpl("peer") ), strand_(socket.get_io_service()), socket_(std::move(socket)), m_want_close_connection(false), m_was_shutdown(false) { // add nullptr checks if removed CHECK_AND_ASSERT_THROW_MES(bool(m_stats), "stats shared_ptr cannot be null"); ++(m_stats->sock_count); // increase the global counter mI->m_peer_number = m_stats->sock_number.fetch_add(1); // use, and increase the generated number std::string remote_addr_str = "?"; try { boost::system::error_code e; remote_addr_str = socket_.remote_endpoint(e).address().to_string(); } catch(...){} ; _note("Spawned connection p2p#"<<mI->m_peer_number<<" to " << remote_addr_str << " currently we have sockets count:" << m_stats->sock_count); }
void threadpool::submit(waiter *obj, std::function<void()> f, bool leaf) { CHECK_AND_ASSERT_THROW_MES(!is_leaf, "A leaf routine is using a thread pool"); boost::unique_lock<boost::mutex> lock(mutex); if (!leaf && ((active == max && !queue.empty()) || depth > 0)) { // if all available threads are already running // and there's work waiting, just run in current thread lock.unlock(); ++depth; is_leaf = leaf; f(); --depth; is_leaf = false; } else { if (obj) obj->inc(); if (leaf) queue.push_front({obj, f, leaf}); else queue.push_back({obj, f, leaf}); has_work.notify_one(); } }
std::shared_ptr<t_message> client_exchange(const std::shared_ptr<const google::protobuf::Message> &req, const boost::optional<messages::MessageType> & resp_type = boost::none, const boost::optional<std::vector<messages::MessageType>> & resp_types = boost::none, const boost::optional<messages::MessageType*> & resp_type_ptr = boost::none, bool open_session = false) { // Require strictly protocol buffers response in the template. BOOST_STATIC_ASSERT(boost::is_base_of<google::protobuf::Message, t_message>::value); const bool accepting_base = boost::is_same<google::protobuf::Message, t_message>::value; if (resp_types && !accepting_base){ throw std::invalid_argument("Cannot specify list of accepted types and not using generic response"); } // Determine type of expected message response const messages::MessageType required_type = accepting_base ? messages::MessageType_Success : (resp_type ? resp_type.get() : MessageMapper::get_message_wire_number<t_message>()); // Open session if required if (open_session){ try { m_transport->open(); } catch (const std::exception& e) { std::throw_with_nested(exc::SessionException("Could not open session")); } } // Scoped session closer BOOST_SCOPE_EXIT_ALL(&, this) { if (open_session){ this->get_transport()->close(); } }; // Write/read the request CHECK_AND_ASSERT_THROW_MES(req, "Request is null"); auto msg_resp = call_raw(req.get()); bool processed = false; do { processed = message_handler(msg_resp); } while(processed); // Response section if (resp_type_ptr){ *(resp_type_ptr.get()) = msg_resp.m_type; } if (msg_resp.m_type == messages::MessageType_Failure) { throw_failure_exception(dynamic_cast<messages::common::Failure *>(msg_resp.m_msg.get())); } else if (!accepting_base && msg_resp.m_type == required_type) { return message_ptr_retype<t_message>(msg_resp.m_msg); } else if (accepting_base && (!resp_types || std::find(resp_types.get().begin(), resp_types.get().end(), msg_resp.m_type) != resp_types.get().end())) { return message_ptr_retype<t_message>(msg_resp.m_msg); } else { throw exc::UnexpectedMessageException(msg_resp.m_type, msg_resp.m_msg); } }
//Does some precomputation to make addKeys3 more efficient // input B a curve point and output a ge_dsmp which has precomputation applied void precomp(ge_dsmp rv, const key & B) { ge_p3 B2; CHECK_AND_ASSERT_THROW_MES(ge_frombytes_vartime(&B2, B.bytes) == 0, "ge_frombytes_vartime failed at "+boost::lexical_cast<std::string>(__LINE__)); ge_dsm_precomp(rv, &B2); }
boost::asio::ssl::context ssl_options_t::create_context() const { boost::asio::ssl::context ssl_context{boost::asio::ssl::context::tlsv12}; if (!bool(*this)) return ssl_context; // only allow tls v1.2 and up ssl_context.set_options(boost::asio::ssl::context::default_workarounds); ssl_context.set_options(boost::asio::ssl::context::no_sslv2); ssl_context.set_options(boost::asio::ssl::context::no_sslv3); ssl_context.set_options(boost::asio::ssl::context::no_tlsv1); ssl_context.set_options(boost::asio::ssl::context::no_tlsv1_1); // only allow a select handful of tls v1.3 and v1.2 ciphers to be used SSL_CTX_set_cipher_list(ssl_context.native_handle(), "ECDHE-ECDSA-CHACHA20-POLY1305-SHA256:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES128-GCM-SHA256"); // set options on the SSL context for added security SSL_CTX *ctx = ssl_context.native_handle(); CHECK_AND_ASSERT_THROW_MES(ctx, "Failed to get SSL context"); SSL_CTX_clear_options(ctx, SSL_OP_LEGACY_SERVER_CONNECT); // SSL_CTX_SET_OPTIONS(3) SSL_CTX_set_session_cache_mode(ctx, SSL_SESS_CACHE_OFF); // https://stackoverflow.com/questions/22378442 #ifdef SSL_OP_NO_TICKET SSL_CTX_set_options(ctx, SSL_OP_NO_TICKET); // https://stackoverflow.com/questions/22378442 #endif #ifdef SSL_OP_NO_RENEGOTIATION SSL_CTX_set_options(ctx, SSL_OP_NO_RENEGOTIATION); #endif #ifdef SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION SSL_CTX_set_options(ctx, SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION); #endif #ifdef SSL_OP_NO_COMPRESSION SSL_CTX_set_options(ctx, SSL_OP_NO_COMPRESSION); #endif #ifdef SSL_OP_CIPHER_SERVER_PREFERENCE SSL_CTX_set_options(ctx, SSL_OP_CIPHER_SERVER_PREFERENCE); #endif SSL_CTX_set_ecdh_auto(ctx, 1); switch (verification) { case ssl_verification_t::system_ca: ssl_context.set_default_verify_paths(); break; case ssl_verification_t::user_certificates: ssl_context.set_verify_depth(0); /* fallthrough */ case ssl_verification_t::user_ca: if (!ca_path.empty()) { const boost::system::error_code err = load_ca_file(ssl_context, ca_path); if (err) throw boost::system::system_error{err, "Failed to load user CA file at " + ca_path}; } break; default: break; } CHECK_AND_ASSERT_THROW_MES(auth.private_key_path.empty() == auth.certificate_path.empty(), "private key and certificate must be either both given or both empty"); if (auth.private_key_path.empty()) { EVP_PKEY *pkey; X509 *cert; bool ok = false; #ifdef USE_EXTRA_EC_CERT CHECK_AND_ASSERT_THROW_MES(create_ec_ssl_certificate(pkey, cert, NID_secp256k1), "Failed to create certificate"); CHECK_AND_ASSERT_THROW_MES(SSL_CTX_use_certificate(ctx, cert), "Failed to use generated certificate"); if (!SSL_CTX_use_PrivateKey(ctx, pkey)) MERROR("Failed to use generated EC private key for " << NID_secp256k1); else ok = true; X509_free(cert); EVP_PKEY_free(pkey); #endif CHECK_AND_ASSERT_THROW_MES(create_rsa_ssl_certificate(pkey, cert), "Failed to create certificate"); CHECK_AND_ASSERT_THROW_MES(SSL_CTX_use_certificate(ctx, cert), "Failed to use generated certificate"); if (!SSL_CTX_use_PrivateKey(ctx, pkey)) MERROR("Failed to use generated RSA private key for RSA"); else ok = true; X509_free(cert); EVP_PKEY_free(pkey); CHECK_AND_ASSERT_THROW_MES(ok, "Failed to use any generated certificate"); } else auth.use_ssl_certificate(ssl_context); return ssl_context; }