aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--CMakeModules/gmpConfig.cmake13
-rw-r--r--libcmix-network/client.cpp83
-rw-r--r--libcmix-network/client.hpp30
-rw-r--r--node/CMakeLists.txt4
-rw-r--r--node/nextnode.cpp20
-rw-r--r--node/nextnode.hpp7
-rw-r--r--node/node.cpp56
7 files changed, 172 insertions, 41 deletions
diff --git a/CMakeModules/gmpConfig.cmake b/CMakeModules/gmpConfig.cmake
new file mode 100644
index 0000000..a6e6682
--- /dev/null
+++ b/CMakeModules/gmpConfig.cmake
@@ -0,0 +1,13 @@
+add_library(gmp UNKNOWN IMPORTED)
+find_library(gmp_LIBRARY NAMES "gmp")
+set_property(TARGET gmp PROPERTY IMPORTED_LOCATION "${gmp_LIBRARY}")
+
+add_library(gmpxx UNKNOWN IMPORTED)
+find_library(gmpxx_LIBRARY NAMES "gmpxx")
+set_property(TARGET gmpxx PROPERTY IMPORTED_LOCATION "${gmpxx_LIBRARY}")
+
+find_path(gmp_INCLUDE_DIR NAMES "gmp.h")
+set_property(TARGET gmp PROPERTY INCLUDE_DIRECTORIES ${gmp_INCLUDE_DIR})
+
+find_path(gmpxx_INCLUDE_DIR NAMES "gmpxx.h")
+set_property(TARGET gmpxx PROPERTY INCLUDE_DIRECTORIES ${gmpxx_INCLUDE_DIR})
diff --git a/libcmix-network/client.cpp b/libcmix-network/client.cpp
index ce9fd4d..d8e79d7 100644
--- a/libcmix-network/client.cpp
+++ b/libcmix-network/client.cpp
@@ -1,9 +1,13 @@
#include "client.hpp"
+#include "connect.hpp"
+
#include "logging.hpp"
#include <boost/asio/placeholders.hpp>
#include <boost/bind.hpp>
+#include <boost/asio/buffer.hpp>
+#include <boost/array.hpp>
#include <iostream>
@@ -16,17 +20,83 @@ Client::Client(tcp::socket &&socket)
, done()
{}
-void Client::handle_receive(MessageHandler message_handler, const error_code &ec, size_t read_bytes)
+void Client::async_connect(std::string next_host, std::string next_port, std::function<void ()> on_connect)
+{
+ ::async_connect(socket, next_host, next_port, on_connect);
+}
+
+std::array<uint8_t, 4> Client::prepare_length_prefix(uint32_t length)
+{
+ length = htonl(length);
+ std::array<uint8_t, 4> buf;
+
+ std::copy(reinterpret_cast<uint8_t*>(&length), reinterpret_cast<uint8_t*>(&length) + 4, buf.data());
+ return buf;
+}
+
+void Client::send(std::string message) {
+
+ boost::array<boost::asio::const_buffer, 2> package = {
+ boost::asio::buffer(prepare_length_prefix(message.size())),
+ boost::asio::buffer(message)
+ };
+
+ auto handler = [](boost::system::error_code const& ec, std::size_t bytes_transferred) {
+ BOOST_LOG_TRIVIAL(trace) << "sent message of " << bytes_transferred << " bytes";
+ if(ec) {
+ BOOST_LOG_TRIVIAL(fatal) << ec;
+ throw std::runtime_error("unable to send message");
+ }
+ };
+
+ socket.async_send(package, 0, handler);
+
+}
+
+std::vector<uint8_t> Client::received_bytes_to_vector(size_t read_bytes)
{
buffer.commit(read_bytes);
std::istream is(&buffer);
+ is.unsetf(std::ios::skipws);
+
+ return std::vector<uint8_t>(std::istream_iterator<uint8_t>(is), {});
+}
- BOOST_LOG_TRIVIAL(trace) << "handling receive";
+void Client::handle_receive_size(Client::MessageHandler message_handler, const error_code& ec, size_t read_bytes)
+{
+ using namespace boost::asio::placeholders;
+
+ if(!ec) {
+ std::vector<uint8_t> data = received_bytes_to_vector(read_bytes);
+ uint32_t size;
+ std::copy(data.begin(), data.end(), reinterpret_cast<uint8_t*>(&size));
+ size = ntohl(size);
+
+ socket.async_receive(
+ buffer.prepare(size),
+ boost::bind(&Client::handle_receive_message, this, message_handler, error(), bytes_transferred())
+ );
+ } else {
+ BOOST_LOG_TRIVIAL(error) << ec;
+ if(done) {
+ done();
+ }
+ }
+}
+void Client::handle_receive_message(MessageHandler message_handler, const error_code &ec, size_t read_bytes)
+{
+ BOOST_LOG_TRIVIAL(trace) << "handling receive of: " << read_bytes << " bytes";
if(!ec) {
+ buffer.commit(read_bytes);
+ std::istream is(&buffer);
+ is.unsetf(std::ios::skipws);
+
std::vector<uint8_t> data(std::istream_iterator<uint8_t>(is), {});
+ BOOST_LOG_TRIVIAL(trace) << "data.size(): " << data.size();
message_handler(data);
} else {
+ BOOST_LOG_TRIVIAL(error) << ec;
if(done) {
done();
}
@@ -37,11 +107,16 @@ void Client::receive(MessageHandler message_handler) {
using namespace boost::asio::placeholders;
socket.async_receive(
- buffer.prepare(512),
- boost::bind(&Client::handle_receive, this, message_handler, error(), bytes_transferred())
+ buffer.prepare(4),
+ boost::bind(&Client::handle_receive_size, this, message_handler, error(), bytes_transferred())
);
}
+void Client::close()
+{
+ socket.close();
+}
+
void Client::on_done(Client::OnDoneFT f) {
done = f;
}
diff --git a/libcmix-network/client.hpp b/libcmix-network/client.hpp
index 981283b..cb81418 100644
--- a/libcmix-network/client.hpp
+++ b/libcmix-network/client.hpp
@@ -31,24 +31,18 @@ protected:
boost::asio::ip::tcp::socket socket;
private:
- /*!
- * \brief buffer Internal private buffer used to receive messages.
- */
boost::asio::streambuf buffer;
- /*!
- * \brief done The done function being called when this is done operating.
- */
OnDoneFT done;
+
+ std::vector<uint8_t> received_bytes_to_vector(size_t read_bytes);
+
+ void handle_receive_size(MessageHandler message_handler, boost::system::error_code const& ec, size_t read_bytes);
+
+ void handle_receive_message(MessageHandler message_handler, boost::system::error_code const& ec, size_t read_bytes);
- /*!
- * \brief handle_receive
- * \param message_handler The function to call when a message has been received.
- * \param ec A possible error that occured during receiving.
- * \param read_bytes The number of bytes read.
- */
- void handle_receive(MessageHandler message_handler, boost::system::error_code const& ec, size_t read_bytes);
-
+ std::array<uint8_t, 4> prepare_length_prefix(uint32_t length);
+
public:
/*!
* \brief Client
@@ -56,15 +50,23 @@ public:
*/
Client(boost::asio::ip::tcp::socket&& socket);
+ void async_connect(std::string next_host, std::string next_port, std::function<void()> on_connect);
+
+ void send(std::string message);
+
/*!
* \brief receive
* \param message_handler The function to call when a message has been received.
*/
void receive(MessageHandler message_handler);
+ void close();
+
/*!
* \brief on_done sets the done callback.
* \param f The new done callback function.
*/
void on_done(OnDoneFT f);
+
+
};
diff --git a/node/CMakeLists.txt b/node/CMakeLists.txt
index c3c8e46..adbedb1 100644
--- a/node/CMakeLists.txt
+++ b/node/CMakeLists.txt
@@ -1,5 +1,7 @@
find_package(Boost COMPONENTS system program_options REQUIRED)
+find_package(gmp REQUIRED)
+
add_executable(node
main.cpp
node.hpp node.cpp
@@ -18,4 +20,6 @@ target_link_libraries(node
PRIVATE cmix
PRIVATE cmix-network
PRIVATE cmix-protobuf
+ PRIVATE gmpxx
+ PRIVATE gmp
)
diff --git a/node/nextnode.cpp b/node/nextnode.cpp
index d38200d..f6c4454 100644
--- a/node/nextnode.cpp
+++ b/node/nextnode.cpp
@@ -1,34 +1,24 @@
#include "nextnode.hpp"
-#include "connect.hpp"
-
#include "logging.hpp"
using namespace boost::asio::ip;
NextNode::NextNode(tcp::socket&& socket)
-: Client(std::move(socket))
+: client(std::move(socket))
{}
void NextNode::send(std::string message)
{
- auto handler = [](boost::system::error_code const& ec, std::size_t bytes_transferred) {
- BOOST_LOG_TRIVIAL(trace) << "sent message";
- if(ec) {
- BOOST_LOG_TRIVIAL(fatal) << ec;
- throw std::runtime_error("unable to send message");
- }
- };
-
- socket.async_send(boost::asio::buffer(message), 0, handler);
+ client.send(message);
}
-void NextNode::connect(std::string next_host, std::string next_port, std::function<void ()> on_connect)
+void NextNode::async_connect(std::string next_host, std::string next_port, std::function<void ()> on_connect)
{
- async_connect(socket, next_host, next_port, on_connect);
+ client.async_connect(next_host, next_port, on_connect);
}
void NextNode::close()
{
- socket.close();
+ client.close();
}
diff --git a/node/nextnode.hpp b/node/nextnode.hpp
index 24b93c4..6550445 100644
--- a/node/nextnode.hpp
+++ b/node/nextnode.hpp
@@ -11,8 +11,9 @@
/*!
* \brief The NextNode class represents the next node in the network, will only be sent to.
*/
-class NextNode : public Client
+class NextNode
{
+ Client client;
public:
/*!
* \brief NextNode
@@ -27,12 +28,12 @@ public:
void send(std::string message);
/*!
- * \brief connect
+ * \brief async_connect
* \param next_host The host of the next node.
* \param next_port The port of the next node.
* \param on_connect The callback to call when the connect was succesfull.
*/
- void connect(std::string next_host, std::string next_port, std::function<void()> on_connect);
+ void async_connect(std::string next_host, std::string next_port, std::function<void()> on_connect);
/*!
* \brief close This function closes the underlying socket connection.
diff --git a/node/node.cpp b/node/node.cpp
index 045eb13..92c51ec 100644
--- a/node/node.cpp
+++ b/node/node.cpp
@@ -2,6 +2,10 @@
#include "logging.hpp"
+#include "gmpxx.h"
+
+#include <iostream>
+
using namespace boost::asio::ip;
Node::Node(ListenSettings const& listen_settings, NodeNetworkSettings network_settings)
@@ -21,7 +25,7 @@ Node::Node(ListenSettings const& listen_settings, NodeNetworkSettings network_se
}
};
- next_node.connect(network_settings.next_host, network_settings.next_port, on_connect);
+ next_node.async_connect(network_settings.next_host, network_settings.next_port, on_connect);
}
Node::~Node() {
@@ -52,18 +56,60 @@ void Node::start_initialisation() {
std::string message;
init.SerializeToString(&message);
- BOOST_LOG_TRIVIAL(trace) << init.DebugString();
+ 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<uint8_t> bytes) {
- network_pub_key = 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<uint8_t>(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<uint8_t> 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);
}
};
- BOOST_LOG_TRIVIAL(trace) << "number of clients: " << clients.size();
for(auto&& client : clients) {
client.receive(f);
}