1147476Sdumbbell/*-
2147476Sdumbbell * Copyright 2000 Hans Reiser
3147476Sdumbbell * See README for licensing and copyright details
4147476Sdumbbell *
5230132Suqs * Ported to FreeBSD by Jean-S��bastien P��dron <jspedron@club-internet.fr>
6147476Sdumbbell *
7147476Sdumbbell * $FreeBSD$
8147476Sdumbbell */
9147476Sdumbbell
10147476Sdumbbell#include <gnu/fs/reiserfs/reiserfs_fs.h>
11147476Sdumbbell
12147476Sdumbbell/*
13147476Sdumbbell * Keyed 32-bit hash function using TEA in a Davis-Meyer function
14147476Sdumbbell *   H0 = Key
15147476Sdumbbell *   Hi = E Mi(Hi-1) + Hi-1
16147476Sdumbbell *
17147476Sdumbbell * (see Applied Cryptography, 2nd edition, p448).
18147476Sdumbbell *
19147476Sdumbbell * Jeremy Fitzhardinge <jeremy@zip.com.au> 1998
20147476Sdumbbell *
21147476Sdumbbell * Jeremy has agreed to the contents of README. -Hans
22147476Sdumbbell * Yura's function is added (04/07/2000)
23147476Sdumbbell */
24147476Sdumbbell
25147476Sdumbbell/*
26147476Sdumbbell * keyed_hash
27147476Sdumbbell * yura_hash
28147476Sdumbbell * r5_hash
29147476Sdumbbell */
30147476Sdumbbell
31147476Sdumbbell#define	DELTA		0x9E3779B9
32147476Sdumbbell#define	FULLROUNDS	10  /* 32 is overkill, 16 is strong crypto */
33147476Sdumbbell#define	PARTROUNDS	6   /* 6 gets complete mixing */
34147476Sdumbbell
35147476Sdumbbell/* a, b, c, d - data; h0, h1 - accumulated hash */
36147476Sdumbbell#define TEACORE(rounds)							\
37147476Sdumbbell    do {								\
38147476Sdumbbell	    int n;							\
39147476Sdumbbell	    uint32_t b0, b1;						\
40147476Sdumbbell	    uint32_t sum;						\
41147476Sdumbbell									\
42147476Sdumbbell	    n = rounds;							\
43147476Sdumbbell	    sum = 0;							\
44147476Sdumbbell	    b0 = h0;							\
45147476Sdumbbell	    b1 = h1;							\
46147476Sdumbbell									\
47147476Sdumbbell	    do {							\
48147476Sdumbbell		    sum += DELTA;					\
49147476Sdumbbell		    b0 += ((b1 << 4) + a) ^ (b1+sum) ^ ((b1 >> 5) + b);	\
50147476Sdumbbell		    b1 += ((b0 << 4) + c) ^ (b0+sum) ^ ((b0 >> 5) + d);	\
51147476Sdumbbell	    } while (--n);						\
52147476Sdumbbell									\
53147476Sdumbbell	    h0 += b0;							\
54147476Sdumbbell	    h1 += b1;							\
55147476Sdumbbell    } while (0)
56147476Sdumbbell
57147476Sdumbbelluint32_t
58147476Sdumbbellkeyed_hash(const signed char *msg, int len)
59147476Sdumbbell{
60147476Sdumbbell	uint32_t k[] = { 0x9464a485, 0x542e1a94, 0x3e846bff, 0xb75bcfc3 };
61147476Sdumbbell
62147476Sdumbbell	uint32_t h0, h1;
63147476Sdumbbell	uint32_t a, b, c, d;
64147476Sdumbbell	uint32_t pad;
65147476Sdumbbell	int i;
66147476Sdumbbell
67147476Sdumbbell	h0 = k[0];
68147476Sdumbbell	h1 = k[1];
69147476Sdumbbell
70147476Sdumbbell	pad = (uint32_t)len | ((uint32_t)len << 8);
71147476Sdumbbell	pad |= pad << 16;
72147476Sdumbbell
73147476Sdumbbell	while(len >= 16) {
74147476Sdumbbell		a = (uint32_t)msg[ 0]       |
75147476Sdumbbell		    (uint32_t)msg[ 1] <<  8 |
76147476Sdumbbell		    (uint32_t)msg[ 2] << 16 |
77147476Sdumbbell		    (uint32_t)msg[ 3] << 24;
78147476Sdumbbell		b = (uint32_t)msg[ 4]       |
79147476Sdumbbell		    (uint32_t)msg[ 5] <<  8 |
80147476Sdumbbell		    (uint32_t)msg[ 6] << 16 |
81147476Sdumbbell		    (uint32_t)msg[ 7] << 24;
82147476Sdumbbell		c = (uint32_t)msg[ 8]       |
83147476Sdumbbell		    (uint32_t)msg[ 9] <<  8 |
84147476Sdumbbell		    (uint32_t)msg[10] << 16 |
85147476Sdumbbell		    (uint32_t)msg[11] << 24;
86147476Sdumbbell		d = (uint32_t)msg[12]       |
87147476Sdumbbell		    (uint32_t)msg[13] <<  8 |
88147476Sdumbbell		    (uint32_t)msg[14] << 16 |
89147476Sdumbbell		    (uint32_t)msg[15] << 24;
90147476Sdumbbell
91147476Sdumbbell		TEACORE(PARTROUNDS);
92147476Sdumbbell
93147476Sdumbbell		len -= 16;
94147476Sdumbbell		msg += 16;
95147476Sdumbbell	}
96147476Sdumbbell
97147476Sdumbbell	if (len >= 12) {
98147476Sdumbbell		a = (uint32_t)msg[ 0]       |
99147476Sdumbbell		    (uint32_t)msg[ 1] <<  8 |
100147476Sdumbbell		    (uint32_t)msg[ 2] << 16 |
101147476Sdumbbell		    (uint32_t)msg[ 3] << 24;
102147476Sdumbbell		b = (uint32_t)msg[ 4]       |
103147476Sdumbbell		    (uint32_t)msg[ 5] <<  8 |
104147476Sdumbbell		    (uint32_t)msg[ 6] << 16 |
105147476Sdumbbell		    (uint32_t)msg[ 7] << 24;
106147476Sdumbbell		c = (uint32_t)msg[ 8]       |
107147476Sdumbbell		    (uint32_t)msg[ 9] <<  8 |
108147476Sdumbbell		    (uint32_t)msg[10] << 16 |
109147476Sdumbbell		    (uint32_t)msg[11] << 24;
110147476Sdumbbell
111147476Sdumbbell		d = pad;
112147476Sdumbbell		for(i = 12; i < len; i++) {
113147476Sdumbbell			d <<= 8;
114147476Sdumbbell			d |= msg[i];
115147476Sdumbbell		}
116147476Sdumbbell	} else if (len >= 8) {
117147476Sdumbbell		a = (uint32_t)msg[ 0]     |
118147476Sdumbbell		    (uint32_t)msg[ 1] <<  8 |
119147476Sdumbbell		    (uint32_t)msg[ 2] << 16 |
120147476Sdumbbell		    (uint32_t)msg[ 3] << 24;
121147476Sdumbbell		b = (uint32_t)msg[ 4]     |
122147476Sdumbbell		    (uint32_t)msg[ 5] <<  8 |
123147476Sdumbbell		    (uint32_t)msg[ 6] << 16 |
124147476Sdumbbell		    (uint32_t)msg[ 7] << 24;
125147476Sdumbbell
126147476Sdumbbell		c = d = pad;
127147476Sdumbbell		for(i = 8; i < len; i++) {
128147476Sdumbbell			c <<= 8;
129147476Sdumbbell			c |= msg[i];
130147476Sdumbbell		}
131147476Sdumbbell	} else if (len >= 4) {
132147476Sdumbbell		a = (uint32_t)msg[ 0]     |
133147476Sdumbbell		    (uint32_t)msg[ 1] <<  8 |
134147476Sdumbbell		    (uint32_t)msg[ 2] << 16 |
135147476Sdumbbell		    (uint32_t)msg[ 3] << 24;
136147476Sdumbbell
137147476Sdumbbell		b = c = d = pad;
138147476Sdumbbell		for(i = 4; i < len; i++) {
139147476Sdumbbell			b <<= 8;
140147476Sdumbbell			b |= msg[i];
141147476Sdumbbell		}
142147476Sdumbbell	} else {
143147476Sdumbbell		a = b = c = d = pad;
144147476Sdumbbell		for(i = 0; i < len; i++) {
145147476Sdumbbell			a <<= 8;
146147476Sdumbbell			a |= msg[i];
147147476Sdumbbell		}
148147476Sdumbbell	}
149147476Sdumbbell
150147476Sdumbbell	TEACORE(FULLROUNDS);
151147476Sdumbbell
152147476Sdumbbell	/* return 0; */
153147476Sdumbbell	return (h0 ^ h1);
154147476Sdumbbell}
155147476Sdumbbell
156147476Sdumbbell/*
157147476Sdumbbell * What follows in this file is copyright 2000 by Hans Reiser, and the
158147476Sdumbbell * licensing of what follows is governed by README
159147476Sdumbbell * */
160147476Sdumbbelluint32_t
161147476Sdumbbellyura_hash(const signed char *msg, int len)
162147476Sdumbbell{
163147476Sdumbbell	int i;
164147476Sdumbbell	int j, pow;
165147476Sdumbbell	uint32_t a, c;
166147476Sdumbbell
167147476Sdumbbell	for (pow = 1, i = 1; i < len; i++)
168147476Sdumbbell		pow = pow * 10;
169147476Sdumbbell
170147476Sdumbbell	if (len == 1)
171147476Sdumbbell		a = msg[0] - 48;
172147476Sdumbbell	else
173147476Sdumbbell		a = (msg[0] - 48) * pow;
174147476Sdumbbell
175147476Sdumbbell	for (i = 1; i < len; i++) {
176147476Sdumbbell		c = msg[i] - 48;
177147476Sdumbbell		for (pow = 1, j = i; j < len - 1; j++)
178147476Sdumbbell			pow = pow * 10;
179147476Sdumbbell		a = a + c * pow;
180147476Sdumbbell	}
181147476Sdumbbell
182147476Sdumbbell	for (; i < 40; i++) {
183147476Sdumbbell		c = '0' - 48;
184147476Sdumbbell		for (pow = 1, j = i; j < len - 1; j++)
185147476Sdumbbell			pow = pow * 10;
186147476Sdumbbell		a = a + c * pow;
187147476Sdumbbell	}
188147476Sdumbbell
189147476Sdumbbell	for (; i < 256; i++) {
190147476Sdumbbell		c = i;
191147476Sdumbbell		for (pow = 1, j = i; j < len - 1; j++)
192147476Sdumbbell			pow = pow * 10;
193147476Sdumbbell		a = a + c * pow;
194147476Sdumbbell	}
195147476Sdumbbell
196147476Sdumbbell	a = a << 7;
197147476Sdumbbell	return (a);
198147476Sdumbbell}
199147476Sdumbbell
200147476Sdumbbelluint32_t
201147476Sdumbbellr5_hash(const signed char *msg, int len)
202147476Sdumbbell{
203147476Sdumbbell	uint32_t a;
204147476Sdumbbell	const signed char *start;
205147476Sdumbbell
206147476Sdumbbell	a = 0;
207147476Sdumbbell	start = msg;
208147476Sdumbbell
209147476Sdumbbell	while (*msg && msg < start + len) {
210147476Sdumbbell		a += *msg << 4;
211147476Sdumbbell		a += *msg >> 4;
212147476Sdumbbell		a *= 11;
213147476Sdumbbell		msg++;
214147476Sdumbbell	}
215147476Sdumbbell
216147476Sdumbbell	return (a);
217147476Sdumbbell}
218