hash.c 1.63 KB
Newer Older
Enrico Pozzobon committed
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74
#include "crypto_hash.h"

#include "beetle.h"
#include "photon.h"

/* Declaration of basic internal functions */
static uint8_t selectConst(
	const bool condition,
	const uint8_t option1,
	const uint8_t option2);

inline static void XOR_const(
	uint8_t *State_inout,
	const uint8_t  Constant);

/* Definition of basic internal functions */
static uint8_t selectConst(
	const bool condition,
	const uint8_t option1,
	const uint8_t option2)
{
	if (condition) return option1;
	return option2;
}

static void XOR_const(
	uint8_t *State_inout,
	const uint8_t  Constant)
{
	State_inout[STATE_INBYTES - 1] ^= (Constant << LAST_THREE_BITS_OFFSET);
}

int crypto_hash(
	unsigned char *out,
	const unsigned char *in,
	unsigned long long inlen
)
{
	/*
	...
	... the code for the hash function implementation goes here
	... generating a hash value out[0],out[1],...,out[CRYPTO_BYTES-1]
	... from a message in[0],in[1],...,in[in-1] 
	...
	... return 0;
	*/
	uint8_t State[STATE_INBYTES] = { 0 };

	uint8_t c0;

	if (inlen == 0)
	{
		XOR_const(State, 1);
	}
	else if (inlen <= HASH_INITIAL_RATE_INBYTES)
	{
		c0 = selectConst((inlen < HASH_INITIAL_RATE_INBYTES), 1, 2);
		memcpy(State, in, inlen);
		if (inlen < HASH_INITIAL_RATE_INBYTES) State[inlen] ^= 0x01; // ozs
		XOR_const(State, c0);
	}
	else
	{
		memcpy(State, in, HASH_INITIAL_RATE_INBYTES);
		inlen -= HASH_INITIAL_RATE_INBYTES;
		c0 = selectConst((inlen % HASH_RATE_INBYTES) == 0, 1, 2);
		HASH(State, in + HASH_INITIAL_RATE_INBYTES, inlen, c0, HASH_RATE_INBYTES);
	}
	TAG(out, State);
	out += SQUEEZE_RATE_INBYTES;
	TAG(out, State);

	return 0;
}