"Sigurd Torkel Meldgaard" <[EMAIL PROTECTED]> writes:

> I have made a quick change of the field-implementation so that it
> uses gmpy instead of internal longs, and it seems that for integers
> in the interval we usually use (~64 bits) it actually runs a bit
> slower (a equality test took 808 ms. instead of 767), I made a run
> with a modulo with 300 bits, and gmpy showed some speedup (965 ms.
> against 1199 ms.). All where tests done locally on camel12.

Thank you for testing this! I'm a bit disappointed that we see a
slowdown instead of a speedup for small field sizes -- I had hoped
performance to be equal if not better.

> I attach the patch if you want to play with it - maybe there is a
> much better way to do the interfacing.
>
> Sigurd
>
> diff -r 7cf3e950211d viff/field.py
> --- a/viff/field.py   Sun Sep 21 19:25:14 2008 +0200
> +++ b/viff/field.py   Wed Sep 24 16:01:12 2008 +0200
> @@ -85,6 +85,7 @@
>  #: Maps *(x,y)* to *xy*. See `_generate_tables`.
>  _mul_table = {}
>  
> +_mpz_type = type(mpz(1))
>  
>  # The class name is slightly wrong since the class instances cannot be
>  # said to be represent a field. Instead they represent instances of
> @@ -103,6 +104,8 @@
>          >>> GF256(1) == GF256(257)
>          True
>          """
> +        if isinstance(value, _mpz_type):
> +            value = int(value)

using int fails for large mpz values, but long works. It is actually
GMPY who is to blame since the int function is clever enough to return
a long integer if its argument overflows a normal integer. But GMPY
seems to not know that and so it throws an exception if int is used:

  >>> int(mpz(2**31 - 1))
  2147483647
  >>> int(mpz(2**31))
  Traceback (most recent call last):
    File "<stdin>", line 1, in ?
  OverflowError: mpz too large for int

>          self.value = value % self.modulus
>  
>      def __add__(self, other):
> @@ -248,6 +251,14 @@
>          """
>          return self.value != 0
>  
> +    @classmethod
> +    def marshal_representation(cls, value):
> +        """Returns a version of this value suitable for
> +        serializing with marshal.
> +
> +        We just return the value, as it is an int."""
> +        return value
> +
>  # We provide the class here to make the construction of new elements
>  # easy in a polymorphic context.
>  GF256.field = GF256
> @@ -337,8 +348,10 @@
>      class GFElement(FieldElement):
>  
>          def __init__(self, value):
> -            self.value = value % self.modulus
> -
> +            if isinstance(value, str):
> +                self.value = mpz(value, 256) % self.modulus

We're only ever supposed to create a GFElement from a string when
we're receiving data over the network -- so maybe it would be nicer
(performancewise) to skip the test here and then just do it in
stringReceived.

> +            else:
> +                self.value = mpz(value) % self.modulus
>          def __add__(self, other):
>              """Addition."""
>              if not isinstance(other, (GFElement, int, long)):
> @@ -508,7 +521,15 @@
>              """
>              return self.value != 0
>  
> -    GFElement.modulus = modulus
> +        @classmethod
> +        def marshal_representation(cls, value):
> +            """Returns a version of this value suitable for
> +            serializing with marshal.
> +
> +            We take the string representation of the mpz"""
> +            return value.binary()

You never actually call these class methods.

> +
> +    GFElement.modulus = mpz(modulus)
>      GFElement.field = GFElement
>  
>      _field_cache[modulus] = GFElement
> diff -r 7cf3e950211d viff/runtime.py
> --- a/viff/runtime.py Sun Sep 21 19:25:14 2008 +0200
> +++ b/viff/runtime.py Wed Sep 24 16:01:12 2008 +0200
> @@ -320,7 +320,10 @@
>          The program counter and the share are marshalled and sent to
>          the peer.
>          """
> -        self.sendData(program_counter, "share", share.value)
> +        if share.field is GF256:
> +            self.sendData(program_counter, "share", share.value)
> +        else:
> +            self.sendData(program_counter, "share", share.value.binary())

Here share is not a Share object as one would think... Instead it is
actually a FieldElement, so you could create a method called binary on
FieldElements and then let that return their self.value or
self.value.binary().

-- 
Martin Geisler

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

Reply via email to