viff

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 diff
     1.1 --- a/viff/bedoza/bedoza.py	Fri Jul 23 13:17:52 2010 +0200
     1.2 +++ b/viff/bedoza/bedoza.py	Mon Jul 26 09:34:47 2010 +0200
     1.3 @@ -32,72 +32,17 @@
     1.4  from viff.bedoza.keylist import BeDOZaKeyList
     1.5  from viff.bedoza.maclist import BeDOZaMACList
     1.6  
     1.7 +from viff.bedoza.share_generators import ShareGenerator
     1.8 +
     1.9  class BeDOZaException(Exception):
    1.10      pass
    1.11 -        
    1.12 -class RandomShareGenerator:
    1.13 -    """ TODO: This is a dummy implementation, and should be replaced with proper code."""
    1.14 -    
    1.15 -    def generate_random_shares(self, field, number_of_shares):
    1.16 -        self.init_keys(field)
    1.17 -        shares = []
    1.18 -        for i in xrange(0, number_of_shares):
    1.19 -            v = field(self.id)
    1.20 -            shares.append(self.generate_share(field, v))
    1.21 -        return shares
    1.22  
    1.23 -    def generate_share(self, field, value):
    1.24 -        my_keys = self.generate_keys(field)
    1.25 -        macs = self.generate_auth_codes(self.id, value)
    1.26 -        return BeDOZaShare(self, field, value, my_keys, macs)
    1.27  
    1.28 -    def generate_auth_codes(self, playerId, value):
    1.29 -        keys = map(lambda (alpha, akeys): (alpha, akeys[playerId - 1]), self.keys.values())
    1.30 -        macs = self.authentication_codes(keys, value)
    1.31 -        return macs
    1.32 -
    1.33 -    def authentication_codes(self, keys, v):
    1.34 -        macs = []
    1.35 -        for alpha, beta in keys:
    1.36 -            macs.append(alpha * v + beta)
    1.37 -        return BeDOZaMACList(macs)
    1.38 -
    1.39 -    def generate_keys(self, field):
    1.40 -        alpha, betas = self.get_keys()
    1.41 -        return BeDOZaKeyList(alpha, betas)
    1.42 -
    1.43 -    def init_keys(self, field):
    1.44 -
    1.45 -        self.keys = {}
    1.46 -        for player_id in self.players:
    1.47 -            betas = [field(56387295767672113),
    1.48 -                     field(89238458945400961),
    1.49 -                     field(12340004554789025),
    1.50 -                     field(12907853897457058),
    1.51 -                     field(90457903592570134),
    1.52 -                     field(56256262346343232),
    1.53 -                     field(23897437894556562),
    1.54 -                     field(90297849575975574)]
    1.55 -            self.keys[player_id] = (field(player_id), betas)
    1.56 -
    1.57 -    def get_keys(self):   
    1.58 -        return self.keys[self.id]
    1.59 -
    1.60 -class BeDOZaMixin(HashBroadcastMixin, RandomShareGenerator):
    1.61 +class BeDOZaMixin(HashBroadcastMixin, ShareGenerator):
    1.62   
    1.63      def MAC(self, alpha, beta, v):
    1.64          return alpha * v + beta
    1.65  
    1.66 -    def random_share(self, field):
    1.67 -        """Retrieve a previously generated random share in the field, field.
    1.68 -
    1.69 -        If no more shares are left, generate self.random_share_number new ones.
    1.70 -        """
    1.71 -        if len(self.random_shares) == 0:
    1.72 -            self.random_shares = self.generate_random_shares(field, self.random_share_number)
    1.73 -
    1.74 -        return self.random_shares.pop()
    1.75 -
    1.76      def output(self, share, receivers=None):
    1.77          return self.open(share, receivers)
    1.78  
    1.79 @@ -360,22 +305,7 @@
    1.80          return x.cmul(c)
    1.81  
    1.82      def _get_triple(self, field):
    1.83 -        """ TODO: This is a dummy implementation, and should be replaced with proper code."""
    1.84 -        self.init_keys(field)
    1.85 -        a, b, c = 0, 0, 0
    1.86 -        share_a = field(2)
    1.87 -        share_b = field(4)
    1.88 -        n = len(self.players)
    1.89 -        share_c = n * share_a * share_b
    1.90 -        for playerid in self.players.keys():
    1.91 -            if self.id == playerid:
    1.92 -                triple_a = self.generate_share(field, share_a)
    1.93 -                a += share_a.value
    1.94 -                triple_b = self.generate_share(field, share_b)
    1.95 -                b += share_b.value
    1.96 -                triple_c = self.generate_share(field, share_c)
    1.97 -                c += share_c.value
    1.98 -        return [triple_a, triple_b, triple_c], False
    1.99 +        return self.triples.pop(), False
   1.100  
   1.101  
   1.102  class BeDOZaRuntime(BeDOZaMixin, SimpleArithmeticRuntime):
   1.103 @@ -402,5 +332,4 @@
   1.104          """Initialize runtime."""
   1.105          SimpleArithmeticRuntime.__init__(self, player, threshold, options)
   1.106          self.threshold = self.num_players - 1
   1.107 -        self.random_share_number = 100
   1.108 -        self.random_shares = []
   1.109 +
     2.1 --- a/viff/bedoza/bedoza_triple.py	Fri Jul 23 13:17:52 2010 +0200
     2.2 +++ b/viff/bedoza/bedoza_triple.py	Mon Jul 26 09:34:47 2010 +0200
     2.3 @@ -27,22 +27,17 @@
     2.4  from viff.field import FieldElement, GF
     2.5  from viff.constants import TEXT
     2.6  from viff.util import rand
     2.7 -
     2.8  from viff.bedoza.shares import BeDOZaShare, BeDOZaShareContents, PartialShare, PartialShareContents
     2.9 -
    2.10  from viff.bedoza.share_generators import PartialShareGenerator, ShareGenerator
    2.11 -
    2.12  from viff.bedoza.keylist import BeDOZaKeyList
    2.13  from viff.bedoza.maclist import BeDOZaMACList
    2.14 -
    2.15  from viff.bedoza.util import _send, _convolute
    2.16  from viff.bedoza.add_macs import add_macs
    2.17 +from viff.bedoza.modified_paillier import ModifiedPaillier
    2.18  
    2.19  # TODO: Use secure random instead!
    2.20  from random import Random
    2.21  
    2.22 -from viff.hash_broadcast import HashBroadcastMixin
    2.23 -
    2.24  try:
    2.25      import pypaillier
    2.26  except ImportError:
    2.27 @@ -58,70 +53,6 @@
    2.28      def __str__(self):
    2.29          return "(%s,%s,%s)" % (self.a, self.b, self.c)
    2.30  
    2.31 -
    2.32 -class ModifiedPaillier(object):
    2.33 -    """A slight modification of the Paillier cryptosystem.
    2.34 -
    2.35 -    This modification has plaintext space [-(n-1)/ ; (n-1)/2] rather
    2.36 -    than the usual Z_n where n is the Paillier modulus.
    2.37 -
    2.38 -    See Ivan's paper, beginning of section 6.
    2.39 -    """
    2.40 -
    2.41 -    def __init__(self, runtime, random):
    2.42 -        self.runtime = runtime;
    2.43 -        self.random = random
    2.44 -
    2.45 -    def _f(self, x, n):
    2.46 -        if x >= 0:
    2.47 -            return x
    2.48 -        else:
    2.49 -            return n + x
    2.50 -
    2.51 -    def _f_inverse(self, y, n):
    2.52 -        if 0 <= y <= (n + 1) / 2:
    2.53 -            return y
    2.54 -        else:
    2.55 -            return y - n
    2.56 -
    2.57 -    def encrypt(self, value, player_id=None):
    2.58 -        """Encrypt using public key of player player_id.
    2.59 -
    2.60 -        Defaults to own public key.
    2.61 -        """
    2.62 -        assert isinstance(value, int) or isinstance(value, long), \
    2.63 -            "paillier: encrypts only integers and longs, got %s" % value.__class__
    2.64 -        if not player_id:
    2.65 -            player_id = self.runtime.id
    2.66 -        n = self.runtime.players[player_id].pubkey['n']
    2.67 -        min = -(n - 1) / 2 + 1
    2.68 -        max = (n + 1) / 2
    2.69 -        assert min <= value <= max, \
    2.70 -            "paillier: plaintext %d outside legal range [-(n-1)/2+1 ; (n+1)/2] = " \
    2.71 -            "[%d ; %d]"  % (value, min, max)
    2.72 -        pubkey = self.runtime.players[player_id].pubkey
    2.73 -        randomness = self.random.randint(1, long(n))
    2.74 -        return pypaillier.encrypt_r(self._f(value, n), randomness, pubkey)
    2.75 -
    2.76 -    def decrypt(self, enc_value):
    2.77 -        """Decrypt using own private key."""
    2.78 -        assert isinstance(enc_value, int) or isinstance(enc_value, long), \
    2.79 -            "paillier decrypts only longs, got %s" % enc_value.__class__
    2.80 -        n = self.runtime.players[self.runtime.id].pubkey['n']
    2.81 -        n_square = self.runtime.players[self.runtime.id].pubkey['n_square']
    2.82 -        assert 0 <= enc_value < n_square, \
    2.83 -            "paillier: ciphertext %d not in range [0 ; n^2] = [0 ; %d]" \
    2.84 -            % (enc_value, n_square)
    2.85 -        seckey = self.runtime.players[self.runtime.id].seckey
    2.86 -        return self._f_inverse(pypaillier.decrypt(enc_value, seckey), n)
    2.87 -
    2.88 -    def get_modulus(self, player_id):
    2.89 -        return self.runtime.players[player_id].pubkey['n']
    2.90 -
    2.91 -    def get_modulus_square(self, player_id):
    2.92 -        return self.runtime.players[player_id].pubkey['n_square']
    2.93 -
    2.94 -
    2.95  class TripleGenerator(object):
    2.96  
    2.97      def __init__(self, runtime, p, random):
     3.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     3.2 +++ b/viff/bedoza/modified_paillier.py	Mon Jul 26 09:34:47 2010 +0200
     3.3 @@ -0,0 +1,86 @@
     3.4 +# Copyright 2010 VIFF Development Team.
     3.5 +#
     3.6 +# This file is part of VIFF, the Virtual Ideal Functionality Framework.
     3.7 +#
     3.8 +# VIFF is free software: you can redistribute it and/or modify it
     3.9 +# under the terms of the GNU Lesser General Public License (LGPL) as
    3.10 +# published by the Free Software Foundation, either version 3 of the
    3.11 +# License, or (at your option) any later version.
    3.12 +#
    3.13 +# VIFF is distributed in the hope that it will be useful, but WITHOUT
    3.14 +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
    3.15 +# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General
    3.16 +# Public License for more details.
    3.17 +#
    3.18 +# You should have received a copy of the GNU Lesser General Public
    3.19 +# License along with VIFF. If not, see <http://www.gnu.org/licenses/>.
    3.20 +
    3.21 +try:
    3.22 +    import pypaillier
    3.23 +except ImportError:
    3.24 +    # The pypaillier module is not released yet, so we cannot expect
    3.25 +    # the import to work.
    3.26 +    print "Error: The pypaillier module or one of the used functions " \
    3.27 +        "are not available."
    3.28 +
    3.29 +class ModifiedPaillier(object):
    3.30 +    """A slight modification of the Paillier cryptosystem.
    3.31 +
    3.32 +    This modification has plaintext space [-(n-1)/ ; (n-1)/2] rather
    3.33 +    than the usual Z_n where n is the Paillier modulus.
    3.34 +
    3.35 +    See Ivan's paper, beginning of section 6.
    3.36 +    """
    3.37 +
    3.38 +    def __init__(self, runtime, random):
    3.39 +        self.runtime = runtime;
    3.40 +        self.random = random
    3.41 +
    3.42 +    def _f(self, x, n):
    3.43 +        if x >= 0:
    3.44 +            return x
    3.45 +        else:
    3.46 +            return n + x
    3.47 +
    3.48 +    def _f_inverse(self, y, n):
    3.49 +        if 0 <= y <= (n + 1) / 2:
    3.50 +            return y
    3.51 +        else:
    3.52 +            return y - n
    3.53 +
    3.54 +    def encrypt(self, value, player_id=None):
    3.55 +        """Encrypt using public key of player player_id.
    3.56 +
    3.57 +        Defaults to own public key.
    3.58 +        """
    3.59 +        assert isinstance(value, int) or isinstance(value, long), \
    3.60 +            "paillier: encrypts only integers and longs, got %s" % value.__class__
    3.61 +        if not player_id:
    3.62 +            player_id = self.runtime.id
    3.63 +        n = self.runtime.players[player_id].pubkey['n']
    3.64 +        min = -(n - 1) / 2 + 1
    3.65 +        max = (n + 1) / 2
    3.66 +        assert min <= value <= max, \
    3.67 +            "paillier: plaintext %d outside legal range [-(n-1)/2+1 ; (n+1)/2] = " \
    3.68 +            "[%d ; %d]"  % (value, min, max)
    3.69 +        pubkey = self.runtime.players[player_id].pubkey
    3.70 +        randomness = self.random.randint(1, long(n))
    3.71 +        return pypaillier.encrypt_r(self._f(value, n), randomness, pubkey)
    3.72 +
    3.73 +    def decrypt(self, enc_value):
    3.74 +        """Decrypt using own private key."""
    3.75 +        assert isinstance(enc_value, int) or isinstance(enc_value, long), \
    3.76 +            "paillier decrypts only longs, got %s" % enc_value.__class__
    3.77 +        n = self.runtime.players[self.runtime.id].pubkey['n']
    3.78 +        n_square = self.runtime.players[self.runtime.id].pubkey['n_square']
    3.79 +        assert 0 <= enc_value < n_square, \
    3.80 +            "paillier: ciphertext %d not in range [0 ; n^2] = [0 ; %d]" \
    3.81 +            % (enc_value, n_square)
    3.82 +        seckey = self.runtime.players[self.runtime.id].seckey
    3.83 +        return self._f_inverse(pypaillier.decrypt(enc_value, seckey), n)
    3.84 +
    3.85 +    def get_modulus(self, player_id):
    3.86 +        return self.runtime.players[player_id].pubkey['n']
    3.87 +
    3.88 +    def get_modulus_square(self, player_id):
    3.89 +        return self.runtime.players[player_id].pubkey['n_square']
     4.1 --- a/viff/test/test_bedoza_runtime.py	Fri Jul 23 13:17:52 2010 +0200
     4.2 +++ b/viff/test/test_bedoza_runtime.py	Mon Jul 26 09:34:47 2010 +0200
     4.3 @@ -17,6 +17,9 @@
     4.4  
     4.5  import sys
     4.6  
     4.7 +# We don't need secure random numbers for test purposes.
     4.8 +from random import Random
     4.9 +
    4.10  from twisted.internet.defer import gatherResults, DeferredList
    4.11  
    4.12  from viff.test.util import RuntimeTestCase, protocol
    4.13 @@ -28,29 +31,29 @@
    4.14  from viff.bedoza.maclist import BeDOZaMACList
    4.15  from viff.field import FieldElement, GF
    4.16  from viff.util import rand
    4.17 +from viff.bedoza.modified_paillier import ModifiedPaillier
    4.18 +from viff.bedoza.share_generators import ShareGenerator
    4.19 +from viff.bedoza.bedoza_triple import TripleGenerator
    4.20  
    4.21 -class KeyLoaderTest(RuntimeTestCase):
    4.22 -    """Test of KeyLoader."""
    4.23 +# The PyPaillier and commitment packages are not standard parts of VIFF so we
    4.24 +# skip them instead of letting them fail if the packages are not available. 
    4.25 +try:
    4.26 +    import pypaillier
    4.27 +except ImportError:
    4.28 +    pypaillier = None
    4.29  
    4.30 -    # Number of players.
    4.31 -    num_players = 3
    4.32 +# HACK: The paillier keys that are available as standard in VIFF tests
    4.33 +# are not suited for use with pypaillier. Hence, we use NaClPaillier
    4.34 +# to generate test keys. This confusion will disappear when pypaillier
    4.35 +# replaces the current Python-based paillier implementation.
    4.36 +from viff.paillierutil import NaClPaillier
    4.37  
    4.38 -    runtime_class = BeDOZaRuntime
    4.39 -
    4.40 -    @protocol
    4.41 -    def test_messagelist(self, runtime):
    4.42 -        """Test loading of keys."""
    4.43 -
    4.44 -        Zp = GF(6277101735386680763835789423176059013767194773182842284081)
    4.45 -
    4.46 -        m1 = BeDOZaMACList([Zp(2), Zp(34)])
    4.47 -        m2 = BeDOZaMACList([Zp(11), Zp(4)])
    4.48 -        m3 = m1 + m2
    4.49 -        self.assertEquals(m3.macs[0], 13)
    4.50 -        self.assertEquals(m3.macs[1], 38)
    4.51 -        self.assertEquals(len(m3.macs), 2)
    4.52 -        return m3
    4.53 -        
    4.54 +# HACK^2: Currently, the NaClPaillier hack only works when triple is
    4.55 +# imported. It should ideally work without the triple package.
    4.56 +try:
    4.57 +    import tripple
    4.58 +except ImportError:
    4.59 +    tripple = None
    4.60  
    4.61  
    4.62  class BeDOZaBasicCommandsTest(RuntimeTestCase):
    4.63 @@ -59,29 +62,30 @@
    4.64      # Number of players.
    4.65      num_players = 3
    4.66  
    4.67 +    timeout = 3
    4.68 +
    4.69      runtime_class = BeDOZaRuntime
    4.70  
    4.71 -    timeout = 3
    4.72 -    
    4.73 -    @protocol
    4.74 -    def test_random_share(self, runtime):
    4.75 -        """Test creation of a random shared number."""
    4.76 +    # TODO: During test, we would like generation of Paillier keys to
    4.77 +    # be deterministic. How do we obtain that?
    4.78 +    def generate_configs(self, *args):
    4.79 +        # In production, paillier keys should be something like 2000
    4.80 +        # bit. For test purposes, it is ok to use small keys.
    4.81 +        # TODO: paillier freezes if key size is too small, e.g. 13.
    4.82 +        return generate_configs(paillier=NaClPaillier(250), *args)
    4.83  
    4.84 -        Zp = GF(6277101735386680763835789423176059013767194773182842284081)
    4.85 -
    4.86 -        def check(v):
    4.87 -            self.assertEquals(True, True)
    4.88 -
    4.89 -        x = runtime.random_share(Zp)
    4.90 -        d = runtime.open(x)
    4.91 -        d.addCallback(check)
    4.92 -        return d
    4.93 +    def setUp(self):
    4.94 +        RuntimeTestCase.setUp(self)
    4.95 +        self.Zp = GF(17)
    4.96 +        bits_in_p = 5
    4.97 +        self.u_bound = 2**(4 * bits_in_p)
    4.98 +        self.alpha = 15
    4.99  
   4.100      @protocol
   4.101      def test_plus(self, runtime):
   4.102          """Test addition of two numbers."""
   4.103  
   4.104 -        Zp = GF(6277101735386680763835789423176059013767194773182842284081)
   4.105 +        Zp = self.Zp
   4.106         
   4.107          x = BeDOZaShareContents(Zp(2), BeDOZaKeyList(Zp(23), [Zp(3), Zp(4), Zp(1)]), BeDOZaMACList([Zp(2), Zp(74), Zp(23), Zp(2)]))
   4.108          y = BeDOZaShareContents(Zp(2), BeDOZaKeyList(Zp(23), [Zp(5), Zp(2), Zp(7)]), BeDOZaMACList([Zp(2), Zp(74), Zp(23), Zp(2)]))
   4.109 @@ -92,15 +96,20 @@
   4.110  
   4.111      @protocol
   4.112      def test_sum(self, runtime):
   4.113 -        """Test addition of two numbers."""
   4.114 -
   4.115 -        Zp = GF(6277101735386680763835789423176059013767194773182842284081)
   4.116 +        """Test addition of two numbers."""       
   4.117  
   4.118          def check(v):
   4.119 -            self.assertEquals(v, 12)
   4.120 +            self.assertEquals(v, 0)
   4.121  
   4.122 -        x2 = runtime.random_share(Zp)
   4.123 -        y2 = runtime.random_share(Zp)
   4.124 +        random = Random(3423993)
   4.125 +        share_random = Random(random.getrandbits(128))
   4.126 +        
   4.127 +        paillier = ModifiedPaillier(runtime, Random(random.getrandbits(128)))          
   4.128 +        gen = ShareGenerator(self.Zp, runtime, share_random,
   4.129 +                             paillier, self.u_bound, self.alpha)
   4.130 +        
   4.131 +        x2 = gen.generate_share(8)
   4.132 +        y2 = gen.generate_share(9)
   4.133          z2 = runtime.add(x2, y2)
   4.134          d = runtime.open(z2)
   4.135          d.addCallback(check)
   4.136 @@ -110,13 +119,18 @@
   4.137      def test_sum_plus(self, runtime):
   4.138          """Test addition of two numbers."""
   4.139  
   4.140 -        Zp = GF(6277101735386680763835789423176059013767194773182842284081)
   4.141 +        def check(v):
   4.142 +            self.assertEquals(v, 11)
   4.143  
   4.144 -        def check(v):
   4.145 -            self.assertEquals(v, 12)
   4.146 -
   4.147 -        x2 = runtime.random_share(Zp)
   4.148 -        y2 = runtime.random_share(Zp)
   4.149 +        random = Random(3423993)
   4.150 +        share_random = Random(random.getrandbits(128))
   4.151 +        
   4.152 +        paillier = ModifiedPaillier(runtime, Random(random.getrandbits(128)))          
   4.153 +        gen = ShareGenerator(self.Zp, runtime, share_random,
   4.154 +                             paillier, self.u_bound, self.alpha)
   4.155 +        
   4.156 +        x2 = gen.generate_share(2)
   4.157 +        y2 = gen.generate_share(9)
   4.158          z2 = x2 + y2
   4.159          d = runtime.open(z2)
   4.160          d.addCallback(check)
   4.161 @@ -126,15 +140,19 @@
   4.162      def test_sum_constant_right(self, runtime):
   4.163          """Test addition of secret shared number and a public number."""
   4.164  
   4.165 -        Zp = GF(31)
   4.166 -
   4.167 -        x1 = 42
   4.168          y1 = 7
   4.169  
   4.170          def check(v):
   4.171 -            self.assertEquals(v, 13)
   4.172 +            self.assertEquals(v, 15)
   4.173  
   4.174 -        x2 = runtime.random_share(Zp)
   4.175 +        random = Random(3423993)
   4.176 +        share_random = Random(random.getrandbits(128))
   4.177 +        
   4.178 +        paillier = ModifiedPaillier(runtime, Random(random.getrandbits(128)))          
   4.179 +        gen = ShareGenerator(self.Zp, runtime, share_random,
   4.180 +                             paillier, self.u_bound, self.alpha)
   4.181 +        
   4.182 +        x2 = gen.generate_share(8)
   4.183          z2 = x2 + y1
   4.184          d = runtime.open(z2)
   4.185          d.addCallback(check)
   4.186 @@ -144,15 +162,19 @@
   4.187      def test_sum_constant_left(self, runtime):
   4.188          """Test addition of a public number and secret shared number."""
   4.189  
   4.190 -        Zp = GF(6277101735386680763835789423176059013767194773182842284081)
   4.191 -
   4.192 -        x1 = 42
   4.193          y1 = 7
   4.194  
   4.195          def check(v):
   4.196 -            self.assertEquals(v, 13)
   4.197 +            self.assertEquals(v, 15)
   4.198  
   4.199 -        x2 = runtime.random_share(Zp)
   4.200 +        random = Random(3423993)
   4.201 +        share_random = Random(random.getrandbits(128))
   4.202 +        
   4.203 +        paillier = ModifiedPaillier(runtime, Random(random.getrandbits(128)))          
   4.204 +        gen = ShareGenerator(self.Zp, runtime, share_random,
   4.205 +                             paillier, self.u_bound, self.alpha)
   4.206 +        
   4.207 +        x2 = gen.generate_share(8)
   4.208          z2 = y1 + x2
   4.209          d = runtime.open(z2)
   4.210          d.addCallback(check)
   4.211 @@ -162,7 +184,7 @@
   4.212      def test_minus(self, runtime):
   4.213          """Test subtraction of two numbers."""
   4.214  
   4.215 -        Zp = GF(6277101735386680763835789423176059013767194773182842284081)
   4.216 +        Zp = self.Zp
   4.217         
   4.218          x = BeDOZaShareContents(Zp(2), BeDOZaKeyList(Zp(23), [Zp(5), Zp(4), Zp(7)]), BeDOZaMACList([Zp(2), Zp(75), Zp(23), Zp(2)]))
   4.219          y = BeDOZaShareContents(Zp(2), BeDOZaKeyList(Zp(23), [Zp(3), Zp(2), Zp(1)]), BeDOZaMACList([Zp(2), Zp(74), Zp(23), Zp(2)]))
   4.220 @@ -175,13 +197,18 @@
   4.221      def test_sub(self, runtime):
   4.222          """Test subtraction of two numbers."""
   4.223  
   4.224 -        Zp = GF(6277101735386680763835789423176059013767194773182842284081)
   4.225 +        def check(v):
   4.226 +            self.assertEquals(v, 1)
   4.227  
   4.228 -        def check(v):
   4.229 -            self.assertEquals(v, 0)
   4.230 -
   4.231 -        x2 = runtime.random_share(Zp)
   4.232 -        y2 = runtime.random_share(Zp)
   4.233 +        random = Random(3423993)
   4.234 +        share_random = Random(random.getrandbits(128))
   4.235 +        
   4.236 +        paillier = ModifiedPaillier(runtime, Random(random.getrandbits(128)))          
   4.237 +        gen = ShareGenerator(self.Zp, runtime, share_random,
   4.238 +                             paillier, self.u_bound, self.alpha)
   4.239 +        
   4.240 +        x2 = gen.generate_share(9)
   4.241 +        y2 = gen.generate_share(8)
   4.242          z2 = runtime.sub(x2, y2)
   4.243          d = runtime.open(z2)
   4.244          d.addCallback(check)
   4.245 @@ -191,13 +218,18 @@
   4.246      def test_sub_minus(self, runtime):
   4.247          """Test subtraction of two numbers."""
   4.248  
   4.249 -        Zp = GF(6277101735386680763835789423176059013767194773182842284081)
   4.250 +        def check(v):
   4.251 +            self.assertEquals(v, 1)
   4.252  
   4.253 -        def check(v):
   4.254 -            self.assertEquals(v, 0)
   4.255 -
   4.256 -        x2 = runtime.random_share(Zp)
   4.257 -        y2 = runtime.random_share(Zp)
   4.258 +        random = Random(3423993)
   4.259 +        share_random = Random(random.getrandbits(128))
   4.260 +        
   4.261 +        paillier = ModifiedPaillier(runtime, Random(random.getrandbits(128)))          
   4.262 +        gen = ShareGenerator(self.Zp, runtime, share_random,
   4.263 +                             paillier, self.u_bound, self.alpha)
   4.264 +        
   4.265 +        x2 = gen.generate_share(9)
   4.266 +        y2 = gen.generate_share(8)
   4.267          z2 = x2 - y2
   4.268          d = runtime.open(z2)
   4.269          d.addCallback(check)
   4.270 @@ -207,14 +239,19 @@
   4.271      def test_sub_constant_right(self, runtime):
   4.272          """Test subtraction of secret shared number and a public number."""
   4.273  
   4.274 -        Zp = GF(31)
   4.275 -
   4.276          y = 4
   4.277  
   4.278          def check(v):
   4.279 -            self.assertEquals(v, 2)
   4.280 +            self.assertEquals(v, 4)
   4.281  
   4.282 -        x2 = runtime.random_share(Zp)
   4.283 +        random = Random(3423993)
   4.284 +        share_random = Random(random.getrandbits(128))
   4.285 +        
   4.286 +        paillier = ModifiedPaillier(runtime, Random(random.getrandbits(128)))          
   4.287 +        gen = ShareGenerator(self.Zp, runtime, share_random,
   4.288 +                             paillier, self.u_bound, self.alpha)
   4.289 +        
   4.290 +        x2 = gen.generate_share(8)
   4.291          z2 = x2 - y
   4.292          d = runtime.open(x2)
   4.293          d.addCallback(check)
   4.294 @@ -224,14 +261,19 @@
   4.295      def test_sub_constant_left(self, runtime):
   4.296          """Test subtraction of a public number and secret shared number."""
   4.297  
   4.298 -        Zp = GF(31)
   4.299 -
   4.300          y = 8
   4.301  
   4.302          def check(v):
   4.303 -            self.assertEquals(v, 2)
   4.304 +            self.assertEquals(v, 3)
   4.305  
   4.306 -        x2 = runtime.random_share(Zp)
   4.307 +        random = Random(3423993)
   4.308 +        share_random = Random(random.getrandbits(128))
   4.309 +        
   4.310 +        paillier = ModifiedPaillier(runtime, Random(random.getrandbits(128)))          
   4.311 +        gen = ShareGenerator(self.Zp, runtime, share_random,
   4.312 +                             paillier, self.u_bound, self.alpha)
   4.313 +        
   4.314 +        x2 = gen.generate_share(5)
   4.315          z2 = y - x2
   4.316          d = runtime.open(x2)
   4.317          d.addCallback(check)
   4.318 @@ -241,17 +283,22 @@
   4.319      def test_constant_multiplication_constant_left(self, runtime):
   4.320          """Test multiplication of two numbers."""
   4.321  
   4.322 -        Zp = GF(6277101735386680763835789423176059013767194773182842284081)
   4.323 -
   4.324          x1 = 6
   4.325          y1 = 7
   4.326  
   4.327          def check(v):
   4.328 -            self.assertEquals(v, x1 * y1)
   4.329 +            self.assertEquals(v, self.Zp(x1 * y1))
   4.330  
   4.331 -        x2 = runtime.random_share(Zp)
   4.332 +        random = Random(3423993)
   4.333 +        share_random = Random(random.getrandbits(128))
   4.334 +        
   4.335 +        paillier = ModifiedPaillier(runtime, Random(random.getrandbits(128)))          
   4.336 +        gen = ShareGenerator(self.Zp, runtime, share_random,
   4.337 +                             paillier, self.u_bound, self.alpha)
   4.338 +        
   4.339 +        x2 = gen.generate_share(x1)
   4.340  
   4.341 -        z2 = runtime._cmul(Zp(y1), x2, Zp)
   4.342 +        z2 = runtime._cmul(self.Zp(y1), x2, self.Zp)
   4.343          d = runtime.open(z2)
   4.344          d.addCallback(check)
   4.345          return d
   4.346 @@ -260,17 +307,22 @@
   4.347      def test_constant_multiplication_constant_right(self, runtime):
   4.348          """Test multiplication of two numbers."""
   4.349  
   4.350 -        Zp = GF(6277101735386680763835789423176059013767194773182842284081)
   4.351 -
   4.352          x1 = 6
   4.353          y1 = 7
   4.354  
   4.355          def check(v):
   4.356 -            self.assertEquals(v, x1 * y1)
   4.357 +            self.assertEquals(v, self.Zp(x1 * y1))
   4.358  
   4.359 -        x2 = runtime.random_share(Zp)
   4.360 +        random = Random(3423993)
   4.361 +        share_random = Random(random.getrandbits(128))
   4.362 +        
   4.363 +        paillier = ModifiedPaillier(runtime, Random(random.getrandbits(128)))          
   4.364 +        gen = ShareGenerator(self.Zp, runtime, share_random,
   4.365 +                             paillier, self.u_bound, self.alpha)
   4.366 +        
   4.367 +        x2 = gen.generate_share(x1)
   4.368  
   4.369 -        z2 = runtime._cmul(x2, Zp(y1), Zp)
   4.370 +        z2 = runtime._cmul(x2, self.Zp(y1), self.Zp)
   4.371          d = runtime.open(z2)
   4.372          d.addCallback(check)
   4.373          return d
   4.374 @@ -279,111 +331,162 @@
   4.375      def test_get_triple(self, runtime):
   4.376          """Test generation of a triple."""
   4.377  
   4.378 -        Zp = GF(6277101735386680763835789423176059013767194773182842284081)
   4.379 -      
   4.380          def check((a, b, c)):
   4.381              self.assertEquals(c, a * b)
   4.382  
   4.383 -        (a, b, c), _ = runtime._get_triple(Zp)
   4.384 -        d1 = runtime.open(a)
   4.385 -        d2 = runtime.open(b)
   4.386 -        d3 = runtime.open(c)
   4.387 -        d = gather_shares([d1, d2, d3])
   4.388 -        d.addCallback(check)
   4.389 -        return d
   4.390 +        def open((a, b, c)):
   4.391 +            d1 = runtime.open(a)
   4.392 +            d2 = runtime.open(b)
   4.393 +            d3 = runtime.open(c)
   4.394 +            d = gather_shares([d1, d2, d3])
   4.395 +            d.addCallback(check)
   4.396 +            return d
   4.397 +
   4.398 +        random = Random(3423993)
   4.399 +        gen = TripleGenerator(runtime, self.Zp.modulus, random)
   4.400 +        [triple] = gen.generate_triples(1)
   4.401 +        triple.addCallback(open)
   4.402 +        return triple
   4.403  
   4.404      @protocol
   4.405      def test_basic_multiply(self, runtime):
   4.406          """Test multiplication of two numbers."""
   4.407  
   4.408 -        Zp = GF(6277101735386680763835789423176059013767194773182842284081)
   4.409 +        x1 = 6
   4.410 +        y1 = 6
   4.411 +
   4.412 +        def check(v):
   4.413 +            self.assertEquals(v, self.Zp(x1 * y1))
   4.414 +
   4.415 +        def do_stuff((a, b, c), alpha):
   4.416 +            random = Random(3423993)
   4.417 +            share_random = Random(random.getrandbits(128))
   4.418 +        
   4.419 +            paillier = ModifiedPaillier(runtime, Random(random.getrandbits(128)))          
   4.420 +            gen = ShareGenerator(self.Zp, runtime, share_random,
   4.421 +                                 paillier, self.u_bound, alpha)
   4.422 +        
   4.423 +            x2 = gen.generate_share(x1)
   4.424 +            y2 = gen.generate_share(y1)
   4.425 +            z2 = runtime._basic_multiplication(x2, y2, a, b, c)
   4.426 +            d = runtime.open(z2)
   4.427 +            d.addCallback(check)
   4.428 +            return d
   4.429 +
   4.430 +        gen = TripleGenerator(runtime, self.Zp.modulus, Random(3423993))
   4.431 +        alpha = gen.alpha
   4.432 +        [triple] = gen.generate_triples(1)
   4.433 +        runtime.schedule_callback(triple, do_stuff, alpha)
   4.434 +        return triple
   4.435 +
   4.436 +    # @protocol
   4.437 +    # def test_mul_mul(self, runtime):
   4.438 +    #     """Test multiplication of two numbers."""
   4.439 +
   4.440 +    #     x1 = 6
   4.441 +    #     y1 = 6
   4.442 +
   4.443 +    #     def check(v):
   4.444 +    #         self.assertEquals(v, self.Zp(x1 * y1))
   4.445 +
   4.446 +    #     gen = TripleGenerator(runtime, self.Zp.modulus, Random(3423993))
   4.447 +    #     alpha = gen.alpha
   4.448 +    #     runtime.triples = gen.generate_triples(1)
   4.449 +        
   4.450 +
   4.451 +    #     random = Random(3423993)
   4.452 +    #     share_random = Random(random.getrandbits(128))
   4.453 +    #     paillier = ModifiedPaillier(runtime, Random(random.getrandbits(128)))          
   4.454 +    #     gen = ShareGenerator(self.Zp, runtime, share_random,
   4.455 +    #                          paillier, self.u_bound, self.alpha)
   4.456 +        
   4.457 +    #     x2 = gen.generate_share(x1)
   4.458 +    #     y2 = gen.generate_share(y1)
   4.459 +        
   4.460 +    #     z2 = x2 * y2
   4.461 +    #     d = runtime.open(z2)
   4.462 +    #     d.addCallback(check)
   4.463 +    #     return d
   4.464 +    
   4.465 +    @protocol
   4.466 +    def test_basic_multiply_constant_right(self, runtime):
   4.467 +        """Test multiplication of two numbers."""
   4.468  
   4.469          x1 = 6
   4.470          y1 = 6
   4.471  
   4.472          def check(v):
   4.473 -            self.assertEquals(v, x1 * y1)
   4.474 +            self.assertEquals(v, self.Zp(x1 * y1))
   4.475  
   4.476 -        x2 = runtime.random_share(Zp)
   4.477 -        y2 = runtime.random_share(Zp)
   4.478 +        def do_stuff((a, b, c), alpha):
   4.479 +            random = Random(3423993)
   4.480 +            share_random = Random(random.getrandbits(128))
   4.481 +        
   4.482 +            paillier = ModifiedPaillier(runtime, Random(random.getrandbits(128)))          
   4.483 +            gen = ShareGenerator(self.Zp, runtime, share_random,
   4.484 +                                 paillier, self.u_bound, alpha)
   4.485 +        
   4.486 +            x2 = gen.generate_share(x1)
   4.487 +            y2 = gen.generate_share(y1)
   4.488 +            z2 = runtime._basic_multiplication(x2, self.Zp(y1), a, b, c)
   4.489 +            d = runtime.open(z2)
   4.490 +            d.addCallback(check)
   4.491 +            return d
   4.492  
   4.493 -        (a, b, c), _ = runtime._get_triple(Zp)
   4.494 -        z2 = runtime._basic_multiplication(x2, y2, a, b, c)
   4.495 -        d = runtime.open(z2)
   4.496 -        d.addCallback(check)
   4.497 -        return d
   4.498 +        gen = TripleGenerator(runtime, self.Zp.modulus, Random(3423993))
   4.499 +        alpha = gen.alpha
   4.500 +        [triple] = gen.generate_triples(1)
   4.501 +        runtime.schedule_callback(triple, do_stuff, alpha)
   4.502 +        return triple
   4.503  
   4.504      @protocol
   4.505 -    def test_mul_mul(self, runtime):
   4.506 +    def test_basic_multiply_constant_left(self, runtime):
   4.507          """Test multiplication of two numbers."""
   4.508  
   4.509 -        Zp = GF(6277101735386680763835789423176059013767194773182842284081)
   4.510 -
   4.511          x1 = 6
   4.512          y1 = 6
   4.513  
   4.514          def check(v):
   4.515 -            self.assertEquals(v, x1 * y1)
   4.516 +            self.assertEquals(v, self.Zp(x1 * y1))
   4.517  
   4.518 -        x2 = runtime.random_share(Zp)
   4.519 -        y2 = runtime.random_share(Zp)
   4.520 +        def do_stuff((a, b, c), alpha):
   4.521 +            random = Random(3423993)
   4.522 +            share_random = Random(random.getrandbits(128))
   4.523 +        
   4.524 +            paillier = ModifiedPaillier(runtime, Random(random.getrandbits(128)))          
   4.525 +            gen = ShareGenerator(self.Zp, runtime, share_random,
   4.526 +                                 paillier, self.u_bound, alpha)
   4.527 +        
   4.528 +            x2 = gen.generate_share(x1)
   4.529 +            y2 = gen.generate_share(y1)
   4.530 +            z2 = runtime._basic_multiplication(self.Zp(x1), y2, a, b, c)
   4.531 +            d = runtime.open(z2)
   4.532 +            d.addCallback(check)
   4.533 +            return d
   4.534  
   4.535 -        z2 = x2 * y2
   4.536 -        d = runtime.open(z2)
   4.537 -        d.addCallback(check)
   4.538 -        return d
   4.539 -    @protocol
   4.540 -    def test_basic_multiply_constant_right(self, runtime):
   4.541 -        """Test multiplication of two numbers."""
   4.542 -
   4.543 -        Zp = GF(6277101735386680763835789423176059013767194773182842284081)
   4.544 -
   4.545 -        x1 = 6
   4.546 -        y1 = 6
   4.547 -
   4.548 -        def check(v):
   4.549 -            self.assertEquals(v, x1 * y1)
   4.550 -
   4.551 -        x2 = runtime.random_share(Zp)
   4.552 -
   4.553 -        (a, b, c), _ = runtime._get_triple(Zp)
   4.554 -        z2 = runtime._basic_multiplication(x2, Zp(y1), a, b, c)
   4.555 -        d = runtime.open(z2)
   4.556 -        d.addCallback(check)
   4.557 -        return d
   4.558 -
   4.559 -    @protocol
   4.560 -    def test_basic_multiply_constant_left(self, runtime):
   4.561 -        """Test multiplication of two numbers."""
   4.562 -
   4.563 -        Zp = GF(6277101735386680763835789423176059013767194773182842284081)
   4.564 -
   4.565 -        x1 = 6
   4.566 -        y1 = 6
   4.567 -
   4.568 -        def check(v):
   4.569 -            self.assertEquals(v, x1 * y1)
   4.570 -
   4.571 -        x2 = runtime.random_share(Zp)
   4.572 -
   4.573 -        (a, b, c), _ = runtime._get_triple(Zp)
   4.574 -        z2 = runtime._basic_multiplication(Zp(y1), x2, a, b, c)
   4.575 -        d = runtime.open(z2)
   4.576 -        d.addCallback(check)
   4.577 -        return d
   4.578 +        gen = TripleGenerator(runtime, self.Zp.modulus, Random(3423993))
   4.579 +        alpha = gen.alpha
   4.580 +        [triple] = gen.generate_triples(1)
   4.581 +        runtime.schedule_callback(triple, do_stuff, alpha)
   4.582 +        return triple
   4.583  
   4.584      @protocol
   4.585      def test_open_multiple_secret_share(self, runtime):
   4.586          """Test sharing and open of a number."""
   4.587  
   4.588 -        Zp = GF(6277101735386680763835789423176059013767194773182842284081)
   4.589 -
   4.590          def check(ls):
   4.591              for v in ls:
   4.592                  self.assertEquals(v, 6)
   4.593  
   4.594 -        x = runtime.random_share(Zp)
   4.595 -        y = runtime.random_share(Zp)
   4.596 +        random = Random(3423993)
   4.597 +        share_random = Random(random.getrandbits(128))
   4.598 +        
   4.599 +        paillier = ModifiedPaillier(runtime, Random(random.getrandbits(128)))          
   4.600 +        gen = ShareGenerator(self.Zp, runtime, share_random,
   4.601 +                             paillier, self.u_bound, self.alpha)
   4.602 +        
   4.603 +        x = gen.generate_share(6)
   4.604 +        y = gen.generate_share(6)
   4.605          d = runtime.open_multiple_values([x, y])
   4.606          d.addCallback(check)
   4.607          return d
   4.608 @@ -392,14 +495,20 @@
   4.609      def test_open_two_secret_share(self, runtime):
   4.610          """Test sharing and open of a number."""
   4.611  
   4.612 -        Zp = GF(6277101735386680763835789423176059013767194773182842284081)
   4.613 -
   4.614          def check((a, b)):
   4.615              self.assertEquals(a, 6)
   4.616              self.assertEquals(b, 6)
   4.617  
   4.618 -        x = runtime.random_share(Zp)
   4.619 -        y = runtime.random_share(Zp)
   4.620 +        random = Random(3423993)
   4.621 +        share_random = Random(random.getrandbits(128))
   4.622 +        
   4.623 +        paillier = ModifiedPaillier(runtime, Random(random.getrandbits(128)))          
   4.624 +        gen = ShareGenerator(self.Zp, runtime, share_random,
   4.625 +                             paillier, self.u_bound, self.alpha)
   4.626 +        
   4.627 +        x = gen.generate_share(6)
   4.628 +        y = gen.generate_share(6)
   4.629          d = runtime.open_two_values(x, y)
   4.630          d.addCallback(check)
   4.631          return d
   4.632 +