ABY Framework  1.0
Arithmetic Bool Yao Framework
 All Classes Files Functions Variables Enumerations Enumerator Macros
hashing_util.h
1 /*
2  * hashing_util.h
3  *
4  * Created on: Oct 8, 2014
5  * Author: mzohner
6  */
7 
8 #ifndef HASHING_UTIL_H_
9 #define HASHING_UTIL_H_
10 
11 #include "../hashing_includes.h"
12 #include <math.h>
13 
14 typedef uint16_t TABLEID_T;
15 
16 //#define TEST_UTILIZATION
17 #define MAX_TABLE_SIZE_BYTES sizeof(TABLEID_T)
18 #define DUMMY_ENTRY_SERVER 0x00
19 #define DUMMY_ENTRY_CLIENT 0xFF
20 
21 #define USE_LUBY_RACKOFF
22 
23 typedef struct hashing_state_ctx {
24  uint32_t nhashfuns;
25  uint32_t*** hf_values;//[NUM_HASH_FUNCTIONS];
26  uint32_t nhfvals;
27  uint32_t nelements;
28  uint32_t nbins;
29  uint32_t inbitlen;
30  uint32_t addrbitlen;
31  uint32_t outbitlen;
32  //the byte values, are stored separately since they are needed very often
33  uint32_t inbytelen;
34  uint32_t addrbytelen;
35  uint32_t outbytelen;
36  uint32_t* address_used;
37  uint32_t mask;
38 } hs_t;
39 
40 
41 //use as mask to address the bits in a uint32_t vector
42 static const uint32_t SELECT_BITS[33] = \
43  {0x00000000, 0x00000001, 0x00000003, 0x00000007, 0x0000000F, 0x0000001F, 0x0000003F, 0x0000007F, \
44  0x000000FF, 0x000001FF, 0x000003FF, 0x000007FF, 0x00000FFF, 0x00001FFF, 0x00003FFF, 0x00007FFF, \
45  0x0000FFFF, 0x0001FFFF, 0x0003FFFF, 0x0007FFFF, 0x000FFFFF, 0x001FFFFF, 0x003FFFFF, 0x007FFFFF, \
46  0x00FFFFFF, 0x01FFFFFF, 0x03FFFFFF, 0x07FFFFFF, 0x0FFFFFFF, 0x1FFFFFFF, 0x3FFFFFFF, 0x7FFFFFFF, \
47  0xFFFFFFFF };
48 
49 //can also be computed as SELECT_BITS ^ 0xFFFFFFFF
50 static const uint32_t SELECT_BITS_INV[33] = \
51  {0xFFFFFFFF, 0xFFFFFFFE, 0xFFFFFFFC, 0xFFFFFFF8, 0xFFFFFFF0, 0xFFFFFFE0, 0xFFFFFFC0, 0xFFFFFF80, \
52  0xFFFFFF00, 0xFFFFFE00, 0xFFFFFC00, 0xFFFFF800, 0xFFFFF000, 0xFFFFE000, 0xFFFFC000, 0xFFFF8000, \
53  0xFFFF0000, 0xFFFE0000, 0xFFFC0000, 0xFFF80000, 0xFFF00000, 0xFFE00000, 0xFFC00000, 0xFF800000, \
54  0xFF000000, 0xFE000000, 0xFC000000, 0xF8000000, 0xF0000000, 0xE0000000, 0xC0000000, 0x80000000, \
55  0x00000000 };
56 
57 static const uint8_t BYTE_SELECT_BITS_INV[8] = {0xFF, 0x7F, 0x3F, 0x1F, 0x0F, 0x07, 0x03, 0x01};
58 
59 //Init the values for the hash function
60 static void init_hashing_state(hs_t* hs, uint32_t nelements, uint32_t inbitlen, uint32_t nbins,
61  uint32_t nhashfuns, prf_state_ctx* prf_state) {
62  uint32_t i, j, nrndbytes;
63  hs->nhashfuns = nhashfuns;
64  hs->nelements = nelements;
65  hs->nbins = nbins;
66 
67  hs->inbitlen = inbitlen;
68  hs->addrbitlen = min((uint32_t) ceil_log2(nbins), inbitlen);
69 
70 #ifdef USE_LUBY_RACKOFF
71  hs->outbitlen = hs->inbitlen - hs->addrbitlen+1;
72 #else
73  hs->outbitlen = inbitlen;
74 #endif
75  //TODO prevent too much memory utilization
76  //assert(hs->outbitlen < 32);
77  //TODO: quickfix to enable hashing for large values
78  //hs->outbitlen = min((double) hs->outbitlen, (double) 24);
79 
80  hs->inbytelen = ceil_divide(hs->inbitlen, 8);
81  hs->addrbytelen = ceil_divide(hs->addrbitlen, 8);
82  hs->outbytelen = ceil_divide(hs->outbitlen, 8);
83 
84  hs->nhfvals = ceil_divide(hs->outbytelen, MAX_TABLE_SIZE_BYTES);
85 
86 
87  nrndbytes = (1<<(8*MAX_TABLE_SIZE_BYTES)) * sizeof(uint32_t);
88 
89  //cout << " random bytes: " << nrndbytes << endl;
90  //cout << "inbitlen = " << hs->inbitlen << ", outbitlen = " << hs->outbitlen << ", addrbitlen = " << hs->addrbitlen <<
91  // ", nhfvals = " << hs->nhfvals << ", nrndbytes = " << nrndbytes << endl;
92 
93  hs->hf_values = (uint32_t***) malloc(sizeof(uint32_t**) * hs->nhashfuns);
94  for(i = 0; i < hs->nhashfuns; i++) {
95  hs->hf_values[i] = (uint32_t**) malloc(sizeof(uint32_t*) * hs->nhfvals);
96 
97  for(j = 0; j < hs->nhfvals; j++) {
98  hs->hf_values[i][j] = (uint32_t*) malloc(nrndbytes);
99  assert(hs->hf_values[i][j]);
100  gen_rnd_bytes(prf_state, (uint8_t*) hs->hf_values[i][j], nrndbytes);
101  }
102  }
103  //cout << "nhfvals = " << hs->nhfvals << endl;
104  hs->address_used = (uint32_t*) calloc(nbins, sizeof(uint32_t));
105  hs->mask = 0xFFFFFFFF >> hs->addrbitlen;
106  if(hs->inbytelen < sizeof(uint32_t)) {
107  hs->mask >>= (sizeof(uint32_t) * 8 - hs->inbitlen - hs->addrbitlen);
108  }
109 }
110 
111 static void free_hashing_state(hs_t* hs) {
112  uint32_t i, j;
113  for(i = 0; i < hs->nhashfuns; i++) {
114  for(j = 0; j < hs->nhfvals; j++) {
115  free(hs->hf_values[i][j]);
116  }
117  free(hs->hf_values[i]);
118  }
119  free(hs->address_used);
120  free(hs->hf_values);
121 }
122 
123 //reduce the bit-length of the elements if some bits are used to determine the bin and a permutation is used for hashing
124 //static uint32_t getOutBitLen(uint32_t inbitlen, uint32_t nelements) {
125 // return inbitlen - ceil_log2(nelements);
126 //};
127 
128 //TODO: a generic place holder, can be replaced by any other hash function
129 //inline void hashElement(uint8_t* element, uint32_t* address, uint8_t* val, uint32_t hfid, hs_t* hs) {
130 inline void hashElement(uint8_t* element, uint32_t* address, uint8_t* val, hs_t* hs) {
131 
132  //for(uint32_t i = 0; i < hs->inbytelen; i++)
133  // cout << (hex) << (uint32_t) element[i];
134  //cout << (dec) << endl;
135 #ifdef USE_LUBY_RACKOFF
136  //TODO: the table-lookup hashing is only used for elements up to 32-bit length, since it gets very inefficient for larger values
137  uint64_t i, j, L, R;
138  TABLEID_T hfmaskaddr;
139  //Store the first hs->addrbitlen bits in L
140  L = *((uint32_t*) element) & SELECT_BITS[hs->addrbitlen];
141  //Store the remaining hs->outbitlen bits in R and pad correspondingly
142  R = (*((uint32_t*) element) & SELECT_BITS_INV[hs->addrbitlen]) >> (hs->addrbitlen);
143 
144  R &= hs->mask;//mask = (1<<32-hs->addrbitlen)
145 
146 
147  //assert(R < (1<<hs->outbitlen));
148  //cout << "R = " << R << endl;
149  /*if(hfid == 0) {
150  *address = L % hs->nbins;
151  *((uint32_t*) val) = R;
152  } else if(hfid == 1) {
153  *address = R % hs->nbins;
154  *((uint32_t*) val) = L;
155  } else {
156  *address = (L ^ R) % hs->nbins;
157  *((uint32_t*) val) = R;
158  }*/
159  hfmaskaddr = R * sizeof(uint32_t);
160  //cout << "L = " << L << ", R = " << R << " addresses: ";
161  for(i = 0; i < hs->nhashfuns; i++) {
162  //cout << "i = " << i << ", addrbytelen = " << hs->addrbytelen << ", R = " << R << ", nbins = " <<
163  // hs->nbins << ", L = " << L << ", addr= " << endl;
164  //address[i] = (L ^ *(((uint32_t*) &(hs->hf_values[i][R*hs->addrbytelen])))) % hs->nbins;
165  for(j = 0; j < hs->nhfvals; j++) {
166  //assert(hfmaskaddr < (1<<(8*MAX_TABLE_SIZE_BYTES)) * hs->addrbytelen);
167  //cout << "i = " << i << ", j = " << j << ", Hfmaskaddr = " << hfmaskaddr << endl;
168  //cout << "Hfvalue: " << hs->hf_values[i][j][hfmaskaddr] << endl;
169  address[i] = (L ^ *((hs->hf_values[i][j]+hfmaskaddr))) % hs->nbins;
170  //address[i] = (L ^ (i * R)) % hs->nbins;
171  }
172  //cout << address[i] << ", ";
173  //hs->address_used[address[i]]++;
174  }
175  //cout << endl;
176 #ifndef TEST_UTILIZATION
177  R++;
178  *((uint32_t*) val) = R;
179  //cout << (hex) << *((uint32_t*) element) << ", L = " << L << ", R = " << R << (dec) << endl;
180  //TODO copy remaining bits
181 
182  //if(hs->outbytelen >= sizeof(uint32_t))
183  if(hs->inbitlen > sizeof(uint32_t) * 8) {
184  //memcpy(val + (sizeof(uint32_t) - hs->addrbytelen), element + sizeof(uint32_t), hs->outbytelen - (sizeof(uint32_t) - hs->addrbytelen));
185  memcpy(val + (sizeof(uint32_t) - (hs->addrbitlen >>3)), element + sizeof(uint32_t), hs->outbytelen - (sizeof(uint32_t) - (hs->addrbitlen >>3)));
186 
187  //cout << "Element: "<< (hex) << (uint32_t) val[hs->outbytelen-1] << ", " << (uint32_t) (BYTE_SELECT_BITS_INV[hs->outbitlen & 0x03])
188  // << ", " << (uint32_t) (val[hs->outbytelen-1] & (BYTE_SELECT_BITS_INV[hs->outbitlen & 0x03]) )<< (dec) << " :";
189 
190  val[hs->outbytelen-1] &= (BYTE_SELECT_BITS_INV[hs->outbitlen & 0x03]);
191 
192  /*for(i = 0; i < hs->inbytelen; i++) {
193  cout << (hex) << (uint32_t) element[i];
194  }
195  cout << ", ";
196  for(i = 0; i < hs->outbytelen; i++) {
197  cout << (hex) << (uint32_t) val[i];
198  }
199  cout << (dec) << endl;*/
200  }
201 
202 
203 #endif
204  //cout << "Address for hfid = " << hfid << ": " << *address << ", L = " << L << ", R = " << R << endl;
205 
206 #else
207  for(uint64_t i = 0; i < NUM_HASH_FUNCTIONS; i++) {
208  address[i] = ((*((uint32_t*) element+i) ^ HF_MASKS[i]) & SELECT_BITS[hs->addrbitlen]) % hs->nbins;
209 
210  #ifndef TEST_UTILIZATION
211  *((uint32_t*) val) = (*((uint32_t*) element) & SELECT_BITS_INV[hs->addrbitlen]) >> (hs->addrbitlen);
212 
213  //copy the remaining full bytes
214  if(hs->outbytelen >= sizeof(uint32_t))
215  memcpy(val + (sizeof(uint32_t) - hs->addrbytelen), element + sizeof(uint32_t), hs->outbytelen - sizeof(uint32_t));
216  #endif
217  }
218 #endif
219 }
220 
221 inline void domain_hashing(uint32_t nelements, uint8_t* elements, uint32_t elebytelen, uint8_t* result,
222  uint32_t resultbytelen, crypto* crypt) {
223 
224  uint8_t *eleptr, *resultptr, *hash_buf;
225  uint32_t i;
226 
227  eleptr=elements;
228  resultptr = result;
229 #ifndef BATCH
230  cout << "Hashing " << nelements << " elements from " << elebytelen << " bytes into " << resultbytelen << " bytes" << endl;
231 #endif
232  hash_buf = (uint8_t*) calloc(crypt->get_hash_bytes(), sizeof(uint8_t));
233  for(i = 0; i < nelements; i++, resultptr+=resultbytelen, eleptr+=elebytelen) {
234  memcpy(hash_buf, eleptr, elebytelen);
235  crypt->hash(resultptr, resultbytelen, hash_buf, elebytelen);
236  }
237  free(hash_buf);
238 }
239 
240 inline void domain_hashing(uint32_t nelements, uint8_t** elements, uint32_t* elebytelens, uint8_t* result,
241  uint32_t resultbytelen, crypto* crypt) {
242  uint8_t *resultptr;//, *hash_buf;
243  uint32_t i;
244 
245  //eleptr=elements;
246  resultptr = result;
247 #ifndef BATCH
248  cout << "Hashing " << nelements << " elements from " << elebytelens << " bytes into " << resultbytelen << " bytes" << endl;
249 #endif
250  //hash_buf = (uint8_t*) calloc(crypt->get_hash_bytes(), sizeof(uint8_t));
251  for(i = 0; i < nelements; i++, resultptr+=resultbytelen) {
252  //memcpy(hash_buf, elements[i], elebytelens[i]);
253  crypt->hash(resultptr, resultbytelen, elements[i], elebytelens[i]);
254  }
255  //free(hash_buf);
256 }
257 
258 #endif /* HASHING_UTIL_H_ */
Definition: crypto.h:58
Definition: hashing_util.h:23
Definition: crypto.h:52