18c2ecf20Sopenharmony_ci
28c2ecf20Sopenharmony_ci/*
38c2ecf20Sopenharmony_ci * Keyed 32-bit hash function using TEA in a Davis-Meyer function
48c2ecf20Sopenharmony_ci *   H0 = Key
58c2ecf20Sopenharmony_ci *   Hi = E Mi(Hi-1) + Hi-1
68c2ecf20Sopenharmony_ci *
78c2ecf20Sopenharmony_ci * (see Applied Cryptography, 2nd edition, p448).
88c2ecf20Sopenharmony_ci *
98c2ecf20Sopenharmony_ci * Jeremy Fitzhardinge <jeremy@zip.com.au> 1998
108c2ecf20Sopenharmony_ci *
118c2ecf20Sopenharmony_ci * Jeremy has agreed to the contents of reiserfs/README. -Hans
128c2ecf20Sopenharmony_ci * Yura's function is added (04/07/2000)
138c2ecf20Sopenharmony_ci */
148c2ecf20Sopenharmony_ci
158c2ecf20Sopenharmony_ci#include <linux/kernel.h>
168c2ecf20Sopenharmony_ci#include "reiserfs.h"
178c2ecf20Sopenharmony_ci#include <asm/types.h>
188c2ecf20Sopenharmony_ci
198c2ecf20Sopenharmony_ci#define DELTA 0x9E3779B9
208c2ecf20Sopenharmony_ci#define FULLROUNDS 10		/* 32 is overkill, 16 is strong crypto */
218c2ecf20Sopenharmony_ci#define PARTROUNDS 6		/* 6 gets complete mixing */
228c2ecf20Sopenharmony_ci
238c2ecf20Sopenharmony_ci/* a, b, c, d - data; h0, h1 - accumulated hash */
248c2ecf20Sopenharmony_ci#define TEACORE(rounds)							\
258c2ecf20Sopenharmony_ci	do {								\
268c2ecf20Sopenharmony_ci		u32 sum = 0;						\
278c2ecf20Sopenharmony_ci		int n = rounds;						\
288c2ecf20Sopenharmony_ci		u32 b0, b1;						\
298c2ecf20Sopenharmony_ci									\
308c2ecf20Sopenharmony_ci		b0 = h0;						\
318c2ecf20Sopenharmony_ci		b1 = h1;						\
328c2ecf20Sopenharmony_ci									\
338c2ecf20Sopenharmony_ci		do							\
348c2ecf20Sopenharmony_ci		{							\
358c2ecf20Sopenharmony_ci			sum += DELTA;					\
368c2ecf20Sopenharmony_ci			b0 += ((b1 << 4)+a) ^ (b1+sum) ^ ((b1 >> 5)+b);	\
378c2ecf20Sopenharmony_ci			b1 += ((b0 << 4)+c) ^ (b0+sum) ^ ((b0 >> 5)+d);	\
388c2ecf20Sopenharmony_ci		} while(--n);						\
398c2ecf20Sopenharmony_ci									\
408c2ecf20Sopenharmony_ci		h0 += b0;						\
418c2ecf20Sopenharmony_ci		h1 += b1;						\
428c2ecf20Sopenharmony_ci	} while(0)
438c2ecf20Sopenharmony_ci
448c2ecf20Sopenharmony_ciu32 keyed_hash(const signed char *msg, int len)
458c2ecf20Sopenharmony_ci{
468c2ecf20Sopenharmony_ci	u32 k[] = { 0x9464a485, 0x542e1a94, 0x3e846bff, 0xb75bcfc3 };
478c2ecf20Sopenharmony_ci
488c2ecf20Sopenharmony_ci	u32 h0 = k[0], h1 = k[1];
498c2ecf20Sopenharmony_ci	u32 a, b, c, d;
508c2ecf20Sopenharmony_ci	u32 pad;
518c2ecf20Sopenharmony_ci	int i;
528c2ecf20Sopenharmony_ci
538c2ecf20Sopenharmony_ci	/*      assert(len >= 0 && len < 256); */
548c2ecf20Sopenharmony_ci
558c2ecf20Sopenharmony_ci	pad = (u32) len | ((u32) len << 8);
568c2ecf20Sopenharmony_ci	pad |= pad << 16;
578c2ecf20Sopenharmony_ci
588c2ecf20Sopenharmony_ci	while (len >= 16) {
598c2ecf20Sopenharmony_ci		a = (u32) msg[0] |
608c2ecf20Sopenharmony_ci		    (u32) msg[1] << 8 | (u32) msg[2] << 16 | (u32) msg[3] << 24;
618c2ecf20Sopenharmony_ci		b = (u32) msg[4] |
628c2ecf20Sopenharmony_ci		    (u32) msg[5] << 8 | (u32) msg[6] << 16 | (u32) msg[7] << 24;
638c2ecf20Sopenharmony_ci		c = (u32) msg[8] |
648c2ecf20Sopenharmony_ci		    (u32) msg[9] << 8 |
658c2ecf20Sopenharmony_ci		    (u32) msg[10] << 16 | (u32) msg[11] << 24;
668c2ecf20Sopenharmony_ci		d = (u32) msg[12] |
678c2ecf20Sopenharmony_ci		    (u32) msg[13] << 8 |
688c2ecf20Sopenharmony_ci		    (u32) msg[14] << 16 | (u32) msg[15] << 24;
698c2ecf20Sopenharmony_ci
708c2ecf20Sopenharmony_ci		TEACORE(PARTROUNDS);
718c2ecf20Sopenharmony_ci
728c2ecf20Sopenharmony_ci		len -= 16;
738c2ecf20Sopenharmony_ci		msg += 16;
748c2ecf20Sopenharmony_ci	}
758c2ecf20Sopenharmony_ci
768c2ecf20Sopenharmony_ci	if (len >= 12) {
778c2ecf20Sopenharmony_ci		a = (u32) msg[0] |
788c2ecf20Sopenharmony_ci		    (u32) msg[1] << 8 | (u32) msg[2] << 16 | (u32) msg[3] << 24;
798c2ecf20Sopenharmony_ci		b = (u32) msg[4] |
808c2ecf20Sopenharmony_ci		    (u32) msg[5] << 8 | (u32) msg[6] << 16 | (u32) msg[7] << 24;
818c2ecf20Sopenharmony_ci		c = (u32) msg[8] |
828c2ecf20Sopenharmony_ci		    (u32) msg[9] << 8 |
838c2ecf20Sopenharmony_ci		    (u32) msg[10] << 16 | (u32) msg[11] << 24;
848c2ecf20Sopenharmony_ci
858c2ecf20Sopenharmony_ci		d = pad;
868c2ecf20Sopenharmony_ci		for (i = 12; i < len; i++) {
878c2ecf20Sopenharmony_ci			d <<= 8;
888c2ecf20Sopenharmony_ci			d |= msg[i];
898c2ecf20Sopenharmony_ci		}
908c2ecf20Sopenharmony_ci	} else if (len >= 8) {
918c2ecf20Sopenharmony_ci		a = (u32) msg[0] |
928c2ecf20Sopenharmony_ci		    (u32) msg[1] << 8 | (u32) msg[2] << 16 | (u32) msg[3] << 24;
938c2ecf20Sopenharmony_ci		b = (u32) msg[4] |
948c2ecf20Sopenharmony_ci		    (u32) msg[5] << 8 | (u32) msg[6] << 16 | (u32) msg[7] << 24;
958c2ecf20Sopenharmony_ci
968c2ecf20Sopenharmony_ci		c = d = pad;
978c2ecf20Sopenharmony_ci		for (i = 8; i < len; i++) {
988c2ecf20Sopenharmony_ci			c <<= 8;
998c2ecf20Sopenharmony_ci			c |= msg[i];
1008c2ecf20Sopenharmony_ci		}
1018c2ecf20Sopenharmony_ci	} else if (len >= 4) {
1028c2ecf20Sopenharmony_ci		a = (u32) msg[0] |
1038c2ecf20Sopenharmony_ci		    (u32) msg[1] << 8 | (u32) msg[2] << 16 | (u32) msg[3] << 24;
1048c2ecf20Sopenharmony_ci
1058c2ecf20Sopenharmony_ci		b = c = d = pad;
1068c2ecf20Sopenharmony_ci		for (i = 4; i < len; i++) {
1078c2ecf20Sopenharmony_ci			b <<= 8;
1088c2ecf20Sopenharmony_ci			b |= msg[i];
1098c2ecf20Sopenharmony_ci		}
1108c2ecf20Sopenharmony_ci	} else {
1118c2ecf20Sopenharmony_ci		a = b = c = d = pad;
1128c2ecf20Sopenharmony_ci		for (i = 0; i < len; i++) {
1138c2ecf20Sopenharmony_ci			a <<= 8;
1148c2ecf20Sopenharmony_ci			a |= msg[i];
1158c2ecf20Sopenharmony_ci		}
1168c2ecf20Sopenharmony_ci	}
1178c2ecf20Sopenharmony_ci
1188c2ecf20Sopenharmony_ci	TEACORE(FULLROUNDS);
1198c2ecf20Sopenharmony_ci
1208c2ecf20Sopenharmony_ci/*	return 0;*/
1218c2ecf20Sopenharmony_ci	return h0 ^ h1;
1228c2ecf20Sopenharmony_ci}
1238c2ecf20Sopenharmony_ci
1248c2ecf20Sopenharmony_ci/*
1258c2ecf20Sopenharmony_ci * What follows in this file is copyright 2000 by Hans Reiser, and the
1268c2ecf20Sopenharmony_ci * licensing of what follows is governed by reiserfs/README
1278c2ecf20Sopenharmony_ci */
1288c2ecf20Sopenharmony_ciu32 yura_hash(const signed char *msg, int len)
1298c2ecf20Sopenharmony_ci{
1308c2ecf20Sopenharmony_ci	int j, pow;
1318c2ecf20Sopenharmony_ci	u32 a, c;
1328c2ecf20Sopenharmony_ci	int i;
1338c2ecf20Sopenharmony_ci
1348c2ecf20Sopenharmony_ci	for (pow = 1, i = 1; i < len; i++)
1358c2ecf20Sopenharmony_ci		pow = pow * 10;
1368c2ecf20Sopenharmony_ci
1378c2ecf20Sopenharmony_ci	if (len == 1)
1388c2ecf20Sopenharmony_ci		a = msg[0] - 48;
1398c2ecf20Sopenharmony_ci	else
1408c2ecf20Sopenharmony_ci		a = (msg[0] - 48) * pow;
1418c2ecf20Sopenharmony_ci
1428c2ecf20Sopenharmony_ci	for (i = 1; i < len; i++) {
1438c2ecf20Sopenharmony_ci		c = msg[i] - 48;
1448c2ecf20Sopenharmony_ci		for (pow = 1, j = i; j < len - 1; j++)
1458c2ecf20Sopenharmony_ci			pow = pow * 10;
1468c2ecf20Sopenharmony_ci		a = a + c * pow;
1478c2ecf20Sopenharmony_ci	}
1488c2ecf20Sopenharmony_ci
1498c2ecf20Sopenharmony_ci	for (; i < 40; i++) {
1508c2ecf20Sopenharmony_ci		c = '0' - 48;
1518c2ecf20Sopenharmony_ci		for (pow = 1, j = i; j < len - 1; j++)
1528c2ecf20Sopenharmony_ci			pow = pow * 10;
1538c2ecf20Sopenharmony_ci		a = a + c * pow;
1548c2ecf20Sopenharmony_ci	}
1558c2ecf20Sopenharmony_ci
1568c2ecf20Sopenharmony_ci	for (; i < 256; i++) {
1578c2ecf20Sopenharmony_ci		c = i;
1588c2ecf20Sopenharmony_ci		for (pow = 1, j = i; j < len - 1; j++)
1598c2ecf20Sopenharmony_ci			pow = pow * 10;
1608c2ecf20Sopenharmony_ci		a = a + c * pow;
1618c2ecf20Sopenharmony_ci	}
1628c2ecf20Sopenharmony_ci
1638c2ecf20Sopenharmony_ci	a = a << 7;
1648c2ecf20Sopenharmony_ci	return a;
1658c2ecf20Sopenharmony_ci}
1668c2ecf20Sopenharmony_ci
1678c2ecf20Sopenharmony_ciu32 r5_hash(const signed char *msg, int len)
1688c2ecf20Sopenharmony_ci{
1698c2ecf20Sopenharmony_ci	u32 a = 0;
1708c2ecf20Sopenharmony_ci	while (*msg) {
1718c2ecf20Sopenharmony_ci		a += *msg << 4;
1728c2ecf20Sopenharmony_ci		a += *msg >> 4;
1738c2ecf20Sopenharmony_ci		a *= 11;
1748c2ecf20Sopenharmony_ci		msg++;
1758c2ecf20Sopenharmony_ci	}
1768c2ecf20Sopenharmony_ci	return a;
1778c2ecf20Sopenharmony_ci}
178