viff

view viff/bedoza/share.py @ 1574:0d3b99e1e3eb

BeDOZa: Connected zero-knowledge proof to the remaining protocol.
author Thomas P Jakobsen <tpj@cs.au.dk>
date Mon Oct 04 21:51:33 2010 +0200 (19 months ago)
parents 54f02cd75714
children
line source
1 # Copyright 2010 VIFF Development Team.
2 #
3 # This file is part of VIFF, the Virtual Ideal Functionality Framework.
4 #
5 # VIFF is free software: you can redistribute it and/or modify it
6 # under the terms of the GNU Lesser General Public License (LGPL) as
7 # published by the Free Software Foundation, either version 3 of the
8 # License, or (at your option) any later version.
9 #
10 # VIFF is distributed in the hope that it will be useful, but WITHOUT
11 # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
12 # or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General
13 # Public License for more details.
14 #
15 # You should have received a copy of the GNU Lesser General Public
16 # License along with VIFF. If not, see <http://www.gnu.org/licenses/>.
18 from gmpy import mpz
20 from twisted.internet.defer import gatherResults
22 from viff.bedoza.zero_knowledge import ZKProof
23 from viff.bedoza.shares import PartialShareContents
25 def generate_partial_share_contents(field_elements, runtime, paillier, k, random):
26 """Protocol for generating partial shares.
28 This protocol corresponds to the "Share" protocol in the document
29 "A new On- and Off-line Phase for MPC".
31 Each party inputs a list of field elements *field_elements*. The
32 values of the field elements are encrypted, the encrypted values
33 are exchanged, and for each player, a zero-knowledge proof is
34 carried out, proving that each player knows the plaintexts
35 corresponding to the ciphertexts, he broadcasts, and that the
36 plaintexts are of limited size.
38 Returns a deferred, which yields a list of PartialShareContents.
40 """
41 # TODO: We should assert that len(field_elements) == s.
43 # TODO: The gatherResults is used several times in this method in
44 # a way that prevents maximal asynchronicity. E.g. all players
45 # wait until all zero-knowledge proofs are completed before they
46 # start constructing partial shares. However, the callback for a
47 # particular partial share could be triggered as soon as the
48 # players have completed the zk proof for that share.
50 runtime.increment_pc()
52 N_squared_list = [paillier.get_modulus_square(player_id)
53 for player_id in runtime.players]
55 list_of_enc_shares = []
56 list_of_random_elements = []
57 for field_element in field_elements:
58 r, e = paillier.encrypt_r(field_element.value)
59 list_of_enc_shares.append(e)
60 list_of_random_elements.append(r)
62 list_of_enc_shares = runtime.broadcast(
63 runtime.players.keys(), runtime.players.keys(),
64 str(list_of_enc_shares))
66 def construct_partial_shares(zk_results, list_of_enc_shares, field_elements):
67 if False in zk_results:
68 raise Exception("Zero-knowledge proof failed")
69 reordered_encrypted_shares = [[] for _ in list_of_enc_shares[0]]
70 for enc_shares in list_of_enc_shares:
71 for inx, enc_share in enumerate(enc_shares):
72 reordered_encrypted_shares[inx].append(enc_share)
73 partial_share_contents = []
74 for enc_shares, field_element \
75 in zip(reordered_encrypted_shares, field_elements):
76 partial_share_contents.append(PartialShareContents(
77 field_element, enc_shares, N_squared_list))
78 return partial_share_contents
80 def do_zk_proofs(list_of_enc_shares, field_elements):
81 zk_results = []
82 list_of_enc_shares = [eval(x) for x in list_of_enc_shares]
84 # We expect all players to broadcast the same number of
85 # encrypted shares.
86 assert all([len(enc_shares) == len(list_of_enc_shares[0])
87 for enc_shares in list_of_enc_shares])
89 for i in range(runtime.num_players):
90 x, r = None, None
91 if runtime.id == i + 1:
92 x, r = [mpz(e.value)
93 for e in field_elements], list_of_random_elements
94 zk_proof = ZKProof(
95 len(field_elements), i + 1, k, runtime, list_of_enc_shares[i],
96 random=random, x=x, r=r, paillier=paillier)
97 zk_result = zk_proof.start()
98 zk_results.append(zk_result)
99 d = gatherResults(zk_results)
100 runtime.schedule_callback(
101 d, construct_partial_shares, list_of_enc_shares, field_elements)
102 return d
104 d = gatherResults(list_of_enc_shares)
105 runtime.schedule_callback(d, do_zk_proofs, field_elements)
106 return d