viff

changeset 1479:aa1c7d6c98ca

BeDOZa: Implemented open of multiple shares.
author Janus Dam Nielsen <janus.nielsen@alexandra.dk>
date Thu, 08 Jul 2010 10:36:21 +0200
parents 71012e8c4be5
children b0975eaed9bb
files viff/bedoza.py viff/test/test_bedoza_runtime.py
diffstat 2 files changed, 97 insertions(+), 1 deletions(-) [+]
line diff
     1.1 --- a/viff/bedoza.py	Wed Jul 07 16:31:50 2010 +0200
     1.2 +++ b/viff/bedoza.py	Thu Jul 08 10:36:21 2010 +0200
     1.3 @@ -21,7 +21,7 @@
     1.4  
     1.5  from viff.runtime import Runtime, Share, ShareList, gather_shares
     1.6  from viff.field import FieldElement
     1.7 -
     1.8 +from viff.constants import TEXT
     1.9  from viff.simplearithmetic import SimpleArithmetic
    1.10  
    1.11  from hash_broadcast import HashBroadcastMixin
    1.12 @@ -200,6 +200,86 @@
    1.13      def output(self, share, receivers=None):
    1.14          return self.open(share, receivers)
    1.15  
    1.16 +    def open_multiple_values(self, shares, receivers=None):
    1.17 +        """Share reconstruction of a list of shares."""
    1.18 +        assert shares
    1.19 +        # all players receive result by default
    1.20 +        if receivers is None:
    1.21 +            receivers = self.players.keys()
    1.22 +
    1.23 +        field = shares[0].field
    1.24 +
    1.25 +        self.increment_pc()
    1.26 +
    1.27 +        def recombine_value(player_shares_codes, keyList, num_shares):
    1.28 +            def check(ls, x, isOK):
    1.29 +                true_str = str(True)
    1.30 +                if reduce(lambda x, y: true_str == y, ls):
    1.31 +                    return x
    1.32 +                else:
    1.33 +                    raise BeDOZaException("Wrong commitment. Some player revieved a wrong commitment. My commitments were: %s", isOK)
    1.34 +
    1.35 +            n = len(self.players)
    1.36 +            alpha = keyList.alpha
    1.37 +            keys = keyList.keys
    1.38 +
    1.39 +            values = num_shares * [0]
    1.40 +            isOK = num_shares * [True]
    1.41 +            for iny in xrange(num_shares):
    1.42 +                for inx, xs in enumerate(player_shares_codes):
    1.43 +                    xi, mi = xs[iny]
    1.44 +                    beta = keys[inx]
    1.45 +                    values[iny] += xi
    1.46 +                    mi_prime = self.MAC(alpha, beta, xi)
    1.47 +                    isOK[iny] = isOK[iny] and mi == mi_prime
    1.48 +
    1.49 +            isOK = reduce(lambda x, y: True == y, isOK)
    1.50 +            ds = self.broadcast(self.players.keys(), self.players.keys(),
    1.51 +                                str(isOK))
    1.52 +            ds = gatherResults(ds)
    1.53 +            ds.addCallbacks(check, self.error_handler, callbackArgs=(values, isOK))
    1.54 +            return ds
    1.55 +        
    1.56 +        def exchange(ls, receivers):
    1.57 +            # Send share to all receivers.
    1.58 +            pc = tuple(self.program_counter)
    1.59 +            for other_id in receivers:
    1.60 +                # self.protocols[other_id].sendShare(pc, xi)
    1.61 +                # self.protocols[other_id].sendShare(pc, codes.auth_codes[other_id - 1])
    1.62 +                message_string = ""
    1.63 +                for inx, (xi, keyList, codes) in enumerate(ls):
    1.64 +                    message_string += "%s:%s;" % \
    1.65 +                           (xi.value, codes.auth_codes[other_id - 1].value)
    1.66 +                self.protocols[other_id].sendData(pc, TEXT, message_string)
    1.67 +
    1.68 +            if self.id in receivers:
    1.69 +                def deserialize(s):
    1.70 +                    def field_long(x):
    1.71 +                        return field(long(x))
    1.72 +                    xs = s[0:-1].split(';')
    1.73 +                    ys = [x.split(':') for x in xs]
    1.74 +                    return [map(field_long, xs) for xs in ys]
    1.75 +                num_players = len(self.players.keys())
    1.76 +                values = num_players * [None]
    1.77 +                for inx, other_id in enumerate(self.players.keys()):
    1.78 +                    d = Deferred()
    1.79 +                    d.addCallbacks(deserialize, self.error_handler)
    1.80 +                    self._expect_data(other_id, TEXT, d)
    1.81 +                    values[inx] = d
    1.82 +                result = gatherResults(values)
    1.83 +                result.addCallbacks(recombine_value, self.error_handler, callbackArgs=(keyList, len(shares)))
    1.84 +                return result
    1.85 +
    1.86 +        result = gather_shares(shares)
    1.87 +        self.schedule_callback(result, exchange, receivers)
    1.88 +        result.addErrback(self.error_handler)
    1.89 +
    1.90 +        # do actual communication
    1.91 +        self.activate_reactor()
    1.92 +
    1.93 +        if self.id in receivers:
    1.94 +            return result
    1.95 +        
    1.96      def open(self, share, receivers=None):
    1.97          """Share reconstruction."""
    1.98          assert isinstance(share, Share)
     2.1 --- a/viff/test/test_bedoza_runtime.py	Wed Jul 07 16:31:50 2010 +0200
     2.2 +++ b/viff/test/test_bedoza_runtime.py	Thu Jul 08 10:36:21 2010 +0200
     2.3 @@ -430,3 +430,19 @@
     2.4          d = runtime.open(z2)
     2.5          d.addCallback(check)
     2.6          return d
     2.7 +
     2.8 +    @protocol
     2.9 +    def test_open_multiple_secret_share(self, runtime):
    2.10 +        """Test sharing and open of a number."""
    2.11 +
    2.12 +        self.Zp = GF(6277101735386680763835789423176059013767194773182842284081)
    2.13 +
    2.14 +        def check(ls):
    2.15 +            for v in ls:
    2.16 +                self.assertEquals(v, 6)
    2.17 +
    2.18 +        x = runtime.random_share(self.Zp)
    2.19 +        y = runtime.random_share(self.Zp)
    2.20 +        d = runtime.open_multiple_values([x, y])
    2.21 +        d.addCallback(check)
    2.22 +        return d