Percy++
A C++ implementation of Private Information Retrieval (PIR) protocols
 All Classes Files Functions Variables Typedefs Enumerations Enumerator Pages
old_matrix_impl.h
1 // Percy++ Copyright 2014 Ian Goldberg <iang@cs.uwaterloo.ca>,
2 // Wouter Lueks <lueks@cs.ru.nl>
3 //
4 // This program is free software; you can redistribute it and/or modify
5 // it under the terms of version 2 of the GNU General Public License as
6 // published by the Free Software Foundation.
7 //
8 // This program is distributed in the hope that it will be useful,
9 // but WITHOUT ANY WARRANTY; without even the implied warranty of
10 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 // GNU General Public License for more details.
12 //
13 // There is a copy of the GNU General Public License in the COPYING file
14 // packaged with this plugin; if you cannot find it, write to the Free
15 // Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
16 // 02110-1301 USA
17 
18 template <typename Element>
19 Matrix<Element>::Matrix(Element *data,
20  dbsize_t num_rows, dbsize_t num_cols)
21 :
22  data(data),
23  num_rows(num_rows),
24  num_cols(num_cols)
25 {}
26 
27 template <typename Element> Matrix<Element>::Matrix () {}
28 
29 template <typename Element>
31  SubMatrix<Element> &m11,
32  SubMatrix<Element> &m12,
33  SubMatrix<Element> &m21,
34  SubMatrix<Element> &m22)
35 {
36  dbsize_t nrows = this->num_rows / 2;
37  dbsize_t ncols = this->num_cols / 2;
38 
39  m11 = SubMatrix<Element>(*this, 0, 0, nrows, ncols);
40  m12 = SubMatrix<Element>(*this, 0, ncols, nrows, ncols);
41  m21 = SubMatrix<Element>(*this, nrows, 0, nrows, ncols);
42  m22 = SubMatrix<Element>(*this, nrows, ncols, nrows, ncols);
43 }
44 
45 template <typename Element>
46 inline void Matrix<Element>::clear()
47 {
48  memset(this->data, 0,
49  this->num_cols * this->num_rows * sizeof(Element));
50 }
51 
52 template <typename Element>
53 inline void Matrix<Element>::is_sum_of(
55 {
56  // WARNING: only works for equal sized submatrices
57  Element * dst = this->data;
58  const Element * src1 = sub1.first();
59  const Element * src2 = sub2.first();
60 
61  size_t nc_bytes = sub1.num_cols * sizeof(Element);
62 
63  for(unsigned int row = 0; row < sub1.num_rows; ++row) {
64  XOR_unequal((unsigned char*) dst,
65  (const unsigned char*) src1,
66  (const unsigned char*) src2, nc_bytes);
67 
68  dst += sub1.num_cols;
69  src1 += sub1.matrix.num_cols;
70  src2 += sub2.matrix.num_cols;
71  }
72 }
73 
74 template <typename Element>
76 {
77  const Element *src = other.first();
78  Element *dst = this->data;
79  for(unsigned int row = 0; row < other.num_rows; ++row) {
80  memcpy((void *) dst, (const void *) src,
81  other.num_cols * sizeof(Element));
82  dst += this->num_cols;
83  src += other.matrix.num_cols;
84  }
85 }
86 
87 template <typename Element>
88 inline void Matrix<Element>::print()
89 {
90  std::cerr << "[";
91  for(unsigned int r = 0; r < this->num_rows; ++r) {
92  for(unsigned int c = 0; c < this->num_cols; ++c) {
93  std::cerr << " " << hex <<
94  (int) *(this->data + r * this->num_cols + c);
95  }
96  std::cerr << ",";
97  }
98  std::cerr << "]" << endl;
99 }
100 
101 template <typename Element> SubMatrix<Element>::SubMatrix () {}
102 
103 template <typename Element>
105  dbsize_t row, dbsize_t col,
106  dbsize_t num_rows, dbsize_t num_cols)
107 :
108  matrix(matrix),
109  row(row),
110  col(col),
111  num_rows(num_rows),
112  num_cols(num_cols)
113 {}
114 
115 template <typename Element>
117 {
118  Element *dst = this->first();
119  Element *src = m.data;
120 
121  size_t nc_bytes = this->num_cols * sizeof(Element);
122 
123  for(unsigned int row = 0; row < this->num_rows; ++row) {
124  XOR_equal((unsigned char *)dst, (const unsigned char*)src,
125  nc_bytes);
126  dst += this->matrix.num_cols;
127  src += m.num_cols;
128  }
129 
130 }
131 
132 template <typename Element>
133 inline void SubMatrix<Element>::print()
134 {
135  Element *data = this->matrix.data;
136  dbsize_t num_cols = this->matrix.num_cols;
137 
138  std::cerr << "[";
139  for(dbsize_t r = this->row; r < this->num_rows + this->row; ++r) {
140  for(dbsize_t c = this->col; c < this->num_cols + this->col; ++c) {
141  std::cerr << " " << hex << (int) *(data + r * num_cols + c);
142  }
143  std::cerr << ",";
144  }
145  std::cerr << "]" << endl;
146 }
147 
148 template <typename Element>
149 inline Element*
150 SubMatrix<Element>::get(dbsize_t row, dbsize_t col)
151 {
152  return this->matrix.data +
153  this->matrix.num_cols * (this->row + row) + (this->col + col);
154 }
155 
156 template <typename Element>
157 inline Element*
159 {
160  return this->matrix.data +
161  this->matrix.num_cols * this->row + this->col;
162 }
163 
164 template <typename Element>
166  dbsize_t row, dbsize_t col, dbsize_t num_cols)
167 :
168  SubMatrix<Element>(matrix, row, col, 1, num_cols)
169 {}
170 
171 template <typename Element>
172 inline Element*
173 Row<Element>::get(dbsize_t col)
174 {
175  return SubMatrix<Element>::get(0, col);
176 }
177 
178 template <typename Element>
180  dbsize_t row, dbsize_t col, dbsize_t num_rows)
181 :
182  SubMatrix<Element>(matrix, row, col, num_rows, 1)
183 {}
184 
185 template <typename Element>
186 inline Element*
187 Col<Element>::get(dbsize_t row)
188 {
189  return SubMatrix<Element>::get(row, 0);
190 }
191 
192 template <typename Element>
194  dbsize_t row, dbsize_t col)
195 :
196  SubMatrix<Element>(matrix, row, col, 1, 1),
197  Row<Element>(matrix, row, col, 1),
198  Col<Element>(matrix, row, col, 1)
199 {}
200 
201 template <typename Element>
202 inline Element*
203 Elem<Element>::get(dbsize_t nothing)
204 {
205  return SubMatrix<Element>::get(0, 0);
206 }
207 
208 template <>
212 {
213  const GF28_Element *row = row_a.first();
214  const GF28_Element *block = mat_b.first();
215 
216  GF28_Element *oc_start = this->first();
217  GF28_Element *oc_end = this->get(mat_b.num_cols & ~7);
218 
219  const GF28_Element *multrow;
220  const GF28_Element *blockc;
221  GF28_Element *oc;
222 
223  for (unsigned int j = 0; j < row_a.num_cols; ++j) {
224  multrow = GF28_mult_table[row[j]];
225  blockc = block;
226  oc = oc_start;
227 
228  while (oc < oc_end) {
229  uint64_t accum = (uint64_t) multrow[*(blockc++)];
230  accum |= (uint64_t) multrow[*(blockc++)] << 8;
231  accum |= (uint64_t) multrow[*(blockc++)] << 16;
232  accum |= (uint64_t) multrow[*(blockc++)] << 24;
233  accum |= (uint64_t) multrow[*(blockc++)] << 32;
234  accum |= (uint64_t) multrow[*(blockc++)] << 40;
235  accum |= (uint64_t) multrow[*(blockc++)] << 48;
236  accum |= (uint64_t) multrow[*(blockc++)] << 56;
237  *((uint64_t *) oc) ^= accum;
238  oc+=8;
239  }
240  for (unsigned int c = 0; c < (mat_b.num_cols & 7); ++c) {
241  *(oc++) ^= multrow[*(blockc++)];
242  }
243 
244  block += mat_b.matrix.num_cols;
245  }
246 }
247 
248 template <>
252 {
253  const GF216_Element *row = row_a.first();
254  const GF216_Element *block = mat_b.first();
255 
256  GF216_Element *oc;
257  GF216_Element *oc_start = this->first();
258  GF216_Element *oc_end = this->get(mat_b.num_cols & ~3);
259  for (dbsize_t j = 0; j < row_a.num_cols; ++j) {
260  GF216_Element inpv_j = row[j];
261  if (inpv_j != 0) {
262  const GF216_Element *blockc = block;
263  GF216_Element log_j = GF216_log_table[inpv_j];
264  const GF216_Element *start = GF216_exp_table + log_j;
265  oc = oc_start;
266  GF216_Element block_c;
267  while(oc < oc_end) {
268  uint64_t accum = 0;
269  block_c = *(blockc++);
270  if (block_c != 0) {
271  GF216_Element log_c = GF216_log_table[block_c];
272  accum |= (uint64_t) start[log_c];
273  }
274  block_c = *(blockc++);
275  if (block_c != 0) {
276  GF216_Element log_c = GF216_log_table[block_c];
277  accum |= (uint64_t) start[log_c] << 16;
278  }
279  block_c = *(blockc++);
280  if (block_c != 0) {
281  GF216_Element log_c = GF216_log_table[block_c];
282  accum |= (uint64_t) start[log_c] << 32;
283  }
284  block_c = *(blockc++);
285  if (block_c != 0) {
286  GF216_Element log_c = GF216_log_table[block_c];
287  accum |= (uint64_t) start[log_c] << 48;
288  }
289  *((uint64_t *) oc) ^= accum;
290  oc+=4;
291  }
292  for (dbsize_t c = 0; c < (mat_b.num_cols & 3); ++c, ++oc) {
293  block_c = *(blockc++);
294  if (block_c != 0) {
295  GF216_Element log_c = GF216_log_table[block_c];
296  *oc ^= start[log_c];
297  }
298  }
299  }
300  block += mat_b.matrix.num_cols;
301  }
302 }
303 
304 template <typename GF2E_Element>
308 {
309  dbsize_t r, c;
310  for(r = 0; r < mat_a.num_rows; ++r) {
311  for(c = 0; c < mat_a.num_cols; ++c) {
312  *this->get(r) ^=
313  multiply_GF2E(*mat_a.get(r,c), *col_b.get(c));
314  }
315  }
316 }
317 
318 template <typename GF2E_Element>
322 {
323  GF2E_Element *acc = this->first();
324 
325  const GF2E_Element *a_ptr = row_a.first();
326  const GF2E_Element *b_ptr = col_b.first();
327  const GF2E_Element *a_end = row_a.get(row_a.num_cols);
328 
329  while(a_ptr < a_end) {
330  *acc ^= multiply_GF2E(*(a_ptr++), *b_ptr);
331  b_ptr += col_b.matrix.num_cols;
332  }
333 }
334 
335 template <>
339 {
340  const GF28_Element *row_start = row_b.first();
341 
342  const GF28_Element *multcol;
343  const GF28_Element *row;
344  GF28_Element *oc, *oc_end;
345 
346  for (dbsize_t r = 0; r < col_a.num_rows; ++r) {
347  multcol = GF28_mult_table[*col_a.get(r)];
348 
349  oc = this->get(r,0);
350  oc_end = this->get(r,row_b.num_cols);
351  row = row_start;
352 
353  while(oc < oc_end)
354  *(oc++) ^= multcol[*(row++)];
355  }
356 }
357 
358 template <>
362 {
363  const GF216_Element *row;
364  const GF216_Element *row_start = row_b.first();
365  GF216_Element row_elem;
366 
367  GF216_Element col_elem;
368  GF216_Element log_c;
369  const GF216_Element *start_c;
370 
371  GF216_Element *oc, *oc_end;
372 
373  for (dbsize_t r = 0; r < col_a.num_rows; ++r) {
374  col_elem = *col_a.get(r);
375  if(col_elem != 0) {
376  dbsize_t c = 0;
377  oc = this->get(r,0);
378  oc_end = this->get(r,row_b.num_cols);
379 
380  log_c = GF216_log_table[col_elem];
381  start_c = GF216_exp_table + log_c;
382 
383  row = row_start;
384 
385  while(oc < oc_end) {
386  row_elem = *(row++);
387  if(row_elem != 0)
388  *oc ^= start_c[GF216_log_table[row_elem]];
389  ++c;
390  ++oc;
391  }
392  }
393  }
394 }
395 
396 template <>
400 {
401  const GF28_Element *mult = GF28_mult_table[*elem_b.first()];
402 
403  const GF28_Element *col = col_a.first();
404  GF28_Element *oc, *oc_end;
405 
406  oc = this->get(0);
407  oc_end = this->get(col_a.num_rows);
408 
409  while(oc < oc_end) {
410  *oc ^= mult[*col];
411  oc += this->matrix.num_cols;
412  col += col_a.matrix.num_cols;
413  }
414 }
415 
416 template <>
420 {
421  GF216_Element b = *elem_b.first();
422 
423  if(b != 0) {
424  const GF216_Element log_mult = GF216_log_table[b];
425  const GF216_Element *start_mult = GF216_exp_table + log_mult;
426 
427  const GF216_Element *col = col_a.first();
428  GF216_Element *oc, *oc_end;
429 
430  oc = this->get(0);
431  oc_end = this->get(col_a.num_rows);
432 
433  while(oc < oc_end) {
434  if(*col != 0)
435  *oc ^= start_mult[GF216_log_table[*col]];
436 
437  oc += this->matrix.num_cols;
438  col += col_a.matrix.num_cols;
439  }
440  }
441 }
442 
443 template <typename GF2E_Element>
447 {
448  *this->first() ^= multiply_GF2E(*elem_a.first(), *elem_b.first());
449 }
Definition: old_matrix.h:28
Definition: old_matrix.h:33
Definition: old_matrix.h:29
Definition: old_matrix.h:30
Definition: old_matrix.h:27