aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDennis Brentjes <d.brentjes@gmail.com>2018-02-04 12:47:09 +0100
committerDennis Brentjes <d.brentjes@gmail.com>2018-02-04 12:47:09 +0100
commit21474893efe0ab38461c3d08727c7c778caa9323 (patch)
tree8d48ec3353c84155dcf7daf67d8ade1dd1fd480d
parent126021b3766e6fb33333b7939d78dadd1c632eb4 (diff)
downloadcmix-21474893efe0ab38461c3d08727c7c778caa9323.tar.gz
cmix-21474893efe0ab38461c3d08727c7c778caa9323.tar.bz2
cmix-21474893efe0ab38461c3d08727c7c778caa9323.zip
Both algorithms are now batchable.
-rw-r--r--client/cmixclient.cpp29
-rw-r--r--client/cmixclient.hpp3
-rw-r--r--client/main.cpp5
-rw-r--r--libcmix-network/acceptor.hpp1
-rw-r--r--libcmix-network/connect.cpp6
-rw-r--r--libcmix-network/connect.hpp2
-rw-r--r--libcmix/cmix.c237
-rw-r--r--libcmix/cmix.h4
-rw-r--r--node/main.cpp5
-rw-r--r--node/node.cpp10
-rw-r--r--node/node.hpp1
-rw-r--r--node/node_node.cpp18
-rwxr-xr-xrun.sh8
13 files changed, 192 insertions, 137 deletions
diff --git a/client/cmixclient.cpp b/client/cmixclient.cpp
index fca653b..17f6e76 100644
--- a/client/cmixclient.cpp
+++ b/client/cmixclient.cpp
@@ -76,22 +76,41 @@ void CMixClient::handle_key_exchange(size_t node_id, cmix_proto::KeyExchange con
);
if(std::all_of(shared_values.begin(), shared_values.end(), [](GroupElement const& value){return value != nullptr;})) {
- size_t len = get_message_size(&cmix_ctx);
-
+ size_t len = cmix_ctx.nr_mixes * get_message_size(&cmix_ctx);
std::vector<char> vec(len, '\0');
char* id;
size_t id_len;
get_pub_key_hash(&cmix_ctx, &id, &id_len);
- std::string s = "abcdefghijklmnopqrstuvwxyz";
+ std::string s = "abcdefghijklmnopqrstuvwxyz"
+ "abcdefghijklmnopqrstuvwxyz"
+ "abcdefghijklmnopqrstuvwxyz"
+ "abcdefghijklmnopqrstuvwxyz"
+ "abcdefghijklmnopqrstuvwxyz"
+ "abcdefghijklmnopqrstuvwxyz"
+ "abcdefghijklmnopqrstuvwxyz"
+ "abcdefghijklmnopqrstuvwxyz"
+ "abcdefghijklmnopqrstuvwxyz"
+ "abcdefghijklmnopqrstuvwxyz"
+ "abcdefghijklmnopqrstuvwxyz"
+ "abcdefghijklmnopqrstuvwxyz"
+ "abcdefghijklmnopqrstuvwxyz"
+ "abcdefghijklmnopqrstuvwxyz"
+ "abcdefghijklmnopqrstuvwxyz"
+ "abcdefghijklmnopqrstuvwxyz"
+ "abcdefghijklmnopqrstuvwxyz"
+ "abcdefghijklmnopqrstuvwxyz"
+ "abcdefghijklmnopqrstuvwxyz"
+ "abcdefghijklmnopqrstuvwxyz"
+ "abcdefghijklmnopqrstuvwxyz";
create_message(&cmix_ctx, vec.data(), id, id_len, s.data(), s.size());
free(id);
cmix_proto::UserMessage message;
- message.mutable_m()->resize(get_group_element_array_size(&cmix_ctx));
+ message.mutable_m()->resize(get_group_element_array_size(&cmix_ctx) * cmix_ctx.nr_mixes);
blind_message(&cmix_ctx, &(*message.mutable_m())[0], vec.data(), shared_values.data(), shared_values.size());
@@ -145,7 +164,7 @@ void CMixClient::handle_message(size_t node_id, cmix_proto::CMixMessage message)
CMixClient::CMixClient(NetworkDetails details)
: io_service()
, ssl_ctx(std::make_shared<boost::asio::ssl::context>(boost::asio::ssl::context::sslv23))
-, cmix_ctx(initialize_cmix_context(get_implementation()))
+, cmix_ctx(initialize_cmix_context(get_implementation(), details.nr_mixes))
, network_details(details)
, network_connections()
, secret_values()
diff --git a/client/cmixclient.hpp b/client/cmixclient.hpp
index 6291bd1..d684c88 100644
--- a/client/cmixclient.hpp
+++ b/client/cmixclient.hpp
@@ -36,6 +36,7 @@ struct NodeDetails {
struct NetworkDetails {
std::vector<NodeDetails> node_details; ///< Vector with all the node hosts and ports in network order.
std::string certdir; ///< The directory with trusted certificates.
+ unsigned int nr_mixes; ///< The number of simultaneous mixes the nodes are set to do.
};
/*!
@@ -78,4 +79,4 @@ public:
* \brief run Runs the underlying io_service.
*/
void run();
-}; \ No newline at end of file
+};
diff --git a/client/main.cpp b/client/main.cpp
index 63d1ebf..efea166 100644
--- a/client/main.cpp
+++ b/client/main.cpp
@@ -33,6 +33,7 @@ int main(int argc, char* argv[]) {
("help,h", "produce help message.")
("network,n", po::value<std::vector<std::string>>()->multitoken(), "The addresses of the network nodes in order")
("certdir", po::value<std::string>(), "Directory containing trusted certificates.")
+ ("nr_mixes,x", po::value<unsigned int>()->default_value(1), "The number of simultanous mixes the network will perform.")
;
po::variables_map vm;
@@ -69,8 +70,10 @@ int main(int argc, char* argv[]) {
return -1;
}
}
+
+ unsigned int nr_mixes = vm["nr_mixes"].as<unsigned int>();
- NetworkDetails details{node_details, certdir};
+ NetworkDetails details{node_details, certdir, nr_mixes};
CMixClient cmix_client(details);
cmix_client.run();
diff --git a/libcmix-network/acceptor.hpp b/libcmix-network/acceptor.hpp
index eecc511..37f1bb1 100644
--- a/libcmix-network/acceptor.hpp
+++ b/libcmix-network/acceptor.hpp
@@ -4,6 +4,7 @@
#include <boost/asio/ip/tcp.hpp>
#include <boost/asio/ssl.hpp>
+#include <boost/asio/io_service.hpp>
#include <functional>
diff --git a/libcmix-network/connect.cpp b/libcmix-network/connect.cpp
index 4bebf9d..81c5800 100644
--- a/libcmix-network/connect.cpp
+++ b/libcmix-network/connect.cpp
@@ -54,7 +54,7 @@ struct IterationInfo {
{}
};
-void async_connect_iteration(basic_socket<tcp, stream_socket_service<tcp>>& socket, std::shared_ptr<IterationInfo> info, std::function<void()> on_connect) {
+void async_connect_iteration(basic_socket<tcp>& socket, std::shared_ptr<IterationInfo> info, std::function<void()> on_connect) {
if(info->it == boost::asio::ip::tcp::resolver::iterator()) {
throw std::runtime_error("None of the supplied endpoints responded");
@@ -99,7 +99,7 @@ void async_connect_iteration(basic_socket<tcp, stream_socket_service<tcp>>& sock
socket.async_connect(*(info->it), handler);
}
-void async_connect(basic_socket<tcp, stream_socket_service<tcp>>& socket, std::string host, std::string port, std::function<void()> on_connect)
+void async_connect(basic_socket<tcp>& socket, std::string host, std::string port, std::function<void()> on_connect)
{
boost::asio::ip::basic_resolver<tcp> resolver(socket.get_io_service());
boost::asio::ip::basic_resolver_query<tcp> query(host, port);
@@ -111,4 +111,4 @@ void async_connect(basic_socket<tcp, stream_socket_service<tcp>>& socket, std::s
std::shared_ptr<IterationInfo> info = std::make_shared<IterationInfo>(0, it, socket.get_io_service());
async_connect_iteration(socket, info, on_connect);
-} \ No newline at end of file
+}
diff --git a/libcmix-network/connect.hpp b/libcmix-network/connect.hpp
index ba70c70..caac09f 100644
--- a/libcmix-network/connect.hpp
+++ b/libcmix-network/connect.hpp
@@ -24,4 +24,4 @@ boost::asio::ip::tcp::socket connect(std::string host, std::string port, boost::
* \param port The port
* \param on_connect The function to call when the connect has succeeded.
*/
-void async_connect(boost::asio::basic_socket<boost::asio::ip::tcp, boost::asio::stream_socket_service<boost::asio::ip::tcp>>& socket, std::string host, std::string port, std::function<void()> on_connect); \ No newline at end of file
+void async_connect(boost::asio::basic_socket<boost::asio::ip::tcp>& socket, std::string host, std::string port, std::function<void()> on_connect);
diff --git a/libcmix/cmix.c b/libcmix/cmix.c
index 695fb05..0874cf0 100644
--- a/libcmix/cmix.c
+++ b/libcmix/cmix.c
@@ -6,10 +6,10 @@
#include <stdio.h>
#include <math.h>
-struct CMixContext initialize_cmix_context(struct Api api) {
+struct CMixContext initialize_cmix_context(struct Api api, unsigned int nr_mixes) {
return (struct CMixContext){
.api = api,
- .nr_mixes = 0,
+ .nr_mixes = nr_mixes,
.nr_participants = 0,
.network_key = NULL,
.r = NULL,
@@ -22,22 +22,22 @@ struct CMixContext initialize_cmix_context(struct Api api) {
}
enum cmix_error alloc_mix(struct CMixContext* ctx) {
- ctx->r = (GroupElement**) calloc(ctx->nr_mixes, sizeof(GroupElement*));
- ctx->s = (GroupElement**) calloc(ctx->nr_mixes, sizeof(GroupElement*));
- ctx->permutation = (unsigned int**) calloc(ctx->nr_mixes, sizeof(unsigned int*));
- ctx->decryption_shares = (GroupElement**) calloc(ctx->nr_mixes, sizeof(GroupElement*));
- ctx->EPiRS = (GroupElement**) calloc(ctx->nr_mixes, sizeof(GroupElement*));
-
- for(size_t m = 0; m < ctx->nr_mixes; ++m) {
- ctx->r[m] = (GroupElement*) calloc(ctx->nr_participants, sizeof(GroupElement));
- ctx->s[m] = (GroupElement*) calloc(ctx->nr_participants, sizeof(GroupElement));
- ctx->permutation[m] = (unsigned int*) calloc(ctx->nr_participants, sizeof(unsigned int));
- ctx->decryption_shares[m] = (GroupElement*) calloc(ctx->nr_participants, sizeof(GroupElement));
- ctx->EPiRS[m] = (GroupElement*) calloc(ctx->nr_participants, sizeof(GroupElement));
+ ctx->r = (GroupElement**) calloc(ctx->nr_participants, sizeof(GroupElement*));
+ ctx->s = (GroupElement**) calloc(ctx->nr_participants, sizeof(GroupElement*));
+ ctx->permutation = (unsigned int**) calloc(ctx->nr_participants, sizeof(unsigned int*));
+ ctx->decryption_shares = (GroupElement**) calloc(ctx->nr_participants, sizeof(GroupElement*));
+ ctx->EPiRS = (GroupElement**) calloc(ctx->nr_participants, sizeof(GroupElement*));
+ ctx->PiMRS = (GroupElement**) calloc(ctx->nr_participants, sizeof(GroupElement*));
+
+ for(size_t m = 0; m < ctx->nr_participants; ++m) {
+ ctx->r[m] = (GroupElement*) calloc(ctx->nr_mixes, sizeof(GroupElement));
+ ctx->s[m] = (GroupElement*) calloc(ctx->nr_mixes, sizeof(GroupElement));
+ ctx->permutation[m] = (unsigned int*) calloc(ctx->nr_mixes, sizeof(unsigned int));
+ ctx->decryption_shares[m] = (GroupElement*) calloc(ctx->nr_mixes, sizeof(GroupElement));
+ ctx->EPiRS[m] = (GroupElement*) calloc(ctx->nr_mixes, sizeof(GroupElement));
+ ctx->PiMRS[m] = (GroupElement*) calloc(ctx->nr_mixes, sizeof(GroupElement));
}
-
- ctx->PiMRS = (GroupElement*) calloc(ctx->nr_participants, sizeof(GroupElement));
if(!ctx->r || !ctx->s || !ctx->permutation || !ctx->decryption_shares || !ctx->EPiRS || !ctx->PiMRS ) {
return out_of_memory;
}
@@ -47,27 +47,27 @@ enum cmix_error alloc_mix(struct CMixContext* ctx) {
void release_mix(struct CMixContext* ctx) {
if(ctx->r && ctx->s && ctx->permutation && ctx->decryption_shares && ctx->EPiRS) {
- for(size_t m = 0; m < ctx->nr_mixes; ++m) {
+ for(size_t m = 0; m < ctx->nr_participants; ++m) {
if(ctx->r[m]) {
- for(size_t i = 0; i < ctx->nr_participants; ++i) {
+ for(size_t i = 0; i < ctx->nr_mixes; ++i) {
ctx->api.free_group_element(ctx->r[m][i]);
}
free(ctx->r[m]);
}
if(ctx->s[m]){
- for(size_t i = 0; i < ctx->nr_participants; ++i) {
+ for(size_t i = 0; i < ctx->nr_mixes; ++i) {
ctx->api.free_group_element(ctx->s[m][i]);
}
}
free(ctx->permutation[m]);
if(ctx->decryption_shares[m]){
- for(size_t i = 0; i < ctx->nr_participants; ++i) {
+ for(size_t i = 0; i < ctx->nr_mixes; ++i) {
ctx->api.free_group_element(ctx->decryption_shares[m][i]);
}
}
if(ctx->EPiRS[m]) {
- for(size_t i = 0; i < ctx->nr_participants; ++i) {
+ for(size_t i = 0; i < ctx->nr_mixes; ++i) {
ctx->api.free_group_element(ctx->EPiRS[m][i]);
}
}
@@ -162,16 +162,16 @@ enum cmix_error generate_permutation(struct CMixContext* ctx) {
for(size_t m = 0; m < ctx->nr_mixes; ++m) {
for(unsigned int i = 0; i < ctx->nr_participants; ++i) {
- ctx->permutation[m][i] = i;
+ ctx->permutation[i][m] = i;
}
//Fisher-Yates shuffle
unsigned int temp = 0;
for(unsigned int i = ctx->nr_participants - 1; i > 0; --i) {
unsigned int rand = ctx->api.get_uniform_int(i+1);
- temp = ctx->permutation[m][i];
- ctx->permutation[m][i] = ctx->permutation[m][rand];
- ctx->permutation[m][rand] = temp;
+ temp = ctx->permutation[i][m];
+ ctx->permutation[i][m] = ctx->permutation[m][rand];
+ ctx->permutation[rand][m] = temp;
}
}
@@ -180,10 +180,11 @@ enum cmix_error generate_permutation(struct CMixContext* ctx) {
}
enum cmix_error initialize_mix_randomness(struct CMixContext* ctx) {
- for(size_t m = 0; m < ctx->nr_mixes; ++m) {
- for(size_t i = 0; i < ctx->nr_participants; ++i) {
- ctx->r[m][i] = ctx->api.get_group_element(true);
- ctx->s[m][i] = ctx->api.get_group_element(true);
+
+ for(size_t i = 0; i < ctx->nr_participants; ++i) {
+ for(size_t m = 0; m < ctx->nr_mixes; ++m) {
+ ctx->r[i][m] = ctx->api.get_group_element(true);
+ ctx->s[i][m] = ctx->api.get_group_element(true);
}
}
@@ -214,15 +215,18 @@ enum cmix_error set_network_key(struct CMixContext* ctx, char const* buffer) {
enum cmix_error encrypt_r(struct CMixContext const* ctx, char** random_buffer, char** message_buffer) {
- for(size_t m = 0; m < ctx->nr_mixes; m++) {
- for(size_t i = 0; i < ctx->nr_participants; ++i) {
+
+ for(size_t i = 0; i < ctx->nr_participants; ++i) {
+ for(size_t m = 0; m < ctx->nr_mixes; m++) {
+ size_t offset = m * get_group_element_array_size(ctx);
+
GroupElement random_element;
GroupElement message_element;
- ctx->api.encrypt(&random_element, &message_element, ctx->r[m][i], ctx->network_key);
+ ctx->api.encrypt(&random_element, &message_element, ctx->r[i][m], ctx->network_key);
- element_to_buffer(ctx, random_buffer[i], random_element);
- element_to_buffer(ctx, message_buffer[i], message_element);
+ element_to_buffer(ctx, random_buffer[i] + offset, random_element);
+ element_to_buffer(ctx, message_buffer[i] + offset, message_element);
ctx->api.free_group_element(random_element);
ctx->api.free_group_element(message_element);
@@ -233,23 +237,25 @@ enum cmix_error encrypt_r(struct CMixContext const* ctx, char** random_buffer, c
enum cmix_error encrypt_r_and_multiply(struct CMixContext const* ctx, char** random_buffer, char** message_buffer, const char** random_element, const char** message_element) {
- for(size_t m = 0; m < ctx->nr_mixes; ++m) {
- for(size_t i = 0; i < ctx->nr_participants; ++i) {
+ for(size_t i = 0; i < ctx->nr_participants; ++i) {
+ for(size_t m = 0; m < ctx->nr_mixes; ++m) {
GroupElement enc_random_element;
GroupElement enc_message_element;
- ctx->api.encrypt(&enc_random_element, &enc_message_element, ctx->r[m][i], ctx->network_key);
+ size_t offset = m * get_group_element_array_size(ctx);
+
+ ctx->api.encrypt(&enc_random_element, &enc_message_element, ctx->r[i][m], ctx->network_key);
size_t el_size = get_group_element_array_size(ctx);
- GroupElement other_random_element = ctx->api.array_to_element(random_element[i], el_size, true);
- GroupElement other_message_element = ctx->api.array_to_element(message_element[i], el_size, true);
+ GroupElement other_random_element = ctx->api.array_to_element(random_element[i] + offset, el_size, true);
+ GroupElement other_message_element = ctx->api.array_to_element(message_element[i] + offset, el_size, true);
GroupElement new_random_element = ctx->api.combine(enc_random_element, other_random_element, true);
GroupElement new_message_element = ctx->api.combine(enc_message_element, other_message_element, true);
- element_to_buffer(ctx, random_buffer[i], new_random_element);
- element_to_buffer(ctx, message_buffer[i], new_message_element);
+ element_to_buffer(ctx, random_buffer[i] + offset, new_random_element);
+ element_to_buffer(ctx, message_buffer[i] + offset, new_message_element);
ctx->api.free_group_element(enc_random_element);
ctx->api.free_group_element(enc_message_element);
@@ -265,23 +271,25 @@ enum cmix_error encrypt_r_and_multiply(struct CMixContext const* ctx, char** ran
enum cmix_error permute_and_multiply_encrypted_s(struct CMixContext const* ctx, char** random_buffer, char** message_buffer, char const** random_element, char const** message_element) {
size_t el_size = get_group_element_array_size(ctx);
-
- for(size_t m = 0; m < ctx->nr_mixes; ++m) {
- for(size_t i = 0; i < ctx->nr_participants; ++i) {
- unsigned int new_pos = ctx->permutation[m][i];
- GroupElement random_r = ctx->api.array_to_element(random_element[i], el_size, true);
- GroupElement message_r = ctx->api.array_to_element(message_element[i], el_size, true);
+
+ for(size_t i = 0; i < ctx->nr_participants; ++i) {
+ for(size_t m = 0; m < ctx->nr_mixes; ++m) {
+ unsigned int new_pos = ctx->permutation[i][m];
+ size_t offset = m * get_group_element_array_size(ctx);
+
+ GroupElement random_r = ctx->api.array_to_element(random_element[i] + offset, el_size, true);
+ GroupElement message_r = ctx->api.array_to_element(message_element[i] + offset, el_size, true);
GroupElement random_s;
GroupElement message_s;
- ctx->api.encrypt(&random_s, &message_s, ctx->s[m][new_pos], ctx->network_key);
+ ctx->api.encrypt(&random_s, &message_s, ctx->s[new_pos][m], ctx->network_key);
GroupElement random_pirs = ctx->api.combine(random_r, random_s, true);
GroupElement message_pirs = ctx->api.combine(message_r, message_s, true);
- element_to_buffer(ctx, random_buffer[new_pos], random_pirs);
- element_to_buffer(ctx, message_buffer[new_pos], message_pirs);
+ element_to_buffer(ctx, random_buffer[new_pos] + offset, random_pirs);
+ element_to_buffer(ctx, message_buffer[new_pos] + offset, message_pirs);
ctx->api.free_group_element(random_r);
ctx->api.free_group_element(message_r);
@@ -298,14 +306,15 @@ enum cmix_error permute_and_multiply_encrypted_s(struct CMixContext const* ctx,
enum cmix_error permute_and_multiply_s(struct CMixContext* ctx, char** out_buffer, char const** message) {
size_t el_size = get_group_element_array_size(ctx);
- for(size_t m = 0; m < ctx->nr_mixes; ++m) {
- for(size_t i = 0; i < ctx->nr_participants; ++i) {
- unsigned int new_pos = ctx->permutation[m][i];
+ for(size_t i = 0; i < ctx->nr_participants; ++i) {
+ for(size_t m = 0; m < ctx->nr_mixes; ++m) {
+ size_t offset = m * get_group_element_array_size(ctx);
+ unsigned int new_pos = ctx->permutation[i][m];
- GroupElement message_el = ctx->api.array_to_element(message[i], el_size, false);
- ctx->PiMRS[new_pos] = ctx->api.combine(message_el, ctx->s[m][new_pos], false);
+ GroupElement message_el = ctx->api.array_to_element(message[i] + offset, el_size, false);
+ ctx->PiMRS[new_pos][m] = ctx->api.combine(message_el, ctx->s[new_pos][m], false);
- element_to_buffer(ctx, out_buffer[new_pos], ctx->PiMRS[new_pos]);
+ element_to_buffer(ctx, out_buffer[new_pos] + offset, ctx->PiMRS[new_pos][m]);
ctx->api.free_group_element(message_el);
}
@@ -318,11 +327,12 @@ enum cmix_error permute_and_multiply_s(struct CMixContext* ctx, char** out_buffe
enum cmix_error multiply_s(struct CMixContext const* ctx, char* out_buffer, char const* message, size_t index) {
for(size_t m = 0; m < ctx->nr_mixes; ++m) {
size_t el_size = get_group_element_array_size(ctx);
+ size_t offset = get_group_element_array_size(ctx);
- GroupElement message_el = ctx->api.array_to_element(message, el_size, false);
+ GroupElement message_el = ctx->api.array_to_element(message + offset, el_size, false);
GroupElement mult = ctx->api.combine(message_el, ctx->s[m][ctx->permutation[m][index]], false);
- element_to_buffer(ctx, out_buffer, mult);
+ element_to_buffer(ctx, out_buffer + offset, mult);
ctx->api.free_group_element(message_el);
ctx->api.free_group_element(mult);
@@ -399,12 +409,14 @@ size_t get_commitment_length(struct CMixContext const* ctx) {
enum cmix_error precomputation_post_process(struct CMixContext* ctx, char* commitment, const char** r_epirs, const char** m_epirs) {
size_t len = get_group_element_array_size(ctx);
- for(size_t m = 0; m < ctx->nr_mixes; ++m) {
- for(size_t i = 0; i < ctx->nr_participants; ++i) {
- GroupElement x = ctx->api.array_to_element(r_epirs[i], get_group_element_array_size(ctx), true);
- ctx->decryption_shares[m][i] = ctx->api.get_decryption_share(x, ctx->keypair.sec);
+ for(size_t i = 0; i < ctx->nr_participants; ++i) {
+ for(size_t m = 0; m < ctx->nr_mixes; ++m) {
+ size_t offset = m * ctx->api.get_group_element_array_size();
- ctx->EPiRS[m][i] = ctx->api.array_to_element(m_epirs[i], len, true);
+ GroupElement x = ctx->api.array_to_element(r_epirs[i] + offset, get_group_element_array_size(ctx), true);
+ ctx->decryption_shares[i][m] = ctx->api.get_decryption_share(x, ctx->keypair.sec);
+
+ ctx->EPiRS[i][m] = ctx->api.array_to_element(m_epirs[i] + offset, len, true);
ctx->api.free_group_element(x);
}
@@ -433,18 +445,23 @@ enum cmix_error blind_message(struct CMixContext const* ctx, char* m_out, char c
if(intermediates == NULL) {
return out_of_memory;
}
-
- intermediates[0] = ctx->api.message_to_element(message, len, true);
-
- for(size_t i = 0; i < nr_nodes; ++i) {
- intermediates[i+1] = ctx->api.combine(intermediates[i], keys[i], false);
+
+ for (size_t i = 0; i < ctx->nr_mixes; ++i) {
+ size_t offset = i * ctx->api.get_group_element_array_size();
+
+ intermediates[0] = ctx->api.message_to_element(message + i*len, len, true);
+
+ for(size_t j = 0; j < nr_nodes; ++j) {
+ intermediates[j+1] = ctx->api.combine(intermediates[j], keys[j], false);
+ }
+
+ element_to_buffer(ctx, m_out + offset, intermediates[nr_nodes]);
+
+ for(size_t j = 0; j < nr_nodes + 1; ++j) {
+ ctx->api.free_group_element(intermediates[j]);
+ }
}
- element_to_buffer(ctx, m_out, intermediates[nr_nodes]);
-
- for(size_t i = 0; i < nr_nodes + 1; ++i) {
- ctx->api.free_group_element(intermediates[i]);
- }
free(intermediates);
return no_error;
@@ -453,17 +470,16 @@ enum cmix_error blind_message(struct CMixContext const* ctx, char* m_out, char c
enum cmix_error swap_k_for_r(struct CMixContext const* ctx, char** out_buffer, const char** message, const GroupElement* key) {
size_t len = get_group_element_array_size(ctx);
- for(size_t m = 0; m < ctx->nr_mixes; ++m) {
- for(size_t i = 0; i < ctx->nr_participants; ++i) {
- GroupElement mes = ctx->api.array_to_element(message[i], len, false);
- GroupElement inv_key = ctx->api.invert(key[i]);
+ for(size_t i = 0; i < ctx->nr_participants; ++i) {
+ for(size_t m = 0; m < ctx->nr_mixes; ++m) {
+ size_t offset = m * get_group_element_array_size(ctx);
+ GroupElement mes = ctx->api.array_to_element(message[i] + offset, len, false);
GroupElement unblinded = ctx->api.uncombine(mes, key[i], false);
- GroupElement blinded = ctx->api.combine(unblinded, ctx->r[m][i], false);
+ GroupElement blinded = ctx->api.combine(unblinded, ctx->r[i][m], false);
- element_to_buffer(ctx, out_buffer[i], blinded);
+ element_to_buffer(ctx, out_buffer[i] + offset, blinded);
ctx->api.free_group_element(mes);
- ctx->api.free_group_element(inv_key);
ctx->api.free_group_element(unblinded);
ctx->api.free_group_element(blinded);
}
@@ -474,9 +490,10 @@ enum cmix_error swap_k_for_r(struct CMixContext const* ctx, char** out_buffer, c
enum cmix_error get_epirs(struct CMixContext const* ctx, char** out_buffer) {
- for(size_t m = 0; m < ctx->nr_mixes; ++m) {
- for(size_t i = 0; i < ctx->nr_participants; ++i) {
- element_to_buffer(ctx, out_buffer[i] + m * get_group_element_array_size(ctx), ctx->EPiRS[m][i]);
+ for(size_t i = 0; i < ctx->nr_participants; ++i) {
+ for(size_t m = 0; m < ctx->nr_mixes; ++m) {
+ size_t offset = m * get_group_element_array_size(ctx);
+ element_to_buffer(ctx, out_buffer[i] + offset, ctx->EPiRS[i][m]);
}
}
@@ -490,11 +507,13 @@ enum cmix_error get_pimrs_commitment(struct CMixContext const* ctx, char* out_bu
}
enum cmix_error decrypt_epirs(struct CMixContext const* ctx, char** out_buffer, const char** epirs) {
- for(size_t m = 0; m < ctx->nr_mixes; ++m) {
- for(size_t i = 0; i < ctx->nr_participants; ++i) {
- GroupElement msg = ctx->api.array_to_element(epirs[i], get_group_element_array_size(ctx), true);
- GroupElement pirs = ctx->api.combine(ctx->decryption_shares[m][i], msg, true);
- element_to_buffer(ctx, out_buffer[i], pirs);
+ for(size_t i = 0; i < ctx->nr_participants; ++i) {
+ for(size_t m = 0; m < ctx->nr_mixes; ++m) {
+ size_t offset = m * get_group_element_array_size(ctx);
+
+ GroupElement msg = ctx->api.array_to_element(epirs[i] + offset, get_group_element_array_size(ctx), true);
+ GroupElement pirs = ctx->api.combine(ctx->decryption_shares[i][m], msg, true);
+ element_to_buffer(ctx, out_buffer[i] + offset, pirs);
ctx->api.free_group_element(msg);
ctx->api.free_group_element(pirs);
@@ -508,25 +527,34 @@ enum cmix_error remove_pirs(struct CMixContext const* ctx, char** out_buffer, co
size_t len = get_group_element_array_size(ctx);
for(size_t i = 0; i < ctx->nr_participants; ++i) {
- GroupElement g_pirs = ctx->api.array_to_element(pirs[i], len, false);
-
- GroupElement mult = ctx->api.uncombine(ctx->PiMRS[i], g_pirs, false);
-
- element_to_buffer(ctx, out_buffer[i], mult);
-
- ctx->api.free_group_element(g_pirs);
- ctx->api.free_group_element(mult);
+ for(size_t m = 0; m < ctx->nr_mixes; ++m) {
+ size_t offset = m * get_group_element_array_size(ctx);
+ GroupElement g_pirs = ctx->api.array_to_element(pirs[i] + offset, len, false);
+
+ GroupElement mult = ctx->api.uncombine(ctx->PiMRS[i][m], g_pirs, false);
+
+ element_to_buffer(ctx, out_buffer[i] + offset, mult);
+
+ ctx->api.free_group_element(g_pirs);
+ ctx->api.free_group_element(mult);
+ }
}
return no_error;
}
enum cmix_error element_to_message(struct CMixContext const* ctx, unsigned char** buffer, char const* element_buffer) {
-
- GroupElement el = ctx->api.array_to_element(element_buffer, ctx->api.get_group_element_array_size(), true);
- ctx->api.element_to_message(buffer, el);
- ctx->api.free_group_element(el);
-
+
+ *buffer = (unsigned char*) calloc(ctx->nr_mixes * get_message_size(ctx), sizeof(unsigned char));
+ for(size_t m = 0; m < ctx->nr_mixes; ++m) {
+ unsigned char* temp;
+ size_t offset = m * get_group_element_array_size(ctx);
+ GroupElement el = ctx->api.array_to_element(element_buffer + offset, get_group_element_array_size(ctx), true);
+ ctx->api.element_to_message(&temp, el);
+ ctx->api.free_group_element(el);
+ memcpy((*buffer) + m * get_message_size(ctx), temp, get_message_size(ctx));
+ }
+
return no_error;
}
@@ -543,11 +571,11 @@ size_t get_pub_key_hash_length(struct CMixContext const* ctx)
enum cmix_error create_message(struct CMixContext const* ctx, char* out_buffer, const char* dest, size_t dest_len, const char* payload, size_t payload_len)
{
- size_t el_arr_len = get_message_size(ctx);
+ size_t el_arr_len = ctx->nr_mixes * get_message_size(ctx);
memcpy(out_buffer, dest, dest_len);
- size_t message_limit = el_arr_len -dest_len;
+ size_t message_limit = el_arr_len - dest_len;
memcpy(out_buffer + dest_len, payload, (message_limit < payload_len ? message_limit : payload_len));
@@ -565,11 +593,12 @@ enum cmix_error split_message(struct CMixContext const* ctx, char** dest_buffer,
}
memcpy(*dest_buffer, message, *dest_len);
- *payload_len = message_len - *dest_len;
+ *payload_len = ctx->nr_mixes * message_len - *dest_len;
*payload_buffer = (char*) calloc(*payload_len, sizeof(char));
if(*payload_buffer == NULL) {
return out_of_memory;
}
+
memcpy(*payload_buffer, &message[*dest_len], *payload_len);
return no_error;
diff --git a/libcmix/cmix.h b/libcmix/cmix.h
index f060762..d35b23f 100644
--- a/libcmix/cmix.h
+++ b/libcmix/cmix.h
@@ -52,7 +52,7 @@ struct CMixContext {
unsigned int** permutation; ///< a permutation (Pi in the paper (called Pi in source)).
GroupElement** decryption_shares; ///< The decryption share for each slot.
GroupElement** EPiRS; ///< stores the current Pi(R) * S for this node. Only usfull for the last node.
- GroupElement* PiMRS; ///< stores the current Pi(M * R) * S for this node. Only usefull for the last node.
+ GroupElement** PiMRS; ///< stores the current Pi(M * R) * S for this node. Only usefull for the last node.
};
/*!
@@ -60,7 +60,7 @@ struct CMixContext {
* \param api The cryptop api to initialize this CMixContext for.
* \return The created and Initialized CMixContext;
*/
-struct CMixContext initialize_cmix_context(struct Api api);
+struct CMixContext initialize_cmix_context(struct Api api, unsigned int nr_mixes);
/*!
* \brief deinitialize deallocates all the context resources and deinitializes the crypto api.
diff --git a/node/main.cpp b/node/main.cpp
index 1e76a1f..e50e997 100644
--- a/node/main.cpp
+++ b/node/main.cpp
@@ -29,6 +29,7 @@ int main(int argc, char* argv[]) {
("certdir", po::value<std::string>(), "Directory containing trusted certificates.")
("statsd,s", po::value<std::string>(), "The address of the statistics daemon.")
("name,a", po::value<std::string>(), "The name to use in the stats daemon file")
+ ("nr_mixes,x", po::value<unsigned int>()->default_value(1), "The number of simultanous mixes the network will perform.")
;
po::variables_map vm;
@@ -126,7 +127,9 @@ int main(int argc, char* argv[]) {
Uri uri = parse_uri(next_node);
- NodeNetworkSettings nsettings{is_first, is_last, uri.host, uri.port, certdir, minimum_nr_messages};
+ unsigned int nr_mixes = vm["nr_mixes"].as<unsigned int>();
+
+ NodeNetworkSettings nsettings{is_first, is_last, uri.host, uri.port, certdir, minimum_nr_messages, nr_mixes};
bool run_stats = vm.count("statsd");
diff --git a/node/node.cpp b/node/node.cpp
index 0249b77..b9006e9 100644
--- a/node/node.cpp
+++ b/node/node.cpp
@@ -23,7 +23,7 @@ Node::Node(ListenSettings const& listen_settings, NodeNetworkSettings network_se
, 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()))
+, cmix_ctx(initialize_cmix_context(get_implementation(), network_settings.nr_mixes))
, shutting_down(false)
{
if(performance_settings.run) {
@@ -31,8 +31,6 @@ Node::Node(ListenSettings const& listen_settings, NodeNetworkSettings network_se
}
initialize_keypair(&cmix_ctx);
-
- cmix_ctx.nr_mixes = 1;
GOOGLE_PROTOBUF_VERIFY_VERSION;
@@ -179,7 +177,7 @@ void Node::start_precomputation() {
ArenaMessage<cmix_proto::PrePre> arena;
cmix_proto::PrePre& prepre = arena.get();
- size_t len = get_group_element_array_size(&cmix_ctx);
+ size_t len = cmix_ctx.nr_mixes * get_group_element_array_size(&cmix_ctx);
std::vector<char*> r_er(cmix_ctx.nr_participants, nullptr);
std::vector<char*> m_er(cmix_ctx.nr_participants, nullptr);
@@ -187,7 +185,7 @@ void Node::start_precomputation() {
std::string* r = prepre.add_r_er();
r->resize(len);
r_er[i] = &(*r)[0];
-
+
std::string* m = prepre.add_m_er();
m->resize(len);
m_er[i] = &(*m)[0];
@@ -227,7 +225,7 @@ void Node::start_realtime_phase() {
ArenaMessage<cmix_proto::RealPre> arena;
cmix_proto::RealPre& realpre = arena.get();
- size_t len = get_group_element_array_size(&cmix_ctx);
+ size_t len = cmix_ctx.nr_mixes * get_group_element_array_size(&cmix_ctx);
std::vector<char*> ms(participants.size(), nullptr);
std::vector<char const*> msv(participants.size(), nullptr);
diff --git a/node/node.hpp b/node/node.hpp
index 335a264..c99af17 100644
--- a/node/node.hpp
+++ b/node/node.hpp
@@ -50,6 +50,7 @@ struct NodeNetworkSettings {
std::string next_port; ///< Next nodes port.
std::string certdir; ///< Directory containing trusted certificate authorities.
unsigned int minimum_nr_messages; ///< The minimum number of available messages before starting to run a mix;
+ unsigned int nr_mixes; ///< The number of simultaneous mixes the network will perform.
};
/*!
diff --git a/node/node_node.cpp b/node/node_node.cpp
index 0086bf7..f44a895 100644
--- a/node/node_node.cpp
+++ b/node/node_node.cpp
@@ -19,7 +19,7 @@ void fill_precomputation_pre_message(CMixContext& ctx, cmix_proto::PrePre& prepr
}
BOOST_LOG_TRIVIAL(trace) << ss.str();
- size_t len = get_group_element_array_size(&ctx);
+ size_t len = ctx.nr_mixes * get_group_element_array_size(&ctx);
std::vector<char*> r_ers(ms.size(), nullptr);
std::vector<char*> m_ers(ms.size(), nullptr);
std::vector<char const*> rsv(ms.size(), nullptr);
@@ -51,7 +51,7 @@ void fill_precomputation_pre_message(CMixContext& ctx, cmix_proto::PrePre& prepr
template <typename T>
void fill_precomputation_mix_message(CMixContext const& ctx, cmix_proto::PreMix& premix, T const& rs, T const& ms) {
- size_t el_len = get_group_element_array_size(&ctx);
+ size_t el_len = ctx.nr_mixes * get_group_element_array_size(&ctx);
std::vector<char*> r_epirs(ms.size(), nullptr);
std::vector<char*> m_epirs(ms.size(), nullptr);
std::vector<char const*> rsv(ms.size(), nullptr);
@@ -127,7 +127,7 @@ void fill_commitments_message(CMixContext& ctx, cmix_proto::Commitments& commits
template <typename T, typename U>
void fill_realtime_pre_message(CMixContext& ctx, cmix_proto::RealPre& realpre, T const& hs, T const& ms, U const& data) {
- size_t len = get_group_element_array_size(&ctx);
+ size_t len = ctx.nr_mixes * get_group_element_array_size(&ctx);
std::vector<char*> msv1(ms.size(), nullptr);
std::vector<char const*> msv2(ms.size(), nullptr);
@@ -155,7 +155,7 @@ void fill_realtime_pre_message(CMixContext& ctx, cmix_proto::RealPre& realpre, T
template <typename T>
void fill_realtime_mix_message(CMixContext& ctx, cmix_proto::RealMix& realmix, T const& ms) {
- size_t len = get_group_element_array_size(&ctx);
+ size_t len = ctx.nr_mixes * get_group_element_array_size(&ctx);
std::vector<char*> mv(ms.size(), nullptr);
std::vector<char const*> msv(ms.size(), nullptr);
for(int i = 0; i < ms.size(); ++i) {
@@ -175,11 +175,11 @@ void fill_realtime_mix_message(CMixContext& ctx, cmix_proto::RealMix& realmix, T
void fill_realtime_post_message(CMixContext& ctx, cmix_proto::RealPost& realpost, cmix_proto::RealMix const& realmix) {
- size_t len = get_group_element_array_size(&ctx);
+ size_t len = ctx.nr_mixes * get_group_element_array_size(&ctx);
std::vector<char*> mv(ctx.nr_participants, nullptr);
for(size_t i = 0; i < ctx.nr_participants; ++i) {
std::string* m = realpost.add_m_epirs();
- m->resize(len * ctx.nr_mixes);
+ m->resize(len);
mv[i] = &(*m)[0];
}
@@ -204,7 +204,7 @@ void fill_realtime_post_message(CMixContext& ctx, cmix_proto::RealPost& realpost
}
void fill_realtime_post_message(CMixContext& ctx, cmix_proto::RealPost& n_realpost, cmix_proto::RealPost const& realpost) {
- size_t len = get_group_element_array_size(&ctx);
+ size_t len = ctx.nr_mixes * get_group_element_array_size(&ctx);
std::vector<char*> mv(ctx.nr_participants, nullptr);
std::vector<char const*> mvs(ctx.nr_participants, nullptr);
for(size_t i = 0; i < ctx.nr_participants; ++i) {
@@ -431,7 +431,7 @@ void Node::handle_node_realpost(cmix_proto::RealPost const& realpost) {
auto& n_realpost = arena.get();
fill_realtime_post_message(cmix_ctx, n_realpost, realpost);
- size_t len = get_group_element_array_size(&cmix_ctx);
+ size_t len = cmix_ctx.nr_mixes * get_group_element_array_size(&cmix_ctx);
std::vector<std::string> message_strings(cmix_ctx.nr_participants);
std::vector<const char*> pirs(cmix_ctx.nr_participants, nullptr);
std::vector<char*> msgs(cmix_ctx.nr_participants, nullptr);
@@ -534,7 +534,7 @@ void Node::handle_node_message(cmix_proto::CMixMessage message)
break;
}
case cmix_proto::CMixMessage::ContentsCase::kCommitments: {
- BOOST_LOG_TRIVIAL(trace) << "Handling PrePost";
+ BOOST_LOG_TRIVIAL(trace) << "Handling Commitments";
handle_node_commitments(message.commitments());
break;
}
diff --git a/run.sh b/run.sh
index 0a81758..37e190f 100755
--- a/run.sh
+++ b/run.sh
@@ -25,18 +25,18 @@ tmux new-session -s cmix -d
#tmux send-keys -t cmix:0 "cd ${build_dir} && LSAN_OPTIONS=report_objects=1 $tool statsd/statsd" Enter
tmux new-window -t cmix:1
-tmux send-keys -t cmix:1 "cd ${build_dir} && ASAN_OPTIONS=detect_odr_violation=0 LSAN_OPTIONS=report_objects=1 $tool node/node -f -m ${nr_clients} -n node2.local:9201 -s localhost:9199 -a node1 -c ../certs/cert1.pem -k ../certs/key1.pem -d ../certs/dh.pem --certdir ../certs/" Enter
+tmux send-keys -t cmix:1 "cd ${build_dir} && ASAN_OPTIONS=detect_odr_violation=0 LSAN_OPTIONS=report_objects=1 $tool node/node -x 2 -f -m ${nr_clients} -n node2.local:9201 -s localhost:9199 -a node1 -c ../certs/cert1.pem -k ../certs/key1.pem -d ../certs/dh.pem --certdir ../certs/" Enter
tmux new-window -t cmix:2
-tmux send-keys -t cmix:2 "cd ${build_dir} && ASAN_OPTIONS=detect_odr_violation=0 LSAN_OPTIONS=report_objects=1 $tool node/node -p 9201 -n node3.local:9202 -s localhost:9199 -a node2 -c ../certs/cert2.pem -k ../certs/key2.pem -d ../certs/dh.pem --certdir ../certs/" Enter
+tmux send-keys -t cmix:2 "cd ${build_dir} && ASAN_OPTIONS=detect_odr_violation=0 LSAN_OPTIONS=report_objects=1 $tool node/node -x 2 -p 9201 -n node3.local:9202 -s localhost:9199 -a node2 -c ../certs/cert2.pem -k ../certs/key2.pem -d ../certs/dh.pem --certdir ../certs/" Enter
tmux new-window -t cmix:3
-tmux send-keys -t cmix:3 "cd ${build_dir} && ASAN_OPTIONS=detect_odr_violation=0 LSAN_OPTIONS=report_objects=1 $tool node/node -l -p 9202 -n node1.local:9200 -s localhost:9199 -a node3 -c ../certs/cert3.pem -k ../certs/key3.pem -d ../certs/dh.pem --certdir ../certs/" Enter
+tmux send-keys -t cmix:3 "cd ${build_dir} && ASAN_OPTIONS=detect_odr_violation=0 LSAN_OPTIONS=report_objects=1 $tool node/node -x 2 -l -p 9202 -n node1.local:9200 -s localhost:9199 -a node3 -c ../certs/cert3.pem -k ../certs/key3.pem -d ../certs/dh.pem --certdir ../certs/" Enter
for i in $(seq 4 $((3+${nr_clients})));
do
tmux new-window -t cmix:${i}
- tmux send-keys -t cmix:${i} "cd ${build_dir} && ASAN_OPTIONS=detect_odr_violation=0 LSAN_OPTIONS=report_objects=1 $tool client/client --certdir ../certs -n node1.local:9200 node2.local:9201 node3.local:9202" Enter
+ tmux send-keys -t cmix:${i} "cd ${build_dir} && ASAN_OPTIONS=detect_odr_violation=0 LSAN_OPTIONS=report_objects=1 $tool client/client -x 2 --certdir ../certs -n node1.local:9200 node2.local:9201 node3.local:9202" Enter
done
tmux select-window -t cmix:4