hash.c 2.36 KB
Newer Older
lwc-tester 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 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116
/* Reference Implementation of ACE-Hash256
 Written by:
 Kalikinkar Mandal <kmandal@uwaterloo.ca>
 */

#include<stdio.h>
#include<math.h>
#include<stdlib.h>
#include<stdint.h>

#include "ace.h"
#include "crypto_hash.h" 
#include "api.h" 

#define KAT_SUCCESS          0
#define KAT_FILE_OPEN_ERROR -1
#define KAT_DATA_ERROR      -3
#define KAT_CRYPTO_FAILURE  -4

const unsigned char rate_bytes[8] = {0,1,2,3,16,17,18,19};

int acehash_init( unsigned char *state )
{
	unsigned char i;

	//Initialize the state to all-ZERO 
	for ( i = 0; i < STATEBYTES; i++ )
		state[i] = 0x0;
	if ( CRYPTO_BYTES == 32 )
	{
		//Initialize state with IV 0x804040
                //According to specification: B[7] = 0x80; B[6] = 0x40; B[5] = 0x40;
		state[8] = 0x80;
		state[9] = 0x40;
		state[10] = 0x40;
		ace_permutation(state);
	}
	else
	{
		return KAT_CRYPTO_FAILURE;
	}
return KAT_SUCCESS;
}

int crypto_hash(
	unsigned char *out,
	const unsigned char *in,
	unsigned long long inlen
	)
{
	unsigned char *state;
	unsigned char i, lblen;
	//int func_ret;
	u64 j, in64len;

	in64len = inlen/8;
	lblen = (unsigned char)(inlen%8);

	state = (unsigned char *)malloc(sizeof(unsigned char)*STATEBYTES);

	//Initialize state with predefined IV.
	if ( acehash_init(state)!= KAT_SUCCESS )
		return(KAT_CRYPTO_FAILURE);

	//Absorbing phase: Rate Bytes A[0],A[1],A[2],A[3],C[0],C[1],C[2],C[3]
	if ( inlen != 0 )
	{

		for ( j = 0; j < in64len; j++ )
		{
			for ( i = 0; i < 8; i++ )
				state[rate_bytes[i]]^=in[8*j+((u64)i)];
			ace_permutation(state);
		}

		if ( lblen != 0 )
		{
			//Encrypting the padded 64-bit block when "mlen" is not a multiple of 8
			for ( i = 0; i < lblen; i++ )
				state[rate_bytes[i]]^= in[in64len*8+(u64)i];
			
			state[rate_bytes[lblen]]^=(0x80); //Padding: 10*
			ace_permutation(state);
		}
		else
		{
			state[rate_bytes[0]]^=(0x80); //Padding: 10*
			ace_permutation(state);
		}
	}
	else
	{
		state[rate_bytes[0]]^=(0x80); //Padding: 10*
		ace_permutation(state);
	}
	//Squeezing phase
	if ( CRYPTO_BYTES == 32 )
	{
		for ( i = 0; i < 8; i++ )
			out[i] = state[rate_bytes[i]];
		ace_permutation(state);
		for ( i = 0; i < 8; i++ )
			out[i+8] = state[rate_bytes[i]];
		ace_permutation(state);
		for ( i = 0; i < 8; i++ )
			out[i+16] = state[rate_bytes[i]];
		ace_permutation(state);
		for ( i = 0; i < 8; i++ )
			out[i+24] = state[rate_bytes[i]];
	}
	else
		out=NULL;
free(state);

return KAT_SUCCESS;
}