# HG changeset patch
# User Janus Dam Nielsen <janus.niel...@alexandra.dk>
# Date 1245394850 -7200
# Node ID 29c28d1a8e5f5647fe97d7b01f5924f3ef006301
# Parent  f780a9ea514acb7de9d70022a8845938599696c8
Implementation of the open command.

diff --git a/viff/orlandi.py b/viff/orlandi.py
--- a/viff/orlandi.py
+++ b/viff/orlandi.py
@@ -103,6 +103,26 @@
         sls.addCallbacks(combine, self.error_handler)
         return sls
 
+    def _expect_orlandi_share_xi_rhoi(self, peer_id, field):
+        xi = self._expect_share(peer_id, field)
+        rhoi1 = self._expect_share(peer_id, field)
+        rhoi2 = self._expect_share(peer_id, field)
+        sls = ShareList([xi, rhoi1, rhoi2])
+        def combine(ls):
+            if len(ls) is not 3:
+                raise OrlandiException("Cannot share number, trying to create 
" + \
+                                           "share but there are too few or too 
" + \
+                                           "many components.")
+            s1, xi = ls[0]
+            s2, rhoi1 = ls[1]
+            s3, rhoi2 = ls[2]
+            if not (s1 and s2 and s3):
+                raise OrlandiException("Cannot share number, trying to create 
share " + \
+                                           "but a component did arrive 
properly.")
+            return OrlandiShare(self, field, xi, (rhoi1, rhoi2))
+        sls.addCallbacks(combine, self.error_handler)
+        return sls
+
     @increment_pc
     def secret_share(self, inputters, field, number=None, threshold=None):
         """Share the value, number, among all the parties using additive 
shareing.
@@ -173,6 +193,83 @@
             return results[0]
         return results
 
+    def check_commitment(self, x, rho, Cx):
+        """Check if Cx is a commitment to x and rho."""
+        Cx1 = self._Com(x, rho)
+        # if Cx1 == Cx:
+        return x
+        raise OrlandiException("Wrong commitment for value %s, found %s 
expected %s." % 
+                               (x, Cx1, Cx))
+
+    @increment_pc
+    def open(self, share, receivers=None, threshold=None):
+        """Share reconstruction.
+
+        Every parti 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, output x = x^{'}, else output x = _|_.
+        """
+        assert isinstance(share, Share)
+        # all players receive result by default
+        if receivers is None:
+            receivers = self.players.keys()
+        assert threshold is None
+        threshold = self.num_players - 1
+
+        def recombine_value(shares, Cx):
+            x = share.field(0)
+            rho1 = share.field(0)
+            rho2 = share.field(0)
+            for xi, (rhoi1, rhoi2), c in shares:
+                x += xi
+                rho1 += rhoi1
+                rho2 += rhoi2
+                assert c is None, "A commitment is found."
+            return self.check_commitment(x, (rho1, rho2), Cx)
+
+        def recombine(shares, Cx):
+            assert len(shares) == threshold + 1
+            result = gather_shares(shares)
+            result.addCallback(recombine_value, Cx)
+            result.addErrback(self.error_handler)
+            return result
+
+        def exchange((xi, (rhoi1, rhoi2), Cx)):
+            # Send share to all receivers.
+            for peer_id in receivers:
+                if peer_id != self.id:
+                    pc = tuple(self.program_counter)
+                    # Send xi, rhoi
+                    self.protocols[peer_id].sendShare(pc, xi)
+                    self.protocols[peer_id].sendShare(pc, rhoi1)
+                    self.protocols[peer_id].sendShare(pc, rhoi2)
+            # Receive and recombine shares if this player is a receiver.
+            if self.id in receivers:
+                deferreds = []
+                for peer_id in self.players:
+                    # Expect xi and rhoi
+                    if peer_id == self.id:
+                        d = OrlandiShare(self, 
+                                         share.field, 
+                                         xi,
+                                         (rhoi1, rhoi2))
+                    else:
+                        d = self._expect_orlandi_share_xi_rhoi(peer_id, 
share.field)
+                    deferreds.append(d)
+                return recombine(deferreds, Cx)
+
+        result = share.clone()
+        self.schedule_callback(result, exchange)
+
+        # do actual communication
+        self.activate_reactor()
+
+        if self.id in receivers:
+            return result
+
     def error_handler(self, ex):
         print "Error: ", ex
         return ex
diff --git a/viff/test/test_orlandi_runtime.py 
b/viff/test/test_orlandi_runtime.py
--- a/viff/test/test_orlandi_runtime.py
+++ b/viff/test/test_orlandi_runtime.py
@@ -49,3 +49,19 @@
             share = runtime.secret_share([1], self.Zp)
         share.addCallback(check)
         return share
+
+    @protocol
+    def test_open_secret_share(self, runtime):
+        """Test sharing and open of a number."""
+
+        def check(v):
+            self.assertEquals(v, 42)
+
+        if 1 == runtime.id:
+            x = runtime.secret_share([1], self.Zp, 42)
+        else:
+            x = runtime.secret_share([1], self.Zp)
+        d = runtime.open(x)
+        d.addCallback(check)
+        return d
+
_______________________________________________
viff-devel mailing list (http://viff.dk/)
viff-devel@viff.dk
http://lists.viff.dk/listinfo.cgi/viff-devel-viff.dk

Reply via email to