Esempio n. 1
0
class ProtocolRandom:
    def __init__(self, l, type):
        self.l = l
        self.type = type
        self.n = config.player_count
        self.t = int((self.n - 1) / 2)
        self.pol = Polynomials()
        self.prime = self.pol.get_prime()
        self.shares = []

    def generate_random_shares(self, count):
        poly = np.transpose([[
            random.SystemRandom().randint(1, self.prime)
            for i in range(self.t + 1)
        ] for j in range(count)])
        M = self.pol.van(self.n, self.t + 1)
        shares = np.dot(M, poly) % self.prime
        return shares

    def calculate_r(self, share):
        self.shares.append(share)
        received_all = len(self.shares) == self.n
        if received_all:
            #print("protocol random shares after dealing", self.shares)
            M = self.pol.van(self.n, self.l)
            r = np.dot(np.transpose(M), self.shares)
            #print("r0", r, self.l)
            return r
        return None
Esempio n. 2
0
 def __init__(self, prover_id, commit_id):
     self.prover_id = prover_id
     self.commit_id = commit_id
     self.my_id = config.id
     self.players = config.players
     self.player_count = config.player_count
     self.degree = int(self.player_count / 3)
     self.pol = Polynomials()
     self.con_vals = {
         player_id: None
         for player_id in range(1, self.player_count + 1)
         if player_id != prover_id and player_id != int(self.my_id)
     }
     self.disputes = {
         player_id: None
         for player_id in range(1, self.player_count + 1)
         if player_id != prover_id and player_id != int(self.my_id)
     }
     self.accusations_con = {
         player_id: None
         for player_id in range(1, self.player_count + 1)
         if player_id != int(prover_id)
     }
     self.accusations_share = {
         player_id: None
         for player_id in range(1, self.player_count + 1)
         if player_id != int(prover_id)
     }
     self.received = {
         player_id: None
         for player_id in range(1, self.player_count + 1)
         if player_id != int(prover_id)
     }
     self.dispute_flag = True
Esempio n. 3
0
 def __init__(self, l, type):
     self.l = l
     self.type = type
     self.n = config.player_count
     self.t = int((self.n - 1) / 2)
     self.pol = Polynomials()
     self.prime = self.pol.get_prime()
     self.shares = []
Esempio n. 4
0
 def __init__(self, l, open, type):
     self.l = l
     self.open = open
     self.type = type
     self.n = config.player_count
     self.t = int((self.n - 1) / 2)
     self.pol = Polynomials()
     self.prime = self.pol.get_prime()
     self.a = None
     self.b = None
     self.D = []
Esempio n. 5
0
 def __init__(self, circuit, sharingStrategy):
     self.sharingStrategy = sharingStrategy
     self.circuit = circuit["circuit"]
     self.output_gate_count = len(circuit["output_gates"])
     self.input_gates = circuit["input_gates"]
     self.circuit_type = circuit["type"]
     self.cur_gid = 0
     self.pol = Polynomials()
     self.output = []
     self.mv = []
     self.cur_layer = 1
     self.start = None
Esempio n. 6
0
class ProtocolTriples:
    def __init__(self, l, open, type):
        self.l = l
        self.open = open
        self.type = type
        self.n = config.player_count
        self.t = int((self.n - 1) / 2)
        self.pol = Polynomials()
        self.prime = self.pol.get_prime()
        self.a = None
        self.b = None
        self.D = []

    def run(self, r_2m, rm, R):
        m = len(rm)
        a, b = np.split(np.transpose(r_2m), 2)
        self.a = np.concatenate(a, axis=0)
        self.b = np.concatenate(b, axis=0)
        #print("a", self.a)
        #print("b", self.b)
        R = np.concatenate(R, axis=0)
        self.rm = np.concatenate(rm, axis=0)
        D = [(self.a[x] * self.b[x] + R[x]) % self.prime
             for x in range(len(R))]
        #print("D", D)
        self.open.request(D, "D")

    def calculate_c(self, D_open):
        c = [(D_open[x] - self.rm[x]) % self.prime for x in range(len(D_open))]
        #print("c",c)
        return self.a, self.b, c
Esempio n. 7
0
 def __init__(self, circuit, sharingStrategy):
     self.sharingStrategy = sharingStrategy
     self.circuit = circuit["circuit"]
     self.input_gates = circuit["input_gates"]
     self.mult_gates = circuit["mult_gates"]
     self.n = config.player_count
     self.t = int(math.ceil((self.n - 1) / 2))
     self.l = self.n - self.t
     self.protocol_open = Op()
     self.pr = ProtocolRandom(self.l, "pre")  # TODO Cleanup types
     self.pdr = ProtocolDoubleRandom(self.l, "pre")
     self.protocol_triples = ProtocolTriples(self.l, self.protocol_open,
                                             "pre")
     self.pol = Polynomials()
     self.prime = self.pol.get_prime()
     self.a_open = None
     self.b_open = None
     self.c_open = None
     self.input_shares = {}
Esempio n. 8
0
class ProtocolDoubleRandom:
    def __init__(self, l, type):
        self.l = l
        self.type = type
        self.n = config.player_count
        self.t = int((self.n - 1) / 2)
        self.pol = Polynomials()
        self.prime = self.pol.get_prime()
        self.shares_t = []
        self.shares_2t = []

    def generate_random_shares(self, count):
        poly_t = np.transpose([[
            random.SystemRandom().randint(1, self.prime)
            for i in range(self.t + 1)
        ] for j in range(count)])
        poly_2t = np.transpose([[
            random.SystemRandom().randint(1, self.prime)
            for i in range(2 * self.t + 1)
        ] for j in range(count)])
        s = random.SystemRandom().randint(1, self.prime)
        poly_t[0] = s
        poly_2t[0] = s
        M_t = self.pol.van(self.n, self.t + 1)
        M_2t = self.pol.van(self.n, 2 * self.t + 1)
        shares_t = np.dot(M_t, poly_t) % self.prime
        shares_2t = np.dot(M_2t, poly_2t) % self.prime
        return shares_t, shares_2t

    def calculate_r(self, share_t, share_2t):
        self.shares_t.append(share_t)
        self.shares_2t.append(share_2t)
        received_all = len(self.shares_t) == self.n
        if received_all:
            #print("protocol random r shares after dealing", self.shares_t)
            #print("protocol random R shares after dealing", self.shares_2t)

            M = self.pol.van(self.n, self.l)
            r = np.dot(np.transpose(M), self.shares_t)
            R = np.dot(np.transpose(M), self.shares_2t)
            return [r, R]
        return None
Esempio n. 9
0
class ShareByWirePlayerId:
    def __init__(self):
        self.pol = Polynomials()

    def share_my_input_values(self, my_values, circuit):
        n = config.player_count
        input_shares = {}
        counter = 0
        for gate in circuit:
            if gate.type == 'input':
                if config.id == str(gate.wires_in[0]):
                    my_value = my_values[counter]
                    counter = counter + 1
                    poly, shares = self.pol.create_poly_and_shares(my_value,
                                                                   degree=int(
                                                                       n / 3),
                                                                   shares=n)
                    for player_id, player in config.players.items():
                        if player_id not in input_shares:
                            input_shares[player_id] = []
                        input_shares[player_id].append(
                            [gate.id, shares[player_id - 1]])
                        gate.output_value = shares[int(config.id) - 1]
        if input_shares != {}:
            self.send_input_shares(input_shares)

    def send_input_shares(self, input_shares):
        for player_id, player in config.players.items():
            url = "http://" + player + "/api/ceps/share/"
            data = {
                "shares": json.dumps(input_shares[player_id]),
                "sender_id": json.dumps(config.id)
            }
            requests.post(url, data)

    def handle_input_shares(self, shares, circuit):
        for share in shares:
            gate_id = share[0]
            point = share[1]
            gate = circuit[gate_id]
            gate.output_value = point
Esempio n. 10
0
 def __init__(self):
     self.pol = Polynomials()
     self.prime = self.pol.get_prime()
     self.shares = {}
Esempio n. 11
0
class Open:
    def __init__(self):
        self.pol = Polynomials()
        self.prime = self.pol.get_prime()
        self.shares = {}

    def request(self, data, type):
        king = config.all_players[1]
        url = "http://" + king + "/api/ceps_speed/protocolOpen/share/"
        data = {"shares": json.dumps(np.array(data).tolist()), "type": type}
        r = requests.post(url, data)

    def request_load(self, data, type):
        for player_id, shares in data.items():
            king = config.all_players[player_id]
            url = "http://" + king + "/api/ceps_speed/protocolOpen/share/"
            dat = {"shares": json.dumps(np.array(shares).tolist()), "type": type}
            requests.post(url, dat)


    def handle_request(self, data, type):
        if type in self.shares.keys():
            array = self.shares[type]
            array.append(data)
        else:
            self.shares[type] = [data]
        received_all = len(self.shares[type]) == config.player_count
        if received_all:
            rec = None
            if type == "layer":
                sorted = self.sort_layer_list(self.shares[type])
                rec = self.reconstruct_layer(sorted)
            elif type == "D":
                x = self.shares[type]
                shares = [[x[i][j] for i in range(0, len(x))] for j in range(0, len(x[0]))]
                rec = [self.pol.lagrange_interpolate(shares[x])[1] for x in range(0, len(x[0]))]
            elif type == "alpha_beta" or type == "and" or type == "xor":
                aplha = [self.shares[type][x][0] for x in range(len(self.shares[type]))]
                beta = [self.shares[type][x][1] for x in range(len(self.shares[type]))]
                rec_aplha = self.pol.lagrange_interpolate(aplha)[1]
                rec_beta = self.pol.lagrange_interpolate(beta)[1]
                rec = [rec_aplha, rec_beta]
            elif type == "output":
                rec = self.pol.lagrange_interpolate(self.shares[type])[1]
            else:
                rec = self.pol.lagrange_interpolate(self.shares[type])[1]
            del self.shares[type]

            for player_id, player in config.all_players.items():
                url = "http://" + player + "/api/ceps_speed/protocolOpen/reconstruction/"
                data = {"rec": json.dumps(rec), "type": type}
                requests.post(url, data)

    def sort_layer_list(self, layer_list):
        sorted = {}
        for player_input in layer_list:
            for gate in player_input:
                gate_id = gate[0]
                gate_type = gate[1]
                if (gate_id, gate_type) not in sorted:
                    sorted[(gate_id, gate_type)] = [[], []]
                if gate_type == 'xor' or gate_type == 'and':
                    alpha = int(gate[2])
                    beta = int(gate[3])
                    sorted[(gate_id, gate_type)][0].append(alpha)
                    sorted[(gate_id, gate_type)][1].append(beta)
                elif gate_type == 'output':
                    value = int(gate[2])
                    sorted[(gate_id, gate_type)][0].append(value)
        return sorted

    def reconstruct_layer(self, sorted):
        rec = []
        for gate, shares in sorted.items():
            gate_id = gate[0]
            gate_type = gate[1]
            if gate_type == 'xor' or gate_type == 'and':
                alpha = shares[0]
                beta = shares[1]
                rec_a = self.pol.lagrange_interpolate(alpha)[1]
                rec_b = self.pol.lagrange_interpolate(beta)[1]
                rec.append([gate_id, gate_type, rec_a, rec_b])
            elif gate_type == 'output':
                output_shares = shares[0]
                rec_o = self.pol.lagrange_interpolate(output_shares)[1]
                rec.append([gate_id, gate_type, rec_o])
        return rec
Esempio n. 12
0
class Ceps:
    def __init__(self, circuit, sharingStrategy):
        self.sharingStrategy = sharingStrategy
        self.circuit = circuit["circuit"]
        self.output_gate_count = len(circuit["output_gates"])
        self.input_gates = circuit["input_gates"]
        self.circuit_type = circuit["type"]
        self.cur_gid = 0
        self.pol = Polynomials()
        self.output = []
        self.mv = []
        self.cur_layer = 1
        self.start = None

    def run(self):
        if self.start is None:
            self.start = time.time()
        self.share_my_input_values(self.mv)

    def setup(self, circuit, my_values):
        self.mv = my_values
        self.circuit = circuit["circuit"]
        self.output_gate_count = len(circuit["output_gates"])
        self.input_gates = circuit["input_gates"]
        self.circuit_type = circuit["type"]
        self.cur_gid = 0
        self.cur_layer = 1
        self.output = []
        self.start = None

    def share_my_input_values(self, my_values):
        print("*************************", my_values, "*********************'")
        self.sharingStrategy.share_my_input_values(my_values=my_values,
                                                   circuit=self.circuit)
        if self.received_all_input_shares():
            self.evaluate_circuit()

    def handle_input_shares(self, shares):
        if self.start is None:
            self.start = time.time()
        self.sharingStrategy.handle_input_shares(shares, self.circuit)
        if self.received_all_input_shares():
            self.evaluate_circuit()

    def handle_mult_share(self, shares, gate_id, sender_id):
        if sender_id is not config.id:
            for tuple in shares:
                gate_id = tuple[0]
                share = tuple[1]
                gate = self.circuit[gate_id]
                gate.shares[sender_id - 1] = share
        if self.received_all_mult_shares(shares):
            #print("got all")
            for tuple in shares:
                gate_id = tuple[0]
                gate = self.circuit[gate_id]
                result = self.reconstruct(gate.shares)[1]
                if gate.type == 'xor':
                    val_in_l = self.circuit[gate.wires_in[0]].output_value
                    val_in_r = self.circuit[gate.wires_in[1]].output_value
                    result = (val_in_l + val_in_r) - 2 * (result)
                    gate.output_value = result
                gate.output_value = result
            self.cur_layer = self.cur_layer + 1
            self.evaluate_circuit()

    def received_all_input_shares(self):
        for g_in in self.input_gates:
            gate = self.circuit[g_in.id]
            if gate.type == 'input' and gate.output_value == None:
                return False
        return True

    def received_all_mult_shares(self, shares):
        for tuple in shares:
            gate_id = tuple[0]
            gate = self.circuit[gate_id]
            if None in gate.shares:
                #print(gate.shares, gate.id, gate.type)
                return False
        return True

    def evaluate_circuit(self):
        n = config.player_count
        layer_shares = {}
        found_gate_in_layer = True
        while found_gate_in_layer:
            found_gate_in_layer = False
            for gate in self.circuit:
                if gate.layer == self.cur_layer:
                    if gate.type == 'input':
                        found_gate_in_layer = True
                    elif gate.type == 'inv':
                        val_in = self.circuit[gate.wires_in[0]].output_value
                        gate.output_value = 1 - val_in
                        found_gate_in_layer = True
                    elif gate.type == 'and' or gate.type == 'xor':
                        val_in_l = self.circuit[gate.wires_in[0]].output_value
                        val_in_r = self.circuit[gate.wires_in[1]].output_value
                        prod = val_in_l * val_in_r
                        poly, shares = self.pol.create_poly_and_shares(
                            prod, degree=int(n / 3), shares=n)
                        for player_id, player in config.players.items():
                            if player_id not in layer_shares:
                                layer_shares[player_id] = []
                            share = shares[player_id - 1]
                            tuple = (gate.id, share)
                            layer_shares[player_id].append(tuple)
                        gate.shares[int(config.id) -
                                    1] = shares[int(config.id) - 1]
                        found_gate_in_layer = True
                    elif gate.type == 'or':
                        val_in_l = self.circuit[gate.wires_in[0]].output_value
                        val_in_r = self.circuit[gate.wires_in[1]].output_value
                        sum = val_in_l + val_in_r
                        gate.output_value = sum
                        found_gate_in_layer = True
                    elif gate.type == 'output':
                        val_in = self.circuit[gate.wires_in[0]].output_value
                        gate.output_value = val_in
                        for player_id, player in config.players.items():
                            if player_id not in layer_shares:
                                layer_shares[player_id] = []
                            tuple = (gate.id, gate.output_value)
                            layer_shares[player_id].append(tuple)
                        gate.shares[int(config.id) - 1] = gate.output_value
                        found_gate_in_layer = True
            # deal layer gate shares
            what = []
            if layer_shares != {}:
                for player_id, player in config.players.items():
                    what = layer_shares[player_id]
                    url = "http://" + player + "/api/ceps/mult_share/"
                    data = {
                        "shares": json.dumps(what),
                        "sender_id": json.dumps(config.id)
                    }
                    requests.post(url, data)
                if self.received_all_mult_shares(what):
                    self.handle_mult_share(what, 0, config.id)
                break
            self.cur_layer = self.cur_layer + 1
            if not found_gate_in_layer:
                for gate in self.circuit:
                    if gate.type == "output":
                        self.output.append(gate.output_value)
                self.protocol_done(self.output)

    def reconstruct(self, shares):
        rec = self.pol.lagrange_interpolate(shares[0:])
        return rec

    def protocol_done(self, result):
        config.result[:] = result
        end = time.time()
        print("Time:", end - self.start)
Esempio n. 13
0
class Commitment:
    def __init__(self, prover_id, commit_id):
        self.prover_id = prover_id
        self.commit_id = commit_id
        self.my_id = config.id
        self.players = config.players
        self.player_count = config.player_count
        self.degree = int(self.player_count / 3)
        self.pol = Polynomials()
        self.con_vals = {
            player_id: None
            for player_id in range(1, self.player_count + 1)
            if player_id != prover_id and player_id != int(self.my_id)
        }
        self.disputes = {
            player_id: None
            for player_id in range(1, self.player_count + 1)
            if player_id != prover_id and player_id != int(self.my_id)
        }
        self.accusations_con = {
            player_id: None
            for player_id in range(1, self.player_count + 1)
            if player_id != int(prover_id)
        }
        self.accusations_share = {
            player_id: None
            for player_id in range(1, self.player_count + 1)
            if player_id != int(prover_id)
        }
        self.received = {
            player_id: None
            for player_id in range(1, self.player_count + 1)
            if player_id != int(prover_id)
        }
        self.dispute_flag = True

    # 1. create poly and broadcast shares.
    def commit_to_value(self, value):
        global shares
        poly, shares = self.pol.create_poly_and_shares_bi(
            secret=value, degree=self.degree, shares=self.player_count)
        for player_id in self.players:
            player = self.players[player_id]
            url = "http://" + player + "/api/ceas/commit/"
            share = json.dumps(shares[player_id].tolist())
            data = {
                "share": share,
                "prover_id": self.my_id,
                "commit_id": self.commit_id
            }
            r = requests.post(url, data)
        return poly  # poly

    # 2. broadcast consistency values
    def share_con_values(self, share):
        global share_poly
        share_poly = share
        for player_id in self.players:
            if player_id != self.prover_id:
                player = self.players[player_id]
                consistency_value = self.pol.eval_poly(share_poly, player_id)
                if self.my_id == '1':
                    consistency_value = 3000
                url = "http://" + player + "/api/ceas/commit/" + str(
                    self.commit_id) + "/consistency/"
                data = {
                    "consistency_value": consistency_value,
                    "prover_id": self.prover_id,
                    "sender_id": self.my_id,
                    "commit_id": self.commit_id
                }
                r = requests.post(url, data)
        self.check_con_value(None, None)

    # 3. check consistency values and broadcast disputes
    # and check the degree of the polynomium. TODO check polynomium and ask why it is done in this step
    def check_con_value(self, con_val, sender_id):
        disputes = []
        status = "success"
        if con_val is not None:
            self.con_vals[sender_id] = con_val
        if None not in self.con_vals.values() and 'share_poly' in globals():
            rest_url = "/api/ceas/commit/" + str(self.commit_id) + "/dispute/"
            for player_id in self.con_vals:
                if len(share_poly) < self.degree + 1:
                    print("p_i sent me a share of too low degree")
                if float(self.con_vals[player_id]) != float(
                        self.pol.eval_poly(share_poly, int(player_id))):
                    disputes.append(player_id)
                    status = "dispute"
            data = {
                "status": status,  # todo status is not used
                "sender_id": self.my_id,
                "disputes": json.dumps(disputes),
                "prover_id": self.prover_id,
                "commit_id": self.commit_id
            }
            self.broadcast(rest_url, data, "post")

    # 4. For each dispute reported in the previous step, P i broadcasts the correct value of beta k,j
    def handle_dispute(self, status, sender_id, disputes):
        self.disputes[sender_id] = disputes
        if None not in self.disputes.values(
        ) and self.my_id == self.prover_id and self.dispute_flag:
            con_vals = {
                p_id: {}
                for p_id in range(1, self.player_count + 1)
                if p_id != int(self.prover_id)
            }
            for p_id, dispute_list in self.disputes.items():
                for d_id in dispute_list:
                    share = self.pol.eval_poly(shares[p_id], d_id)
                    con_vals[p_id][d_id] = share
                    con_vals[d_id][p_id] = share
            rest_url = "/api/ceas/commit/" + str(
                self.commit_id) + "/consistency/"
            data = {
                "consistency_values": json.dumps(con_vals),
                "sender_id": self.my_id,
                "prover_id": self.prover_id,
                "commit_id": self.commit_id
            }
            self.broadcast(rest_url, data, "put")
            self.dispute_flag = False

    # 5. If any P k finds a disagreement between what P i has broadcast and what he received
    # privately from P i , he knows P i is corrupt and broadcasts (accuse, k).
    # TODO check message came from prover
    # TODO check that we got expected con_vals
    def check_new_con_value(self, con_vals):
        should_accuse = False
        my_con_vals = con_vals[self.my_id]
        for d_id, value in my_con_vals.items():
            if self.my_id == '1':
                value = 3000
            if float(value) != self.pol.eval_poly(share_poly, int(d_id)):
                should_accuse = True
                break
        self.accusations_con[int(
            self.my_id)] = "accuse" if should_accuse else "success"
        rest_url = "/api/ceas/commit/" + str(self.commit_id) + "/accusation/"
        data = {
            "accusation": self.accusations_con[int(self.my_id)],
            "sender_id": self.my_id,
            "prover_id": self.prover_id,
            "commit_id": self.commit_id
        }
        self.broadcast(rest_url, data, "post")
        self.handle_con_accusation(None, None)

    # 6. For any accusation from P k in the previous step, P i broadcasts f k (X). TODO if person tries to accuse multiple times
    def handle_con_accusation(self, accusation, sender_id):
        if accusation is not None:
            self.accusations_con[sender_id] = accusation
        if None not in self.accusations_con.values(
        ) and self.my_id == self.prover_id:
            acc_shares = {
                acc_id: shares[acc_id].tolist()
                for acc_id, acc in self.accusations_con.items()
                if acc == "accuse"
            }
            rest_url = "/api/ceas/commit/"
            data = {
                "shares": json.dumps(acc_shares),
                "sender_id": self.my_id,
                "prover_id": self.my_id,
                "commit_id": self.commit_id
            }
            self.broadcast(rest_url, data, "put")

    # 7. If any P k finds a new disagreement between what P i has now broadcast and what he
    # received privately from P i , he knows P i is corrupt and broadcasts (accuse, k).
    # TODO check that we got expected shares
    def check_share(self, shares):
        accusation = "success"
        for share_id, share in shares.items():
            con_val1 = self.pol.eval_poly(share_poly, int(share_id))
            con_val2 = self.pol.eval_poly(np.array(share), int(self.my_id))
            if con_val1 != con_val2:
                accusation = "accuse"
                break
        self.accusations_share[int(self.my_id)] = accusation
        rest_url = "/api/ceas/commit/" + str(self.commit_id) + "/accusation/"
        data = {
            "accusation": accusation,
            "sender_id": self.my_id,
            "prover_id": self.prover_id,
            "commit_id": self.commit_id
        }
        self.broadcast(rest_url, data, "put")
        self.handle_share_accusation(None, None)

    # 8. If the information broadcast by P i is not consistent, or if more than t players have
    # accused P i , players output fail.
    # Otherwise, players who accused P i and had a new polynomial f k (X) broadcast will
    # accept it as their polynomial. All others keep the polynoshare_polymial they received in the first
    # step. Now each P k outputs success and stores (cid, i, beta k = f k (0)). In addition P i
    # stores the polynomial g a (X) = f a (X, 0).
    def handle_share_accusation(self, accusation, sender_id):
        if accusation is not None:
            self.accusations_share[sender_id] = accusation
        if None not in self.accusations_share.values():
            accuse_count = Counter(self.accusations_share.values())["accuse"]
            if accuse_count <= self.degree:
                print("success")
                if self.my_id == self.prover_id:
                    return (self.commit_id, self.prover_id, "random")
                else:
                    return (self.commit_id, self.prover_id, share_poly)
            else:
                print("fail on commitment:", self.commit_id)
        return None, None, None

    def broadcast(self, rest_url, data, request_type):
        for player_id in self.players:
            player = self.players[player_id]
            url = "http://" + player + rest_url
            if request_type == "post":
                r = requests.post(url, data)
            elif request_type == "put":
                r = requests.put(url, data)
Esempio n. 14
0
 def __init__(self):
     self.pol = Polynomials()
Esempio n. 15
0
class Preprocessing:
    def __init__(self, circuit, sharingStrategy):
        self.sharingStrategy = sharingStrategy
        self.circuit = circuit["circuit"]
        self.input_gates = circuit["input_gates"]
        self.mult_gates = circuit["mult_gates"]
        self.n = config.player_count
        self.t = int(math.ceil((self.n - 1) / 2))
        self.l = self.n - self.t
        self.protocol_open = Op()
        self.pr = ProtocolRandom(self.l, "pre")  # TODO Cleanup types
        self.pdr = ProtocolDoubleRandom(self.l, "pre")
        self.protocol_triples = ProtocolTriples(self.l, self.protocol_open,
                                                "pre")
        self.pol = Polynomials()
        self.prime = self.pol.get_prime()
        self.a_open = None
        self.b_open = None
        self.c_open = None
        self.input_shares = {}

    def run(self):
        i = len(self.input_gates)
        m = len(self.mult_gates)
        protocol_double_random_count = int(m / (self.l)) + 1
        protocol_random_count = (protocol_double_random_count * 2) + int(
            i / 2) + 1
        #print("number of input gates", i, "so it need protocol random to run", int(i / 2) + 1)
        #print("number of mult gates", m, "so it need protocol random to run", 2*protocol_double_random_count)
        #print("number of protocol random should run", protocol_random_count)
        #print("number of protocol double random should run", protocol_double_random_count)
        #print("number of random protocols produce (l)", self.l)
        #print("number of players (n)", self.n)
        pr_shares = self.pr.generate_random_shares(protocol_random_count)
        pdr_shares_r, pdr_shares_R = self.pdr.generate_random_shares(
            protocol_double_random_count)

        #print("pr\n", pr_shares)
        #print("pdr_r\n", pdr_shares_r)
        #print("pdr_R\n", pdr_shares_R)

        self.deal_rand_shares(pr_shares, pdr_shares_r, pdr_shares_R)

    def deal_rand_shares(self, pr_shares, pdr_shares_r, pdr_shares_R):
        for player_id, player in config.all_players.items():
            pr_share_r = pr_shares[player_id - 1]
            pdr_share_r = pdr_shares_r[player_id - 1]
            pdr_share_R = pdr_shares_R[player_id - 1]
            url = "http://" + player + "/api/ceps_speed/random_shares/"
            data = {
                "pr_share": json.dumps(pr_share_r.tolist()),
                "pdr_share_r": json.dumps(pdr_share_r.tolist()),
                "pdr_share_R": json.dumps(pdr_share_R.tolist())
            }
            requests.post(url, data)

    def compute_preprossing_randomness(self, pr_share, pdr_share_r,
                                       pdr_share_R):
        protocol_random_shares = self.pr.calculate_r(pr_share)
        protocol_double_random_shares = self.pdr.calculate_r(
            pdr_share_r, pdr_share_R)
        #print("single\n", protocol_random_shares)
        #print("double\n", protocol_double_random_shares)

        if protocol_random_shares is not None:
            i = len(self.input_gates)
            m = len(self.input_gates)

            i_runs = int(i / 2) + 1

            #print("i_runs", i_runs)
            #print("2m_runs", m*2)
            input, mult = np.hsplit(protocol_random_shares,
                                    [i_runs])  #l x i_runs, l x 2m_runs
            #print("input random shares", input)
            #print("mult random shares", mult)
            self.add_random_input_values_to_circuit(input)
            #print(protocol_random_shares)
            #print(protocol_double_random_shares[0])
            #print(protocol_double_random_shares[1])
            self.protocol_triples.run(mult, protocol_double_random_shares[0],
                                      protocol_double_random_shares[1])

    def add_random_input_values_to_circuit(self, input_random_shares):
        self.sharingStrategy.add_random_input_values_to_circuit(
            input_random_shares, self.input_gates)

    def handle_random_input_shares(self, r, gate_id):
        if isinstance(r, list):
            for tuple in r:
                self.add_input_share_to_circuit(int(tuple[0]), int(tuple[1]))
        else:
            r = int(r)
            gate_id = int(gate_id)
            self.add_input_share_to_circuit(r, gate_id)

    def add_input_share_to_circuit(self, r, gate_id):
        if gate_id in self.input_shares:
            shares = self.input_shares[gate_id]
            shares.append(r)
            received_all = len(shares) == config.player_count
            if received_all:
                gate = self.circuit[gate_id]
                gate.r_open = self.pol.lagrange_interpolate(shares)[1]
        else:
            self.input_shares[gate_id] = [r]

    def handle_protocol_open_answer(self, data, type):
        if type == "D":
            a, b, c = self.protocol_triples.calculate_c(data)
            self.add_triples_to_circuit(a, b, c)
        elif type == "A":
            self.a_open = data
        elif type == "B":
            self.b_open = data
        elif type == "C":
            self.c_open = data
        else:
            print(type, data)
        if self.a_open is not None and self.b_open is not None and self.c_open is not None:
            for x in range(len(self.a_open)):
                print("triples", self.a_open[x] * self.b_open[x] % self.prime,
                      "==", self.c_open[x])

    def add_triples_to_circuit(self, a, b, c):
        #print("a", a)
        #print("b", b)
        #print("c", c)
        counter = 0
        for g in self.mult_gates:
            gate = self.circuit[g.id]
            gate.a = a[counter]
            gate.b = b[counter]
            gate.c = c[counter]
            counter = counter + 1
        config.ceps_speed.set_preprossing_circuit(self.circuit)