#pragma once #ifdef __cplusplus extern "C" { #endif #include "api.h" #include "keypair.h" #include "groupelement.h" /*! * \file */ /*! * \brief The cmix_error enum describes the output state of a each of the cmix functions */ enum cmix_error { no_error = 0, index_out_of_range = 1000, cmix_bignum_error = 2000, out_of_memory = 4000, }; /*! * \brief The CMixContext struct contains all the neccesary data to perform a cmix "mix" */ struct CMixContext { struct Api api; ///< The crypto api in use. struct KeyPair keypair; ///< The keypair used in the crypto api. GroupElement network_key; ///< The network key (called d in the paper). size_t nr_participants; ///< The number of mix participants. GroupElement* r; ///< An array of random values (R in the paper). GroupElement* s; ///< An array of random values (S in the paper). unsigned int* permutation; ///< a permutation (π in the paper (called Pi in source)). GroupElement* pirs; ///< an array containing π(R) * S }; #ifndef NDEBUG /*! * \brief element_to_buffer under Release operation non public function that converts a element to an array. * This function is disabled in release builds * \param ctx The current cmix context. * \param buffer A pointer that points to a buffer large enough to fit the element. * \param element The element to convert to the array representation. */ void element_to_buffer(struct CMixContext const* ctx, char* buffer, GroupElement const element); #endif /*! * \brief initialize_cmix_context is a CMixContext factory. it required a crypto api. * \param api The cryptop api to initialize this CMixContext for. * \return The created and Initialized CMixContext; */ struct CMixContext initialize_cmix_context(struct Api api); /*! * \brief deinitialize deallocates all the context resources and deinitializes the crypto api. * \param ctx The CMixContext to deinitialize. */ void deinitialize(struct CMixContext* ctx); /*! * \brief initialize_keypair initializes a new keypair from random data, using the crypto api. * \param ctx The relevant cmix context. * \return A cmix_error */ enum cmix_error initialize_keypair(struct CMixContext* ctx); /*! * \brief get_public_key Retrieves an array representation of the public key. * \param ctx The context with the public key. * \param buffer The buffer to store the array representation in. Should be long enough to store the result. * \return A cmix_error */ enum cmix_error get_public_key(struct CMixContext const* ctx, char* buffer); /*! * \brief add_public_share Multiplies your public key with the received public share. * \param ctx The relevant context. * \param buffer Buffer large enough to write the result to. * \param share Buffer containing the current share. * \return A cmix_error */ enum cmix_error add_public_share(struct CMixContext const* ctx, char* buffer, char const* share); /*! * \brief get_pub_key_hash get a hash representation of your public key; * \param ctx The relevant context. * \param buffer A pointer to a char pointer that after this function will point to a buffer * of size len containing the hash. Should be deleted with free after use * \param len The length of the hash buffer. * \return A cmix_error */ enum cmix_error get_pub_key_hash(struct CMixContext const* ctx, char** buffer, size_t* len); /*! * \brief get_pub_key_hash_length a seperate function that returns the length of the hash returned by get_pub_key_hash * \param ctx The relevant context. * \return A cmix_error */ size_t get_pub_key_hash_length(struct CMixContext const* ctx); /*! * \brief start_mix Releases the previous and allocates the new mix. * \param ctx The relevant context. * \param nr_participants The number of participants in the new mix. * \return A cmix_error */ enum cmix_error start_mix(struct CMixContext* ctx, size_t nr_participants); /*! * \brief release_mix Releases all the mix resources in the current mix (not the keypair nor the api) * \param ctx The relevant context. */ void release_mix(struct CMixContext* ctx); /*! * \brief initialize_mix_randomness initializes all the randomness (R, S and Pi (permutation)) * \param ctx The relevant context. * \return A cmix_error */ enum cmix_error initialize_mix_randomness(struct CMixContext* ctx); /*! * \brief generate_random_message Generates a random message * \param ctx The relevant context. * \param buffer A pointer to a buffer large enough to hold an array representation of a group element. * \return A cmix_error */ enum cmix_error generate_random_message(struct CMixContext* ctx, char* buffer); /*! * \brief get_group_element_array_size Get the minimum size required to store an array representation of a group element. * \param ctx The relevant context. * \return A cmix_error */ size_t get_group_element_array_size(struct CMixContext const* ctx); /*! * \brief set_network_key Sets the nework key in the context to the group element stored in buffer. * \param ctx The relevant context. * \param buffer The buffer containing an array representation of a group element. * \return */ enum cmix_error set_network_key(struct CMixContext* ctx, char const* buffer); /*! * \brief encrypt_r Encrypts r with the network key * \param ctx The relevant context. * \param random_buffer An array of buffers for storing the random component of the elgamal encryption. * \param message_buffer An array of buffers for storing the message component of the elgamal encryption. * \return A cmix_error */ enum cmix_error encrypt_r(struct CMixContext const* ctx, char** random_buffer, char** message_buffer); /*! * \brief encrypt_r_and_multiply Encrypts R and multiplies it with a previous result. * \param ctx The relevant context. * \param random_buffer The random component output buffer. * \param message_buffer The message component output buffer. * \param random_element The random component of a previous encryption. * \param message_element The message componenet of a previous encryption. * \return */ 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); /*! * \brief permute_and_multiply_encrypted_s Permutes the incoming buffer and multiplies with encrypted S * \param ctx The relevant context. * \param random_buffer The random component output buffer. * \param message_buffer The message component output buffer. * \param random_element The random component of a previous encryption. * \param message_element The message component of a previous encryption. * \return */ enum cmix_error permute_and_multiply_encrypted_s(struct CMixContext const* ctx, char** random_buffer, char** message_buffer, char const** random_element, char const** message_element); /*! * \brief permute_and_multiply_s Permutes the incoming buffer and multiplies with S * \param ctx The relevant context. * \param out_buffer The output buffer. * \param message The input buffer. * \return A cmix_error */ enum cmix_error permute_and_multiply_s(struct CMixContext const* ctx, char** out_buffer, char const** message); /*! * \brief key_exchange_init Function to call when initiating a key exchange. * \param ctx The relevan context. * \param pubkey_buffer Buffer large enough to hold the public key in array representation. * \param value_buffer The exchange value to send over to the other party. * \param secret_value The secret value used to finalize the key exchange. * \return A cmix_error */ enum cmix_error key_exchange_init(struct CMixContext const* ctx, char* pubkey_buffer, char* value_buffer, GroupElement* secret_value); /*! * \brief key_exchange_responder When receiving a key exchange request call this function. * \param ctx The relevant context. * \param shared_key A pointer to a GroupElement storage that will be filled by this function. * \param public_key_buffer A buffer large enough to hold the array representation of your public key. * \param exhange_value_buffer The exchange value to send over to the other party. * \param pubkey The other parties public key in array representation. * \param value The other parties exchange value. * \return A cmix_error */ enum cmix_error key_exchange_responder(struct CMixContext const* ctx, GroupElement* shared_key, char* public_key_buffer, char* exhange_value_buffer, char const* pubkey, char const* value); /*! * \brief key_exchange_initiator When you initiaed the key exchange and receive an exchagne message call this function. * \param ctx The relevant context. * \param shared_key A pointer to a GroupElement storage that will be filled by this function. * \param pubkey The other parties public key. * \param value The other parties exchange value. * \param priv_el The private element generated by key_exchange_init. * \return A cmix_error */ enum cmix_error key_exchange_initiator(struct CMixContext const* ctx, GroupElement* shared_key, char const* pubkey, char const* value, GroupElement* priv_el); /*! * \brief post_process decrypts Pi(R) * S and stores it in the context. * \note The stored pirs only has meaning for the last node, but just storing it for the last node just adds unneeded complexity. * \param ctx The relevant context. * \param r_out The output buffer for the random components. * \param m_out The output buffer for the message components. * \param r_epirs The input buffer for the random components. * \param m_epirs The input buffer for the message components. * \return A cmix_error */ enum cmix_error post_process(struct CMixContext* ctx, char** r_out, char** m_out, char const** r_epirs, char const** m_epirs); //TODO: check if we should add a length that pairs with message. /*! * \brief blind_message Blinds the message with all the shared keys between you and the nodes. * \param ctx The relevant context. * \param m_out The output buffer large enough to hold the array representation of a group element. * \param message The input message buffer. * \param keys Buffer that contains nr_nodes shared keys. * \param nr_nodes The number of keys in the keys buffer. * \return A cmix_error */ enum cmix_error blind_message(struct CMixContext const* ctx, char* m_out, char const* message, GroupElement const* keys, size_t const nr_nodes); /*! * \brief swap_k_for_r multiplies with K^-1 and multiplies with R * \param ctx The relevant context. * \param out_buffer The output buffer. * \param message The input buffer. * \param key The K to inverse and multiply with. * \return A cmix_error */ enum cmix_error swap_k_for_r(struct CMixContext const* ctx, char** out_buffer, char const** message, GroupElement const* key); /*! * \brief remove_r_and_s multiply with (Pi(R) * S)^-1 * \param ctx The relevant context. * \param out_buffer The ouput buffer, * \param message The input buffer * \param index message process message x (take the x'th Pi(R) * S) * \return A cmix_error */ enum cmix_error remove_r_and_s(struct CMixContext const* ctx, char* out_buffer, char const* message, size_t index); /*! * \brief create_message Creates a message by embedding the destination in the message buffer. * \param ctx The relevant context. * \param out_buffer output buffer needs to be large enough to hold a GroupElement in array representation. * \param dest The destination string. * \param dest_len The destination string length. * \param payload The payload string. * \param payload_len The payload string length. * \return A cmix_error */ enum cmix_error create_message(struct CMixContext const* ctx, char* out_buffer, char const* dest, size_t dest_len, char const* payload, size_t payload_len); /*! * \brief split_message Splits a message in its destination and payload components. * \param ctx The relevant context. * \param dest_buffer pointer to a char* storage that will be initialized by this function. * must be free()d * \param dest_len pointer to a size_t ,will be filled with the resulting destination string length. * \param payload_buffer pointer to a char* storage that will be initialized by this function. * must be free()d * \param payload_len point to a size_t, will be filled with the resulting payload string length. * \param message The unsplitted string pointer (is of length group element array representation length). * \return A cmix_error */ enum cmix_error split_message(struct CMixContext const* ctx, char** dest_buffer, size_t* dest_len, char** payload_buffer, size_t* payload_len, char const* message); #ifdef __cplusplus } // extern "C" #endif