aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDennis Brentjes <d.brentjes@gmail.com>2016-10-30 13:38:49 +0100
committerDennis Brentjes <d.brentjes@gmail.com>2016-10-30 16:37:03 +0100
commita3e62d3bc6e7f75949726f9a8dafe03e757e869b (patch)
tree49e59076a7ffd7ea757f650a64aaba2b16be1886
parent158bf81343054982800d44d507e8e50f2eeb6dd4 (diff)
downloadcmix-a3e62d3bc6e7f75949726f9a8dafe03e757e869b.tar.gz
cmix-a3e62d3bc6e7f75949726f9a8dafe03e757e869b.tar.bz2
cmix-a3e62d3bc6e7f75949726f9a8dafe03e757e869b.zip
Added the Preprocessing step for the Precomputation of CMix.
-rw-r--r--client/cmixclient.cpp24
-rw-r--r--client/cmixclient.hpp6
-rw-r--r--libcmix-common/CMakeLists.txt2
-rw-r--r--libcmix-common/cmixprotofunctor.cpp18
-rw-r--r--libcmix-common/cmixprotofunctor.hpp47
-rw-r--r--libcmix-crypto/api.h35
-rw-r--r--libcmix-crypto/curve25519/curve25519.c5
-rw-r--r--libcmix-crypto/curve25519/curve25519.h2
-rw-r--r--libcmix-crypto/curve25519/sodium/libsodium_curve25519.c2
-rw-r--r--libcmix-crypto/elgamal/elgamal.c25
-rw-r--r--libcmix-crypto/elgamal/elgamal.h80
-rw-r--r--libcmix-crypto/elgamal/gcrypt/gcrypt_elgamal.c97
-rw-r--r--libcmix-crypto/groupelement.h11
-rw-r--r--libcmix-crypto/keypair.h6
-rw-r--r--libcmix-crypto/sharedkey.h4
-rw-r--r--libcmix-protobuf/cmix.proto14
-rw-r--r--node/node.cpp125
-rw-r--r--node/node.hpp18
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);