changeset 1523:c58e71fb884b

BeDOZa: Remove RandomShareGenerator.
author Janus Dam Nielsen <janus.nielsen@alexandra.dk>
date Mon, 26 Jul 2010 09:34:47 +0200
parents e45ed7224d20
children 8da98c5697b5
files viff/bedoza/bedoza.py viff/bedoza/bedoza_triple.py viff/bedoza/modified_paillier.py viff/test/test_bedoza_runtime.py
diffstat 4 files changed, 364 insertions(+), 309 deletions(-) [+]
line wrap: on
line diff
--- a/viff/bedoza/bedoza.py	Fri Jul 23 13:17:52 2010 +0200
+++ b/viff/bedoza/bedoza.py	Mon Jul 26 09:34:47 2010 +0200
@@ -32,72 +32,17 @@
 from viff.bedoza.keylist import BeDOZaKeyList
 from viff.bedoza.maclist import BeDOZaMACList
 
+from viff.bedoza.share_generators import ShareGenerator
+
 class BeDOZaException(Exception):
     pass
-        
-class RandomShareGenerator:
-    """ TODO: This is a dummy implementation, and should be replaced with proper code."""
-    
-    def generate_random_shares(self, field, number_of_shares):
-        self.init_keys(field)
-        shares = []
-        for i in xrange(0, number_of_shares):
-            v = field(self.id)
-            shares.append(self.generate_share(field, v))
-        return shares
 
-    def generate_share(self, field, value):
-        my_keys = self.generate_keys(field)
-        macs = self.generate_auth_codes(self.id, value)
-        return BeDOZaShare(self, field, value, my_keys, macs)
 
-    def generate_auth_codes(self, playerId, value):
-        keys = map(lambda (alpha, akeys): (alpha, akeys[playerId - 1]), self.keys.values())
-        macs = self.authentication_codes(keys, value)
-        return macs
-
-    def authentication_codes(self, keys, v):
-        macs = []
-        for alpha, beta in keys:
-            macs.append(alpha * v + beta)
-        return BeDOZaMACList(macs)
-
-    def generate_keys(self, field):
-        alpha, betas = self.get_keys()
-        return BeDOZaKeyList(alpha, betas)
-
-    def init_keys(self, field):
-
-        self.keys = {}
-        for player_id in self.players:
-            betas = [field(56387295767672113),
-                     field(89238458945400961),
-                     field(12340004554789025),
-                     field(12907853897457058),
-                     field(90457903592570134),
-                     field(56256262346343232),
-                     field(23897437894556562),
-                     field(90297849575975574)]
-            self.keys[player_id] = (field(player_id), betas)
-
-    def get_keys(self):   
-        return self.keys[self.id]
-
-class BeDOZaMixin(HashBroadcastMixin, RandomShareGenerator):
+class BeDOZaMixin(HashBroadcastMixin, ShareGenerator):
  
     def MAC(self, alpha, beta, v):
         return alpha * v + beta
 
-    def random_share(self, field):
-        """Retrieve a previously generated random share in the field, field.
-
-        If no more shares are left, generate self.random_share_number new ones.
-        """
-        if len(self.random_shares) == 0:
-            self.random_shares = self.generate_random_shares(field, self.random_share_number)
-
-        return self.random_shares.pop()
-
     def output(self, share, receivers=None):
         return self.open(share, receivers)
 
@@ -360,22 +305,7 @@
         return x.cmul(c)
 
     def _get_triple(self, field):
-        """ TODO: This is a dummy implementation, and should be replaced with proper code."""
-        self.init_keys(field)
-        a, b, c = 0, 0, 0
-        share_a = field(2)
-        share_b = field(4)
-        n = len(self.players)
-        share_c = n * share_a * share_b
-        for playerid in self.players.keys():
-            if self.id == playerid:
-                triple_a = self.generate_share(field, share_a)
-                a += share_a.value
-                triple_b = self.generate_share(field, share_b)
-                b += share_b.value
-                triple_c = self.generate_share(field, share_c)
-                c += share_c.value
-        return [triple_a, triple_b, triple_c], False
+        return self.triples.pop(), False
 
 
 class BeDOZaRuntime(BeDOZaMixin, SimpleArithmeticRuntime):
@@ -402,5 +332,4 @@
         """Initialize runtime."""
         SimpleArithmeticRuntime.__init__(self, player, threshold, options)
         self.threshold = self.num_players - 1
-        self.random_share_number = 100
-        self.random_shares = []
+
--- a/viff/bedoza/bedoza_triple.py	Fri Jul 23 13:17:52 2010 +0200
+++ b/viff/bedoza/bedoza_triple.py	Mon Jul 26 09:34:47 2010 +0200
@@ -27,22 +27,17 @@
 from viff.field import FieldElement, GF
 from viff.constants import TEXT
 from viff.util import rand
-
 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
+from viff.bedoza.modified_paillier import ModifiedPaillier
 
 # TODO: Use secure random instead!
 from random import Random
 
-from viff.hash_broadcast import HashBroadcastMixin
-
 try:
     import pypaillier
 except ImportError:
@@ -58,70 +53,6 @@
     def __str__(self):
         return "(%s,%s,%s)" % (self.a, self.b, self.c)
 
-
-class ModifiedPaillier(object):
-    """A slight modification of the Paillier cryptosystem.
-
-    This modification has plaintext space [-(n-1)/ ; (n-1)/2] rather
-    than the usual Z_n where n is the Paillier modulus.
-
-    See Ivan's paper, beginning of section 6.
-    """
-
-    def __init__(self, runtime, random):
-        self.runtime = runtime;
-        self.random = random
-
-    def _f(self, x, n):
-        if x >= 0:
-            return x
-        else:
-            return n + x
-
-    def _f_inverse(self, y, n):
-        if 0 <= y <= (n + 1) / 2:
-            return y
-        else:
-            return y - n
-
-    def encrypt(self, value, player_id=None):
-        """Encrypt using public key of player player_id.
-
-        Defaults to own public key.
-        """
-        assert isinstance(value, int) or isinstance(value, long), \
-            "paillier: encrypts only integers and longs, got %s" % value.__class__
-        if not player_id:
-            player_id = self.runtime.id
-        n = self.runtime.players[player_id].pubkey['n']
-        min = -(n - 1) / 2 + 1
-        max = (n + 1) / 2
-        assert min <= value <= max, \
-            "paillier: plaintext %d outside legal range [-(n-1)/2+1 ; (n+1)/2] = " \
-            "[%d ; %d]"  % (value, min, max)
-        pubkey = self.runtime.players[player_id].pubkey
-        randomness = self.random.randint(1, long(n))
-        return pypaillier.encrypt_r(self._f(value, n), randomness, pubkey)
-
-    def decrypt(self, enc_value):
-        """Decrypt using own private key."""
-        assert isinstance(enc_value, int) or isinstance(enc_value, long), \
-            "paillier decrypts only longs, got %s" % enc_value.__class__
-        n = self.runtime.players[self.runtime.id].pubkey['n']
-        n_square = self.runtime.players[self.runtime.id].pubkey['n_square']
-        assert 0 <= enc_value < n_square, \
-            "paillier: ciphertext %d not in range [0 ; n^2] = [0 ; %d]" \
-            % (enc_value, n_square)
-        seckey = self.runtime.players[self.runtime.id].seckey
-        return self._f_inverse(pypaillier.decrypt(enc_value, seckey), n)
-
-    def get_modulus(self, player_id):
-        return self.runtime.players[player_id].pubkey['n']
-
-    def get_modulus_square(self, player_id):
-        return self.runtime.players[player_id].pubkey['n_square']
-
-
 class TripleGenerator(object):
 
     def __init__(self, runtime, p, random):
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/viff/bedoza/modified_paillier.py	Mon Jul 26 09:34:47 2010 +0200
@@ -0,0 +1,86 @@
+# 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/>.
+
+try:
+    import pypaillier
+except ImportError:
+    # The pypaillier module is not released yet, so we cannot expect
+    # the import to work.
+    print "Error: The pypaillier module or one of the used functions " \
+        "are not available."
+
+class ModifiedPaillier(object):
+    """A slight modification of the Paillier cryptosystem.
+
+    This modification has plaintext space [-(n-1)/ ; (n-1)/2] rather
+    than the usual Z_n where n is the Paillier modulus.
+
+    See Ivan's paper, beginning of section 6.
+    """
+
+    def __init__(self, runtime, random):
+        self.runtime = runtime;
+        self.random = random
+
+    def _f(self, x, n):
+        if x >= 0:
+            return x
+        else:
+            return n + x
+
+    def _f_inverse(self, y, n):
+        if 0 <= y <= (n + 1) / 2:
+            return y
+        else:
+            return y - n
+
+    def encrypt(self, value, player_id=None):
+        """Encrypt using public key of player player_id.
+
+        Defaults to own public key.
+        """
+        assert isinstance(value, int) or isinstance(value, long), \
+            "paillier: encrypts only integers and longs, got %s" % value.__class__
+        if not player_id:
+            player_id = self.runtime.id
+        n = self.runtime.players[player_id].pubkey['n']
+        min = -(n - 1) / 2 + 1
+        max = (n + 1) / 2
+        assert min <= value <= max, \
+            "paillier: plaintext %d outside legal range [-(n-1)/2+1 ; (n+1)/2] = " \
+            "[%d ; %d]"  % (value, min, max)
+        pubkey = self.runtime.players[player_id].pubkey
+        randomness = self.random.randint(1, long(n))
+        return pypaillier.encrypt_r(self._f(value, n), randomness, pubkey)
+
+    def decrypt(self, enc_value):
+        """Decrypt using own private key."""
+        assert isinstance(enc_value, int) or isinstance(enc_value, long), \
+            "paillier decrypts only longs, got %s" % enc_value.__class__
+        n = self.runtime.players[self.runtime.id].pubkey['n']
+        n_square = self.runtime.players[self.runtime.id].pubkey['n_square']
+        assert 0 <= enc_value < n_square, \
+            "paillier: ciphertext %d not in range [0 ; n^2] = [0 ; %d]" \
+            % (enc_value, n_square)
+        seckey = self.runtime.players[self.runtime.id].seckey
+        return self._f_inverse(pypaillier.decrypt(enc_value, seckey), n)
+
+    def get_modulus(self, player_id):
+        return self.runtime.players[player_id].pubkey['n']
+
+    def get_modulus_square(self, player_id):
+        return self.runtime.players[player_id].pubkey['n_square']
--- a/viff/test/test_bedoza_runtime.py	Fri Jul 23 13:17:52 2010 +0200
+++ b/viff/test/test_bedoza_runtime.py	Mon Jul 26 09:34:47 2010 +0200
@@ -17,6 +17,9 @@
 
 import sys
 
+# We don't need secure random numbers for test purposes.
+from random import Random
+
 from twisted.internet.defer import gatherResults, DeferredList
 
 from viff.test.util import RuntimeTestCase, protocol
@@ -28,29 +31,29 @@
 from viff.bedoza.maclist import BeDOZaMACList
 from viff.field import FieldElement, GF
 from viff.util import rand
+from viff.bedoza.modified_paillier import ModifiedPaillier
+from viff.bedoza.share_generators import ShareGenerator
+from viff.bedoza.bedoza_triple import TripleGenerator
 
-class KeyLoaderTest(RuntimeTestCase):
-    """Test of KeyLoader."""
+# The PyPaillier and commitment packages are not standard parts of VIFF so we
+# skip them instead of letting them fail if the packages are not available. 
+try:
+    import pypaillier
+except ImportError:
+    pypaillier = None
 
-    # Number of players.
-    num_players = 3
+# HACK: The paillier keys that are available as standard in VIFF tests
+# are not suited for use with pypaillier. Hence, we use NaClPaillier
+# to generate test keys. This confusion will disappear when pypaillier
+# replaces the current Python-based paillier implementation.
+from viff.paillierutil import NaClPaillier
 
-    runtime_class = BeDOZaRuntime
-
-    @protocol
-    def test_messagelist(self, runtime):
-        """Test loading of keys."""
-
-        Zp = GF(6277101735386680763835789423176059013767194773182842284081)
-
-        m1 = BeDOZaMACList([Zp(2), Zp(34)])
-        m2 = BeDOZaMACList([Zp(11), Zp(4)])
-        m3 = m1 + m2
-        self.assertEquals(m3.macs[0], 13)
-        self.assertEquals(m3.macs[1], 38)
-        self.assertEquals(len(m3.macs), 2)
-        return m3
-        
+# HACK^2: Currently, the NaClPaillier hack only works when triple is
+# imported. It should ideally work without the triple package.
+try:
+    import tripple
+except ImportError:
+    tripple = None
 
 
 class BeDOZaBasicCommandsTest(RuntimeTestCase):
@@ -59,29 +62,30 @@
     # Number of players.
     num_players = 3
 
+    timeout = 3
+
     runtime_class = BeDOZaRuntime
 
-    timeout = 3
-    
-    @protocol
-    def test_random_share(self, runtime):
-        """Test creation of a random shared number."""
+    # TODO: During test, we would like generation of Paillier keys to
+    # be deterministic. How do we obtain that?
+    def generate_configs(self, *args):
+        # In production, paillier keys should be something like 2000
+        # bit. For test purposes, it is ok to use small keys.
+        # TODO: paillier freezes if key size is too small, e.g. 13.
+        return generate_configs(paillier=NaClPaillier(250), *args)
 
-        Zp = GF(6277101735386680763835789423176059013767194773182842284081)
-
-        def check(v):
-            self.assertEquals(True, True)
-
-        x = runtime.random_share(Zp)
-        d = runtime.open(x)
-        d.addCallback(check)
-        return d
+    def setUp(self):
+        RuntimeTestCase.setUp(self)
+        self.Zp = GF(17)
+        bits_in_p = 5
+        self.u_bound = 2**(4 * bits_in_p)
+        self.alpha = 15
 
     @protocol
     def test_plus(self, runtime):
         """Test addition of two numbers."""
 
-        Zp = GF(6277101735386680763835789423176059013767194773182842284081)
+        Zp = self.Zp
        
         x = BeDOZaShareContents(Zp(2), BeDOZaKeyList(Zp(23), [Zp(3), Zp(4), Zp(1)]), BeDOZaMACList([Zp(2), Zp(74), Zp(23), Zp(2)]))
         y = BeDOZaShareContents(Zp(2), BeDOZaKeyList(Zp(23), [Zp(5), Zp(2), Zp(7)]), BeDOZaMACList([Zp(2), Zp(74), Zp(23), Zp(2)]))
@@ -92,15 +96,20 @@
 
     @protocol
     def test_sum(self, runtime):
-        """Test addition of two numbers."""
-
-        Zp = GF(6277101735386680763835789423176059013767194773182842284081)
+        """Test addition of two numbers."""       
 
         def check(v):
-            self.assertEquals(v, 12)
+            self.assertEquals(v, 0)
 
-        x2 = runtime.random_share(Zp)
-        y2 = runtime.random_share(Zp)
+        random = Random(3423993)
+        share_random = Random(random.getrandbits(128))
+        
+        paillier = ModifiedPaillier(runtime, Random(random.getrandbits(128)))          
+        gen = ShareGenerator(self.Zp, runtime, share_random,
+                             paillier, self.u_bound, self.alpha)
+        
+        x2 = gen.generate_share(8)
+        y2 = gen.generate_share(9)
         z2 = runtime.add(x2, y2)
         d = runtime.open(z2)
         d.addCallback(check)
@@ -110,13 +119,18 @@
     def test_sum_plus(self, runtime):
         """Test addition of two numbers."""
 
-        Zp = GF(6277101735386680763835789423176059013767194773182842284081)
+        def check(v):
+            self.assertEquals(v, 11)
 
-        def check(v):
-            self.assertEquals(v, 12)
-
-        x2 = runtime.random_share(Zp)
-        y2 = runtime.random_share(Zp)
+        random = Random(3423993)
+        share_random = Random(random.getrandbits(128))
+        
+        paillier = ModifiedPaillier(runtime, Random(random.getrandbits(128)))          
+        gen = ShareGenerator(self.Zp, runtime, share_random,
+                             paillier, self.u_bound, self.alpha)
+        
+        x2 = gen.generate_share(2)
+        y2 = gen.generate_share(9)
         z2 = x2 + y2
         d = runtime.open(z2)
         d.addCallback(check)
@@ -126,15 +140,19 @@
     def test_sum_constant_right(self, runtime):
         """Test addition of secret shared number and a public number."""
 
-        Zp = GF(31)
-
-        x1 = 42
         y1 = 7
 
         def check(v):
-            self.assertEquals(v, 13)
+            self.assertEquals(v, 15)
 
-        x2 = runtime.random_share(Zp)
+        random = Random(3423993)
+        share_random = Random(random.getrandbits(128))
+        
+        paillier = ModifiedPaillier(runtime, Random(random.getrandbits(128)))          
+        gen = ShareGenerator(self.Zp, runtime, share_random,
+                             paillier, self.u_bound, self.alpha)
+        
+        x2 = gen.generate_share(8)
         z2 = x2 + y1
         d = runtime.open(z2)
         d.addCallback(check)
@@ -144,15 +162,19 @@
     def test_sum_constant_left(self, runtime):
         """Test addition of a public number and secret shared number."""
 
-        Zp = GF(6277101735386680763835789423176059013767194773182842284081)
-
-        x1 = 42
         y1 = 7
 
         def check(v):
-            self.assertEquals(v, 13)
+            self.assertEquals(v, 15)
 
-        x2 = runtime.random_share(Zp)
+        random = Random(3423993)
+        share_random = Random(random.getrandbits(128))
+        
+        paillier = ModifiedPaillier(runtime, Random(random.getrandbits(128)))          
+        gen = ShareGenerator(self.Zp, runtime, share_random,
+                             paillier, self.u_bound, self.alpha)
+        
+        x2 = gen.generate_share(8)
         z2 = y1 + x2
         d = runtime.open(z2)
         d.addCallback(check)
@@ -162,7 +184,7 @@
     def test_minus(self, runtime):
         """Test subtraction of two numbers."""
 
-        Zp = GF(6277101735386680763835789423176059013767194773182842284081)
+        Zp = self.Zp
        
         x = BeDOZaShareContents(Zp(2), BeDOZaKeyList(Zp(23), [Zp(5), Zp(4), Zp(7)]), BeDOZaMACList([Zp(2), Zp(75), Zp(23), Zp(2)]))
         y = BeDOZaShareContents(Zp(2), BeDOZaKeyList(Zp(23), [Zp(3), Zp(2), Zp(1)]), BeDOZaMACList([Zp(2), Zp(74), Zp(23), Zp(2)]))
@@ -175,13 +197,18 @@
     def test_sub(self, runtime):
         """Test subtraction of two numbers."""
 
-        Zp = GF(6277101735386680763835789423176059013767194773182842284081)
+        def check(v):
+            self.assertEquals(v, 1)
 
-        def check(v):
-            self.assertEquals(v, 0)
-
-        x2 = runtime.random_share(Zp)
-        y2 = runtime.random_share(Zp)
+        random = Random(3423993)
+        share_random = Random(random.getrandbits(128))
+        
+        paillier = ModifiedPaillier(runtime, Random(random.getrandbits(128)))          
+        gen = ShareGenerator(self.Zp, runtime, share_random,
+                             paillier, self.u_bound, self.alpha)
+        
+        x2 = gen.generate_share(9)
+        y2 = gen.generate_share(8)
         z2 = runtime.sub(x2, y2)
         d = runtime.open(z2)
         d.addCallback(check)
@@ -191,13 +218,18 @@
     def test_sub_minus(self, runtime):
         """Test subtraction of two numbers."""
 
-        Zp = GF(6277101735386680763835789423176059013767194773182842284081)
+        def check(v):
+            self.assertEquals(v, 1)
 
-        def check(v):
-            self.assertEquals(v, 0)
-
-        x2 = runtime.random_share(Zp)
-        y2 = runtime.random_share(Zp)
+        random = Random(3423993)
+        share_random = Random(random.getrandbits(128))
+        
+        paillier = ModifiedPaillier(runtime, Random(random.getrandbits(128)))          
+        gen = ShareGenerator(self.Zp, runtime, share_random,
+                             paillier, self.u_bound, self.alpha)
+        
+        x2 = gen.generate_share(9)
+        y2 = gen.generate_share(8)
         z2 = x2 - y2
         d = runtime.open(z2)
         d.addCallback(check)
@@ -207,14 +239,19 @@
     def test_sub_constant_right(self, runtime):
         """Test subtraction of secret shared number and a public number."""
 
-        Zp = GF(31)
-
         y = 4
 
         def check(v):
-            self.assertEquals(v, 2)
+            self.assertEquals(v, 4)
 
-        x2 = runtime.random_share(Zp)
+        random = Random(3423993)
+        share_random = Random(random.getrandbits(128))
+        
+        paillier = ModifiedPaillier(runtime, Random(random.getrandbits(128)))          
+        gen = ShareGenerator(self.Zp, runtime, share_random,
+                             paillier, self.u_bound, self.alpha)
+        
+        x2 = gen.generate_share(8)
         z2 = x2 - y
         d = runtime.open(x2)
         d.addCallback(check)
@@ -224,14 +261,19 @@
     def test_sub_constant_left(self, runtime):
         """Test subtraction of a public number and secret shared number."""
 
-        Zp = GF(31)
-
         y = 8
 
         def check(v):
-            self.assertEquals(v, 2)
+            self.assertEquals(v, 3)
 
-        x2 = runtime.random_share(Zp)
+        random = Random(3423993)
+        share_random = Random(random.getrandbits(128))
+        
+        paillier = ModifiedPaillier(runtime, Random(random.getrandbits(128)))          
+        gen = ShareGenerator(self.Zp, runtime, share_random,
+                             paillier, self.u_bound, self.alpha)
+        
+        x2 = gen.generate_share(5)
         z2 = y - x2
         d = runtime.open(x2)
         d.addCallback(check)
@@ -241,17 +283,22 @@
     def test_constant_multiplication_constant_left(self, runtime):
         """Test multiplication of two numbers."""
 
-        Zp = GF(6277101735386680763835789423176059013767194773182842284081)
-
         x1 = 6
         y1 = 7
 
         def check(v):
-            self.assertEquals(v, x1 * y1)
+            self.assertEquals(v, self.Zp(x1 * y1))
 
-        x2 = runtime.random_share(Zp)
+        random = Random(3423993)
+        share_random = Random(random.getrandbits(128))
+        
+        paillier = ModifiedPaillier(runtime, Random(random.getrandbits(128)))          
+        gen = ShareGenerator(self.Zp, runtime, share_random,
+                             paillier, self.u_bound, self.alpha)
+        
+        x2 = gen.generate_share(x1)
 
-        z2 = runtime._cmul(Zp(y1), x2, Zp)
+        z2 = runtime._cmul(self.Zp(y1), x2, self.Zp)
         d = runtime.open(z2)
         d.addCallback(check)
         return d
@@ -260,17 +307,22 @@
     def test_constant_multiplication_constant_right(self, runtime):
         """Test multiplication of two numbers."""
 
-        Zp = GF(6277101735386680763835789423176059013767194773182842284081)
-
         x1 = 6
         y1 = 7
 
         def check(v):
-            self.assertEquals(v, x1 * y1)
+            self.assertEquals(v, self.Zp(x1 * y1))
 
-        x2 = runtime.random_share(Zp)
+        random = Random(3423993)
+        share_random = Random(random.getrandbits(128))
+        
+        paillier = ModifiedPaillier(runtime, Random(random.getrandbits(128)))          
+        gen = ShareGenerator(self.Zp, runtime, share_random,
+                             paillier, self.u_bound, self.alpha)
+        
+        x2 = gen.generate_share(x1)
 
-        z2 = runtime._cmul(x2, Zp(y1), Zp)
+        z2 = runtime._cmul(x2, self.Zp(y1), self.Zp)
         d = runtime.open(z2)
         d.addCallback(check)
         return d
@@ -279,111 +331,162 @@
     def test_get_triple(self, runtime):
         """Test generation of a triple."""
 
-        Zp = GF(6277101735386680763835789423176059013767194773182842284081)
-      
         def check((a, b, c)):
             self.assertEquals(c, a * b)
 
-        (a, b, c), _ = runtime._get_triple(Zp)
-        d1 = runtime.open(a)
-        d2 = runtime.open(b)
-        d3 = runtime.open(c)
-        d = gather_shares([d1, d2, d3])
-        d.addCallback(check)
-        return d
+        def open((a, b, c)):
+            d1 = runtime.open(a)
+            d2 = runtime.open(b)
+            d3 = runtime.open(c)
+            d = gather_shares([d1, d2, d3])
+            d.addCallback(check)
+            return d
+
+        random = Random(3423993)
+        gen = TripleGenerator(runtime, self.Zp.modulus, random)
+        [triple] = gen.generate_triples(1)
+        triple.addCallback(open)
+        return triple
 
     @protocol
     def test_basic_multiply(self, runtime):
         """Test multiplication of two numbers."""
 
-        Zp = GF(6277101735386680763835789423176059013767194773182842284081)
+        x1 = 6
+        y1 = 6
+
+        def check(v):
+            self.assertEquals(v, self.Zp(x1 * y1))
+
+        def do_stuff((a, b, c), alpha):
+            random = Random(3423993)
+            share_random = Random(random.getrandbits(128))
+        
+            paillier = ModifiedPaillier(runtime, Random(random.getrandbits(128)))          
+            gen = ShareGenerator(self.Zp, runtime, share_random,
+                                 paillier, self.u_bound, alpha)
+        
+            x2 = gen.generate_share(x1)
+            y2 = gen.generate_share(y1)
+            z2 = runtime._basic_multiplication(x2, y2, a, b, c)
+            d = runtime.open(z2)
+            d.addCallback(check)
+            return d
+
+        gen = TripleGenerator(runtime, self.Zp.modulus, Random(3423993))
+        alpha = gen.alpha
+        [triple] = gen.generate_triples(1)
+        runtime.schedule_callback(triple, do_stuff, alpha)
+        return triple
+
+    # @protocol
+    # def test_mul_mul(self, runtime):
+    #     """Test multiplication of two numbers."""
+
+    #     x1 = 6
+    #     y1 = 6
+
+    #     def check(v):
+    #         self.assertEquals(v, self.Zp(x1 * y1))
+
+    #     gen = TripleGenerator(runtime, self.Zp.modulus, Random(3423993))
+    #     alpha = gen.alpha
+    #     runtime.triples = gen.generate_triples(1)
+        
+
+    #     random = Random(3423993)
+    #     share_random = Random(random.getrandbits(128))
+    #     paillier = ModifiedPaillier(runtime, Random(random.getrandbits(128)))          
+    #     gen = ShareGenerator(self.Zp, runtime, share_random,
+    #                          paillier, self.u_bound, self.alpha)
+        
+    #     x2 = gen.generate_share(x1)
+    #     y2 = gen.generate_share(y1)
+        
+    #     z2 = x2 * y2
+    #     d = runtime.open(z2)
+    #     d.addCallback(check)
+    #     return d
+    
+    @protocol
+    def test_basic_multiply_constant_right(self, runtime):
+        """Test multiplication of two numbers."""
 
         x1 = 6
         y1 = 6
 
         def check(v):
-            self.assertEquals(v, x1 * y1)
+            self.assertEquals(v, self.Zp(x1 * y1))
 
-        x2 = runtime.random_share(Zp)
-        y2 = runtime.random_share(Zp)
+        def do_stuff((a, b, c), alpha):
+            random = Random(3423993)
+            share_random = Random(random.getrandbits(128))
+        
+            paillier = ModifiedPaillier(runtime, Random(random.getrandbits(128)))          
+            gen = ShareGenerator(self.Zp, runtime, share_random,
+                                 paillier, self.u_bound, alpha)
+        
+            x2 = gen.generate_share(x1)
+            y2 = gen.generate_share(y1)
+            z2 = runtime._basic_multiplication(x2, self.Zp(y1), a, b, c)
+            d = runtime.open(z2)
+            d.addCallback(check)
+            return d
 
-        (a, b, c), _ = runtime._get_triple(Zp)
-        z2 = runtime._basic_multiplication(x2, y2, a, b, c)
-        d = runtime.open(z2)
-        d.addCallback(check)
-        return d
+        gen = TripleGenerator(runtime, self.Zp.modulus, Random(3423993))
+        alpha = gen.alpha
+        [triple] = gen.generate_triples(1)
+        runtime.schedule_callback(triple, do_stuff, alpha)
+        return triple
 
     @protocol
-    def test_mul_mul(self, runtime):
+    def test_basic_multiply_constant_left(self, runtime):
         """Test multiplication of two numbers."""
 
-        Zp = GF(6277101735386680763835789423176059013767194773182842284081)
-
         x1 = 6
         y1 = 6
 
         def check(v):
-            self.assertEquals(v, x1 * y1)
+            self.assertEquals(v, self.Zp(x1 * y1))
 
-        x2 = runtime.random_share(Zp)
-        y2 = runtime.random_share(Zp)
+        def do_stuff((a, b, c), alpha):
+            random = Random(3423993)
+            share_random = Random(random.getrandbits(128))
+        
+            paillier = ModifiedPaillier(runtime, Random(random.getrandbits(128)))          
+            gen = ShareGenerator(self.Zp, runtime, share_random,
+                                 paillier, self.u_bound, alpha)
+        
+            x2 = gen.generate_share(x1)
+            y2 = gen.generate_share(y1)
+            z2 = runtime._basic_multiplication(self.Zp(x1), y2, a, b, c)
+            d = runtime.open(z2)
+            d.addCallback(check)
+            return d
 
-        z2 = x2 * y2
-        d = runtime.open(z2)
-        d.addCallback(check)
-        return d
-    @protocol
-    def test_basic_multiply_constant_right(self, runtime):
-        """Test multiplication of two numbers."""
-
-        Zp = GF(6277101735386680763835789423176059013767194773182842284081)
-
-        x1 = 6
-        y1 = 6
-
-        def check(v):
-            self.assertEquals(v, x1 * y1)
-
-        x2 = runtime.random_share(Zp)
-
-        (a, b, c), _ = runtime._get_triple(Zp)
-        z2 = runtime._basic_multiplication(x2, Zp(y1), a, b, c)
-        d = runtime.open(z2)
-        d.addCallback(check)
-        return d
-
-    @protocol
-    def test_basic_multiply_constant_left(self, runtime):
-        """Test multiplication of two numbers."""
-
-        Zp = GF(6277101735386680763835789423176059013767194773182842284081)
-
-        x1 = 6
-        y1 = 6
-
-        def check(v):
-            self.assertEquals(v, x1 * y1)
-
-        x2 = runtime.random_share(Zp)
-
-        (a, b, c), _ = runtime._get_triple(Zp)
-        z2 = runtime._basic_multiplication(Zp(y1), x2, a, b, c)
-        d = runtime.open(z2)
-        d.addCallback(check)
-        return d
+        gen = TripleGenerator(runtime, self.Zp.modulus, Random(3423993))
+        alpha = gen.alpha
+        [triple] = gen.generate_triples(1)
+        runtime.schedule_callback(triple, do_stuff, alpha)
+        return triple
 
     @protocol
     def test_open_multiple_secret_share(self, runtime):
         """Test sharing and open of a number."""
 
-        Zp = GF(6277101735386680763835789423176059013767194773182842284081)
-
         def check(ls):
             for v in ls:
                 self.assertEquals(v, 6)
 
-        x = runtime.random_share(Zp)
-        y = runtime.random_share(Zp)
+        random = Random(3423993)
+        share_random = Random(random.getrandbits(128))
+        
+        paillier = ModifiedPaillier(runtime, Random(random.getrandbits(128)))          
+        gen = ShareGenerator(self.Zp, runtime, share_random,
+                             paillier, self.u_bound, self.alpha)
+        
+        x = gen.generate_share(6)
+        y = gen.generate_share(6)
         d = runtime.open_multiple_values([x, y])
         d.addCallback(check)
         return d
@@ -392,14 +495,20 @@
     def test_open_two_secret_share(self, runtime):
         """Test sharing and open of a number."""
 
-        Zp = GF(6277101735386680763835789423176059013767194773182842284081)
-
         def check((a, b)):
             self.assertEquals(a, 6)
             self.assertEquals(b, 6)
 
-        x = runtime.random_share(Zp)
-        y = runtime.random_share(Zp)
+        random = Random(3423993)
+        share_random = Random(random.getrandbits(128))
+        
+        paillier = ModifiedPaillier(runtime, Random(random.getrandbits(128)))          
+        gen = ShareGenerator(self.Zp, runtime, share_random,
+                             paillier, self.u_bound, self.alpha)
+        
+        x = gen.generate_share(6)
+        y = gen.generate_share(6)
         d = runtime.open_two_values(x, y)
         d.addCallback(check)
         return d
+