viff

changeset 1395:3ede8d56ae64

Merged with Janus.
author Janus Dam Nielsen <janus.nielsen@alexandra.dk>
date Thu, 12 Nov 2009 11:22:24 +0100
parents 86d966f49a8a ff5f3ce6501c
children 866a0167ddeb
files viff/orlandi.py
diffstat 2 files changed, 102 insertions(+), 4 deletions(-) [+]
line diff
     1.1 --- a/viff/orlandi.py	Thu Nov 12 10:43:59 2009 +0100
     1.2 +++ b/viff/orlandi.py	Thu Nov 12 11:22:24 2009 +0100
     1.3 @@ -282,6 +282,81 @@
     1.4          if self.id in receivers:
     1.5              return result
     1.6  
     1.7 +    def open_multiple_values(self, shares, receivers=None):
     1.8 +        """Share reconstruction.
     1.9 +
    1.10 +        Open multiple values in one burst. 
    1.11 +        If called with one value it is slower than the open method.
    1.12 +        If called with more than two values it is faster than using 
    1.13 +        multiple calls to the open method. 
    1.14 +
    1.15 +        Every partyi broadcasts a share pair ``(x_i', rho_x,i')``.
    1.16 +
    1.17 +        The parties compute the sums ``x'``, ``rho_x'`` and check
    1.18 +        ``Com_ck(x',rho_x') = C_x``.
    1.19 +
    1.20 +        If yes, return ``x = x'``, else else return :const:`None`.
    1.21 +        """
    1.22 +        assert shares
    1.23 +        # all players receive result by default
    1.24 +        if receivers is None:
    1.25 +            receivers = self.players.keys()
    1.26 +
    1.27 +        field = shares[0].field
    1.28 +
    1.29 +        self.increment_pc()
    1.30 +
    1.31 +        def recombine_value((shares, Cx)):
    1.32 +            x = 0
    1.33 +            rho1 = 0
    1.34 +            rho2 = 0
    1.35 +            for xi, rhoi1, rhoi2 in shares:
    1.36 +                x += xi
    1.37 +                rho1 += rhoi1
    1.38 +                rho2 += rhoi2
    1.39 +            Cx1 = commitment.commit(x.value, rho1.value, rho2.value)
    1.40 +            if Cx1 == Cx:
    1.41 +                return x
    1.42 +            else:
    1.43 +                #return x
    1.44 +                raise OrlandiException("Wrong commitment for value %s, %s, %s, found %s expected %s." %
    1.45 +                                       (x, rho1, rho2, Cx1, Cx))
    1.46 +
    1.47 +        def deserialize(ls, commitments):
    1.48 +            def convert_from_string_to_field(s):
    1.49 +                def field_long(x):
    1.50 +                    return field(long(x))
    1.51 +                xs = s[0:-1].split(';')
    1.52 +                ys = [x.split(':') for x in xs]
    1.53 +                return [map(field_long, xs) for xs in ys]
    1.54 +            shares = map(convert_from_string_to_field, ls)
    1.55 +            return map(recombine_value, zip(zip(*shares), commitments))
    1.56 +
    1.57 +        def exchange(ls, receivers):
    1.58 +            commitments = [None] * len(ls)
    1.59 +            broadcast_string = ""
    1.60 +            for inx, (xi, (rhoi1, rhoi2), Cx) in enumerate(ls):
    1.61 +                broadcast_string += "%s:%s:%s;" % (xi.value, rhoi1.value, rhoi2.value)
    1.62 +                commitments[inx] = (Cx)
    1.63 +            # Send share to all receivers.
    1.64 +            ds = self.broadcast(self.players.keys(), receivers, broadcast_string)
    1.65 +
    1.66 +            if self.id in receivers:
    1.67 +                result = gatherResults(ds)
    1.68 +                result.addCallbacks(deserialize, self.error_handler,
    1.69 +                                    callbackArgs=(commitments,))
    1.70 +                return result
    1.71 +
    1.72 +        result = gather_shares(shares)
    1.73 +        self.schedule_callback(result, exchange, receivers)
    1.74 +        result.addErrback(self.error_handler)
    1.75 +
    1.76 +        # do actual communication
    1.77 +        self.activate_reactor()
    1.78 +
    1.79 +        if self.id in receivers:
    1.80 +            return result
    1.81 +
    1.82      def random_share(self, field):
    1.83          """Generate a random share in the field, field.
    1.84  
    1.85 @@ -611,7 +686,9 @@
    1.86          if cmul_result is  not None:
    1.87              return cmul_result
    1.88  
    1.89 -        def multiply((x, y, d, e, c)):
    1.90 +        def multiply((x, y, ds, c)):
    1.91 +            d = ds[0]
    1.92 +            e = ds[1]
    1.93              # [de]
    1.94              de = self._additive_constant(field(0), d * e)
    1.95              # e[x]
    1.96 @@ -627,10 +704,9 @@
    1.97              return OrlandiShare(self, field, zi, rhoz, Cz)
    1.98  
    1.99          # d = Open([x] - [a])
   1.100 -        d = self.open(share_x - triple_a)
   1.101          # e = Open([y] - [b])
   1.102 -        e = self.open(share_y - triple_b)
   1.103 -        result = gather_shares([share_x, share_y, d, e, triple_c])
   1.104 +        ds = self.open_multiple_values([share_x - triple_a, share_y - triple_b])
   1.105 +        result = gather_shares([share_x, share_y, ds, triple_c])
   1.106          result.addCallbacks(multiply, self.error_handler)
   1.107  
   1.108          # do actual communication
     2.1 --- a/viff/test/test_orlandi_runtime.py	Thu Nov 12 10:43:59 2009 +0100
     2.2 +++ b/viff/test/test_orlandi_runtime.py	Thu Nov 12 11:22:24 2009 +0100
     2.3 @@ -92,6 +92,28 @@
     2.4          return d
     2.5  
     2.6      @protocol
     2.7 +    def test_open_multiple_secret_share(self, runtime):
     2.8 +        """Test sharing and open of a number."""
     2.9 +
    2.10 +        self.Zp = GF(6277101735386680763835789423176059013767194773182842284081)
    2.11 +
    2.12 +        def check(ls):
    2.13 +            for inx, v in enumerate(ls):
    2.14 +                self.assertEquals(v, (inx + 1) * 42)
    2.15 +
    2.16 +        if 1 == runtime.id:
    2.17 +            x = runtime.secret_share([1], self.Zp, 42)
    2.18 +        else:
    2.19 +            x = runtime.secret_share([1], self.Zp)
    2.20 +        if 1 == runtime.id:
    2.21 +            y = runtime.secret_share([1], self.Zp, 84)
    2.22 +        else:
    2.23 +            y = runtime.secret_share([1], self.Zp)
    2.24 +        d = runtime.open_multiple_values([x, y])
    2.25 +        d.addCallback(check)
    2.26 +        return d
    2.27 +
    2.28 +    @protocol
    2.29      def test_random_share(self, runtime):
    2.30          """Test creation of a random shared number."""
    2.31