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