def next_data_in(self): self.params = {"SETSIZE_C": 3, "SETSIZE_S": 3} self.client_inputs = {"X": (1, 2, 3)} self.server_inputs = {"Y": (2, 3, 4)} self.intersection = set((2, 3)) yield for i in xrange(10): randset = nogen( get_random(1, 2**state.config.asymmetric_security_parameter - 1, 100)) self.count_C = rand.randint(1, 50) self.count_S = rand.randint(1, 50) self.params = { "SETSIZE_C": self.count_C, "SETSIZE_S": self.count_S } client_inputs = set(rand.sample(randset, self.count_C)) server_inputs = set(rand.sample(randset, self.count_S)) self.client_inputs = {"X": client_inputs} self.server_inputs = {"Y": server_inputs} self.intersection = client_inputs.intersection(server_inputs) yield
def next_data_in(self): self.params = {"dim": 3, "lenX": 32, "lenY": 32} self.client_inputs = {"X": (1, 2, 3)} self.server_inputs = {"Y": (2, 3, 4)} self.result = 2 yield for i in xrange(10): self.params = { "dim": rand.randint(0, 100), "lenX": rand.randint(0, 512), "lenY": rand.randint(0, 512) } self.client_inputs = { "X": nogen( get_random(0, 2**self.params['lenX'] - 1, self.params["dim"])) } self.server_inputs = { "Y": nogen( get_random(0, 2**self.params['lenY'] - 1, self.params["dim"])) } self.result = min( map(lambda x: x[0] * x[1], zip(self.client_inputs["X"], self.server_inputs["Y"]))) yield
def generate_test_data_for_iteration(self): if self.iterations: start = rand.randint( 1, 2**state.config.asymmetric_security_parameter - 1) end = (start + 400) % 2**state.config.asymmetric_security_parameter - 1 if start > end: start, end = end, start self.count_C = rand.randint(1, 200) self.count_S = rand.randint(1, 200) self.params = { "SETSIZE_C": self.count_C, "SETSIZE_S": self.count_S } self.client_inputs = set( [rand.randint(start, end) for count in xrange(self.count_C)]) self.server_inputs = set( [rand.randint(start, end) for count in xrange(self.count_S)]) self.intersection = self.client_inputs.intersection( self.server_inputs) self.iterations -= 1 else: self.params = None
def next_data_in(self): for i in range(1, 2**8): self.params = {"la": i, "lb": i} self.client_inputs = self.server_inputs = { "a": rand.randint(0, 2**i - 1), "b": rand.randint(0, 2**i - 1) } yield
def next_data_in(self): for i in range(1, 2**8): self.params = {'la': i, 'lb': i} self.client_inputs = self.server_inputs = { 'a': rand.randint(0, 2**i - 1), 'b': rand.randint(0, 2**i - 1) } yield
def compute_r(key): """Computes random number @rtype: mpz @return: a random integer """ if isinstance(key, tasty.crypt.homomorph.paillier.gmp.generate.SecretKeyGMP): return crt_pow(rand.randint(0, long(key.n)), key.n, key) return pow(mpz(rand.randint(1, long(key.n))), key.n, key.nsq)
def __init__(self, *args): super(HomomorphicMultiplication, self).__init__(*args) #FIXME: statistic security parameter? if not self.t: HomomorphicMultiplication.t = t = state.config.symmetric_security_parameter else: t = self.t (c1, c2) = self.precomp_args[:2] if state.active_party.role == state.active_party.SERVER: self.r1 = tasty.types.Unsigned(val=rand.randint(0, (1 << c1.get_bitlen() + t + 1)-1), bitlen=c1.get_bitlen() + t + 1) self.r2 = tasty.types.Unsigned(val=rand.randint(0, (1 << c2.get_bitlen() + t + 1)-1), bitlen=c2.get_bitlen() + t + 1) self.hr1r2 = tasty.types.Homomorphic(val=-(self.r1 * self.r2), signed=True)
def next_data_in(self): for i in xrange(self.COUNT): da = rand.randint(1, self.MAXDIM) db = rand.randint(1, self.MAXDIM) la = rand.randint(1, self.MAXBITLEN) lb = rand.randint(1, self.MAXBITLEN) self.params = {'la': la, 'lb': lb, 'da': da, 'db': db} self.inputs = { 'a': tuple(get_random(1, (2**la) - 1, da)), 'b': rand.randint(1, (2**lb) - 1) } yield
def random(bitlen, signed): if signed == SIGNED: end = 1 << (bitlen - 1) start = -end else: end = 1 << bitlen start = 0 return rand.randint(start, end)
def random(self, bitlen, signed, num=1): if signed: start, end = -(2**(bitlen - 1)), 2**(bitlen - 1) - 1 else: start, end = 0, 2**bitlen - 1 if num > 1: return list(get_random(start, end, num)) else: return rand.randint(start, end)
def next_data_in(self): self.params = {"la": 32, "lb": 32} self.inputs = {"a": 0, "b": self.random(32, 0)} yield self.inputs = {"b": 0, "a": self.random(32, 1)} yield self.inputs = {"a": 0, "b": 0} yield self.inputs = {"a": 2**32 - 1, "b": 2**32 - 1} yield for i in xrange(self.COUNT): la = rand.randint(1, self.MAXBITLEN) if self.SAMEBITLEN: lb = la else: lb = rand.randint(1, self.MAXBITLEN) self.params = {'la': la, 'lb': lb} self.inputs = {'a': self.random(la, 0), 'b': self.random(lb, 1)} yield
def next_data_in(self): self.params = {"la": 32, "lb": 32} self.inputs = {"a": 0, "b": rand.randint(1, 2**32 - 1)} yield self.inputs = {"b": 0, "a": rand.randint(1, 2**32 - 1)} yield self.inputs = {"a": 0, "b": 0} yield self.inputs = {"a": 2**32 - 1, "b": 2**32 - 1} yield for i in xrange(self.COUNT): la = lb = rand.randint(1, self.MAXBITLEN) self.params = {'la': la, 'lb': lb} self.inputs = { 'a': rand.randint(1, (2**la) - 1), 'b': rand.randint(1, (2**lb) - 1) } yield
def next_data_in(self): self.params = {"la": 32, "lb": 32, "da": 8, "db": 8} self.inputs = {"a": 8 * (0, ), "b": self.get_random(32, 8, 0)} yield self.inputs = {"b": 8 * (0, ), "a": self.get_random(32, 8, 1)} yield self.inputs = {"a": 8 * (0, ), "b": 8 * (0, )} yield self.inputs = {"a": 8 * (2**32 - 1, ), "b": 8 * (2**32 - 1, )} yield for i in xrange(self.COUNT): da = rand.randint(1, self.MAXDIM) db = rand.randint(1, self.MAXDIM) la = rand.randint(1, self.MAXBITLEN) lb = rand.randint(1, self.MAXBITLEN) self.params = {'la': la, 'lb': lb, 'da': da, 'db': db} self.inputs = { 'a': self.get_random(la, da, 0), 'b': self.get_random(lb, db, 1) } yield
def find_random_prime(k): """Find a random *k* bit prime number. The prime has exactly *k* significant bits: @type k: int @param k: number of significant bits @rtype: mpz @return: prime number >>> 2 <= _find_random_prime(10) < 2**10 True """ while True: prime = gmpy.next_prime(rand.randint(2**(k - 1), 2**k - 1)) if prime < 2**k: return prime
def next_data_in(self): self.params = {"la": 32, "lb": 32, "da": 8, "db": 8} self.inputs = {"a": 8 * (0, ), "b": rand.randint(1, 2**31 - 1)} yield self.inputs = {"b": 0, "a": nogen(get_random(1, 2**31 - 1, 8))} yield self.inputs = {"a": 8 * (0, ), "b": 0} yield self.inputs = {"a": 8 * (2**31 - 1, ), "b": 2**31 - 1} yield for i in xrange(self.COUNT): da = rand.randint(1, self.MAXDIM) db = rand.randint(1, self.MAXDIM) la = rand.randint(2, self.MAXBITLEN) lb = rand.randint(2, self.MAXBITLEN) self.params = {'la': la, 'lb': lb, 'da': da, 'db': db} self.inputs = { 'a': tuple(get_random(1, max(1, (2**(la - 1)) - 1), da)), 'b': rand.randint(1, max(1, (2**(lb - 1)) - 1)) } yield
def random(self, maxbit, innum=0): if self.SIGNED[innum]: return rand.randint(-2**(maxbit - 1) - 1, 2**(maxbit - 1) - 1) else: return rand.randint(0, 2**maxbit - 1)
def Paillier_Garbled_send(src, dst, bitlen, dim, signed, force_bitlen=None, force_signed=None): if force_bitlen is not None: diff = bitlen - force_bitlen bitlen = force_bitlen else: diff = 0 masklen = bitlen + state.config.symmetric_security_parameter # p = partyAttribute if not isserver(): raise TastySyntaxError("Conversion from Homomorphic to Garbled from Client to Server does not make sense") if state.precompute: if force_signed is not None: signed = force_signed if signed: mask = Unsigned(val=rand.randint(2**bitlen - 1, 2**masklen - 1), bitlen=masklen) # generate the Homomorphic blinding mask and store else: mask = Unsigned(val=rand.randint(0, 2**masklen - 1), bitlen=masklen) hmask = tasty.types.Homomorphic(val=mask, signed=False) state.active_party.push_tmpattr(hmask) # Generate the Garbled Blinding Mask mgm = Garbled(bitlen=bitlen, signed=False, val=p) mgm.plainmask = mask # save the mask to be able to access it in online phase state.passive_party.push_tmpattr(mgm) # save the new Garbled zv = Garbled.get_zero_value(mgm.gid) mgm[:] = plain2garbled(value2bits(mask.get_value() & ((1<<bitlen) - 1), bitlen), zv, state.R) _sendcost(state.config.symmetric_security_parameter * bitlen) _send(mgm) # Precompute the garbled for the masked plain value mgv = Garbled(bitlen=bitlen, passive=True, val=p, signed=False) state.passive_party.push_tmpattr(mgv) # prepare the addition circuit to remove the mask ret = mgv.dropmsb_sub(mgm) # save shadow copy of resulting Garbled _set_dst(src, dst, ret) ret.set_bit_length(bitlen) ret._signed = False # avoid warning here else: assert signed == src.signed(), "the analyzer disagrees with the typesystems signedness" if force_signed is not None: signed = force_signed hmask = state.active_party.pop_tmpattr() mgm = state.passive_party.pop_tmpattr() state.passive_party._tmp_ = state.passive_party.pop_tmpattr() # blind the homomorphic and send to other party hval = src + hmask hval._bit_length -= diff # force_bitlen _sendcost(state.config.asymmetric_security_parameter * 2) _send(hval) # help to encrypt the masked value into Garbled state.passive_party._tmp_ = Garbled(bitlen=masklen + 1, passive=True, val=p, signed=signed) # help removing the mask ret = state.passive_party._tmp_.dropmsb_sub(mgm) # tasty calculates theoretical worst case bitlengths. Since we know better, # we can safely overwrite that _set_dst(src, dst, ret) ret.set_bit_length(bitlen) ret._signed = hval.signed()
def PaillierVec_GarbledVec_send(src, dst, source_bitlen, source_dim, signed, force_bitlen=None, force_signed=None): if force_bitlen and (force_signed or (signed and not force_signed == False)): raise NotImplementedError("forcing bitlen on signeds is not supported now") if force_bitlen is not None: diff = source_bitlen - force_bitlen source_bitlen = force_bitlen else: diff = 0 p = partyAttribute if not isserver(): raise TastySyntaxError("Conversion from Homomorphic to Garbled from Client to Server does not make sense") # number of maximal bits in content overallbitlen = _dimtimes(source_dim) * source_bitlen # we have asymmetric_security_parameter bits to pack into, but need symmetric_security_parameter bits to blind cpc = state.config.asymmetric_security_parameter - state.config.symmetric_security_parameter - 1 chunksize = cpc / source_bitlen chunkpayloadbits = chunksize * source_bitlen chunks = (overallbitlen - 1) / chunkpayloadbits + 1 lastchunksize = overallbitlen % chunkpayloadbits Homomorphic = tasty.types.Homomorphic HomomorphicVec = tasty.types.HomomorphicVec if lastchunksize: chunksizes = (chunks - 1) * (chunkpayloadbits, ) + (lastchunksize, ) else: chunksizes = chunks * (chunkpayloadbits, ) if state.precompute: if lastchunksize: masks = nogen(get_randomm(0, 2**(chunkpayloadbits + state.config.symmetric_security_parameter) - 1, chunks - 1)) + (mpz(rand.randint(0, 2**(lastchunksize + state.config.symmetric_security_parameter) - 1)),) else: masks = nogen(get_randomm(0, 2**(chunkpayloadbits + state.config.symmetric_security_parameter)- 1, chunks)) if force_signed is not None: signed = force_signed # generate Mask values umasks = nogen(Unsigned(val=v, bitlen=l + state.config.symmetric_security_parameter) for v, l in zip(masks, chunksizes)) # homomorphically encrypt masks hmasks = tuple(tasty.types.Homomorphic(val=mask, signed=False) for mask in umasks) state.active_party.push_tmpval(hmasks) # garble first chunkpayloadbits of the masks (manual construction of garbled! Voodoo!) mgms = [] for mask, chunksize in zip(masks, chunksizes): state.passive_party._tmp_ = Garbled(bitlen=chunksize, signed=False, val=p) zv = Garbled.get_zero_value(state.passive_party._tmp_.gid) state.passive_party._tmp_[:] = plain2garbled(value2bits(mask & (1<<chunksize) - 1, chunksize), zv, state.R) mgms.append(state.passive_party._tmp_) state.passive_party.push_tmpval(mgms) #raise NotImplementedError("COSTS") # _sendcost(chunks * chunksize[0] # send garbled masks to client _send(mgms) # precompute the first chunkpayloadbits for the garbled masked value mgvs = [] for chunksize in chunksizes: mgv = Garbled(bitlen=chunksize, passive=True, val=p, signed=False) state.passive_party.push_tmpattr(mgv) mgvs.append(mgv) # precompute the unmasking and unpacking rets = [] for mgv, mgm, chunksize in zip(mgvs, mgms, chunksizes): ret = mgv.unpack(mgm, source_bitlen, chunksize, signed) state.passive_party.push_tmpattr(ret) rets.extend(ret) rets.reverse() # packing works exactly in the oposite direction then unpacking, so reverse here to get original result back vec = GarbledVec(bitlen=source_bitlen, dim=source_dim, val=rets) # save shadow copy of resulting GarbledVec _set_dst(src, dst, vec) else: # online phase assert signed == src.signed(), "the analyzer disagrees with the typesystems signedness" if force_signed is not None: signed = force_signed if not isserver(): raise TastySyntaxError("Conversion from Homomorphic to Garbled from Client to Server does not make sense") # Pack the values with respecting the force_signed and force_bitlen hmasks = state.active_party.pop_tmpval() if force_signed is not None: # we must change it to the forced sign origsigned = src.signed() src._signed = force_signed for i in src: i._signed = force_signed packed, _, _ = src.pack(-(state.config.symmetric_security_parameter + 1), force_bitlen=force_bitlen) if force_signed is not None: # no change in the source, so revert changes done before pack() src._signed = origsigned for i in src: i._signed = origsigned assert len(packed) == len(hmasks), "packing error (%d packed chunks, but %d expected (%r, %r))"%(len(packed), len(hmasks), hmasks, packed) # mask the packed values for i, j in zip(packed, hmasks): i += j # send packed values to client _send(packed) # retrive garbled masks from tmpval-stack mgms = state.passive_party.pop_tmpval() # passive part for generation of garbled masked values mgvs = [] for chunksize in chunksizes: state.passive_party._tmp_ = state.passive_party.pop_tmpattr() state.passive_party._tmp_ = Garbled(val=p, bitlen=chunksize, passive=True, signed=False) mgvs.append(state.passive_party._tmp_) # passive part of unblinding and unpacking # rets = [] for mgm, mgv, chunksize in zip(mgms, mgvs, chunksizes): state.passive_party._tmp_ = state.passive_party.pop_tmpattr()
def generate_random_set(max_number, num): ' generate a random set with num entries in the r ange between 0 and max_number ' s = set() while len(s) < num: s.add(rand.randint(0, max_number)) return s
def PaillierVec_GarbledVec_receive(src, dst, source_bitlen, source_dim, signed, force_bitlen=None, force_signed=None): p = partyAttribute if force_bitlen and (force_signed or (signed and not force_signed == False)): raise NotImplementedError("forcing bitlen on signeds is not supported now") if force_bitlen: source_bitlen = force_bitlen overallbitlen = reduce(operator.mul, source_dim, 1) * source_bitlen cpc = state.config.asymmetric_security_parameter - state.config.symmetric_security_parameter - 1 chunksize = (cpc - 1) / source_bitlen chunkpayloadbits = chunksize * source_bitlen chunks = (overallbitlen - 1) / chunkpayloadbits + 1 lastchunksize = overallbitlen % (chunksize * source_bitlen) if lastchunksize: chunksizes = (chunks - 1) * (chunkpayloadbits, ) + (lastchunksize, ) masks = nogen(get_randomm(0, 2**(chunkpayloadbits + state.config.symmetric_security_parameter) - 1, chunks - 1)) + (mpz(rand.randint(0, 2**(lastchunksize + state.config.symmetric_security_parameter) - 1)),) else: chunksizes = chunks * (chunkpayloadbits, ) masks = nogen(get_randomm(0, 2**(chunkpayloadbits + state.config.symmetric_security_parameter)- 1, chunks)) if state.precompute: if force_signed is not None: signed = force_signed # receive garbled Mask mgms = _receive(src, dst) for mgm, size in zip(mgms, chunksizes): mgm._bit_length = size # prepare for creation of garbled masked plain value state.active_party.push_tmpval(mgms) # precompute first chunkpayloadbits for the garbled masked value mgvs = [] for i in chunksizes: mgv = Garbled(bitlen=i, val=p, signed=False) state.passive_party.push_tmpattr(mgv) mgvs.append(mgv) # precompute the unmasking and unpacking rets = [] for mgv, mgm, chunksize in zip (mgvs, mgms, chunksizes): ret = mgv.unpack(mgm, source_bitlen, chunksize, signed) state.active_party.push_tmpattr(ret) rets.extend(ret) rets.reverse() vec = GarbledVec(bitlen=source_bitlen, dim=source_dim, val=rets, signed=signed) # save shadow copy of resulting GarbledVec _set_dst(src, dst, vec) else: # online phase if force_signed is not None: signed = force_signed if not isclient(): raise TastySyntaxError("Conversion from Homomorphic to Garbled from Client to Server does not make sense") # receive masked homomorphic values mhvs = _receive() for i, chunksize in zip(mhvs, chunksizes): i._bit_length = chunksize # decrypt masked garbled values mvs = nogen(Unsigned(val=i) for i in mhvs) # get the masked garbled values from tmpval-stack mgms = state.active_party.pop_tmpval() # compute first chunksize bits of garbled masked values mgvs = [] for mv, chunksize in zip(mvs, chunksizes): state.passive_party._tmp_ = mgv = state.passive_party.pop_tmpattr() mv._value &= (1<<chunksize) - 1 mv.set_bit_length(chunksize) state.passive_party._tmp_ = Garbled(val=mv, bitlen=chunksize, signed=signed) mgvs.append(state.passive_party._tmp_) # unpacking and unblinding rets = [] for mgm, mgv, chunksize in zip(mgms, mgvs, chunksizes): state.active_party._tmp_ = state.active_party.pop_tmpattr() state.active_party._tmp_ = mgv.unpack(mgm, source_bitlen, chunksize, signed) rets.extend(state.active_party._tmp_) rets.reverse() vec = GarbledVec(bitlen=source_bitlen, dim=source_dim, val=rets, signed = rets[0].signed()) _set_dst(src, dst, vec)
def test_UnpackCircuit(self): """ testing UnpackCircuit """ def pack(values, bitlen, signed): """ pack values """ assert signed == SIGNED or not filter(lambda x: x < 0, values) ret = 0 for val in values: if signed == SIGNED: val += (1 << (bitlen - 1)) ret <<= bitlen ret += val return ret def random(bitlen, signed): if signed == SIGNED: end = 1 << (bitlen - 1) start = -end else: end = 1 << bitlen start = 0 return rand.randint(start, end) def mask(length): return random(length + 80, False) def test(self, values, bitlen, signed, m=None): values = list(values) num = len(values) totallength = num * bitlen tmask = (1 << totallength) - 1 c = UnpackCircuit(bitlen, num, signed) c.check() packed = pack(values, bitlen, signed) if m is None: m = mask(num * bitlen) packed += m ret = c.eval((packed & tmask, m & tmask)) if signed == SIGNED: f = lambda x: int(comp22int(x, bitlen)) else: f = lambda x: int(x) x = [f(i) for i in reversed(ret)] self.assertEqual(x, values) # TODO: Add tests for impossbile conditions # brute force for 1 to 3 bit values and 2 to 4bit signed values tests = 10 for bitlen in xrange(1, 4): for num in xrange(1, 4): for values in product(xrange(1 << bitlen), repeat=num): for r in xrange(1 << (bitlen * num)): test(self, values, bitlen, UNSIGNED, r) val = map(lambda x: x - 2**(bitlen - 1), values) test(self, val, bitlen, SIGNED, r) # random tests for i in xrange(tests): num = rand.randint(1, 50) bitlen = rand.randint(1, 1024) signed = rand.sample((SIGNED, UNSIGNED), 1)[0] values = [random(bitlen, signed) for i in xrange(num)] test(self, values, bitlen, signed)