int crypto_hash( unsigned char *out, const unsigned char *in, unsigned long long inlen )
{
    tKeccakLane    state[5 * 5];
#if (crypto_hash_BYTES >= cKeccakR_SizeInBytes)
    #define temp out
#else
    unsigned char temp[cKeccakR_SizeInBytes];
#endif

    memset( state, 0, sizeof(state) );

    for ( /* empty */; inlen >= cKeccakR_SizeInBytes; inlen -= cKeccakR_SizeInBytes, in += cKeccakR_SizeInBytes )
    {
        KeccakF( state, (const tKeccakLane*)in, cKeccakR_SizeInBytes / sizeof(tKeccakLane) );
    }

    //    padding
    memcpy( temp, in, (size_t)inlen );
    temp[inlen++] = 1;
    memset( temp+inlen, 0, cKeccakR_SizeInBytes - (size_t)inlen );
    temp[cKeccakR_SizeInBytes-1] |= 0x80;
    KeccakF( state, (const tKeccakLane*)temp, cKeccakR_SizeInBytes / sizeof(tKeccakLane) );
    memcpy( out, state, crypto_hash_BYTES );
    #if (crypto_hash_BYTES >= cKeccakR_SizeInBytes)
    #undef temp
    #endif

    return ( 0 );
}
Beispiel #2
0
int crypto_hash( unsigned char *out, const unsigned char *in, unsigned long long inlen )
{
#if 1

	tSmallUInt			i;
	tSmallUInt			len;
	unsigned char * pState;
  tKeccakLane			state[5 * 5];

  memset( state, 0, sizeof(state) );

	/*	Full blocks	*/
  for ( /* empty */; inlen >= cKeccakR_SizeInBytes; inlen -= cKeccakR_SizeInBytes )
  {
		in = xorLanes( state, in, cKeccakR_SizeInBytes / 8 );
    KeccakF( state );
  }

  /*	Last uncomplete block */
	len = (tSmallUInt)inlen;
	xorBytes( state, in, len );

	pState = (unsigned char*)state + len; 

  /*	Padding	*/
	for ( i = 0; i < 4; /* empty */ )
	{
    *(pState++) ^= pgm_read_byte(&KeccakPadding[i++]);
    if ( ++len == cKeccakR_SizeInBytes )
    {
        KeccakF( state );
        pState = (unsigned char*)state;
        len = 0;
    }
	}

  if ( len != 0 )
  {
    KeccakF( state );
  }

  memcpy( out, state, crypto_hash_BYTES );

	return ( 0 );

#else

	hashState state;

	Init( &state );
	Update( &state, in, inlen * 8 );
	return (Final( &state, out, crypto_hash_BYTES ) );

#endif

}
Beispiel #3
0
HashReturn Update(hashState *state, const BitSequence *data, DataLength databitlen)
{
	tSmallUInt	trailingBits;
	tSmallUInt	len;
	
	if ( (state->bytesInQueue == 0xFF) || (state->trailingBitsInQueue != 0) )
	{
		/*	 Final() already called or bits already in queue not modulo 8.	*/
		return ( FAIL );
	}

	trailingBits = (unsigned char)databitlen & 7;
	databitlen >>= 3;	/*	becomes byte length	*/
	
	/*	If already data in queue, continue queuing first */
	if ( (state->bytesInQueue != 0) && (databitlen != 0) )
	{
		len = cKeccakR_SizeInBytes - state->bytesInQueue;
		if ( databitlen < len )
		{
			len = (unsigned char)databitlen;
		}
		data = xorBytes( state->state + state->bytesInQueue, data, len );
		databitlen -= len;
		if ( (state->bytesInQueue += len) == cKeccakR_SizeInBytes )
		{
			KeccakF( (tKeccakLane *)state->state );
			state->bytesInQueue = 0;
		}
	}

	/*	Absorb complete blocks */
	for ( /* */; databitlen >= cKeccakR_SizeInBytes; databitlen -= cKeccakR_SizeInBytes )
	{
		data = xorLanes( state->state, data, cKeccakR_SizeInBytes / 8 );
		KeccakF( (tKeccakLane *)state->state );
	}

	/*	Queue remaining data bytes */
	if ( (unsigned char)databitlen != 0 )
	{
		data = xorBytes( state->state, data, (unsigned char)databitlen );
		state->bytesInQueue = (unsigned char)databitlen;
	}

	/*	Queue eventual remaining data bits plus add first padding bit */
	if ( trailingBits != 0 )
	{
		state->trailingBitsInQueue = 1;
		state->state[state->bytesInQueue++] ^= (*data >> (8 - trailingBits)) | (1 << trailingBits);
	}
int crypto_hash( unsigned char *out, const unsigned char *in, unsigned long long inlen )
{
    tKeccakLane		state[5 * 5];
	#if (crypto_hash_BYTES >= cKeccakR_SizeInBytes)
    #define temp out
	#else
    unsigned char 	temp[cKeccakR_SizeInBytes];
	#endif

    memset( state, 0, sizeof(state) );

    for ( /* empty */; inlen >= cKeccakR_SizeInBytes; inlen -= cKeccakR_SizeInBytes, in += cKeccakR_SizeInBytes )
    {
        KeccakF( state, (const tKeccakLane*)in, cKeccakR_SizeInBytes / sizeof(tKeccakLane) );
    }

    /*    Last data and padding	*/
    memcpy( temp, in, (size_t)inlen );
    temp[inlen++] = 1;
    memset( temp+inlen, 0, cKeccakR_SizeInBytes - (size_t)inlen );
    temp[cKeccakR_SizeInBytes-1] |= 0x80;
    KeccakF( state, (const tKeccakLane*)temp, cKeccakR_SizeInBytes / sizeof(tKeccakLane) );

    #if (PLATFORM_BYTE_ORDER == IS_LITTLE_ENDIAN) || (cKeccakB == 200)

    memcpy( out, state, crypto_hash_BYTES );

	#else

    for ( i = 0; i < (crypto_hash_BYTES / sizeof(tKeccakLane)); ++i )
	{
		tSmallUInt		j;
	    tKeccakLane		t;

		t = state[i];
		for ( j = 0; j < sizeof(tKeccakLane); ++j )
		{
			*(out++) = (unsigned char)t;
			t >>= 8;
		}
	}

	#endif
	#if (crypto_hash_BYTES >= cKeccakR_SizeInBytes)
    #undef temp
	#endif

    return ( 0 );
}
HashReturn Update(hashState *state, const BitSequence *data, DataLength databitlen)
{
	
	if ( (state->bitsInQueue < 0) || ((state->bitsInQueue % 8) != 0) )
	{
		/*	 Final() already called or bits already in queue not modulo 8.	*/
		return ( FAIL );
	}

	/*	If already data in queue, continue queuing first */
	for ( /* empty */; (databitlen >= 8) && (state->bitsInQueue != 0); databitlen -= 8 )
	{
		state->state[state->bitsInQueue / 8] ^= *(data++);
		if ( (state->bitsInQueue += 8) == cKeccakR )
		{
			KeccakF( (tKeccakLane *)state->state, 0, 0 );
			state->bitsInQueue = 0;
		}
	}

	/*	Absorb complete blocks */
	for ( /* */; databitlen >= cKeccakR; databitlen -= cKeccakR, data += cKeccakR_SizeInBytes )
	{
		KeccakF( (tKeccakLane *)state->state, (const tKeccakLane *)data, cKeccakR_SizeInBytes / sizeof(tKeccakLane) );
	}

	/*	Queue remaining data bytes */
	for ( /* empty */; databitlen >=8; databitlen -= 8, state->bitsInQueue += 8 )
	{
		state->state[state->bitsInQueue / 8] ^= *(data++);
	}
	/*	Queue eventual remaining data bits plus add first padding bit */
	if ( databitlen != 0 )
	{
		state->state[state->bitsInQueue / 8] ^= (*data >> (8 - databitlen));
		state->bitsInQueue += (int)databitlen;
	}
// DO NOT MODIFY THE HEADING OF THIS FUNCTION
unsigned char* Hash(unsigned char* message, unsigned int length)
 {
        //Initialization and padding
        // Step 1 S[x,y] = 0

        unsigned long** S = malloc(5 * sizeof(unsigned long));  //defining the state array S
        int x;
        for (x = 0; x < 5; x++) 
	{
                S[x] = malloc(5 * sizeof(unsigned long));       // Allocating the required memory for  S array
        }

        //Here I am initializing  and assignning  the Value 0 to the state array S
        S[0][0] = 0;
        S[1][0] = 0;
        S[2][0] = 0;
        S[3][0] = 0;
        S[4][0] = 0;

        S[0][1] = 0;
        S[1][1] = 0;
        S[2][1] = 0;
        S[3][1] = 0;
        S[4][1] = 0;

        S[0][2] = 0;
        S[1][2] = 0;
	 S[2][2] = 0;
        S[3][2] = 0;
        S[4][2] = 0;

        S[0][3] = 0;
        S[1][3] = 0;
        S[2][3] = 0;
        S[3][3] = 0;
        S[4][3] = 0;

        S[0][4] = 0;
        S[1][4] = 0;
        S[2][4] = 0;
        S[3][4] = 0;
        S[4][4] = 0;

/* ------------------------------------------------------------------------------------------------------------------- */

        //P = M || 0x01 || 0x00 || … || 0x00

	//P = P xor (0x00 || … || 0x00 || 0x80)

        unsigned int how_many_blocks, padding_length, padding_byte;     //Declaring the variables used.

        how_many_blocks = (length / 128) + 1;  // calculating how many blocks are required for the padding length

        padding_length = how_many_blocks;

        padding_byte = 128 - (length % 128); // Calculating how many Bytes of _Padding is required

        unsigned char* padded_msg = malloc(length + padding_byte);

        memcpy(padded_msg, message, 251);       //Copying the message to an array called padded_msg which will be padded in later stages

        //If there is just one byte to be padded then the  last byte will be padded as 0x81
        if (padding_byte == 1)
	 {
                memcpy(padded_msg + length, "\x81", 1);
         } 
	else 
	{
                memcpy(padded_msg + length, "\x01", 1);         //In other cases, first byte to be padded is  0x01

		int i, pbpl;
                pbpl = (padding_byte + length) - 1;
                for (i = length + 1; i < pbpl; i++) {
                        memcpy(padded_msg + i, "\x00", 1);      //All the other bytes untill last byte will be padded as 0x00
                }
                memcpy(padded_msg + i, "\x80", 1);              //Last byte will padded as 0x80
        }

/*--------------------------------------  Making the P-Blocks of length 128 bytes-------------------------------------------------*/


        // Here the padded _msg will be divided into different blocks of 128 bytes each

        int k = 0;

        unsigned long** P = malloc(padding_length * sizeof(unsigned long));     //Defining the array P
        for (x = 0; x < padding_length; x++)
         {
                P[x] = malloc(16 * sizeof(unsigned long));                      //Allocating required memory to P
 	 }
        for (int i = 0; i < padding_length; i++) 
        {
                for (int j = 0; j < 16; j++,k+=8) 
                {
                        unsigned char* temp_array = malloc(sizeof(unsigned long)); //a temporary arry for copying
                        memcpy(temp_array, padded_msg + k, 8);                    //Copying the padded_msg byte by byte
                        memcpy(&P[i][j], temp_array, 8);                          // In very time temp_array is copied to array P
                }
        }

/* --------------------------------------------------------------------------------------------------------------------------------*/

        // Absorbing phase
        //  forall block Pi in P
        //    S[x,y] = S[x,y] xor Pi[x+5*y],          forall (x,y) such that x+5*y < r/w
        //    S = Keccak-f[r+c](S)

        for (int m = 0; m < padding_length; m++) 
	{
	 for (int x = 0; x < 5; x++)
		       {
                        for (int y = 0; y < 5; y++) {
                                if ((x + (5 * y)) < (R/w)) // Defined R =1024 and w = 64  globally
                                {
                                        S[x][y] ^= P[m][x + (5 * y)];
                                }
                        }
                }
          S = KeccakF(S);        //In each iteration the function state array S is fed to KeaackF from 1st assignment and 
                                 //not to  KeccakF_bytes function
        }


/* -----------------------------------------------   Squeezing phase ------- ----------------------------------------------------*/


        /* Z = Z || S[x,y] */
// Here the  array Z  is concatenated with S from previous step.
        unsigned char* Z = malloc(R / 8);
	int c = 0;
        for (int a = 0; a < 5; a++) 
	   {
                for (int b = 0; b < 5; b++, c+=8)
                 {
                        if (c < (R / 8)) 
                        {
                                memcpy(Z + c, &S[b][a], 8);
                        }
                 }
           }
  return Z;
 }
int main(){
  unsigned long** INPUT=malloc(5*sizeof(unsigned long));
  int x;
  for(x=0;x<5;x++){
    INPUT[x]=malloc(5*sizeof(unsigned long));
  }
  INPUT[0][0]=0;
  INPUT[1][0]=0;
  INPUT[2][0]=0;
  INPUT[3][0]=0;
  INPUT[4][0]=0;

  INPUT[0][1]=0;
  INPUT[1][1]=0;
  INPUT[2][1]=0;
  INPUT[3][1]=0;
  INPUT[4][1]=0;

  INPUT[0][2]=0;
  INPUT[1][2]=0;
  INPUT[2][2]=0;
  INPUT[3][2]=0;
  INPUT[4][2]=0;

  INPUT[0][3]=0;
  INPUT[1][3]=0;
  INPUT[2][3]=0;
  INPUT[3][3]=0;
  INPUT[4][3]=0;

  INPUT[0][4]=0;
  INPUT[1][4]=0;
  INPUT[2][4]=0;
  INPUT[3][4]=0;
  INPUT[4][4]=0;

  unsigned long** OUTPUT_REF=malloc(5*sizeof(unsigned long));
  for(x=0;x<5;x++){
    OUTPUT_REF[x]=malloc(5*sizeof(unsigned long));
  }

  OUTPUT_REF[0][0]=0xF1258F7940E1DDE7;
  OUTPUT_REF[1][0]=0x84D5CCF933C0478A;
  OUTPUT_REF[2][0]=0xD598261EA65AA9EE;
  OUTPUT_REF[3][0]=0xBD1547306F80494D;
  OUTPUT_REF[4][0]=0x8B284E056253D057;

  OUTPUT_REF[0][1]=0xFF97A42D7F8E6FD4;
  OUTPUT_REF[1][1]=0x90FEE5A0A44647C4;
  OUTPUT_REF[2][1]=0x8C5BDA0CD6192E76;
  OUTPUT_REF[3][1]=0xAD30A6F71B19059C;
  OUTPUT_REF[4][1]=0x30935AB7D08FFC64;
 
  OUTPUT_REF[0][2]=0xEB5AA93F2317D635;
  OUTPUT_REF[1][2]=0xA9A6E6260D712103;
  OUTPUT_REF[2][2]=0x81A57C16DBCF555F;
  OUTPUT_REF[3][2]=0x43B831CD0347C826; 
  OUTPUT_REF[4][2]=0x01F22F1A11A5569F;

  OUTPUT_REF[0][3]=0x05E5635A21D9AE61;
  OUTPUT_REF[1][3]=0x64BEFEF28CC970F2;
  OUTPUT_REF[2][3]=0x613670957BC46611;
  OUTPUT_REF[3][3]=0xB87C5A554FD00ECB;
  OUTPUT_REF[4][3]=0x8C3EE88A1CCF32C8;

  OUTPUT_REF[0][4]=0x940C7922AE3A2614;
  OUTPUT_REF[1][4]=0x1841F924A2C509E4;
  OUTPUT_REF[2][4]=0x16F53526E70465C2;
  OUTPUT_REF[3][4]=0x75F644E97F30A13B;
  OUTPUT_REF[4][4]=0xEAF1FF7B5CECA249;
  
  unsigned long** OUTPUT=KeccakF(INPUT);


  //check 
  int y;
  int count=1;
  for(x=0;x<5;x++){
    for(y=0;y<5;y++){
      if(OUTPUT[x][y]!=OUTPUT_REF[x][y]){
	count=0;
      }
    }
  }
  if(count==0){
    printf("FAIL\n");
  }
  else{
    printf("PASS\n");
  }

  for(x=0;x<5;x++){
    free(INPUT[x]);
    free(OUTPUT[x]);
    free(OUTPUT_REF[x]);
  }
   free(INPUT);
   free(OUTPUT);
   free(OUTPUT_REF);

 
  return 0;
}