viff

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 diff
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/viff/bedoza/add_macs.py	Fri Jul 23 13:17:52 2010 +0200
     1.3 @@ -0,0 +1,85 @@
     1.4 +# Copyright 2010 VIFF Development Team.
     1.5 +#
     1.6 +# This file is part of VIFF, the Virtual Ideal Functionality Framework.
     1.7 +#
     1.8 +# VIFF is free software: you can redistribute it and/or modify it
     1.9 +# under the terms of the GNU Lesser General Public License (LGPL) as
    1.10 +# published by the Free Software Foundation, either version 3 of the
    1.11 +# License, or (at your option) any later version.
    1.12 +#
    1.13 +# VIFF is distributed in the hope that it will be useful, but WITHOUT
    1.14 +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
    1.15 +# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General
    1.16 +# Public License for more details.
    1.17 +#
    1.18 +# You should have received a copy of the GNU Lesser General Public
    1.19 +# License along with VIFF. If not, see <http://www.gnu.org/licenses/>.
    1.20 +
    1.21 +from twisted.internet.defer import gatherResults
    1.22 +from viff.runtime import Share
    1.23 +
    1.24 +from viff.bedoza.util import _send
    1.25 +from viff.bedoza.keylist import BeDOZaKeyList
    1.26 +from viff.bedoza.maclist import BeDOZaMACList
    1.27 +
    1.28 +from viff.bedoza.shares import BeDOZaShare, BeDOZaShareContents
    1.29 +
    1.30 +def add_macs(runtime, field, u_bound, alpha, random, paillier, partial_shares):
    1.31 +    """Adds macs to the set of PartialBeDOZaShares.
    1.32 +        
    1.33 +    Returns a deferred which yields a list of full shares, e.g.
    1.34 +    including macs.  (the full shares are deferreds of type
    1.35 +    BeDOZaShare.)
    1.36 +    """        
    1.37 +    # TODO: Would be nice with a class ShareContents like the class
    1.38 +    # PartialShareContents used here.
    1.39 +        
    1.40 +    runtime.increment_pc() # Huh!?
    1.41 +
    1.42 +    def do_add_macs(partial_share_contents, result_shares):
    1.43 +        num_players = runtime.num_players
    1.44 +        lists_of_mac_keys = [ [] for x in runtime.players ]
    1.45 +        lists_of_c_list = [ [] for x in runtime.players ]
    1.46 +        for partial_share_content in partial_share_contents:
    1.47 +            for j in xrange(0, num_players):
    1.48 +                # TODO: This is probably not the fastes way to generate
    1.49 +                # the betas.
    1.50 +                beta = random.randint(0, u_bound)
    1.51 +                # TODO: Outcommented until mod paillier works for negative numbers.
    1.52 +                # if rand.choice([True, False]):
    1.53 +                #    beta = -beta
    1.54 +                enc_beta = paillier.encrypt(beta, player_id=j + 1)
    1.55 +                c_j = partial_share_content.enc_shares[j]
    1.56 +                n2 = paillier.get_modulus_square(j + 1)
    1.57 +                c = (pow(c_j, alpha, n2) * enc_beta) % n2
    1.58 +                lists_of_c_list[j].append(c)
    1.59 +                lists_of_mac_keys[j].append(field(beta))
    1.60 +
    1.61 +        received_cs = _send(runtime, lists_of_c_list, deserialize=eval)
    1.62 +
    1.63 +        def finish_sharing(recevied_cs, partial_share_contents, lists_of_mac_keys, result_shares):
    1.64 +            shares = []               
    1.65 +            for inx in xrange(0, len(partial_share_contents)):
    1.66 +                mac_keys = []
    1.67 +                decrypted_cs = []
    1.68 +                for c_list, mkeys in zip(recevied_cs,
    1.69 +                                         lists_of_mac_keys):
    1.70 +                    decrypted_cs.append(field(paillier.decrypt(c_list[inx])))
    1.71 +                    mac_keys.append(mkeys[inx])
    1.72 +                partial_share = partial_share_contents[inx]
    1.73 +                mac_key_list = BeDOZaKeyList(alpha, mac_keys)
    1.74 +
    1.75 +                mac_msg_list = BeDOZaMACList(decrypted_cs)
    1.76 +                result_shares[inx].callback(BeDOZaShareContents(partial_share.value,
    1.77 +                                                                mac_key_list,
    1.78 +                                                                mac_msg_list))
    1.79 +            return shares
    1.80 +
    1.81 +        runtime.schedule_callback(received_cs, finish_sharing, partial_share_contents, lists_of_mac_keys, result_shares)
    1.82 +        return received_cs
    1.83 +
    1.84 +    result_shares = [Share(runtime, field) for x in xrange(len(partial_shares))]
    1.85 +    runtime.schedule_callback(gatherResults(partial_shares),
    1.86 +                              do_add_macs,
    1.87 +                              result_shares)
    1.88 +    return result_shares
     2.1 --- a/viff/bedoza/bedoza_triple.py	Fri Jul 23 13:17:51 2010 +0200
     2.2 +++ b/viff/bedoza/bedoza_triple.py	Fri Jul 23 13:17:52 2010 +0200
     2.3 @@ -30,9 +30,14 @@
     2.4  
     2.5  from viff.bedoza.shares import BeDOZaShare, BeDOZaShareContents, PartialShare, PartialShareContents
     2.6  
     2.7 +from viff.bedoza.share_generators import PartialShareGenerator, ShareGenerator
     2.8 +
     2.9  from viff.bedoza.keylist import BeDOZaKeyList
    2.10  from viff.bedoza.maclist import BeDOZaMACList
    2.11  
    2.12 +from viff.bedoza.util import _send, _convolute
    2.13 +from viff.bedoza.add_macs import add_macs
    2.14 +
    2.15  # TODO: Use secure random instead!
    2.16  from random import Random
    2.17  
    2.18 @@ -46,6 +51,7 @@
    2.19      print "Error: The pypaillier module or one of the used functions " \
    2.20          "are not available."
    2.21  
    2.22 +
    2.23  class Triple(object):
    2.24      def __init__(self, a, b, c):
    2.25          self.a, self.b, self.c = a, b, c
    2.26 @@ -53,107 +59,6 @@
    2.27          return "(%s,%s,%s)" % (self.a, self.b, self.c)
    2.28  
    2.29  
    2.30 -def _send(runtime, vals, serialize=str, deserialize=int):
    2.31 -    """Send vals[i] to player i + 1. Returns deferred list.
    2.32 -
    2.33 -    Works as default for integers. If other stuff has to be
    2.34 -    sent, supply another serialization, deserialition.
    2.35 -    """
    2.36 -    runtime.increment_pc()
    2.37 -    
    2.38 -    pc = tuple(runtime.program_counter)
    2.39 -    for p in runtime.players:
    2.40 -        msg = serialize(vals[p - 1])
    2.41 -        runtime.protocols[p].sendData(pc, TEXT, msg)
    2.42 -    def err_handler(err):
    2.43 -        print err
    2.44 -    values = []
    2.45 -    for p in runtime.players:
    2.46 -        d = Deferred()
    2.47 -        d.addCallbacks(deserialize, err_handler)
    2.48 -        runtime._expect_data(p, TEXT, d)
    2.49 -        values.append(d)
    2.50 -    result = gatherResults(values)
    2.51 -    return result
    2.52 -
    2.53 -def _convolute(runtime, val, serialize=str, deserialize=int):
    2.54 -    """As send, but sends the same val to all players."""
    2.55 -    return _send(runtime, [val] * runtime.num_players,
    2.56 -                 serialize=serialize, deserialize=deserialize)
    2.57 -
    2.58 -def _convolute_gf_elm(runtime, gf_elm):
    2.59 -    return _convolute(runtime, gf_elm,
    2.60 -                      serialize=lambda x: str(x.value),
    2.61 -                      deserialize=lambda x: gf_elm.field(int(x)))
    2.62 -
    2.63 -def _send_gf_elm(runtime, vals):
    2.64 -    return _send(runtime, vals, 
    2.65 -                 serialize=lambda x: str(x.value),
    2.66 -                 deserialize=lambda x: gf_elm.field(int(x)))
    2.67 -
    2.68 -
    2.69 -class PartialShareGenerator:
    2.70 -
    2.71 -    def __init__(self, Zp, runtime, random, paillier):
    2.72 -        self.paillier = paillier
    2.73 -        self.Zp = Zp
    2.74 -        self.runtime = runtime
    2.75 -        self.random = random
    2.76 -
    2.77 -    def generate_share(self, value):
    2.78 -        self.runtime.increment_pc()
    2.79 -        
    2.80 -        r = [self.Zp(self.random.randint(0, self.Zp.modulus - 1)) # TODO: Exclusve?
    2.81 -             for _ in range(self.runtime.num_players - 1)]
    2.82 -        if self.runtime.id == 1:
    2.83 -            share = value - sum(r)
    2.84 -        else:
    2.85 -            share = r[self.runtime.id - 2]
    2.86 -        enc_share = self.paillier.encrypt(share.value)
    2.87 -        enc_shares = _convolute(self.runtime, enc_share)
    2.88 -        def create_partial_share(enc_shares, share):
    2.89 -            return PartialShare(self.runtime, self.Zp, share, enc_shares)
    2.90 -        self.runtime.schedule_callback(enc_shares, create_partial_share, share)
    2.91 -        return enc_shares
    2.92 -
    2.93 -    def generate_random_shares(self, n):
    2.94 -        self.runtime.increment_pc()
    2.95 -        N_squared_list = [ self.runtime.players[player_id].pubkey['n_square'] for player_id in self.runtime.players]
    2.96 -        shares = [PartialShare(self.runtime, self.Zp) for _ in xrange(n)]
    2.97 -        for inx in xrange(n):
    2.98 -            r = self.random.randint(0, self.Zp.modulus - 1)
    2.99 -            ri = self.Zp(r)
   2.100 -            enc_share = self.paillier.encrypt(ri.value)
   2.101 -            enc_shares = _convolute(self.runtime, enc_share)
   2.102 -            def create_partial_share(enc_shares, ri, s, N_squared_list):
   2.103 -                s.callback(PartialShareContents(ri, enc_shares, N_squared_list))
   2.104 -            self.runtime.schedule_callback(enc_shares,
   2.105 -                                           create_partial_share,
   2.106 -                                           ri,
   2.107 -                                           shares[inx],
   2.108 -                                           N_squared_list)
   2.109 -        return shares
   2.110 -
   2.111 -class ShareGenerator(PartialShareGenerator):
   2.112 -
   2.113 -    def __init__(self, Zp, runtime, random, paillier, u_bound, alpha):
   2.114 -        self.u_bound = u_bound
   2.115 -        self.alpha = alpha
   2.116 -        PartialShareGenerator.__init__(self, Zp, runtime, random, paillier)
   2.117 -
   2.118 -    def generate_share(self, value):
   2.119 -        self.runtime.increment_pc()
   2.120 -        partial_share = PartialShareGenerator.generate_share(self, value)
   2.121 -        full_share = add_macs(self.runtime, self.Zp, self.u_bound, self.alpha,
   2.122 -                             self.random, self.paillier, [partial_share])
   2.123 -        return full_share[0]
   2.124 -    
   2.125 -    def generate_random_shares(self, n):
   2.126 -        self.runtime.increment_pc()
   2.127 -        partial_shares = PartialShareGenerator.generate_random_shares(self, n)
   2.128 -        return add_macs(self.runtime, self.Zp, self.u_bound, self.alpha,
   2.129 -                        self.random, self.paillier, partial_shares)
   2.130 -
   2.131  class ModifiedPaillier(object):
   2.132      """A slight modification of the Paillier cryptosystem.
   2.133  
   2.134 @@ -216,66 +121,6 @@
   2.135      def get_modulus_square(self, player_id):
   2.136          return self.runtime.players[player_id].pubkey['n_square']
   2.137  
   2.138 -def add_macs(runtime, field, u_bound, alpha, random, paillier, partial_shares):
   2.139 -    """Adds macs to the set of PartialBeDOZaShares.
   2.140 -        
   2.141 -    Returns a deferred which yields a list of full shares, e.g.
   2.142 -    including macs.  (the full shares are deferreds of type
   2.143 -    BeDOZaShare.)
   2.144 -    """        
   2.145 -    # TODO: Would be nice with a class ShareContents like the class
   2.146 -    # PartialShareContents used here.
   2.147 -        
   2.148 -    runtime.increment_pc() # Huh!?
   2.149 -
   2.150 -    def do_add_macs(partial_share_contents, result_shares):
   2.151 -        num_players = runtime.num_players
   2.152 -        lists_of_mac_keys = [ [] for x in runtime.players ]
   2.153 -        lists_of_c_list = [ [] for x in runtime.players ]
   2.154 -        for partial_share_content in partial_share_contents:
   2.155 -            for j in xrange(0, num_players):
   2.156 -                # TODO: This is probably not the fastes way to generate
   2.157 -                # the betas.
   2.158 -                beta = random.randint(0, u_bound)
   2.159 -                # TODO: Outcommented until mod paillier works for negative numbers.
   2.160 -                # if rand.choice([True, False]):
   2.161 -                #    beta = -beta
   2.162 -                enc_beta = paillier.encrypt(beta, player_id=j + 1)
   2.163 -                c_j = partial_share_content.enc_shares[j]
   2.164 -                n2 = paillier.get_modulus_square(j + 1)
   2.165 -                c = (pow(c_j, alpha, n2) * enc_beta) % n2
   2.166 -                lists_of_c_list[j].append(c)
   2.167 -                lists_of_mac_keys[j].append(field(beta))
   2.168 -
   2.169 -        received_cs = _send(runtime, lists_of_c_list, deserialize=eval)
   2.170 -
   2.171 -        def finish_sharing(recevied_cs, partial_share_contents, lists_of_mac_keys, result_shares):
   2.172 -            shares = []               
   2.173 -            for inx in xrange(0, len(partial_share_contents)):
   2.174 -                mac_keys = []
   2.175 -                decrypted_cs = []
   2.176 -                for c_list, mkeys in zip(recevied_cs,
   2.177 -                                         lists_of_mac_keys):
   2.178 -                    decrypted_cs.append(field(paillier.decrypt(c_list[inx])))
   2.179 -                    mac_keys.append(mkeys[inx])
   2.180 -                partial_share = partial_share_contents[inx]
   2.181 -                mac_key_list = BeDOZaKeyList(alpha, mac_keys)
   2.182 -
   2.183 -                mac_msg_list = BeDOZaMACList(decrypted_cs)
   2.184 -                result_shares[inx].callback(BeDOZaShareContents(partial_share.value,
   2.185 -                                                                mac_key_list,
   2.186 -                                                                mac_msg_list))
   2.187 -            return shares
   2.188 -
   2.189 -        runtime.schedule_callback(received_cs, finish_sharing, partial_share_contents, lists_of_mac_keys, result_shares)
   2.190 -        return received_cs
   2.191 -
   2.192 -    result_shares = [Share(runtime, field) for x in xrange(len(partial_shares))]
   2.193 -    runtime.schedule_callback(gatherResults(partial_shares),
   2.194 -                              do_add_macs,
   2.195 -                              result_shares)
   2.196 -    return result_shares
   2.197 -
   2.198  
   2.199  class TripleGenerator(object):
   2.200  
     3.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     3.2 +++ b/viff/bedoza/share_generators.py	Fri Jul 23 13:17:52 2010 +0200
     3.3 @@ -0,0 +1,82 @@
     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 +from viff.bedoza.shares import BeDOZaShare, BeDOZaShareContents, PartialShare, PartialShareContents
    3.22 +from viff.bedoza.util import _convolute
    3.23 +from viff.bedoza.add_macs import add_macs
    3.24 +
    3.25 +class PartialShareGenerator:
    3.26 +
    3.27 +    def __init__(self, Zp, runtime, random, paillier):
    3.28 +        self.paillier = paillier
    3.29 +        self.Zp = Zp
    3.30 +        self.runtime = runtime
    3.31 +        self.random = random
    3.32 +
    3.33 +    def generate_share(self, value):
    3.34 +        self.runtime.increment_pc()
    3.35 +        
    3.36 +        r = [self.Zp(self.random.randint(0, self.Zp.modulus - 1)) # TODO: Exclusve?
    3.37 +             for _ in range(self.runtime.num_players - 1)]
    3.38 +        if self.runtime.id == 1:
    3.39 +            share = value - sum(r)
    3.40 +        else:
    3.41 +            share = r[self.runtime.id - 2]
    3.42 +        enc_share = self.paillier.encrypt(share.value)
    3.43 +        enc_shares = _convolute(self.runtime, enc_share)
    3.44 +        def create_partial_share(enc_shares, share):
    3.45 +            return PartialShare(self.runtime, self.Zp, share, enc_shares)
    3.46 +        self.runtime.schedule_callback(enc_shares, create_partial_share, share)
    3.47 +        return enc_shares
    3.48 +
    3.49 +    def generate_random_shares(self, n):
    3.50 +        self.runtime.increment_pc()
    3.51 +        N_squared_list = [ self.runtime.players[player_id].pubkey['n_square'] for player_id in self.runtime.players]
    3.52 +        shares = [PartialShare(self.runtime, self.Zp) for _ in xrange(n)]
    3.53 +        for inx in xrange(n):
    3.54 +            r = self.random.randint(0, self.Zp.modulus - 1)
    3.55 +            ri = self.Zp(r)
    3.56 +            enc_share = self.paillier.encrypt(ri.value)
    3.57 +            enc_shares = _convolute(self.runtime, enc_share)
    3.58 +            def create_partial_share(enc_shares, ri, s, N_squared_list):
    3.59 +                s.callback(PartialShareContents(ri, enc_shares, N_squared_list))
    3.60 +            self.runtime.schedule_callback(enc_shares,
    3.61 +                                           create_partial_share,
    3.62 +                                           ri,
    3.63 +                                           shares[inx],
    3.64 +                                           N_squared_list)
    3.65 +        return shares
    3.66 +
    3.67 +class ShareGenerator(PartialShareGenerator):
    3.68 +
    3.69 +    def __init__(self, Zp, runtime, random, paillier, u_bound, alpha):
    3.70 +        self.u_bound = u_bound
    3.71 +        self.alpha = alpha
    3.72 +        PartialShareGenerator.__init__(self, Zp, runtime, random, paillier)
    3.73 +
    3.74 +    def generate_share(self, value):
    3.75 +        self.runtime.increment_pc()
    3.76 +        partial_share = PartialShareGenerator.generate_share(self, value)
    3.77 +        full_share = add_macs(self.runtime, self.Zp, self.u_bound, self.alpha,
    3.78 +                             self.random, self.paillier, [partial_share])
    3.79 +        return full_share[0]
    3.80 +    
    3.81 +    def generate_random_shares(self, n):
    3.82 +        self.runtime.increment_pc()
    3.83 +        partial_shares = PartialShareGenerator.generate_random_shares(self, n)
    3.84 +        return add_macs(self.runtime, self.Zp, self.u_bound, self.alpha,
    3.85 +                        self.random, self.paillier, partial_shares)
     4.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     4.2 +++ b/viff/bedoza/util.py	Fri Jul 23 13:17:52 2010 +0200
     4.3 @@ -0,0 +1,58 @@
     4.4 +# Copyright 2010 VIFF Development Team.
     4.5 +#
     4.6 +# This file is part of VIFF, the Virtual Ideal Functionality Framework.
     4.7 +#
     4.8 +# VIFF is free software: you can redistribute it and/or modify it
     4.9 +# under the terms of the GNU Lesser General Public License (LGPL) as
    4.10 +# published by the Free Software Foundation, either version 3 of the
    4.11 +# License, or (at your option) any later version.
    4.12 +#
    4.13 +# VIFF is distributed in the hope that it will be useful, but WITHOUT
    4.14 +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
    4.15 +# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General
    4.16 +# Public License for more details.
    4.17 +#
    4.18 +# You should have received a copy of the GNU Lesser General Public
    4.19 +# License along with VIFF. If not, see <http://www.gnu.org/licenses/>.
    4.20 +
    4.21 +from twisted.internet.defer import Deferred, gatherResults
    4.22 +
    4.23 +from viff.constants import TEXT
    4.24 +
    4.25 +def _send(runtime, vals, serialize=str, deserialize=int):
    4.26 +    """Send vals[i] to player i + 1. Returns deferred list.
    4.27 +
    4.28 +    Works as default for integers. If other stuff has to be
    4.29 +    sent, supply another serialization, deserialition.
    4.30 +    """
    4.31 +    runtime.increment_pc()
    4.32 +    
    4.33 +    pc = tuple(runtime.program_counter)
    4.34 +    for p in runtime.players:
    4.35 +        msg = serialize(vals[p - 1])
    4.36 +        runtime.protocols[p].sendData(pc, TEXT, msg)
    4.37 +    def err_handler(err):
    4.38 +        print err
    4.39 +    values = []
    4.40 +    for p in runtime.players:
    4.41 +        d = Deferred()
    4.42 +        d.addCallbacks(deserialize, err_handler)
    4.43 +        runtime._expect_data(p, TEXT, d)
    4.44 +        values.append(d)
    4.45 +    result = gatherResults(values)
    4.46 +    return result
    4.47 +
    4.48 +def _convolute(runtime, val, serialize=str, deserialize=int):
    4.49 +    """As send, but sends the same val to all players."""
    4.50 +    return _send(runtime, [val] * runtime.num_players,
    4.51 +                 serialize=serialize, deserialize=deserialize)
    4.52 +
    4.53 +def _convolute_gf_elm(runtime, gf_elm):
    4.54 +    return _convolute(runtime, gf_elm,
    4.55 +                      serialize=lambda x: str(x.value),
    4.56 +                      deserialize=lambda x: gf_elm.field(int(x)))
    4.57 +
    4.58 +def _send_gf_elm(runtime, vals):
    4.59 +    return _send(runtime, vals, 
    4.60 +                 serialize=lambda x: str(x.value),
    4.61 +                 deserialize=lambda x: gf_elm.field(int(x)))
     5.1 --- a/viff/test/test_bedoza_triple.py	Fri Jul 23 13:17:51 2010 +0200
     5.2 +++ b/viff/test/test_bedoza_triple.py	Fri Jul 23 13:17:52 2010 +0200
     5.3 @@ -32,9 +32,11 @@
     5.4  
     5.5  from viff.bedoza.bedoza import BeDOZaRuntime, BeDOZaShare
     5.6  from viff.bedoza.keylist import BeDOZaKeyList
     5.7 -from viff.bedoza.bedoza_triple import TripleGenerator, ModifiedPaillier, PartialShareGenerator, ShareGenerator
     5.8 +from viff.bedoza.bedoza_triple import TripleGenerator, ModifiedPaillier
     5.9 +from viff.bedoza.share_generators import PartialShareGenerator, ShareGenerator
    5.10  from viff.bedoza.shares import PartialShare, PartialShareContents
    5.11 -from viff.bedoza.bedoza_triple import _send, _convolute, _convolute_gf_elm, add_macs
    5.12 +from viff.bedoza.util import _send, _convolute, _convolute_gf_elm
    5.13 +from viff.bedoza.add_macs import add_macs
    5.14  
    5.15  from viff.field import FieldElement, GF
    5.16  from viff.config import generate_configs