emp-toolkit
mextension_kos.h
Go to the documentation of this file.
1 #ifndef OT_M_EXTENSION_KOS_H__
2 #define OT_M_EXTENSION_KOS_H__
3 #include "ot.h"
4 #include "co.h"
5 
9 class MOTExtension_KOS: public OT<MOTExtension_KOS> { public:
13  const int l = 128;
14  block *k0 = nullptr, *k1 = nullptr;
15  bool *s = nullptr;
16 
17  block * qT = nullptr, block_s, *tT = nullptr, *open_data = nullptr;
18  bool setup = false;
19  int ssp;
20  bool * extended_r = nullptr;
21  bool committing = false;
23  MOTExtension_KOS(NetIO * io, bool committing = false, int ssp = 40): OT(io) {
24  this->base_ot = new OTCO(io);
25  this->ssp = ssp;
26  this->s = new bool[l];
27  this->k0 = new block[l];
28  this->k1 = new block[l];
29  this->committing = committing;
30  }
31 
33  delete base_ot;
37 
41  delete_array_null(extended_r);
42  }
43 
44  void setup_send(block * in_k0 = nullptr, bool * in_s = nullptr){
45  setup = true;
46  if(in_s != nullptr) {
47  memcpy(k0, in_k0, l*sizeof(block));
48  memcpy(s, in_s, l);
49  block_s = bool_to128(s);
50  return;
51  }
52  prg.random_bool(s, l);
53  base_ot->recv(k0, s, l);
54  block_s = bool_to128(s);
55  }
56 
57  void setup_recv(block * in_k0 = nullptr, block * in_k1 =nullptr) {
58  setup = true;
59  if(in_k0 !=nullptr) {
60  memcpy(k0, in_k0, l*sizeof(block));
61  memcpy(k1, in_k1, l*sizeof(block));
62  return;
63  }
64  prg.random_block(k0, l);
65  prg.random_block(k1, l);
66  base_ot->send(k0, k1, l);
67  }
68 
69  void send_pre(int length) {
70  length = ((length+128+ssp+127)/128)*128;
71 
72  if(!setup) setup_send();
73  setup = false;
74  if (committing) {
75  Hash::hash_once(dgst, &block_s, sizeof(block));
77  }
78  block * q = new block[length];
80  qT = new block[length];
81  //get u, compute q
82  block *tmp = new block[length/128];
83  PRG G;
84  for(int i = 0; i < l; ++i) {
85  io->recv_data(tmp, length/8);
86  G.reseed(&k0[i]);
87  G.random_data(q+(i*length/128), length/8);
88  if (s[i])
89  xorBlocks_arr(q+(i*length/128), q+(i*length/128), tmp, length/128);
90  }
91  sse_trans((uint8_t *)(qT), (uint8_t*)q, l, length);
92  delete[] tmp;
93  delete[] q;
94  }
95 
96  void recv_pre(const bool* r, int length) {
97  int old_length = length;
98  length = ((length+128+ssp+127)/128)*128;
99 
100  if(!setup)setup_recv();
101  setup = false;
102  if (committing) {
104  }
105  bool * r2 = new bool[length];
106  memcpy(r2, r, old_length);
107  delete_array_null(extended_r);
108  extended_r = new bool[length - old_length];
109  prg.random_bool(extended_r, length- old_length);
110  memcpy(r2+old_length, extended_r, length - old_length);
111 
112  block *block_r = new block[length/128];
113  for(int i = 0; i < length/128; ++i) {
114  block_r[i] = bool_to128(r2+i*128);
115  }
116  // send u
117  block* t = new block[length];
118  delete_array_null(tT);
119  tT = new block[length];
120  block* tmp = new block[length/128];
121  PRG G;
122  for(int i = 0; i < l; ++i) {
123  G.reseed(&k0[i]);
124  G.random_data(t+i*length/128, length/8);
125  G.reseed(&k1[i]);
126  G.random_data(tmp, length/8);
127  xorBlocks_arr(tmp, t+(i*length/128), tmp, length/128);
128  xorBlocks_arr(tmp, block_r, tmp, length/128);
129  io->send_data(tmp, length/8);
130  }
131 
132  sse_trans((uint8_t *)tT, (uint8_t*)t, l, length);
133 
134  delete[] t;
135  delete[] tmp;
136  delete[] block_r;
137  delete[] r2;
138  }
139 
140  bool send_check(int length) {
141  int extended_length = ((length+128+ssp+127)/128)*128;
142  block seed2, x, t[2], q[2], tmp1, tmp2;
143  io->recv_block(&seed2, 1);
144  block *chi = new block[extended_length];
145  PRG prg2(&seed2);
146  prg2.random_block(chi, extended_length);
147 
148  q[0] = zero_block();
149  q[1] = zero_block();
150  for(int i = 0; i < extended_length; ++i) {
151  mul128(qT[i], chi[i], &tmp1, &tmp2);
152  q[0] = xorBlocks(q[0], tmp1);
153  q[1] = xorBlocks(q[1], tmp2);
154  }
155  io->recv_block(&x, 1);
156  io->recv_block(t, 2);
157 
158  mul128(x, block_s, &tmp1, &tmp2);
159  q[0] = xorBlocks(q[0], tmp1);
160  q[1] = xorBlocks(q[1], tmp2);
161 
162  delete[] chi;
163  return block_cmp(q, t, 2);
164  }
165  void recv_check(const bool* r, int length) {
166  int extended_length = ((length+128+ssp+127)/128)*128;
167  block *chi = new block[extended_length];
168  block seed2, x = zero_block(), t[2], tmp1, tmp2;
169  prg.random_block(&seed2,1);
170  io->send_block(&seed2, 1);
171  PRG prg2(&seed2);
172  t[0] = t[1] = zero_block();
173  prg2.random_block(chi,extended_length);
174  for(int i = 0 ; i < length; ++i) {
175  if(r[i])
176  x = xorBlocks(x, chi[i]);
177  }
178  for(int i = 0 ; i < extended_length - length; ++i) {
179  if(extended_r[i])
180  x = xorBlocks(x, chi[i+length]);
181  }
182 
183  io->send_block(&x, 1);
184  for(int i = 0 ; i < extended_length; ++i) {
185  mul128(chi[i], tT[i], &tmp1, &tmp2);
186  t[0] = xorBlocks(t[0], tmp1);
187  t[1] = xorBlocks(t[1], tmp2);
188  }
189  io->send_block(t, 2);
190 
191  delete[] chi;
192  }
193  void got_send_post(const block* data0, const block* data1, int length) {
194  block pad[2];
195  for(int i = 0; i < length; ++i) {
196  pad[0] = qT[i];
197  pad[1] = xorBlocks(qT[i], block_s);
198  pi.H<2>(pad, pad, 2*i);
199  pad[0] = xorBlocks(pad[0], data0[i]);
200  pad[1] = xorBlocks(pad[1], data1[i]);
201  io->send_data(pad, 2*sizeof(block));
202  }
203  delete[] qT; qT = nullptr;
204  }
205 
206  void got_recv_post(block* data, const bool* r, int length) {
207  block res[2];
209  open_data = new block[length];
210  for(int i = 0; i < length; ++i) {
211  io->recv_data(res, 2*sizeof(block));
212  if(r[i]) {
213  data[i] = xorBlocks(res[1], pi.H(tT[i], 2*i+1));
214  open_data[i] = res[0];
215  } else {
216  data[i] = xorBlocks(res[0], pi.H(tT[i], 2*i));
217  open_data[i] = res[1];
218  }
219  }
220  }
221  void send_impl(const block* data0, const block* data1, int length) {
222  send_pre(length);
223  if(!send_check(length))
224  error("OT Extension check failed");
225  got_send_post(data0, data1, length);
226  }
227 
228  void recv_impl(block* data, const bool* b, int length) {
229  recv_pre(b, length);
230  recv_check(b, length);
231  got_recv_post(data, b, length);
232  }
233 
234  void send_rot(block * data0, block * data1, int length) {
235  send_pre(length);
236  if(!send_check(length))
237  error("OT Extension check failed");
238  rot_send_post(data0, data1, length);
239  }
240  void recv_rot(block* data, const bool* b, int length) {
241  recv_pre(b, length);
242  recv_check(b, length);
243  rot_recv_post(data, b, length);
244  }
245 
246  void rot_send_post(block* data0, block* data1, int length) {
247  block pad[2];
248  for(int i = 0; i < length; ++i) {
249  pad[0] = qT[i];
250  pad[1] = xorBlocks(qT[i], block_s);
251  pi.H<2> (pad, pad, 2*i);
252  data0[i] = pad[0];
253  data1[i] = pad[1];
254  }
255  }
256 
257  void rot_recv_post(block* data, const bool* r, int length) {
258  for(int i = 0; i < length; ++i)
259  data[i] = pi.H(tT[i], 2*i+r[i]);
260  }
261 
262  void open() {
263  if (!committing)
264  error("Committing not enabled");
265  io->send_block(&block_s, 1);
266  }
267 
268  void open(block * data, const bool * r, int length) {
269  if (!committing)
270  error("Committing not enabled");
271  io->recv_block(&block_s, 1);
272  char com_recv[Hash::DIGEST_SIZE];
273  Hash::hash_once(com_recv, &block_s, sizeof(block));
274  if (strncmp(com_recv, dgst, 20)!= 0)
275  error("invalid commitment");
276 
277  for(int i = 0; i < length; ++i) {
278  tT[i] = xorBlocks(tT[i], block_s);
279  if(r[i])
280  data[i] = xorBlocks(open_data[i], pi.H(tT[i], 2*i));
281  else
282  data[i] = xorBlocks(open_data[i], pi.H(tT[i], 2*i+1));
283  }
284  }
285 
308  inline void mul128(__m128i a, __m128i b, __m128i *res1, __m128i *res2) {
309  /* block a0xora1 = xorBlocks(a, _mm_srli_si128(a, 8));
310  block b0xorb1 = xorBlocks(b, _mm_srli_si128(b, 8));
311 
312  block a0b0 = _mm_clmulepi64_si128(a, b, 0x00);
313  block a1b1 = _mm_clmulepi64_si128(a, b, 0x11);
314  block ab = _mm_clmulepi64_si128(a0xora1, b0xorb1, 0x00);
315 
316  block tmp = xorBlocks(a0b0, a1b1);
317  tmp = xorBlocks(tmp, ab);
318 
319  *res1 = xorBlocks(a1b1, _mm_srli_si128(tmp, 8));
320  *res2 = xorBlocks(a0b0, _mm_slli_si128(tmp, 8));*/
321  __m128i tmp3, tmp4, tmp5, tmp6;
322  tmp3 = _mm_clmulepi64_si128(a, b, 0x00);
323  tmp4 = _mm_clmulepi64_si128(a, b, 0x10);
324  tmp5 = _mm_clmulepi64_si128(a, b, 0x01);
325  tmp6 = _mm_clmulepi64_si128(a, b, 0x11);
326 
327  tmp4 = _mm_xor_si128(tmp4, tmp5);
328  tmp5 = _mm_slli_si128(tmp4, 8);
329  tmp4 = _mm_srli_si128(tmp4, 8);
330  tmp3 = _mm_xor_si128(tmp3, tmp5);
331  tmp6 = _mm_xor_si128(tmp6, tmp4);
332  // initial mul now in tmp3, tmp6
333  *res1 = tmp3;
334  *res2 = tmp6;
335  }
336 };
337 
339 #endif// OT_M_EXTENSION_KOS_H__
void send_data(const void *data, int nbyte)
Definition: io_channel.h:14
void recv_check(const bool *r, int length)
Definition: mextension_kos.h:165
void recv_data(void *data, int nbyte)
Definition: io_channel.h:17
void random_bool(bool *data, int length)
Definition: prg.h:57
void send_pre(int length)
Definition: mextension_kos.h:69
void delete_array_null(T *ptr)
Definition: utils.h:20
__m128i block
Definition: block.h:8
block * k0
Definition: mextension_kos.h:14
void error(const char *s, int line=0, const char *file=nullptr)
Definition: utils.h:27
void send(const block *data0, const block *data1, int length)
Definition: ot.h:10
MOTExtension_KOS(NetIO *io, bool committing=false, int ssp=40)
Definition: mextension_kos.h:23
block * k1
Definition: mextension_kos.h:14
bool committing
Definition: mextension_kos.h:21
block xorBlocks(block x, block y)
Definition: block.h:35
Definition: net_io_channel.h:22
void sse_trans(uint8_t *out, uint8_t const *inp, int nrows, int ncols)
Definition: block.h:85
void mul128(__m128i a, __m128i b, __m128i *res1, __m128i *res2)
Definition: mextension_kos.h:308
block * open_data
Definition: mextension_kos.h:17
void open()
Definition: mextension_kos.h:262
void open(block *data, const bool *r, int length)
Definition: mextension_kos.h:268
void recv_rot(block *data, const bool *b, int length)
Definition: mextension_kos.h:240
bool * s
Definition: mextension_kos.h:15
void rot_send_post(block *data0, block *data1, int length)
Definition: mextension_kos.h:246
#define zero_block()
Definition: block.h:66
int ssp
Definition: mextension_kos.h:19
void recv_pre(const bool *r, int length)
Definition: mextension_kos.h:96
void got_recv_post(block *data, const bool *r, int length)
Definition: mextension_kos.h:206
const int l
Definition: mextension_kos.h:13
void got_send_post(const block *data0, const block *data1, int length)
Definition: mextension_kos.h:193
block * qT
Definition: mextension_kos.h:17
void send_rot(block *data0, block *data1, int length)
Definition: mextension_kos.h:234
block * tT
Definition: mextension_kos.h:17
block block_s
Definition: mextension_kos.h:17
void random_block(block *data, int nblocks=1)
Definition: prg.h:75
block H(block in, uint64_t id)
Definition: prp.h:48
Definition: mextension_kos.h:9
char dgst[Hash::DIGEST_SIZE]
Definition: mextension_kos.h:22
void reseed(const void *key, uint64_t id=0)
Definition: prg.h:41
Definition: prp.h:11
Definition: co.h:8
bool setup
Definition: mextension_kos.h:18
NetIO * io
Definition: ot.h:9
void rot_recv_post(block *data, const bool *r, int length)
Definition: mextension_kos.h:257
void recv(block *data, const bool *b, int length)
Definition: ot.h:13
void send_impl(const block *data0, const block *data1, int length)
Definition: mextension_kos.h:221
Definition: prg.h:16
bool block_cmp(const block *x, const block *y, int nblocks)
Definition: block.h:56
bool send_check(int length)
Definition: mextension_kos.h:140
void random_data(void *data, int nbytes)
Definition: prg.h:49
void setup_send(block *in_k0=nullptr, bool *in_s=nullptr)
Definition: mextension_kos.h:44
OTCO * base_ot
Definition: mextension_kos.h:10
PRP pi
Definition: mextension_kos.h:12
void send_block(const block *data, int nblock)
Definition: io_channel.h:132
void recv_impl(block *data, const bool *b, int length)
Definition: mextension_kos.h:228
void recv_block(block *data, int nblock)
Definition: io_channel.h:136
PRG prg
Definition: mextension_kos.h:11
Definition: ot.h:6
block bool_to128(const bool *data)
Definition: utils.hpp:76
bool * extended_r
Definition: mextension_kos.h:20
static const int DIGEST_SIZE
Definition: hash.h:17
void xorBlocks_arr(block *res, const block *x, const block *y, int nblocks)
Definition: block.h:37
~MOTExtension_KOS()
Definition: mextension_kos.h:32
void setup_recv(block *in_k0=nullptr, block *in_k1=nullptr)
Definition: mextension_kos.h:57
static void hash_once(void *digest, const void *data, int nbyte)
Definition: hash.h:49