changeset 1522:e45ed7224d20

BeDOZa: Moved generators to their own file.
author Janus Dam Nielsen <janus.nielsen@alexandra.dk>
date Fri, 23 Jul 2010 13:17:52 +0200
parents 9dcbcf1a3a6d
children c58e71fb884b
files viff/bedoza/add_macs.py viff/bedoza/bedoza_triple.py viff/bedoza/share_generators.py viff/bedoza/util.py viff/test/test_bedoza_triple.py
diffstat 5 files changed, 235 insertions(+), 163 deletions(-) [+]
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/viff/bedoza/add_macs.py	Fri Jul 23 13:17:52 2010 +0200
@@ -0,0 +1,85 @@
+# Copyright 2010 VIFF Development Team.
+#
+# This file is part of VIFF, the Virtual Ideal Functionality Framework.
+#
+# VIFF is free software: you can redistribute it and/or modify it
+# under the terms of the GNU Lesser General Public License (LGPL) as
+# published by the Free Software Foundation, either version 3 of the
+# License, or (at your option) any later version.
+#
+# VIFF is distributed in the hope that it will be useful, but WITHOUT
+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General
+# Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with VIFF. If not, see <http://www.gnu.org/licenses/>.
+
+from twisted.internet.defer import gatherResults
+from viff.runtime import Share
+
+from viff.bedoza.util import _send
+from viff.bedoza.keylist import BeDOZaKeyList
+from viff.bedoza.maclist import BeDOZaMACList
+
+from viff.bedoza.shares import BeDOZaShare, BeDOZaShareContents
+
+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
--- a/viff/bedoza/bedoza_triple.py	Fri Jul 23 13:17:51 2010 +0200
+++ b/viff/bedoza/bedoza_triple.py	Fri Jul 23 13:17:52 2010 +0200
@@ -30,9 +30,14 @@
 
 from viff.bedoza.shares import BeDOZaShare, BeDOZaShareContents, PartialShare, PartialShareContents
 
+from viff.bedoza.share_generators import PartialShareGenerator, ShareGenerator
+
 from viff.bedoza.keylist import BeDOZaKeyList
 from viff.bedoza.maclist import BeDOZaMACList
 
+from viff.bedoza.util import _send, _convolute
+from viff.bedoza.add_macs import add_macs
+
 # TODO: Use secure random instead!
 from random import Random
 
@@ -46,6 +51,7 @@
     print "Error: The pypaillier module or one of the used functions " \
         "are not available."
 
+
 class Triple(object):
     def __init__(self, a, b, c):
         self.a, self.b, self.c = a, b, c
@@ -53,107 +59,6 @@
         return "(%s,%s,%s)" % (self.a, self.b, self.c)
 
 
-def _send(runtime, vals, serialize=str, deserialize=int):
-    """Send vals[i] to player i + 1. Returns deferred list.
-
-    Works as default for integers. If other stuff has to be
-    sent, supply another serialization, deserialition.
-    """
-    runtime.increment_pc()
-    
-    pc = tuple(runtime.program_counter)
-    for p in runtime.players:
-        msg = serialize(vals[p - 1])
-        runtime.protocols[p].sendData(pc, TEXT, msg)
-    def err_handler(err):
-        print err
-    values = []
-    for p in runtime.players:
-        d = Deferred()
-        d.addCallbacks(deserialize, err_handler)
-        runtime._expect_data(p, TEXT, d)
-        values.append(d)
-    result = gatherResults(values)
-    return result
-
-def _convolute(runtime, val, serialize=str, deserialize=int):
-    """As send, but sends the same val to all players."""
-    return _send(runtime, [val] * runtime.num_players,
-                 serialize=serialize, deserialize=deserialize)
-
-def _convolute_gf_elm(runtime, gf_elm):
-    return _convolute(runtime, gf_elm,
-                      serialize=lambda x: str(x.value),
-                      deserialize=lambda x: gf_elm.field(int(x)))
-
-def _send_gf_elm(runtime, vals):
-    return _send(runtime, vals, 
-                 serialize=lambda x: str(x.value),
-                 deserialize=lambda x: gf_elm.field(int(x)))
-
-
-class PartialShareGenerator:
-
-    def __init__(self, Zp, runtime, random, paillier):
-        self.paillier = paillier
-        self.Zp = Zp
-        self.runtime = runtime
-        self.random = random
-
-    def generate_share(self, value):
-        self.runtime.increment_pc()
-        
-        r = [self.Zp(self.random.randint(0, self.Zp.modulus - 1)) # TODO: Exclusve?
-             for _ in range(self.runtime.num_players - 1)]
-        if self.runtime.id == 1:
-            share = value - sum(r)
-        else:
-            share = r[self.runtime.id - 2]
-        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, self.Zp, share, enc_shares)
-        self.runtime.schedule_callback(enc_shares, create_partial_share, share)
-        return enc_shares
-
-    def generate_random_shares(self, n):
-        self.runtime.increment_pc()
-        N_squared_list = [ self.runtime.players[player_id].pubkey['n_square'] for player_id in self.runtime.players]
-        shares = [PartialShare(self.runtime, self.Zp) for _ in xrange(n)]
-        for inx in xrange(n):
-            r = self.random.randint(0, self.Zp.modulus - 1)
-            ri = self.Zp(r)
-            enc_share = self.paillier.encrypt(ri.value)
-            enc_shares = _convolute(self.runtime, enc_share)
-            def create_partial_share(enc_shares, ri, s, N_squared_list):
-                s.callback(PartialShareContents(ri, enc_shares, N_squared_list))
-            self.runtime.schedule_callback(enc_shares,
-                                           create_partial_share,
-                                           ri,
-                                           shares[inx],
-                                           N_squared_list)
-        return shares
-
-class ShareGenerator(PartialShareGenerator):
-
-    def __init__(self, Zp, runtime, random, paillier, u_bound, alpha):
-        self.u_bound = u_bound
-        self.alpha = alpha
-        PartialShareGenerator.__init__(self, Zp, runtime, random, paillier)
-
-    def generate_share(self, value):
-        self.runtime.increment_pc()
-        partial_share = PartialShareGenerator.generate_share(self, value)
-        full_share = add_macs(self.runtime, self.Zp, self.u_bound, self.alpha,
-                             self.random, self.paillier, [partial_share])
-        return full_share[0]
-    
-    def generate_random_shares(self, n):
-        self.runtime.increment_pc()
-        partial_shares = PartialShareGenerator.generate_random_shares(self, n)
-        return add_macs(self.runtime, self.Zp, self.u_bound, self.alpha,
-                        self.random, self.paillier, partial_shares)
-
 class ModifiedPaillier(object):
     """A slight modification of the Paillier cryptosystem.
 
@@ -216,66 +121,6 @@
     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):
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/viff/bedoza/share_generators.py	Fri Jul 23 13:17:52 2010 +0200
@@ -0,0 +1,82 @@
+# Copyright 2010 VIFF Development Team.
+#
+# This file is part of VIFF, the Virtual Ideal Functionality Framework.
+#
+# VIFF is free software: you can redistribute it and/or modify it
+# under the terms of the GNU Lesser General Public License (LGPL) as
+# published by the Free Software Foundation, either version 3 of the
+# License, or (at your option) any later version.
+#
+# VIFF is distributed in the hope that it will be useful, but WITHOUT
+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General
+# Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with VIFF. If not, see <http://www.gnu.org/licenses/>.
+
+from viff.bedoza.shares import BeDOZaShare, BeDOZaShareContents, PartialShare, PartialShareContents
+from viff.bedoza.util import _convolute
+from viff.bedoza.add_macs import add_macs
+
+class PartialShareGenerator:
+
+    def __init__(self, Zp, runtime, random, paillier):
+        self.paillier = paillier
+        self.Zp = Zp
+        self.runtime = runtime
+        self.random = random
+
+    def generate_share(self, value):
+        self.runtime.increment_pc()
+        
+        r = [self.Zp(self.random.randint(0, self.Zp.modulus - 1)) # TODO: Exclusve?
+             for _ in range(self.runtime.num_players - 1)]
+        if self.runtime.id == 1:
+            share = value - sum(r)
+        else:
+            share = r[self.runtime.id - 2]
+        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, self.Zp, share, enc_shares)
+        self.runtime.schedule_callback(enc_shares, create_partial_share, share)
+        return enc_shares
+
+    def generate_random_shares(self, n):
+        self.runtime.increment_pc()
+        N_squared_list = [ self.runtime.players[player_id].pubkey['n_square'] for player_id in self.runtime.players]
+        shares = [PartialShare(self.runtime, self.Zp) for _ in xrange(n)]
+        for inx in xrange(n):
+            r = self.random.randint(0, self.Zp.modulus - 1)
+            ri = self.Zp(r)
+            enc_share = self.paillier.encrypt(ri.value)
+            enc_shares = _convolute(self.runtime, enc_share)
+            def create_partial_share(enc_shares, ri, s, N_squared_list):
+                s.callback(PartialShareContents(ri, enc_shares, N_squared_list))
+            self.runtime.schedule_callback(enc_shares,
+                                           create_partial_share,
+                                           ri,
+                                           shares[inx],
+                                           N_squared_list)
+        return shares
+
+class ShareGenerator(PartialShareGenerator):
+
+    def __init__(self, Zp, runtime, random, paillier, u_bound, alpha):
+        self.u_bound = u_bound
+        self.alpha = alpha
+        PartialShareGenerator.__init__(self, Zp, runtime, random, paillier)
+
+    def generate_share(self, value):
+        self.runtime.increment_pc()
+        partial_share = PartialShareGenerator.generate_share(self, value)
+        full_share = add_macs(self.runtime, self.Zp, self.u_bound, self.alpha,
+                             self.random, self.paillier, [partial_share])
+        return full_share[0]
+    
+    def generate_random_shares(self, n):
+        self.runtime.increment_pc()
+        partial_shares = PartialShareGenerator.generate_random_shares(self, n)
+        return add_macs(self.runtime, self.Zp, self.u_bound, self.alpha,
+                        self.random, self.paillier, partial_shares)
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/viff/bedoza/util.py	Fri Jul 23 13:17:52 2010 +0200
@@ -0,0 +1,58 @@
+# Copyright 2010 VIFF Development Team.
+#
+# This file is part of VIFF, the Virtual Ideal Functionality Framework.
+#
+# VIFF is free software: you can redistribute it and/or modify it
+# under the terms of the GNU Lesser General Public License (LGPL) as
+# published by the Free Software Foundation, either version 3 of the
+# License, or (at your option) any later version.
+#
+# VIFF is distributed in the hope that it will be useful, but WITHOUT
+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General
+# Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with VIFF. If not, see <http://www.gnu.org/licenses/>.
+
+from twisted.internet.defer import Deferred, gatherResults
+
+from viff.constants import TEXT
+
+def _send(runtime, vals, serialize=str, deserialize=int):
+    """Send vals[i] to player i + 1. Returns deferred list.
+
+    Works as default for integers. If other stuff has to be
+    sent, supply another serialization, deserialition.
+    """
+    runtime.increment_pc()
+    
+    pc = tuple(runtime.program_counter)
+    for p in runtime.players:
+        msg = serialize(vals[p - 1])
+        runtime.protocols[p].sendData(pc, TEXT, msg)
+    def err_handler(err):
+        print err
+    values = []
+    for p in runtime.players:
+        d = Deferred()
+        d.addCallbacks(deserialize, err_handler)
+        runtime._expect_data(p, TEXT, d)
+        values.append(d)
+    result = gatherResults(values)
+    return result
+
+def _convolute(runtime, val, serialize=str, deserialize=int):
+    """As send, but sends the same val to all players."""
+    return _send(runtime, [val] * runtime.num_players,
+                 serialize=serialize, deserialize=deserialize)
+
+def _convolute_gf_elm(runtime, gf_elm):
+    return _convolute(runtime, gf_elm,
+                      serialize=lambda x: str(x.value),
+                      deserialize=lambda x: gf_elm.field(int(x)))
+
+def _send_gf_elm(runtime, vals):
+    return _send(runtime, vals, 
+                 serialize=lambda x: str(x.value),
+                 deserialize=lambda x: gf_elm.field(int(x)))
--- a/viff/test/test_bedoza_triple.py	Fri Jul 23 13:17:51 2010 +0200
+++ b/viff/test/test_bedoza_triple.py	Fri Jul 23 13:17:52 2010 +0200
@@ -32,9 +32,11 @@
 
 from viff.bedoza.bedoza import BeDOZaRuntime, BeDOZaShare
 from viff.bedoza.keylist import BeDOZaKeyList
-from viff.bedoza.bedoza_triple import TripleGenerator, ModifiedPaillier, PartialShareGenerator, ShareGenerator
+from viff.bedoza.bedoza_triple import TripleGenerator, ModifiedPaillier
+from viff.bedoza.share_generators import PartialShareGenerator, ShareGenerator
 from viff.bedoza.shares import PartialShare, PartialShareContents
-from viff.bedoza.bedoza_triple import _send, _convolute, _convolute_gf_elm, add_macs
+from viff.bedoza.util import _send, _convolute, _convolute_gf_elm
+from viff.bedoza.add_macs import add_macs
 
 from viff.field import FieldElement, GF
 from viff.config import generate_configs