viff

changeset 1508:891df84eb779

BeDOZa: addMacs is now able to process multiple shares in a batch.
author Janus Dam Nielsen <janus.nielsen@alexandra.dk>
date Tue, 20 Jul 2010 14:01:16 +0200
parents 3787ff4776bc
children a6be6cce7046
files viff/bedoza_triple.py viff/test/test_bedoza_triple.py
diffstat 2 files changed, 68 insertions(+), 52 deletions(-) [+]
line diff
     1.1 --- a/viff/bedoza_triple.py	Tue Jul 20 09:49:59 2010 +0200
     1.2 +++ b/viff/bedoza_triple.py	Tue Jul 20 14:01:16 2010 +0200
     1.3 @@ -244,52 +244,62 @@
     1.4      def _add_macs(self, partial_shares):
     1.5          """Adds macs to the set of PartialBeDOZaShares.
     1.6          
     1.7 -        Returns a tuple with a single element that is a list of full
     1.8 -        shares, e.g. including macs.  (the full shares are deferreds
     1.9 -        of type BeDOZaShare.)
    1.10 -
    1.11 -        TODO: We have to return the list in a tuple due to some
    1.12 -        Twisted thing.
    1.13 +        Returns a deferred which yields a list of full shares, e.g.
    1.14 +        including macs.  (the full shares are deferreds of type
    1.15 +        BeDOZaShare.)
    1.16          """        
    1.17          # TODO: Would be nice with a class ShareContents like the class
    1.18          # PartialShareContents used here.
    1.19          
    1.20          self.runtime.increment_pc() # Huh!?
    1.21  
    1.22 -        mac_keys = []
    1.23 +        def do_add_macs(partial_share_contents):
    1.24 +            num_players = self.runtime.num_players
    1.25 +            lists_of_mac_keys = [ [] for x in self.runtime.players ]
    1.26 +            lists_of_c_list = [ [] for x in self.runtime.players ]
    1.27 +            for partial_share_content in partial_share_contents:
    1.28 +                for j in xrange(0, num_players):
    1.29 +                    # TODO: This is probably not the fastes way to generate
    1.30 +                    # the betas.
    1.31 +                    beta = self.random.randint(0, self.u_bound)
    1.32 +                    # TODO: Outcommented until mod paillier works for negative numbers.
    1.33 +                    # if rand.choice([True, False]):
    1.34 +                    #    beta = -beta
    1.35 +                    enc_beta = self.paillier.encrypt(beta, player_id=j + 1)
    1.36 +                    c_j = partial_share_content.enc_shares[j]
    1.37 +                    n2 = self.paillier.get_modulus_square(j + 1)
    1.38 +                    c = (pow(c_j, self.alpha, n2) * enc_beta) % n2
    1.39 +                    lists_of_c_list[j].append(c)
    1.40 +                    lists_of_mac_keys[j].append(self.Zp(beta))
    1.41  
    1.42 -        # TODO: Currently only support for one share.
    1.43 -        i = 0
    1.44 +            received_cs = _send(self.runtime, lists_of_c_list, deserialize=eval)
    1.45  
    1.46 -        c_list = []
    1.47 -        for j in range(self.runtime.num_players):
    1.48 -            # TODO: This is probably not the fastes way to generate
    1.49 -            # the betas.
    1.50 -            beta = self.random.randint(0, self.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 = self.paillier.encrypt(beta, player_id=j+1)
    1.55 -            c_j = partial_shares[i].enc_shares[j]
    1.56 -            n2 = self.runtime.players[j + 1].pubkey['n_square']
    1.57 -            c = (pow(c_j, self.alpha, n2) * enc_beta) % n2
    1.58 -            c_list.append(c)
    1.59 -            mac_keys.append(self.Zp(beta))
    1.60 -        received_cs = _send(self.runtime, c_list)
    1.61 +            def finish_sharing(recevied_cs, partial_share_contents, lists_of_mac_keys):
    1.62 +                shares = []               
    1.63 +                for inx in xrange(0, len(partial_share_contents)):
    1.64 +                    mac_keys = []
    1.65 +                    decrypted_cs = []
    1.66 +                    for c_list, mkeys in zip(recevied_cs,
    1.67 +                                             lists_of_mac_keys):
    1.68 +                        decrypted_cs.append(self.Zp(self.paillier.decrypt(c_list[inx])))
    1.69 +                        mac_keys.append(mkeys[inx])
    1.70 +                    partial_share = partial_share_contents[inx]
    1.71 +                    mac_key_list = BeDOZaKeyList(self.alpha, mac_keys)
    1.72  
    1.73 -        def finish_sharing(recevied_cs):
    1.74 -            mac_key_list = BeDOZaKeyList(self.alpha, mac_keys)
    1.75 -            decrypted_cs = [self.Zp(self.paillier.decrypt(c)) for c in received_cs.result]
    1.76 -            mac_msg_list = BeDOZaMACList(decrypted_cs)
    1.77 -            # Twisted HACK: Need to pack share into tuple.
    1.78 -            return BeDOZaShare(self.runtime,
    1.79 -                               partial_shares[i].value.field,
    1.80 -                               partial_shares[i].value,
    1.81 -                               mac_key_list,
    1.82 -                               mac_msg_list),
    1.83 +                    mac_msg_list = BeDOZaMACList(decrypted_cs)
    1.84 +                    shares.append(BeDOZaShare(self.runtime,
    1.85 +                                              partial_share.value.field,
    1.86 +                                              partial_share.value,
    1.87 +                                              mac_key_list,
    1.88 +                                              mac_msg_list))
    1.89 +                return shares
    1.90  
    1.91 -        self.runtime.schedule_callback(received_cs, finish_sharing)
    1.92 -        return [received_cs]
    1.93 +            self.runtime.schedule_callback(received_cs, finish_sharing, partial_share_contents, lists_of_mac_keys)
    1.94 +            return received_cs
    1.95 +
    1.96 +        d = gatherResults(partial_shares)
    1.97 +        self.runtime.schedule_callback(d, do_add_macs)
    1.98 +        return d
    1.99  
   1.100          # for player i:
   1.101          #     receive c from player i and set 
     2.1 --- a/viff/test/test_bedoza_triple.py	Tue Jul 20 09:49:59 2010 +0200
     2.2 +++ b/viff/test/test_bedoza_triple.py	Tue Jul 20 14:01:16 2010 +0200
     2.3 @@ -279,25 +279,31 @@
     2.4          # order to be more unit testish, this test should use its own
     2.5          # way of verifying these.
     2.6          p = 17
     2.7 -        secret = 9
     2.8 +        secret = 6
     2.9          random = Random(283883)        
    2.10          triple_generator = TripleGenerator(runtime, p, random)
    2.11          paillier = triple_generator.paillier
    2.12 -        share = partial_share(random, runtime, GF(p), secret, paillier=paillier)
    2.13 -        def add_macs(share):
    2.14 -            full_share_list = triple_generator._add_macs([share])
    2.15 -            d = gatherResults(full_share_list)
    2.16 -            def foo(ls):
    2.17 -                # Twisted HACK: Need to unpack value ls[0] from tuple.
    2.18 -                opened_share = runtime.open(ls[0][0])
    2.19 -                def verify(open_share):
    2.20 -                    self.assertEquals(secret, open_share.value)
    2.21 -                runtime.schedule_callback(opened_share, verify)
    2.22 -                return opened_share
    2.23 -            d.addCallback(foo)
    2.24 -            return d
    2.25 -        runtime.schedule_callback(share, add_macs)
    2.26 -        return share
    2.27 +        shares = []
    2.28 +        shares.append(partial_share(random, runtime, GF(p), secret, paillier=paillier))
    2.29 +        shares.append(partial_share(random, runtime, GF(p), secret + 1, paillier=paillier))
    2.30 +        shares.append(partial_share(random, runtime, GF(p), secret + 2, paillier=paillier))
    2.31 +        shares.append(partial_share(random, runtime, GF(p), secret + 3, paillier=paillier))
    2.32 +
    2.33 +        zs = triple_generator._add_macs(shares)
    2.34 +        def foo(ls):
    2.35 +            def verify(open_shares):
    2.36 +                inx = secret
    2.37 +                for open_share in open_shares:
    2.38 +                    self.assertEquals(inx, open_share.value)
    2.39 +                    inx += 1
    2.40 +            opened_shares = []
    2.41 +            for s in ls:
    2.42 +                opened_shares.append(runtime.open(s))
    2.43 +            shares = gather_shares(opened_shares)
    2.44 +            runtime.schedule_callback(shares, verify)
    2.45 +            return shares
    2.46 +        zs.addCallback(foo)
    2.47 +        return zs
    2.48  
    2.49          
    2.50  #    @protocol