aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--CMakeLists.txt1
-rw-r--r--libcmix/cmix.c91
-rw-r--r--libcmix/cmix.h12
-rw-r--r--microbench/CMakeLists.txt18
-rw-r--r--microbench/microbench.cpp41
-rw-r--r--node/node.cpp6
6 files changed, 103 insertions, 66 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 226c73d..b9170d3 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -76,3 +76,4 @@ add_subdirectory(client)
add_subdirectory(statsd)
add_subdirectory(scratchpad)
+add_subdirectory(microbench)
diff --git a/libcmix/cmix.c b/libcmix/cmix.c
index 50fee36..4aba927 100644
--- a/libcmix/cmix.c
+++ b/libcmix/cmix.c
@@ -22,21 +22,12 @@ struct CMixContext initialize_cmix_context(struct Api api, unsigned int nr_mixes
}
enum cmix_error alloc_mix(struct CMixContext* ctx) {
- 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->r = (GroupElement*) calloc(ctx->nr_participants * ctx->nr_mixes, sizeof(GroupElement));
+ ctx->s = (GroupElement*) calloc(ctx->nr_participants * ctx->nr_mixes, sizeof(GroupElement));
+ ctx->permutation = (unsigned int*) calloc(ctx->nr_participants * ctx->nr_mixes, sizeof(unsigned int));
+ ctx->decryption_shares = (GroupElement*) calloc(ctx->nr_participants * ctx->nr_mixes, sizeof(GroupElement));
+ ctx->EPiRS = (GroupElement*) calloc(ctx->nr_participants * ctx->nr_mixes, sizeof(GroupElement));
+ ctx->PiMRS = (GroupElement*) calloc(ctx->nr_participants * ctx->nr_mixes, sizeof(GroupElement));
if(!ctx->r || !ctx->s || !ctx->permutation || !ctx->decryption_shares || !ctx->EPiRS || !ctx->PiMRS ) {
return out_of_memory;
@@ -47,39 +38,25 @@ 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_participants; ++m) {
+ for(size_t m = 0; m < ctx->nr_participants * ctx->nr_mixes; ++m) {
if(ctx->r[m]) {
- for(size_t i = 0; i < ctx->nr_mixes; ++i) {
- ctx->api.free_group_element(ctx->r[m][i]);
- }
- free(ctx->r[m]);
+ ctx->api.free_group_element(ctx->r[m]);
}
if(ctx->s[m]){
- for(size_t i = 0; i < ctx->nr_mixes; ++i) {
- ctx->api.free_group_element(ctx->s[m][i]);
- }
+ ctx->api.free_group_element(ctx->s[m]);
}
- free(ctx->permutation[m]);
-
if(ctx->decryption_shares[m]){
- for(size_t i = 0; i < ctx->nr_mixes; ++i) {
- ctx->api.free_group_element(ctx->decryption_shares[m][i]);
- }
+ ctx->api.free_group_element(ctx->decryption_shares[m]);
}
if(ctx->EPiRS[m]) {
- for(size_t i = 0; i < ctx->nr_mixes; ++i) {
- ctx->api.free_group_element(ctx->EPiRS[m][i]);
- }
+ ctx->api.free_group_element(ctx->EPiRS[m]);
+ }
+ if(ctx->PiMRS[m]) {
+ ctx->api.free_group_element(ctx->PiMRS[m]);
}
}
}
-
- for(size_t i = 0; i < ctx->nr_participants; ++i) {
-
- ctx->api.free_group_element(ctx->PiMRS[i]);
- }
-
free(ctx->r);
ctx->r = NULL;
@@ -162,16 +139,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[i][m] = i;
+ ctx->permutation[i * ctx->nr_mixes + 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[i][m];
- ctx->permutation[i][m] = ctx->permutation[rand][m];
- ctx->permutation[rand][m] = temp;
+ temp = ctx->permutation[i * ctx->nr_mixes + m];
+ ctx->permutation[i * ctx->nr_mixes + m] = ctx->permutation[rand * ctx->nr_mixes + m];
+ ctx->permutation[rand * ctx->nr_mixes + m] = temp;
}
}
@@ -183,8 +160,8 @@ enum cmix_error initialize_mix_randomness(struct CMixContext* ctx) {
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);
+ ctx->r[i * ctx->nr_mixes + m] = ctx->api.get_group_element(true);
+ ctx->s[i * ctx->nr_mixes + m] = ctx->api.get_group_element(true);
}
}
@@ -223,7 +200,7 @@ enum cmix_error encrypt_r(struct CMixContext const* ctx, char** random_buffer, c
GroupElement random_element;
GroupElement message_element;
- ctx->api.encrypt(&random_element, &message_element, ctx->r[i][m], ctx->network_key);
+ ctx->api.encrypt(&random_element, &message_element, ctx->r[i * ctx->nr_mixes + m], ctx->network_key);
element_to_buffer(ctx, random_buffer[i] + offset, random_element);
element_to_buffer(ctx, message_buffer[i] + offset, message_element);
@@ -244,7 +221,7 @@ enum cmix_error encrypt_r_and_multiply(struct CMixContext const* ctx, char** ran
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);
+ ctx->api.encrypt(&enc_random_element, &enc_message_element, ctx->r[i * ctx->nr_mixes + m], ctx->network_key);
size_t el_size = get_group_element_array_size(ctx);
@@ -274,7 +251,7 @@ enum cmix_error permute_and_multiply_encrypted_s(struct CMixContext const* ctx,
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];
+ unsigned int new_pos = ctx->permutation[i * ctx->nr_mixes + 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);
@@ -283,7 +260,7 @@ enum cmix_error permute_and_multiply_encrypted_s(struct CMixContext const* ctx,
GroupElement random_s;
GroupElement message_s;
- ctx->api.encrypt(&random_s, &message_s, ctx->s[new_pos][m], ctx->network_key);
+ ctx->api.encrypt(&random_s, &message_s, ctx->s[new_pos * ctx->nr_mixes + 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);
@@ -309,12 +286,12 @@ enum cmix_error permute_and_multiply_s(struct CMixContext* ctx, char** out_buffe
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];
+ unsigned int new_pos = ctx->permutation[i * ctx->nr_mixes + m];
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);
+ ctx->PiMRS[new_pos * ctx->nr_mixes + m] = ctx->api.combine(message_el, ctx->s[new_pos * ctx->nr_mixes + m], false);
- element_to_buffer(ctx, out_buffer[new_pos] + offset, ctx->PiMRS[new_pos][m]);
+ element_to_buffer(ctx, out_buffer[new_pos] + offset, ctx->PiMRS[new_pos * ctx->nr_mixes + m]);
ctx->api.free_group_element(message_el);
}
@@ -330,7 +307,7 @@ enum cmix_error multiply_s(struct CMixContext const* ctx, char* out_buffer, char
size_t offset = get_group_element_array_size(ctx);
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);
+ GroupElement mult = ctx->api.combine(message_el, ctx->s[m * ctx->nr_mixes + ctx->permutation[m * ctx->nr_mixes + index]], false);
element_to_buffer(ctx, out_buffer + offset, mult);
@@ -414,9 +391,9 @@ enum cmix_error precomputation_post_process(struct CMixContext* ctx, char* commi
size_t offset = m * ctx->api.get_group_element_array_size();
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->decryption_shares[i * ctx->nr_mixes + 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->EPiRS[i * ctx->nr_mixes + m] = ctx->api.array_to_element(m_epirs[i] + offset, len, true);
ctx->api.free_group_element(x);
}
@@ -476,7 +453,7 @@ enum cmix_error swap_k_for_r(struct CMixContext const* ctx, char** out_buffer, c
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[i][m], false);
+ GroupElement blinded = ctx->api.combine(unblinded, ctx->r[i * ctx->nr_mixes + m], false);
element_to_buffer(ctx, out_buffer[i] + offset, blinded);
ctx->api.free_group_element(mes);
@@ -493,7 +470,7 @@ enum cmix_error get_epirs(struct CMixContext const* ctx, char** out_buffer) {
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]);
+ element_to_buffer(ctx, out_buffer[i] + offset, ctx->EPiRS[i * ctx->nr_mixes + m]);
}
}
@@ -512,7 +489,7 @@ enum cmix_error decrypt_epirs(struct CMixContext const* ctx, char** out_buffer,
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);
+ GroupElement pirs = ctx->api.combine(ctx->decryption_shares[i * ctx->nr_mixes + m], msg, true);
element_to_buffer(ctx, out_buffer[i] + offset, pirs);
ctx->api.free_group_element(msg);
@@ -531,7 +508,7 @@ enum cmix_error remove_pirs(struct CMixContext const* ctx, char** out_buffer, co
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);
+ GroupElement mult = ctx->api.uncombine(ctx->PiMRS[i * ctx->nr_mixes + m], g_pirs, false);
element_to_buffer(ctx, out_buffer[i] + offset, mult);
diff --git a/libcmix/cmix.h b/libcmix/cmix.h
index d35b23f..028089c 100644
--- a/libcmix/cmix.h
+++ b/libcmix/cmix.h
@@ -47,12 +47,12 @@ struct CMixContext {
GroupElement network_key; ///< The network key (called d in the paper).
size_t nr_mixes; ///< The amount of mixes to do simultanuous
size_t nr_participants; ///< The number of mix participants.
- GroupElement** r; ///< An array of random values (R in the paper).
- GroupElement** s; ///< An array of random values (S in the paper).
- 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* r; ///< An array of random values (R in the paper).
+ GroupElement* s; ///< An array of random values (S in the paper).
+ 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.
};
/*!
diff --git a/microbench/CMakeLists.txt b/microbench/CMakeLists.txt
new file mode 100644
index 0000000..a132ecf
--- /dev/null
+++ b/microbench/CMakeLists.txt
@@ -0,0 +1,18 @@
+
+find_package(Gcrypt REQUIRED)
+find_package(Boost COMPONENTS timer REQUIRED)
+
+add_executable(microbench
+ microbench.cpp
+)
+
+target_compile_options(scratchpad
+ PRIVATE ${Gcrypt_CFLAGS}
+)
+
+target_link_libraries(microbench
+ PRIVATE cmix
+ PRIVATE cmix-crypto
+ PRIVATE ${Gcrypt_LIBRARIES}
+ PRIVATE Boost::timer
+)
diff --git a/microbench/microbench.cpp b/microbench/microbench.cpp
new file mode 100644
index 0000000..0d21e5f
--- /dev/null
+++ b/microbench/microbench.cpp
@@ -0,0 +1,41 @@
+
+#include "api.h"
+
+#include <vector>
+#include <boost/timer/timer.hpp>
+#include <iostream>
+
+int main(int, char*[]) {
+ struct Api api = get_implementation();
+
+ size_t nr_test = 10000;
+
+ std::vector<GroupElement> elements(nr_test);
+
+ boost::timer::cpu_timer timer;
+ timer.start();
+
+ for(auto&& el : elements) {
+ el = api.get_group_element(true);
+ }
+
+ auto random_time = timer.elapsed().user;
+
+ for(size_t i = 0; i < nr_test; i++) {
+ elements[i] = api.combine(elements[i], elements[(i+1) % nr_test], true);
+ }
+
+ auto combine_time = timer.elapsed().user - random_time;
+
+ for(size_t i = 0; i < nr_test; i++) {
+ elements[i] = api.uncombine(elements[i], elements[(i+1) % nr_test], true);
+ }
+
+ auto uncombine_time = timer.elapsed().user - combine_time;
+ timer.stop();
+
+ std::cout << "Micro Benchmark:" << std::endl
+ << "Random:\t\t" << random_time / 1000000.0 << " ms" << std::endl
+ << "Combine:\t" << combine_time / 1000000.0 << " ms" << std::endl
+ << "Uncombine:\t" << uncombine_time / 1000000.0 << " ms" << std::endl;
+}
diff --git a/node/node.cpp b/node/node.cpp
index 5c6025a..2c8adb5 100644
--- a/node/node.cpp
+++ b/node/node.cpp
@@ -160,14 +160,14 @@ void Node::handle_message(Purgatory::iterator handle, cmix_proto::CMixMessage me
}
void Node::start_precomputation() {
- BOOST_LOG_TRIVIAL(trace) << "Starting precomputation for " << messages.size() << " clients.";
- participants.clear();
-
if(messages.size() < network_settings.minimum_nr_messages) {
start_timer_delayed_mix();
return;
}
+ BOOST_LOG_TRIVIAL(trace) << "Starting precomputation for " << messages.size() << " clients.";
+ participants.clear();
+
if(performance) {
performance->send("pre_pre_start");
}