def receiver_online1(self, args): """ self.args is expected to be a list of one-bit integers """ # receive C and rG from sender args = tuple(args) self.C = C = decompressPoint(args[0], self.EC) self.rG = decompressPoint(args[1], self.EC) self.idx = utils.nogen(self.args) G = self.G order = self.EC.getOrder() compress = self.compress self.s = ss = [] #Communication costs in this round: one ECPoint per bit in self.args cost_results.CostSystem.costs["theoretical"]["setup"]["accumulated"]( Send=utils.bit2byte(len(self.idx) * self.comCostsECPoint)) for i in self.idx: s = utils.rand.randint(1, order) ss.append(s) PK = G * s PK.compress = compress if i == 0: yield PK else: PK2 = C - PK PK2.compress = compress yield PK2
def server_1(self, args): gc.disable() s = list(utils.get_random(0, 1, self.k)) m = len(self.args) if m <= state.config.symmetric_security_parameter: # IKNP03 does not make sense if m <= symmetric_security_parameter # Use the subot directly then. self.subot.forward() self.subot(self.args) return None self.subot(s) tmp = [utils.value2bits(res, m) for res in self.subot.get_results()] Q = zip(*tmp) # transpose tmp del tmp si = utils.bits2value(s) q = [utils.bits2value(j) for j in Q] cost_results.CostSystem.costs["theoretical"]["setup"]["accumulated"]( Send=2 * utils.bit2byte(state.config.symmetric_security_parameter) * m) gc.enable() return (((xj0 ^ self.H(j, qj)).binary(), (xj1 ^ self.H(j, qj ^ si)).binary()) for (j, qj), (xj0, xj1) in zip(enumerate(q), self.args))
def server_round1(self, args): """Additively blinds the homomorphic values and sends them to client. """ # we send at least one ciphertext cost_results.CostSystem.costs["theoretical"]["online"]["accumulated"](Send=utils.bit2byte(2*state.config.asymmetric_security_parameter)) c1, c2 = self.args self.rbitlen = c1.bit_length() + c2.bit_length() if ((c1.get_bitlen() + c2.get_bitlen() + 2*self.t) < state.config.asymmetric_security_parameter): if not (c1.signed() or c2.signed()): c = ((c1 + self.r1) * tasty.types.Unsigned(val=1<<(c2.get_bitlen() + self.t + 1), bitlen=c2.get_bitlen() + self.t + 1, signed=False) + (c2 + self.r2)) + tasty.types.Homomorphic(val=mpz(0), bitlen=0, signed=False) return (c, c1.get_bitlen(), c2.get_bitlen()) else: raise NotImplementedError("We do not pack signeds yet") # we send two ciphertexts now cost_results.CostSystem.costs["theoretical"]["online"]["accumulated"](Send=utils.bit2byte(2*state.config.asymmetric_security_parameter)) return (c1 + self.r1, c2 + self.r2)
def server_online2(self, args): cost_results.CostSystem.costs["theoretical"]["online"]["accumulated"]( Send=utils.bit2byte( len(self.args[0]) * 2 * state.config.symmetric_security_parameter)) args = tuple(args) x = tuple(((prec_m[0] ^ m[1 - int(b)]).binary(), (prec_m[1] ^ m[int(b)]).binary()) for b, m, prec_m in zip(args[0], *self.args)) return (x, )
def client_online1(self, args): """ self.args is a tuple containing: ( list of wanted bits, list of random bits, chosen at precomputation time, list of values received from the Server at runtime ) args is empty (first round) """ b, prec_b = self.args[:2] cost_results.CostSystem.costs["theoretical"]["online"]["accumulated"]( Send=utils.bit2byte(len(b))) return (tuple(i == j for i, j in zip(b, prec_b)), )
def sender_online0(self, args): k = utils.rand.randint(1, self.EC.getOrder()) self.C = self.G * k self.C.compress = self.compress self.r = r = utils.rand.randint(1, self.EC.getOrder()) self.rG = self.G * r self.rG.compress = self.compress self.rC = self.C * r cost_results.CostSystem.costs["theoretical"]["setup"]["accumulated"]( Send=utils.bit2byte(2 * self.comCostsECPoint)) yield self.C yield self.rG
def sender_online2(self, args): """ self.args is expected to be a list of message-tuples """ args = tuple(args) self.args = utils.nogen(self.args) r = self.r rC = self.rC #TODO: PLEASE FIX COSTS !!! #communication costs: # at the moment we sent 256 bit chunks. so the bits needed to transmit a message is # ceil(bitlen(msg)/256) * 256 costs = 0 for msg in self.args: costs += int(math.ceil(mpz(msg[0]).bit_length() / 256.0)) * 256 costs += int(math.ceil(mpz(msg[1]).bit_length() / 256.0)) * 256 cost_results.CostSystem.costs["theoretical"]["setup"]["accumulated"]( Send=utils.bit2byte(costs)) for i, (m0, m1) in enumerate(self.args): PK = decompressPoint(args[i], self.EC) PK0r = PK * r PK1r = rC - PK0r # digest0 = "" # digest1 = "" chunks = ((utils.bitlength(max(m0, m1)) - 1) // 256) + 1 cost_results.CostSystem.costs["theoretical"]["setup"][ "accumulated"](SHA256=2 * chunks) key0 = cPickle.dumps((PK0r, "0"), protocol=2) key1 = cPickle.dumps((PK1r, "1"), protocol=2) digest0 = "".join( hashlib.sha256(key0 + mpz(j).binary()).digest() for j in xrange(chunks)) digest1 = "".join( hashlib.sha256(key1 + mpz(j).binary()).digest() for j in xrange(chunks)) # for j in xrange(chunks): # sj = mpz(j).binary() # digest0 += hashlib.sha256(key0 + sj).digest() # digest1 += hashlib.sha256(key1 + sj).digest() #TODO: truncate digest0 and digest1 to same length as m0 and m1 !!! h0 = abs(mpz(digest0, 256)) ^ m0 h1 = abs(mpz(digest1, 256)) ^ m1 yield (h0.binary(), h1.binary())
def client_round1(self, args): """ """ args = tuple(args) if isinstance(args[1], tasty.types.HomomorphicType): for new, precomp in zip(args, self.precomp_args): new._bit_length = precomp._bit_length + self.t + 1 x = tasty.types.Signed(val=args[0]) y = tasty.types.Signed(val=args[1]) else: #packed c, l1, l2 = args c._bit_length = l1 + l2 + 2 * self.t + 2 p = tasty.types.Unsigned(val=c).get_value() y = tasty.types.Unsigned(val=(p & ((1<<(self.t + l2 + 1)) - 1)), bitlen=l2 + self.t + 1) x = tasty.types.Unsigned(val=(p >> (self.t + l2 + 1)), bitlen=l1 + self.t + 1) cost_results.CostSystem.costs["theoretical"]["online"]["accumulated"](Send=utils.bit2byte(2*state.config.asymmetric_security_parameter)) return (tasty.types.Homomorphic(val=(x * y), signed=False),)
def server_round1(self, args): m1, m2 = self.args[:2] # print m1, m2 t1 = tasty.types.HomomorphicVec(val=m1) t2 = tasty.types.HomomorphicVec(val=m2) #generate copys to not operate on original data self.t1bitlen = t1.bit_length() self.t2bitlen = t2.bit_length() self.t1dim = t1.dim() self.blindings = t1.blind() p1 = t1.pack() self.blindings2 = t2.blind() p2 = t2.pack() chunks = len(p1[0]) + len(p2[0]) cost_results.CostSystem.costs["theoretical"]["online"]["accumulated"](Send=utils.bit2byte(4*state.config.asymmetric_security_parameter * chunks)) return (p1, p2)
def client_online1(self, args): """ args is empty (no previous messages) self.args is expected to be a list of one-bit integers returns generator function for encrypted bits """ pk, sk = Gen(state.config.asymmetric_security_parameter) self.sk = sk yield pk size = 0 size = utils.bit2byte(2*state.config.asymmetric_security_parameter + len(self.args) * state.config.asymmetric_security_parameter * 2) if state.precompute: cost_results.CostSystem.costs["theoretical"]["setup"]["accumulated"](Send=size) else: cost_results.CostSystem.costs["theoretical"]["online"]["accumulated"](Send=size) for i in self.args: yield Enc(i, pk).binary()
def server_online2(self, args): """ args[0] = key args[1] = list of encrypted bit values self.args is expected to be a list of message-tuples returns generator function for encrypted messages """ args = list(args) key = args.pop(0) size = utils.bit2byte(len(self.args) * state.config.asymmetric_security_parameter * 2) if state.precompute: cost_results.CostSystem.costs["theoretical"]["setup"]["accumulated"](Send=size) else: cost_results.CostSystem.costs["theoretical"]["online"]["accumulated"](Send=size) return (add(mul(mpz(cb, 256), m[1] - m[0], key), Enc(m[0], key), key).binary() for m, cb in zip(self.args, args))
def packforhash(self, tup, gid): """ pack into string for sha-hashing tup = inputs gid = gate id d = num of inputs """ from struct import pack d = len(tup) secparambytes = bit2byte(state.config.symmetric_security_parameter + 1) s = pack((str(secparambytes) + "s") * d + "HI", # formatstring: "11s11s11sHI" for d = 3 with t = 80 *map(lambda x: x.binary(), tup) + [ # tup[0].binary(), tup[1].binary(), tup[2].binary() self.circuit_id, gid]) # s = pack(str(secparambytes) + "s" + str(secparambytes) + "sHH", # formatstring looks as follows: "10s10sHH" # (tup[0]>>1).binary(), (tup[1]>>1).binary(), # self.circuit_id, # gid) #TODO: check that this works # return s + mpz(gid << 2 | (_bit(tup[0], 1) << 1) | _bit(tup[1], 1)).binary() return s # "tup[0] || ... || tup[d-1] || circuit_id || gate_id"
def creation_costs(self): """ IMPLEMENT ME""" t = self.circuit.gate_types() hashes = 0 bits = 0 for key in t.keys(): if key == "2_XOR": pass elif key == "2_NONXOR": hashes += t[key] * 4 bits += t[key] * 3 * (state.config.symmetric_security_parameter + 1) else: d = int(key) hashes += t[key] * (1<<d) bits += t[key] * ((1<<d) - 1) * (state.config.symmetric_security_parameter + 1) #TODO: we should count theoretical costs in bits # instead of rounding each time when converting from bits to bytes. # for now to remain compatible: bytes = bit2byte(bits) return {"SHA256": hashes, "Send": bytes }
def _sendcost(bits): cost_results.CostSystem.costs["theoretical"]["online"]["accumulated"](Send=bit2byte(bits))
def client_round1(self, args): u1, u2 = self.unpack_homovec(args) cost_results.CostSystem.costs["theoretical"]["online"]["accumulated"](Send=utils.bit2byte(2*state.config.asymmetric_security_parameter * len(u1))) return tasty.types.HomomorphicVec(val=u1.componentmult(u2), signed=False)