Exemplo n.º 1
0
    def invert_by_masking(self, byte):
        bits = bit_decompose(byte)

        for j in range(len(bits)):
            bits[j].addCallback(lambda x: 1 - x)
#            bits[j] = 1 - bits[j]

        while len(bits) > 1:
            bits.append(bits.pop(0) * bits.pop(0))

        # b == 1 if byte is 0, b == 0 else
        b = bits[0]

        r = Share(self.runtime, GF256)
        c = Share(self.runtime, GF256)

        def get_masked_byte(c_opened, r_related, c, r, byte):
            if c_opened == 0:
                r_trial = self.runtime.prss_share_random(GF256)
                c_trial = self.runtime.open((byte + b) * r_trial)
                self.runtime.schedule_callback(c_trial, get_masked_byte,
                                               r_trial, c, r, byte)
            else:
                r_related.addCallback(r.callback)
                c.callback(~c_opened)

        get_masked_byte(0, None, c, r, byte)

        # necessary to avoid communication in multiplication
        # was: return c * r - b
        result = gather_shares([c, r, b])
        result.addCallback(lambda (c, r, b): c * r - b)
        return result
Exemplo n.º 2
0
    def mul(self, share_a, share_b):
        """Multiplication of shares."""
        field = getattr(share_a, "field", getattr(share_b, "field", None))

        k = self.options.security_parameter
        n = min(self.player.pubkey['n'], self.peer.pubkey['n'])
        assert field.modulus ** 2 + 2 ** k < n, \
            "Need bigger Paillier keys to multiply."

        if not isinstance(share_a, Share):
            share_a = Share(self, field, share_a)
        if not isinstance(share_b, Share):
            share_b = Share(self, field, share_b)

        def finish_mul((a, b)):
            pc = tuple(self.program_counter)
            send_data = self.protocols[self.peer.id].sendData

            if hash(pc) % 2 == self.id:
                # We play the role of P1.
                a1, b1 = a, b
                enc_a1 = encrypt(a1.value, self.player.pubkey)
                enc_b1 = encrypt(b1.value, self.player.pubkey)
                send_data(pc, PAILLIER, str(enc_a1))
                send_data(pc, PAILLIER, str(enc_b1))

                enc_c1 = Share(self, field)
                self._expect_data(self.peer.id, PAILLIER, enc_c1)
                c1 = enc_c1.addCallback(decrypt, self.player.seckey)
                c1.addCallback(lambda c: long(c) + a1 * b1)
                return c1
            else:
                # We play the role of P2.
                a2, b2 = a, b
                enc_a1 = Deferred()
                self._expect_data(self.peer.id, PAILLIER, enc_a1)
                enc_a1.addCallback(long)
                enc_b1 = Deferred()
                self._expect_data(self.peer.id, PAILLIER, enc_b1)
                enc_b1.addCallback(long)

                nsq = self.peer.pubkey['n']**2
                # Calculate a1 * b2 and b1 * a2 inside the encryption.
                enc_a1_b2 = enc_a1.addCallback(pow, b2.value, nsq)
                enc_b1_a2 = enc_b1.addCallback(pow, a2.value, nsq)

                # Chose and encrypt r.
                r = rand.randint(0, 2 * field.modulus**2 + 2**k)
                enc_r = encrypt(r, self.peer.pubkey)

                c1 = gatherResults([enc_a1_b2, enc_b1_a2])
                c1.addCallback(lambda (a, b): a * b * enc_r)
                c1.addCallback(lambda c: send_data(pc, PAILLIER, str(c)))

                c2 = a2 * b2 - r
                return Share(self, field, c2)

        result = gather_shares([share_a, share_b])
        result.addCallback(finish_mul)
        return result
Exemplo n.º 3
0
    def greater_than_equal(self, share_a, share_b):
        """Compute ``share_a >= share_b``.

        Both arguments must be from the same field. The result is a
        :class:`~viff.field.GF256` share.

        :warning:
           The result type (:class:`~viff.field.GF256`) is different
           from the argument types (general field elements).

        """
        field = getattr(share_a, "field", getattr(share_b, "field", None))
        if not isinstance(share_a, Share):
            share_a = Share(self, field, share_a)
        if not isinstance(share_b, Share):
            share_b = Share(self, field, share_b)

        l = self.options.bit_length
        m = l + self.options.security_parameter
        t = m + 1

        assert 2**(l + 1) + 2**t < field.modulus, "2^(l+1) + 2^t < p must hold"
        assert self.num_players + 2 < 2**l

        a = share_a - share_b + 2**l
        b, bits = self.decomposed_random_sharing(field, m)
        T = self.open(2**t - b + a)

        result = gather_shares((T, ) + bits)
        self.schedule_callback(result, self._finish_greater_than_equal, l)
        return result
Exemplo n.º 4
0
Arquivo: active.py Projeto: lu562/viff
    def _exchange_double(self, shares, rvec1, rvec2, T, field, d1, d2):
        """Exchange and (if possible) verify shares."""
        svec1, svec2 = shares
        pc = tuple(self.program_counter)
        inputters = range(1, self.num_players + 1)

        # We send our shares to the verifying players.
        for offset, (s1, s2) in enumerate(zip(svec1, svec2)):
            if T + 1 + offset != self.id:
                self.protocols[T + 1 + offset].sendShare(pc, s1)
                self.protocols[T + 1 + offset].sendShare(pc, s2)

        if self.id > T:
            # The other players will send us their shares of si_1
            # and si_2 and we will verify it.
            si_1 = []
            si_2 = []
            for peer_id in inputters:
                if self.id == peer_id:
                    si_1.append(Share(self, field, svec1[peer_id - T - 1]))
                    si_2.append(Share(self, field, svec2[peer_id - T - 1]))
                else:
                    si_1.append(self._expect_share(peer_id, field))
                    si_2.append(self._expect_share(peer_id, field))
            result = gatherResults([gatherResults(si_1), gatherResults(si_2)])
            result.addCallback(self._verify_double, rvec1, rvec2, T, field, d1,
                               d2)
            return result
        else:
            # We cannot verify anything.
            return (rvec1[:T], rvec2[:T])

        # do actual communication
        self.activate_reactor()
Exemplo n.º 5
0
 def test_open_does_not_mutate_share(self, runtime):
     """Test that opening a share does not change it."""
     # The parties have shares 43, 44, 45 respectively.
     share = Share(runtime, self.Zp, self.Zp(42 + runtime.id))
     opened = runtime.open(share)
     opened.addCallback(self.assertEquals, 42)
     share.addCallback(self.assertEquals, 42 + runtime.id)
     return opened
Exemplo n.º 6
0
 def test_open_does_not_mutate_share(self, runtime):
     """Test that opening a share does not change it."""
     # The parties have shares 43, 44, 45 respectively.
     share = Share(runtime, self.Zp, self.Zp(42 + runtime.id))
     opened = runtime.open(share)
     opened.addCallback(self.assertEquals, 42)
     share.addCallback(self.assertEquals, 42 + runtime.id)
     return opened
Exemplo n.º 7
0
 def __init__(self, runtime, field, value=None, keyList=None,
              authentication_codes=None):
     if value == None and keyList == None and authentication_codes == None:
         Share.__init__(self, runtime, field)
     else:
         Share.__init__(self, runtime, field,
                        BeDOZaShareContents(value, keyList,
                                            authentication_codes))
Exemplo n.º 8
0
 def __init__(self, runtime, field, value=None, enc_shares=None):
     if value == None and enc_shares == None:
         Share.__init__(self, runtime, field)
     else:
         N_squared_list = [ runtime.players[player_id].pubkey['n_square']
                           for player_id in runtime.players.keys()]
         partial_share_contents = PartialShareContents(value, enc_shares,
                                                       N_squared_list)
         Share.__init__(self, runtime, field, partial_share_contents)
Exemplo n.º 9
0
    def _test_binop(self, runtime, op):
        a, b = 12345, 34567
        share_a = Share(runtime, self.Zp, self.Zp(a + runtime.id))
        share_b = Share(runtime, self.Zp, self.Zp(b - runtime.id))

        expected = self.Zp(op(a, b))
        result = op(share_a, share_b)

        opened = runtime.open(result)
        opened.addCallback(self.assertEquals, expected)
        return opened
Exemplo n.º 10
0
 def check(triple):
     a, b, c = triple
     self.assert_type(a, self.Zp)
     self.assert_type(b, self.Zp)
     self.assert_type(c, self.Zp)
     open_a = runtime.open(Share(self, self.Zp, a))
     open_b = runtime.open(Share(self, self.Zp, b))
     open_c = runtime.open(Share(self, self.Zp, c))
     result = gatherResults([open_a, open_b, open_c])
     result.addCallback(verify)
     return result
Exemplo n.º 11
0
 def __init__(self, runtime, field, value=None, enc_shares=None):
     if value == None and enc_shares == None:
         Share.__init__(self, runtime, field)
     else:
         N_squared_list = [
             runtime.players[player_id].pubkey['n_square']
             for player_id in runtime.players.keys()
         ]
         partial_share_contents = PartialShareContents(
             value, enc_shares, N_squared_list)
         Share.__init__(self, runtime, field, partial_share_contents)
Exemplo n.º 12
0
 def __init__(self,
              runtime,
              field,
              value=None,
              keyList=None,
              authentication_codes=None):
     if value == None and keyList == None and authentication_codes == None:
         Share.__init__(self, runtime, field)
     else:
         Share.__init__(
             self, runtime, field,
             BeDOZaShareContents(value, keyList, authentication_codes))
Exemplo n.º 13
0
    def sub(self, a, b):
        """Subtraction of a and b.

        Communication cost: none.
        """
        if not isinstance(a, Share):
            a = Share(self, b.field, a)
        if not isinstance(b, Share):
            b = Share(self, a.field, b)

        yield declareReturn(self, a.field)

        a, b = yield a, b
        returnValue(a - b)
Exemplo n.º 14
0
    def sub(self, share_a, share_b):
        """Subtraction of shares.

        Communication cost: none.
        """
        field = getattr(share_a, "field", getattr(share_b, "field", None))
        if not isinstance(share_a, Share):
            share_a = Share(self, field, share_a)
        if not isinstance(share_b, Share):
            share_b = Share(self, field, share_b)

        result = gather_shares([share_a, share_b])
        result.addCallback(lambda (a, b): a - b)
        return result
Exemplo n.º 15
0
    def _finish_greater_than_equal(self, results, l):
        """Finish the calculation."""
        T = results[0]
        bit_bits = results[1:]

        vec = [(GF256(0), GF256(0))]

        # Calculate the vector, using only the first l bits
        for i, bi in enumerate(bit_bits[:l]):
            Ti = GF256(T.bit(i))
            ci = Share(self, GF256, bi ^ Ti)
            vec.append((ci, Ti))

        # Reduce using the diamond operator. We want to do as much
        # as possible in parallel while being careful not to
        # switch the order of elements since the diamond operator
        # is non-commutative.
        while len(vec) > 1:
            tmp = []
            while len(vec) > 1:
                tmp.append(self._diamond(vec.pop(0), vec.pop(0)))
            if len(vec) == 1:
                tmp.append(vec[0])
            vec = tmp

        return GF256(T.bit(l)) ^ (bit_bits[l] ^ vec[0][1])
Exemplo n.º 16
0
    def share(self, inputters, field, number=None):
        """Share *number* additively."""
        assert number is None or self.id in inputters

        results = []
        for peer_id in inputters:
            # Unique program counter per input.
            self.increment_pc()

            if peer_id == self.id:
                a = field(rand.randint(0, field.modulus - 1))
                b = number - a

                results.append(Share(self, a.field, a))
                pc = tuple(self.program_counter)
                self.protocols[self.peer.id].sendShare(pc, b)
            else:
                share = self._expect_share(peer_id, field)
                results.append(share)

        # Unpack a singleton list.
        if len(results) == 1:
            return results[0]
        else:
            return results
Exemplo n.º 17
0
 def prss_share_random(self, field):
     """Generate a share of a uniformly random element."""
     prfs = self.players[self.id].prfs(field.modulus)
     # There can only be one PRF in the dictionary.
     prf = prfs.values()[0]
     share = field(prf(tuple(self.program_counter)))
     return Share(self, field, share)
Exemplo n.º 18
0
def argmax(xs, gte_max):
    n = len(xs)
    if n==1: return (xs[0], Share(tv, Zp, Zp(0)))
    max0, i0 = argmax(xs[:n/2], gte_max)   
    max1, i1 = argmax(xs[n/2:], gte_max)
    b, max = gte_max(max0, max1)
    return max, i0 + b * (n/2 + i1 - i0)
Exemplo n.º 19
0
    def test_key_expansion(self, runtime):
        aes = AES(runtime, 256, quiet=True)
        key = []
        ascii_key = []

        for i in xrange(8):
            key.append([])

            for j in xrange(4):
                b = 15 * i + j
                key[i].append(Share(runtime, GF256, GF256(b)))
                ascii_key.append(chr(b))

        result = aes.key_expansion(key)

        r = rijndael(ascii_key)
        expected_result = []

        for round_key in r.Ke:
            for word in round_key:
                split_word = []
                expected_result.append(split_word)

                for j in xrange(4):
                    split_word.insert(0, word % 256)
                    word /= 256

        self.verify(runtime, result, expected_result)
Exemplo n.º 20
0
    def __init__(self, runtime):
        self.k = 4
        self.runtime = runtime
        self.ramdom_shares = [
            0 for i in range(self.k * int(math.log(self.k, 2)))
        ]
        self.triggers = [
            Share(self.runtime, Zp)
            for i in range(self.k * int(math.log(self.k, 2)))
        ]
        self.p = find_prime(2**256, blum=True)
        print self.p

        for i in range(self.k * int(math.log(self.k, 2))):

            r = runtime.prss_share_random(Zp)
            u = r * r
            open_u = runtime.open(u)
            open_u.addCallback(self.calculate_share, r, i)

        list = [
            self.triggers[i] for i in range(self.k * int(math.log(self.k, 2)))
        ]
        result = gather_shares(list)
        result.addCallback(self.preprocess_ready)
Exemplo n.º 21
0
def bit_decompose(share, use_lin_comb=True):
    """Bit decomposition for GF256 shares."""

    assert isinstance(share, Share) and share.field == GF256, \
        "Parameter must be GF256 share."

    r_bits = share.runtime.prss_share_random_multi(GF256, 8, binary=True)

    if use_lin_comb:
        r = share.runtime.lin_comb([2 ** i for i in range(8)], r_bits)
    else:
        r = sum([r_bits[i] * 2 ** i for i in range(8)])

    c = share.runtime.open(share + r)
    c_bits = [Share(share.runtime, GF256) for i in range(8)]

    def decompose(byte, bits):
        value = byte.value

        for i in range(8):
            c_bits[i].callback(GF256(value & 1))
            value >>= 1

    c.addCallback(decompose, c_bits)

    return [c_bits[i] + r_bits[i] for i in range(8)]
Exemplo n.º 22
0
Arquivo: active.py Projeto: lu562/viff
    def _exchange_single(self, svec, rvec, T, field, degree):
        """Exchange and (if possible) verify shares."""
        pc = tuple(self.program_counter)
        inputters = range(1, self.num_players + 1)

        # We send our shares to the verifying players.
        for offset, share in enumerate(svec):
            if T + 1 + offset != self.id:
                self.protocols[T + 1 + offset].sendShare(pc, share)

        if self.id > T:
            # The other players will send us their shares of si_1
            # and si_2 and we will verify it.
            si = []
            for peer_id in inputters:
                if self.id == peer_id:
                    si.append(Share(self, field, svec[peer_id - T - 1]))
                else:
                    si.append(self._expect_share(peer_id, field))
            result = gatherResults(si)
            result.addCallback(self._verify_single, rvec, T, field, degree)
            return result
        else:
            # We cannot verify anything.
            return rvec[:T]

        # do actual communication
        self.activate_reactor()
Exemplo n.º 23
0
    def shamir_share(self, inputters, field, number=None, threshold=None):
        """Secret share *number* over *field* using Shamir's method.

        The number is shared using polynomial of degree *threshold*
        (defaults to :attr:`threshold`). Returns a list of shares
        unless there is only one inputter in which case the
        share is returned directly.

        In code it is used like this::

            a, b, c = runtime.shamir_share([1, 2, 3], Zp, x)

        where ``Zp`` is a field and ``x`` is a Python integer holding
        the input of each player (three inputs in total).

        If only a subset of the players provide input it looks like
        this::

            if runtime.id == 1:
                a = runtime.shamir_share([1], Zp, x)
            else:
                a = runtime.shamir_share([1], Zp)

        Instead of branching when calling :meth:`shamir_share`, one
        can give ``None`` as input::

            if runtime.id == 1:
                x = int(raw_input("Input x: "))
            else:
                x = None
            a = runtime.shamir_share([1], Zp, x)

        which might be practical in some cases.

        Communication cost: n elements transmitted.
        """
        assert number is None or self.id in inputters
        if threshold is None:
            threshold = self.threshold

        results = []
        for peer_id in inputters:
            # Unique program counter per input.
            self.increment_pc()
            if peer_id == self.id:
                shares = shamir.share(field(number), threshold,
                                      len(self.players))
                for other_id, share in shares:
                    if other_id.value == self.id:
                        results.append(Share(self, field, share))
                    else:
                        self._send_share(other_id.value, share)
            else:
                results.append(self._expect_share(peer_id, field))
        # Unpack a singleton list.
        if len(results) == 1:
            return results[0]
        else:
            return results
Exemplo n.º 24
0
 def _get_triple(self, field):
     results = [Share(self, field) for i in range(3)]
     def chain(triple, results):
         for i, result in zip(triple, results):
             result.callback(i)
     self.random_triple(field, 1)[0].addCallbacks(chain, self.error_handler,
                                                  (results,))
     return results
Exemplo n.º 25
0
 def exchange(share):
     # Send share to all receivers.
     for peer_id in receivers:
         if peer_id != self.id:
             pc = tuple(self.program_counter)
             self.protocols[peer_id].sendShare(pc, share)
     # Receive and recombine shares if this player is a receiver.
     if self.id in receivers:
         deferreds = []
         for peer_id in self.players:
             if peer_id == self.id:
                 d = Share(self, share.field, (share.field(peer_id), share))
             else:
                 d = self._expect_share(peer_id, share.field)
                 d.addCallback(lambda s, peer_id: (s.field(peer_id), s), peer_id)
             deferreds.append(d)
         return recombine(deferreds)
Exemplo n.º 26
0
 def test_all_players_receive_implicit(self, runtime):
     """Shamir share and open Zp(42)."""
     # The parties have shares 43, 44, 45 respectively.
     share = Share(runtime, self.Zp, self.Zp(42 + runtime.id))
     opened = runtime.open(share)
     self.assert_type(opened, Share)
     opened.addCallback(self.assertEquals, 42)
     return opened
Exemplo n.º 27
0
def vc_read_additive_shares(runtime, Zp, blockname, inputters):
    allvals = map(vc_read_values, [
        vc_directory + "geppblk." + blockname + "." + str(curid) + my_suffix
        for curid in inputters
    ])
    vals = map(lambda x: Share(runtime, Zp, Zp(sum(x) % vc_modulus)),
               zip(*allvals))
    #print "vals", vals
    return vals
Exemplo n.º 28
0
 def add_and_multiply(masked_byte, random_powers, prep):
     masked_powers = self.runtime.powerchain(masked_byte, 7)
     byte_powers = map(operator.add, masked_powers, random_powers)[1:]
     if prep:
         byte_powers = [Share(self.runtime, GF256, value)
                        for value in byte_powers]
     while len(byte_powers) > 1:
         byte_powers.append(byte_powers.pop(0) * byte_powers.pop(0))
     return byte_powers[0]
Exemplo n.º 29
0
 def preprocess(self, input):
     if isinstance(input, str):
         return [Share(self.runtime, GF256, GF256(ord(c))) for c in input]
     else:
         for byte in input:
             assert byte.field == GF256, \
                 "Input must be a list of GF256 elements " \
                 "or of shares thereof."
         return input
Exemplo n.º 30
0
def vc_input_predist(runtime, blockname):
    """ Import inputs that were pre-distributed via vc_share_offline. Returns VcShares. """
    vals = vc_read_values(vc_directory + "geppblk." + blockname + my_suffix)
    importer = lambda x: VcShare.from_share(
        runtime, Share(runtime, runtime.Zp, runtime.Zp(x)))
    vcs = map(importer, vals[:-1])
    rnd1 = importer(vals[-1])
    (qp, bn, _, _, _) = vc_declare_block(runtime, vcs, rnd1)
    print >> qap, "[input]", qp, bn, blockname
    return vcs
Exemplo n.º 31
0
 def exchange(share):
     # Send share to all receivers.
     for peer_id in receivers:
         if peer_id != self.id:
             pc = tuple(self.program_counter)
             self.protocols[peer_id].sendShare(pc, share)
     # Receive and recombine shares if this player is a receiver.
     if self.id in receivers:
         deferreds = []
         for peer_id in self.players:
             if peer_id == self.id:
                 d = Share(self, share.field,
                           (share.field(peer_id), share))
             else:
                 d = self._expect_share(peer_id, share.field)
                 d.addCallback(lambda s, peer_id: (s.field(peer_id), s),
                               peer_id)
             deferreds.append(d)
         return recombine(deferreds)
Exemplo n.º 32
0
    def greater_than_equal(self, share_a, share_b):
        """Compute ``share_a >= share_b``.

        Both arguments must be shares from the same field. The result
        is a new 0/1 share from the field.
        """
        # TODO: Make all input-taking methods do coercion like this.
        field = getattr(share_a, "field", getattr(share_b, "field", None))
        if not isinstance(share_a, Share):
            if not isinstance(share_a, FieldElement):
                share_a = field(share_a)
            share_a = Share(self, field, share_a)
        if not isinstance(share_b, Share):
            if not isinstance(share_b, FieldElement):
                share_b = field(share_b)
            share_b = Share(self, field, share_b)

        preproc = self.greater_than_equal_preproc(field)
        return self.greater_than_equal_online(share_a, share_b, preproc, field)
Exemplo n.º 33
0
 def finish(square, share, binary):
     if square == 0:
         # We were unlucky, try again...
         return self.prss_share_random(field, binary)
     else:
         # We can finish the calculation
         root = square.sqrt()
         # When the root is computed, we divide the share and
         # convert the resulting -1/1 share into a 0/1 share.
         return Share(self, field, (share / root + 1) / 2)
Exemplo n.º 34
0
        def finish_mul((a, b)):
            pc = tuple(self.program_counter)
            send_data = self.protocols[self.peer.id].sendData

            if hash(pc) % 2 == self.id:
                # We play the role of P1.
                a1, b1 = a, b
                enc_a1 = encrypt(a1.value, self.player.pubkey)
                enc_b1 = encrypt(b1.value, self.player.pubkey)
                send_data(pc, PAILLIER, str(enc_a1))
                send_data(pc, PAILLIER, str(enc_b1))

                enc_c1 = Share(self, field)
                self._expect_data(self.peer.id, PAILLIER, enc_c1)
                c1 = enc_c1.addCallback(decrypt, self.player.seckey)
                c1.addCallback(lambda c: long(c) + a1 * b1)
                return c1
            else:
                # We play the role of P2.
                a2, b2 = a, b
                enc_a1 = Deferred()
                self._expect_data(self.peer.id, PAILLIER, enc_a1)
                enc_a1.addCallback(long)
                enc_b1 = Deferred()
                self._expect_data(self.peer.id, PAILLIER, enc_b1)
                enc_b1.addCallback(long)

                nsq = self.peer.pubkey['n']**2
                # Calculate a1 * b2 and b1 * a2 inside the encryption.
                enc_a1_b2 = enc_a1.addCallback(pow, b2.value, nsq)
                enc_b1_a2 = enc_b1.addCallback(pow, a2.value, nsq)

                # Chose and encrypt r.
                r = rand.randint(0, 2 * field.modulus**2 + 2**k)
                enc_r = encrypt(r, self.peer.pubkey)

                c1 = gatherResults([enc_a1_b2, enc_b1_a2])
                c1.addCallback(lambda (a,b): a * b * enc_r)
                c1.addCallback(lambda c: send_data(pc, PAILLIER, str(c)))

                c2 = a2 * b2 - r
                return Share(self, field, c2)
Exemplo n.º 35
0
        def finish_mul((a, b)):
            pc = tuple(self.program_counter)
            send_data = self.protocols[self.peer.id].sendData

            if hash(pc) % 2 == self.id:
                # We play the role of P1.
                a1, b1 = a, b
                enc_a1 = encrypt(a1.value, self.player.pubkey)
                enc_b1 = encrypt(b1.value, self.player.pubkey)
                send_data(pc, PAILLIER, str(enc_a1))
                send_data(pc, PAILLIER, str(enc_b1))

                enc_c1 = Share(self, field)
                self._expect_data(self.peer.id, PAILLIER, enc_c1)
                c1 = enc_c1.addCallback(decrypt, self.player.seckey)
                c1.addCallback(lambda c: long(c) + a1 * b1)
                return c1
            else:
                # We play the role of P2.
                a2, b2 = a, b
                enc_a1 = Deferred()
                self._expect_data(self.peer.id, PAILLIER, enc_a1)
                enc_a1.addCallback(long)
                enc_b1 = Deferred()
                self._expect_data(self.peer.id, PAILLIER, enc_b1)
                enc_b1.addCallback(long)

                nsq = self.peer.pubkey['n']**2
                # Calculate a1 * b2 and b1 * a2 inside the encryption.
                enc_a1_b2 = enc_a1.addCallback(pow, b2.value, nsq)
                enc_b1_a2 = enc_b1.addCallback(pow, a2.value, nsq)

                # Chose and encrypt r.
                r = rand.randint(0, 2 * field.modulus**2 + 2**k)
                enc_r = encrypt(r, self.peer.pubkey)

                c1 = gatherResults([enc_a1_b2, enc_b1_a2])
                c1.addCallback(lambda (a, b): a * b * enc_r)
                c1.addCallback(lambda c: send_data(pc, PAILLIER, str(c)))

                c2 = a2 * b2 - r
                return Share(self, field, c2)
Exemplo n.º 36
0
    def prss_share(self, inputters, field, element=None):
        """Creates pseudo-random secret sharings.

        This protocol creates a secret sharing for each player in the
        subset of players specified in *inputters*. Each inputter
        provides an integer. The result is a list of shares, one for
        each inputter.

        The protocol uses the pseudo-random secret sharing technique
        described in the paper "Share Conversion, Pseudorandom
        Secret-Sharing and Applications to Secure Computation" by
        Ronald Cramer, Ivan Damgård, and Yuval Ishai in Proc. of TCC
        2005, LNCS 3378. `Download
        <http://www.cs.technion.ac.il/~yuvali/pubs/CDI05.ps>`__

        Communication cost: Each inputter does one broadcast.
        """
        # Verifying parameters.
        if element is None:
            assert self.id not in inputters, "No element given."
        else:
            assert self.id in inputters, \
                "Element given, but we are not sharing?"

        n = self.num_players

        # Key used for PRSS.
        key = self.prss_key()

        # The shares for which we have all the keys.
        all_shares = []

        # Shares we calculate from doing PRSS with the other players.
        tmp_shares = {}

        prfs = self.players[self.id].dealer_prfs(field.modulus)

        # Compute and broadcast correction value.
        if self.id in inputters:
            for player in self.players:
                share = prss(n, player, field, prfs[self.id], key)
                all_shares.append((field(player), share))
            shared = shamir.recombine(all_shares[:self.threshold+1])
            correction = element - shared
            # if this player is inputter then broadcast correction value
            # TODO: more efficient broadcast?
            pc = tuple(self.program_counter)
            for peer_id in self.players:
                if self.id != peer_id:
                    self.protocols[peer_id].sendShare(pc, correction)

        # Receive correction value from inputters and compute share.
        result = []
        for player in inputters:
            tmp_shares[player] = prss(n, self.id, field, prfs[player], key)
            if player == self.id:
                d = Share(self, field, correction)
            else:
                d = self._expect_share(player, field)
            d.addCallback(lambda c, s: s + c, tmp_shares[player])
            result.append(d)

        # Unpack a singleton list.
        if len(result) == 1:
            return result[0]
        else:
            return result
Exemplo n.º 37
0
 def __init__(self, runtime, field, value=None, rho=None, commitment=None):
     self.share = value
     self.rho = rho
     self.commitment = commitment
     Share.__init__(self, runtime, field, (value, rho, commitment))
Exemplo n.º 38
0
    def shift(self, inputters, field, number=None):
        """Shift of a share.

        Useful for input.

        Communication cost: ???.

        Assume the parties are given a random share ``[r]`` by a
        trusted dealer. Then we denote the following protocol but
        ``[x] = Shift(P_i, x, [r])``.

        1. ``r = OpenTo(P_i, [r])``

        2. ``P_i broadcasts Delta = r - x``

        3. ``[x] = [r] - Delta``
        """
        # TODO: Communitcation costs?
        assert (self.id in inputters and number is not None) or (self.id not in inputters)

        self.increment_pc()

        results = []
        def hack(_, peer_id):
            # Assume the parties are given a random share [r] by a
            # trusted dealer.
            share_r = self.random_share(field)
            # 1. r = OpenTo(P_i, [r])
            open_r = self.open(share_r, [peer_id])
            def subtract_delta(delta, share_r):
                delta = field(long(delta))
                x = self.sub(share_r, delta)
                return x
            if peer_id == self.id:
                def g(r, x):
                    delta = r - x
                    delta = self.broadcast([peer_id], self.players.keys(),
                                           str(delta.value))
                    self.schedule_callback(delta, subtract_delta, share_r)
                    delta.addErrback(self.error_handler)
                    return delta
                self.schedule_callback(open_r, g, number)
                open_r.addErrback(self.error_handler)
                return open_r
            else:
                d = Deferred()
                def g(_, peer_id, share_r):
                    delta = self.broadcast([peer_id], self.players.keys())
                    self.schedule_callback(delta, subtract_delta, share_r)
                    delta.addErrback(self.error_handler)
                    return delta
                self.schedule_callback(d, g, peer_id, share_r)
                d.addErrback(self.error_handler)
                d.callback(None)
                return d

        for peer_id in inputters:
            s = Share(self, field)
            self.schedule_callback(s, hack, peer_id)
            s.addErrback(self.error_handler)
            s.callback(None)
            results.append(s)

        # do actual communication
        self.activate_reactor()

        if len(results) == 1:
             return results[0]
        return results