emp-toolkit
integer.hpp
Go to the documentation of this file.
1 //https://github.com/samee/obliv-c/blob/obliv-c/src/ext/oblivc/obliv_bits.c#L1487
2 inline void add_full(Bit* dest, Bit * carryOut, const Bit * op1, const Bit * op2,
3  const Bit * carryIn, int size) {
4  Bit carry, bxc, axc, t;
5  int skipLast;
6  int i = 0;
7  if(size==0) {
8  if(carryIn && carryOut)
9  *carryOut = *carryIn;
10  return;
11  }
12  if(carryIn)
13  carry = *carryIn;
14  else
15  carry = false;
16  // skip AND on last bit if carryOut==NULL
17  skipLast = (carryOut == nullptr);
18  while(size-->skipLast) {
19  axc = op1[i] ^ carry;
20  bxc = op2[i] ^ carry;
21  dest[i] = op1[i] ^ bxc;
22  t = axc & bxc;
23  carry =carry^t;
24  ++i;
25  }
26  if(carryOut != nullptr)
27  *carryOut = carry;
28  else
29  dest[i] = carry ^ op2[i] ^ op1[i];
30 }
31 inline void sub_full(Bit * dest, Bit * borrowOut, const Bit * op1, const Bit * op2,
32  const Bit * borrowIn, int size) {
33  Bit borrow,bxc,bxa,t;
34  int skipLast; int i = 0;
35  if(size==0) {
36  if(borrowIn && borrowOut)
37  *borrowOut = *borrowIn;
38  return;
39  }
40  if(borrowIn)
41  borrow = *borrowIn;
42  else
43  borrow = false;
44  // skip AND on last bit if borrowOut==NULL
45  skipLast = (borrowOut == nullptr);
46  while(size-- > skipLast) {
47  bxa = op1[i] ^ op2[i];
48  bxc = borrow ^ op2[i];
49  dest[i] = bxa ^ borrow;
50  t = bxa & bxc;
51  borrow = borrow ^ t;
52  ++i;
53  }
54  if(borrowOut != nullptr) {
55  *borrowOut = borrow;
56  }
57  else
58  dest[i] = op1[i] ^ op2[i] ^ borrow;
59 }
60 inline void mul_full(Bit * dest, const Bit * op1, const Bit * op2, int size) {
61  // OblivBit temp[MAX_BITS]={},sum[MAX_BITS]={};
62  Bit * sum = new Bit[size];
63  Bit * temp = new Bit[size];
64  for(int i = 0; i < size; ++i)sum[i]=false;
65  for(int i=0;i<size;++i) {
66  for (int k = 0; k < size-i; ++k)
67  temp[k] = op1[k] & op2[i];
68  add_full(sum+i, nullptr, sum+i, temp, nullptr, size-i);
69  }
70  memcpy(dest, sum, sizeof(Bit)*size);
71  delete[] sum;
72  delete[] temp;
73 }
74 
75 inline void ifThenElse(Bit * dest, const Bit * tsrc, const Bit * fsrc,
76  int size, Bit cond) {
77  Bit x, a;
78  int i = 0;
79  while(size-- > 0) {
80  x = tsrc[i] ^ fsrc[i];
81  a = cond & x;
82  dest[i] = a ^ fsrc[i];
83  ++i;
84  }
85 }
86 inline void condNeg(Bit cond, Bit * dest, const Bit * src, int size) {
87  int i;
88  Bit c = cond;
89  for(i=0; i < size-1; ++i) {
90  dest[i] = src[i] ^ cond;
91  Bit t = dest[i] ^ c;
92  c = c & dest[i];
93  dest[i] = t;
94  }
95  dest[i] = cond ^ c ^ src[i];
96 }
97 
98 inline void div_full(Bit * vquot, Bit * vrem, const Bit * op1, const Bit * op2,
99  int size) {
100  Bit * overflow = new Bit[size];
101  Bit * temp = new Bit[size];
102  Bit * rem = new Bit[size];
103  Bit * quot = new Bit[size];
104  Bit b;
105  memcpy(rem, op1, size*sizeof(Bit));
106  overflow[0] = false;
107  for(int i = 1; i < size;++i)
108  overflow[i] = overflow[i-1] | op2[size-i];
109  // skip AND on last bit if borrowOut==NULL
110  for(int i = size-1; i >= 0; --i) {
111  sub_full(temp, &b, rem+i, op2, nullptr, size-i);
112  b = b | overflow[i];
113  ifThenElse(rem+i,rem+i,temp,size-i,b);
114  quot[i] = !b;
115  }
116  if(vrem != nullptr) memcpy(vrem, rem, size*sizeof(Bit));
117  if(vquot != nullptr) memcpy(vquot, quot, size*sizeof(Bit));
118  delete[] overflow;
119  delete[] temp;
120  delete[] rem;
121  delete[] quot;
122 }
123 
124 
125 inline void init(Bit * bits, const bool* b, int length, int party) {
126  block * bbits = (block *) bits;
127  if (party == PUBLIC) {
128  block one = local_gc->public_label(true);
129  block zero = local_gc->public_label(false);
130  for(int i = 0; i < length; ++i)
131  bbits[i] = b[i] ? one : zero;
132  }
133  else {
134  local_backend->Feed((block *)bits, party, b, length);
135  }
136 }
137 
138 /*inline Integer::Integer(const bool * b, int length, int party) {
139  bits = new Bit[length];
140  init(bits,b,length, party);
141  }*/
142 
143 inline Integer::Integer(int len, const string& str, int party) : length(len) {
144  bool* b = new bool[len];
145  bool_data(b, len, str);
146  bits = new Bit[length];
147  init(bits,b,length, party);
148  delete[] b;
149 }
150 
151 inline Integer::Integer(int len, long long input, int party)
152  : Integer(len, std::to_string(input), party) {
153  }
154 
155 inline Integer Integer::select(const Bit & select, const Integer & a) const{
156  Integer res(*this);
157  for(int i = 0; i < size(); ++i)
158  res[i] = bits[i].select(select, a[i]);
159  return res;
160 }
161 
162 inline Bit& Integer::operator[](int index) {
163  return bits[min(index, size()-1)];
164 }
165 
166 inline const Bit &Integer::operator[](int index) const {
167  return bits[min(index, size()-1)];
168 }
169 
170 template<>
171 inline string Integer::reveal<string>(int party) const {
172  bool * b = new bool[length];
174  string bin="";
175  for(int i = length-1; i >= 0; --i)
176  bin += (b[i]? '1':'0');
177  delete [] b;
178  return bin_to_dec(bin);
179 }
180 
181 template<>
182 inline int Integer::reveal<int>(int party) const {
183  string s = reveal<string>(party);
184  return stoi(s);
185 }
186 template<>
187 inline uint32_t Integer::reveal<uint32_t>(int party) const {
188  Integer tmp = *this;
189  tmp.resize(tmp.size()+1, false);
190  string s = tmp.reveal<string>(party);
191  return stoi(s);
192 }
193 
194 
195 template<>
196 inline long long Integer::reveal<long long>(int party) const {
197  string s = reveal<string>(party);
198  return stoll(s);
199 }
200 
201 
202 
203 inline int Integer::size() const {
204  return length;
205 }
206 
207 //circuits
208 inline Integer Integer::abs() const {
209  Integer res(*this);
210  for(int i = 0; i < size(); ++i)
211  res[i] = bits[size()-1];
212  return ( (*this) + res) ^ res;
213 }
214 
215 inline Integer& Integer::resize(int len, bool signed_extend) {
216  Bit * old = bits;
217  bits = new Bit[len];
218  memcpy(bits, old, min(len, size())*sizeof(Bit));
219  Bit extended_bit = old[length-1] & signed_extend;
220  for(int i = min(len, size()); i < len; ++i)
221  bits[i] = extended_bit;
222  this->length = len;
223  delete[] old;
224  return *this;
225 }
226 
227 //Logical operations
228 inline Integer Integer::operator^(const Integer& rhs) const {
229  Integer res(*this);
230  for(int i = 0; i < size(); ++i)
231  res.bits[i] = res.bits[i] ^ rhs.bits[i];
232  return res;
233 }
234 
235 inline Integer Integer::operator|(const Integer& rhs) const {
236  Integer res(*this);
237  for(int i = 0; i < size(); ++i)
238  res.bits[i] = res.bits[i] | rhs.bits[i];
239  return res;
240 }
241 
242 inline Integer Integer::operator&(const Integer& rhs) const {
243  Integer res(*this);
244  for(int i = 0; i < size(); ++i)
245  res.bits[i] = res.bits[i] & rhs.bits[i];
246  return res;
247 }
248 
249 inline Integer Integer::operator<<(int shamt) const {
250  Integer res(*this);
251  if(shamt > size()) {
252  for(int i = 0; i < size(); ++i)
253  res.bits[i] = false;
254  }
255  else {
256  for(int i = size()-1; i >= shamt; --i)
257  res.bits[i] = bits[i-shamt];
258  for(int i = shamt-1; i>=0; --i)
259  res.bits[i] = false;
260  }
261  return res;
262 }
263 
264 inline Integer Integer::operator>>(int shamt) const {
265  Integer res(*this);
266  if(shamt >size()) {
267  for(int i = 0; i < size(); ++i)
268  res.bits[i] = false;
269  }
270  else {
271  for(int i = shamt; i < size(); ++i)
272  res.bits[i-shamt] = bits[i];
273  for(int i = size()-shamt; i < size(); ++i)
274  res.bits[i] = false;
275  }
276  return res;
277 }
278 
279 inline Integer Integer::operator<<(const Integer& shamt) const {
280  Integer res(*this);
281  for(int i = 0; i < min(int(ceil(log2(size()))) , shamt.size()-1); ++i)
282  res = res.select(shamt[i], res<<(1<<i));
283  return res;
284 }
285 
286 inline Integer Integer::operator>>(const Integer& shamt) const{
287  Integer res(*this);
288  for(int i = 0; i <min(int(ceil(log2(size()))) , shamt.size()-1); ++i)
289  res = res.select(shamt[i], res>>(1<<i));
290  return res;
291 }
292 
293 //Comparisons
294 inline Bit Integer::geq (const Integer& rhs) const {
295 /* Bit res(false);
296  for(int i = 0; i < size(); ++i) {
297  res = ((bits[i]^res)&(rhs[i]^res))^bits[i];
298  }
299  return res;
300 */
301  Integer tmp = (*this) - rhs;
302  return !tmp[tmp.size()-1];
303 }
304 
305 inline Bit Integer::equal(const Integer& rhs) const {
306  Bit res(true);
307  for(int i = 0; i < size(); ++i)
308  res = res & (bits[i] == rhs[i]);
309  return res;
310 }
311 
312 /* Arithmethics
313  */
314 inline Integer Integer::operator+(const Integer & rhs) const {
315  Integer res(*this);
316  add_full(res.bits, nullptr, bits, rhs.bits, nullptr, size());
317  return res;
318 }
319 
320 inline Integer Integer::operator-(const Integer& rhs) const {
321  Integer res(*this);
322  sub_full(res.bits, nullptr, bits, rhs.bits, nullptr, size());
323  return res;
324 }
325 
326 
327 inline Integer Integer::operator*(const Integer& rhs) const {
328  Integer res(*this);
329  mul_full(res.bits, bits, rhs.bits, size());
330  return res;
331 }
332 
333 inline Integer Integer::operator/(const Integer& rhs) const {
334  Integer res(*this);
335  Integer i1 = abs();
336  Integer i2 = rhs.abs();
337  Bit sign = bits[size()-1] ^ rhs[size()-1];
338  div_full(res.bits, nullptr, i1.bits, i2.bits, size());
339  condNeg(sign, res.bits, res.bits, size());
340  return res;
341 }
342 inline Integer Integer::operator%(const Integer& rhs) const {
343  Integer res(*this);
344  Integer i1 = abs();
345  Integer i2 = rhs.abs();
346  Bit sign = bits[size()-1];
347  div_full(nullptr, res.bits, i1.bits, i2.bits, size());
348  condNeg(sign, res.bits, res.bits, size());
349  return res;
350 }
351 
352 inline Integer Integer::operator-() const {
353  return Integer(size(), 0, PUBLIC)-(*this);
354 }
355 
356 //Others
358  Integer res = *this;
359  for(int i = size() - 2; i>=0; --i)
360  res[i] = res[i+1] | res[i];
361 
362  for(int i = 0; i < res.size(); ++i)
363  res[i] = !res[i];
364  return res.hamming_weight();
365 }
366 
368  vector<Integer> vec;
369  for(int i = 0; i < size(); i++) {
370  Integer tmp(2, 0, PUBLIC);
371  tmp[0] = bits[i];
372  vec.push_back(tmp);
373  }
374 
375  while(vec.size() > 1) {
376  int j = 0;
377  for(size_t i = 0; i < vec.size()-1; i+=2) {
378  vec[j++] = vec[i]+vec[i+1];
379  }
380  if(vec.size()%2 == 1) {
381  vec[j++] = vec[vec.size()-1];
382  }
383  for(int i = 0; i < j; ++i)
384  vec[i].resize(vec[i].size()+1, false);
385  int vec_size = vec.size();
386  for(int i = j; i < vec_size; ++i)
387  vec.pop_back();
388  }
389  return vec[0];
390 }
392  // the value of q should be less than half of the MAX_INT
393  Integer base = *this;
394  Integer res(1, size());
395  for(int i = 0; i < p.size(); ++i) {
396  Integer tmp = (res * base) % q;
397  res.select(p[i], tmp);
398  base = (base*base) % q;
399  }
400  return res;
401 }
Bit equal(const Integer &rhs) const
Definition: integer.hpp:305
__m128i block
Definition: block.h:8
void div_full(Bit *vquot, Bit *vrem, const Bit *op1, const Bit *op2, int size)
Definition: integer.hpp:98
Integer operator+(const Integer &rhs) const
Definition: integer.hpp:314
Bit geq(const Integer &rhs) const
Definition: integer.hpp:294
block public_label(bool b)
Definition: garble_circuit.h:18
void sub_full(Bit *dest, Bit *borrowOut, const Bit *op1, const Bit *op2, const Bit *borrowIn, int size)
Definition: integer.hpp:31
Integer operator/(const Integer &rhs) const
Definition: integer.hpp:333
Integer operator*(const Integer &rhs) const
Definition: integer.hpp:327
void Reveal(bool *out, int party, const block *lbls, int nel)
Definition: backend.h:15
Integer & resize(int length, bool signed_extend=true)
Definition: integer.hpp:215
string bin_to_dec(const string &bin2)
Definition: utils.h:82
Integer operator|(const Integer &rhs) const
Definition: integer.hpp:235
Bit & operator[](int index)
Definition: integer.hpp:162
#define PUBLIC
Definition: utils.h:14
static void bool_data(bool *data, size_t len, long long num)
Definition: integer.h:82
Integer operator>>(int shamt) const
Definition: integer.hpp:264
Integer abs() const
Definition: integer.hpp:208
Integer operator^(const Integer &rhs) const
Definition: integer.hpp:228
void Feed(block *lbls, int party, const bool *b, int nel)
Definition: backend.h:12
Integer()
Definition: integer.h:40
int size() const
Definition: integer.hpp:203
Definition: integer.h:14
void ifThenElse(Bit *dest, const Bit *tsrc, const Bit *fsrc, int size, Bit cond)
Definition: integer.hpp:75
Integer operator &(const Integer &rhs) const
Integer operator<<(int shamt) const
Definition: integer.hpp:249
Integer modExp(Integer p, Integer q)
Definition: integer.hpp:391
Integer leading_zeros() const
Definition: integer.hpp:357
Definition: bit.h:8
Integer hamming_weight() const
Definition: integer.hpp:367
Backend * local_backend
Definition: backend.cpp:7
int length
Definition: integer.h:15
Integer operator%(const Integer &rhs) const
Definition: integer.hpp:342
O reveal(int party=PUBLIC) const
void add_full(Bit *dest, Bit *carryOut, const Bit *op1, const Bit *op2, const Bit *carryIn, int size)
Definition: integer.hpp:2
Integer select(const Bit &sel, const Integer &rhs) const
Definition: integer.hpp:155
int party
Definition: input-check-malicious.cpp:12
void condNeg(Bit cond, Bit *dest, const Bit *src, int size)
Definition: integer.hpp:86
Bit * bits
Definition: integer.h:16
GarbleCircuit * local_gc
Definition: backend.cpp:8
void mul_full(Bit *dest, const Bit *op1, const Bit *op2, int size)
Definition: integer.hpp:60
Integer operator-() const
Definition: integer.hpp:352
void init(Bit *bits, const bool *b, int length, int party)
Definition: integer.hpp:125