viff

changeset 1182:e89fb02c5e3d

Merged with Marcel.
author Martin Geisler <mg@cs.au.dk>
date Thu, 14 May 2009 12:01:54 +0200
parents a1304b0072d4 3171ea9886cb
children b5eea8738968 6cd5ceb87542 e918af983f75
files
diffstat 4 files changed, 46 insertions(+), 46 deletions(-) [+]
line diff
     1.1 --- a/viff/aes.py	Thu May 14 10:47:12 2009 +0200
     1.2 +++ b/viff/aes.py	Thu May 14 12:01:54 2009 +0200
     1.3 @@ -205,7 +205,7 @@
     1.4  
     1.5                  # include the translation in the matrix multiplication
     1.6                  # (see definition of AES.A)
     1.7 -                bits.append(GF256(1))
     1.8 +                bits.append(Share(self.runtime, GF256, GF256(1)))
     1.9  
    1.10                  if (use_lin_comb):
    1.11                      bits = [self.runtime.lin_comb(AES.A.rows[j], bits) 
     2.1 --- a/viff/field.py	Thu May 14 10:47:12 2009 +0200
     2.2 +++ b/viff/field.py	Thu May 14 12:01:54 2009 +0200
     2.3 @@ -168,16 +168,21 @@
     2.4              other = other.value
     2.5          return GF256(self.value ^ other)
     2.6  
     2.7 -    #: Add this and another GF256 element (reflected argument version).
     2.8 -    __radd__ = __add__
     2.9 +    def __radd__(self, other):
    2.10 +        """Add this and another number (reflected argument version).
    2.11  
    2.12 +        other is not Share, otherwise Share.__add__() would have been
    2.13 +        called, and other is not a GF256, otherwise GF256.__add__()
    2.14 +        would have been called."""
    2.15 +        return GF256(self.value ^ other)
    2.16 +    
    2.17      #: Subtract this and another GF256 element.
    2.18      #:
    2.19      #: Addition is its own inverse in GF(2^8) and so this is the same
    2.20      #: as `__add__`.
    2.21      __sub__ = __add__
    2.22      #: Subtract this and another GF256 element (reflected argument version).
    2.23 -    __rsub__ = __sub__
    2.24 +    __rsub__ = __radd__
    2.25  
    2.26      #: Exclusive-or.
    2.27      #:
    2.28 @@ -185,7 +190,7 @@
    2.29      __xor__ = __add__
    2.30  
    2.31      #: Exclusive-or (reflected argument version).
    2.32 -    __rxor__ = __xor__
    2.33 +    __rxor__ = __radd__
    2.34  
    2.35      def __mul__(self, other):
    2.36          """Multiply this and another GF256.
    2.37 @@ -204,8 +209,14 @@
    2.38          return _mul_table[(self.value, other)]
    2.39  
    2.40  
    2.41 -    #: Multiply this and another GF256 element (reflected argument version).
    2.42 -    __rmul__ = __mul__
    2.43 +    def __rmul__(self, other):
    2.44 +        """Multiply this and another number (reflected argument
    2.45 +        version).
    2.46 +
    2.47 +        other is not Share, otherwise Share.__mul__() would have been
    2.48 +        called, and other is not a GF256, otherwise GF256.__mul__()
    2.49 +        would have been called."""
    2.50 +        return _mul_table[(self.value, other)]
    2.51  
    2.52      def __pow__(self, exponent):
    2.53          """Exponentiation."""
     3.1 --- a/viff/passive.py	Thu May 14 10:47:12 2009 +0200
     3.2 +++ b/viff/passive.py	Thu May 14 12:01:54 2009 +0200
     3.3 @@ -113,12 +113,14 @@
     3.4  
     3.5          Communication cost: none.
     3.6          """
     3.7 -        field = getattr(share_a, "field", getattr(share_b, "field", None))
     3.8 -        if not isinstance(share_a, Share):
     3.9 -            share_a = Share(self, field, share_a)
    3.10          if not isinstance(share_b, Share):
    3.11 -            share_b = Share(self, field, share_b)
    3.12 -
    3.13 +            # Addition with constant. share_a always is a Share by
    3.14 +            # operator overloading in Share. Clone share_a to avoid
    3.15 +            # changing it.
    3.16 +            result = share_a.clone()
    3.17 +            result.addCallback(lambda a, b: a + b, share_b)
    3.18 +            return result
    3.19 +        
    3.20          result = gather_shares([share_a, share_b])
    3.21          result.addCallback(lambda (a, b): a + b)
    3.22          return result
    3.23 @@ -149,16 +151,13 @@
    3.24              assert not isinstance(coeff, Share), \
    3.25                  "Coefficients should not be shares."
    3.26  
    3.27 +        for share in shares:
    3.28 +            assert isinstance(share, Share), \
    3.29 +                "Shares should be shares."
    3.30 +
    3.31          assert len(coefficients) == len(shares), \
    3.32              "Number of coefficients and shares should be equal."
    3.33  
    3.34 -        field = None
    3.35 -        for share in shares:
    3.36 -            field = getattr(share, "field", field)
    3.37 -        for i, share in enumerate(shares):
    3.38 -            if not isinstance(share, Share):
    3.39 -                shares[i] = Share(self, field, share)
    3.40 -
    3.41          def computation(shares, coefficients):
    3.42              summands = [shares[i] * coefficients[i] for i in range(len(shares))]
    3.43              return reduce(lambda x, y: x + y, summands)
    3.44 @@ -174,17 +173,13 @@
    3.45  
    3.46          Communication cost: 1 Shamir sharing.
    3.47          """
    3.48 -        assert isinstance(share_a, Share) or isinstance(share_b, Share), \
    3.49 -            "At least one of share_a and share_b must be a Share."
    3.50 +        assert isinstance(share_a, Share), \
    3.51 +            "share_a must be a Share."
    3.52  
    3.53 -        if not isinstance(share_a, Share):
    3.54 -            # Then share_b must be a Share => local multiplication. We
    3.55 -            # clone first to avoid changing share_b.
    3.56 -            result = share_b.clone()
    3.57 -            result.addCallback(lambda b: share_a * b)
    3.58 -            return result
    3.59          if not isinstance(share_b, Share):
    3.60 -            # Likewise when share_b is a constant.
    3.61 +            # Local multiplication. share_a always is a Share by
    3.62 +            # operator overloading in Share. We clone share_a first
    3.63 +            # to avoid changing it.
    3.64              result = share_a.clone()
    3.65              result.addCallback(lambda a: a * share_b)
    3.66              return result
    3.67 @@ -227,11 +222,7 @@
    3.68  
    3.69      @increment_pc
    3.70      def xor(self, share_a, share_b):
    3.71 -        field = getattr(share_a, "field", getattr(share_b, "field", None))
    3.72 -        if not isinstance(share_a, Share):
    3.73 -            if not isinstance(share_a, FieldElement):
    3.74 -                share_a = field(share_a)
    3.75 -            share_a = Share(self, field, share_a)
    3.76 +        field = share_a.field
    3.77          if not isinstance(share_b, Share):
    3.78              if not isinstance(share_b, FieldElement):
    3.79                  share_b = field(share_b)
     4.1 --- a/viff/runtime.py	Thu May 14 10:47:12 2009 +0200
     4.2 +++ b/viff/runtime.py	Thu May 14 12:01:54 2009 +0200
     4.3 @@ -92,7 +92,7 @@
     4.4  
     4.5      def __radd__(self, other):
     4.6          """Addition (reflected argument version)."""
     4.7 -        return self.runtime.add(other, self)
     4.8 +        return self.runtime.add(self, other)
     4.9  
    4.10      def __sub__(self, other):
    4.11          """Subtraction."""
    4.12 @@ -108,7 +108,7 @@
    4.13  
    4.14      def __rmul__(self, other):
    4.15          """Multiplication (reflected argument version)."""
    4.16 -        return self.runtime.mul(other, self)
    4.17 +        return self.runtime.mul(self, other)
    4.18  
    4.19      def __pow__(self, exponent):
    4.20          """Exponentation to known integer exponents."""
    4.21 @@ -120,7 +120,7 @@
    4.22  
    4.23      def __rxor__(self, other):
    4.24          """Exclusive-or (reflected argument version)."""
    4.25 -        return self.runtime.xor(other, self)
    4.26 +        return self.runtime.xor(self, other)
    4.27  
    4.28      def __lt__(self, other):
    4.29          """Strictly less-than comparison."""
    4.30 @@ -270,6 +270,7 @@
    4.31          self.lost_connection = Deferred()
    4.32          #: Data expected to be received in the future.
    4.33          self.incoming_data = {}
    4.34 +        self.waiting_deferreds = {}
    4.35  
    4.36      def connectionMade(self):
    4.37          self.sendString(str(self.factory.runtime.id))
    4.38 @@ -312,13 +313,14 @@
    4.39  
    4.40                  key = (program_counter, data_type)
    4.41  
    4.42 -                deq = self.incoming_data.setdefault(key, deque())
    4.43 -                if deq and isinstance(deq[0], Deferred):
    4.44 +                if key in self.waiting_deferreds:
    4.45 +                    deq = self.waiting_deferreds[key]
    4.46                      deferred = deq.popleft()
    4.47                      if not deq:
    4.48 -                        del self.incoming_data[key]
    4.49 +                        del self.waiting_deferreds[key]
    4.50                      deferred.callback(data)
    4.51                  else:
    4.52 +                    deq = self.incoming_data.setdefault(key, deque())
    4.53                      deq.append(data)
    4.54              except struct.error, e:
    4.55                  self.factory.runtime.abort(self, e)
    4.56 @@ -601,11 +603,6 @@
    4.57          Any extra arguments are passed to the callback as with
    4.58          :meth:`addCallback`.
    4.59          """
    4.60 -        # TODO, http://tracker.viff.dk/issue22: When several callbacks
    4.61 -        # are scheduled from the same method, they all save the same
    4.62 -        # program counter. Simply decorating callback with increase_pc
    4.63 -        # does not seem to work (the multiplication benchmark hangs).
    4.64 -        # This should be fixed.
    4.65          saved_pc = self.program_counter[:]
    4.66  
    4.67          @wrapper(func)
    4.68 @@ -642,15 +639,16 @@
    4.69          pc = tuple(self.program_counter)
    4.70          key = (pc, data_type)
    4.71  
    4.72 -        deq = self.protocols[peer_id].incoming_data.setdefault(key, deque())
    4.73 -        if deq and not isinstance(deq[0], Deferred):
    4.74 +        if key in self.protocols[peer_id].incoming_data:
    4.75              # We have already received some data from the other side.
    4.76 +            deq = self.protocols[peer_id].incoming_data[key]
    4.77              data = deq.popleft()
    4.78              if not deq:
    4.79                  del self.protocols[peer_id].incoming_data[key]
    4.80              deferred.callback(data)
    4.81          else:
    4.82              # We have not yet received anything from the other side.
    4.83 +            deq = self.protocols[peer_id].waiting_deferreds.setdefault(key, deque())
    4.84              deq.append(deferred)
    4.85  
    4.86      def _exchange_shares(self, peer_id, field_element):