changeset 1320:fb09cb799cc8

Preprocess decorator returns data without deferreds.
author Marcel Keller <mkeller@cs.au.dk>
date Fri, 02 Oct 2009 16:39:19 +0200
parents 96e0f7de22b0
children 71f205befbbb
files apps/aes.py viff/active.py viff/aes.py viff/passive.py viff/runtime.py
diffstat 5 files changed, 44 insertions(+), 47 deletions(-) [+]
line wrap: on
line diff
--- a/apps/aes.py	Fri Oct 02 11:27:08 2009 +0200
+++ b/apps/aes.py	Fri Oct 02 16:39:19 2009 +0200
@@ -141,7 +141,7 @@
             pcs = [(1, 2 + 130 * options.count + 141 * i + j, 1, 0)
                    for i in range(10 * options.count)
                    for j in range(140)] + \
-                  [(2, 18, k) + (81,) * i + (2 + 4 * j, 3, l, 1, 0)
+                  [(2, 18, k) + (121,) * i + (4 + 6 * j, l, 1, 0)
                    for k in range(1, options.count + 1)
                    for i in range(10)
                    for j in range(20)
@@ -154,7 +154,7 @@
         program_desc[("generate_triples", (GF256,))] = pcs
 
     if options.exponentiation == 4:
-        pcs = [(2, 18, k) + (81,) * i + (1 + j * 4, 0)
+        pcs = [(2, 18, k) + (121,) * i + (1 + j * 6, 0)
                for k in range(1, options.count + 1)
                for i in range(10)
                for j in range(20)]
--- a/viff/active.py	Fri Oct 02 11:27:08 2009 +0200
+++ b/viff/active.py	Fri Oct 02 16:39:19 2009 +0200
@@ -381,10 +381,10 @@
     def get_triple(self, field):
         # This is a waste, but this function is only called if there
         # are no pre-processed triples left.
-        return self.generate_triples(field)[0]
+        return self.generate_triples(field, gather=False)[0]
 
     @increment_pc
-    def generate_triples(self, field):
+    def generate_triples(self, field, gather=True):
         """Generate multiplication triples.
 
         These are random numbers *a*, *b*, and *c* such that ``c =
@@ -411,14 +411,23 @@
             d = [self.open(d_2t[i], threshold=2*t) for i in range(T)]
             c_t = [r_t[i] + d[i] for i in range(T)]
 
-            for triple, result in zip(zip(a_t, b_t, c_t), results):
-                gatherResults(triple).chainDeferred(result)
+            if gather:
+                for triple, result in zip(zip(a_t, b_t, c_t), results):
+                    gatherResults(triple).chainDeferred(result)
+            else:
+                for triple, result_triple in zip(zip(a_t, b_t, c_t), results):
+                    for item, result_item in zip(triple, result_triple):
+                        item.chainDeferred(result_item)
 
         single_a = self.single_share_random(T, t, field)
         single_b = self.single_share_random(T, t, field)
         double_c = self.double_share_random(T, t, 2*t, field)
 
-        results = [Deferred() for i in range(T)]
+        if gather:
+            results = [Deferred() for i in range(T)]
+        else:
+            results = [[Share(self, field) for i in range(3)] for i in range(T)]
+
         self.schedule_callback(gatherResults([single_a, single_b, double_c]), make_triple, results)
         return results
 
@@ -428,11 +437,11 @@
     @increment_pc
     @preprocess("generate_triples")
     def get_triple(self, field):
-        result = self.generate_triples(field, quantity=1)
+        result = self.generate_triples(field, quantity=1, gather=False)
         return result[0]
 
     @increment_pc
-    def generate_triples(self, field, quantity=20):
+    def generate_triples(self, field, quantity=20, gather=True):
         """Generate *quantity* multiplication triples using PRSS.
 
         These are random numbers *a*, *b*, and *c* such that ``c =
@@ -455,7 +464,10 @@
             d = self.open(d_2t, threshold=2*self.threshold)
             c_t[i] = r_t[i] + d
 
-        return [gatherResults(triple) for triple in zip(a_t, b_t, c_t)]
+        if gather:
+            return [gatherResults(triple) for triple in zip(a_t, b_t, c_t)]
+        else:
+            return zip(a_t, b_t, c_t)
 
 
 class BasicActiveRuntime(PassiveRuntime):
@@ -493,31 +505,21 @@
 
         # At this point both share_x and share_y must be Share
         # objects. We multiply them via a multiplication triple.
-        def finish_mul(triple):
-            a, b, c = triple
-            d = self.open(share_x - a)
-            e = self.open(share_y - b)
+        a, b, c = self.get_triple(share_x.field)
+        d = self.open(share_x - a)
+        e = self.open(share_y - b)
 
-            # TODO: We ought to be able to simply do
-            #
-            #   return d*e + d*y + e*x + c
-            #
-            # but that leads to infinite recursion since d and e are
-            # Shares, not FieldElements. So we have to do a bit more
-            # work... The following callback also leads to recursion, but
-            # only one level since d and e are FieldElements now, which
-            # means that we return in the above if statements.
-            result = gather_shares([d, e])
-            result.addCallback(lambda (d,e): d*e + d*b + e*a + c)
-            return result
-
-        # This will be the result, a Share object.
-        result = Share(self, share_x.field)
-        # This is the Deferred we will do processing on.
-        triple = self.get_triple(share_x.field)
-        triple = self.schedule_callback(triple, finish_mul)
-        # We add the result to the chains in triple.
-        triple.chainDeferred(result)
+        # TODO: We ought to be able to simply do
+        #
+        #   return d*e + d*y + e*x + c
+        #
+        # but that leads to infinite recursion since d and e are
+        # Shares, not FieldElements. So we have to do a bit more
+        # work... The following callback also leads to recursion, but
+        # only one level since d and e are FieldElements now, which
+        # means that we return in the above if statements.
+        result = gather_shares([d, e])
+        result.addCallback(lambda (d,e): d*e + d*b + e*a + c)
         return result
 
 
--- a/viff/aes.py	Fri Oct 02 11:27:08 2009 +0200
+++ b/viff/aes.py	Fri Oct 02 16:39:19 2009 +0200
@@ -167,17 +167,12 @@
                 byte_powers.append(byte_powers.pop(0) * byte_powers.pop(0))
             return byte_powers[0]
 
-        def open_and_exponentiate(random_powers):
-            masked_byte = self.runtime.open(byte + random_powers[0])
-            masked_powers = self.runtime.schedule_callback(masked_byte,
-                lambda masked_byte: self.runtime.powerchain(masked_byte, 7))
-            return self.runtime.schedule_callback(
-                masked_powers, add_and_multiply, random_powers)
-
-        result = Share(self.runtime, GF256)
-        self.runtime.prss_powerchain().chainDeferred(result)
-        result = self.runtime.schedule_callback(result, open_and_exponentiate)
-        return result
+        random_powers = self.runtime.prss_powerchain()
+        masked_byte = self.runtime.open(byte + random_powers[0])
+        masked_powers = self.runtime.schedule_callback(masked_byte,
+            lambda masked_byte: self.runtime.powerchain(masked_byte, 7))
+        return self.runtime.schedule_callback(
+            masked_powers, add_and_multiply, random_powers)
 
     def invert_by_exponentiation(self, byte):
         byte_2 = byte * byte
--- a/viff/passive.py	Fri Oct 02 11:27:08 2009 +0200
+++ b/viff/passive.py	Fri Oct 02 16:39:19 2009 +0200
@@ -467,7 +467,7 @@
         """Generate a random secret share in GF256 and returns
         [*share*, *share*^2, *share*^4, ..., *share*^(i^max)]."""
         share = self.prss_share_random(GF256)
-        return gatherResults(self.powerchain(share, max))
+        return self.powerchain(share, max)
 
     def prss_powerchains(self, max=7, quantity=20):
         """Does *quantity* times the same as :meth:`prss_powerchain`.
--- a/viff/runtime.py	Fri Oct 02 11:27:08 2009 +0200
+++ b/viff/runtime.py	Fri Oct 02 16:39:19 2009 +0200
@@ -446,7 +446,7 @@
         def preprocess_wrapper(self, *args, **kwargs):
             pc = tuple(self.program_counter)
             try:
-                return succeed(self._pool.pop(pc))
+                return self._pool.pop(pc)
             except KeyError:
                 key = (generator, args)
                 pcs = self._needed_data.setdefault(key, [])