From b42cb376c32ef4182d3e7f405f50dde2641e85b0 Mon Sep 17 00:00:00 2001 From: Dennis Brentjes Date: Wed, 14 Dec 2016 15:51:43 +0100 Subject: Reworks the protocol to be tag attack resistant. --- libcmix/cmix.c | 122 +++++++++++++++++++++++++++++++++++++++++++++------------ libcmix/cmix.h | 69 +++++++++++++++++++++++++------- 2 files changed, 153 insertions(+), 38 deletions(-) (limited to 'libcmix') diff --git a/libcmix/cmix.c b/libcmix/cmix.c index 0255f42..a4fba6f 100644 --- a/libcmix/cmix.c +++ b/libcmix/cmix.c @@ -14,7 +14,9 @@ struct CMixContext initialize_cmix_context(struct Api api) { .r = NULL, .s = NULL, .permutation = NULL, - .pirs = NULL, + .decryption_shares = NULL, + .EPiRS = NULL, + .PiMRS = NULL }; } @@ -22,8 +24,10 @@ 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->pirs = (GroupElement*) calloc(ctx->nr_participants, sizeof(GroupElement)); - if(!ctx->r || !ctx->s || !ctx->permutation || !ctx->pirs) { + 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)); + if(!ctx->r || !ctx->s || !ctx->permutation || !ctx->decryption_shares || !ctx->EPiRS || !ctx->PiMRS ) { return out_of_memory; } return no_error; @@ -33,7 +37,9 @@ void release_mix(struct CMixContext* ctx) { for(size_t i = 0; i < ctx->nr_participants; ++i) { 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->decryption_shares[i]); + ctx->api.free_group_element(ctx->EPiRS[i]); + ctx->api.free_group_element(ctx->PiMRS[i]); } free(ctx->r); ctx->r = NULL; @@ -44,8 +50,14 @@ void release_mix(struct CMixContext* ctx) { free(ctx->permutation); ctx->permutation = NULL; - free(ctx->pirs); - ctx->pirs = NULL; + free(ctx->decryption_shares); + ctx->decryption_shares = NULL; + + free(ctx->EPiRS); + ctx->EPiRS = NULL; + + free(ctx->PiMRS); + ctx->PiMRS = NULL; ctx->nr_participants = 0; } @@ -186,7 +198,7 @@ enum cmix_error encrypt_r_and_multiply(struct CMixContext const* ctx, char** ran element_to_buffer(ctx, random_buffer[i], new_random_element); element_to_buffer(ctx, message_buffer[i], new_message_element); - + ctx->api.free_group_element(enc_random_element); ctx->api.free_group_element(enc_message_element); ctx->api.free_group_element(other_random_element); @@ -228,21 +240,22 @@ enum cmix_error permute_and_multiply_encrypted_s(struct CMixContext const* ctx, return no_error; } -enum cmix_error permute_and_multiply_s(struct CMixContext const* ctx, char** out_buffer, char const** message) { +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 i = 0; i < ctx->nr_participants; ++i) { unsigned int new_pos = ctx->permutation[i]; GroupElement message_el = ctx->api.array_to_element(message[i], el_size, false); - GroupElement mult = ctx->api.multiply(message_el, ctx->s[new_pos], false); + ctx->PiMRS[new_pos] = ctx->api.multiply(message_el, ctx->s[new_pos], false); - element_to_buffer(ctx, out_buffer[new_pos], mult); + element_to_buffer(ctx, out_buffer[new_pos], ctx->PiMRS[new_pos]); ctx->api.free_group_element(message_el); - ctx->api.free_group_element(mult); } + + return no_error; } @@ -298,7 +311,8 @@ enum cmix_error key_exchange_initiator(struct CMixContext const* ctx, GroupEleme return no_error; } -enum cmix_error post_process(struct CMixContext* ctx, char** r_out, char** m_out, const char** r_epirs, const char** m_epirs) { +/* +enum cmix_error precomputation_post_process_unsafe(struct CMixContext* ctx, char** r_out, char** m_out, const char** r_epirs, const char** m_epirs) { 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); GroupElement D = ctx->api.get_decryption_share(x, ctx->keypair.sec); @@ -318,6 +332,37 @@ enum cmix_error post_process(struct CMixContext* ctx, char** r_out, char** m_out return no_error; } +*/ + +size_t get_commitment_length(struct CMixContext const* ctx) { + return 1; +} + +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 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[i] = ctx->api.get_decryption_share(x, ctx->keypair.sec); + + ctx->EPiRS[i] = ctx->api.array_to_element(m_epirs[i], len, true); + + ctx->api.free_group_element(x); + } + + //ToDo: actually calculate commitment. + + memset(commitment, 0, get_commitment_length(ctx)); + + return no_error; +} + +enum cmix_error commit_precomputation_ciphertext(struct CMixContext* ctx, char* commitment, const char** m_epirs) { + //ToDo: actually calculate commitment. + memset(commitment, 0, get_commitment_length(ctx)); + + return no_error; +} enum cmix_error blind_message(struct CMixContext const* ctx, char* m_out, char const* message, GroupElement const* keys, size_t const nr_nodes) { size_t len = get_group_element_array_size(ctx); @@ -363,19 +408,48 @@ enum cmix_error swap_k_for_r(struct CMixContext const* ctx, char** out_buffer, c 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); + +enum cmix_error get_epirs(struct CMixContext const* ctx, char** out_buffer) { + for(size_t i = 0; i < ctx->nr_participants; ++i) { + element_to_buffer(ctx, out_buffer[i], ctx->EPiRS[i]); + } + return no_error; +} + +enum cmix_error get_pimrs_commitment(struct CMixContext const* ctx, char* out_buffer, const char** pimrss) { + (void) pimrss; + memset(out_buffer, '\0', get_commitment_length(ctx)); + return no_error; +} + +enum cmix_error decrypt_epirs(struct CMixContext const* ctx, char** out_buffer, const char** epirs) { + 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.multiply(ctx->decryption_shares[i], msg, true); + element_to_buffer(ctx, out_buffer[i], pirs); + + ctx->api.free_group_element(msg); + ctx->api.free_group_element(pirs); + } - ctx->api.free_group_element(mes); - ctx->api.free_group_element(inv_pirs); - ctx->api.free_group_element(mult); + return no_error; +} + +enum cmix_error remove_pirs(struct CMixContext const* ctx, char** out_buffer, const char** pirs) { + 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 inv_pirs = ctx->api.invert(g_pirs); + + GroupElement mult = ctx->api.multiply(ctx->PiMRS[i], inv_pirs, false); + + element_to_buffer(ctx, out_buffer[i], mult); + + ctx->api.free_group_element(g_pirs); + ctx->api.free_group_element(inv_pirs); + ctx->api.free_group_element(mult); + } return no_error; } diff --git a/libcmix/cmix.h b/libcmix/cmix.h index 06fd939..5c6a4c1 100644 --- a/libcmix/cmix.h +++ b/libcmix/cmix.h @@ -49,7 +49,9 @@ struct CMixContext { 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 (π in the paper (called Pi in source)). - GroupElement* pirs; ///< an array containing π(R) * S + GroupElement* decryption_shares; ///< The decryption share for each slot. + GroupElement* EPiRS; ///< stores teh current π(R) * S for this node. Only usfull for the last node. + GroupElement* PiMRS; ///< stores the current π(M * R) * S for this node. Only usefull for the last node. }; /*! @@ -240,16 +242,30 @@ 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); /*! - * \brief post_process decrypts Pi(R) * S and stores it in the context. + * \brief get_commitment_length + * \param ctx + * \return + */ +size_t get_commitment_length(struct CMixContext const* ctx); + +/*! + * \brief precomputation_post_process Calculates it's decryption shares and it's commitment to them. * \note The stored pirs only has meaning for the last node, but just storing it for the last node just adds unneeded complexity. * \param ctx The relevant context. - * \param r_out The output buffer for the random components. - * \param m_out The output buffer for the message components. + * \param commitment a buffer of size get_commitment_length() to store the commitment. * \param r_epirs The input buffer for the random components. - * \param m_epirs The input buffer for the message components. * \return A cmix_error */ -enum cmix_error post_process(struct CMixContext* ctx, char** r_out, char** m_out, char const** r_epirs, char const** m_epirs); +enum cmix_error precomputation_post_process(struct CMixContext* ctx, char* commitment, const char** r_epirs, const char** m_epirs); + +/*! + * \brief commit_precomputation_ciphertext + * \param ctx + * \param commitment + * \param m_epirs + * \return + */ +enum cmix_error commit_precomputation_ciphertext(struct CMixContext* ctx, char* commitment, const char** m_epirs); /*! * \brief swap_k_for_r multiplies with K^-1 and multiplies with R @@ -268,17 +284,42 @@ enum cmix_error swap_k_for_r(struct CMixContext const* ctx, char** out_buffer, c * \param message The input buffer. * \return A cmix_error */ -enum cmix_error permute_and_multiply_s(struct CMixContext const* ctx, char** out_buffer, char const** message); +enum cmix_error permute_and_multiply_s(struct CMixContext* ctx, char** out_buffer, char const** message); /*! - * \brief remove_r_and_s multiply with (Pi(R) * S)^-1 - * \param ctx The relevant context. - * \param out_buffer The ouput buffer, - * \param message The input buffer - * \param index message process message x (take the x'th Pi(R) * S) - * \return A cmix_error + * \brief get_epirs + * \param ctx + * \param out_buffer + * \return + */ +enum cmix_error get_epirs(struct CMixContext const* ctx, char** out_buffer); + +/*! + * \brief get_pimrs_commitment + * \param ctx + * \param out_buffer + * \param pimrss + * \return + */ +enum cmix_error get_pimrs_commitment(struct CMixContext const* ctx, char* out_buffer, const char** pimrss); + +/*! + * \brief decrypt_epirs + * \param ctx + * \param out_buffer + * \param epirs + * \return + */ +enum cmix_error decrypt_epirs(struct CMixContext const* ctx, char** out_buffer, const char** epirs); + +/*! + * \brief remove_pirs + * \param ctx + * \param out_buffer + * \param pirs + * \return */ -enum cmix_error remove_r_and_s(struct CMixContext const* ctx, char* out_buffer, char const* message, size_t index); +enum cmix_error remove_pirs(struct CMixContext const* ctx, char** out_buffer, const char** pirs); /*! * \brief split_message Splits a message in its destination and payload components. -- cgit v1.2.3-70-g09d2