viff

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 diff
     1.1 --- a/viff/bedoza.py	Wed Jul 07 14:31:27 2010 +0200
     1.2 +++ b/viff/bedoza.py	Wed Jul 07 14:31:30 2010 +0200
     1.3 @@ -371,3 +371,70 @@
     1.4                  triple_c = self.generate_share(field, share_c)
     1.5                  c += share_c.value
     1.6          return [triple_a, triple_b, triple_c]
     1.7 +
     1.8 +    def mul(self, share_x, share_y):
     1.9 +        """Multiplication of shares."""
    1.10 +        assert isinstance(share_x, Share) or isinstance(share_y, Share), \
    1.11 +            "At least one of share_x and share_y must be a Share."
    1.12 +
    1.13 +        self.increment_pc()
    1.14 +
    1.15 +        field = getattr(share_x, "field", getattr(share_y, "field", None))
    1.16 +
    1.17 +        triple = self._get_triple(field)
    1.18 +        return self._basic_multiplication(share_x, share_y, *triple)
    1.19 +
    1.20 +    def _basic_multiplication(self, share_x, share_y, triple_a, triple_b, triple_c):
    1.21 +        """Multiplication of shares give a triple.
    1.22 +
    1.23 +        Communication cost: ???.
    1.24 +
    1.25 +        ``d = Open([x] - [a])``
    1.26 +        ``e = Open([y] - [b])``
    1.27 +        ``[z] = e[x] + d[y] - [de] + [c]``
    1.28 +        """
    1.29 +        assert isinstance(share_x, Share) or isinstance(share_y, Share), \
    1.30 +            "At least one of share_x and share_y must be a Share."
    1.31 +
    1.32 +        self.increment_pc()
    1.33 +
    1.34 +        field = getattr(share_x, "field", getattr(share_y, "field", None))
    1.35 +        n = field(0)
    1.36 +
    1.37 +        cmul_result = self._cmul(share_x, share_y, field)
    1.38 +        if cmul_result is  not None:
    1.39 +            return cmul_result
    1.40 +
    1.41 +        def multiply((x, y, c, d, e)):
    1.42 +            # [de]
    1.43 +            de = d * e
    1.44 +            # e[x]
    1.45 +            t1 = self._constant_multiply(x, e)
    1.46 +            # d[y]
    1.47 +            t2 = self._constant_multiply(y, d)
    1.48 +            # d[y] - [de]
    1.49 +            t3 = self._minus_public_right1(t2, de, field)
    1.50 +            # d[y] - [de] + [c]
    1.51 +            t4 = self._plus((t3, c), field)
    1.52 +            # [z] = e[x] + d[y] - [de] + [c]
    1.53 +            zi, zks, zms = self._plus((t1, t4), field)
    1.54 +            return BeDOZaShare(self, field, zi, zks, zms)
    1.55 +
    1.56 +        #d = Open([x] - [a])
    1.57 +        d = self.output(share_x - triple_a)
    1.58 +        # e = Open([y] - [b])
    1.59 +        e = self.output(share_y - triple_b)
    1.60 +        result = gather_shares([share_x, share_y, triple_c, d, e])
    1.61 +        result.addCallbacks(multiply, self.error_handler)
    1.62 +
    1.63 +        # do actual communication
    1.64 +        self.activate_reactor()
    1.65 +
    1.66 +        return result
    1.67 +
    1.68 +    def _minus_public_right1(self, x, c, field):
    1.69 +        (xi, xks, xms) = x
    1.70 +        if self.id == 1:
    1.71 +            xi = xi - c
    1.72 +        xks.keys[0] = xks.keys[0] + xks.alpha * c
    1.73 +        return xi, xks, xms
     2.1 --- a/viff/test/test_bedoza_runtime.py	Wed Jul 07 14:31:27 2010 +0200
     2.2 +++ b/viff/test/test_bedoza_runtime.py	Wed Jul 07 14:31:30 2010 +0200
     2.3 @@ -116,6 +116,8 @@
     2.4  
     2.5      runtime_class = BeDOZaRuntime
     2.6  
     2.7 +    timeout = 3
     2.8 +    
     2.9      @protocol
    2.10      def test_random_share(self, runtime):
    2.11          """Test creation of a random shared number."""
    2.12 @@ -348,3 +350,24 @@
    2.13          d = gather_shares([d1, d2, d3])
    2.14          d.addCallback(check)
    2.15          return d
    2.16 +
    2.17 +    @protocol
    2.18 +    def test_basic_multiply(self, runtime):
    2.19 +        """Test multiplication of two numbers."""
    2.20 +
    2.21 +        self.Zp = GF(6277101735386680763835789423176059013767194773182842284081)
    2.22 +
    2.23 +        x1 = 6
    2.24 +        y1 = 6
    2.25 +
    2.26 +        def check(v):
    2.27 +            self.assertEquals(v, x1 * y1)
    2.28 +
    2.29 +        x2 = runtime.random_share(self.Zp)
    2.30 +        y2 = runtime.random_share(self.Zp)
    2.31 +
    2.32 +        a, b, c = runtime._get_triple(self.Zp)
    2.33 +        z2 = runtime._basic_multiplication(x2, y2, a, b, c)
    2.34 +        d = runtime.open(z2)
    2.35 +        d.addCallback(check)
    2.36 +        return d