Search code examples
cencryptionencryption-symmetric

C Crypto Libraries Supporting HC-128/256?


I have been searching for a while for a crypto library that I can used on linux to implement HC-128/256 encryption for using on network traffic. Unfortunately, support for this seems rather rare. Bouncy Castle supports it for C# and Java, but I need it for C. I have the source code for the HC-128/256 algorithms, but no examples on how to actually use it.

HC-256 Wikipedia:
http://en.wikipedia.org/wiki/HC-256

HC-128 Source Code and Article:
http://www.ecrypt.eu.org/stream/hcp3.html

Any help?


Solution

  • I created a CRYPTOSOCKET class for encrypted comms. It also has a public "encrypt" and "decrypt" function. The socket part really just does encrypt/decrypt and calls send/recv for you. The "socket" functionality of it can be easily stripped out.

    This is C++. If you want C, just look at the encrypt and decrypt functions of the CRYPTOSOCKET class and the constructor. Its very simple. Also, this is HC-256, not HC-128.

    In a header "crypto.hpp".

    #include "ecrypt-sync.h"
    
    #ifndef CRYPTO_H
    #define CRYPTO_H
    
    class CRYPTOSOCKET{
      public:
    /**
    * Creates and initializes the structures required for encryption.
    * 
    * @param[in] socket
    * The socket to send and receive data on. This should already be connected.
    * @param[in] key
    * The key used for encryption and decryption.
    * @param[in] iv
    * The initialization vector used by AES256 CBC mode. This can just be random bytes.
    * 
    * @see generateRandom
    */
    CRYPTOSOCKET(int socket, unsigned char *key, unsigned char *iv);
    
    ~CRYPTOSOCKET();
    
    /**
    * A wrapper for sending data across the connection.
    * 
    * This encrypts the data into an intermediate buffer 
    * prior to sending it across the wire.
    *
    * @see man send
    */
    ssize_t send(const void *buf, size_t len, int flags);
    
    /**
    * A wrapper for receiving data across the connection.
    * 
    * This receives the encrypted data into an intermediate buffer,
    * then decrypts it, and writes it to the output buffer.
    * 
    * @see man recv
    */
    ssize_t recv(void *buf, size_t len, int flags);
    
    /**
    * Encrypts the specified data and places the encrypted data in the specified buffer.
    *
    * @param len Used as input for how long the plaintext is, then for output of how long the cipher text is.
    * @param[in] plaintext The unencrypted data to encrypt.
    * @param[out] ciphertext Where to place the encrypted data.
    * 
    * @returns A pointer to the ciphertext.
    * 
    * @see unsigned char *decrypt(unsigned char *ciphertext, unsigned int len, unsigned char *plaintext)
    */
    unsigned char *encrypt(unsigned char *plaintext, unsigned int len, unsigned char *ciphertext);
    
    /**
    * Decrypts the specified data and places the unencrypted data into the specified buffer.
    * 
    * @param len Used as input for how long the ciphertext is and as output for how long the plaintext is.
    * @param[in] ciphertext The encrypted data to unencrypt.
    * @param[out] plaintext The buffer to place the unencrypted data in.
    * 
    * @returns A pointer to the plaintext.
    *
    * @see unsigned char *encrypt(unsigned char *plaintext, unsigned int len, unsigned char *ciphertext)
    */
    unsigned char *decrypt(unsigned char *ciphertext, unsigned int len, unsigned char *plaintext);
    
    int sock; /**< The underlying socket that this sends and receives on. */
    
      private:
    ECRYPT_ctx e_ctx; /**< The ctx used for encryption. */
    ECRYPT_ctx d_ctx; /**< The ctx used for decryption. */
    };
    
    #endif
    

    And inside "crypto.cpp":

    #include "crypto.hpp"
    #include <sys/types.h>
    #include <sys/socket.h>
    
    CRYPTOSOCKET::CRYPTOSOCKET(int socket, unsigned char *key, unsigned char *iv){
      // Initialize the encryptor.
      ECRYPT_keysetup(&e_ctx, key, 128, 128);
      ECRYPT_ivsetup(&e_ctx, iv);
    
      // Initialize the decryptor.
      ECRYPT_keysetup(&d_ctx, key, 128, 128);
      ECRYPT_ivsetup(&d_ctx, iv);
    
      sock = socket;
    };
    
    CRYPTOSOCKET::~CRYPTOSOCKET(){
      // Nothing to do.
    };
    
    unsigned char *CRYPTOSOCKET::encrypt(unsigned char *plaintext, unsigned int len, unsigned char *ciphertext){
      ECRYPT_process_bytes(0, &e_ctx, plaintext, ciphertext, len);
      return ciphertext;
    }
    
    unsigned char *CRYPTOSOCKET::decrypt(unsigned char *ciphertext, unsigned int len, unsigned char *plaintext){
      ECRYPT_process_bytes(1, &d_ctx, ciphertext, plaintext, len);
      return plaintext;
    }
    
    ssize_t CRYPTOSOCKET::send(const void *buf, size_t len, int flags){
      unsigned char buffer[len];
      encrypt((unsigned char*)buf, len, buffer);
      return ::send(sock, buffer, len, MSG_WAITALL);
    };
    
    ssize_t CRYPTOSOCKET::recv(void *buf, size_t len, int flags){
      unsigned char buffer[len];
      int data = ::recv(sock, buffer, len, MSG_WAITALL);
    
      if(data > 0)
    decrypt(buffer, len, (unsigned char *)buf);
    
      return data;
    };
    /*******************************************************************
    * ECRYPT crap below here....
    */
    
    /* ecrypt-sync.c */
    
    /* *** Please do not edit below here. *** */
    
    //#include "ecrypt-sync.h"
    
    void ECRYPT_init(void){
    };
    
    void ECRYPT_process_bytes(
      int action,                 /* 0 = encrypt; 1 = decrypt; */
      ECRYPT_ctx* ctx, 
      const u8* input, 
      u8* output, 
      u32 msglen)                /* Message length in bytes. */ 
    {
      u32 i, j, msglen32, keystreamword;
    
      msglen32 = msglen >> 2;
    
      for (i = 0; i < msglen32; i++) { 
      keystreamword = generate(ctx);                 /*generate a 32-bit word*/
      for (j = 0; j < 4; j++) {
          *output = *input ^ keystreamword;       /*encrypt one byte*/
          output += 1; 
          input +=1;
              keystreamword = keystreamword >> 8;
          }
      }  
    
      keystreamword = generate(ctx);
      for (i = 0; i < (msglen & 3); i++) {
          *output = *input ^ keystreamword;       /*encrypt one byte*/
      output += 1; 
      input +=1;
      keystreamword = keystreamword >> 8;
      }
    }
    
    void ECRYPT_ivsetup(
      ECRYPT_ctx* ctx, 
      const u8* iv)
    { 
    u32 W[2560],i;
    
    /* initialize the iv */
    for (i = 0; i < 8; i++) ctx->iv[i] = 0;
    for (i = 0; (i < ctx->ivsize) & (i < 32); i++) {
            ctx->iv[i >> 2] =  ctx->iv[i >> 2] | iv[i];
            ctx->iv[i >> 2] = ROTL32(ctx->iv[i >> 2],8);
    }
    
    /* setup the table P and Q */ 
    
        for (i = 0; i < 8;  i++) W[i] = ctx->key[i];
        for (i = 8; i < 16; i++) W[i] = ctx->iv[i-8];
    
        for (i = 16; i < 2560; i++) W[i] = f2(W[i-2]) + W[i-7] + f1(W[i-15]) + W[i-16]+i; 
    
        for (i = 0; i < 1024; i++)  ctx->P[i] = W[i+512];
        for (i = 0; i < 1024; i++)  ctx->Q[i] = W[i+1536];
    
        ctx->counter2048 = 0;
    
      /* run the cipher 4096 steps before generating the output */
        for (i = 0; i < 4096; i++)  generate(ctx);  
    }
    
    void ECRYPT_keysetup(
      ECRYPT_ctx* ctx, 
      const u8* key, 
      u32 keysize,                /* Key size in bits. */ 
      u32 ivsize)                 /* IV size in bits. */
    { 
      u32 i;  
    
      ctx->keysize = keysize >> 3;
      ctx->ivsize = ivsize >> 3;
    
      for (i = 0; i < 8; i++) ctx->key[i] = 0;
      for (i = 0; (i < ctx->keysize) & (i < 32); i++) {
            ctx->key[i >> 2] =  ctx->key[i >> 2] | key[i];
            ctx->key[i >> 2] = ROTL32(ctx->key[i >> 2],8);
      }
    
    } /* initialize the key, save the iv size*/
    
    u32 generate(ECRYPT_ctx* ctx) /*one step of the cipher*/
    {
            u32 i,i3, i10, i12, i1023;
            u32 output;
    
            i   = ctx->counter2048 & 0x3ff;
            i3  = (i - 3) & 0x3ff;
            i10 = (i - 10) & 0x3ff;
            i12 = (i - 12) & 0x3ff;
            i1023 = (i - 1023) & 0x3ff;
    
            if (ctx->counter2048 < 1024) {
                ctx->P[i] = ctx->P[i] + ctx->P[i10] + (ROTR32(ctx->P[i3],10)^ROTR32(ctx->P[i1023],23))+ctx->Q[(ctx->P[i3]^ctx->P[i1023])&0x3ff];
                output = h1(ctx,ctx->P[i12]) ^ ctx->P[i];
            }
            else {                                   
                ctx->Q[i] = ctx->Q[i] + ctx->Q[i10] + (ROTR32(ctx->Q[i3],10)^ROTR32(ctx->Q[i1023],23))+ctx->P[(ctx->Q[i3]^ctx->Q[i1023])&0x3ff];
                output = h2(ctx, ctx->Q[i12]) ^ ctx->Q[i];
            }
            ctx->counter2048 = (ctx->counter2048+1) & 0x7ff;
            return (output);
    }
    
    u32 h2(ECRYPT_ctx* ctx, u32 u) {
        u32 tem;            
        unsigned char a,b,c,d;          
        a = (unsigned char) ((u));      
        b = (unsigned char) ((u) >> 8); 
        c = (unsigned char) ((u) >> 16);    
        d = (unsigned char) ((u) >> 24);    
        tem = ctx->P[a]+ctx->P[256+b]+ctx->P[512+c]+ctx->P[768+d];
        return (tem);
    }
    
    
    u32 h1(ECRYPT_ctx* ctx, u32 u) {
        u32 tem;            
        unsigned char a,b,c,d;          
        a = (unsigned char) ((u));      
        b = (unsigned char) ((u) >> 8); 
        c = (unsigned char) ((u) >> 16);    
        d = (unsigned char) ((u) >> 24);    
        tem = ctx->Q[a]+ctx->Q[256+b]+ctx->Q[512+c]+ctx->Q[768+d];
        return (tem);
    }
    
    
    
    #ifdef ECRYPT_USES_DEFAULT_ALL_IN_ONE
    
    /*
    * Default implementation of all-in-one encryption/decryption of
    * (short) packets.
    */
    
    #ifdef ECRYPT_HAS_SINGLE_PACKET_FUNCTION
    
    void ECRYPT_process_packet(
      int action,
      ECRYPT_ctx* ctx,
      const u8* iv,
      const u8* input,
      u8* output,
      u32 msglen)
    {
      ECRYPT_ivsetup(ctx, iv);
    
    #ifdef ECRYPT_HAS_SINGLE_BYTE_FUNCTION
      ECRYPT_process_bytes(action, ctx, input, output, msglen);
    #else
      if (action == 0)
    ECRYPT_encrypt_bytes(ctx, input, output, msglen);
      else
    ECRYPT_decrypt_bytes(ctx, input, output, msglen);
    #endif
    }
    
    #else
    
    void ECRYPT_encrypt_packet(
      ECRYPT_ctx* ctx,
      const u8* iv,
      const u8* plaintext,
      u8* ciphertext,
      u32 msglen)
    {
      ECRYPT_ivsetup(ctx, iv);
      ECRYPT_encrypt_bytes(ctx, plaintext, ciphertext, msglen);
    }
    
    void ECRYPT_decrypt_packet(
      ECRYPT_ctx* ctx,
      const u8* iv,
      const u8* ciphertext,
      u8* plaintext,
      u32 msglen)
    {
      ECRYPT_ivsetup(ctx, iv);
      ECRYPT_decrypt_bytes(ctx, ciphertext, plaintext, msglen);
    }
    
    #endif
    
    #endif
    

    And inside "ecrypt-sync.h":

    /* ecrypt-sync.h */
    
    /* 
    * Header file for synchronous stream ciphers without authentication
    * mechanism.
    * 
    * *** Please only edit parts marked with "[edit]". ***
    */
    
    #include "ecrypt-portable.h"
    
    #ifndef ECRYPT_SYNC
    #define ECRYPT_SYNC
    
    /* ------------------------------------------------------------------------- */
    
    /* Cipher parameters */
    
    /* 
    * The name of your cipher.
    */
    #define ECRYPT_NAME "ECRYPT Stream Cipher HC-256"    /* [edit] */ 
    
    /*
    * Specify which key and IV sizes are supported by your cipher. A user
    * should be able to enumerate the supported sizes by running the
    * following code:
    *
    * for (i = 0; ECRYPT_KEYSIZE(i) <= ECRYPT_MAXKEYSIZE; ++i)
    *   {
    *     keysize = ECRYPT_KEYSIZE(i);
    *
    *     ...
    *   }
    *
    * All sizes are in bits.
    */
    
    #define ECRYPT_MAXKEYSIZE 256                 /* [edit] */
    #define ECRYPT_KEYSIZE(i) (128 + (i)*32)      /* [edit] */
    
    #define ECRYPT_MAXIVSIZE 256                  /* [edit] */
    #define ECRYPT_IVSIZE(i) (64 + (i)*64)        /* [edit] */
    
    /* ------------------------------------------------------------------------- */
    
    /* Data structures */
    
    /* 
    * ECRYPT_ctx is the structure containing the representation of the
    * internal state of your cipher. 
    */
    
    typedef struct
    {
      /* 
      * [edit]
      *
      * Put here all state variable needed during the encryption process.
      */
      u32 P[1024];
      u32 Q[1024];
      u32 counter2048;
      u32 key[8];
      u32 iv[8];
      u32 keysize;   /* key size in bytes */
      u32 ivsize;    /* iv size in bytes  */ 
    } ECRYPT_ctx;
    
    /* ------------------------------------------------------------------------- */
    
    /* Mandatory functions */
    
    /*
    * Key and message independent initialization. This function will be
    * called once when the program starts (e.g., to build expanded S-box
    * tables).
    */
    void ECRYPT_init(void);
    
    /*
    * Key setup. It is the user's responsibility to select the values of
    * keysize and ivsize from the set of supported values specified
    * above.
    */
    void ECRYPT_keysetup(
      ECRYPT_ctx* ctx, 
      const u8* key, 
      u32 keysize,                /* Key size in bits. */ 
      u32 ivsize);                /* IV size in bits. */ 
    
    /*
    * IV setup. After having called ECRYPT_keysetup(), the user is
    * allowed to call ECRYPT_ivsetup() different times in order to
    * encrypt/decrypt different messages with the same key but different
    * IV's.
    */
    void ECRYPT_ivsetup(
      ECRYPT_ctx* ctx, 
      const u8* iv);
    
    /*
    * Encryption/decryption of arbitrary length messages.
    *
    * For efficiency reasons, the API provides two types of
    * encrypt/decrypt functions. The ECRYPT_encrypt_bytes() function
    * (declared here) encrypts byte strings of arbitrary length, while
    * the ECRYPT_encrypt_blocks() function (defined later) only accepts
    * lengths which are multiples of ECRYPT_BLOCKLENGTH.
    * 
    * The user is allowed to make multiple calls to
    * ECRYPT_encrypt_blocks() to incrementally encrypt a long message,
    * but he is NOT allowed to make additional encryption calls once he
    * has called ECRYPT_encrypt_bytes() (unless he starts a new message
    * of course). For example, this sequence of calls is acceptable:
    *
    * ECRYPT_keysetup();
    *
    * ECRYPT_ivsetup();
    * ECRYPT_encrypt_blocks();
    * ECRYPT_encrypt_blocks();
    * ECRYPT_encrypt_bytes();
    *
    * ECRYPT_ivsetup();
    * ECRYPT_encrypt_blocks();
    * ECRYPT_encrypt_blocks();
    *
    * ECRYPT_ivsetup();
    * ECRYPT_encrypt_bytes();
    * 
    * The following sequence is not:
    *
    * ECRYPT_keysetup();
    * ECRYPT_ivsetup();
    * ECRYPT_encrypt_blocks();
    * ECRYPT_encrypt_bytes();
    * ECRYPT_encrypt_blocks();
    */
    
    /*
    * By default ECRYPT_encrypt_bytes() and ECRYPT_decrypt_bytes() are
    * defined as macros which redirect the call to a single function
    * ECRYPT_process_bytes(). If you want to provide separate encryption
    * and decryption functions, please undef
    * ECRYPT_HAS_SINGLE_BYTE_FUNCTION.
    */
    #define ECRYPT_HAS_SINGLE_BYTE_FUNCTION  1  /* [edit] */
    #ifdef ECRYPT_HAS_SINGLE_BYTE_FUNCTION
    
    #define ECRYPT_encrypt_bytes(ctx, plaintext, ciphertext, msglen)   \
      ECRYPT_process_bytes(0, ctx, plaintext, ciphertext, msglen)
    
    #define ECRYPT_decrypt_bytes(ctx, ciphertext, plaintext, msglen)   \
      ECRYPT_process_bytes(1, ctx, ciphertext, plaintext, msglen)
    
    void ECRYPT_process_bytes(
      int action,                 /* 0 = encrypt; 1 = decrypt; */
      ECRYPT_ctx* ctx, 
      const u8* input, 
      u8* output, 
      u32 msglen);                /* Message length in bytes. */ 
    
    #else
    
    void ECRYPT_encrypt_bytes(
      ECRYPT_ctx* ctx, 
      const u8* plaintext, 
      u8* ciphertext, 
      u32 msglen);                /* Message length in bytes. */ 
    
    void ECRYPT_decrypt_bytes(
      ECRYPT_ctx* ctx, 
      const u8* ciphertext, 
      u8* plaintext, 
      u32 msglen);                /* Message length in bytes. */ 
    
    #endif
    
    /* ------------------------------------------------------------------------- */
    
    /* Optional features */
    
    /* 
    * For testing purposes it can sometimes be useful to have a function
    * which immediately generates keystream without having to provide it
    * with a zero plaintext. If your cipher cannot provide this function
    * (e.g., because it is not strictly a synchronous cipher), please
    * reset the ECRYPT_GENERATES_KEYSTREAM flag.
    */
    
    #define ECRYPT_GENERATES_KEYSTREAM
    #ifdef ECRYPT_GENERATES_KEYSTREAM
    
    void ECRYPT_keystream_bytes(
      ECRYPT_ctx* ctx,
      u8* keystream,
      u32 length);                /* Length of keystream in bytes. */
    
    #endif
    
    /* ------------------------------------------------------------------------- */
    
    /* Optional optimizations */
    
    /* 
    * By default, the functions in this section are implemented using
    * calls to functions declared above. However, you might want to
    * implement them differently for performance reasons.
    */
    
    /*
    * All-in-one encryption/decryption of (short) packets.
    *
    * The default definitions of these functions can be found in
    * "ecrypt-sync.c". If you want to implement them differently, please
    * undef the ECRYPT_USES_DEFAULT_ALL_IN_ONE flag.
    */
    #define ECRYPT_USES_DEFAULT_ALL_IN_ONE        /* [edit] */
    
    /*
    * Undef ECRYPT_HAS_SINGLE_PACKET_FUNCTION if you want to provide
    * separate packet encryption and decryption functions.
    */
    #define ECRYPT_HAS_SINGLE_PACKET_FUNCTION     /* [edit] */
    #ifdef ECRYPT_HAS_SINGLE_PACKET_FUNCTION
    
    #define ECRYPT_encrypt_packet(                                        \
    ctx, iv, plaintext, ciphertext, mglen)                            \
      ECRYPT_process_packet(0,                                            \
    ctx, iv, plaintext, ciphertext, mglen)
    
    #define ECRYPT_decrypt_packet(                                        \
    ctx, iv, ciphertext, plaintext, mglen)                            \
      ECRYPT_process_packet(1,                                            \
    ctx, iv, ciphertext, plaintext, mglen)
    
    void ECRYPT_process_packet(
      int action,                 /* 0 = encrypt; 1 = decrypt; */
      ECRYPT_ctx* ctx, 
      const u8* iv,
      const u8* input, 
      u8* output, 
      u32 msglen);
    
    #else
    
    void ECRYPT_encrypt_packet(
      ECRYPT_ctx* ctx, 
      const u8* iv,
      const u8* plaintext, 
      u8* ciphertext, 
      u32 msglen);
    
    void ECRYPT_decrypt_packet(
      ECRYPT_ctx* ctx, 
      const u8* iv,
      const u8* ciphertext, 
      u8* plaintext, 
      u32 msglen);
    
    #endif
    
    /*
    * Encryption/decryption of blocks.
    * 
    * By default, these functions are defined as macros. If you want to
    * provide a different implementation, please undef the
    * ECRYPT_USES_DEFAULT_BLOCK_MACROS flag and implement the functions
    * declared below.
    */
    
    #define ECRYPT_BLOCKLENGTH 4                  /* [edit] */
    
    #define ECRYPT_USES_DEFAULT_BLOCK_MACROS      /* [edit] */
    #ifdef ECRYPT_USES_DEFAULT_BLOCK_MACROS
    
    #define ECRYPT_encrypt_blocks(ctx, plaintext, ciphertext, blocks)  \
      ECRYPT_encrypt_bytes(ctx, plaintext, ciphertext,                 \
    (blocks) * ECRYPT_BLOCKLENGTH)
    
    #define ECRYPT_decrypt_blocks(ctx, ciphertext, plaintext, blocks)  \
      ECRYPT_decrypt_bytes(ctx, ciphertext, plaintext,                 \
    (blocks) * ECRYPT_BLOCKLENGTH)
    
    #ifdef ECRYPT_GENERATES_KEYSTREAM
    
    #define ECRYPT_keystream_blocks(ctx, keystream, blocks)            \
      ECRYPT_keystream_bytes(ctx, keystream,                           \
    (blocks) * ECRYPT_BLOCKLENGTH)
    
    #endif
    
    #else
    
    /*
    * Undef ECRYPT_HAS_SINGLE_BLOCK_FUNCTION if you want to provide
    * separate block encryption and decryption functions.
    */
    #define ECRYPT_HAS_SINGLE_BLOCK_FUNCTION      /* [edit] */
    #ifdef ECRYPT_HAS_SINGLE_BLOCK_FUNCTION
    
    #define ECRYPT_encrypt_blocks(ctx, plaintext, ciphertext, blocks)     \
      ECRYPT_process_blocks(0, ctx, plaintext, ciphertext, blocks)
    
    #define ECRYPT_decrypt_blocks(ctx, ciphertext, plaintext, blocks)     \
      ECRYPT_process_blocks(1, ctx, ciphertext, plaintext, blocks)
    
    void ECRYPT_process_blocks(
      int action,                 /* 0 = encrypt; 1 = decrypt; */
      ECRYPT_ctx* ctx, 
      const u8* input, 
      u8* output, 
      u32 blocks);                /* Message length in blocks. */
    
    #else
    
    void ECRYPT_encrypt_blocks(
      ECRYPT_ctx* ctx, 
      const u8* plaintext, 
      u8* ciphertext, 
      u32 blocks);                /* Message length in blocks. */ 
    
    void ECRYPT_decrypt_blocks(
      ECRYPT_ctx* ctx, 
      const u8* ciphertext, 
      u8* plaintext, 
      u32 blocks);                /* Message length in blocks. */ 
    
    #endif
    
    #ifdef ECRYPT_GENERATES_KEYSTREAM
    
    void ECRYPT_keystream_blocks(
      ECRYPT_ctx* ctx,
      u8* keystream,
      u32 blocks);                /* Keystream length in blocks. */ 
    
    #endif
    
    #endif
    
    /*
    * If your cipher can be implemented in different ways, you can use
    * the ECRYPT_VARIANT parameter to allow the user to choose between
    * them at compile time (e.g., gcc -DECRYPT_VARIANT=3 ...). Please
    * only use this possibility if you really think it could make a
    * significant difference and keep the number of variants
    * (ECRYPT_MAXVARIANT) as small as possible (definitely not more than
    * 10). Note also that all variants should have exactly the same
    * external interface (i.e., the same ECRYPT_BLOCKLENGTH, etc.). 
    */
    #define ECRYPT_MAXVARIANT 1                   /* [edit] */
    
    #ifndef ECRYPT_VARIANT
    #define ECRYPT_VARIANT 1
    #endif
    
    #if (ECRYPT_VARIANT > ECRYPT_MAXVARIANT)
    #error this variant does not exist
    #endif
    
    /* ------------------------------------------------------------------------- */
    
    #endif
    
    
    /* ===========================================================================
    
            Added functions:    HC-256 Mandatory functions 
    
    ============================================================================== */
    
    #define f1(x)    (ROTR32((x),7) ^ ROTR32((x),18) ^ ((x) >> 3))
    #define f2(x)    (ROTR32((x),17) ^ ROTR32((x),19) ^ ((x) >> 10))
    
    /*
    
    
    
    
    void ECRYPT_keysetup(
      ECRYPT_ctx* ctx, 
      const u8* key, 
      u32 keysize,                // Key size in bits. 
      u32 ivsize);                // IV size in bits. 
    
    void ECRYPT_ivsetup(
      ECRYPT_ctx* ctx, 
      const u8* iv);
    
    void ECRYPT_process_bytes(
      int action,                 // 0 = encrypt; 1 = decrypt; 
      ECRYPT_ctx* ctx, 
      const u8* input, 
      u8* output, 
      u32 msglen);                // Message length in bytes. 
    
    */
    
    void ECRYPT_init(void);
    u32 h1(ECRYPT_ctx* ctx, u32 u);
    u32 h2(ECRYPT_ctx* ctx, u32 u);
    u32 generate(ECRYPT_ctx* ctx);
    

    Then use "ecrypt-machine.h", "ecrypt-config.h", and "ecrypt-portable.h" from here: http://www.ecrypt.eu.org/stream/p3ciphers/hc/hc256_p3source.zip

    Here is a quick application to test it. You will have to create the "generateRandom" function, or just make up some random bytes lol.

    #include "crypto.hpp"
    
    int main(int argc, char **argv){
      CRYPTOSOCKET *socket;
      unsigned char key[32];
      unsigned char iv[32];
      unsigned char buf1[1024];
      unsigned char buf2[1024];
      unsigned char buf3[1024];
      char *teststring = "This is a test.\n";
    
      // Generate a random key
      generateRandom(key, 32);
    
      // Generate a random IV
      generateRandom(iv, 32);
    
      // Create a new cryptosocket with that key and iv.
      socket = new CRYPTOSOCKET(0, key, iv);
    
      // Copy teststring into buffer 1
      sprintf((char*)buf1,teststring);
    
      // Encrypt buffer 1 and placed the encrypted contents into buffer 2.
      socket->encrypt(buf1,strlen(teststring), buf2);
    
      // Decrypt buffer 2 into buffer 3.
      socket->decrypt(buf2, strlen(teststring), buf3);
    
      // Print out whats in buffer 3.
      printf((char*)buf3);
    
    }