changeset 1470:f27609bc4831

BeDOZa: Implemented basic multiplication.
author Janus Dam Nielsen <janus.nielsen@alexandra.dk>
date Wed, 07 Jul 2010 14:31:30 +0200
parents c2bb60bd132e
children 06b1b7647643
files viff/bedoza.py viff/test/test_bedoza_runtime.py
diffstat 2 files changed, 90 insertions(+), 0 deletions(-) [+]
line wrap: on
line diff
--- a/viff/bedoza.py	Wed Jul 07 14:31:27 2010 +0200
+++ b/viff/bedoza.py	Wed Jul 07 14:31:30 2010 +0200
@@ -371,3 +371,70 @@
                 triple_c = self.generate_share(field, share_c)
                 c += share_c.value
         return [triple_a, triple_b, triple_c]
+
+    def mul(self, share_x, share_y):
+        """Multiplication of shares."""
+        assert isinstance(share_x, Share) or isinstance(share_y, Share), \
+            "At least one of share_x and share_y must be a Share."
+
+        self.increment_pc()
+
+        field = getattr(share_x, "field", getattr(share_y, "field", None))
+
+        triple = self._get_triple(field)
+        return self._basic_multiplication(share_x, share_y, *triple)
+
+    def _basic_multiplication(self, share_x, share_y, triple_a, triple_b, triple_c):
+        """Multiplication of shares give a triple.
+
+        Communication cost: ???.
+
+        ``d = Open([x] - [a])``
+        ``e = Open([y] - [b])``
+        ``[z] = e[x] + d[y] - [de] + [c]``
+        """
+        assert isinstance(share_x, Share) or isinstance(share_y, Share), \
+            "At least one of share_x and share_y must be a Share."
+
+        self.increment_pc()
+
+        field = getattr(share_x, "field", getattr(share_y, "field", None))
+        n = field(0)
+
+        cmul_result = self._cmul(share_x, share_y, field)
+        if cmul_result is  not None:
+            return cmul_result
+
+        def multiply((x, y, c, d, e)):
+            # [de]
+            de = d * e
+            # e[x]
+            t1 = self._constant_multiply(x, e)
+            # d[y]
+            t2 = self._constant_multiply(y, d)
+            # d[y] - [de]
+            t3 = self._minus_public_right1(t2, de, field)
+            # d[y] - [de] + [c]
+            t4 = self._plus((t3, c), field)
+            # [z] = e[x] + d[y] - [de] + [c]
+            zi, zks, zms = self._plus((t1, t4), field)
+            return BeDOZaShare(self, field, zi, zks, zms)
+
+        #d = Open([x] - [a])
+        d = self.output(share_x - triple_a)
+        # e = Open([y] - [b])
+        e = self.output(share_y - triple_b)
+        result = gather_shares([share_x, share_y, triple_c, d, e])
+        result.addCallbacks(multiply, self.error_handler)
+
+        # do actual communication
+        self.activate_reactor()
+
+        return result
+
+    def _minus_public_right1(self, x, c, field):
+        (xi, xks, xms) = x
+        if self.id == 1:
+            xi = xi - c
+        xks.keys[0] = xks.keys[0] + xks.alpha * c
+        return xi, xks, xms
--- a/viff/test/test_bedoza_runtime.py	Wed Jul 07 14:31:27 2010 +0200
+++ b/viff/test/test_bedoza_runtime.py	Wed Jul 07 14:31:30 2010 +0200
@@ -116,6 +116,8 @@
 
     runtime_class = BeDOZaRuntime
 
+    timeout = 3
+    
     @protocol
     def test_random_share(self, runtime):
         """Test creation of a random shared number."""
@@ -348,3 +350,24 @@
         d = gather_shares([d1, d2, d3])
         d.addCallback(check)
         return d
+
+    @protocol
+    def test_basic_multiply(self, runtime):
+        """Test multiplication of two numbers."""
+
+        self.Zp = GF(6277101735386680763835789423176059013767194773182842284081)
+
+        x1 = 6
+        y1 = 6
+
+        def check(v):
+            self.assertEquals(v, x1 * y1)
+
+        x2 = runtime.random_share(self.Zp)
+        y2 = runtime.random_share(self.Zp)
+
+        a, b, c = runtime._get_triple(self.Zp)
+        z2 = runtime._basic_multiplication(x2, y2, a, b, c)
+        d = runtime.open(z2)
+        d.addCallback(check)
+        return d