#pragma once #define VAR_IN_(x, y) x ## _ ## y #define VAR_IN(x, y) VAR_IN_(x, y) #define VAR(y) VAR_IN(ALGORITHM, y) #define DEF_IN_(x, y, z) x ## _ ## y ## _ ## z #define DEF_IN(x, y, z) DEF_IN_(x, y, z) #define DEF(z) DEF_IN(API, ALGORITHM, z) #define LINK_IMPLEMENTATION \ Initializer VAR(initialize) = &DEF(initialize); \ KeyPairCreator VAR(create_keypair) = &DEF(create_keypair); \ KeyPairDeleter VAR(delete_keypair) = &DEF(delete_keypair); \ ElementToArray VAR(element_to_array) = &DEF(element_to_array); \ BufferDeleter VAR(free_buffer) = &DEF(free_buffer); \ ArrayToElement VAR(array_to_element) = &DEF(array_to_element); \ MessageToElement VAR(message_to_element) = &DEF(message_to_element); \ ElementToMessage VAR(element_to_message) = &DEF(element_to_message); \ PubKeyHashGetter VAR(get_pub_key_hash) = &DEF(get_pub_key_hash); \ PubKeyHashLengthGetter VAR(get_pub_key_hash_length) = &DEF(get_pub_key_hash_length); \ GroupElementGetter VAR(get_group_element) = &DEF(get_group_element); \ GroupElementDeleter VAR(delete_group_element) = &DEF(delete_group_element); \ KeyExchangeValueGetter VAR(get_key_exchange_value) = &DEF(get_key_exchange_value); \ GroupElementCombiner VAR(combine) = &DEF(combine); \ GroupElementUncombiner VAR(uncombine) = &DEF(uncombine); \ DecryptionShareGetter VAR(get_decryption_share) = &DEF(get_decryption_share); \ GroupElementArraySizeGetter VAR(get_group_element_array_size) = &DEF(get_group_element_array_size); \ MessageSizeGetter VAR(get_message_size) = &DEF(get_message_size); \ PublicShareAdder VAR(add_public_share) = &DEF(add_public_share); \ SharedKeyDeriver VAR(derive_shared_key) = &DEF(derive_shared_key); \ SharedKeyDeleter VAR(delete_shared_key) = &DEF(delete_shared_key); \ Encrypter VAR(encrypt) = &DEF(encrypt); \ Inverter VAR(invert) = &DEF(invert); \ UniformIntGetter VAR(get_uniform_int) = &DEF(get_uniform_int); \ Deinitializer VAR(deinitialize) = &DEF(deinitialize); //before expanding LINK_IMPLEMENTATION in your crypto api implementation file you need to define the following functions /* void DEF(initialize)(void) {} struct KeyPair DEF(create_keypair)(void) {} void DEF(delete_keypair)(struct KeyPair* pair) {} void DEF(element_to_array)(unsigned char** buffer, size_t* len, GroupElement element) {} void DEF(free_buffer)(void* buffer) {} GroupElement DEF(array_to_element)(char const* buffer, size_t len, bool secure) {} GroupElement DEF(message_to_element)(char const* buffer, size_t len, bool secure) {} void DEF(element_to_message)(char** buffer, const GroupElement el); size_t DEF(get_pub_key_hash_length)(void) {} void DEF(get_pub_key_hash)(char** buffer, size_t* len, GroupElement const pub) {} GroupElement DEF(get_group_element)(bool secure) {} GroupElement DEF(get_key_exchange_value)(GroupElement group_el) {} GroupElement DEF(combine)(GroupElement lh, GroupElement rh, bool secure) {} GroupElement DEF(uncombine)(GroupElement lh, GroupElement rh, bool secure) {} GroupElement DEF(get_decryption_share)(GroupElement r, GroupElement e) {} size_t DEF(get_group_element_array_size)(void) {} size_t DEF(get_message_size)(void) {} void DEF(delete_group_element)(GroupElement element) {} void DEF(add_public_share)(GroupElement* el, char const* share, size_t in_len, GroupElement pubkey) {} GroupElement DEF(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) {} void DEF(delete_shared_key)(struct SharedKey* s) {} void DEF(encrypt)(GroupElement* random_element, GroupElement* message_element, GroupElement value, GroupElement key) } GroupElement DEF(invert)(GroupElement const x) {} unsigned int DEF(get_uniform_int)(unsigned int upper) {} void DEF(deinitialize)(void) {} */