viff

changeset 1465:8779d6f6bad0

BeDOZa: Enabled subtraction with a non-share value as left operand.
author Janus Dam Nielsen <janus.nielsen@alexandra.dk>
date Wed, 07 Jul 2010 11:01:14 +0200
parents a28c7d75c09e
children 6b96a1fdb751
files viff/bedoza.py viff/orlandi.py viff/simplearithmetic.py viff/test/test_bedoza_runtime.py viff/test/test_orlandi_runtime.py
diffstat 5 files changed, 86 insertions(+), 22 deletions(-) [+]
line diff
     1.1 --- a/viff/bedoza.py	Tue Jul 06 16:17:16 2010 +0200
     1.2 +++ b/viff/bedoza.py	Wed Jul 07 11:01:14 2010 +0200
     1.3 @@ -295,12 +295,16 @@
     1.4          zms = xms + yms
     1.5          return (zi, zks, zms)
     1.6  
     1.7 -    def _minus_public(self, x, c, field):
     1.8 +    def _minus_public_right(self, x, c, field):
     1.9          (xi, xks, xms) = x
    1.10          if self.id == 1:
    1.11              xi = xi - c
    1.12          xks.keys[0] = xks.keys[0] + xks.alpha * c
    1.13          return BeDOZaShare(self, field, xi, xks, xms)
    1.14 +
    1.15 +    def _minus_public_left(self, x, c, field):
    1.16 +        y = self._constant_multiply(x, field(-1))
    1.17 +        return self._plus_public(y, c, field)
    1.18      
    1.19      def _minus(self, (x, y), field):
    1.20          """Subtraction of share-tuples *x* and *y*.
    1.21 @@ -318,7 +322,6 @@
    1.22          zms = xms - yms
    1.23          return (zi, zks, zms)
    1.24  
    1.25 -
    1.26      def _cmul(self, share_x, share_y, field):
    1.27          """Multiplication of a share with a constant.
    1.28  
     2.1 --- a/viff/orlandi.py	Tue Jul 06 16:17:16 2010 +0200
     2.2 +++ b/viff/orlandi.py	Wed Jul 07 11:01:14 2010 +0200
     2.3 @@ -464,9 +464,13 @@
     2.4          Cz = Cx * Cy
     2.5          return (zi, (rhozi1, rhozi2), Cz)
     2.6  
     2.7 -    def _minus_public(self, x, c, field):
     2.8 +    def _minus_public_right(self, x, c, field):
     2.9          return self._do_arithmetic_op(x, c, field, self._minus)
    2.10  
    2.11 +    def _minus_public_left(self, x, c, field):
    2.12 +        y = self._constant_multiply(x, field(-1))
    2.13 +        return self._do_arithmetic_op(y, c, field, self._plus)
    2.14 +
    2.15      def _do_arithmetic_op(self, x, c, field, op):
    2.16          y = self._convert_public_to_share(c, field)
    2.17          (zi, (rhozi1, rhozi2), Cz) = op((x, y), field)
    2.18 @@ -595,7 +599,7 @@
    2.19          """
    2.20          def constant_multiply(x, c):
    2.21              assert(isinstance(c, FieldElement))
    2.22 -            zi, rhoz, Cx = self._const_mul(c.value, x)
    2.23 +            zi, rhoz, Cx = self._constant_multiply(x, c)
    2.24              return OrlandiShare(self, field, zi, rhoz, Cx)
    2.25          if not isinstance(share_x, Share):
    2.26              # Then share_y must be a Share => local multiplication. We
    2.27 @@ -614,13 +618,13 @@
    2.28              return result
    2.29          return None
    2.30  
    2.31 -    def _const_mul(self, c, x):
    2.32 +    def _constant_multiply(self, x, c):
    2.33          """Multiplication of a share-tuple with a constant c."""
    2.34 -        assert(isinstance(c, long) or isinstance(c, int))
    2.35 +        assert(isinstance(c, FieldElement))
    2.36          xi, (rhoi1, rhoi2), Cx = x
    2.37          zi = xi * c
    2.38          rhoz = (rhoi1 * c, rhoi2 * c)
    2.39 -        Cz = Cx**c
    2.40 +        Cz = Cx**c.value
    2.41          return (zi, rhoz, Cz)
    2.42  
    2.43      def _get_share(self, field, value):
    2.44 @@ -665,9 +669,9 @@
    2.45              # [de]
    2.46              de = self._convert_public_to_share(d * e, field)
    2.47              # e[x]
    2.48 -            t1 = self._const_mul(e.value, x)
    2.49 +            t1 = self._constant_multiply(x, e)
    2.50              # d[y]
    2.51 -            t2 = self._const_mul(d.value, y)
    2.52 +            t2 = self._constant_multiply(y, d)
    2.53              # d[y] - [de]
    2.54              t3 = self._minus((t2, de), field)
    2.55              # d[y] - [de] + [c]
     3.1 --- a/viff/simplearithmetic.py	Tue Jul 06 16:17:16 2010 +0200
     3.2 +++ b/viff/simplearithmetic.py	Wed Jul 07 11:01:14 2010 +0200
     3.3 @@ -22,8 +22,11 @@
     3.4      """Provides methods for addition and subtraction.
     3.5  
     3.6      Provides set: {add, sub}.
     3.7 -    Requires set: {self._plus((x,y), field), self._minus((x,y), field),
     3.8 -                   self._convert_public_to_share_and_do(operation)}.
     3.9 +    Requires set: {self._plus((x,y), field),
    3.10 +                   self._minus((x,y), field),
    3.11 +                   self._plus_public(x, c, field),
    3.12 +                   self._minus_public_right(x, c, field),
    3.13 +                   self._minus_public_left(x, c, field)}.
    3.14      """
    3.15  
    3.16      def add(self, share_a, share_b):
    3.17 @@ -31,20 +34,10 @@
    3.18  
    3.19          share_a is assumed to be an instance of Share.
    3.20          If share_b is also an instance of Share then self._plus gets called.
    3.21 -        If not then self._add_public get called.
    3.22 +        If not then self._plus_public get called.
    3.23          """
    3.24          return self.both_shares(share_a, share_b, self._plus_public, self._plus)
    3.25  
    3.26 -    def sub(self, share_a, share_b):
    3.27 -        """Subtraction of shares.
    3.28 -
    3.29 -        share_a is assumed to be an instance of Share.
    3.30 -        If share_b is also an instance of Share then self._minus gets called.
    3.31 -        If not then self._sub_public get called.
    3.32 -        """
    3.33 -        return self.both_shares(share_a, share_b, self._minus_public, self._minus)
    3.34 -
    3.35 -
    3.36      def both_shares(self, share_a, share_b, if_not, if_so):
    3.37          field = share_a.field
    3.38          if not isinstance(share_b, Share):
    3.39 @@ -56,3 +49,28 @@
    3.40              result = gather_shares([share_a, share_b])
    3.41              result.addCallbacks(if_so, self.error_handler, callbackArgs=(field,))
    3.42              return result
    3.43 +
    3.44 +    def sub(self, share_a, share_b):
    3.45 +        """Subtraction of shares.
    3.46 +
    3.47 +        If share_a is an instance of Share but not share_b, then self._minus_public_right gets called.
    3.48 +        If share_b is an instance of Share but not share_b, then self._minus_public_left gets called.
    3.49 +        If share_a and share_b are both instances of Share then self._minus get called.
    3.50 +        """
    3.51 +        if not isinstance(share_b, Share):
    3.52 +            field = share_a.field
    3.53 +            if not isinstance(share_b, FieldElement):
    3.54 +                share_b = field(share_b)
    3.55 +            share_a.addCallbacks(self._minus_public_right, self.error_handler, callbackArgs=(share_b, field))
    3.56 +            return share_a
    3.57 +        elif not isinstance(share_a, Share):
    3.58 +            field = share_b.field
    3.59 +            if not isinstance(share_a, FieldElement):
    3.60 +                share_a = field(share_a)
    3.61 +            share_b.addCallbacks(self._minus_public_left, self.error_handler, callbackArgs=(share_a, field))
    3.62 +            return share_b
    3.63 +        else:
    3.64 +            field = share_a.field
    3.65 +            result = gather_shares([share_a, share_b])
    3.66 +            result.addCallbacks(self._minus, self.error_handler, callbackArgs=(field,))
    3.67 +            return result
     4.1 --- a/viff/test/test_bedoza_runtime.py	Tue Jul 06 16:17:16 2010 +0200
     4.2 +++ b/viff/test/test_bedoza_runtime.py	Wed Jul 07 11:01:14 2010 +0200
     4.3 @@ -276,6 +276,23 @@
     4.4          return d
     4.5  
     4.6      @protocol
     4.7 +    def test_sub_constant_left(self, runtime):
     4.8 +        """Test subtraction of a public number and secret shared number."""
     4.9 +
    4.10 +        self.Zp = GF(31)
    4.11 +
    4.12 +        y = 8
    4.13 +
    4.14 +        def check(v):
    4.15 +            self.assertEquals(v, 2)
    4.16 +
    4.17 +        x2 = runtime.random_share(self.Zp)
    4.18 +        z2 = y - x2
    4.19 +        d = runtime.open(x2)
    4.20 +        d.addCallback(check)
    4.21 +        return d
    4.22 +
    4.23 +    @protocol
    4.24      def test_constant_multiplication_constant_left(self, runtime):
    4.25          """Test multiplication of two numbers."""
    4.26  
     5.1 --- a/viff/test/test_orlandi_runtime.py	Tue Jul 06 16:17:16 2010 +0200
     5.2 +++ b/viff/test/test_orlandi_runtime.py	Wed Jul 07 11:01:14 2010 +0200
     5.3 @@ -307,6 +307,28 @@
     5.4          d.addCallback(check)
     5.5          return d
     5.6  
     5.7 +    @protocol
     5.8 +    def test_sub_constant_left(self, runtime):
     5.9 +        """Test subtraction of a public number and secret shared number."""
    5.10 +
    5.11 +        self.Zp = GF(6277101735386680763835789423176059013767194773182842284081)
    5.12 +
    5.13 +        x1 = 6
    5.14 +        y1 = 8
    5.15 +
    5.16 +        def check(v):
    5.17 +            self.assertEquals(v, y1 - x1)
    5.18 +
    5.19 +        if 1 == runtime.id:
    5.20 +            x2 = runtime.secret_share([1], self.Zp, x1)
    5.21 +        else:
    5.22 +            x2 = runtime.secret_share([1], self.Zp)
    5.23 +            
    5.24 +        z2 = y1 - x2
    5.25 +        d = runtime.open(x2)
    5.26 +        d.addCallback(check)
    5.27 +        return d
    5.28 +    
    5.29  
    5.30  keys = None
    5.31