## viff

### changeset 1182:e89fb02c5e3d

Merged with Marcel.
author Martin Geisler Thu, 14 May 2009 12:01:54 +0200 a1304b0072d4 3171ea9886cb b5eea8738968 6cd5ceb87542 e918af983f75 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.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.22      #: Subtract this and another GF256 element (reflected argument version).
2.23 -    __rsub__ = __sub__
2.25
2.26      #: Exclusive-or.
2.27      #:
2.28 @@ -185,7 +190,7 @@
2.30
2.31      #: Exclusive-or (reflected argument version).
2.32 -    __rxor__ = __xor__
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.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.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.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.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.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):
```