## viff

### changeset 647:5f643bb9c9fb

Added multiplication based on multiplication triples.
author Martin Geisler Sat, 05 Apr 2008 00:00:24 +0200 89187d5b7d6a e6cc20a96ac2 viff/runtime.py 1 files changed, 47 insertions(+), 0 deletions(-) [+]
line diff
```     1.1 --- a/viff/runtime.py	Sat Apr 05 00:00:24 2008 +0200
1.2 +++ b/viff/runtime.py	Sat Apr 05 00:00:24 2008 +0200
1.3 @@ -965,6 +965,53 @@
1.4          Runtime.__init__(self, player, threshold, options)
1.5
1.6      @increment_pc
1.7 +    def mul(self, share_x, share_y):
1.8 +        """Multiplication of shares.
1.9 +
1.10 +        Preprocessing: 1 multiplication triple.
1.11 +        Communication: 2 openings.
1.12 +        """
1.13 +        assert isinstance(share_x, Share) or isinstance(share_y, Share), \
1.14 +            "At least one of share_x and share_y must be a Share."
1.15 +
1.16 +        if not isinstance(share_x, Share):
1.17 +            # Then share_y must be a Share => local multiplication. We
1.18 +            # clone first to avoid changing share_y.
1.19 +            result = share_y.clone()
1.20 +            result.addCallback(lambda y: share_x * y)
1.21 +            return result
1.22 +        if not isinstance(share_y, Share):
1.23 +            # Likewise when share_y is a constant.
1.24 +            result = share_x.clone()
1.25 +            result.addCallback(lambda x: x * share_y)
1.26 +            return result
1.27 +
1.28 +        # At this point both share_x and share_y must be Share
1.29 +        # objects. We multiply them via a multiplication triple.
1.30 +
1.31 +        # TODO: This is of course insecure... We should move
1.32 +        # generate_triples to a preprocessing step and draw the
1.33 +        # triples from a pool instead. Also, using only the first
1.34 +        # triple is quite wasteful...
1.35 +        a, b, c = self.generate_triples(share_x.field)[0]
1.36 +
1.37 +        d = self.open(share_x - a)
1.38 +        e = self.open(share_y - b)
1.39 +
1.40 +        # TODO: We ought to be able to simple do
1.41 +        #
1.42 +        #   return d*e + d*y + e*x + c
1.43 +        #
1.44 +        # but that leads to infinite recursion since d and e are
1.45 +        # Shares, not FieldElements. So we have to do a bit more
1.46 +        # work... The following callback also leads to recursion, but
1.47 +        # only one level since d and e are FieldElements now, which
1.48 +        # means that we return in the above if statements.
1.49 +        result = gather_shares([d, e])
1.50 +        result.addCallback(lambda (d,e): d*e + d*b + e*a + c)
1.51 +        return result
1.52 +
1.53 +    @increment_pc
1.54      def double_share_random(self, T, d1, d2, field):
1.55          """Double-shares a randoms secret by using two polynomials.
1.56
```