hash.c 4.3 KB
Newer Older
lwc-tester committed
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
#include"api.h"
typedef unsigned char u8;
typedef unsigned long long u64;
typedef long long i64;
typedef long long i64;
typedef unsigned int u32;

#define sbox(a, b, c, d, e, f, g, h)                                                                            \
{                                                                                                                             \
	t1 = ~a; t2 = b & t1;t3 = c ^ t2; h = d ^ t3; t5 = b | c; t6 = d ^ t1; g = t5 ^ t6; t8 = b ^ d; t9 = t3 & t6; e = t8 ^ t9; t11 = g & t8; f = t3 ^ t11; \
}

#define ARR_SIZE(a) (sizeof((a))/sizeof((a[0])))

#define LOTR1281(a,b,n) (((a)<<(n))|((b)>>(64-n)))
#define LOTR1282(a,b,n) (((b)<<(n))|((a)>>(64-n)))

lwc-tester committed
18
u8 constant8[255] = { 0x01, 0x02, 0x04, 0x08, 0x11, 0x23, 0x47, 0x8e, 0x1c,
lwc-tester committed
19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41
		0x38, 0x71, 0xe2, 0xc4, 0x89, 0x12, 0x25, 0x4b, 0x97, 0x2e, 0x5c, 0xb8,
		0x70, 0xe0, 0xc0, 0x81, 0x03, 0x06, 0x0c, 0x19, 0x32, 0x64, 0xc9, 0x92,
		0x24, 0x49, 0x93, 0x26, 0x4d, 0x9b, 0x37, 0x6e, 0xdc, 0xb9, 0x72, 0xe4,
		0xc8, 0x90, 0x20, 0x41, 0x82, 0x05, 0x0a, 0x15, 0x2b, 0x56, 0xad, 0x5b,
		0xb6, 0x6d, 0xda, 0xb5, 0x6b, 0xd6, 0xac, 0x59, 0xb2, 0x65, 0xcb, 0x96,
		0x2c, 0x58, 0xb0, 0x61, 0xc3, 0x87, 0x0f, 0x1f, 0x3e, 0x7d, 0xfb, 0xf6,
		0xed, 0xdb, 0xb7, 0x6f, 0xde, 0xbd, 0x7a, 0xf5, 0xeb, 0xd7, 0xae, 0x5d,
		0xba, 0x74, 0xe8, 0xd1, 0xa2, 0x44, 0x88, 0x10, 0x21, 0x43, 0x86, 0x0d,
		0x1b, 0x36, 0x6c, 0xd8, 0xb1, 0x63, 0xc7, 0x8f, 0x1e, 0x3c, 0x79, 0xf3,
		0xe7, 0xce, 0x9c, 0x39, 0x73, 0xe6, 0xcc, 0x98, 0x31, 0x62, 0xc5, 0x8b,
		0x16, 0x2d, 0x5a, 0xb4, 0x69, 0xd2, 0xa4, 0x48, 0x91, 0x22, 0x45, 0x8a,
		0x14, 0x29, 0x52, 0xa5, 0x4a, 0x95, 0x2a, 0x54, 0xa9, 0x53, 0xa7, 0x4e,
		0x9d, 0x3b, 0x77, 0xee, 0xdd, 0xbb, 0x76, 0xec, 0xd9, 0xb3, 0x67, 0xcf,
		0x9e, 0x3d, 0x7b, 0xf7, 0xef, 0xdf, 0xbf, 0x7e, 0xfd, 0xfa, 0xf4, 0xe9,
		0xd3, 0xa6, 0x4c, 0x99, 0x33, 0x66, 0xcd, 0x9a, 0x35, 0x6a, 0xd4, 0xa8,
		0x51, 0xa3, 0x46, 0x8c, 0x18, 0x30, 0x60, 0xc1, 0x83, 0x07, 0x0e, 0x1d,
		0x3a, 0x75, 0xea, 0xd5, 0xaa, 0x55, 0xab, 0x57, 0xaf, 0x5f, 0xbe, 0x7c,
		0xf9, 0xf2, 0xe5, 0xca, 0x94, 0x28, 0x50, 0xa1, 0x42, 0x84, 0x09, 0x13,
		0x27, 0x4f, 0x9f, 0x3f, 0x7f, 0xff, 0xfe, 0xfc, 0xf8, 0xf0, 0xe1, 0xc2,
		0x85, 0x0b, 0x17, 0x2f, 0x5e, 0xbc, 0x78, 0xf1, 0xe3, 0xc6, 0x8d, 0x1a,
		0x34, 0x68, 0xd0, 0xa0, 0x40, 0x80 };

void load64(u64* x, u8* S) {
lwc-tester committed
42
	int i;
lwc-tester committed
43 44
	*x = 0;
	for (i = 0; i < 8; ++i)
lwc-tester committed
45
		*x |= ((u64)S[i]) << i * 8;
lwc-tester committed
46 47 48
}

void store64(u8* S, u64 x) {
lwc-tester committed
49
	int i;
lwc-tester committed
50
	for (i = 0; i < 8; ++i)
lwc-tester committed
51
		S[i] = (u8)(x >> i * 8);
lwc-tester committed
52 53 54 55
}
void permutation512(u8* S, int rounds, u8 *c) {
	int i;
	u64 x00 = 0, x10 = 0, x20 = 0, x30 = 0, x40, x50, x60, x70, x01 = 0,
lwc-tester committed
56
		x11 = 0, x21 = 0, x31 = 0, x41, x51, x61, x71;
lwc-tester committed
57 58

	u64 t1, t2, t3, t5, t6, t8, t9, t11;
lwc-tester committed
59 60 61 62 63 64 65 66
	load64(&x00, S);
	load64(&x01, S + 8);
	load64(&x10, S + 16);
	load64(&x11, S + 24);
	load64(&x20, S + 32);
	load64(&x21, S + 40);
	load64(&x30, S + 48);
	load64(&x31, S + 56);
lwc-tester committed
67 68
	for (i = 0; i < rounds; ++i) {
		// addition of round constant
lwc-tester committed
69 70
		x00 ^= c[i];

lwc-tester committed
71 72 73 74 75 76 77 78 79 80 81 82 83 84 85
		// substitution layer

		sbox(x00, x10, x20, x30, x40, x50, x60, x70);
		sbox(x01, x11, x21, x31, x41, x51, x61, x71);

		// linear diffusion layer
		x00 = x40;
		x01 = x41;
		x10 = LOTR1281(x50, x51, 1);
		x11 = LOTR1282(x50, x51, 1);
		x20 = LOTR1281(x60, x61, 16);
		x21 = LOTR1282(x60, x61, 16);
		x30 = LOTR1281(x70, x71, 25);
		x31 = LOTR1282(x70, x71, 25);

lwc-tester committed
86 87 88 89 90 91 92 93 94
	}
	store64(S + 0, x00);
	store64(S + 8, x01);
	store64(S + 16, x10);
	store64(S + 24, x11);
	store64(S + 32, x20);
	store64(S + 40, x21);
	store64(S + 48, x30);
	store64(S + 56, x31);
lwc-tester committed
95 96
}
int crypto_hash(unsigned char *out, const unsigned char *in,
lwc-tester committed
97
	unsigned long long inlen) {
lwc-tester committed
98 99 100
	int nrh = 140;
	u32 i, j;
	int b = 512, r1 = 64, r2 = 256;
lwc-tester committed
101
	u32 size = b / 8; // 64    
lwc-tester committed
102
	u32 rate1 = r1 / 8;  //8
lwc-tester committed
103
	u32 rate2 = r2 / 8;  //8 
lwc-tester committed
104 105 106 107 108 109 110
	u64 v = inlen / rate1 + 1;
	u32 u = CRYPTO_BYTES / rate2;  //32/16=2
	u8 M[v * rate1];
	u8 S[size];
	// pad in
	for (i = 0; i < inlen; ++i)
		M[i] = in[i];
lwc-tester committed
111
	M[inlen] = 0x01;
lwc-tester committed
112 113 114 115 116 117
	for (i = inlen + 1; i < v * rate1; ++i)
		M[i] = 0;
	// initialization
	for (i = 0; i < size; ++i)
		S[i] = 0;
	//absorb
lwc-tester committed
118
	for (i = 0; i < v; ++i) {
lwc-tester committed
119

lwc-tester committed
120 121 122
		for (j = 0; j < rate1; ++j)
			S[j] ^= M[i * rate1 + j];
		permutation512(S, nrh, constant8);
lwc-tester committed
123 124 125 126
	}
	//sequeez
	for (i = 0; i < u - 1; ++i) {
		for (j = 0; j < rate2; ++j) {
lwc-tester committed
127
			out[j + i * rate2] = S[j];
lwc-tester committed
128
		}
lwc-tester committed
129
		permutation512(S, nrh, constant8);
lwc-tester committed
130 131 132 133 134 135 136 137
	}
	for (j = 0; j < rate2; ++j) {
		out[j + i * rate2] = S[j];
	}

	return 0;
}