diff options
| -rw-r--r-- | client/cmixclient.cpp | 24 | ||||
| -rw-r--r-- | client/cmixclient.hpp | 6 | ||||
| -rw-r--r-- | libcmix-common/CMakeLists.txt | 2 | ||||
| -rw-r--r-- | libcmix-common/cmixprotofunctor.cpp | 18 | ||||
| -rw-r--r-- | libcmix-common/cmixprotofunctor.hpp | 47 | ||||
| -rw-r--r-- | libcmix-crypto/api.h | 35 | ||||
| -rw-r--r-- | libcmix-crypto/curve25519/curve25519.c | 5 | ||||
| -rw-r--r-- | libcmix-crypto/curve25519/curve25519.h | 2 | ||||
| -rw-r--r-- | libcmix-crypto/curve25519/sodium/libsodium_curve25519.c | 2 | ||||
| -rw-r--r-- | libcmix-crypto/elgamal/elgamal.c | 25 | ||||
| -rw-r--r-- | libcmix-crypto/elgamal/elgamal.h | 80 | ||||
| -rw-r--r-- | libcmix-crypto/elgamal/gcrypt/gcrypt_elgamal.c | 97 | ||||
| -rw-r--r-- | libcmix-crypto/groupelement.h | 11 | ||||
| -rw-r--r-- | libcmix-crypto/keypair.h | 6 | ||||
| -rw-r--r-- | libcmix-crypto/sharedkey.h | 4 | ||||
| -rw-r--r-- | libcmix-protobuf/cmix.proto | 14 | ||||
| -rw-r--r-- | node/node.cpp | 125 | ||||
| -rw-r--r-- | node/node.hpp | 18 |
18 files changed, 350 insertions, 171 deletions
diff --git a/client/cmixclient.cpp b/client/cmixclient.cpp index cc743db..f05b200 100644 --- a/client/cmixclient.cpp +++ b/client/cmixclient.cpp @@ -6,31 +6,31 @@ using namespace boost::asio::ip; using namespace boost::asio; -void CMixClient::key_exchange(int i) { - BOOST_LOG_TRIVIAL(trace) << "Sending KeyExchange for node: " << i; +void CMixClient::key_exchange(size_t node_id) { + BOOST_LOG_TRIVIAL(trace) << "Sending KeyExchange for node: " << node_id; - char* buffer; + unsigned char* buffer; size_t len; - api.get_key_array(&buffer, &len, keypair.pub); + api.element_to_array(&buffer, &len, keypair.pub); cmix_proto::KeyExchange ke; ke.set_public_key(buffer, len); free(buffer); - data.at(i).secret_value = api.get_group_element(true); - void* shared_value = api.get_key_exchange_value(data.at(i).secret_value); + data.at(node_id).secret_value = api.get_group_element(true); + void* shared_value = api.get_key_exchange_value(data.at(node_id).secret_value); - api.get_key_array(&buffer, &len, shared_value); + api.element_to_array(&buffer, &len, shared_value); ke.set_value(buffer, len); free(buffer); - network_connections.at(i).async_send(ke); - network_connections.at(i).async_receive([i, this](cmix_proto::CMixMessage message) { - handle_message(i, message); + network_connections.at(node_id).async_send(ke); + network_connections.at(node_id).async_receive([node_id, this](cmix_proto::CMixMessage message) { + handle_message(node_id, message); }); } @@ -55,7 +55,7 @@ void CMixClient::initialize_connections() { } } -void CMixClient::handle_key_exchange(int node_id, cmix_proto::KeyExchange const& ke) +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); @@ -63,7 +63,7 @@ void CMixClient::handle_key_exchange(int node_id, cmix_proto::KeyExchange const& network_connections.at(node_id).async_send(bye); } -void CMixClient::handle_message(int node_id, cmix_proto::CMixMessage message) +void CMixClient::handle_message(size_t node_id, cmix_proto::CMixMessage message) { switch(message.contents_case()) { case cmix_proto::CMixMessage::ContentsCase::kKeyexchange: { diff --git a/client/cmixclient.hpp b/client/cmixclient.hpp index 8922f41..2df754b 100644 --- a/client/cmixclient.hpp +++ b/client/cmixclient.hpp @@ -51,13 +51,13 @@ class CMixClient { Api api; KeyPair keypair; - void key_exchange(int i); + void key_exchange(size_t node_id); void initialize_connections(); - void handle_key_exchange(int node_id, cmix_proto::KeyExchange const& ke); + void handle_key_exchange(size_t node_id, cmix_proto::KeyExchange const& ke); - void handle_message(int node_id, cmix_proto::CMixMessage message); + void handle_message(size_t node_id, cmix_proto::CMixMessage message); public: /*! diff --git a/libcmix-common/CMakeLists.txt b/libcmix-common/CMakeLists.txt index 0861e95..cc3125c 100644 --- a/libcmix-common/CMakeLists.txt +++ b/libcmix-common/CMakeLists.txt @@ -1,6 +1,6 @@ add_library(cmix-common - cmixprotofunctor.hpp cmixprotofunctor.cpp + cmixprotofunctor.hpp receiver.hpp sender.hpp senderreceiver.hpp senderreceiver.cpp diff --git a/libcmix-common/cmixprotofunctor.cpp b/libcmix-common/cmixprotofunctor.cpp deleted file mode 100644 index 525b3c9..0000000 --- a/libcmix-common/cmixprotofunctor.cpp +++ /dev/null @@ -1,18 +0,0 @@ -#include "cmixprotofunctor.hpp" - -#define MESSAGE_SETTER_DEF(TYPE, NAME) \ - CMixProtoFunctor::proto_type CMixProtoFunctor::operator()(cmix_proto::TYPE const& v) { \ - proto_type m; \ - *m.mutable_##NAME() = v; \ - return m; \ - } \ - -MESSAGE_SETTER_DEF(Initialization, initialization) -MESSAGE_SETTER_DEF(ImANode, imanode) -MESSAGE_SETTER_DEF(ImAClient, imaclient) -MESSAGE_SETTER_DEF(Bye, bye) -MESSAGE_SETTER_DEF(KeyExchange, keyexchange) -MESSAGE_SETTER_DEF(SecretKey, secretkey) -MESSAGE_SETTER_DEF(NodeReady, nodeready) - -#undef MESSAGE_SETTER_DEF
\ No newline at end of file diff --git a/libcmix-common/cmixprotofunctor.hpp b/libcmix-common/cmixprotofunctor.hpp index bd69504..75944f9 100644 --- a/libcmix-common/cmixprotofunctor.hpp +++ b/libcmix-common/cmixprotofunctor.hpp @@ -19,46 +19,55 @@ struct CMixProtoFunctor { typedef cmix_proto::CMixMessage proto_type; /*! - * \def MESSAGE_SETTER_DECL(TYPE) - * Generates a message setter declaration for the Protobuf type in TYPE. + * \def MESSAGE_SETTER_DEF(TYPE, NAME) + * Generates a message setter definition for the Protobuf type in TYPE with member name NAME. */ - #define MESSAGE_SETTER_DECL(TYPE) \ - proto_type operator()(cmix_proto::TYPE const& v) + #define MESSAGE_SETTER_DEF(TYPE, NAME) \ + proto_type operator()(cmix_proto::TYPE const& v) { \ + proto_type m; \ + *m.mutable_##NAME() = v; \ + return m; \ + } \ /*! - * #MESSAGE_SETTER_DECL(Initialization) + * #MESSAGE_SETTER_DECL(Initialization, initialization) */ - MESSAGE_SETTER_DECL(Initialization); + MESSAGE_SETTER_DEF(Initialization, initialization) /*! - * #MESSAGE_SETTER_DECL(ImANode) + * #MESSAGE_SETTER_DECL(ImANode, imanode) */ - MESSAGE_SETTER_DECL(ImANode); + MESSAGE_SETTER_DEF(ImANode, imanode) /*! - * #MESSAGE_SETTER_DECL(ImAClient) + * #MESSAGE_SETTER_DECL(ImAClient, imaclient) */ - MESSAGE_SETTER_DECL(ImAClient); + MESSAGE_SETTER_DEF(ImAClient, imaclient) /*! - * #MESSAGE_SETTER_DECL(Bye) + * #MESSAGE_SETTER_DECL(Bye, bye) */ - MESSAGE_SETTER_DECL(Bye); + MESSAGE_SETTER_DEF(Bye, bye) /*! - * #MESSAGE_SETTER_DECL(KeyExchange) + * #MESSAGE_SETTER_DECL(KeyExchange, keyexchange) */ - MESSAGE_SETTER_DECL(KeyExchange); + MESSAGE_SETTER_DEF(KeyExchange, keyexchange) /*! - * #MESSAGE_SETTER_DECL(SecretKey) + * #MESSAGE_SETTER_DECL(SecretKey, secretkey) */ - MESSAGE_SETTER_DECL(SecretKey); + MESSAGE_SETTER_DEF(SecretKey, secretkey) /*! - * + * #MESSAGE_SETTER_DECL(NodeReady, nodeready) */ - MESSAGE_SETTER_DECL(NodeReady); + MESSAGE_SETTER_DEF(NodeReady, nodeready) + + /*! + * #MESSAGE_SETTER_DECL(PrePre, prepre) + */ + MESSAGE_SETTER_DEF(PrePre, prepre); - #undef MESSAGE_SETTER + #undef MESSAGE_SETTER_DEF }; diff --git a/libcmix-crypto/api.h b/libcmix-crypto/api.h index 99f6417..f50cee0 100644 --- a/libcmix-crypto/api.h +++ b/libcmix-crypto/api.h @@ -10,6 +10,7 @@ extern "C" { #include <stdbool.h> +#include "groupelement.h" #include "keypair.h" #include "sharedkey.h" @@ -31,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, void*, bool); +typedef struct SharedKey (*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. @@ -47,27 +48,42 @@ typedef void(*Deinitializer)(void); /*! * \brief PubKeyArrayGetter typedef */ -typedef void(*KeyArrayGetter)(char**, size_t* size, void*); +typedef void(*ElementToArray)(unsigned char**, size_t* size, GroupElement); + +/*! + * + */ +typedef GroupElement(*ArrayToElement)(char const*, size_t size, bool); /*! * \brief PublicShareAdder typedef */ -typedef void(*PublicShareAdder)(char**, size_t*, char const*, size_t, void*); +typedef void(*PublicShareAdder)(char**, size_t*, char const*, size_t, GroupElement); /*! * */ -typedef void*(*GroupElementGetter)(bool); +typedef GroupElement(*GroupElementGetter)(bool); /*! * */ -typedef void*(*KeyExchangeValueGetter)(void*); +typedef GroupElement(*KeyExchangeValueGetter)(GroupElement); + +/*! + * + */ +typedef GroupElement(*GroupElementMultiplier)(GroupElement, GroupElement, bool); /*! * */ -typedef void(*GroupElementDeleter)(void*); +typedef void(*GroupElementDeleter)(GroupElement); + +/*! + * + */ +typedef void (*Encrypter)(GroupElement*, GroupElement*, GroupElement, GroupElement); /*! * \brief The Api struct stores pointers to functions of a specific implementation. Like a Curve25519 specific one. @@ -76,13 +92,16 @@ 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 - KeyArrayGetter get_key_array; ///< Get the array representation of a public key + ElementToArray element_to_array; ///< Get the array representation of a public key + ArrayToElement array_to_element; ///< The the GroupElement representation of this array; GroupElementGetter get_group_element; ///< get group element - KeyExchangeValueGetter get_key_exchange_value; ///< get generator *op* group element. 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. PublicShareAdder add_public_share; ///< Adds the public key stored in void* to the existing share. SharedKeyDeriver derive_shared_key; ///< Pointer to shared key derivation function SharedKeyDeleter free_shared_key; ///< Pointer to shared key deleter function + Encrypter encrypt; ///< encrypt value with key; Deinitializer deinitialize; ///< Function that will deinitialize the crypto library. }; diff --git a/libcmix-crypto/curve25519/curve25519.c b/libcmix-crypto/curve25519/curve25519.c index 0036808..1a83308 100644 --- a/libcmix-crypto/curve25519/curve25519.c +++ b/libcmix-crypto/curve25519/curve25519.c @@ -8,13 +8,16 @@ struct Api get_curve25519_implementation() &curve25519_initialize, &curve25519_create_keypair, &curve25519_keypair_deleter, - &curve25519_get_key_array, + &curve25519_key_to_array, + NULL, + NULL, NULL, NULL, NULL, &curve25519_add_public_share, &curve25519_derive_shared_key, &curve25519_shared_key_deleter, + NULL, &curve25519_deinitialize }; } diff --git a/libcmix-crypto/curve25519/curve25519.h b/libcmix-crypto/curve25519/curve25519.h index 2dc2e48..9b65d4e 100644 --- a/libcmix-crypto/curve25519/curve25519.h +++ b/libcmix-crypto/curve25519/curve25519.h @@ -33,7 +33,7 @@ extern void curve25519_keypair_deleter(struct KeyPair* p); * \param buffer * \param len */ -extern void curve25519_get_key_array(char** buffer, size_t* len, void* pubkey); +extern void curve25519_key_to_array(unsigned char** buffer, size_t* len, void* pubkey); /*! * \brief curve25519_add_public_share diff --git a/libcmix-crypto/curve25519/sodium/libsodium_curve25519.c b/libcmix-crypto/curve25519/sodium/libsodium_curve25519.c index 0fbd387..6c3fe13 100644 --- a/libcmix-crypto/curve25519/sodium/libsodium_curve25519.c +++ b/libcmix-crypto/curve25519/sodium/libsodium_curve25519.c @@ -39,7 +39,7 @@ void curve25519_shared_key_deleter(struct SharedKey* s) { s->shared = NULL; } -void curve25519_get_key_array(char** buffer, size_t* len, void* key) { +void curve25519_key_to_array(unsigned char** buffer, size_t* len, void* key) { } diff --git a/libcmix-crypto/elgamal/elgamal.c b/libcmix-crypto/elgamal/elgamal.c index 342659b..3ee86d7 100644 --- a/libcmix-crypto/elgamal/elgamal.c +++ b/libcmix-crypto/elgamal/elgamal.c @@ -4,17 +4,20 @@ struct Api get_elgamal_implementation() { elgamal_initialize(); return (struct Api) { - &elgamal_initialize, - &elgamal_create_keypair, - &elgamal_keypair_deleter, - &elgamal_get_key_array, - &elgamal_get_group_element, - &elgamal_get_key_exchange_value, - &elgamal_free_group_element, - &elgamal_add_public_share, - &elgamal_derive_shared_key, - &elgamal_shared_key_deleter, - &elgamal_deinitialize + elgamal_initialize, + elgamal_create_keypair, + elgamal_delete_keypair, + elgamal_element_to_array, + 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 }; } diff --git a/libcmix-crypto/elgamal/elgamal.h b/libcmix-crypto/elgamal/elgamal.h index dc2dd6f..746b726 100644 --- a/libcmix-crypto/elgamal/elgamal.h +++ b/libcmix-crypto/elgamal/elgamal.h @@ -10,79 +10,33 @@ extern "C" { #include "api.h" -/*! - * \brief elgamal_initialize initializes the elgamal library - */ -extern void elgamal_initialize(void); +extern Initializer elgamal_initialize; -/*! - * \brief elgamal_create_keypair - * \return The new keypair - */ -extern struct KeyPair elgamal_create_keypair(void); +extern KeyPairCreator elgamal_create_keypair; -/*! - * \brief elgamal_keypair_deleter - * \param p the keypair to be freed - */ -extern void elgamal_keypair_deleter(struct KeyPair* p); +extern KeyPairDeleter elgamal_delete_keypair; -/*! - * \brief elgamal_get_pubkey_array - * \param buffer - * \param len - * \param pubkey - */ -extern void elgamal_get_key_array(char** buffer, size_t* len, void* pubkey); +extern ElementToArray elgamal_element_to_array; -/*! - * \brief get_group_element - * \param secure - * \return - */ -extern void* elgamal_get_group_element(bool secure); +extern ArrayToElement elgamal_array_to_element; -/*! - * \brief get_key_exchange_value - * \param group_el - * \return - */ -extern void* elgamal_get_key_exchange_value(void* group_el); +extern GroupElementGetter elgamal_get_group_element; -/*! - * \brief elgamal_free_group_element - */ -extern void elgamal_free_group_element(void*); +extern GroupElementDeleter elgamal_delete_group_element; -/*! - * \brief elgamal_add_public_share - * \param buffer - * \param in_len - * \param share - * \param in_len - * \param pubkey - */ -void elgamal_add_public_share(char** buffer, size_t* out_len, char const* share, size_t in_len, void* pubkey); +extern KeyExchangeValueGetter elgamal_get_key_exchange_value; -/*! - * \brief elgamal_derive_shared_key - * \param pair Our keypair. - * \param pub_key The public key of the other party. - * \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 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); +extern GroupElementMultiplier elgamal_multiply; -/*! - * \brief elgamal_shared_key_deleter - * \param s The shared key to be freed. - */ -extern void elgamal_shared_key_deleter(struct SharedKey* s); +extern PublicShareAdder elgamal_add_public_share; -/*! - * \brief elgamal_deinitialize deinitializes the elgamal_library - */ -void elgamal_deinitialize(void); +extern SharedKeyDeriver elgamal_derive_shared_key; + +extern SharedKeyDeleter elgamal_delete_shared_key; + +extern Encrypter elgamal_encrypt; + +extern Deinitializer elgamal_deinitialize; /*! * \brief get_elgamal_implementation diff --git a/libcmix-crypto/elgamal/gcrypt/gcrypt_elgamal.c b/libcmix-crypto/elgamal/gcrypt/gcrypt_elgamal.c index ac90a51..1dd0690 100644 --- a/libcmix-crypto/elgamal/gcrypt/gcrypt_elgamal.c +++ b/libcmix-crypto/elgamal/gcrypt/gcrypt_elgamal.c @@ -1,5 +1,5 @@ -#include "api.h" +#include "elgamal.h" #include "gcrypt.h" @@ -32,7 +32,7 @@ void print_sexp(gcry_sexp_t exp) { free(str); } -void elgamal_initialize(void) { +void gcrypt_elgamal_initialize(void) { if (!gcry_check_version (GCRYPT_VERSION)) { fprintf(stderr, "libgcrypt version mismatch\n"); exit(-1); @@ -61,7 +61,7 @@ void elgamal_initialize(void) { check(error); } -struct KeyPair elgamal_create_keypair() { +struct KeyPair gcrypt_elgamal_create_keypair() { size_t parse_error_offset; gcry_error_t error; @@ -90,23 +90,33 @@ struct KeyPair elgamal_create_keypair() { }; } -void elgamal_keypair_deleter(struct KeyPair* p) { +void gcrypt_elgamal_delete_keypair(struct KeyPair* p) { gcry_mpi_release((gcry_mpi_t) p->sec); gcry_mpi_release((gcry_mpi_t) p->pub); p->sec = NULL; p->pub = NULL; } -void elgamal_get_key_array(unsigned char** buffer, size_t* len, void* key) { +void gcrypt_elgamal_element_to_array(unsigned char** buffer, size_t* len, void* key) { gcry_mpi_t mpi = (gcry_mpi_t) key; gcry_error_t error; - error = gcry_mpi_aprint(GCRYMPI_FMT_USG, buffer, len, mpi); check(error); } -void* elgamal_get_group_element(bool secure) { +void* gcrypt_elgamal_array_to_element(char const* buffer, size_t len, bool secure) { + size_t error_pos; + gcry_error_t error; + + gcry_mpi_t mpi = secure ? gcry_mpi_snew(0) : gcry_mpi_new(0); + error = gcry_mpi_scan(&mpi, GCRYMPI_FMT_USG, buffer, len, &error_pos); + check(error); + + return mpi; +} + +void* gcrypt_elgamal_get_group_element(bool secure) { size_t parse_error_offset; gcry_error_t error; @@ -120,11 +130,7 @@ void* elgamal_get_group_element(bool secure) { return a; } -void elgamal_free_group_element(void* el) { - gcry_mpi_release((gcry_mpi_t) el); -} - -void* elgamal_get_key_exchange_value(void* group_el) { +GroupElement gcrypt_elgamal_get_key_exchange_value(GroupElement group_el) { gcry_mpi_t el = (gcry_mpi_t) group_el; gcry_mpi_t val = gcry_mpi_new(0); @@ -133,7 +139,19 @@ void* elgamal_get_key_exchange_value(void* group_el) { return val; } -void elgamal_add_public_share(char** buffer, size_t* out_len, char const* share, size_t in_len, void* pubkey) { +GroupElement gcrypt_elgamal_multiply(GroupElement lh, GroupElement rh, bool secure) { + gcry_mpi_t ret = secure ? gcry_mpi_snew(0) : gcry_mpi_new(0); + gcry_mpi_mulm(ret, (gcry_mpi_t) lh, (gcry_mpi_t) rh, p); + return ret; +} + +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) { gcry_error_t error; size_t parse_error_pos; @@ -151,13 +169,7 @@ void elgamal_add_public_share(char** buffer, size_t* out_len, char const* share, check(error); } -void elgamal_shared_key_deleter(struct SharedKey* s) { - gcry_mpi_release((gcry_mpi_t) s->shared); - s->shared = NULL; -} - - -struct SharedKey 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) { +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) { gcry_error_t error; size_t parse_error_pos; @@ -177,8 +189,51 @@ struct SharedKey elgamal_derive_shared_key(struct KeyPair keypair, unsigned char }; } -void elgamal_deinitialize(void) { +void gcrypt_elgamal_delete_shared_key(struct SharedKey* s) { + gcry_mpi_release((gcry_mpi_t) s->shared); + s->shared = NULL; +} + +void gcrypt_elgamal_encrypt(GroupElement* random_element, GroupElement* message_element, GroupElement value, GroupElement key) { + gcry_error_t error; + size_t parse_error_pos; + + gcry_sexp_t pubkey_expr; + error = gcry_sexp_build(&pubkey_expr, &parse_error_pos, "(public-key (elg (p %M) (g %M) (y %M)))", p, g, key); + check(error); + + gcry_sexp_t value_expr; + error = gcry_sexp_build(&value_expr, &parse_error_pos, "(data (flags raw) (value %M))", value); + check(error); + + gcry_sexp_t enc_expr; + error = gcry_pk_encrypt(&enc_expr, value_expr, pubkey_expr); + check(error); + + gcry_sexp_extract_param(enc_expr, NULL, "ab", random_element, message_element, NULL); + + gcry_sexp_release(enc_expr); + gcry_sexp_release(value_expr); + gcry_sexp_release(pubkey_expr); +} + +void gcrypt_elgamal_deinitialize(void) { gcry_mpi_release(p); gcry_mpi_release(q); gcry_mpi_release(g); } + +Initializer elgamal_initialize = &gcrypt_elgamal_initialize; +KeyPairCreator elgamal_create_keypair = &gcrypt_elgamal_create_keypair; +KeyPairDeleter elgamal_delete_keypair = &gcrypt_elgamal_delete_keypair; +ElementToArray elgamal_element_to_array = &gcrypt_elgamal_element_to_array; +ArrayToElement elgamal_array_to_element = &gcrypt_elgamal_array_to_element; +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; +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; +Encrypter elgamal_encrypt = &gcrypt_elgamal_encrypt; +Deinitializer elgamal_deinitialize = &gcrypt_elgamal_deinitialize;
\ No newline at end of file diff --git a/libcmix-crypto/groupelement.h b/libcmix-crypto/groupelement.h new file mode 100644 index 0000000..60c6b21 --- /dev/null +++ b/libcmix-crypto/groupelement.h @@ -0,0 +1,11 @@ +#pragma once + +#ifdef __cplusplus +extern "C" { +#endif + +typedef void* GroupElement; + +#ifdef __cplusplus +} +#endif
\ No newline at end of file diff --git a/libcmix-crypto/keypair.h b/libcmix-crypto/keypair.h index 3b6e0d1..1222c51 100644 --- a/libcmix-crypto/keypair.h +++ b/libcmix-crypto/keypair.h @@ -8,6 +8,8 @@ extern "C" { #endif +#include "groupelement.h" + #include <stdlib.h> /*! @@ -17,8 +19,8 @@ extern "C" { * responsible for memory meanagement. See the Api struct for examples of this. */ struct KeyPair { - void* sec; ///< Private key - void* pub; ///< Public key + GroupElement sec; ///< Private key + GroupElement pub; ///< Public key }; diff --git a/libcmix-crypto/sharedkey.h b/libcmix-crypto/sharedkey.h index b89cb5b..b2f84f6 100644 --- a/libcmix-crypto/sharedkey.h +++ b/libcmix-crypto/sharedkey.h @@ -8,13 +8,15 @@ extern "C" { #endif +#include "groupelement.h" + /*! * \brief The SharedKey struct. * * Stored the derived shared secret after for instance Diffie-Hellman. */ struct SharedKey { - void* shared; ///< The Shared key. + GroupElement shared; ///< The Shared key. }; #ifdef __cplusplus diff --git a/libcmix-protobuf/cmix.proto b/libcmix-protobuf/cmix.proto index 6403cee..2fe2d83 100644 --- a/libcmix-protobuf/cmix.proto +++ b/libcmix-protobuf/cmix.proto @@ -29,6 +29,19 @@ message NodeReady { } +message PrePre { + repeated bytes r_ER = 1; + repeated bytes m_ER = 2; +} + +message PreMix { + repeated bytes EPiRS = 1; +} + +message PrePost { + repeated bytes PiRS = 1; +} + message CMixMessage { oneof contents { Initialization initialization = 1; @@ -38,5 +51,6 @@ message CMixMessage { Bye bye = 5; KeyExchange keyexchange = 6; NodeReady nodeready = 7; + PrePre prepre = 8; } } diff --git a/node/node.cpp b/node/node.cpp index e8303eb..f5c8dbe 100644 --- a/node/node.cpp +++ b/node/node.cpp @@ -5,7 +5,7 @@ #include "logging.hpp" -#include <iostream> +#include <numeric> using namespace boost::asio::ip; @@ -21,6 +21,7 @@ Node::Node(ListenSettings const& listen_settings, NodeNetworkSettings network_se , api(get_implementation()) , keypair(api.create_key_pair()) , network_key() +, precomputation_data() , shutting_down(false) { GOOGLE_PROTOBUF_VERIFY_VERSION; @@ -69,9 +70,9 @@ void Node::connect_to_next_node() void Node::start_initialisation() { cmix_proto::Initialization init; - char* pub_key; + unsigned char* pub_key; size_t len; - api.get_key_array(&pub_key, &len, keypair.pub); + api.element_to_array(&pub_key, &len, keypair.pub); init.set_public_share(pub_key, len); free(pub_key); @@ -79,11 +80,21 @@ void Node::start_initialisation() { next_node.async_send(init); } + 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); + cmix_proto::SecretKey sec; - sec.set_secret_key(network_key.data(), network_key.size()); + + unsigned char* data; + size_t len; + + api.element_to_array(&data, &len, network_key); + sec.set_secret_key(data, len); + free(data); + next_node.async_send(sec); } else { @@ -103,7 +114,8 @@ void Node::handle_node_initialization(const cmix_proto::Initialization& init) void Node::handle_node_secretkey(cmix_proto::SecretKey const& secret) { std::string share = secret.secret_key(); - network_key = std::vector<uint8_t>(share.begin(), share.end()); + + network_key = api.array_to_element(secret.secret_key().c_str(), secret.secret_key().size(), true); if(network_settings.is_first) { start_precomputation(); @@ -112,6 +124,58 @@ void Node::handle_node_secretkey(cmix_proto::SecretKey const& secret) } } +void Node::handle_node_prepre(cmix_proto::PrePre const& pre) { + if(network_settings.is_first) { + + + } else { + std::vector<size_t> permutation(clients.size()); + std::iota(permutation.begin(), permutation.end(), 0); + //ToDo: generate something different than the ID permutation. + + 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); + free(buffer); + + api.element_to_array(&buffer, &len, new_message_element); + prepre.add_m_er(buffer, len); + free(buffer); + + 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); + + precomputation_data.emplace_back(MixData{r, s, "", permutation[i]}); + } + + next_node.async_send(prepre); + } +} + void Node::handle_node_message(cmix_proto::CMixMessage message) { switch(message.contents_case()) { @@ -130,6 +194,11 @@ void Node::handle_node_message(cmix_proto::CMixMessage message) handle_node_secretkey(message.secretkey()); break; } + case cmix_proto::CMixMessage::ContentsCase::kPrepre: { + BOOST_LOG_TRIVIAL(trace) << "Handling PrePre"; + handle_node_prepre(message.prepre()); + break; + } default: { BOOST_LOG_TRIVIAL(error) << "handle_node_message: CMixMessage contains unknown contents."; } @@ -150,14 +219,14 @@ void Node::handle_client_keyexchange(ClientConnections::key_type handle, cmix_pr cmix_proto::KeyExchange exchange; - char* buffer; + unsigned char* buffer; size_t len; - api.get_key_array(&buffer, &len, keypair.pub); + api.element_to_array(&buffer, &len, keypair.pub); exchange.set_public_key(buffer, len); free(buffer); - api.get_key_array(&buffer, &len, ex_val); + api.element_to_array(&buffer, &len, ex_val); exchange.set_value(buffer, len); free(buffer); @@ -246,4 +315,44 @@ void Node::handle_message(Purgatory::iterator handle, cmix_proto::CMixMessage me } void Node::start_precomputation() { + precomputation_data.clear(); + precomputation_data.reserve(clients.size()); + + std::vector<size_t> permutation(clients.size()); + std::iota(permutation.begin(), permutation.end(), 0); + //ToDo: generate something different than the ID permutation. + + 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); + + unsigned char* buffer; + size_t len; + + api.element_to_array(&buffer, &len, random_element); + prepre.add_m_er(buffer, len); + free(buffer); + + api.element_to_array(&buffer, &len, message_element); + prepre.add_m_er(buffer, len); + free(buffer); + + next_node.async_send(prepre); + + //ToDo generate permutation. + precomputation_data.emplace_back(MixData{r, s, pair.first, *perm_it++}); + + api.free_group_element(random_element); + api.free_group_element(message_element); + } + + next_node.async_send(prepre); } diff --git a/node/node.hpp b/node/node.hpp index 9d59687..9e256c7 100644 --- a/node/node.hpp +++ b/node/node.hpp @@ -27,6 +27,19 @@ struct NodeNetworkSettings { std::string certdir; ///< Directory containing trusted certificate authorities. }; +struct MixData { + GroupElement r; + GroupElement s; + std::string client_handle; + size_t new_location; + + ~MixData(){ + Api api = get_implementation(); + api.free_group_element(r); + api.free_group_element(s); + } +}; + /*! * \brief The Node class */ @@ -55,7 +68,9 @@ class Node Api api; KeyPair keypair; - std::vector<uint8_t> network_key; + void* network_key; + + std::vector<MixData> precomputation_data; bool shutting_down; @@ -67,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_message(cmix_proto::CMixMessage message); void handle_client_keyexchange(ClientConnections::key_type handle, cmix_proto::KeyExchange ke); |
