xref: /openbmc/linux/fs/reiserfs/hashes.c (revision e5451c8f8330e03ad3cfa16048b4daf961af434f)
11da177e4SLinus Torvalds 
21da177e4SLinus Torvalds /*
31da177e4SLinus Torvalds  * Keyed 32-bit hash function using TEA in a Davis-Meyer function
41da177e4SLinus Torvalds  *   H0 = Key
51da177e4SLinus Torvalds  *   Hi = E Mi(Hi-1) + Hi-1
61da177e4SLinus Torvalds  *
71da177e4SLinus Torvalds  * (see Applied Cryptography, 2nd edition, p448).
81da177e4SLinus Torvalds  *
91da177e4SLinus Torvalds  * Jeremy Fitzhardinge <jeremy@zip.com.au> 1998
101da177e4SLinus Torvalds  *
111da177e4SLinus Torvalds  * Jeremy has agreed to the contents of reiserfs/README. -Hans
121da177e4SLinus Torvalds  * Yura's function is added (04/07/2000)
131da177e4SLinus Torvalds  */
141da177e4SLinus Torvalds 
151da177e4SLinus Torvalds #include <linux/kernel.h>
16f466c6fdSAl Viro #include "reiserfs.h"
171da177e4SLinus Torvalds #include <asm/types.h>
181da177e4SLinus Torvalds 
191da177e4SLinus Torvalds #define DELTA 0x9E3779B9
201da177e4SLinus Torvalds #define FULLROUNDS 10		/* 32 is overkill, 16 is strong crypto */
211da177e4SLinus Torvalds #define PARTROUNDS 6		/* 6 gets complete mixing */
221da177e4SLinus Torvalds 
231da177e4SLinus Torvalds /* a, b, c, d - data; h0, h1 - accumulated hash */
241da177e4SLinus Torvalds #define TEACORE(rounds)							\
251da177e4SLinus Torvalds 	do {								\
261da177e4SLinus Torvalds 		u32 sum = 0;						\
271da177e4SLinus Torvalds 		int n = rounds;						\
281da177e4SLinus Torvalds 		u32 b0, b1;						\
291da177e4SLinus Torvalds 									\
301da177e4SLinus Torvalds 		b0 = h0;						\
311da177e4SLinus Torvalds 		b1 = h1;						\
321da177e4SLinus Torvalds 									\
331da177e4SLinus Torvalds 		do							\
341da177e4SLinus Torvalds 		{							\
351da177e4SLinus Torvalds 			sum += DELTA;					\
361da177e4SLinus Torvalds 			b0 += ((b1 << 4)+a) ^ (b1+sum) ^ ((b1 >> 5)+b);	\
371da177e4SLinus Torvalds 			b1 += ((b0 << 4)+c) ^ (b0+sum) ^ ((b0 >> 5)+d);	\
381da177e4SLinus Torvalds 		} while(--n);						\
391da177e4SLinus Torvalds 									\
401da177e4SLinus Torvalds 		h0 += b0;						\
411da177e4SLinus Torvalds 		h1 += b1;						\
421da177e4SLinus Torvalds 	} while(0)
431da177e4SLinus Torvalds 
keyed_hash(const signed char * msg,int len)441da177e4SLinus Torvalds u32 keyed_hash(const signed char *msg, int len)
451da177e4SLinus Torvalds {
461da177e4SLinus Torvalds 	u32 k[] = { 0x9464a485, 0x542e1a94, 0x3e846bff, 0xb75bcfc3 };
471da177e4SLinus Torvalds 
481da177e4SLinus Torvalds 	u32 h0 = k[0], h1 = k[1];
491da177e4SLinus Torvalds 	u32 a, b, c, d;
501da177e4SLinus Torvalds 	u32 pad;
511da177e4SLinus Torvalds 	int i;
521da177e4SLinus Torvalds 
53*098297b2SJeff Mahoney 	/*      assert(len >= 0 && len < 256); */
541da177e4SLinus Torvalds 
551da177e4SLinus Torvalds 	pad = (u32) len | ((u32) len << 8);
561da177e4SLinus Torvalds 	pad |= pad << 16;
571da177e4SLinus Torvalds 
58bd4c625cSLinus Torvalds 	while (len >= 16) {
591da177e4SLinus Torvalds 		a = (u32) msg[0] |
60bd4c625cSLinus Torvalds 		    (u32) msg[1] << 8 | (u32) msg[2] << 16 | (u32) msg[3] << 24;
611da177e4SLinus Torvalds 		b = (u32) msg[4] |
62bd4c625cSLinus Torvalds 		    (u32) msg[5] << 8 | (u32) msg[6] << 16 | (u32) msg[7] << 24;
631da177e4SLinus Torvalds 		c = (u32) msg[8] |
641da177e4SLinus Torvalds 		    (u32) msg[9] << 8 |
65bd4c625cSLinus Torvalds 		    (u32) msg[10] << 16 | (u32) msg[11] << 24;
661da177e4SLinus Torvalds 		d = (u32) msg[12] |
671da177e4SLinus Torvalds 		    (u32) msg[13] << 8 |
68bd4c625cSLinus Torvalds 		    (u32) msg[14] << 16 | (u32) msg[15] << 24;
691da177e4SLinus Torvalds 
701da177e4SLinus Torvalds 		TEACORE(PARTROUNDS);
711da177e4SLinus Torvalds 
721da177e4SLinus Torvalds 		len -= 16;
731da177e4SLinus Torvalds 		msg += 16;
741da177e4SLinus Torvalds 	}
751da177e4SLinus Torvalds 
76bd4c625cSLinus Torvalds 	if (len >= 12) {
771da177e4SLinus Torvalds 		a = (u32) msg[0] |
78bd4c625cSLinus Torvalds 		    (u32) msg[1] << 8 | (u32) msg[2] << 16 | (u32) msg[3] << 24;
791da177e4SLinus Torvalds 		b = (u32) msg[4] |
80bd4c625cSLinus Torvalds 		    (u32) msg[5] << 8 | (u32) msg[6] << 16 | (u32) msg[7] << 24;
811da177e4SLinus Torvalds 		c = (u32) msg[8] |
821da177e4SLinus Torvalds 		    (u32) msg[9] << 8 |
83bd4c625cSLinus Torvalds 		    (u32) msg[10] << 16 | (u32) msg[11] << 24;
841da177e4SLinus Torvalds 
851da177e4SLinus Torvalds 		d = pad;
86bd4c625cSLinus Torvalds 		for (i = 12; i < len; i++) {
871da177e4SLinus Torvalds 			d <<= 8;
881da177e4SLinus Torvalds 			d |= msg[i];
891da177e4SLinus Torvalds 		}
90bd4c625cSLinus Torvalds 	} else if (len >= 8) {
911da177e4SLinus Torvalds 		a = (u32) msg[0] |
92bd4c625cSLinus Torvalds 		    (u32) msg[1] << 8 | (u32) msg[2] << 16 | (u32) msg[3] << 24;
931da177e4SLinus Torvalds 		b = (u32) msg[4] |
94bd4c625cSLinus Torvalds 		    (u32) msg[5] << 8 | (u32) msg[6] << 16 | (u32) msg[7] << 24;
951da177e4SLinus Torvalds 
961da177e4SLinus Torvalds 		c = d = pad;
97bd4c625cSLinus Torvalds 		for (i = 8; i < len; i++) {
981da177e4SLinus Torvalds 			c <<= 8;
991da177e4SLinus Torvalds 			c |= msg[i];
1001da177e4SLinus Torvalds 		}
101bd4c625cSLinus Torvalds 	} else if (len >= 4) {
1021da177e4SLinus Torvalds 		a = (u32) msg[0] |
103bd4c625cSLinus Torvalds 		    (u32) msg[1] << 8 | (u32) msg[2] << 16 | (u32) msg[3] << 24;
1041da177e4SLinus Torvalds 
1051da177e4SLinus Torvalds 		b = c = d = pad;
106bd4c625cSLinus Torvalds 		for (i = 4; i < len; i++) {
1071da177e4SLinus Torvalds 			b <<= 8;
1081da177e4SLinus Torvalds 			b |= msg[i];
1091da177e4SLinus Torvalds 		}
110bd4c625cSLinus Torvalds 	} else {
1111da177e4SLinus Torvalds 		a = b = c = d = pad;
112bd4c625cSLinus Torvalds 		for (i = 0; i < len; i++) {
1131da177e4SLinus Torvalds 			a <<= 8;
1141da177e4SLinus Torvalds 			a |= msg[i];
1151da177e4SLinus Torvalds 		}
1161da177e4SLinus Torvalds 	}
1171da177e4SLinus Torvalds 
1181da177e4SLinus Torvalds 	TEACORE(FULLROUNDS);
1191da177e4SLinus Torvalds 
1201da177e4SLinus Torvalds /*	return 0;*/
1211da177e4SLinus Torvalds 	return h0 ^ h1;
1221da177e4SLinus Torvalds }
1231da177e4SLinus Torvalds 
124*098297b2SJeff Mahoney /*
125*098297b2SJeff Mahoney  * What follows in this file is copyright 2000 by Hans Reiser, and the
126*098297b2SJeff Mahoney  * licensing of what follows is governed by reiserfs/README
127*098297b2SJeff Mahoney  */
yura_hash(const signed char * msg,int len)1281da177e4SLinus Torvalds u32 yura_hash(const signed char *msg, int len)
1291da177e4SLinus Torvalds {
1301da177e4SLinus Torvalds 	int j, pow;
1311da177e4SLinus Torvalds 	u32 a, c;
1321da177e4SLinus Torvalds 	int i;
1331da177e4SLinus Torvalds 
134bd4c625cSLinus Torvalds 	for (pow = 1, i = 1; i < len; i++)
135bd4c625cSLinus Torvalds 		pow = pow * 10;
1361da177e4SLinus Torvalds 
1371da177e4SLinus Torvalds 	if (len == 1)
1381da177e4SLinus Torvalds 		a = msg[0] - 48;
1391da177e4SLinus Torvalds 	else
1401da177e4SLinus Torvalds 		a = (msg[0] - 48) * pow;
1411da177e4SLinus Torvalds 
1421da177e4SLinus Torvalds 	for (i = 1; i < len; i++) {
1431da177e4SLinus Torvalds 		c = msg[i] - 48;
144bd4c625cSLinus Torvalds 		for (pow = 1, j = i; j < len - 1; j++)
145bd4c625cSLinus Torvalds 			pow = pow * 10;
1461da177e4SLinus Torvalds 		a = a + c * pow;
1471da177e4SLinus Torvalds 	}
1481da177e4SLinus Torvalds 
1491da177e4SLinus Torvalds 	for (; i < 40; i++) {
1501da177e4SLinus Torvalds 		c = '0' - 48;
151bd4c625cSLinus Torvalds 		for (pow = 1, j = i; j < len - 1; j++)
152bd4c625cSLinus Torvalds 			pow = pow * 10;
1531da177e4SLinus Torvalds 		a = a + c * pow;
1541da177e4SLinus Torvalds 	}
1551da177e4SLinus Torvalds 
1561da177e4SLinus Torvalds 	for (; i < 256; i++) {
1571da177e4SLinus Torvalds 		c = i;
158bd4c625cSLinus Torvalds 		for (pow = 1, j = i; j < len - 1; j++)
159bd4c625cSLinus Torvalds 			pow = pow * 10;
1601da177e4SLinus Torvalds 		a = a + c * pow;
1611da177e4SLinus Torvalds 	}
1621da177e4SLinus Torvalds 
1631da177e4SLinus Torvalds 	a = a << 7;
1641da177e4SLinus Torvalds 	return a;
1651da177e4SLinus Torvalds }
1661da177e4SLinus Torvalds 
r5_hash(const signed char * msg,int len)1671da177e4SLinus Torvalds u32 r5_hash(const signed char *msg, int len)
1681da177e4SLinus Torvalds {
1691da177e4SLinus Torvalds 	u32 a = 0;
1701da177e4SLinus Torvalds 	while (*msg) {
1711da177e4SLinus Torvalds 		a += *msg << 4;
1721da177e4SLinus Torvalds 		a += *msg >> 4;
1731da177e4SLinus Torvalds 		a *= 11;
1741da177e4SLinus Torvalds 		msg++;
1751da177e4SLinus Torvalds 	}
1761da177e4SLinus Torvalds 	return a;
1771da177e4SLinus Torvalds }
178