#include "node.hpp" #include "logging.hpp" #include "gmpxx.h" #include using namespace boost::asio::ip; Node::Node(ListenSettings const& listen_settings, NodeNetworkSettings network_settings) : io_service() , server(io_service, listen_settings, [this](boost::asio::ip::tcp::socket&& socket){accept_handler(std::move(socket));}) , clients() , network_settings(network_settings) , next_node(tcp::socket(io_service)) , api(get_curve25519_implementation()) , keypair(api.create_key_pair()) , network_pub_key() { auto on_connect = [this, network_settings](){ BOOST_LOG_TRIVIAL(trace) << "is first: " << std::boolalpha << network_settings.is_first; if(network_settings.is_first) { start_initialisation(); } }; next_node.async_connect(network_settings.next_host, network_settings.next_port, on_connect); } Node::~Node() { api.free_key_pair(keypair); } void Node::run() { io_service.run(); } void Node::accept_handler(boost::asio::ip::tcp::socket&& socket) { clients.emplace_back(std::move(socket)); auto it = --clients.end(); clients.back().on_done( [this, it]() { clients.erase(it); } ); } void Node::start_initialisation() { initialization init; init.set_public_share(keypair.pub, keypair.pub_len); BOOST_LOG_TRIVIAL(trace) << "length of keypair.pub: " << keypair.pub_len; std::string message; init.SerializeToString(&message); BOOST_LOG_TRIVIAL(trace) << "init: " << init.DebugString(); BOOST_LOG_TRIVIAL(trace) << "size: " << message.size(); BOOST_LOG_TRIVIAL(trace) << "raw: " << message; next_node.send(message); auto f = [this](std::vector bytes) { if(network_settings.is_first) { BOOST_LOG_TRIVIAL(trace) << "bytes.size(): " << bytes.size(); BOOST_LOG_TRIVIAL(trace) << "raw2: " << std::string(bytes.begin(), bytes.end()); initialization init; init.ParseFromArray(bytes.data(), bytes.size()); std::string share = init.public_share(); network_pub_key = std::vector(share.begin(), share.end()); BOOST_LOG_TRIVIAL(trace) << "The network pub_key: " << init.DebugString(); start_precomputation(); } else { mpz_t shared; mpz_init(shared); mpz_import(shared, bytes.size(), -1, 1, 0, 0, bytes.data()); mpz_t my_share; mpz_init(my_share); mpz_import(my_share, keypair.pub_len, -1, 1, 0, 0, keypair.pub); mpz_mul(shared, shared, my_share); mpz_t mod; mpz_init(mod); mpz_set_ui(mod, 2); mpz_pow_ui(mod, mod, 255); mpz_sub_ui(mod, mod, 19); mpz_mod(shared, shared, mod); std::vector new_shared(keypair.pub_len, '\0'); size_t size; mpz_export(new_shared.data(), &size, -1, 1, 0, 0, shared); initialization init; init.set_public_share(new_shared.data(), new_shared.size()); std::string message; init.SerializeToString(&message); next_node.send(message); mpz_clear(shared); mpz_clear(my_share); mpz_clear(mod); } }; for(auto&& client : clients) { client.receive(f); } } void Node::start_precomputation() { io_service.stop(); }