changeset 1466:6b96a1fdb751

Merged.
author Janus Dam Nielsen <janus.nielsen@alexandra.dk>
date Wed, 07 Jul 2010 10:56:22 +0200
parents d09cd2050333 8779d6f6bad0
children f1d0c720a269
files
diffstat 5 files changed, 142 insertions(+), 24 deletions(-) [+]
line wrap: on
line diff
--- a/viff/bedoza.py	Tue Jul 06 15:21:05 2010 +0200
+++ b/viff/bedoza.py	Wed Jul 07 10:56:22 2010 +0200
@@ -295,12 +295,16 @@
         zms = xms + yms
         return (zi, zks, zms)
 
-    def _minus_public(self, x, c, field):
+    def _minus_public_right(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 BeDOZaShare(self, field, xi, xks, xms)
+
+    def _minus_public_left(self, x, c, field):
+        y = self._constant_multiply(x, field(-1))
+        return self._plus_public(y, c, field)
     
     def _minus(self, (x, y), field):
         """Subtraction of share-tuples *x* and *y*.
@@ -317,3 +321,36 @@
         zks = xks - yks
         zms = xms - yms
         return (zi, zks, zms)
+
+    def _cmul(self, share_x, share_y, field):
+        """Multiplication of a share with a constant.
+
+        Either share_x or share_y must be a BeDOZaShare but not
+        both. Returns None if both share_x and share_y are
+        BeDOZaShares.
+        """
+        if not isinstance(share_x, Share):
+            # Then share_y must be a Share => local multiplication. We
+            # clone first to avoid changing share_y.
+            assert isinstance(share_y, Share), \
+                "At least one of the arguments must be a share."
+            result = share_y.clone()
+            result.addCallback(self._constant_multiply, share_x)
+            return result
+        if not isinstance(share_y, Share):
+            # Likewise when share_y is a constant.
+            assert isinstance(share_x, Share), \
+                "At least one of the arguments must be a share."
+            result = share_x.clone()
+            result.addCallback(self._constant_multiply, share_y)
+            return result
+        return None
+
+    def _constant_multiply(self, x, c):
+        """Multiplication of a share-tuple with a constant c."""
+        assert(isinstance(c, FieldElement))
+        xi, xks, xms = x
+        zi = c * xi
+        zks = BeDOZaKeyList(xks.alpha, map(lambda k: c * k, xks.keys))
+        zms = BeDOZaMessageList(map(lambda m: c * m, xms.auth_codes))
+        return (zi, zks, zms)
--- a/viff/orlandi.py	Tue Jul 06 15:21:05 2010 +0200
+++ b/viff/orlandi.py	Wed Jul 07 10:56:22 2010 +0200
@@ -464,9 +464,13 @@
         Cz = Cx * Cy
         return (zi, (rhozi1, rhozi2), Cz)
 
-    def _minus_public(self, x, c, field):
+    def _minus_public_right(self, x, c, field):
         return self._do_arithmetic_op(x, c, field, self._minus)
 
+    def _minus_public_left(self, x, c, field):
+        y = self._constant_multiply(x, field(-1))
+        return self._do_arithmetic_op(y, c, field, self._plus)
+
     def _do_arithmetic_op(self, x, c, field, op):
         y = self._convert_public_to_share(c, field)
         (zi, (rhozi1, rhozi2), Cz) = op((x, y), field)
@@ -595,7 +599,7 @@
         """
         def constant_multiply(x, c):
             assert(isinstance(c, FieldElement))
-            zi, rhoz, Cx = self._const_mul(c.value, x)
+            zi, rhoz, Cx = self._constant_multiply(x, c)
             return OrlandiShare(self, field, zi, rhoz, Cx)
         if not isinstance(share_x, Share):
             # Then share_y must be a Share => local multiplication. We
@@ -614,13 +618,13 @@
             return result
         return None
 
-    def _const_mul(self, c, x):
+    def _constant_multiply(self, x, c):
         """Multiplication of a share-tuple with a constant c."""
-        assert(isinstance(c, long) or isinstance(c, int))
+        assert(isinstance(c, FieldElement))
         xi, (rhoi1, rhoi2), Cx = x
         zi = xi * c
         rhoz = (rhoi1 * c, rhoi2 * c)
-        Cz = Cx**c
+        Cz = Cx**c.value
         return (zi, rhoz, Cz)
 
     def _get_share(self, field, value):
@@ -665,9 +669,9 @@
             # [de]
             de = self._convert_public_to_share(d * e, field)
             # e[x]
-            t1 = self._const_mul(e.value, x)
+            t1 = self._constant_multiply(x, e)
             # d[y]
-            t2 = self._const_mul(d.value, y)
+            t2 = self._constant_multiply(y, d)
             # d[y] - [de]
             t3 = self._minus((t2, de), field)
             # d[y] - [de] + [c]
--- a/viff/simplearithmetic.py	Tue Jul 06 15:21:05 2010 +0200
+++ b/viff/simplearithmetic.py	Wed Jul 07 10:56:22 2010 +0200
@@ -22,8 +22,11 @@
     """Provides methods for addition and subtraction.
 
     Provides set: {add, sub}.
-    Requires set: {self._plus((x,y), field), self._minus((x,y), field),
-                   self._convert_public_to_share_and_do(operation)}.
+    Requires set: {self._plus((x,y), field),
+                   self._minus((x,y), field),
+                   self._plus_public(x, c, field),
+                   self._minus_public_right(x, c, field),
+                   self._minus_public_left(x, c, field)}.
     """
 
     def add(self, share_a, share_b):
@@ -31,20 +34,10 @@
 
         share_a is assumed to be an instance of Share.
         If share_b is also an instance of Share then self._plus gets called.
-        If not then self._add_public get called.
+        If not then self._plus_public get called.
         """
         return self.both_shares(share_a, share_b, self._plus_public, self._plus)
 
-    def sub(self, share_a, share_b):
-        """Subtraction of shares.
-
-        share_a is assumed to be an instance of Share.
-        If share_b is also an instance of Share then self._minus gets called.
-        If not then self._sub_public get called.
-        """
-        return self.both_shares(share_a, share_b, self._minus_public, self._minus)
-
-
     def both_shares(self, share_a, share_b, if_not, if_so):
         field = share_a.field
         if not isinstance(share_b, Share):
@@ -56,3 +49,28 @@
             result = gather_shares([share_a, share_b])
             result.addCallbacks(if_so, self.error_handler, callbackArgs=(field,))
             return result
+
+    def sub(self, share_a, share_b):
+        """Subtraction of shares.
+
+        If share_a is an instance of Share but not share_b, then self._minus_public_right gets called.
+        If share_b is an instance of Share but not share_b, then self._minus_public_left gets called.
+        If share_a and share_b are both instances of Share then self._minus get called.
+        """
+        if not isinstance(share_b, Share):
+            field = share_a.field
+            if not isinstance(share_b, FieldElement):
+                share_b = field(share_b)
+            share_a.addCallbacks(self._minus_public_right, self.error_handler, callbackArgs=(share_b, field))
+            return share_a
+        elif not isinstance(share_a, Share):
+            field = share_b.field
+            if not isinstance(share_a, FieldElement):
+                share_a = field(share_a)
+            share_b.addCallbacks(self._minus_public_left, self.error_handler, callbackArgs=(share_a, field))
+            return share_b
+        else:
+            field = share_a.field
+            result = gather_shares([share_a, share_b])
+            result.addCallbacks(self._minus, self.error_handler, callbackArgs=(field,))
+            return result
--- a/viff/test/test_bedoza_runtime.py	Tue Jul 06 15:21:05 2010 +0200
+++ b/viff/test/test_bedoza_runtime.py	Wed Jul 07 10:56:22 2010 +0200
@@ -279,16 +279,53 @@
     def test_sub_constant_left(self, runtime):
         """Test subtraction of a public number and secret shared number."""
 
+        self.Zp = GF(31)
+
+        y = 8
+
+        def check(v):
+            self.assertEquals(v, 2)
+
+        x2 = runtime.random_share(self.Zp)
+        z2 = y - x2
+        d = runtime.open(x2)
+        d.addCallback(check)
+        return d
+
+    @protocol
+    def test_constant_multiplication_constant_left(self, runtime):
+        """Test multiplication of two numbers."""
+
         self.Zp = GF(6277101735386680763835789423176059013767194773182842284081)
 
-        x1 = 42
+        x1 = 6
         y1 = 7
 
         def check(v):
-            self.assertEquals(v, 1)
+            self.assertEquals(v, x1 * y1)
 
         x2 = runtime.random_share(self.Zp)
-        z2 = y1 - x2
+
+        z2 = runtime._cmul(self.Zp(y1), x2, self.Zp)
         d = runtime.open(z2)
         d.addCallback(check)
         return d
+
+    @protocol
+    def test_constant_multiplication_constant_right(self, runtime):
+        """Test multiplication of two numbers."""
+
+        self.Zp = GF(6277101735386680763835789423176059013767194773182842284081)
+
+        x1 = 6
+        y1 = 7
+
+        def check(v):
+            self.assertEquals(v, x1 * y1)
+
+        x2 = runtime.random_share(self.Zp)
+
+        z2 = runtime._cmul(x2, self.Zp(y1), self.Zp)
+        d = runtime.open(z2)
+        d.addCallback(check)
+        return d
--- a/viff/test/test_orlandi_runtime.py	Tue Jul 06 15:21:05 2010 +0200
+++ b/viff/test/test_orlandi_runtime.py	Wed Jul 07 10:56:22 2010 +0200
@@ -307,6 +307,28 @@
         d.addCallback(check)
         return d
 
+    @protocol
+    def test_sub_constant_left(self, runtime):
+        """Test subtraction of a public number and secret shared number."""
+
+        self.Zp = GF(6277101735386680763835789423176059013767194773182842284081)
+
+        x1 = 6
+        y1 = 8
+
+        def check(v):
+            self.assertEquals(v, y1 - x1)
+
+        if 1 == runtime.id:
+            x2 = runtime.secret_share([1], self.Zp, x1)
+        else:
+            x2 = runtime.secret_share([1], self.Zp)
+            
+        z2 = y1 - x2
+        d = runtime.open(x2)
+        d.addCallback(check)
+        return d
+    
 
 keys = None