## viff

### changeset 1470:f27609bc4831

BeDOZa: Implemented basic multiplication.
author Janus Dam Nielsen Wed, 07 Jul 2010 14:31:30 +0200 c2bb60bd132e 06b1b7647643 viff/bedoza.py viff/test/test_bedoza_runtime.py 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.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.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)