hash.c 2.93 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 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136
#include <string.h>
#include <stdio.h>
#include "api.h"
#include "crypto_hash.h"

#define constB1  0xb7e151628aeull
#define constB2  0x243f6a8885aull

#define LengthA  80
#define LengthB  88
#define LengthC  88
#define NLa  73
#define NLb  65
#define NLc  77
#define FBa  74
#define FBb  66
#define FBc  84
#define FFa  68
#define FFb  64
#define FFc  68
#define INb  85
#define INc  85

#define P_ROUNDS  1024


void Stateupdate(unsigned char *FSR1, unsigned char *FSR2, unsigned char *FSR3, unsigned char exbit)
{
	unsigned char p = 0, q = 0, r = 0;
	int i;

	p = (FSR1[NLa - 1] & FSR1[LengthA - 1 - 1]) ^ FSR1[LengthA - 1] ^ FSR1[FFa - 1] ^ FSR2[FBb - 1] ^ (FSR2[INb - 1] & FSR3[INc - 1]);
	q = (FSR2[NLb - 1] & FSR2[LengthB - 1 - 1]) ^ FSR2[LengthB - 1] ^ FSR2[FFb - 1] ^ FSR3[FBc - 1];
	r = (FSR3[NLc - 1] & FSR3[LengthC - 1 - 1]) ^ FSR3[LengthC - 1] ^ FSR3[FFc - 1] ^ FSR1[FBa - 1];

	for (i = LengthA - 1; i >= 1; i--)
    FSR1[i] = FSR1[i - 1];
	FSR1[0] = (r ^ exbit);

	for (i = LengthB - 1; i >= 1; i--)
    FSR2[i] = FSR2[i - 1];
	FSR2[0] = (p ^ exbit);

	for (i = LengthC - 1; i >= 1; i--)
    FSR3[i] = FSR3[i - 1];
	FSR3[0] = (q ^ exbit);


}

void Squeeze_digest(unsigned char *out, unsigned char *FSR)
{
	unsigned char i;
	unsigned char statebit = 0;

	for (i = 0; i < 8; i++)
	{
		statebit = FSR[i];
		*out |= (statebit << (7 - i % 8));
	}
}



int crypto_hash(
	unsigned char *out, 
	const unsigned char *in, 
	unsigned long long inlen
	)
{
	unsigned char FSR1[LengthA], FSR2[LengthB], FSR3[LengthC];
	unsigned char c1[44], c2[44];
	unsigned char pad[4] = { 0, 0, 0, 0 };
	unsigned long long i,j;

	memset(FSR1, 0x00, LengthA);
	memset(FSR2, 0x00, LengthB);
	memset(FSR3, 0x00, LengthC);

	memset(c1, 0x00, 44);
	memset(c2, 0x00, 44);

	memset(out, 0x00, 32);
	

	for (i = 0; i < 44; i++)
    c1[i] = (constB1 >> (43 - i)) & 0x1;
	for (i = 0; i < 44; i++)
    c2[i] = (constB2 >> (43 - i)) & 0x1;

	memcpy(FSR2, c1, 44);
	memcpy(FSR2 + 44, c2, 44);

	
	for (i = 0; i < (inlen) / 4; i++){
		for (j = 0; j < 32; j++){
			FSR1[j] = FSR1[j] ^ ((in[3 - (j / 8) + (i * 4)] >> (7 - (j % 8))) & 0x1U);
		}
		for (j = 0; j < P_ROUNDS; j++)
      Stateupdate(FSR1, FSR2, FSR3, 0);
	}



	for (i = 0; i < (inlen % 4); i++)
		pad[i] = in[inlen - (inlen % 4) + i];
	

	pad[i] = 0x80U;
	for (j = 0; j < 32; j++){
		FSR1[j] = FSR1[j] ^ ((pad[3 - (j / 8)] >> (7 - (j % 8))) & 0x1U);
	}
	for (j = 0; j < P_ROUNDS; j++)
    Stateupdate(FSR1, FSR2, FSR3, 0);

	
	for (i = 0; i < 6; i++)
    Squeeze_digest(out + i, FSR2 + 40 - 8 * i);
	for (i = 0; i < 10; i++)
    Squeeze_digest(out + 6 + i, FSR1 + 72 - 8 * i);
		

	for (j = 0; j < P_ROUNDS; j++)
    Stateupdate(FSR1, FSR2, FSR3, 0);

	for (i = 0; i < 6; i++)
    Squeeze_digest(out + 16 + i, FSR2 + 40 - 8 * i);
	for (i = 0; i < 10; i++)
    Squeeze_digest(out + 16 + 6 + i, FSR1 + 72 - 8 * i);


	return 0;
}