Mikkel Krøigård <[EMAIL PROTECTED]> writes:

Cool, thank you for attacking this long-standing bug...

Could you please split up the patch so that the change of the
data_type from strings to integers is one patch, and the replacements
of the marshal module is another.

> # HG changeset patch
> # User Mikkel Krøigård <[EMAIL PROTECTED]>
> # Date 1223542718 -7200
> # Node ID da39016c1284776802e9a23b64384c207b29f3e0
> # Parent  19013451fcdd87acc6146fc7ca42d32f388be523
> Replaced marshal module
>
> diff --git a/viff/active.py b/viff/active.py
> --- a/viff/active.py
> +++ b/viff/active.py
> @@ -26,7 +26,8 @@
>  from viff import shamir
>  from viff.util import rand
>  from viff.matrix import Matrix, hyper
> -from viff.runtime import Runtime, Share, increment_pc, preprocess, 
> gather_shares
> +from viff.runtime import READY, ECHO, SEND, SHARE, Runtime, Share, \
> +    increment_pc, preprocess, gather_shares
>  
>  
>  class BrachaBroadcastMixin:
> @@ -79,7 +80,7 @@
>                  ids.append(peer_id)
>                  if len(ids) >= ceil((n+t+1)/2) and not ready:
>                      bracha_sent_ready[message] = True
> -                    unsafe_broadcast("ready", message)
> +                    unsafe_broadcast(READY, message)
>                      ready_received(message, self.id)
>  
>          def ready_received(message, peer_id):
> @@ -94,7 +95,7 @@
>                  ids.append(peer_id)
>                  if len(ids) == t+1 and not ready:
>                      bracha_sent_ready[message] = True
> -                    unsafe_broadcast("ready", message)
> +                    unsafe_broadcast(READY, message)
>                      ready_received(message, self.id)
>  
>                  elif len(ids) == 2*t+1 and not delivered:
> @@ -106,7 +107,7 @@
>              # by sending an echo message to each player. Since the
>              # unsafe broadcast doesn't send a message to this player,
>              # we simulate it by calling the echo_received function.
> -            unsafe_broadcast("echo", message)
> +            unsafe_broadcast(ECHO, message)
>              echo_received(message, self.id)
>  
>  
> @@ -116,20 +117,20 @@
>          for peer_id in self.players:
>              if peer_id != self.id:
>                  d_echo = Deferred().addCallback(echo_received, peer_id)
> -                self._expect_data(peer_id, "echo", d_echo)
> +                self._expect_data(peer_id, ECHO, d_echo)
>  
>                  d_ready = Deferred().addCallback(ready_received, peer_id)
> -                self._expect_data(peer_id, "ready", d_ready)
> +                self._expect_data(peer_id, READY, d_ready)
>  
>          # If this player is the sender, we transmit a send message to
>          # each player. We send one to this player by calling the
>          # send_received function.
>          if self.id == sender:
> -            unsafe_broadcast("send", message)
> +            unsafe_broadcast(SEND, message)
>              send_received(message)
>          else:
>              d_send = Deferred().addCallback(send_received)
> -            self._expect_data(sender, "send", d_send)
> +            self._expect_data(sender, SEND, d_send)
>  
>  
>          return result
> diff --git a/viff/runtime.py b/viff/runtime.py
> --- a/viff/runtime.py
> +++ b/viff/runtime.py
> @@ -34,9 +34,11 @@
>  __docformat__ = "restructuredtext"
>  
>  import time
> -import marshal
> +import struct
>  from optparse import OptionParser, OptionGroup
>  from collections import deque
> +
> +from gmpy import mpz

Not used anymore, I think...

>  from viff import shamir
>  from viff.prss import prss, prss_lsb, prss_zero
> @@ -50,6 +52,10 @@
>  from twisted.internet.protocol import ReconnectingClientFactory, 
> ServerFactory
>  from twisted.protocols.basic import Int16StringReceiver
>  
> +SHARE = 0
> +ECHO  = 1
> +READY = 2
> +SEND  = 3

We need a big fat comment here which explains them. And some
documentation in doc/runtime.txt.

>  class Share(Deferred):
>      """A shared number.
> @@ -295,7 +301,18 @@
>                      self.transport.loseConnection()
>              self.factory.identify_peer(self)
>          else:
> -            program_counter, data_type, data = marshal.loads(string)

We need a comment which describes the packet format too.

> +            # TODO: we cannot handle the empty string
> +            # also note that we cannot handle pcs longer than 256
> +            pc_size = ord(string[0])
> +            fmt = (pc_size + 1)*'i'

I think we can use the repeat count here: "%di" % (pc_size + 1)

> +            predata_size = struct.calcsize(fmt) + 1
> +            fmt = "%s%is" % (fmt, len(string)-predata_size)
> +
> +            unpacked = struct.unpack(fmt, string[1:])
> +            

Empty line not needed.

> +            program_counter = unpacked[:pc_size]
> +            data_type, data = unpacked[-2:]
> +            
>              key = (program_counter, data_type)
>  
>              deq = self.incoming_data.setdefault(key, deque())
> @@ -311,8 +328,11 @@
>              # TypeError. They should be handled somehow.
>  
>      def sendData(self, program_counter, data_type, data):
> -        send_data = (program_counter, data_type, data)
> -        self.sendString(marshal.dumps(send_data))
> +        pc_size = len(program_counter)
> +        fmt = "%s%is" % ((pc_size + 1)*'i', len(data))
> +        data_tuple = program_counter + (data_type, data)
> +
> +        self.sendString(chr(pc_size) + struct.pack(fmt, *data_tuple))
>  
>      def sendShare(self, program_counter, share):
>          """Send a share.
> @@ -320,8 +340,8 @@
>          The program counter and the share are marshalled and sent to
>          the peer.
>          """
> -        self.sendData(program_counter, "share", share.value)
> -
> +        self.sendData(program_counter, SHARE, hex(share.value))
> +        
>      def loseConnection(self):
>          """Disconnect this protocol instance."""
>          self.transport.loseConnection()
> @@ -613,9 +633,13 @@
>              return share
>  
>      def _expect_share(self, peer_id, field):
> +
> +        def unpack_share(value_string):
> +            return field(long(value_string, 16))
> +
>          share = Share(self, field)
> -        share.addCallback(lambda value: field(value))
> -        self._expect_data(peer_id, "share", share)
> +        share.addCallback(unpack_share)
> +        self._expect_data(peer_id, SHARE, share)
>          return share
>  
>      @increment_pc
> @@ -630,7 +654,7 @@
>            ``int`` tells us how many items of pre-processed data the
>            :class:`Deferred` will yield.
>  
> -        - The Deferred must yield a list of the promissed length.
> +        - The Deferred must yield a list of the promised length.

Unrelated change -- please put it in a separate patch.

>  
>          - The list contains the actual data. This data can be either a
>            Deferred or a tuple of Deferreds.
> diff --git a/viff/test/test_basic_runtime.py b/viff/test/test_basic_runtime.py
> --- a/viff/test/test_basic_runtime.py
> +++ b/viff/test/test_basic_runtime.py
> @@ -140,20 +140,20 @@
>          for peer_id in range(1, self.num_players+1):
>              if peer_id != runtime.id:
>                  pc = tuple(runtime.program_counter)
> -                runtime.protocols[peer_id].sendData(pc, "test", 100)
> -                runtime.protocols[peer_id].sendData(pc, "test", 200)
> -                runtime.protocols[peer_id].sendData(pc, "test", 300)
> +                runtime.protocols[peer_id].sendData(pc, 42, '100')
> +                runtime.protocols[peer_id].sendData(pc, 42, '200')
> +                runtime.protocols[peer_id].sendData(pc, 42, '300')
>  
>          # Then receive the data.
>          deferreds = []
>          for peer_id in range(1, self.num_players+1):
>              if peer_id != runtime.id:
> -                d100 = Deferred().addCallback(self.assertEquals, 100)
> -                d200 = Deferred().addCallback(self.assertEquals, 200)
> -                d300 = Deferred().addCallback(self.assertEquals, 300)
> -                runtime._expect_data(peer_id, "test", d100)
> -                runtime._expect_data(peer_id, "test", d200)
> -                runtime._expect_data(peer_id, "test", d300)
> +                d100 = Deferred().addCallback(self.assertEquals, '100')
> +                d200 = Deferred().addCallback(self.assertEquals, '200')
> +                d300 = Deferred().addCallback(self.assertEquals, '300')
> +                runtime._expect_data(peer_id, 42, d100)
> +                runtime._expect_data(peer_id, 42, d200)
> +                runtime._expect_data(peer_id, 42, d300)
>                  deferreds.extend([d100, d200, d300])


-- 
Martin Geisler

VIFF (Virtual Ideal Functionality Framework) brings easy and efficient
SMPC (Secure Multi-Party Computation) to Python. See: http://viff.dk/.
_______________________________________________
viff-patches mailing list
[email protected]
http://lists.viff.dk/listinfo.cgi/viff-patches-viff.dk

Reply via email to