aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--client/cmixclient.cpp6
-rw-r--r--libcmix-crypto/api.h14
-rw-r--r--libcmix-crypto/curve25519/curve25519.c1
-rw-r--r--libcmix-crypto/curve25519/curve25519.h2
-rw-r--r--libcmix-crypto/curve25519/sodium/libsodium_curve25519.c6
-rw-r--r--libcmix-crypto/elgamal/elgamal.c31
-rw-r--r--libcmix-crypto/elgamal/elgamal.h2
-rw-r--r--libcmix-crypto/elgamal/gcrypt/gcrypt_elgamal.c17
-rw-r--r--libcmix/cmix.c180
-rw-r--r--libcmix/cmix.h43
-rw-r--r--node/node.cpp225
-rw-r--r--node/node.hpp8
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);