def _bit_lt(self, a, b_bits): d_vals = [] a_bits = [] for bit in bin(a)[2:]: a_bits.append(int(bit) * self.scale) a_bits = [0] * (len(b_bits) - len(a_bits)) + a_bits for i in range(len(a_bits)): d_val = b_bits[i].const_add(a_bits[i]) d_val += b_bits[i].const_mult(-2 * a_bits[i]) d_vals.append(d_val.const_add(1 * self.scale)) p_vals = self._premul(d_vals) p_vals.reverse() s_vals = [] for i in range(len(p_vals) - 1): s_val = p_vals[i] + p_vals[i + 1].const_mult(-1, scaled=False) s_vals.append(s_val) s_vals.append(p_vals[-1].const_add(-1, scaled=False)) a_bits.reverse() s = Share(0, 0, mod=self.mod, fp_prec=self.fpp) slen = len(s_vals) for i in range(slen): s += s_vals[i].const_mult(self.scale - a_bits[i]) ret_val = self._mod2(s, len(b_bits)) return ret_val
def _multiply(self, share1, share2): if self.random_index >= len(self.randomness): raise Exception( 'Randomness for multiplicaiton exhausted. Please generate more randomness.' ) rand_value = self.randomness[self.random_index] r = share1.pre_mult(share2, rand_value) new_r = self._interact(r) return Share(new_r - r, -2 * new_r - r, mod=self.mod, fp_prec=self.fpp)
def test_switch_precision(share, old_prec, new_prec, mod, expected): a = randint(0, mod - 1) b = randint(0, mod - 1) c = (-(a + b)) % mod share1 = Share(a, c - share, mod=mod, fp_prec=old_prec) share2 = Share(b, a - share, mod=mod, fp_prec=old_prec) share1_new = share1.switch_precision(new_prec) share2_new = share2.switch_precision(new_prec) assert expected == (share1_new.unshare(share2_new) % mod)
def test_const_add(share, const, mod, expected): a = randint(0, mod - 1) b = randint(0, mod - 1) c = (-(a + b)) % mod share1 = Share(a, c - share, mod=mod, fp_prec=0) share2 = Share(b, a - share, mod=mod, fp_prec=0) share1_add = share1.const_add(const) share2_add = share2.const_add(const) assert expected == (share1_add.unshare(share2_add) % mod)
def _dot(self, gate): gid = gate.get_id() [xvec, yvec] = gate.get_inputs() gate_output = self.circuit[gid] z_val = Share(0, 0, mod=self.mod, fp_prec=self.fpp) for i in range(len(xvec)): x_val = xvec[i] y_val = yvec[i] z_val += self._multiply(x_val, y_val) self.random_index += 1 for gout in gate_output: gout.add_input(gid, z_val) if gout.is_ready(): self.q.put(gout)
def test_const_add_scale(share, const, mod, fpp, expected): scale = 10**fpp share = share * scale a = randint(0, mod - 1) b = randint(0, mod - 1) c = (-(a + b)) % mod share1 = Share(a, c - share, mod=mod, fp_prec=fpp) share2 = Share(b, a - share, mod=mod, fp_prec=fpp) share1_add = share1.const_add(const, scaled=False) share2_add = share2.const_add(const, scaled=False) assert expected * scale == (share1_add.unshare(share2_add) % mod)
def _make_shares(self, input_value, random=False): it = type(input_value) if (it == int) or (it == np.int64) or (it == np.float64) or (it == float): val = int(input_value * self.scale) % self.mod # first generate three random values a, b, c s.t. a + b + c = 0 #a = int(randint(0,self.mod-1) ) #b = int(randint(0,self.mod-1) ) #c = (- (a + b)) % self.mod a = int( randint(0, math.floor(self.mod / self.scale) - 1) * self.scale) b = int( randint(0, math.floor(self.mod / self.scale) - 1) * self.scale) c = (-(a + b)) % self.mod if random: share1 = a share2 = b share3 = c else: #share1 = (a,c-val) #share2 = (b,a-val) #share3 = (c,b-val) share1 = Share(a, c - val, mod=self.mod, fp_prec=self.fpp) share2 = Share(b, a - val, mod=self.mod, fp_prec=self.fpp) share3 = Share(c, b - val, mod=self.mod, fp_prec=self.fpp) else: share1 = [] share2 = [] share3 = [] for val in input_value: mod_val = int(round(val * self.scale)) % self.mod # first generate three random values a, b, c s.t. a + b + c = 0 #a = int(randint(0,self.mod-1)) #b = int(randint(0,self.mod-1)) #c = (- (a + b)) % self.mod a = int( randint(0, math.floor(self.mod / self.scale) - 1) * self.scale) b = int( randint(0, math.floor(self.mod / self.scale) - 1) * self.scale) c = (-(a + b)) % self.mod if random: share1.append(a) share2.append(b) share3.append(c) else: share1.append( Share(a, c - mod_val, mod=self.mod, fp_prec=self.fpp)) share2.append( Share(b, a - mod_val, mod=self.mod, fp_prec=self.fpp)) share3.append( Share(c, b - mod_val, mod=self.mod, fp_prec=self.fpp)) return (share1, share2, share3)
def test_eq(share1, share2, mod, fpp, expected): shr1 = Share(share1[0], share1[1], mod=mod, fp_prec=fpp) shr2 = Share(share2[0], share2[1], mod=mod, fp_prec=fpp) assert (shr1 == shr2) == expected