changeset 1482:79ff80ee9810

Orlandi: Added a method for opening two shares in one batch.
author Janus Dam Nielsen <janus.nielsen@alexandra.dk>
date Thu, 08 Jul 2010 14:13:03 +0200
parents 2aa3bec0492e
children 32af54d63bce
files viff/orlandi.py viff/test/test_orlandi_runtime.py
diffstat 2 files changed, 89 insertions(+), 0 deletions(-) [+]
line wrap: on
line diff
--- a/viff/orlandi.py	Thu Jul 08 10:58:52 2010 +0200
+++ b/viff/orlandi.py	Thu Jul 08 14:13:03 2010 +0200
@@ -305,6 +305,73 @@
         if self.id in receivers:
             return result
 
+    def open_two_values(self, share_a, share_b, receivers=None):
+        """Share reconstruction of two shares."""
+        assert isinstance(share_a, Share)
+        assert isinstance(share_b, Share)
+        # all players receive result by default
+        if receivers is None:
+            receivers = self.players.keys()
+
+        field = share_a.field
+
+        self.increment_pc()
+
+        def recombine_value(shares, Ca, Cb):
+            a, b = 0, 0
+            rhoa1, rhob1 = 0, 0
+            rhoa2, rhob2 = 0, 0
+            for ai, rhoai1, rhoai2, bi, rhobi1, rhobi2 in shares:
+                a += ai
+                b += bi
+                rhoa1 += rhoai1
+                rhob1 += rhobi1
+                rhoa2 += rhoai2
+                rhob2 += rhobi2
+            Ca1 = commitment.commit(a.value, rhoa1.value, rhoa2.value)
+            Cb1 = commitment.commit(b.value, rhob1.value, rhob2.value)
+            if Ca1 == Ca and Cb1 == Cb:
+                return a, b
+            else:
+                #return x
+                raise OrlandiException("Wrong commitment for value %s, %s, %s, %s, %s, %s, found %s, %s expected %s, %s." %
+                                       (a, rhoa1, rhoa2, b, rhob1, rhob2, Ca1, Cb1, Ca, Cb))
+
+        def deserialize(ls):
+            shares = [(field(long(ai)), field(long(rhoa1)), field(long(rhoa2)),
+                       field(long(bi)), field(long(rhob1)), field(long(rhob2)))
+                      for ai, rhoa1, rhoa2, bi, rhob1, rhob2 in map(self.list_str, ls)]
+            return shares
+
+        def exchange((a, b), receivers):
+            (ai, (rhoai1, rhoai2), Ca) = a
+            (bi, (rhobi1, rhobi2), Cb) = b
+            # Send share to all receivers.
+            ds = self.broadcast(self.players.keys(), receivers,
+                                str((str(ai.value),
+                                     str(rhoai1.value),
+                                     str(rhoai2.value),
+                                     str(bi.value),
+                                     str(rhobi1.value),
+                                     str(rhobi2.value))))
+
+            if self.id in receivers:
+                result = gatherResults(ds)
+                result.addCallbacks(deserialize, self.error_handler)
+                result.addCallbacks(recombine_value, self.error_handler,
+                                    callbackArgs=(Ca, Cb))
+                return result
+
+        result = gather_shares([share_a, share_b])
+        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_multiple_values(self, shares, receivers=None):
         """Share reconstruction.
 
--- a/viff/test/test_orlandi_runtime.py	Thu Jul 08 10:58:52 2010 +0200
+++ b/viff/test/test_orlandi_runtime.py	Thu Jul 08 14:13:03 2010 +0200
@@ -126,6 +126,28 @@
         return d
 
     @protocol
+    def test_open_two_secret_share(self, runtime):
+        """Test sharing and open of a number."""
+
+        self.Zp = GF(6277101735386680763835789423176059013767194773182842284081)
+
+        def check((a, b)):
+            self.assertEquals(a, 42)
+            self.assertEquals(b, 84)
+
+        if 1 == runtime.id:
+            x = runtime.secret_share([1], self.Zp, 42)
+        else:
+            x = runtime.secret_share([1], self.Zp)
+        if 1 == runtime.id:
+            y = runtime.secret_share([1], self.Zp, 84)
+        else:
+            y = runtime.secret_share([1], self.Zp)
+        d = runtime.open_two_values(x, y)
+        d.addCallback(check)
+        return d
+
+    @protocol
     def test_random_share(self, runtime):
         """Test creation of a random shared number."""