diff options
Diffstat (limited to 'node')
| -rw-r--r-- | node/main.cpp | 2 | ||||
| -rw-r--r-- | node/node.cpp | 67 | ||||
| -rw-r--r-- | node/node.hpp | 39 | ||||
| -rw-r--r-- | node/node_client.cpp | 15 | ||||
| -rw-r--r-- | node/node_node.cpp | 157 |
5 files changed, 251 insertions, 29 deletions
diff --git a/node/main.cpp b/node/main.cpp index 28ef60c..acfdafe 100644 --- a/node/main.cpp +++ b/node/main.cpp @@ -21,7 +21,7 @@ int main(int argc, char* argv[]) { ("interface6,6", po::value<std::string>()->default_value("::"), "Set the ipv6 address to listen on.") ("next_node,n", po::value<std::string>(), "The address of the next node in the network.") ("first,f", "This is the first node and will be the communication point for the clients.") - ("last,f", "this is the last node and will be able to send the original message out of the network.") + ("last,l", "this is the last node and will be able to send the original message out of the network.") ("cert,c", po::value<std::string>(), "The cert file to use (in pem format).") ("key,k", po::value<std::string>(), "The key file (in pem format).") ("dhparam,d", po::value<std::string>(), "The dhparam file.") diff --git a/node/node.cpp b/node/node.cpp index b5c8506..5bce063 100644 --- a/node/node.cpp +++ b/node/node.cpp @@ -11,19 +11,40 @@ using namespace boost::asio::ip; Node::Node(ListenSettings const& listen_settings, NodeNetworkSettings network_settings) : io_service() +, timer(io_service) , ssl_ctx(std::make_shared<boost::asio::ssl::context>(boost::asio::ssl::context::sslv23)) , server(io_service, listen_settings, ssl_ctx, [this](std::unique_ptr<boost::asio::ssl::stream<boost::asio::ip::tcp::socket>>&& socket, std::shared_ptr<boost::asio::ssl::context> ctx){accept_handler(std::move(socket), ctx);}) , clients() , data() +, messages() , network_settings(network_settings) , prev_node(SSLReceiver(std::unique_ptr<boost::asio::ssl::stream<tcp::socket>>(new boost::asio::ssl::stream<boost::asio::ip::tcp::socket>(io_service, *ssl_ctx)))) , next_node(SSLSender(std::unique_ptr<boost::asio::ssl::stream<tcp::socket>>(new boost::asio::ssl::stream<boost::asio::ip::tcp::socket>(io_service, *ssl_ctx)))) , cmix_ctx(initialize_cmix_context(get_implementation())) -, precomputation_data() , shutting_down(false) { initialize_keypair(&cmix_ctx); + std::string x = to_string(cmix_ctx.keypair.sec, cmix_ctx); + std::string y = to_string(cmix_ctx.keypair.pub, cmix_ctx); + { + std::stringstream ss; + ss << "sec: "; + for(auto&& c : x) { + ss << "\\" << std::setw(3) << std::setfill('0') << std::oct << (unsigned int) c; + } + BOOST_LOG_TRIVIAL(trace) << ss.str(); + } + + { + std::stringstream ss; + ss << "pub: "; + for(auto&& c : y) { + ss << "\\" << std::setw(3) << std::setfill('0') << std::oct << (unsigned int) c; + } + BOOST_LOG_TRIVIAL(trace) << ss.str(); + } + GOOGLE_PROTOBUF_VERIFY_VERSION; if(network_settings.is_first) { @@ -131,14 +152,15 @@ void Node::handle_message(Purgatory::iterator handle, cmix_proto::CMixMessage me } void Node::start_precomputation() { + BOOST_LOG_TRIVIAL(trace) << "Starting precomputation for " << clients.size() << " clients."; + index_map.clear(); if(start_mix(&cmix_ctx, clients.size()) != no_error) { exit(-1); } - int i = 0; + unsigned int i = 0; for(auto&& pair : clients) { index_map[pair.first] = i++; - generate_random_message(&cmix_ctx, i); } if(initialize_mix_randomness(&cmix_ctx) != no_error) { @@ -148,15 +170,54 @@ void Node::start_precomputation() { cmix_proto::PrePre prepre; for(size_t i = 0; i < cmix_ctx.nr_participants; ++i) { + prepre.add_m_er(); + prepre.add_r_er(); + size_t len = get_group_element_array_size(&cmix_ctx); prepre.mutable_r_er(i)->resize(len); prepre.mutable_m_er(i)->resize(len); + { + std::stringstream ss; + ss << "r: "; + std::string r = to_string(cmix_ctx.r[i], cmix_ctx); + for(auto&& c : r) { + ss << "\\" << std::setw(3) << std::setfill('0') << std::oct << (unsigned int) c; + } + BOOST_LOG_TRIVIAL(trace) << ss.str(); + } + if(encrypt_r(&cmix_ctx, &(*prepre.mutable_r_er(i))[0], &(*prepre.mutable_m_er(i))[0], i) != no_error) { exit(-1); } } + BOOST_LOG_TRIVIAL(trace) << "Sending prepre message: " << prepre.ShortDebugString(); next_node.async_send(prepre); } + +void Node::start_realtime_phase() { + + cmix_proto::RealPre realpre; + + size_t len = get_group_element_array_size(&cmix_ctx); + for(auto&& pair : index_map) { + realpre.add_h(); + realpre.add_m(); + realpre.mutable_m(pair.second)->resize(len); + std::decay<decltype(pair)>::type::first_type const& handle = pair.first; + std::decay<decltype(pair)>::type::second_type const& index = pair.second; + + auto& queue = messages[pair.first]; + if(queue.empty()) { + std::vector<char> v(len); + generate_random_message(&cmix_ctx, v.data()); + swap_k_for_r(&cmix_ctx, &(*realpre.mutable_m(index))[0], v.data(), data[handle].shared_value, index); + } else { + swap_k_for_r(&cmix_ctx, &(*realpre.mutable_m(index))[0], queue.front().data(), data[handle].shared_value, index); + } + *realpre.mutable_h(index) = handle; + } + next_node.async_send(realpre); +} diff --git a/node/node.hpp b/node/node.hpp index a4c7992..b166c71 100644 --- a/node/node.hpp +++ b/node/node.hpp @@ -14,11 +14,23 @@ #include <list> #include <string> +#include <queue> +#include <iomanip> /*! * \file */ +#ifndef NDEBUG +inline std::string to_string(GroupElement el, CMixContext const& ctx) { + std::string ret; + ret.resize(get_group_element_array_size(&ctx)); + + element_to_buffer(&ctx, &ret[0], el); + return ret; +} +#endif + /*! * \brief The NodeNetworkSettings struct */ @@ -30,29 +42,17 @@ struct NodeNetworkSettings { std::string certdir; ///< Directory containing trusted certificate authorities. }; -struct MixData { - GroupElement r; - GroupElement s; - std::string client_handle; - size_t new_location; - - ~MixData(){ - Api api = get_implementation(); - api.free_group_element(r); - api.free_group_element(s); - } -}; - /*! * \brief The Node class */ class Node { struct CMixClientData { - SharedKey shared_value; + GroupElement shared_value; }; boost::asio::io_service io_service; + boost::asio::deadline_timer timer; std::shared_ptr<boost::asio::ssl::context> ssl_ctx; Server server; @@ -63,6 +63,8 @@ class Node ClientConnections clients; typedef std::map<std::string, CMixClientData> ClientData; ClientData data; + typedef std::map<std::string, std::queue<std::string>> ClientMessages; + ClientMessages messages; NodeNetworkSettings network_settings; @@ -71,26 +73,29 @@ class Node CMixContext cmix_ctx; - std::vector<MixData> precomputation_data; - std::map<std::string, int> index_map; + std::map<std::string, unsigned int> index_map; bool shutting_down; void accept_handler(std::unique_ptr<boost::asio::ssl::stream<boost::asio::ip::tcp::socket>>&& socket, std::shared_ptr<boost::asio::ssl::context> ctx); void connect_to_next_node(); - void start_precomputation(); void start_initialisation(); + void start_precomputation(); + void start_realtime_phase(); void handle_node_initialization(cmix_proto::Initialization const& init); void handle_node_secretkey(cmix_proto::SecretKey const& secret); void handle_node_prepre(cmix_proto::PrePre const& prepre); void handle_node_premix(cmix_proto::PreMix const& premix); void handle_node_prepost(cmix_proto::PrePost const& prepost); + void handle_node_realpre(cmix_proto::RealPre const& realpre); + void handle_node_realmix(cmix_proto::RealMix const& realmix); void handle_node_message(cmix_proto::CMixMessage message); void handle_client_keyexchange(ClientConnections::key_type handle, cmix_proto::KeyExchange const& ke); void handle_client_bye(ClientConnections::key_type handle, cmix_proto::Bye const&); + void handle_client_usermessage(ClientConnections::key_type handle, cmix_proto::UserMessage const& um); void handle_client_message(ClientConnections::key_type handle, cmix_proto::CMixMessage message); void handle_imanode(Purgatory::iterator handle, cmix_proto::ImANode const&); diff --git a/node/node_client.cpp b/node/node_client.cpp index f60c48d..baf4251 100644 --- a/node/node_client.cpp +++ b/node/node_client.cpp @@ -10,7 +10,7 @@ void Node::handle_client_keyexchange(ClientConnections::key_type handle, cmix_pr nke.mutable_public_key()->resize(len); nke.mutable_value()->resize(len); - key_exchange_responder(&cmix_ctx, &d.shared_value.shared, &(*nke.mutable_public_key())[0], &(*nke.mutable_value())[0], ke.public_key().data(), ke.value().data()); + key_exchange_responder(&cmix_ctx, &d.shared_value, &(*nke.mutable_public_key())[0], &(*nke.mutable_value())[0], ke.public_key().data(), ke.value().data()); data[handle] = d; @@ -23,6 +23,14 @@ void Node::handle_client_bye(ClientConnections::key_type handle, cmix_proto::Bye clients.erase(handle); } +void Node::handle_client_usermessage(ClientConnections::key_type handle, cmix_proto::UserMessage const& um) { + if(!network_settings.is_first) { + BOOST_LOG_TRIVIAL(warning) << "Received a user message but I'm not the first node, ignoring."; + return; + } + messages[handle].push(um.m()); +} + void Node::handle_client_message(ClientConnections::key_type handle, cmix_proto::CMixMessage message) { switch(message.contents_case()) { @@ -36,6 +44,11 @@ void Node::handle_client_message(ClientConnections::key_type handle, cmix_proto: handle_client_bye(handle, message.bye()); return; } + case cmix_proto::CMixMessage::ContentsCase::kUsermessage: { + BOOST_LOG_TRIVIAL(trace) << "Handling user message"; + handle_client_usermessage(handle, message.usermessage()); + break; + } default: { BOOST_LOG_TRIVIAL(error) << "handle_client_message: CMixMessage contains unknown contents."; } diff --git a/node/node_node.cpp b/node/node_node.cpp index eea9eb0..f24ff0a 100644 --- a/node/node_node.cpp +++ b/node/node_node.cpp @@ -13,12 +13,25 @@ cmix_proto::PrePre fill_precomputation_pre_message(CMixContext& ctx, T const& rs cmix_proto::PrePre prepre; - for(size_t i = 0; i < ctx.nr_participants; ++i) { + for(size_t i = 0; i < ms.size(); ++i) { + prepre.add_m_er(); + prepre.add_r_er(); + size_t len = get_group_element_array_size(&ctx); prepre.mutable_m_er(i)->resize(len); prepre.mutable_r_er(i)->resize(len); + { + std::stringstream ss; + ss << "r: "; + std::string r = to_string(ctx.r[i], ctx); + for(auto&& c : r) { + ss << "\\" << std::setw(3) << std::setfill('0') << std::oct << (unsigned int) c; + } + BOOST_LOG_TRIVIAL(trace) << ss.str(); + } + if(encrypt_r_and_multiply( &ctx, &(*prepre.mutable_r_er(i))[0], @@ -36,14 +49,29 @@ cmix_proto::PrePre fill_precomputation_pre_message(CMixContext& ctx, T const& rs template <typename T> cmix_proto::PreMix fill_precomputation_mix_message(CMixContext const& ctx, T const& rs, T const& ms) { cmix_proto::PreMix premix; - for(size_t i = 0; i < ctx.nr_participants; ++i) { + + for(size_t i = 0; i < ms.size(); ++i) { + premix.add_r_epirs(); + premix.add_m_epirs(); + } + for(size_t i = 0; i < ms.size(); ++i) { auto new_pos = ctx.permutation[i]; size_t el_len = get_group_element_array_size(&ctx); premix.mutable_r_epirs(new_pos)->resize(el_len); premix.mutable_m_epirs(new_pos)->resize(el_len); - multiply_s( + { + std::stringstream ss; + ss << "s: "; + std::string s = to_string(ctx.s[i], ctx); + for(auto&& c : s) { + ss << "\\" << std::setw(3) << std::setfill('0') << std::oct << (unsigned int) c; + } + BOOST_LOG_TRIVIAL(trace) << ss.str(); + } + + multiply_encrypted_s( &ctx, &(*premix.mutable_r_epirs(new_pos))[0], &(*premix.mutable_m_epirs(new_pos))[0], @@ -59,7 +87,10 @@ template <typename T> cmix_proto::PrePost fill_precomputation_post_message(CMixContext& ctx, T const& rs, T const& ms) { cmix_proto::PrePost prepost; - for(size_t i = 0; i < ctx.nr_participants; ++i) { + for(size_t i = 0; i < ms.size(); ++i) { + prepost.add_r_epirs(); + prepost.add_m_epirs(); + size_t el_len = get_group_element_array_size(&ctx); prepost.mutable_r_epirs(i)->resize(el_len); @@ -74,6 +105,16 @@ cmix_proto::PrePost fill_precomputation_post_message(CMixContext& ctx, T const& i ); + { + std::stringstream ss; + ss << "pirs: "; + std::string pirs = to_string(ctx.pirs[i], ctx); + for(auto&& c : pirs) { + ss << "\\" << std::setw(3) << std::setfill('0') << std::oct << (unsigned int) c; + } + BOOST_LOG_TRIVIAL(trace) << ss.str(); + } + *prepost.mutable_r_epirs(i) = rs.Get(i); *prepost.mutable_m_epirs(i) = ms.Get(i); } @@ -81,6 +122,56 @@ cmix_proto::PrePost fill_precomputation_post_message(CMixContext& ctx, T const& return prepost; } +template <typename T> +cmix_proto::RealPre fill_realtime_pre_message(CMixContext& ctx, T const& hs, T const& ms, Node::ClientData const& data) { + cmix_proto::RealPre realpre; + + size_t len = get_group_element_array_size(&ctx); + for(int i = 0; i < ms.size(); ++i) { + realpre.add_h(); + realpre.add_m(); + realpre.mutable_m(i)->resize(len); + + swap_k_for_r( + &ctx, + &(*realpre.mutable_m(i))[0], + ms.Get(i).data(), + data.at(hs.Get(i)).shared_value, + i + ); + *realpre.mutable_h(i) = hs.Get(i); + } + + return realpre; +} + +template <typename T> +cmix_proto::RealMix fill_realtime_mix_message(CMixContext& ctx, T const& ms) { + cmix_proto::RealMix realmix; + + size_t len = get_group_element_array_size(&ctx); + + for(int i = 0; i < ms.size(); ++i) { + realmix.add_m(); + } + + for(int i = 0; i < ms.size(); ++i) { + auto new_pos = ctx.permutation[i]; + + realmix.mutable_m(i)->resize(len); + + multiply_s( + &ctx, + &(*realmix.mutable_m(new_pos))[0], + ms.Get(i).data(), + i + ); + + } + + return realmix; +} + void Node::handle_node_initialization(const cmix_proto::Initialization& init) { if(network_settings.is_first) { @@ -97,7 +188,7 @@ void Node::handle_node_initialization(const cmix_proto::Initialization& init) n_init.mutable_public_share()->resize(len); add_public_share(&cmix_ctx, &(*n_init.mutable_public_share())[0], init.public_share().data()); - BOOST_LOG_TRIVIAL(trace) << "Sending intialization"; + BOOST_LOG_TRIVIAL(trace) << "sending message: " << n_init.ShortDebugString(); next_node.async_send(n_init); } } @@ -109,7 +200,10 @@ void Node::handle_node_secretkey(cmix_proto::SecretKey const& secret) set_network_key(&cmix_ctx, secret.secret_key().data(), secret.secret_key().size()); if(network_settings.is_first) { - start_precomputation(); + timer.expires_from_now(boost::posix_time::seconds(4)); + timer.async_wait([this](boost::system::error_code const& ec) { + start_precomputation(); + }); } else { next_node.async_send(secret); } @@ -137,15 +231,54 @@ void Node::handle_node_premix(cmix_proto::PreMix const& premix) { void Node::handle_node_prepost(cmix_proto::PrePost const& prepost) { if(network_settings.is_first) { - + start_realtime_phase(); } else { cmix_proto::PrePost n_prepost = fill_precomputation_post_message(cmix_ctx, prepost.r_epirs(), prepost.m_epirs()); next_node.async_send(n_prepost); } } +void Node::handle_node_realpre(cmix_proto::RealPre const& realpre) { + if(network_settings.is_first) { + cmix_proto::RealMix n_realmix = fill_realtime_mix_message(cmix_ctx, realpre.m()); + next_node.async_send(n_realmix); + } else { + cmix_proto::RealPre n_realpre = fill_realtime_pre_message(cmix_ctx, realpre.h(), realpre.m(), data); + next_node.async_send(n_realpre); + } +} + +void Node::handle_node_realmix(cmix_proto::RealMix const& realmix) { + if(network_settings.is_last) { + BOOST_LOG_TRIVIAL(trace) << "Doing the last step:"; + + cmix_proto::RealMix n_realmix = fill_realtime_mix_message(cmix_ctx, realmix.m()); + + size_t len = get_group_element_array_size(&cmix_ctx); + std::string str; + str.resize(len); + + for(int i = 0; i < n_realmix.m_size(); i++) { + remove_r_and_s(&cmix_ctx, &str[0], n_realmix.m(i).data(), i); + + { + std::stringstream ss; + for(auto&& c : str) { + ss << "\\" << std::setw(3) << std::setfill('0') << std::oct << (unsigned int) c; + } + BOOST_LOG_TRIVIAL(trace) << ss.str(); + } + } + + } else { + cmix_proto::RealMix n_realmix = fill_realtime_mix_message(cmix_ctx, realmix.m()); + next_node.async_send(n_realmix); + } +} + void Node::handle_node_message(cmix_proto::CMixMessage message) { + BOOST_LOG_TRIVIAL(trace) << "Message: " << message.ShortDebugString(); switch(message.contents_case()) { case cmix_proto::CMixMessage::ContentsCase::kInitialization: { BOOST_LOG_TRIVIAL(trace) << "Handling initialization"; @@ -177,6 +310,16 @@ void Node::handle_node_message(cmix_proto::CMixMessage message) handle_node_prepost(message.prepost()); break; } + case cmix_proto::CMixMessage::ContentsCase::kRealpre: { + BOOST_LOG_TRIVIAL(trace) << "Handling RealPre"; + handle_node_realpre(message.realpre()); + break; + } + case cmix_proto::CMixMessage::ContentsCase::kRealmix: { + BOOST_LOG_TRIVIAL(trace) << "Handling RealMix"; + handle_node_realmix(message.realmix()); + break; + } default: { BOOST_LOG_TRIVIAL(error) << "handle_node_message: CMixMessage contains unknown contents."; } |
