예제 #1
0
    def half_gates_ungarble(self, garblers_label, evaluators_label):
        """
            Evaluates the gate by decrypting each half gate and XORing
            the result.

            :param garblers_label: the chosen label by the garbler
            :param evaluators_label: the chosen label by the evaluator
            :return: the correct output label
            :rtype: :class:`Label`
        """
        if self.gate_type == 'AND':
            s_a, s_b = garblers_label.pp_bit, evaluators_label.pp_bit
            entry1, entry2 = self.table
            gen = hashlib.sha256(garblers_label.label).digest()
            eva = hashlib.sha256(evaluators_label.label).digest()

            C_g = xor(gen, entry1) if s_a else gen
            C_e = xor(eva, xor(entry2, garblers_label.label)) if s_b else eva

            output_label = Label(0)
            output_label.represents = None
            output_label.label = xor(C_g, C_e)
            output_label.pp_bit = get_last_bit(output_label.label)
            return output_label
        else:
            return self.free_xor_ungarble(garblers_label, evaluators_label)
예제 #2
0
    def free_xor_garble(self):
        """
            In this optimization *XOR* gates are garbled for free, that is,
            the table corresponding to this gate is empty. The way this
            optimization accomplishes this is by setting the true label
            of each wire as an offset *R* of the false label. This offset
            is global to the whole circuit, so by the properties of *XOR*,
            everything works out nicely. For more information see `the paper
            <http://www.cs.toronto.edu/~vlad/papers/XOR_ICALP08.pdf>`_.

            Note that FreeXOR is not compatible with GRR2.
        """
        if self.gate_type == 'XOR':
            A0 = self.left_wire.false_label.label
            B0 = self.right_wire.false_label.label
            R = settings.R
            C0, C1 = xor(A0, B0), xor(xor(A0, B0), R)
            pp_bit = get_last_bit(C0)
            f_label = self.output_wire.false_label
            t_label = self.output_wire.true_label
            f_label.label = C0
            f_label.pp_bit = pp_bit
            t_label.label = C1
            t_label.pp_bit = not pp_bit
        else:
            if settings.GRR3:
                self.grr3_garble()
            else:
                self.point_and_permute_garble()
예제 #3
0
 def __init__(self, identifier=None):
     self.identifier = identifier
     if settings.CLASSICAL:
         self.false_label = Label(False)
         self.true_label = Label(True)
     else:
         b = random.choice([True, False])
         self.false_label = Label(False, pp_bit=b)
         self.true_label = Label(True, pp_bit=not b)
     if settings.FREE_XOR or settings.HALF_GATES:
         self.true_label.label = xor(self.false_label.label, settings.R)
예제 #4
0
    def half_gates_garble(self):
        """
            In this optimization, the most current one to date, the
            authors propose a method to garble *AND* gates with a table
            size of two ciphertexts in a way that is compatible with
            FreeXOR. The way they accomplish this is by breaking up
            an *AND* gate into two *half gates*. For more information
            see `the paper <https://eprint.iacr.org/2014/756.pdf>`_.
        """
        if self.gate_type == 'AND':

            def H(x):
                return hashlib.sha256(x).digest()

            self.table = [None] * 2
            p_a = self.left_wire.false_label.pp_bit
            p_b = self.right_wire.false_label.pp_bit

            # Generator Half Gate
            entry1 = xor(H(self.left_wire.false_label.label),
                         H(self.left_wire.true_label.label))
            if p_b:
                entry1 = xor(entry1, settings.R)
            C0 = H(self.left_wire.false_label.label)
            if p_a:
                C0 = xor(C0, entry1)

            # Evaluator Half Gate
            entry2 = xor(H(self.right_wire.false_label.label),
                         H(self.right_wire.true_label.label))
            entry2 = xor(entry2, self.left_wire.false_label.label)
            C0_ = H(self.right_wire.false_label.label)
            if p_b:
                C0_ = xor(C0_, xor(entry2, self.left_wire.false_label.label))

            self.table = [entry1, entry2]
            self.update_output_wire(xor(C0, C0_), xor(xor(C0, C0_),
                                                      settings.R))
        else:
            self.free_xor_garble()
예제 #5
0
 def flexor_garble(self):
     """
         In this optimization *XOR* are garbled with a table size
         of 0, 1, or 2 (hence its name flexible XORs). The innovation
         at the time was that this method is compatible with GRR2.
         The way it accomplishes this is by changing the input wires'
         labels to have the same offset as the output wire's labels.
         For more information see `the paper
         <https://pdfs.semanticscholar.org/72ba/7c639e3d7b07\
         5fde8eeca3385923551c6a39.pdf>`_.
     """
     if self.gate_type == 'XOR':
         self.table = [None] * 4
         left, right, out = self.wires()
         adjust_wire_offset(out)
         A0, A1 = left.false_label.label, left.true_label.label
         B0, B1 = right.false_label.label, right.true_label.label
         C0, C1 = out.false_label.label, out.true_label.label
         R1, R2, R3 = xor(A0, A1), xor(B0, B1), xor(C0, C1)
         k1, k2 = AESKey(A0), AESKey(B0)
         A0_ = k1.decrypt(bytes(settings.NUM_BYTES))
         B0_ = k2.decrypt(bytes(settings.NUM_BYTES))
         C0_, C1_ = xor(A0_, B0_), xor(xor(A0_, B0_), R3)
         A1_, B1_ = xor(A0_, R3), xor(B0_, R3)
         self.modify_pp_bits(A0_, B0_, C0_)
         out.false_label.label = C0_
         out.true_label.label = C1_
         k1, k2 = AESKey(A1), AESKey(B1)
         if R1 == R2 == R3:
             self.free_xor_garble()
         elif R1 != R2 != R3:
             self.table[left.true_label.pp_bit] = k1.encrypt(A1_)
             self.table[right.true_label.pp_bit + 2] = k2.encrypt(B1_)
         elif R1 == R3:
             self.table[right.true_label.pp_bit + 2] = k2.encrypt(B1_)
         elif R2 == R3:
             self.table[left.true_label.pp_bit] = k1.encrypt(A1_)
     else:
         if settings.GRR3:
             self.grr3_garble()
         else:
             self.point_and_permute_garble()
예제 #6
0
    def free_xor_ungarble(self, garblers_label, evaluators_label):
        """
            Evaluates *XOR* gates for free by XORing the two
            labels he receives.

            :param garblers_label: the chosen label by the garbler
            :param evaluators_label: the chosen label by the evaluator
            :return: the correct output label
            :rtype: :class:`Label`
        """
        if self.gate_type == 'XOR':
            output_label = Label(0)
            output_label.represents = None
            output_label.label = xor(garblers_label.label,
                                     evaluators_label.label)
            output_label.pp_bit = get_last_bit(output_label.label)
        else:
            g, e = garblers_label, evaluators_label
            if settings.GRR3:
                output_label = self.grr3_ungarble(g, e)
            else:
                output_label = self.point_and_permute_ungarble(g, e)
        return output_label