Return Styles: Pseud0ch, Terminal, Valhalla, NES, Geocities, Blue Moon. Entire thread

Amateur Cryptography Time

Name: Anonymous 2009-04-24 11:40

Hey /prog/, here's something I started a few months ago, and just found and improved upon some more recently. It's a hash function based an the XTEA block cipher. It's faster than MD5, though I can't attest to its security. I'm particularly concerned that short messages may be insecure, since it only uses four rounds (two cycles) of XTEA.

xtash.c

/*******************************************************************************
 * xtash.c -- a hash function based on XTEA.                                   *
 * Copyright (c) 2009, Samuel Fredrickson <kinghajj@gmail.com>;                 *
 * All rights reserved.                                                        *
 *                                                                             *
 * Redistribution and use in source and binary forms, with or without          *
 * modification, are permitted provided that the following conditions are met: *
 *     * Redistributions of source code must retain the above copyright        *
 *       notice, this list of conditions and the following disclaimer.         *
 *     * Redistributions in binary form must reproduce the above copyright     *
 *       notice, this list of conditions and the following disclaimer in the   *
 *       documentation and/or other materials provided with the distribution.  *
 *                                                                             *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER ``AS IS'' AND ANY EXPRESS *
 * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED           *
 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE      *
 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY        *
 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES  *
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR          *
 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER  *
 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT          *
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY   *
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH *
 * DAMAGE.                                                                     *
 ******************************************************************************/

/*******************************************************************************
 * XTASH is a Merkle-Damgard construction hash function that uses XTEA as a    *
 * one-way compression function using the Davies-Meyer method. To speed things *
 * up, only two XTEA cycles are performed per compression, which probably      *
 * doesn't help with its security.                                             *
 *                                                                             *
 * Simple tests appear to show a good avalanche effect, but I don't reccommend *
 * anyone use this for anything serious, as I'm an amateur cryptographer.      *
 *                                                                             *
 * I've tested this on both big- and little-endian machines, and both provide  *
 * the same results. This code may run faster on a big-endian machine, because *
 * there's less swapping. However, since I'm using ntohl and htonl, swapping   *
 * should be faster on processors with a byteswap instruction.                 *
 *                                                                             *
 * Because XTEA operates on 64-bit blocks with a 128-bit key, the compression  *
 * function enciphers both halves of the previous state with the input message *
 * block.                                                                      *
 ******************************************************************************/

#include <netinet/in.h>
#include <stdlib.h>
#include <string.h>
#include "xtash.h"

/* Converts an array of 4 bytes into a 32-bit integer. */
static inline uint32_t UInt8s_To_UInt32(uint8_t in[4])
{
    return ntohl(*(uint32_t*)in);
}

/* Converts a 32-bit integer into an array of 4 bytes. */
static inline void UInt32_To_UInt8s(uint32_t in, uint8_t out[4])
{
    *(uint32_t*)out = htonl(in);
}

/* The XTEA encryption function. */
static inline void encipher(uint32_t v[2], uint32_t k[4])
{
    const static uint32_t XTEA_CYCLES = 2;
    uint32_t v0=v[0], v1=v[1], i;
    uint32_t sum = 0, delta = 0x9e3779b9;

    for(i = 0; i < XTEA_CYCLES; ++i) {
        v0 += (((v1 << 4) ^ (v1 >> 5)) + v1) ^ (sum + k[sum & 3]);
        sum += delta;
        v1 += (((v0 << 4) ^ (v0 >> 5)) + v0) ^ (sum + k[(sum >> 11) & 3]);
    }

    v[0] = v0, v[1] = v1;
}

/* The XTASH compression function. */
static inline void compress(uint32_t a[4], uint32_t b[4])
{
    // just a simple compression function, but it seems to work decently.
    encipher(a, b);
    encipher(&a[2], b);
}

/* Converts the data to uint32_t, then calls compress(). */
static inline void compress_data(XTASH_State *state, uint8_t *data)
{
    uint32_t b[4];

    // construct a uint32_t block from the data.
    b[0] = UInt8s_To_UInt32(data);
    b[1] = UInt8s_To_UInt32(data + 4);
    b[2] = UInt8s_To_UInt32(data + 8);
    b[3] = UInt8s_To_UInt32(data + 12);
    // compress it.
    compress(state->state, b);
}

/* Initializes a hash state with the IV. */
void XTASH_Init (XTASH_State *state)
{
    // this is the md5 sum of "XTASH\n". probably not the best IV.
    const static uint32_t iv[4] =
        { 0x6a39cda1, 0x62a1c9dd, 0xf41a42cc, 0x28a638f4 };

    memcpy(state->state, iv, XTASH_DIGEST_SIZE);
    state->length   = 0;
    state->leftover = 0;
}

/* Updates the hash state with new data. */
void XTASH_Update(XTASH_State *state, uint8_t *data, uint64_t len)
{
    if(!len) return;

    state->length += len;

    // if there are leftovers,
    if(state->leftover) {
        // fill the rest of the leftover block as much as possible.
        while(len && state->leftover < XTASH_DIGEST_SIZE)
            state->data[state->leftover++] = *data++, len--;
        // if we're full of leftovers, use them and move on.
        if(state->leftover == XTASH_DIGEST_SIZE)
            compress_data(state, state->data), state->leftover = 0;
    }

    // while we have enough for one block,
    while(len >= XTASH_DIGEST_SIZE) {
        compress_data(state, data);
        len  -= XTASH_DIGEST_SIZE;
        data += XTASH_DIGEST_SIZE;
    }

    // if there are leftovers, save them.
    if(len) memcpy(state->data, data, (state->leftover = (uint8_t)len));
}

/* Finalizes a hash state into a digest. */
void XTASH_Final(XTASH_State *state, uint8_t *sum)
{
    uint32_t block[4];
    uint8_t fluff[XTASH_DIGEST_SIZE];

    // flush any leftovers.
    if(state->leftover) {
        memset(fluff, 0, XTASH_DIGEST_SIZE);
        XTASH_Update(state, fluff, XTASH_DIGEST_SIZE - state->leftover);
    }

    // create a block with the message length and compress it.
    block[0] = state->length & (~UINT32_MAX);
    block[1] = state->length & UINT32_MAX;
    block[2] = block[3] = 0;
    compress(state->state, block);

    // put state into the sum array.
    UInt32_To_UInt8s(state->state[0], sum);
    UInt32_To_UInt8s(state->state[1], sum + 4);
    UInt32_To_UInt8s(state->state[2], sum + 8);
    UInt32_To_UInt8s(state->state[3], sum + 12);
}

/* Streams data from a file and calculates the digest. */
void XTASH_Stream(FILE *f, uint8_t *digest)
{
    const size_t buffer_size = 4096;
    uint8_t buffer[buffer_size];
    XTASH_State state;
    size_t read;

    XTASH_Init(&state);

    while((read = fread(buffer, 1, buffer_size, f)))
        XTASH_Update(&state, buffer, read);

    XTASH_Final(&state, digest);
}

#ifdef XTASH_MAIN

int main()
{
    uint8_t digest[XTASH_DIGEST_SIZE];
    int i;

    XTASH_Stream(stdin, digest);

    for(i = 0; i < XTASH_DIGEST_SIZE; i++)
        printf("%02x", digest[i]);
    fputc('\n', stdout);

    return 0;
}

#endif

Name: Anonymous 2009-04-24 13:17

>>7
Post it then, faggot.

Newer Posts
Don't change these.
Name: Email:
Entire Thread Thread List