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 wrap: on
line diff
--- a/viff/bedoza.py	Wed Jul 07 16:31:50 2010 +0200
+++ b/viff/bedoza.py	Thu Jul 08 10:36:21 2010 +0200
@@ -21,7 +21,7 @@
 
 from viff.runtime import Runtime, Share, ShareList, gather_shares
 from viff.field import FieldElement
-
+from viff.constants import TEXT
 from viff.simplearithmetic import SimpleArithmetic
 
 from hash_broadcast import HashBroadcastMixin
@@ -200,6 +200,86 @@
     def output(self, share, receivers=None):
         return self.open(share, receivers)
 
+    def open_multiple_values(self, shares, receivers=None):
+        """Share reconstruction of a list of shares."""
+        assert shares
+        # all players receive result by default
+        if receivers is None:
+            receivers = self.players.keys()
+
+        field = shares[0].field
+
+        self.increment_pc()
+
+        def recombine_value(player_shares_codes, keyList, num_shares):
+            def check(ls, x, isOK):
+                true_str = str(True)
+                if reduce(lambda x, y: true_str == y, ls):
+                    return x
+                else:
+                    raise BeDOZaException("Wrong commitment. Some player revieved a wrong commitment. My commitments were: %s", isOK)
+
+            n = len(self.players)
+            alpha = keyList.alpha
+            keys = keyList.keys
+
+            values = num_shares * [0]
+            isOK = num_shares * [True]
+            for iny in xrange(num_shares):
+                for inx, xs in enumerate(player_shares_codes):
+                    xi, mi = xs[iny]
+                    beta = keys[inx]
+                    values[iny] += xi
+                    mi_prime = self.MAC(alpha, beta, xi)
+                    isOK[iny] = isOK[iny] and mi == mi_prime
+
+            isOK = reduce(lambda x, y: True == y, isOK)
+            ds = self.broadcast(self.players.keys(), self.players.keys(),
+                                str(isOK))
+            ds = gatherResults(ds)
+            ds.addCallbacks(check, self.error_handler, callbackArgs=(values, isOK))
+            return ds
+        
+        def exchange(ls, receivers):
+            # Send share to all receivers.
+            pc = tuple(self.program_counter)
+            for other_id in receivers:
+                # self.protocols[other_id].sendShare(pc, xi)
+                # self.protocols[other_id].sendShare(pc, codes.auth_codes[other_id - 1])
+                message_string = ""
+                for inx, (xi, keyList, codes) in enumerate(ls):
+                    message_string += "%s:%s;" % \
+                           (xi.value, codes.auth_codes[other_id - 1].value)
+                self.protocols[other_id].sendData(pc, TEXT, message_string)
+
+            if self.id in receivers:
+                def deserialize(s):
+                    def field_long(x):
+                        return field(long(x))
+                    xs = s[0:-1].split(';')
+                    ys = [x.split(':') for x in xs]
+                    return [map(field_long, xs) for xs in ys]
+                num_players = len(self.players.keys())
+                values = num_players * [None]
+                for inx, other_id in enumerate(self.players.keys()):
+                    d = Deferred()
+                    d.addCallbacks(deserialize, self.error_handler)
+                    self._expect_data(other_id, TEXT, d)
+                    values[inx] = d
+                result = gatherResults(values)
+                result.addCallbacks(recombine_value, self.error_handler, callbackArgs=(keyList, len(shares)))
+                return result
+
+        result = gather_shares(shares)
+        self.schedule_callback(result, exchange, receivers)
+        result.addErrback(self.error_handler)
+
+        # do actual communication
+        self.activate_reactor()
+
+        if self.id in receivers:
+            return result
+        
     def open(self, share, receivers=None):
         """Share reconstruction."""
         assert isinstance(share, Share)
--- a/viff/test/test_bedoza_runtime.py	Wed Jul 07 16:31:50 2010 +0200
+++ b/viff/test/test_bedoza_runtime.py	Thu Jul 08 10:36:21 2010 +0200
@@ -430,3 +430,19 @@
         d = runtime.open(z2)
         d.addCallback(check)
         return d
+
+    @protocol
+    def test_open_multiple_secret_share(self, runtime):
+        """Test sharing and open of a number."""
+
+        self.Zp = GF(6277101735386680763835789423176059013767194773182842284081)
+
+        def check(ls):
+            for v in ls:
+                self.assertEquals(v, 6)
+
+        x = runtime.random_share(self.Zp)
+        y = runtime.random_share(self.Zp)
+        d = runtime.open_multiple_values([x, y])
+        d.addCallback(check)
+        return d