changeset 637:d1d4c633fca8

Make "Share * int" multiplication local too. Making Runtime.mul stricter in the type of arguments it accepts unveiled a little strangeness in prss_share_random: it called Runtime.mul with the same FieldElement used twice as argument. That is not necessary, so we now save a resharing there too.
author Martin Geisler <mg@daimi.au.dk>
date Fri, 04 Apr 2008 22:25:03 +0200
parents ba9166a59c20
children 45ce0d082747
files viff/runtime.py
diffstat 1 files changed, 17 insertions(+), 21 deletions(-) [+]
line wrap: on
line diff
--- a/viff/runtime.py	Fri Apr 04 21:20:19 2008 +0200
+++ b/viff/runtime.py	Fri Apr 04 22:25:03 2008 +0200
@@ -717,28 +717,23 @@
 
         Communication cost: 1 Shamir sharing.
         """
-        # If one of the arguments is a FieldElement, we do a local
-        # multiplication and skip the resharing step.
+        assert isinstance(share_a, Share) or isinstance(share_b, Share), \
+            "At least one of share_a and share_b must be a Share."
 
-        field = getattr(share_a, "field", getattr(share_b, "field", None))
+        if not isinstance(share_a, Share):
+            # Then share_b must be a Share => local multiplication. We
+            # clone first to avoid changing share_b.
+            result = share_b.clone()
+            result.addCallback(lambda b: share_a * b)
+            return result
+        if not isinstance(share_b, Share):
+            # Likewise when share_b is a constant.
+            result = share_a.clone()
+            result.addCallback(lambda a: a * share_b)
+            return result
 
-        if not isinstance(share_a, (Share, FieldElement)):
-            share_a = Share(self, field, share_a)
-
-        if not isinstance(share_b, (Share, FieldElement)):
-            share_b = Share(self, field, share_b)
-
-        if isinstance(share_a, FieldElement) and isinstance(share_b,
-                                                            FieldElement):
-            return Share(self, field, share_a * share_b)
-
-        if isinstance(share_a, FieldElement):
-            share_b.addCallback(lambda x: Share(self, field, share_a*x.value))
-            return share_b
-        if isinstance(share_b, FieldElement):
-            share_a.addCallback(lambda x: Share(self, field, x.value*share_b))
-            return share_a
-
+        # At this point both share_a and share_b must be Share
+        # objects. So we wait on them, multiply and reshare.
         result = gather_shares([share_a, share_b])
         result.addCallback(lambda (a, b): a * b)
         self.schedule_callback(result, self._shamir_share)
@@ -865,7 +860,8 @@
             return Share(self, field, share)
 
         # Open the square and compute a square-root
-        result = self.open(self.mul(share, share), threshold=2*self.threshold)
+        result = self.open(Share(self, field, share*share),
+                           threshold=2*self.threshold)
 
         def finish(square, share, binary):
             if square == 0: