viff

changeset 647:5f643bb9c9fb

Added multiplication based on multiplication triples.
author Martin Geisler <mg@daimi.au.dk>
date Sat, 05 Apr 2008 00:00:24 +0200
parents 89187d5b7d6a
children e6cc20a96ac2
files viff/runtime.py
diffstat 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