コード例 #1
0
    def send_result(socket, circuit, g_tables, pbits_out, b_inputs):
        """Evaluate circuit and send the result to Alice.

        Keyword arguments:
        socket    -- socket for exchanges between A and B
        circuit   -- dict containing circuit spec
        g_tables  -- garbled tables of yao circuit
        pbits_out -- p-bits of outputs
        b_inputs  -- dict mapping Bob's wires to (clear) input bits
        """
        # dict mapping Alice's wires to (key, encr_bit) inputs
        a_inputs = socket.receive()
        # dict mapping Bob's wires to (key, encr_bit) inputs
        b_inputs_encr = {}

        for w, b_input in b_inputs.items():
            # Send the gate ID on which to perform OT
            socket.send(w)
            # Perform oblivious transfer
            util.log('OT Request sent')
            b_inputs_encr[w] = pickle.loads(ot_bob(socket, b_input))

        # Evaluate circuit using Alice and Bob's inputs
        result = yao.evaluate(circuit, g_tables, pbits_out, \
                              a_inputs, b_inputs_encr)
        socket.send(result)
コード例 #2
0
    def send_result(self, circuit, g_tables, pbits_out, b_inputs):
        """Evaluate circuit and send the result to Alice.

        Args:
            circuit: A dict containing circuit spec.
            g_tables: Garbled tables of yao circuit.
            pbits_out: p-bits of outputs.
            b_inputs: A dict mapping Bob's wires to (clear) input bits.
        """
        # map from Alice's wires to (key, encr_bit) inputs
        a_inputs = self.socket.receive()
        # map from Bob's wires to (key, encr_bit) inputs
        b_inputs_encr = {}

        logging.debug("Received Alice's inputs")

        for w, b_input in b_inputs.items():
            logging.debug(f"Sending gate ID {w}")
            self.socket.send(w)

            if self.enabled:
                b_inputs_encr[w] = pickle.loads(self.ot_evaluator(b_input))
            else:
                pair = self.socket.receive()
                logging.debug(f"Received key pair, key {b_input} selected")
                b_inputs_encr[w] = pair[b_input]

        result = yao.evaluate(circuit, g_tables, pbits_out, a_inputs,
                              b_inputs_encr)

        logging.debug("Sending circuit evaluation")
        self.socket.send(result)
コード例 #3
0
    def send_result(socket, circuit, g_tables, pbits_out, b_inputs):
        a_inputs = socket.receive()
        b_inputs_encr = {}

        for w, b_input in b_inputs.items():
            socket.send(w)
            pair = socket.receive()
            # Bob receives the pair of keys and choose one of them
            b_inputs_encr[w] = pair[b_input]

        result = yao.evaluate(circuit, g_tables, pbits_out, \
                              a_inputs, b_inputs_encr)
        socket.send(result)
コード例 #4
0
def print_evaluation_local(circuit, g_tables, keys, pbits):
    """Print circuit evaluation for all Bob and Alice inputs.
    Keyword arguments:
    circuit  -- dict containing circuit spec
    g_tables -- garbled tables of the yao circuit
    keys     -- dict mapping each wire to a pair of key
    pbits    -- dict mapping each wire to a p-bit
    """
    outputs = circuit["out"]  # ID of outputs
    a_wires = circuit.get("alice", [])  # list of Alice's wires
    b_wires = circuit.get("bob", [])  # list of Bob's wires
    # dict mapping Alice's wires to (key, encr_bit) inputs
    a_inputs = {}
    # dict mapping Bob's wires to (key, encr_bit) inputs
    b_inputs = {}
    # p-bits of outputs
    pbits_out = {w: pbits[w] for w in outputs}

    print("\n======= {0} =======".format(circuit["name"]))

    len_a_wires, len_b_wires = len(a_wires), len(b_wires)
    N = len_a_wires + len_b_wires

    # Generate all possible inputs for both Alice and Bob
    for bits in [format(n, 'b').zfill(N) for n in range(2**N)]:
        bits_a = [int(b) for b in bits[:len_a_wires]]  # Alice's inputs
        bits_b = [int(b) for b in bits[N - len_b_wires:]]  # Bob's inputs

        # Map Alice's wires to (key, encr_bit)
        for i in range(len_a_wires):
            a_inputs[a_wires[i]] = \
                (keys[a_wires[i]][bits_a[i]], pbits[a_wires[i]] ^ bits_a[i])
        # Map Bob's wires to (key, encr_bit)
        for i in range(len_b_wires):
            b_inputs[b_wires[i]] = \
                (keys[b_wires[i]][bits_b[i]], pbits[b_wires[i]] ^ bits_b[i])

        # Send Alice's encrypted inputs and keys to Bob and wait for results
        result = yao.evaluate(circuit, g_tables, pbits_out, a_inputs, b_inputs)

        # Last term is a little hack to respect the given output format
        str_bits_a = ' '.join(bits[:len_a_wires]) + ' ' * bool(len_a_wires)
        str_bits_b = ' '.join(bits[len_a_wires:]) + ' ' * bool(len_b_wires)
        str_result = ' '.join([str(result[w]) for w in outputs]) + ' '
        # Print one evaluation of the circuit
        line       = "  Alice{0} = {1} Bob{2} = {3}  Outputs{4} = {5}".\
            format(a_wires, str_bits_a, b_wires, str_bits_b, \
                   outputs, str_result)
        print(line)
コード例 #5
0
    def _print_evaluation(self, entry):
        """Print circuit evaluation."""
        circuit, pbits, keys = entry["circuit"], entry["pbits"], entry["keys"]
        garbled_tables = entry["garbled_tables"]
        outputs = circuit["out"]
        a_wires = circuit.get("alice", [])  # Alice's wires
        a_inputs = {}  # map from Alice's wires to (key, encr_bit) inputs
        b_wires = circuit.get("bob", [])  # Bob's wires
        b_inputs = {}  # map from Bob's wires to (key, encr_bit) inputs
        pbits_out = {w: pbits[w] for w in outputs}  # p-bits of outputs
        N = len(a_wires) + len(b_wires)

        print(f"======== {circuit['id']} ========")

        # Generate all possible inputs for both Alice and Bob
        for bits in [format(n, 'b').zfill(N) for n in range(2**N)]:
            bits_a = [int(b) for b in bits[:len(a_wires)]]  # Alice's inputs
            bits_b = [int(b) for b in bits[N - len(b_wires):]]  # Bob's inputs

            # Map Alice's wires to (key, encr_bit)
            for i in range(len(a_wires)):
                a_inputs[a_wires[i]] = (keys[a_wires[i]][bits_a[i]],
                                        pbits[a_wires[i]] ^ bits_a[i])

            # Map Bob's wires to (key, encr_bit)
            for i in range(len(b_wires)):
                b_inputs[b_wires[i]] = (keys[b_wires[i]][bits_b[i]],
                                        pbits[b_wires[i]] ^ bits_b[i])

            result = yao.evaluate(circuit, garbled_tables, pbits_out, a_inputs,
                                  b_inputs)

            # Format output
            str_bits_a = ' '.join(bits[:len(a_wires)])
            str_bits_b = ' '.join(bits[len(a_wires):])
            str_result = ' '.join([str(result[w]) for w in outputs])

            print(f"  Alice{a_wires} = {str_bits_a} "
                  f"Bob{b_wires} = {str_bits_b}  "
                  f"Outputs{outputs} = {str_result}")

        print()
コード例 #6
0
    def _print_evaluation(self, entry):
        """
        Print circuit evaluation and perform equality check of the result.
        """
        circuit, pbits, keys = entry["circuit"], entry["pbits"], entry["keys"]
        garbled_tables = entry["garbled_tables"]
        outputs = circuit["out"]

        # Alice
        a_wires = circuit.get("alice", [])  # Alice's wires
        a_inputs = {}  # map from Alice's wires to (key, encr_bit) inputs
        print(f'Alice\'s wires {a_wires[::-1]}')

        # Bob
        b_wires = circuit.get("bob", [])  # Bob's wires
        b_inputs = {}  # map from Bob's wires to (key, encr_bit) inputs
        print(f'Bob\'s wires {b_wires[::-1]}\n')

        pbits_out = {w: pbits[w] for w in outputs}  # p-bits of outputs
        total_wires = len(a_wires) + len(b_wires)
        print(f'Total wires: {total_wires}')

        possible_bit_combinations = [
            format(n, 'b').zfill(total_wires) for n in range(2**total_wires)
        ]

        print(f"======== {circuit['id']} ========")

        # Generate all possible inputs for both Alice and Bob
        for bits in possible_bit_combinations:
            bits_a = [int(b) for b in bits[:len(a_wires)]]  # Alice's inputs
            bits_b = [int(b) for b in bits[total_wires - len(b_wires):]
                      ]  # Bob's inputs

            # Excluding carry
            bits_per_party = len(bits_b)

            # Map Alice's wires to (key, encr_bit)
            for i in range(len(a_wires)):
                a_inputs[a_wires[i]] = (keys[a_wires[i]][bits_a[i]],
                                        pbits[a_wires[i]] ^ bits_a[i])

            # Map Bob's wires to (key, encr_bit)
            for i in range(len(b_wires)):
                b_inputs[b_wires[i]] = (keys[b_wires[i]][bits_b[i]],
                                        pbits[b_wires[i]] ^ bits_b[i])

            result = yao.evaluate(circuit, garbled_tables, pbits_out, a_inputs,
                                  b_inputs)

            # Format output
            str_bits_a = ''.join(bits[:len(a_wires)])
            str_bits_b = ''.join(bits[len(a_wires):])
            mpc_result = ''.join([str(result[w]) for w in outputs])

            # === Performing the non-MPC function evaluation ===
            non_mpc_result = add_n_bits(bits_a,
                                        bits_b,
                                        bits_per_party=bits_per_party)

            # This operation is necessary because the result of
            # add_n_bits will have the following shape:
            # R_3, R_2, R_1, R_0, C_3
            #
            # While the outputs variable has the following shape:
            # R_0, R_1, R_2, R_3, C_3
            #
            # Therefore the displayed wires order needs to be modified accordingly.
            output_wires = outputs[::-1][1:]
            output_wires.append(outputs[-1])

            print(outputs)

            print(
                f"Alice{a_wires[::-1]} = {str_bits_a} - "
                f"Bob{b_wires[::-1]} = {str_bits_b}  ->  "
                f"Outputs{output_wires} = {mpc_result}  -  "
                f"Correct result = {non_mpc_result} - "
                f"Are they equal? {'Yes' if verifyResults(mpc_result, non_mpc_result) else 'No'}"
            )