diff options
| author | Dennis Brentjes <d.brentjes@gmail.com> | 2018-02-04 12:47:09 +0100 |
|---|---|---|
| committer | Dennis Brentjes <d.brentjes@gmail.com> | 2018-02-04 12:47:09 +0100 |
| commit | 21474893efe0ab38461c3d08727c7c778caa9323 (patch) | |
| tree | 8d48ec3353c84155dcf7daf67d8ade1dd1fd480d /libcmix | |
| parent | 126021b3766e6fb33333b7939d78dadd1c632eb4 (diff) | |
| download | cmix-21474893efe0ab38461c3d08727c7c778caa9323.tar.gz cmix-21474893efe0ab38461c3d08727c7c778caa9323.tar.bz2 cmix-21474893efe0ab38461c3d08727c7c778caa9323.zip | |
Both algorithms are now batchable.
Diffstat (limited to 'libcmix')
| -rw-r--r-- | libcmix/cmix.c | 237 | ||||
| -rw-r--r-- | libcmix/cmix.h | 4 |
2 files changed, 135 insertions, 106 deletions
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. |
