aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDennis Brentjes <d.brentjes@gmail.com>2016-11-07 12:53:59 +0100
committerDennis Brentjes <d.brentjes@gmail.com>2016-11-07 12:53:59 +0100
commit46f22621759d388f7cef4bf0d2ac03667a5d611e (patch)
treeb26cd49fe2552680eb16d9008695c8f56e757ded
parent7e21069bea9e8e6276591eee98f22cb07d67392d (diff)
downloadcmix-46f22621759d388f7cef4bf0d2ac03667a5d611e.tar.gz
cmix-46f22621759d388f7cef4bf0d2ac03667a5d611e.tar.bz2
cmix-46f22621759d388f7cef4bf0d2ac03667a5d611e.zip
prepares the api for sending and mixing messages in the realtime phase.
-rw-r--r--client/cmixclient.cpp52
-rw-r--r--client/cmixclient.hpp9
-rw-r--r--libcmix-protobuf/cmix.proto12
-rw-r--r--libcmix/cmix.c41
-rw-r--r--libcmix/cmix.h13
-rw-r--r--node/main.cpp4
-rw-r--r--node/node.cpp6
-rw-r--r--node/node.hpp2
-rw-r--r--node/node_client.cpp2
-rw-r--r--node/node_node.cpp15
10 files changed, 108 insertions, 48 deletions
diff --git a/client/cmixclient.cpp b/client/cmixclient.cpp
index ba1a187..ba2f1da 100644
--- a/client/cmixclient.cpp
+++ b/client/cmixclient.cpp
@@ -17,25 +17,12 @@ using namespace boost::asio;
void CMixClient::key_exchange(size_t node_id) {
BOOST_LOG_TRIVIAL(trace) << "Sending KeyExchange for node: " << node_id;
-
- unsigned char* buffer;
- size_t len;
-
- api.element_to_array(&buffer, &len, keypair.pub);
cmix_proto::KeyExchange ke;
- ke.set_public_key(buffer, len);
- api.free_buffer(buffer);
-
- data.at(node_id).secret_value = api.get_group_element(true);
-
- GroupElement shared_value = api.get_key_exchange_value(data.at(node_id).secret_value);
+ ke.mutable_public_key()->resize(get_group_element_array_size(&cmix_ctx));
+ ke.mutable_value()->resize(get_group_element_array_size(&cmix_ctx));
- api.element_to_array(&buffer, &len, shared_value);
- ke.set_value(buffer, len);
- api.free_buffer(buffer);
-
- api.free_group_element(shared_value);
+ key_exchange_init(&cmix_ctx, &(*ke.mutable_public_key())[0], &(*ke.mutable_value())[0], &data.at(node_id).secret_value);
network_connections.at(node_id).async_send(ke);
network_connections.at(node_id).async_receive([node_id, this](cmix_proto::CMixMessage message) {
@@ -59,14 +46,26 @@ void CMixClient::initialize_connections() {
});
};
- network_connections.emplace_back(std::unique_ptr<ssl::stream<tcp::socket>>(new ssl::stream<tcp::socket>(io_service, *ctx)));
+ network_connections.emplace_back(std::unique_ptr<ssl::stream<tcp::socket>>(new ssl::stream<tcp::socket>(io_service, *ssl_ctx)));
network_connections.back().async_connect(network_details.node_details[i].host, network_details.node_details[i].port, handler);
}
}
void CMixClient::handle_key_exchange(size_t node_id, cmix_proto::KeyExchange const& ke)
{
- data.at(node_id).shared_value.shared = api.derive_shared_key(keypair, reinterpret_cast<uint8_t const*>(ke.public_key().c_str()), ke.public_key().size(), reinterpret_cast<uint8_t const*>(ke.value().c_str()), ke.value().size(), data.at(node_id).secret_value, false);
+ key_exchange_initiator(
+ &cmix_ctx,
+ &data.at(node_id).shared_value,
+ ke.public_key().data(),
+ ke.value().data(),
+ data.at(node_id).secret_value
+ );
+
+ size_t len = get_group_element_array_size(&cmix_ctx);
+ std::string s = "abcdefghijklmnopqrstuvwxyz";
+ s.resize(len, '0');
+
+
cmix_proto::Bye bye;
network_connections.at(node_id).async_send(bye);
@@ -104,14 +103,16 @@ void CMixClient::handle_message(size_t node_id, cmix_proto::CMixMessage message)
CMixClient::CMixClient(NetworkDetails details)
: io_service()
-, ctx(std::make_shared<boost::asio::ssl::context>(boost::asio::ssl::context::sslv23))
+, ssl_ctx(std::make_shared<boost::asio::ssl::context>(boost::asio::ssl::context::sslv23))
+, cmix_ctx(initialize_cmix_context(get_implementation()))
, network_details(details)
, network_connections()
-, api(get_implementation())
-, keypair(api.create_keypair())
+, data()
{
+ initialize_keypair(&cmix_ctx);
+
if(!details.certdir.empty()) {
- ctx->add_verify_path(details.certdir);
+ ssl_ctx->add_verify_path(details.certdir);
}
initialize_connections();
@@ -119,12 +120,7 @@ CMixClient::CMixClient(NetworkDetails details)
CMixClient::~CMixClient()
{
- api.free_keypair(&keypair);
- for(auto&& d : data) {
- api.free_shared_key(&d.shared_value);
- api.free_group_element(d.secret_value);
- }
- api.deinitialize();
+ deinitialize(&cmix_ctx);
}
void CMixClient::run() {
diff --git a/client/cmixclient.hpp b/client/cmixclient.hpp
index ee99d38..59aeba6 100644
--- a/client/cmixclient.hpp
+++ b/client/cmixclient.hpp
@@ -1,6 +1,7 @@
#pragma once
#include "senderreceiver.hpp"
+#include "cmix.h"
#include "api.h"
#include "groupelement.h"
#include "keypair.h"
@@ -44,19 +45,17 @@ class CMixClient {
struct NodeData {
GroupElement secret_value;
- SharedKey shared_value;
+ GroupElement shared_value;
};
boost::asio::io_service io_service;
- std::shared_ptr<boost::asio::ssl::context> ctx;
+ std::shared_ptr<boost::asio::ssl::context> ssl_ctx;
+ CMixContext cmix_ctx;
NetworkDetails network_details;
std::vector<SSLSenderReceiver> network_connections;
std::vector<NodeData> data;
- Api api;
- KeyPair keypair;
-
void key_exchange(size_t node_id);
void initialize_connections();
diff --git a/libcmix-protobuf/cmix.proto b/libcmix-protobuf/cmix.proto
index e048fef..9ff5bb2 100644
--- a/libcmix-protobuf/cmix.proto
+++ b/libcmix-protobuf/cmix.proto
@@ -29,6 +29,11 @@ message NodeReady {
}
+message UserMessage {
+ required bytes r_M = 1;
+ required bytes m_M = 2;
+}
+
message PrePre {
repeated bytes r_ER = 1;
repeated bytes m_ER = 2;
@@ -53,8 +58,9 @@ message CMixMessage {
Bye bye = 5;
KeyExchange keyexchange = 6;
NodeReady nodeready = 7;
- PrePre prepre = 8;
- PreMix premix = 9;
- PrePost prepost = 10;
+ UserMessage usermessage = 8;
+ PrePre prepre = 9;
+ PreMix premix = 10;
+ PrePost prepost = 11;
}
}
diff --git a/libcmix/cmix.c b/libcmix/cmix.c
index 28f56db..582fe70 100644
--- a/libcmix/cmix.c
+++ b/libcmix/cmix.c
@@ -45,7 +45,8 @@ struct CMixContext initialize_cmix_context(struct Api api) {
.r = NULL,
.s = NULL,
.permutation = NULL,
- .pirs = NULL
+ .pirs = NULL,
+ .messages = NULL
};
}
@@ -54,17 +55,20 @@ void release_mix(struct CMixContext* ctx) {
ctx->api.free_group_element(ctx->r[i]);
ctx->api.free_group_element(ctx->s[i]);
ctx->api.free_group_element(ctx->pirs[i]);
+ ctx->api.free_group_element(ctx->messages[i]);
}
free(ctx->r);
free(ctx->s);
free(ctx->permutation);
free(ctx->pirs);
+ free(ctx->messages);
}
void deinitialize(struct CMixContext* ctx)
{
ctx->api.free_keypair(&ctx->keypair);
release_mix(ctx);
+ ctx->api.deinitialize();
}
void element_to_buffer(struct CMixContext const* ctx, char* out_buffer, GroupElement element) {
@@ -106,7 +110,8 @@ enum cmix_error alloc_mix(struct CMixContext* ctx) {
ctx->s = (GroupElement*) calloc(ctx->nr_participants, sizeof(GroupElement));
ctx->permutation = (unsigned int*) calloc(ctx->nr_participants, sizeof(unsigned int));
ctx->pirs = (GroupElement*) calloc(ctx->nr_participants, sizeof(GroupElement));
- if(!ctx->r || !ctx->s || !ctx->permutation || !ctx->pirs) {
+ ctx->pirs = (GroupElement*) calloc(ctx->nr_participants, sizeof(GroupElement));
+ if(!ctx->r || !ctx->s || !ctx->permutation || !ctx->pirs || !ctx->messages) {
return out_of_memory;
}
return no_error;
@@ -127,6 +132,11 @@ enum cmix_error initialize_mix_randomness(struct CMixContext* ctx) {
return no_error;
}
+enum cmix_error generate_random_message(struct CMixContext* ctx, size_t index) {
+ ctx->messages[index] = ctx->api.get_group_element(true);
+ return no_error;
+}
+
size_t get_group_element_array_size(struct CMixContext const* ctx) {
return ctx->api.get_group_element_array_size();
}
@@ -200,12 +210,20 @@ enum cmix_error multiply_s(struct CMixContext const* ctx, char* r_out_buffer, ch
return no_error;
}
-enum cmix_error key_exchange(struct CMixContext const* ctx, GroupElement* shared_key, char* public_key_buffer, char* exchange_value_buffer, char const* pubkey, char const* value) {
+enum cmix_error key_exchange_init(struct CMixContext const* ctx, char* pubkey_buffer, char* value_buffer, GroupElement* priv_el) {
+ *priv_el = ctx->api.get_group_element(true);
+ GroupElement value = ctx->api.get_key_exchange_value(priv_el);
+
+ get_public_key(ctx, pubkey_buffer);
+ element_to_buffer(ctx, value_buffer, value);
+ return no_error;
+}
+
+enum cmix_error key_exchange_responder(struct CMixContext const* ctx, GroupElement* shared_key, char* public_key_buffer, char* exchange_value_buffer, char const* pubkey, char const* value) {
GroupElement priv_el = ctx->api.get_group_element(true);
GroupElement ex_val = ctx->api.get_key_exchange_value(priv_el);
size_t el_len = get_group_element_array_size(ctx);
-
*shared_key = ctx->api.derive_shared_key(ctx->keypair, (unsigned char*)pubkey, el_len, (unsigned char*)value, el_len, priv_el, true);
element_to_buffer(ctx, public_key_buffer, ctx->keypair.pub);
@@ -217,15 +235,24 @@ enum cmix_error key_exchange(struct CMixContext const* ctx, GroupElement* shared
return no_error;
}
-enum cmix_error post_process(struct CMixContext* ctx, char const* r_epirs, char const* m_epirs, size_t index) {
- GroupElement x = ctx->api.array_to_element(r_epirs, get_group_element_array_size(ctx), true);
+enum cmix_error key_exchange_initiator(struct CMixContext const* ctx, GroupElement* shared_key, char const* pubkey, char const* value, GroupElement priv_el) {
+ size_t el_len = get_group_element_array_size(ctx);
+ *shared_key = ctx->api.derive_shared_key(ctx->keypair, (unsigned char*)pubkey, el_len, (unsigned char*)value, el_len, priv_el, false);
+ return no_error;
+}
+
+enum cmix_error post_process(struct CMixContext* ctx, char* r_out, char* m_out, char const* r_epirs, char const* m_epirs, size_t index) {
+ GroupElement x = ctx->api.array_to_element(r_epirs, get_group_element_array_size(ctx), true);
GroupElement D = ctx->api.get_decryption_share(x, ctx->keypair.sec);
+ element_to_buffer(ctx, r_out, D);
GroupElement msg = ctx->api.array_to_element(m_epirs, get_group_element_array_size(ctx), true);
GroupElement pirs = ctx->api.multiply(D, msg, true);
+ element_to_buffer(ctx, m_out, pirs);
+
+ ctx->pirs = pirs; // this is not always usable as only the last node will be able to use this effectively, but we store it anyways.
- ctx->pirs[index] = pirs;
ctx->api.free_group_element(x);
ctx->api.free_group_element(D);
ctx->api.free_group_element(msg);
diff --git a/libcmix/cmix.h b/libcmix/cmix.h
index 433c3bc..7442369 100644
--- a/libcmix/cmix.h
+++ b/libcmix/cmix.h
@@ -78,6 +78,7 @@ struct CMixContext {
GroupElement* s;
unsigned int* permutation;
GroupElement* pirs;
+ GroupElement* messages;
};
struct CMixContext initialize_cmix_context(struct Api api);
@@ -94,6 +95,8 @@ enum cmix_error start_mix(struct CMixContext* ctx, size_t nr_participants);
enum cmix_error initialize_mix_randomness(struct CMixContext* ctx);
+enum cmix_error generate_random_message(struct CMixContext* ctx, size_t index);
+
size_t get_group_element_array_size(struct CMixContext const* ctx);
enum cmix_error set_network_key(struct CMixContext* ctx, char const* buffer, size_t len);
@@ -104,9 +107,15 @@ enum cmix_error encrypt_r_and_multiply(struct CMixContext const* ctx, char* rand
enum cmix_error multiply_s(struct CMixContext const* ctx, char* r_out_buffer, char* m_out_buffer, char const* r_in_buffer, char const* m_in_buffer, size_t index);
-enum cmix_error key_exchange(struct CMixContext const* ctx, GroupElement* shared_key, char* public_key_buffer, char* exhange_value_buffer, char const* pubkey, char const* value);
+enum cmix_error get_key_exchange_value(struct CMixContext const* ctx, char* buffer, GroupElement priv_element);
+
+enum cmix_error key_exchange_init(struct CMixContext const* ctx, char* pubkey_buffer, char* value_buffer, GroupElement* secret_value);
+
+enum cmix_error key_exchange_responder(struct CMixContext const* ctx, GroupElement* shared_key, char* public_key_buffer, char* exhange_value_buffer, char const* pubkey, char const* value);
+
+enum cmix_error key_exchange_initiator(struct CMixContext const* ctx, GroupElement* shared_key, char const* pubkey, char const* value, GroupElement priv_el);
-enum cmix_error post_process(struct CMixContext* ctx, char const* r_epirs, char const* m_epirs, size_t index);
+enum cmix_error post_process(struct CMixContext* ctx, char* r_out, char* m_out, char const* r_epirs, char const* m_epirs, size_t index);
#ifdef __cplusplus
} // extern "C"
diff --git a/node/main.cpp b/node/main.cpp
index 0c81312..28ef60c 100644
--- a/node/main.cpp
+++ b/node/main.cpp
@@ -21,6 +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.")
("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.")
@@ -92,6 +93,7 @@ int main(int argc, char* argv[]) {
BOOST_LOG_TRIVIAL(info) << "Started node";
bool is_first = bool(vm.count("first"));
+ bool is_last = bool(vm.count("last"));
std::string next_node;
if(vm.count("next_node")) {
next_node = vm["next_node"].as<std::string>();
@@ -112,7 +114,7 @@ int main(int argc, char* argv[]) {
Uri uri = parse_uri(next_node);
- NodeNetworkSettings nsettings{is_first, uri.host, uri.port, certdir};
+ NodeNetworkSettings nsettings{is_first, is_last, uri.host, uri.port, certdir};
Node node(lsettings, nsettings);
node.run();
diff --git a/node/node.cpp b/node/node.cpp
index fa9a721..b5c8506 100644
--- a/node/node.cpp
+++ b/node/node.cpp
@@ -135,6 +135,12 @@ void Node::start_precomputation() {
exit(-1);
}
+ 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) {
exit(-1);
}
diff --git a/node/node.hpp b/node/node.hpp
index ea73121..a4c7992 100644
--- a/node/node.hpp
+++ b/node/node.hpp
@@ -24,6 +24,7 @@
*/
struct NodeNetworkSettings {
bool is_first; ///< Are we the first node in the network.
+ bool is_last; ///< Are we the last node in the network.
std::string next_host; ///< Next nodes host.
std::string next_port; ///< Next nodes port.
std::string certdir; ///< Directory containing trusted certificate authorities.
@@ -71,6 +72,7 @@ class Node
CMixContext cmix_ctx;
std::vector<MixData> precomputation_data;
+ std::map<std::string, int> index_map;
bool shutting_down;
diff --git a/node/node_client.cpp b/node/node_client.cpp
index fef1937..f60c48d 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(&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.shared, &(*nke.mutable_public_key())[0], &(*nke.mutable_value())[0], ke.public_key().data(), ke.value().data());
data[handle] = d;
diff --git a/node/node_node.cpp b/node/node_node.cpp
index fecc4ad..eea9eb0 100644
--- a/node/node_node.cpp
+++ b/node/node_node.cpp
@@ -60,7 +60,20 @@ cmix_proto::PrePost fill_precomputation_post_message(CMixContext& ctx, T const&
cmix_proto::PrePost prepost;
for(size_t i = 0; i < ctx.nr_participants; ++i) {
- post_process(&ctx, rs.Get(i).data(), ms.Get(i).data(), i);
+ size_t el_len = get_group_element_array_size(&ctx);
+
+ prepost.mutable_r_epirs(i)->resize(el_len);
+ prepost.mutable_m_epirs(i)->resize(el_len);
+
+ post_process(
+ &ctx,
+ &(*prepost.mutable_r_epirs(i))[0],
+ &(*prepost.mutable_m_epirs(i))[0],
+ rs.Get(i).data(),
+ ms.Get(i).data(),
+ i
+ );
+
*prepost.mutable_r_epirs(i) = rs.Get(i);
*prepost.mutable_m_epirs(i) = ms.Get(i);
}