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