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 | |
| 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.
| -rw-r--r-- | client/cmixclient.cpp | 6 | ||||
| -rw-r--r-- | libcmix-crypto/api.h | 14 | ||||
| -rw-r--r-- | libcmix-crypto/curve25519/curve25519.c | 1 | ||||
| -rw-r--r-- | libcmix-crypto/curve25519/curve25519.h | 2 | ||||
| -rw-r--r-- | libcmix-crypto/curve25519/sodium/libsodium_curve25519.c | 6 | ||||
| -rw-r--r-- | libcmix-crypto/elgamal/elgamal.c | 31 | ||||
| -rw-r--r-- | libcmix-crypto/elgamal/elgamal.h | 2 | ||||
| -rw-r--r-- | libcmix-crypto/elgamal/gcrypt/gcrypt_elgamal.c | 17 | ||||
| -rw-r--r-- | libcmix/cmix.c | 180 | ||||
| -rw-r--r-- | libcmix/cmix.h | 43 | ||||
| -rw-r--r-- | node/node.cpp | 225 | ||||
| -rw-r--r-- | node/node.hpp | 8 |
12 files changed, 353 insertions, 182 deletions
diff --git a/client/cmixclient.cpp b/client/cmixclient.cpp index ea178d3..ba1a187 100644 --- a/client/cmixclient.cpp +++ b/client/cmixclient.cpp @@ -66,7 +66,7 @@ void CMixClient::initialize_connections() { void CMixClient::handle_key_exchange(size_t node_id, cmix_proto::KeyExchange const& ke) { - data.at(node_id).shared_value = api.derive_shared_key(keypair, reinterpret_cast<uint8_t const*>(ke.public_key().c_str()), ke.public_key().size(), reinterpret_cast<uint8_t const*>(ke.value().c_str()), ke.value().size(), data.at(node_id).secret_value, false); + data.at(node_id).shared_value.shared = api.derive_shared_key(keypair, reinterpret_cast<uint8_t const*>(ke.public_key().c_str()), ke.public_key().size(), reinterpret_cast<uint8_t const*>(ke.value().c_str()), ke.value().size(), data.at(node_id).secret_value, false); cmix_proto::Bye bye; network_connections.at(node_id).async_send(bye); @@ -108,7 +108,7 @@ CMixClient::CMixClient(NetworkDetails details) , network_details(details) , network_connections() , api(get_implementation()) -, keypair(api.create_key_pair()) +, keypair(api.create_keypair()) { if(!details.certdir.empty()) { ctx->add_verify_path(details.certdir); @@ -119,7 +119,7 @@ CMixClient::CMixClient(NetworkDetails details) CMixClient::~CMixClient() { - api.free_key_pair(&keypair); + api.free_keypair(&keypair); for(auto&& d : data) { api.free_shared_key(&d.shared_value); api.free_group_element(d.secret_value); diff --git a/libcmix-crypto/api.h b/libcmix-crypto/api.h index 8c40d23..6d701d7 100644 --- a/libcmix-crypto/api.h +++ b/libcmix-crypto/api.h @@ -32,7 +32,7 @@ typedef void (*KeyPairDeleter)(struct KeyPair*); * \brief Defines how a Derived Shared Key function should look like. * Used to store a pointer to function to a implementation. */ -typedef struct SharedKey (*SharedKeyDeriver)(struct KeyPair, unsigned char const*, size_t, unsigned char const*, size_t, GroupElement, bool); +typedef GroupElement (*SharedKeyDeriver)(struct KeyPair, unsigned char const*, size_t, unsigned char const*, size_t, GroupElement, bool); /*! * \brief Defines how a Derived Shared Key deleter function should look like. @@ -63,7 +63,7 @@ typedef GroupElement(*ArrayToElement)(char const*, size_t size, bool); /*! * \brief PublicShareAdder typedef */ -typedef void(*PublicShareAdder)(char**, size_t*, char const*, size_t, GroupElement); +typedef void(*PublicShareAdder)(GroupElement*, char const*, size_t, GroupElement); /*! * @@ -83,6 +83,11 @@ typedef GroupElement(*GroupElementMultiplier)(GroupElement, GroupElement, bool); /*! * */ +typedef size_t(*GroupElementArraySizeGetter)(); + +/*! + * + */ typedef void(*GroupElementDeleter)(GroupElement); /*! @@ -95,12 +100,13 @@ typedef void (*Encrypter)(GroupElement*, GroupElement*, GroupElement, GroupEleme */ struct Api { Initializer initialize; ///< Function that will initialize the crypto library. - KeyPairCreator create_key_pair; ///< Pointer to keypair creation function - KeyPairDeleter free_key_pair; ///< Pointer to keypair deletor function + KeyPairCreator create_keypair; ///< Pointer to keypair creation function + KeyPairDeleter free_keypair; ///< Pointer to keypair deletor function ElementToArray element_to_array; ///< Get the array representation of a public key BufferDeleter free_buffer; ///< frees library allocated buffers. ArrayToElement array_to_element; ///< The the GroupElement representation of this array; GroupElementGetter get_group_element; ///< get group element + GroupElementArraySizeGetter get_group_element_array_size; ///< Return the size required to store a groupelement in an array; GroupElementDeleter free_group_element; ///< frees a base type of the cryptolibrary. KeyExchangeValueGetter get_key_exchange_value; ///< get generator *op* group element. GroupElementMultiplier multiply; ///< Multiplies two groupelements modulo group. diff --git a/libcmix-crypto/curve25519/curve25519.c b/libcmix-crypto/curve25519/curve25519.c index 6eaaafc..db77d9a 100644 --- a/libcmix-crypto/curve25519/curve25519.c +++ b/libcmix-crypto/curve25519/curve25519.c @@ -15,6 +15,7 @@ struct Api get_curve25519_implementation() NULL, NULL, NULL, + NULL, &curve25519_add_public_share, &curve25519_derive_shared_key, &curve25519_shared_key_deleter, diff --git a/libcmix-crypto/curve25519/curve25519.h b/libcmix-crypto/curve25519/curve25519.h index 9b65d4e..762e8db 100644 --- a/libcmix-crypto/curve25519/curve25519.h +++ b/libcmix-crypto/curve25519/curve25519.h @@ -51,7 +51,7 @@ extern void curve25519_add_public_share(char** buffer, size_t* out_len, char con * \param swap_pub_order Should we swap the order in which we feed the public keys to the hash function. * \return A Shared key */ -extern struct SharedKey curve25519_derive_shared_key(struct KeyPair pair, unsigned char const* other_pub, size_t pub_len, unsigned char const* value, size_t value_len, void* priv_value, bool swap_pub_order); +extern GroupElement curve25519_derive_shared_key(struct KeyPair pair, unsigned char const* other_pub, size_t pub_len, unsigned char const* value, size_t value_len, void* priv_value, bool swap_pub_order); /*! * \brief curve25519_shared_key_deleter * \param s the Shared key to free. diff --git a/libcmix-crypto/curve25519/sodium/libsodium_curve25519.c b/libcmix-crypto/curve25519/sodium/libsodium_curve25519.c index 6c3fe13..2405442 100644 --- a/libcmix-crypto/curve25519/sodium/libsodium_curve25519.c +++ b/libcmix-crypto/curve25519/sodium/libsodium_curve25519.c @@ -47,7 +47,7 @@ void curve25519_add_public_share(char** buffer, size_t* out_len, char const* sha } -struct SharedKey curve25519_derive_shared_key(struct KeyPair pair, unsigned char const* other_pub, size_t pub_len, unsigned char const* value, size_t value_len, void* priv_value, bool swap_pub_order) { +GroupElement curve25519_derive_shared_key(struct KeyPair pair, unsigned char const* other_pub, size_t pub_len, unsigned char const* value, size_t value_len, void* priv_value, bool swap_pub_order) { unsigned char* shared = (unsigned char*) sodium_malloc(crypto_generichash_BYTES); crypto_generichash_state h; @@ -71,9 +71,7 @@ struct SharedKey curve25519_derive_shared_key(struct KeyPair pair, unsigned char sodium_free(scalarmult_q); - return (struct SharedKey){ - shared, - }; + return shared; } void curve25519_deinitialize(void) {} diff --git a/libcmix-crypto/elgamal/elgamal.c b/libcmix-crypto/elgamal/elgamal.c index 336d974..e54f76d 100644 --- a/libcmix-crypto/elgamal/elgamal.c +++ b/libcmix-crypto/elgamal/elgamal.c @@ -4,21 +4,22 @@ struct Api get_elgamal_implementation() { elgamal_initialize(); return (struct Api) { - elgamal_initialize, - elgamal_create_keypair, - elgamal_delete_keypair, - elgamal_element_to_array, - elgamal_free_buffer, - elgamal_array_to_element, - elgamal_get_group_element, - elgamal_delete_group_element, - elgamal_get_key_exchange_value, - elgamal_multiply, - elgamal_add_public_share, - elgamal_derive_shared_key, - elgamal_delete_shared_key, - elgamal_encrypt, - elgamal_deinitialize + .initialize = elgamal_initialize, + .create_keypair = elgamal_create_keypair, + .free_keypair = elgamal_delete_keypair, + .element_to_array = elgamal_element_to_array, + .free_buffer = elgamal_free_buffer, + .array_to_element = elgamal_array_to_element, + .get_group_element = elgamal_get_group_element, + .get_group_element_array_size = elgamal_get_group_element_array_size, + .free_group_element = elgamal_delete_group_element, + .get_key_exchange_value = elgamal_get_key_exchange_value, + .multiply = elgamal_multiply, + .add_public_share = elgamal_add_public_share, + .derive_shared_key = elgamal_derive_shared_key, + .free_shared_key = elgamal_delete_shared_key, + .encrypt = elgamal_encrypt, + .deinitialize = elgamal_deinitialize }; } diff --git a/libcmix-crypto/elgamal/elgamal.h b/libcmix-crypto/elgamal/elgamal.h index 71046c5..43ddca0 100644 --- a/libcmix-crypto/elgamal/elgamal.h +++ b/libcmix-crypto/elgamal/elgamal.h @@ -30,6 +30,8 @@ extern KeyExchangeValueGetter elgamal_get_key_exchange_value; extern GroupElementMultiplier elgamal_multiply; +extern GroupElementArraySizeGetter elgamal_get_group_element_array_size; + extern PublicShareAdder elgamal_add_public_share; extern SharedKeyDeriver elgamal_derive_shared_key; diff --git a/libcmix-crypto/elgamal/gcrypt/gcrypt_elgamal.c b/libcmix-crypto/elgamal/gcrypt/gcrypt_elgamal.c index a0512dd..c610556 100644 --- a/libcmix-crypto/elgamal/gcrypt/gcrypt_elgamal.c +++ b/libcmix-crypto/elgamal/gcrypt/gcrypt_elgamal.c @@ -152,11 +152,15 @@ GroupElement gcrypt_elgamal_multiply(GroupElement lh, GroupElement rh, bool secu return ret; } +size_t gcrypt_elgamal_get_group_element_array_size() { + return 256u; +} + void gcrypt_elgamal_delete_group_element(void* el) { gcry_mpi_release((gcry_mpi_t) el); } -void gcrypt_elgamal_add_public_share(char** buffer, size_t* out_len, char const* share, size_t in_len, void* pubkey) { +void gcrypt_elgamal_add_public_share(GroupElement* el, char const* share, size_t in_len, void* pubkey) { gcry_error_t error; size_t parse_error_pos; @@ -170,14 +174,12 @@ void gcrypt_elgamal_add_public_share(char** buffer, size_t* out_len, char const* gcry_mpi_t result = gcry_mpi_new(0); gcry_mpi_mulm(result, mpi_share, y, p); - error = gcry_mpi_aprint(GCRYMPI_FMT_USG, (unsigned char**) buffer, out_len, result); - check(error); + *el = result; gcry_mpi_release(mpi_share); - gcry_mpi_release(result); } -struct SharedKey gcrypt_elgamal_derive_shared_key(struct KeyPair keypair, unsigned char const* other_pub, size_t pub_len, unsigned char const* value, size_t value_len, void* priv_value, bool swap) { +GroupElement gcrypt_elgamal_derive_shared_key(struct KeyPair keypair, unsigned char const* other_pub, size_t pub_len, unsigned char const* value, size_t value_len, void* priv_value, bool swap) { gcry_error_t error; size_t parse_error_pos; @@ -192,9 +194,7 @@ struct SharedKey gcrypt_elgamal_derive_shared_key(struct KeyPair keypair, unsign gcry_mpi_release(ga); - return (struct SharedKey){ - gab - }; + return gab; } void gcrypt_elgamal_delete_shared_key(struct SharedKey* s) { @@ -241,6 +241,7 @@ GroupElementGetter elgamal_get_group_element = &gcrypt_elgamal_get_group_element GroupElementDeleter elgamal_delete_group_element = &gcrypt_elgamal_delete_group_element; KeyExchangeValueGetter elgamal_get_key_exchange_value = &gcrypt_elgamal_get_key_exchange_value; GroupElementMultiplier elgamal_multiply = &gcrypt_elgamal_multiply; +GroupElementArraySizeGetter elgamal_get_group_element_array_size = &gcrypt_elgamal_get_group_element_array_size; 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; 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; +} diff --git a/libcmix/cmix.h b/libcmix/cmix.h index e0d9961..3877382 100644 --- a/libcmix/cmix.h +++ b/libcmix/cmix.h @@ -1,7 +1,12 @@ +#pragma once + #ifdef __cplusplus extern "C" { #endif +#include "api.h" +#include "keypair.h" +#include "groupelement.h" #include "bignum.h" /*! @@ -26,6 +31,7 @@ enum cmix_error { no_error = 0, index_out_of_range = 1000, cmix_bignum_error = 2000, + out_of_memory = 4000, }; /*! @@ -63,6 +69,43 @@ enum cmix_error set_message(char const* message, struct CMixBuffer b, unsigned i */ enum cmix_error calculate_shared_key_part(struct Bignum* result, struct Bignum partial_shared, struct Bignum my_share, struct Bignum mod); +struct CMixContext { + struct Api api; + struct KeyPair keypair; + GroupElement network_key; + size_t nr_participants; + GroupElement* r; + GroupElement* s; + unsigned int* permutation; + GroupElement* pirs; +}; + +struct CMixContext initialize_cmix_context(struct Api api); + +void deinitialize(struct CMixContext* ctx); + +enum cmix_error initialize_keypair(struct CMixContext* ctx); + +enum cmix_error get_public_key(struct CMixContext const* ctx, char* buffer); + +enum cmix_error add_public_share(struct CMixContext const* ctx, char* buffer, char const* share); + +enum cmix_error start_mix(struct CMixContext* ctx, size_t nr_participants); + +enum cmix_error initialize_mix_randomness(struct CMixContext* ctx); + +size_t get_group_element_array_size(struct CMixContext const* ctx); + +enum cmix_error set_network_key(struct CMixContext* ctx, char const* buffer, size_t len); + +enum cmix_error encrypt_r(struct CMixContext const* ctx, char* random_buffer, char* message_buffer, size_t index); + +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 key_exchange(struct CMixContext const* ctx, GroupElement* shared_key, char* public_key_buffer, char* exhange_value_buffer, char const* pubkey, char const* value); + #ifdef __cplusplus } // extern "C" #endif diff --git a/node/node.cpp b/node/node.cpp index 02ddb3e..fc41656 100644 --- a/node/node.cpp +++ b/node/node.cpp @@ -11,19 +11,19 @@ using namespace boost::asio::ip; Node::Node(ListenSettings const& listen_settings, NodeNetworkSettings network_settings) : io_service() -, ctx(std::make_shared<boost::asio::ssl::context>(boost::asio::ssl::context::sslv23)) -, server(io_service, listen_settings, 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);}) +, 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() , 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, *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, *ctx)))) -, api(get_implementation()) -, keypair(api.create_key_pair()) -, network_key() +, 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); + GOOGLE_PROTOBUF_VERIFY_VERSION; if(network_settings.is_first) { @@ -32,7 +32,7 @@ Node::Node(ListenSettings const& listen_settings, NodeNetworkSettings network_se } Node::~Node() { - api.free_key_pair(&keypair); + deinitialize(&cmix_ctx); } void Node::run() { @@ -56,7 +56,7 @@ void Node::accept_handler(std::unique_ptr<boost::asio::ssl::stream<boost::asio:: void Node::connect_to_next_node() { if(!network_settings.certdir.empty()) { - ctx->add_verify_path(network_settings.certdir); + ssl_ctx->add_verify_path(network_settings.certdir); } auto on_connect = [this](){ @@ -70,11 +70,10 @@ void Node::connect_to_next_node() void Node::start_initialisation() { cmix_proto::Initialization init; - unsigned char* pub_key; - size_t len; - api.element_to_array(&pub_key, &len, keypair.pub); - init.set_public_share(pub_key, len); - free(pub_key); + size_t len = get_group_element_array_size(&cmix_ctx); + init.mutable_public_share()->resize(len); + + get_public_key(&cmix_ctx, &(*init.mutable_public_share())[0]); BOOST_LOG_TRIVIAL(trace) << "Sending intialization as first node"; next_node.async_send(init); @@ -84,31 +83,21 @@ void Node::start_initialisation() { void Node::handle_node_initialization(const cmix_proto::Initialization& init) { if(network_settings.is_first) { - network_key = api.array_to_element(init.public_share().c_str(), init.public_share().size(), true); + set_network_key(&cmix_ctx, init.public_share().data(), init.public_share().size()); cmix_proto::SecretKey sec; - - unsigned char* data; - size_t len; - - api.element_to_array(&data, &len, network_key); - sec.set_secret_key(data, len); - - api.free_buffer(data); + sec.set_secret_key(init.public_share().data(), init.public_share().size()); next_node.async_send(sec); } else { - - char* buffer; - size_t len; - api.add_public_share(&buffer, &len, init.public_share().c_str(), init.public_share().size(), keypair.pub); - - cmix_proto::Initialization init; - init.set_public_share(buffer, len); - api.free_buffer(buffer); + size_t len = get_group_element_array_size(&cmix_ctx); + cmix_proto::Initialization n_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"; - next_node.async_send(init); + next_node.async_send(n_init); } } @@ -116,7 +105,7 @@ void Node::handle_node_secretkey(cmix_proto::SecretKey const& secret) { std::string share = secret.secret_key(); - network_key = api.array_to_element(secret.secret_key().c_str(), secret.secret_key().size(), true); + set_network_key(&cmix_ctx, secret.secret_key().data(), secret.secret_key().size()); if(network_settings.is_first) { start_precomputation(); @@ -129,85 +118,58 @@ void Node::handle_node_prepre(cmix_proto::PrePre const& pre) { if(network_settings.is_first) { cmix_proto::PreMix premix; - for(int i = 0; i < pre.m_er_size(); ++i) { - GroupElement random_r = api.array_to_element(pre.r_er(i).data(), pre.r_er(i).size(), true); - GroupElement message_r = api.array_to_element(pre.m_er(i).data(), pre.m_er(i).size(), true); - - GroupElement random_s; - GroupElement message_s; - - api.encrypt(&random_s, &message_s, precomputation_data[precomputation_data[i].new_location].s, network_key); - - GroupElement random_pirs = api.multiply(random_r, random_s, true); - GroupElement message_pirs = api.multiply(message_r, message_s, true); - - unsigned char* data; - size_t len; + for(int i = 0; i < cmix_ctx.nr_participants; ++i) { + auto new_pos = cmix_ctx.permutation[i]; + size_t el_len = get_group_element_array_size(&cmix_ctx); - api.element_to_array(&data, &len, random_pirs); - premix.set_r_epirs(precomputation_data[i].new_location, data, len); - api.free_buffer(data); + premix.mutable_r_epirs(new_pos)->resize(el_len); + premix.mutable_m_epirs(new_pos)->resize(el_len); - api.element_to_array(&data, &len, message_pirs); - premix.set_m_epirs(precomputation_data[i].new_location, data, len); - api.free_buffer(data); - - api.free_group_element(random_r); - api.free_group_element(message_r); - api.free_group_element(random_s); - api.free_group_element(message_s); + multiply_s( + &cmix_ctx, + &(*premix.mutable_r_epirs(new_pos))[0], + &(*premix.mutable_m_epirs(new_pos))[0], + pre.r_er(i).data(), + pre.m_er(i).data(), + i + ); } next_node.async_send(premix); } else { - std::vector<size_t> permutation(clients.size()); - std::iota(permutation.begin(), permutation.end(), 0); - //ToDo: generate something different than the ID permutation. + if(start_mix(&cmix_ctx, pre.r_er_size()) != no_error) { + exit(-1); + } + + if(initialize_mix_randomness(&cmix_ctx) != no_error) { + exit(-1); + } cmix_proto::PrePre prepre; for(int i = 0; i < pre.m_er_size(); ++i) { - GroupElement r = api.get_group_element(true); - GroupElement s = api.get_group_element(true); - - GroupElement random_element; - GroupElement message_element; - - api.encrypt(&random_element, &message_element, r, network_key); - - GroupElement other_random_element = api.array_to_element(pre.r_er(i).data(), pre.r_er(i).size(), true); - GroupElement other_message_element = api.array_to_element(pre.m_er(i).data(), pre.m_er(i).size(), true); - - GroupElement new_random_element = api.multiply(random_element, other_random_element, true); - GroupElement new_message_element = api.multiply(message_element, other_message_element, true); - - - unsigned char* buffer; - size_t len; - - api.element_to_array(&buffer, &len, new_random_element); - prepre.add_r_er(buffer, len); - api.free_buffer(buffer); - - api.element_to_array(&buffer, &len, new_message_element); - prepre.add_m_er(buffer, len); - api.free_buffer(buffer); + size_t len = get_group_element_array_size(&cmix_ctx); - api.free_group_element(random_element); - api.free_group_element(message_element); - api.free_group_element(other_random_element); - api.free_group_element(other_message_element); - api.free_group_element(new_random_element); - api.free_group_element(new_message_element); + prepre.mutable_m_er(i)->resize(len); + prepre.mutable_r_er(i)->resize(len); - precomputation_data.emplace_back(MixData{r, s, "", permutation[i]}); + if(encrypt_r_and_multiply(&cmix_ctx, &(*prepre.mutable_r_er(i))[0], &(*prepre.mutable_m_er(i))[0], pre.r_er(i).data(), pre.m_er(i).data(), i) != no_error) { + exit(-1); + } } - next_node.async_send(prepre); } } +void Node::handle_node_premix(cmix_proto::PreMix const& premix) { + if(network_settings.is_first) { + + } else { + + } +} + void Node::handle_node_message(cmix_proto::CMixMessage message) { switch(message.contents_case()) { @@ -231,6 +193,11 @@ void Node::handle_node_message(cmix_proto::CMixMessage message) handle_node_prepre(message.prepre()); break; } + case cmix_proto::CMixMessage::ContentsCase::kPremix: { + BOOST_LOG_TRIVIAL(trace) << "Handling PreMix"; + handle_node_premix(message.premix()); + break; + } default: { BOOST_LOG_TRIVIAL(error) << "handle_node_message: CMixMessage contains unknown contents."; } @@ -241,30 +208,19 @@ void Node::handle_node_message(cmix_proto::CMixMessage message) } void Node::handle_client_keyexchange(ClientConnections::key_type handle, cmix_proto::KeyExchange ke) { - void* priv_el = api.get_group_element(true); - - data[handle].shared_value = api.derive_shared_key(keypair, reinterpret_cast<uint8_t const*>(ke.public_key().c_str()), ke.public_key().size(), reinterpret_cast<uint8_t const*>(ke.value().c_str()), ke.value().size(), priv_el, true); - - void* ex_val = api.get_key_exchange_value(priv_el); + CMixClientData d; - api.free_group_element(priv_el); + size_t len = get_group_element_array_size(&cmix_ctx); - cmix_proto::KeyExchange exchange; + cmix_proto::KeyExchange nke; + nke.mutable_public_key()->resize(len); + nke.mutable_value()->resize(len); - unsigned char* buffer; - size_t len; + key_exchange(&cmix_ctx, &d.shared_value.shared, &(*nke.mutable_public_key())[0], &(*nke.mutable_value())[0], ke.public_key().data(), ke.value().data()); - api.element_to_array(&buffer, &len, keypair.pub); - exchange.set_public_key(buffer, len); - api.free_buffer(buffer); + data[handle] = d; - api.element_to_array(&buffer, &len, ex_val); - exchange.set_value(buffer, len); - api.free_buffer(buffer); - - api.free_group_element(ex_val); - - clients.at(handle).async_send(exchange); + clients.at(handle).async_send(nke); } void Node::handle_client_bye(ClientConnections::key_type handle, cmix_proto::Bye) @@ -347,42 +303,25 @@ void Node::handle_message(Purgatory::iterator handle, cmix_proto::CMixMessage me } void Node::start_precomputation() { - precomputation_data.clear(); - precomputation_data.reserve(clients.size()); + if(start_mix(&cmix_ctx, clients.size()) != no_error) { + exit(-1); + } - std::vector<size_t> permutation(clients.size()); - std::iota(permutation.begin(), permutation.end(), 0); - //ToDo: generate something different than the ID permutation. + if(initialize_mix_randomness(&cmix_ctx) != no_error) { + exit(-1); + } cmix_proto::PrePre prepre; - auto perm_it = permutation.begin(); - for(auto const& pair : clients) { - GroupElement r = api.get_group_element(true); - GroupElement s = api.get_group_element(true); - - GroupElement random_element; - GroupElement message_element; - - api.encrypt(&random_element, &message_element, r, network_key); + for(size_t i = 0; i < cmix_ctx.nr_participants; ++i) { + size_t len = get_group_element_array_size(&cmix_ctx); - unsigned char* buffer; - size_t len; + prepre.mutable_r_er(i)->resize(len); + prepre.mutable_m_er(i)->resize(len); - api.element_to_array(&buffer, &len, random_element); - prepre.add_m_er(buffer, len); - api.free_buffer(buffer); - - api.element_to_array(&buffer, &len, message_element); - prepre.add_m_er(buffer, len); - api.free_buffer(buffer); - - next_node.async_send(prepre); - - precomputation_data.emplace_back(MixData{r, s, pair.first, *perm_it++}); - - api.free_group_element(random_element); - api.free_group_element(message_element); + if(encrypt_r(&cmix_ctx, &(*prepre.mutable_r_er(i))[0], &(*prepre.mutable_m_er(i))[0], i) != no_error) { + exit(-1); + } } next_node.async_send(prepre); diff --git a/node/node.hpp b/node/node.hpp index 9e256c7..6587556 100644 --- a/node/node.hpp +++ b/node/node.hpp @@ -6,6 +6,7 @@ #include "sender.hpp" #include "api.h" +#include "cmix.h" #include "cmix.pb.h" @@ -50,7 +51,7 @@ class Node }; boost::asio::io_service io_service; - std::shared_ptr<boost::asio::ssl::context> ctx; + std::shared_ptr<boost::asio::ssl::context> ssl_ctx; Server server; typedef std::list<SSLReceiver> Purgatory; @@ -66,9 +67,7 @@ class Node SSLReceiver prev_node; SSLSender next_node; - Api api; - KeyPair keypair; - void* network_key; + CMixContext cmix_ctx; std::vector<MixData> precomputation_data; @@ -83,6 +82,7 @@ class Node 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_message(cmix_proto::CMixMessage message); void handle_client_keyexchange(ClientConnections::key_type handle, cmix_proto::KeyExchange ke); |
