changeset 1225:bb9566f09d3f

Implementation of random share command.
author Janus Dam Nielsen <janus.nielsen@alexandra.dk>
date Tue, 06 Oct 2009 10:05:24 +0200
parents 7ed324dff36b
children 94086392cb3c
files viff/orlandi.py viff/runtime.py viff/test/test_orlandi_runtime.py
diffstat 3 files changed, 63 insertions(+), 14 deletions(-) [+]
line wrap: on
line diff
--- a/viff/orlandi.py	Tue Oct 06 10:05:24 2009 +0200
+++ b/viff/orlandi.py	Tue Oct 06 10:05:24 2009 +0200
@@ -269,6 +269,53 @@
         if self.id in receivers:
             return result
 
+    def random_share(self, field):
+        """Generate a random share in the field, field.
+
+        To generate a share of a random element ``r in Z_p``, party ``P_i`` 
+        chooses at random ``r_i, rho_ri in Z_p X (Z_p)^2`` and
+        broadcast ``C_r^i = Com_ck(r_i, rho_ri)``.
+
+        Every party computes ``C_r = PRODUCT_i=1^n C_r^i = Com_ck(r, rho_r)``,
+        where ``r_i = SUM_i=1^n r_i and rho_r = SUM_i=1^n rho_ri``.
+
+        Party ``P_i sets [r]_i = (r_i, rho_ri, C_r)``.
+
+        """
+        self.program_counter[-1] += 1
+
+        # P_i chooses at random r_i, rho_ri in Z_p x (Z_p)^2
+        ri = field(rand.randint(0, field.modulus - 1))     
+        rhoi1 = field(rand.randint(0, field.modulus - 1))
+        rhoi2 = field(rand.randint(0, field.modulus - 1))
+
+        # compute C_r^i = Com_ck(r_i, rho_ri).
+        Cri = commitment.commit(ri.value, rhoi1, rhoi2)
+
+        # Broadcast C_r^i.
+        sls = gatherResults(self.broadcast(self.players.keys(), self.players.keys(), repr(Cri)))
+
+        def compute_commitment(ls):
+            Cr = ls.pop()
+            for Cri in ls:
+                Cr = Cr * Cri
+            return OrlandiShare(self, field, ri, (rhoi1, rhoi2), Cr)
+
+        def deserialize(ls):
+            return [ commitment.deserialize(x) for x in ls ]
+
+        sls.addCallbacks(deserialize, self.error_handler)
+        sls.addCallbacks(compute_commitment, self.error_handler)
+
+        s = Share(self, field)
+        # We add the result to the chains in triple.
+        sls.chainDeferred(s)
+
+        # do actual communication
+        self.activate_reactor()
+
+        return s
+
     def error_handler(self, ex):
         print "Error: ", ex
         return ex
--- a/viff/runtime.py	Tue Oct 06 10:05:24 2009 +0200
+++ b/viff/runtime.py	Tue Oct 06 10:05:24 2009 +0200
@@ -327,20 +327,13 @@
 
                 key = (program_counter, data_type)
 
-#                 print "Player %s has received data %s from %s with pc: %s" % (str(self.factory.runtime.id), 
-#                                                                               str(data), 
-#                                                                               str(self.peer_id),
-#                                                                               str(key))
-
                 if key in self.waiting_deferreds:
-#                    print "A deferred was waiting"
                     deq = self.waiting_deferreds[key]
                     deferred = deq.popleft()
                     if not deq:
                         del self.waiting_deferreds[key]
                     self.factory.runtime.handle_deferred_data(deferred, data)
                 else:
-#                    print "A deferred is not waiting, lets put the data on the shelf"
                     deq = self.incoming_data.setdefault(key, deque())
                     deq.append(data)
             except struct.error, e:
@@ -399,12 +392,6 @@
         """
         try:
             key = (program_counter, data_type)
-
-#            print self
-#             print "Player %s has received data %s from %s with pc: %s" % (str(self.factory.runtime.id), 
-#                                                                           str(data), 
-#                                                                           str(self.peer_id),
-#                                                                           program_counter)
                          
             if key in self.waiting_deferreds:
                 deq = self.waiting_deferreds[key]
@@ -754,7 +741,6 @@
         else:
             # We have not yet received anything from the other side.
             deq = self.protocols[peer_id].waiting_deferreds.setdefault(key, deque())
-#             print "The deferred %s is waiting on data from %i with key: %s" % (str(deferred), peer_id, str(key))
             deq.append(deferred)
 
     def _exchange_shares(self, peer_id, field_element):
@@ -869,6 +855,7 @@
     def handle_deferred_data(self, deferred, data):
         """Put deferred and data into the queue if the ViffReactor is running. 
         Otherwise, just execute the callback."""
+
         if self.using_viff_reactor:
             self.deferred_queue.append((deferred, data))
         else:
--- a/viff/test/test_orlandi_runtime.py	Tue Oct 06 10:05:24 2009 +0200
+++ b/viff/test/test_orlandi_runtime.py	Tue Oct 06 10:05:24 2009 +0200
@@ -71,3 +71,18 @@
         d.addCallback(check)
         return d
 
+    @protocol
+    def test_random_share(self, runtime):
+        """Test creation of a random shared number."""
+
+        self.Zp = GF(6277101735386680763835789423176059013767194773182842284081)        
+
+        def check(v):
+            self.assertEquals(True, True)           
+
+        x = runtime.random_share(self.Zp)
+        d = runtime.open(x)
+        d.addCallback(check)
+        return d
+ 
+