changeset 1508:891df84eb779

BeDOZa: addMacs is now able to process multiple shares in a batch.
author Janus Dam Nielsen <janus.nielsen@alexandra.dk>
date Tue, 20 Jul 2010 14:01:16 +0200
parents 3787ff4776bc
children a6be6cce7046
files viff/bedoza_triple.py viff/test/test_bedoza_triple.py
diffstat 2 files changed, 68 insertions(+), 52 deletions(-) [+]
line wrap: on
line diff
--- a/viff/bedoza_triple.py	Tue Jul 20 09:49:59 2010 +0200
+++ b/viff/bedoza_triple.py	Tue Jul 20 14:01:16 2010 +0200
@@ -244,52 +244,62 @@
     def _add_macs(self, partial_shares):
         """Adds macs to the set of PartialBeDOZaShares.
         
-        Returns a tuple with a single element that is a list of full
-        shares, e.g. including macs.  (the full shares are deferreds
-        of type BeDOZaShare.)
-
-        TODO: We have to return the list in a tuple due to some
-        Twisted thing.
+        Returns a deferred which yields a list of full shares, e.g.
+        including macs.  (the full shares are deferreds of type
+        BeDOZaShare.)
         """        
         # TODO: Would be nice with a class ShareContents like the class
         # PartialShareContents used here.
         
         self.runtime.increment_pc() # Huh!?
 
-        mac_keys = []
+        def do_add_macs(partial_share_contents):
+            num_players = self.runtime.num_players
+            lists_of_mac_keys = [ [] for x in self.runtime.players ]
+            lists_of_c_list = [ [] for x in self.runtime.players ]
+            for partial_share_content in partial_share_contents:
+                for j in xrange(0, num_players):
+                    # TODO: This is probably not the fastes way to generate
+                    # the betas.
+                    beta = self.random.randint(0, self.u_bound)
+                    # TODO: Outcommented until mod paillier works for negative numbers.
+                    # if rand.choice([True, False]):
+                    #    beta = -beta
+                    enc_beta = self.paillier.encrypt(beta, player_id=j + 1)
+                    c_j = partial_share_content.enc_shares[j]
+                    n2 = self.paillier.get_modulus_square(j + 1)
+                    c = (pow(c_j, self.alpha, n2) * enc_beta) % n2
+                    lists_of_c_list[j].append(c)
+                    lists_of_mac_keys[j].append(self.Zp(beta))
 
-        # TODO: Currently only support for one share.
-        i = 0
+            received_cs = _send(self.runtime, lists_of_c_list, deserialize=eval)
 
-        c_list = []
-        for j in range(self.runtime.num_players):
-            # TODO: This is probably not the fastes way to generate
-            # the betas.
-            beta = self.random.randint(0, self.u_bound)
-            # TODO: Outcommented until mod paillier works for negative numbers.
-            #if rand.choice([True, False]):
-            #    beta = -beta
-            enc_beta = self.paillier.encrypt(beta, player_id=j+1)
-            c_j = partial_shares[i].enc_shares[j]
-            n2 = self.runtime.players[j + 1].pubkey['n_square']
-            c = (pow(c_j, self.alpha, n2) * enc_beta) % n2
-            c_list.append(c)
-            mac_keys.append(self.Zp(beta))
-        received_cs = _send(self.runtime, c_list)
+            def finish_sharing(recevied_cs, partial_share_contents, lists_of_mac_keys):
+                shares = []               
+                for inx in xrange(0, len(partial_share_contents)):
+                    mac_keys = []
+                    decrypted_cs = []
+                    for c_list, mkeys in zip(recevied_cs,
+                                             lists_of_mac_keys):
+                        decrypted_cs.append(self.Zp(self.paillier.decrypt(c_list[inx])))
+                        mac_keys.append(mkeys[inx])
+                    partial_share = partial_share_contents[inx]
+                    mac_key_list = BeDOZaKeyList(self.alpha, mac_keys)
 
-        def finish_sharing(recevied_cs):
-            mac_key_list = BeDOZaKeyList(self.alpha, mac_keys)
-            decrypted_cs = [self.Zp(self.paillier.decrypt(c)) for c in received_cs.result]
-            mac_msg_list = BeDOZaMACList(decrypted_cs)
-            # Twisted HACK: Need to pack share into tuple.
-            return BeDOZaShare(self.runtime,
-                               partial_shares[i].value.field,
-                               partial_shares[i].value,
-                               mac_key_list,
-                               mac_msg_list),
+                    mac_msg_list = BeDOZaMACList(decrypted_cs)
+                    shares.append(BeDOZaShare(self.runtime,
+                                              partial_share.value.field,
+                                              partial_share.value,
+                                              mac_key_list,
+                                              mac_msg_list))
+                return shares
 
-        self.runtime.schedule_callback(received_cs, finish_sharing)
-        return [received_cs]
+            self.runtime.schedule_callback(received_cs, finish_sharing, partial_share_contents, lists_of_mac_keys)
+            return received_cs
+
+        d = gatherResults(partial_shares)
+        self.runtime.schedule_callback(d, do_add_macs)
+        return d
 
         # for player i:
         #     receive c from player i and set 
--- a/viff/test/test_bedoza_triple.py	Tue Jul 20 09:49:59 2010 +0200
+++ b/viff/test/test_bedoza_triple.py	Tue Jul 20 14:01:16 2010 +0200
@@ -279,25 +279,31 @@
         # order to be more unit testish, this test should use its own
         # way of verifying these.
         p = 17
-        secret = 9
+        secret = 6
         random = Random(283883)        
         triple_generator = TripleGenerator(runtime, p, random)
         paillier = triple_generator.paillier
-        share = partial_share(random, runtime, GF(p), secret, paillier=paillier)
-        def add_macs(share):
-            full_share_list = triple_generator._add_macs([share])
-            d = gatherResults(full_share_list)
-            def foo(ls):
-                # Twisted HACK: Need to unpack value ls[0] from tuple.
-                opened_share = runtime.open(ls[0][0])
-                def verify(open_share):
-                    self.assertEquals(secret, open_share.value)
-                runtime.schedule_callback(opened_share, verify)
-                return opened_share
-            d.addCallback(foo)
-            return d
-        runtime.schedule_callback(share, add_macs)
-        return share
+        shares = []
+        shares.append(partial_share(random, runtime, GF(p), secret, paillier=paillier))
+        shares.append(partial_share(random, runtime, GF(p), secret + 1, paillier=paillier))
+        shares.append(partial_share(random, runtime, GF(p), secret + 2, paillier=paillier))
+        shares.append(partial_share(random, runtime, GF(p), secret + 3, paillier=paillier))
+
+        zs = triple_generator._add_macs(shares)
+        def foo(ls):
+            def verify(open_shares):
+                inx = secret
+                for open_share in open_shares:
+                    self.assertEquals(inx, open_share.value)
+                    inx += 1
+            opened_shares = []
+            for s in ls:
+                opened_shares.append(runtime.open(s))
+            shares = gather_shares(opened_shares)
+            runtime.schedule_callback(shares, verify)
+            return shares
+        zs.addCallback(foo)
+        return zs
 
         
 #    @protocol