changeset 1449:04a121c3b6a5

Added an open operation.
author Janus Dam Nielsen <janus.nielsen@alexandra.dk>
date Mon, 05 Jul 2010 11:34:00 +0200
parents 3c21042745e7
children d910c8a78a2e
files viff/bedoza.py viff/test/test_bedoza_runtime.py
diffstat 2 files changed, 81 insertions(+), 2 deletions(-) [+]
line wrap: on
line diff
--- a/viff/bedoza.py	Mon Jul 05 11:33:58 2010 +0200
+++ b/viff/bedoza.py	Mon Jul 05 11:34:00 2010 +0200
@@ -19,10 +19,13 @@
 
 from twisted.internet.defer import Deferred, gatherResults, succeed
 
-from viff.runtime import Runtime, Share
+from viff.runtime import Runtime, Share, ShareList
 
 from hash_broadcast import HashBroadcastMixin
 
+class BeDOZaException(Exception):
+    pass
+
 class BeDOZaShare(Share):
     """A share in the BeDOZa runtime.
 
@@ -125,6 +128,69 @@
 
         return self.random_shares.pop()
 
+    def open(self, share, receivers=None):
+        """Share reconstruction.
+ 
+        Every partyi broadcasts a share pair ``(x_i', rho_x,i')``.
+
+        The parties compute the sums ``x'``, ``rho_x'`` and check
+        ``Com_ck(x',rho_x') = C_x``.
+
+        If yes, return ``x = x'``, else else return :const:`None`.
+        """
+        assert isinstance(share, Share)
+        # all players receive result by default
+        if receivers is None:
+            receivers = self.players.keys()
+
+        field = share.field
+
+        self.increment_pc()
+
+        def recombine_value(shares_codes):
+            isOK = True
+            n = len(self.players)
+            alpha = self.get_keys()[0]
+            keys = self.get_keys()[1]
+            x = 0
+            for inx in xrange(0, n):
+                xi = shares_codes[inx]
+                mi = shares_codes[n + inx]
+                beta = keys[inx]
+                x += xi
+                isOK = isOK and mi == self.MAC(alpha, beta, xi)
+            if not isOK:
+                raise BeDOZaException("Wrong commitment for value %s." % x)
+            return x
+
+        def exchange((xi, codes), 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[other_id - 1])
+
+            if self.id in receivers:
+                num_players = len(self.players.keys())
+                values = num_players * [None]
+                codes = num_players * [None]
+                for inx, other_id in enumerate(self.players.keys()):
+                    values[inx] =  self._expect_share(other_id, field)
+                    codes[inx] = self._expect_share(other_id, field)
+                result = gatherResults(values + codes)
+                result.addCallbacks(recombine_value, self.error_handler)
+                return result
+
+        result = share.clone()
+        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 get_keys(self):
         if self.id == 1:
             return self.keys[1]
--- a/viff/test/test_bedoza_runtime.py	Mon Jul 05 11:33:58 2010 +0200
+++ b/viff/test/test_bedoza_runtime.py	Mon Jul 05 11:34:00 2010 +0200
@@ -107,4 +107,17 @@
 
     runtime_class = BeDOZaRuntime
 
-BeDOZaBasicCommandsTest.skip = "Skipped because the tested code is not implemented."
+    @protocol
+    def test_random_share(self, runtime):
+        """Test creation of a random shared number."""
+
+        self.Zp = GF(6277101735386680763835789423176059013767194773182842284081)
+
+        def check(v):
+            self.assertEquals(True, True)
+
+        x = runtime.random_share(self.Zp)
+        d = runtime.open(x)
+        d.addCallback(check)
+        return d
+