aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDennis Brentjes <d.brentjes@gmail.com>2016-11-12 13:48:30 +0100
committerDennis Brentjes <d.brentjes@gmail.com>2016-11-12 13:48:30 +0100
commitf93d52bbd0053574fb35d72b85c4b299dc1f3ee5 (patch)
tree4a2120a162ce9161d70074fd9ffa3ed21d80a40e
parent8ff9babe2da4a2efc8529e800a6093fbd0327286 (diff)
downloadcmix-f93d52bbd0053574fb35d72b85c4b299dc1f3ee5.tar.gz
cmix-f93d52bbd0053574fb35d72b85c4b299dc1f3ee5.tar.bz2
cmix-f93d52bbd0053574fb35d72b85c4b299dc1f3ee5.zip
Fixes decryption share calculation, adds lots of debugging statements.
-rw-r--r--client/cmixclient.cpp19
-rw-r--r--libcmix-common/CMakeLists.txt2
-rw-r--r--libcmix-common/cmixprotofunctor.hpp14
-rw-r--r--libcmix-common/senderreceiver.cpp1
-rw-r--r--libcmix-crypto/api.h6
-rw-r--r--libcmix-crypto/elgamal/elgamal.c1
-rw-r--r--libcmix-crypto/elgamal/elgamal.h2
-rw-r--r--libcmix-crypto/elgamal/gcrypt/gcrypt_elgamal.c82
-rw-r--r--libcmix-protobuf/cmix.proto11
-rw-r--r--libcmix/cmix.c73
-rw-r--r--libcmix/cmix.h19
-rw-r--r--liblog/logging.cpp2
-rw-r--r--node/main.cpp2
-rw-r--r--node/node.cpp67
-rw-r--r--node/node.hpp39
-rw-r--r--node/node_client.cpp15
-rw-r--r--node/node_node.cpp157
17 files changed, 435 insertions, 77 deletions
diff --git a/client/cmixclient.cpp b/client/cmixclient.cpp
index f8ecf7d..d7e1387 100644
--- a/client/cmixclient.cpp
+++ b/client/cmixclient.cpp
@@ -63,21 +63,26 @@ void CMixClient::handle_key_exchange(size_t node_id, cmix_proto::KeyExchange con
&secret_values.at(node_id)
);
- size_t len = get_group_element_array_size(&cmix_ctx);
- std::vector<char> vec(len, '\0');
- std::string s = "abcdefghijklmnopqrstuvwxyz";
- std::copy_n(s.begin(), s.size(), vec.begin() + 1);
-
if(std::all_of(shared_values.begin(), shared_values.end(), [](auto const& value){return value != nullptr;})) {
+ size_t len = get_group_element_array_size(&cmix_ctx);
+ std::vector<char> vec(len, '\0');
+ std::string s = "\1";
+ std::copy_n(s.begin(), s.size(), vec.begin() + 1);
+
cmix_proto::UserMessage message;
message.mutable_m()->resize(len);
blind_message(&cmix_ctx, &(*message.mutable_m())[0], vec.data(), shared_values.data(), shared_values.size());
+ BOOST_LOG_TRIVIAL(trace) << "sending UserMessage: " << message.ShortDebugString();
network_connections.at(0).async_send(message);
- cmix_proto::Bye bye;
- network_connections.at(node_id).async_send(bye);
+ size_t last_node_id = network_details.node_details.size() - 1;
+ network_connections.at(last_node_id).async_receive(
+ [this, last_node_id](cmix_proto::CMixMessage const& message) {
+ handle_message(last_node_id, message);
+ }
+ );
}
}
diff --git a/libcmix-common/CMakeLists.txt b/libcmix-common/CMakeLists.txt
index cc3125c..71aa472 100644
--- a/libcmix-common/CMakeLists.txt
+++ b/libcmix-common/CMakeLists.txt
@@ -3,7 +3,7 @@ add_library(cmix-common
cmixprotofunctor.hpp
receiver.hpp
sender.hpp
- senderreceiver.hpp senderreceiver.cpp
+ senderreceiver.hpp
)
target_include_directories(cmix-common
diff --git a/libcmix-common/cmixprotofunctor.hpp b/libcmix-common/cmixprotofunctor.hpp
index effa8bd..0055593 100644
--- a/libcmix-common/cmixprotofunctor.hpp
+++ b/libcmix-common/cmixprotofunctor.hpp
@@ -37,9 +37,19 @@ struct CMixProtoFunctor {
return m; \
} \
+ /*!
+ * \def MESSAGE_SETTER_DEF_ITERATION(Z, N, DATA)
+ * Defines one iteration of the Repeat below,
+ * \param Z level over repeat we are using it should be 1.
+ * \param N current iteration
+ * \param The sequence consisiting of "pairs" of TYPE, NAME
+ */
#define MESSAGE_SETTER_DEF_ITERATION(Z, N, DATA) \
MESSAGE_SETTER_DEF(BOOST_PP_SEQ_ELEM(BOOST_PP_MUL(N, 2), DATA), BOOST_PP_SEQ_ELEM(BOOST_PP_ADD(BOOST_PP_MUL(N, 2), 1), DATA))
+ /*!
+ * Loops over the length of the variadic macro parameter / 2
+ */
#define MESSAGE_SETTER_DEFS(...) \
BOOST_PP_REPEAT(BOOST_PP_DIV(BOOST_PP_VARIADIC_SIZE(__VA_ARGS__), 2), MESSAGE_SETTER_DEF_ITERATION, BOOST_PP_VARIADIC_TO_SEQ(__VA_ARGS__))
@@ -54,7 +64,9 @@ struct CMixProtoFunctor {
UserMessage, usermessage,
PrePre, prepre,
PreMix, premix,
- PrePost, prepost
+ PrePost, prepost,
+ RealPre, realpre,
+ RealMix, realmix,
)
#undef MESSAGE_SETTER_DEFS
#undef MESSAGE_SETTER_DEF_ITERATION
diff --git a/libcmix-common/senderreceiver.cpp b/libcmix-common/senderreceiver.cpp
deleted file mode 100644
index 8b13789..0000000
--- a/libcmix-common/senderreceiver.cpp
+++ /dev/null
@@ -1 +0,0 @@
-
diff --git a/libcmix-crypto/api.h b/libcmix-crypto/api.h
index addf9e3..98c81a1 100644
--- a/libcmix-crypto/api.h
+++ b/libcmix-crypto/api.h
@@ -98,6 +98,11 @@ typedef void (*Encrypter)(GroupElement*, GroupElement*, GroupElement, GroupEleme
/*!
*
*/
+typedef GroupElement (*Inverter)(GroupElement);
+
+/*!
+ *
+ */
typedef GroupElement (*DecryptionShareGetter)(GroupElement, GroupElement);
/*!
@@ -120,6 +125,7 @@ struct Api {
SharedKeyDeriver derive_shared_key; ///< Pointer to shared key derivation function
SharedKeyDeleter free_shared_key; ///< Pointer to shared key deleter function
Encrypter encrypt; ///< encrypt value with key;
+ Inverter invert; ///< Invert the group element;
Deinitializer deinitialize; ///< Function that will deinitialize the crypto library.
};
diff --git a/libcmix-crypto/elgamal/elgamal.c b/libcmix-crypto/elgamal/elgamal.c
index dbfccb9..1525618 100644
--- a/libcmix-crypto/elgamal/elgamal.c
+++ b/libcmix-crypto/elgamal/elgamal.c
@@ -20,6 +20,7 @@ struct Api get_elgamal_implementation()
.derive_shared_key = elgamal_derive_shared_key,
.free_shared_key = elgamal_delete_shared_key,
.encrypt = elgamal_encrypt,
+ .invert = elgamal_invert,
.deinitialize = elgamal_deinitialize
};
}
diff --git a/libcmix-crypto/elgamal/elgamal.h b/libcmix-crypto/elgamal/elgamal.h
index 21bf58a..1fcb044 100644
--- a/libcmix-crypto/elgamal/elgamal.h
+++ b/libcmix-crypto/elgamal/elgamal.h
@@ -42,6 +42,8 @@ extern SharedKeyDeleter elgamal_delete_shared_key;
extern Encrypter elgamal_encrypt;
+extern Inverter elgamal_invert;
+
extern Deinitializer elgamal_deinitialize;
/*!
diff --git a/libcmix-crypto/elgamal/gcrypt/gcrypt_elgamal.c b/libcmix-crypto/elgamal/gcrypt/gcrypt_elgamal.c
index 1824ccc..8a6fb7e 100644
--- a/libcmix-crypto/elgamal/gcrypt/gcrypt_elgamal.c
+++ b/libcmix-crypto/elgamal/gcrypt/gcrypt_elgamal.c
@@ -9,6 +9,7 @@
static gcry_mpi_t p;
static gcry_mpi_t q;
static gcry_mpi_t g;
+static unsigned int nr_bytes = 2;
void check(gcry_error_t error) {
if (error) {
@@ -44,9 +45,13 @@ void gcrypt_elgamal_initialize(void) {
gcry_control (GCRYCTL_INITIALIZATION_FINISHED, 0);
//leading 0 as specified by libgcrypt
- char p_hex[] = "087A8E61DB4B6663CFFBBD19C651959998CEEF608660DD0F25D2CEED4435E3B00E00DF8F1D61957D4FAF7DF4561B2AA3016C3D91134096FAA3BF4296D830E9A7C209E0C6497517ABD5A8A9D306BCF67ED91F9E6725B4758C022E0B1EF4275BF7B6C5BFC11D45F9088B941F54EB1E59BB8BC39A0BF12307F5C4FDB70C581B23F76B63ACAE1CAA6B7902D52526735488A0EF13C6D9A51BFA4AB3AD8347796524D8EF6A167B5A41825D967E144E5140564251CCACB83E6B486F6B3CA3F7971506026C0B857F689962856DED4010ABD0BE621C3A3960A54E710C375F26375D7014103A4B54330C198AF126116D2276E11715F693877FAD7EF09CADB094AE91E1A1597";
- char q_hex[] = "08CF83642A709A097B447997640129DA299B1A47D1EB3750BA308B0FE64F5FBD3";
- char g_hex[] = "03FB32C9B73134D0B2E77506660EDBD484CA7B18F21EF205407F4793A1A0BA12510DBC15077BE463FFF4FED4AAC0BB555BE3A6C1B0C6B47B1BC3773BF7E8C6F62901228F8C28CBB18A55AE31341000A650196F931C77A57F2DDF463E5E9EC144B777DE62AAAB8A8628AC376D282D6ED3864E67982428EBC831D14348F6F2F9193B5045AF2767164E1DFC967C1FB3F2E55A4BD1BFFE83B9C80D052B985D182EA0ADB2A3B7313D3FE14C8484B1E052588B9B7D2BBD2DF016199ECD06E1557CD0915B3353BBB64E0EC377FD028370DF92B52C7891428CDC67EB6184B523D1DB246C32F63078490F00EF8D647D148D47954515E2327CFEF98C582664B4C0F6CC41659";
+ //char p_hex[] = "087A8E61DB4B6663CFFBBD19C651959998CEEF608660DD0F25D2CEED4435E3B00E00DF8F1D61957D4FAF7DF4561B2AA3016C3D91134096FAA3BF4296D830E9A7C209E0C6497517ABD5A8A9D306BCF67ED91F9E6725B4758C022E0B1EF4275BF7B6C5BFC11D45F9088B941F54EB1E59BB8BC39A0BF12307F5C4FDB70C581B23F76B63ACAE1CAA6B7902D52526735488A0EF13C6D9A51BFA4AB3AD8347796524D8EF6A167B5A41825D967E144E5140564251CCACB83E6B486F6B3CA3F7971506026C0B857F689962856DED4010ABD0BE621C3A3960A54E710C375F26375D7014103A4B54330C198AF126116D2276E11715F693877FAD7EF09CADB094AE91E1A1597";
+ //char q_hex[] = "08CF83642A709A097B447997640129DA299B1A47D1EB3750BA308B0FE64F5FBD3";
+ //char g_hex[] = "03FB32C9B73134D0B2E77506660EDBD484CA7B18F21EF205407F4793A1A0BA12510DBC15077BE463FFF4FED4AAC0BB555BE3A6C1B0C6B47B1BC3773BF7E8C6F62901228F8C28CBB18A55AE31341000A650196F931C77A57F2DDF463E5E9EC144B777DE62AAAB8A8628AC376D282D6ED3864E67982428EBC831D14348F6F2F9193B5045AF2767164E1DFC967C1FB3F2E55A4BD1BFFE83B9C80D052B985D182EA0ADB2A3B7313D3FE14C8484B1E052588B9B7D2BBD2DF016199ECD06E1557CD0915B3353BBB64E0EC377FD028370DF92B52C7891428CDC67EB6184B523D1DB246C32F63078490F00EF8D647D148D47954515E2327CFEF98C582664B4C0F6CC41659";
+
+ char p_hex[] = "0b";
+ char q_hex[] = "00";
+ char g_hex[] = "02";
size_t nr_bytes_scanned;
gcry_error_t error;
@@ -66,11 +71,15 @@ struct KeyPair gcrypt_elgamal_create_keypair() {
size_t parse_error_offset;
gcry_error_t error;
- void* bytes = gcry_random_bytes_secure(2048/8, GCRY_VERY_STRONG_RANDOM);
- gcry_mpi_t x;
- error = gcry_mpi_scan(&x, GCRYMPI_FMT_USG, bytes, 2048/8, &parse_error_offset);
- check(error);
-
+ gcry_mpi_t x = NULL;
+ do {
+ gcry_mpi_release(x);
+ void* bytes = gcry_random_bytes_secure(nr_bytes, GCRY_VERY_STRONG_RANDOM);
+ error = gcry_mpi_scan(&x, GCRYMPI_FMT_USG, bytes, nr_bytes, &parse_error_offset);
+ gcry_free(bytes);
+ check(error);
+ gcry_mpi_mod(x, x, p); //bias needs to be removed.
+ } while(gcry_mpi_cmp_ui(x, 0) == 0 || gcry_mpi_cmp(x, p) != -1);
gcry_mpi_t y = gcry_mpi_new(0);
gcry_mpi_powm(y, g, x, p);
@@ -82,7 +91,6 @@ struct KeyPair gcrypt_elgamal_create_keypair() {
check(error);
gcry_sexp_release(priv_key);
- gcry_free(bytes);
return (struct KeyPair){
x,
@@ -115,7 +123,7 @@ void* gcrypt_elgamal_array_to_element(char const* buffer, size_t len, bool secur
gcry_mpi_t mpi;
error = gcry_mpi_scan(&mpi, GCRYMPI_FMT_USG, buffer, len, &error_pos);
- gcry_mpi_set_flag(mpi, GCRYMPI_FLAG_SECURE);
+ //gcry_mpi_set_flag(mpi, GCRYMPI_FLAG_SECURE);
check(error);
return mpi;
@@ -125,14 +133,18 @@ void* gcrypt_elgamal_get_group_element(bool secure) {
size_t parse_error_offset;
gcry_error_t error;
- void* bytes = gcry_random_bytes_secure(2048/8, GCRY_VERY_STRONG_RANDOM);
- gcry_mpi_t a;
- error = gcry_mpi_scan(&a, GCRYMPI_FMT_USG, bytes, 2048/8, &parse_error_offset);
+ gcry_mpi_t a = NULL;
+ do {
+ gcry_mpi_release(a);
+ void* bytes = gcry_random_bytes_secure(nr_bytes, GCRY_VERY_STRONG_RANDOM);
+ error = gcry_mpi_scan(&a, GCRYMPI_FMT_USG, bytes, nr_bytes, &parse_error_offset);
+ check(error);
+ gcry_mpi_mod(a, a, p); //BIAS REMOVE THIS.
+ gcry_free(bytes);
+ } while(gcry_mpi_cmp_ui(a, 0) == 0 || gcry_mpi_cmp(a, p) != -1);
//random bytes generated with GCRY{,_VERY}_STRONG_RANDOM are generated in "secure memory"
//so secure is unused.
- check(error);
- gcry_free(bytes);
return a;
}
@@ -153,17 +165,21 @@ GroupElement gcrypt_elgamal_multiply(GroupElement lh, GroupElement rh, bool secu
}
GroupElement gcrypt_elgamal_get_decryption_share(GroupElement r, GroupElement e) {
- gcry_mpi_t inve = gcry_mpi_snew(0);
- gcry_mpi_invm(inve, (gcry_mpi_t)e, p);
+ //gcry_mpi_t inve = gcry_mpi_snew(0);
+ //gcry_mpi_invm(inve, (gcry_mpi_t)e, p);
+
+ gcry_mpi_t inv_d = gcry_mpi_snew(0);
+ gcry_mpi_powm(inv_d, (gcry_mpi_t)r, (gcry_mpi_t)e, p);
gcry_mpi_t d = gcry_mpi_snew(0);
- gcry_mpi_powm(d, (gcry_mpi_t)r, inve, p);
- gcry_mpi_release(inve);
+ gcry_mpi_invm(d, inv_d, p);
+
+ gcry_mpi_release(inv_d);
return d;
}
size_t gcrypt_elgamal_get_group_element_array_size() {
- return 256u;
+ return nr_bytes;
}
void gcrypt_elgamal_delete_group_element(void* el) {
@@ -213,7 +229,22 @@ void gcrypt_elgamal_delete_shared_key(struct SharedKey* s) {
}
void gcrypt_elgamal_encrypt(GroupElement* random_element, GroupElement* message_element, GroupElement value, GroupElement key) {
- gcry_error_t error;
+
+ GroupElement random = gcrypt_elgamal_get_group_element(true);
+
+ *random_element = gcry_mpi_new(0);
+ gcry_mpi_powm((gcry_mpi_t) *random_element, g, (gcry_mpi_t) random, p);
+
+ gcry_mpi_t key_pow_random = gcry_mpi_snew(0);
+ gcry_mpi_powm(key_pow_random, (gcry_mpi_t) key, (gcry_mpi_t) random, p);
+
+ *message_element = gcry_mpi_snew(0);
+ gcry_mpi_mulm((gcry_mpi_t)*message_element, (gcry_mpi_t) value, key_pow_random, p);
+
+ gcry_mpi_release((gcry_mpi_t) random);
+ gcry_mpi_release(key_pow_random);
+
+/* gcry_error_t error;
size_t parse_error_pos;
gcry_sexp_t pubkey_expr;
@@ -232,7 +263,13 @@ void gcrypt_elgamal_encrypt(GroupElement* random_element, GroupElement* message_
gcry_sexp_release(enc_expr);
gcry_sexp_release(value_expr);
- gcry_sexp_release(pubkey_expr);
+ gcry_sexp_release(pubkey_expr); */
+}
+
+GroupElement gcrypt_elgamal_invert(GroupElement const x) {
+ gcry_mpi_t inv_x = gcry_mpi_new(0);
+ gcry_mpi_invm(inv_x, (gcry_mpi_t)x, p);
+ return inv_x;
}
void gcrypt_elgamal_deinitialize(void) {
@@ -257,4 +294,5 @@ PublicShareAdder elgamal_add_public_share = &gcrypt_elgamal_add_public_share;
SharedKeyDeriver elgamal_derive_shared_key = &gcrypt_elgamal_derive_shared_key;
SharedKeyDeleter elgamal_delete_shared_key = &gcrypt_elgamal_delete_shared_key;
Encrypter elgamal_encrypt = &gcrypt_elgamal_encrypt;
+Inverter elgamal_invert = &gcrypt_elgamal_invert;
Deinitializer elgamal_deinitialize = &gcrypt_elgamal_deinitialize; \ No newline at end of file
diff --git a/libcmix-protobuf/cmix.proto b/libcmix-protobuf/cmix.proto
index ce1f2c2..8bb1d42 100644
--- a/libcmix-protobuf/cmix.proto
+++ b/libcmix-protobuf/cmix.proto
@@ -48,6 +48,15 @@ message PrePost {
repeated bytes m_EPiRS = 2;
}
+message RealPre {
+ repeated bytes h = 1;
+ repeated bytes m = 2;
+}
+
+message RealMix {
+ repeated bytes m = 2;
+}
+
message CMixMessage {
oneof contents {
Initialization initialization = 1;
@@ -61,5 +70,7 @@ message CMixMessage {
PrePre prepre = 9;
PreMix premix = 10;
PrePost prepost = 11;
+ RealPre realpre = 12;
+ RealMix realmix = 13;
}
}
diff --git a/libcmix/cmix.c b/libcmix/cmix.c
index a47a9fa..4465011 100644
--- a/libcmix/cmix.c
+++ b/libcmix/cmix.c
@@ -46,7 +46,6 @@ struct CMixContext initialize_cmix_context(struct Api api) {
.s = NULL,
.permutation = NULL,
.pirs = NULL,
- .messages = NULL
};
}
@@ -55,13 +54,11 @@ 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)
@@ -71,7 +68,7 @@ void deinitialize(struct CMixContext* ctx)
ctx->api.deinitialize();
}
-void element_to_buffer(struct CMixContext const* ctx, char* out_buffer, GroupElement element) {
+void element_to_buffer(struct CMixContext const* ctx, char* out_buffer, GroupElement const element) {
size_t el_size = get_group_element_array_size(ctx);
unsigned char* buffer;
@@ -110,8 +107,7 @@ 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));
- ctx->pirs = (GroupElement*) calloc(ctx->nr_participants, sizeof(GroupElement));
- if(!ctx->r || !ctx->s || !ctx->permutation || !ctx->pirs || !ctx->messages) {
+ if(!ctx->r || !ctx->s || !ctx->permutation || !ctx->pirs) {
return out_of_memory;
}
return no_error;
@@ -132,8 +128,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);
+enum cmix_error generate_random_message(struct CMixContext* ctx, char* buffer) {
+ GroupElement el = ctx->api.get_group_element(true);
+ element_to_buffer(ctx, buffer, el);
+ ctx->api.free_group_element(el);
+
return no_error;
}
@@ -185,7 +184,7 @@ enum cmix_error encrypt_r_and_multiply(struct CMixContext const* ctx, char* rand
return no_error;
}
-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 multiply_encrypted_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) {
size_t el_size = get_group_element_array_size(ctx);
GroupElement random_r = ctx->api.array_to_element(r_in_buffer, el_size, true);
@@ -210,9 +209,23 @@ enum cmix_error multiply_s(struct CMixContext const* ctx, char* r_out_buffer, ch
return no_error;
}
+enum cmix_error multiply_s(struct CMixContext const* ctx, char* out_buffer, char const* message, size_t index) {
+ size_t el_size = get_group_element_array_size(ctx);
+
+ GroupElement message_el = ctx->api.array_to_element(message, el_size, false);
+ GroupElement mult = ctx->api.multiply(message_el, ctx->s[ctx->permutation[index]], false);
+
+ element_to_buffer(ctx, out_buffer, mult);
+
+ ctx->api.free_group_element(message_el);
+ ctx->api.free_group_element(mult);
+
+ return no_error;
+}
+
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);
+ GroupElement value = ctx->api.get_key_exchange_value(*priv_el);
get_public_key(ctx, pubkey_buffer);
element_to_buffer(ctx, value_buffer, value);
@@ -239,7 +252,7 @@ enum cmix_error key_exchange_responder(struct CMixContext const* ctx, GroupEleme
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);
+ *shared_key = ctx->api.derive_shared_key(ctx->keypair, (unsigned char*)pubkey, el_len, (unsigned char*)value, el_len, *priv_el, false);
ctx->api.free_group_element(*priv_el);
*priv_el = NULL;
@@ -250,17 +263,20 @@ enum cmix_error key_exchange_initiator(struct CMixContext const* ctx, GroupEleme
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);
+ //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);
+ GroupElement new_r = ctx->api.multiply(x, D, true);
+ element_to_buffer(ctx, r_out, new_r);
ctx->pirs[index] = pirs; // this is not always usable as only the last node will be able to use this effectively, but we store it anyways.
ctx->api.free_group_element(x);
ctx->api.free_group_element(D);
ctx->api.free_group_element(msg);
+ ctx->api.free_group_element(new_r);
return no_error;
}
@@ -280,3 +296,36 @@ enum cmix_error blind_message(struct CMixContext const* ctx, char* m_out, char c
return no_error;
}
+
+enum cmix_error swap_k_for_r(struct CMixContext const* ctx, char* out_buffer, char const* message, GroupElement const key, size_t index) {
+ size_t len = get_group_element_array_size(ctx);
+
+ GroupElement mes = ctx->api.array_to_element(message, len, false);
+ GroupElement inv_key = ctx->api.invert(key);
+
+ GroupElement unblinded = ctx->api.multiply(mes, inv_key, false);
+ GroupElement blinded = ctx->api.multiply(unblinded, ctx->r[index], false);
+
+ element_to_buffer(ctx, out_buffer, 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);
+
+ return no_error;
+}
+
+enum cmix_error remove_r_and_s(struct CMixContext const* ctx, char* out_buffer, char const* message, size_t index) {
+ size_t len = get_group_element_array_size(ctx);
+
+ GroupElement mes = ctx->api.array_to_element(message, len, false);
+ GroupElement inv_pirs = ctx->api.invert(ctx->pirs[index]);
+
+ GroupElement mult = ctx->api.multiply(mes, inv_pirs, false);
+
+ element_to_buffer(ctx, out_buffer, mult);
+
+ ctx->api.free_group_element(mes);
+ ctx->api.free_group_element(inv_pirs);
+ ctx->api.free_group_element(mult);
+}
diff --git a/libcmix/cmix.h b/libcmix/cmix.h
index 33b99d2..ba0b826 100644
--- a/libcmix/cmix.h
+++ b/libcmix/cmix.h
@@ -78,9 +78,12 @@ struct CMixContext {
GroupElement* s;
unsigned int* permutation;
GroupElement* pirs;
- GroupElement* messages;
};
+#ifndef NDEBUG
+void element_to_buffer(struct CMixContext const* ctx, char* buffer, GroupElement const element);
+#endif
+
struct CMixContext initialize_cmix_context(struct Api api);
void deinitialize(struct CMixContext* ctx);
@@ -95,7 +98,7 @@ 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);
+enum cmix_error generate_random_message(struct CMixContext* ctx, char* buffer);
size_t get_group_element_array_size(struct CMixContext const* ctx);
@@ -105,7 +108,9 @@ enum cmix_error encrypt_r(struct CMixContext const* ctx, char* random_buffer, ch
enum cmix_error encrypt_r_and_multiply(struct CMixContext const* ctx, char* random_buffer, char* message_buffer, char const* random_element, char const* message_element, size_t index);
-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 multiply_encrypted_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 multiply_s(struct CMixContext const* ctx, char* out_buffer, char const* message, size_t index);
enum cmix_error get_key_exchange_value(struct CMixContext const* ctx, char* buffer, GroupElement priv_element);
@@ -119,6 +124,14 @@ enum cmix_error post_process(struct CMixContext* ctx, char* r_out, char* m_out,
enum cmix_error blind_message(struct CMixContext const* ctx, char* m_out, char const* message, GroupElement const* keys, size_t const nr_nodes);
+enum cmix_error enqueue_message(struct CMixContext* ctx, char const* message, size_t index);
+
+enum cmix_error enqueue_random_message(struct CMixContext* ctx, size_t index);
+
+enum cmix_error swap_k_for_r(struct CMixContext const* ctx, char* out_buffer, char const* message, GroupElement const key, size_t index);
+
+enum cmix_error remove_r_and_s(struct CMixContext const* ctx, char* out_buffer, char const* message, size_t index);
+
#ifdef __cplusplus
} // extern "C"
#endif
diff --git a/liblog/logging.cpp b/liblog/logging.cpp
index 3b0c2c5..d34de9b 100644
--- a/liblog/logging.cpp
+++ b/liblog/logging.cpp
@@ -18,7 +18,7 @@ void init_logging(boost::log::trivial::severity_level log_level, std::string fil
(
boost::log::keywords::file_name = file_name + ".log",
boost::log::keywords::rotation_size = 10 * 1024 * 1024,
- boost::log::keywords::format = "[%Severity%] (%TimeStamp%): %Message%",
+ boost::log::keywords::format = "(%TimeStamp%):" + (" " + file_name + " ") + "[%Severity%] %Message%",
boost::log::keywords::auto_flush = true
);
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.";
}