changeset 1517:054a27514891

BeDOZa: Refactored _add_macs to a toplevel function add_macs.
author Janus Dam Nielsen <janus.nielsen@alexandra.dk>
date Thu, 22 Jul 2010 15:53:25 +0200
parents 7beb12b97911
children 4d229908e78f
files viff/bedoza_triple.py viff/test/test_bedoza_triple.py
diffstat 2 files changed, 141 insertions(+), 119 deletions(-) [+]
line wrap: on
line diff
--- a/viff/bedoza_triple.py	Thu Jul 22 12:21:19 2010 +0200
+++ b/viff/bedoza_triple.py	Thu Jul 22 15:53:25 2010 +0200
@@ -146,7 +146,7 @@
         enc_share = self.paillier.encrypt(share.value)
         enc_shares = _convolute(self.runtime, enc_share)
         def create_partial_share(enc_shares, share):
-            return PartialShare(self.runtime, value.field, share, enc_shares)
+            return PartialShare(self.runtime, self.Zp, share, enc_shares)
         self.runtime.schedule_callback(enc_shares, create_partial_share, share)
         return enc_shares
 
@@ -166,9 +166,17 @@
                                            ri,
                                            shares[inx],
                                            N_squared_list)
-            
         return shares
 
+class ShareGenerator(PartialShareGenerator):
+
+    def __init__(self, Zp, runtime, random, paillier):
+        PartialShareGenerator.__init__(self, Zp, runtime, random, paillier)
+
+    def generate_random_shares(self, n):
+        partial_shares = PartialShareGenerator.generate_random_shares(self, n)
+
+
 class ModifiedPaillier(object):
     """A slight modification of the Paillier cryptosystem.
 
@@ -231,6 +239,67 @@
     def get_modulus_square(self, player_id):
         return self.runtime.players[player_id].pubkey['n_square']
 
+def add_macs(runtime, field, u_bound, alpha, random, paillier, partial_shares):
+    """Adds macs to the set of PartialBeDOZaShares.
+        
+    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.
+        
+    runtime.increment_pc() # Huh!?
+
+    def do_add_macs(partial_share_contents, result_shares):
+        num_players = runtime.num_players
+        lists_of_mac_keys = [ [] for x in runtime.players ]
+        lists_of_c_list = [ [] for x in 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 = random.randint(0, u_bound)
+                # TODO: Outcommented until mod paillier works for negative numbers.
+                # if rand.choice([True, False]):
+                #    beta = -beta
+                enc_beta = paillier.encrypt(beta, player_id=j + 1)
+                c_j = partial_share_content.enc_shares[j]
+                n2 = paillier.get_modulus_square(j + 1)
+                c = (pow(c_j, alpha, n2) * enc_beta) % n2
+                lists_of_c_list[j].append(c)
+                lists_of_mac_keys[j].append(field(beta))
+
+        received_cs = _send(runtime, lists_of_c_list, deserialize=eval)
+
+        def finish_sharing(recevied_cs, partial_share_contents, lists_of_mac_keys, result_shares):
+            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(field(paillier.decrypt(c_list[inx])))
+                    mac_keys.append(mkeys[inx])
+                partial_share = partial_share_contents[inx]
+                mac_key_list = BeDOZaKeyList(alpha, mac_keys)
+
+                mac_msg_list = BeDOZaMACList(decrypted_cs)
+                result_shares[inx].callback(BeDOZaShareContents(partial_share.value,
+                                                                mac_key_list,
+                                                                mac_msg_list))
+            return shares
+
+        runtime.schedule_callback(received_cs, finish_sharing, partial_share_contents, lists_of_mac_keys, result_shares)
+        return received_cs
+
+    result_shares = [Share(runtime, field) for x in xrange(len(partial_shares))]
+    runtime.schedule_callback(gatherResults(partial_shares),
+                              do_add_macs,
+                              result_shares)
+    return result_shares
+
+
 class TripleGenerator(object):
 
     def __init__(self, runtime, p, random):
@@ -298,7 +367,7 @@
         for _ in xrange(n):
              random_shares.append(gen.generate_share(self.random.randint(0, self.Zp.modulus - 1)))
 
-        random_shares = self._add_macs(random_shares)
+        random_shares = add_macs(self.runtime, self.Zp, self.u_bound, self.alpha, self.random, self.paillier, random_shares)
 
         results = [Deferred() for _ in xrange(n)]
         
@@ -336,69 +405,9 @@
 
         partial_shares_c = self._full_mul(partial_shares[0:n], partial_shares[n:2*n])
 
-        full_shares = self._add_macs(partial_shares + partial_shares_c)
+        full_shares = add_macs(self.runtime, self.Zp, self.u_bound, self.alpha, self.random, self.paillier, partial_shares + partial_shares_c)
 
-        return full_shares
-    
-    def _add_macs(self, partial_shares):
-        """Adds macs to the set of PartialBeDOZaShares.
-        
-        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!?
-
-        def do_add_macs(partial_share_contents, result_shares):
-            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))
-
-            received_cs = _send(self.runtime, lists_of_c_list, deserialize=eval)
-
-            def finish_sharing(recevied_cs, partial_share_contents, lists_of_mac_keys, result_shares):
-                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)
-
-                    mac_msg_list = BeDOZaMACList(decrypted_cs)
-                    result_shares[inx].callback(BeDOZaShareContents(partial_share.value,
-                                                                   mac_key_list,
-                                                                   mac_msg_list))
-                return shares
-
-            self.runtime.schedule_callback(received_cs, finish_sharing, partial_share_contents, lists_of_mac_keys, result_shares)
-            return received_cs
-
-        result_shares = [Share(self.runtime, self.Zp) for x in xrange(len(partial_shares))]
-        self.runtime.schedule_callback(gatherResults(partial_shares),
-                                       do_add_macs,
-                                       result_shares)
-        return result_shares
+        return full_shares  
 
         # for player i:
         #     receive c from player i and set 
--- a/viff/test/test_bedoza_triple.py	Thu Jul 22 12:21:19 2010 +0200
+++ b/viff/test/test_bedoza_triple.py	Thu Jul 22 15:53:25 2010 +0200
@@ -32,7 +32,7 @@
 from viff.bedoza import BeDOZaRuntime, BeDOZaShare, BeDOZaKeyList
 
 from viff.bedoza_triple import TripleGenerator, PartialShare, PartialShareContents, ModifiedPaillier, PartialShareGenerator
-from viff.bedoza_triple import _send, _convolute, _convolute_gf_elm
+from viff.bedoza_triple import _send, _convolute, _convolute_gf_elm, add_macs
 
 from viff.field import FieldElement, GF
 from viff.config import generate_configs
@@ -209,7 +209,6 @@
     gen = PartialShareGenerator(Zp, runtime, share_random, paillier)
     return gen.generate_random_shares(n)
 
-
 class ParialShareGeneratorTest(BeDOZaTestCase):
     num_players = 3
  
@@ -281,11 +280,76 @@
             
         return shares
 
+class AddMacsTest(BeDOZaTestCase): 
+    num_players = 3
+
+    timeout = 10
+
+    @protocol
+    def test_add_macs_produces_correct_sharing(self, runtime):
+        # TODO: Here we use the open method of the BeDOZa runtime in
+        # order to verify the macs of the generated full share. In
+        # order to be more unit testish, this test should use its own
+        # way of verifying these.
+        p = 17
+        Zp = GF(p)
+        secret = 6
+        random = Random(283883)
+        paillier_random = Random(random.getrandbits(128))
+        paillier = ModifiedPaillier(runtime, random)
+
+        add_macs_random = Random(random.getrandbits(128))
+
+        shares_random = Random(random.getrandbits(128))
+        shares = []
+        shares.append(partial_share(shares_random, runtime, Zp, secret, paillier=paillier))
+        shares.append(partial_share(shares_random, runtime, Zp, secret + 1, paillier=paillier))
+        shares.append(partial_share(shares_random, runtime, Zp, secret + 2, paillier=paillier))
+        shares.append(partial_share(shares_random, runtime, Zp, secret + 3, paillier=paillier))
+
+        bits_in_p = 5
+        u_bound = 2**(4 * bits_in_p)
+        alpha = 15
+
+        zs = add_macs(runtime, Zp, u_bound, alpha,
+                      add_macs_random, paillier, shares)
+        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 zs:
+            opened_shares.append(runtime.open(s))
+        d = gather_shares(opened_shares)
+        d.addCallback(verify)
+        return d
+
+        
+#    @protocol
+#    def test_add_macs_preserves_value_of_sharing(self, runtime):
+#        partial_share = self._generate_partial_share_of(42)
+#        full_share = TripleGenerator()._add_macs(partial_share)
+#        secret = self._open_sharing(full_share)
+#        self.assertEquals(42, secret)
+#        return partial_share
+#    #test_add_macs_preserves_value_of_sharing.skip = "nyi"
+#        
+#    @protocol
+#    def test_add_macs_preserves_value_of_zero_sharing(self, runtime):
+#        partial_share = self._generate_partial_share_of(0)
+#        full_share = TripleGenerator()._add_macs(partial_share)
+#        secret = self._open_sharing(full_share)
+#        self.assertEquals(0, secret)
+#        return partial_share
+#    #test_add_macs_preserves_value_of_zero_sharing.skip = "nyi"
+# 
 
 class TripleTest(BeDOZaTestCase): 
     num_players = 3
 
-    timeout = 120
+    timeout = 12
 
     @protocol
     def test_generate_triples_generates_correct_triples(self, runtime):
@@ -333,57 +397,6 @@
         d.addCallback(verify)
         return d
 
-    @protocol
-    def test_add_macs_produces_correct_sharing(self, runtime):
-        # TODO: Here we use the open method of the BeDOZa runtime in
-        # order to verify the macs of the generated full share. In
-        # order to be more unit testish, this test should use its own
-        # way of verifying these.
-        p = 17
-        Zp = GF(p)
-        secret = 6
-        random = Random(283883)        
-        triple_generator = TripleGenerator(runtime, p, random)
-        paillier = triple_generator.paillier
-        shares = []
-        shares.append(partial_share(random, runtime, Zp, secret, paillier=paillier))
-        shares.append(partial_share(random, runtime, Zp, secret + 1, paillier=paillier))
-        shares.append(partial_share(random, runtime, Zp, secret + 2, paillier=paillier))
-        shares.append(partial_share(random, runtime, Zp, secret + 3, paillier=paillier))
-
-        zs = triple_generator._add_macs(shares)
-        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 zs:
-            opened_shares.append(runtime.open(s))
-        d = gather_shares(opened_shares)
-        d.addCallback(verify)
-        return d
-
-        
-#    @protocol
-#    def test_add_macs_preserves_value_of_sharing(self, runtime):
-#        partial_share = self._generate_partial_share_of(42)
-#        full_share = TripleGenerator()._add_macs(partial_share)
-#        secret = self._open_sharing(full_share)
-#        self.assertEquals(42, secret)
-#        return partial_share
-#    #test_add_macs_preserves_value_of_sharing.skip = "nyi"
-#        
-#    @protocol
-#    def test_add_macs_preserves_value_of_zero_sharing(self, runtime):
-#        partial_share = self._generate_partial_share_of(0)
-#        full_share = TripleGenerator()._add_macs(partial_share)
-#        secret = self._open_sharing(full_share)
-#        self.assertEquals(0, secret)
-#        return partial_share
-#    #test_add_macs_preserves_value_of_zero_sharing.skip = "nyi"
-# 
-
 class MulTest(BeDOZaTestCase): 
     num_players = 3