diff options
| author | Dennis Brentjes <d.brentjes@gmail.com> | 2016-11-01 17:40:17 +0100 |
|---|---|---|
| committer | Dennis Brentjes <d.brentjes@gmail.com> | 2016-11-01 17:40:17 +0100 |
| commit | 9531b6bea9fb29074c588a4e4e8838f6d9335a2b (patch) | |
| tree | 4d0e9429203bf5976507b43e6663f9fe0b21e6d0 /libcmix/cmix.c | |
| parent | bdc26e00ad99f4f670df1a65b5e6439d0dfadc87 (diff) | |
| download | cmix-9531b6bea9fb29074c588a4e4e8838f6d9335a2b.tar.gz cmix-9531b6bea9fb29074c588a4e4e8838f6d9335a2b.tar.bz2 cmix-9531b6bea9fb29074c588a4e4e8838f6d9335a2b.zip | |
Moves cmix calculation stuff outisde of the node class.
Moves the computations and cryptography to the the libcmix library
where we can group and memory manage the underlying crypto-library.
Diffstat (limited to 'libcmix/cmix.c')
| -rw-r--r-- | libcmix/cmix.c | 180 |
1 files changed, 180 insertions, 0 deletions
diff --git a/libcmix/cmix.c b/libcmix/cmix.c index e0256cf..6a39767 100644 --- a/libcmix/cmix.c +++ b/libcmix/cmix.c @@ -2,6 +2,7 @@ #include "cmix.h" #include <string.h> +#include <stdlib.h> enum cmix_error permutation(struct CMixBuffer b) { return no_error; @@ -36,3 +37,182 @@ enum cmix_error calculate_shared_key_part(struct Bignum* result, struct Bignum p } return no_error; } + +struct CMixContext initialize_cmix_context(struct Api api) { + return (struct CMixContext){ + .api = api, + .nr_participants = 0, + .r = NULL, + .s = NULL, + .permutation = NULL, + .pirs = NULL + }; +} + +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]); + } + free(ctx->r); + free(ctx->s); + free(ctx->permutation); + free(ctx->pirs); +} + +void deinitialize(struct CMixContext* ctx) +{ + ctx->api.free_keypair(&ctx->keypair); + release_mix(ctx); +} + +void element_to_buffer(struct CMixContext const* ctx, char* out_buffer, GroupElement element) { + size_t el_size = get_group_element_array_size(ctx); + + unsigned char* buffer; + size_t len; + + ctx->api.element_to_array(&buffer, &len, element); + size_t diff = el_size - len; + memcpy(out_buffer + diff, buffer, len); + ctx->api.free_buffer(buffer); +} + +enum cmix_error initialize_keypair(struct CMixContext* ctx) +{ + ctx->keypair = ctx->api.create_keypair(); + return no_error; +} + +enum cmix_error get_public_key(struct CMixContext const* ctx, char* buffer) +{ + element_to_buffer(ctx, buffer, ctx->keypair.pub); + return no_error; +} + +enum cmix_error add_public_share(struct CMixContext const* ctx, char* buffer, char const* share) { + size_t len = get_group_element_array_size(ctx); + + GroupElement el; + ctx->api.add_public_share(&el, share, len, ctx->keypair.pub); + + element_to_buffer(ctx, buffer, el); + ctx->api.free_group_element(el); +} + +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) { + return out_of_memory; + } + return no_error; +} + +enum cmix_error start_mix(struct CMixContext* ctx, size_t nr_participants) { + release_mix(ctx); + ctx->nr_participants = nr_participants; + return alloc_mix(ctx); +} + +enum cmix_error initialize_mix_randomness(struct CMixContext* ctx) { + for(size_t i = 0; i < ctx->nr_participants; ++i) { + ctx->r[i] = ctx->api.get_group_element(true); + ctx->s[i] = ctx->api.get_group_element(true); + ctx->permutation[i] = i; + } + return no_error; +} + +size_t get_group_element_array_size(struct CMixContext const* ctx) { + return ctx->api.get_group_element_array_size(); +} + +enum cmix_error set_network_key(struct CMixContext* ctx, char const* buffer, size_t len) { + ctx->network_key = ctx->api.array_to_element(buffer, len, true); + return no_error; +} + +enum cmix_error encrypt_r(struct CMixContext const* ctx, char* random_buffer, char* message_buffer, size_t index) { + GroupElement random_element; + GroupElement message_element; + + ctx->api.encrypt(&random_element, &message_element, ctx->r[index], ctx->network_key); + + element_to_buffer(ctx, random_buffer, random_element); + element_to_buffer(ctx, message_buffer, message_element); + + return no_error; +} + +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, size_t index) { + GroupElement enc_random_element; + GroupElement enc_message_element; + + ctx->api.encrypt(&enc_random_element, &enc_message_element, ctx->r[index], ctx->network_key); + + size_t el_size = get_group_element_array_size(ctx); + + GroupElement other_random_element = ctx->api.array_to_element(random_element, el_size, true); + GroupElement other_message_element = ctx->api.array_to_element(message_element, el_size, true); + + GroupElement new_random_element = ctx->api.multiply(enc_random_element, other_random_element, true); + GroupElement new_message_element = ctx->api.multiply(enc_message_element, other_message_element, true); + + element_to_buffer(ctx, random_buffer, new_random_element); + element_to_buffer(ctx, message_buffer, 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); + ctx->api.free_group_element(other_message_element); + ctx->api.free_group_element(new_random_element); + ctx->api.free_group_element(new_message_element); + + 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) { + size_t el_size = get_group_element_array_size(ctx); + + GroupElement random_r = ctx->api.array_to_element(r_in_buffer, el_size, true); + GroupElement message_r = ctx->api.array_to_element(m_in_buffer, el_size, true); + + GroupElement random_s; + GroupElement message_s; + + ctx->api.encrypt(&random_s, &message_s, ctx->s[index], ctx->network_key); + + GroupElement random_pirs = ctx->api.multiply(random_r, random_s, true); + GroupElement message_pirs = ctx->api.multiply(message_r, message_s, true); + + element_to_buffer(ctx, r_out_buffer, random_pirs); + element_to_buffer(ctx, m_out_buffer, message_pirs); + + ctx->api.free_group_element(random_r); + ctx->api.free_group_element(message_r); + ctx->api.free_group_element(random_s); + ctx->api.free_group_element(message_s); + + 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) { + 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); + element_to_buffer(ctx, exchange_value_buffer, ex_val); + + ctx->api.free_group_element(priv_el); + ctx->api.free_group_element(ex_val); + + return no_error; +} |
