# HG changeset patch # User Janus Dam Nielsen <[email protected]> # Date 1254816324 -7200 # Node ID 7ed324dff36bceac194528fd00f43dd572254bc8 # Parent 42d95e56edf626b2a2c8535e5bfbe856a1e82a3b Implementation of the open command.
diff --git a/viff/orlandi.py b/viff/orlandi.py --- a/viff/orlandi.py +++ b/viff/orlandi.py @@ -15,12 +15,14 @@ # You should have received a copy of the GNU Lesser General Public # License along with VIFF. If not, see <http://www.gnu.org/licenses/>. -from twisted.internet.defer import Deferred +from twisted.internet.defer import Deferred, gatherResults from viff.runtime import Runtime, Share, ShareList, gather_shares from viff.util import rand from viff.constants import TEXT +from hash_broadcast import HashBroadcastMixin + import commitment commitment.set_reference_string(23434347834783478783478L, 489237823478234783478020L) @@ -54,7 +56,7 @@ Share.__init__(self, runtime, field, (value, rho, commitment)) -class OrlandiRuntime(Runtime): +class OrlandiRuntime(Runtime, HashBroadcastMixin): """The Orlandi runtime. The runtime is used for sharing values (:meth:`secret_share` or @@ -113,6 +115,27 @@ sls.addCallbacks(combine, self.error_handler) return sls + def _expect_orlandi_share_xi_rhoi(self, peer_id, field): + xi = self._expect_share(peer_id, field) + rhoi1 = self._expect_share(peer_id, field) + rhoi2 = self._expect_share(peer_id, field) + sls = ShareList([xi, rhoi1, rhoi2]) + def combine(ls): + expected_num = 3; + if len(ls) is not expected_num: + raise OrlandiException("Cannot share number, trying to create a share," + " expected %s components got %s." % (expected_num, len(ls))) + + s1, xi = ls[0] + s2, rhoi1 = ls[1] + s3, rhoi2 = ls[2] + if not (s1 and s2 and s3): + raise OrlandiException("Cannot share number, trying to create share " + "but a component did arrive properly.") + return OrlandiShare(self, field, xi, (rhoi1, rhoi2)) + sls.addCallbacks(combine, self.error_handler) + return sls + def secret_share(self, inputters, field, number=None, threshold=None): """Share the value, number, among all the parties using additive shareing. @@ -186,6 +209,66 @@ return results[0] return results + def open(self, share, receivers=None, threshold=None): + """Share reconstruction. + + Every partyi broadcasts a share pair ``(x_i', rho_x,i')``. + + The parties compute the sums ``x'``, ``rho_x'`` and + check ``Com_ck(x',rho_x' = C_x``. + + If yes, return ``x = x'``, else else return :const:`None`. + """ + assert isinstance(share, Share) + # all players receive result by default + if receivers is None: + receivers = self.players.keys() + assert threshold is None + threshold = self.num_players - 1 + + field = share.field + + self.program_counter[-1] += 1 + + def recombine_value(shares, Cx): + x = 0 + rho1 = 0 + rho2 = 0 + for xi, rhoi1, rhoi2 in shares: + x += xi + rho1 += rhoi1 + rho2 += rhoi2 + Cx1 = commitment.commit(x.value, rho1.value, rho2.value) + if Cx1 == Cx: + return x + else: + raise OrlandiException("Wrong commitment for value %s, found %s expected %s." % + (x, Cx1, Cx)) + + def deserialize(ls): + shares = [(field(long(x)), field(long(rho1)), field(long(rho2))) for x, rho1, rho2 in map(self.list_str, ls)] + return shares + + def exchange((xi, (rhoi1, rhoi2), Cx), receivers): + # Send share to all receivers. + ds = self.broadcast(self.players.keys(), receivers, str((str(xi.value), str(rhoi1.value), str(rhoi2.value)))) + + if self.id in receivers: + result = gatherResults(ds) + result.addCallbacks(deserialize, self.error_handler) + result.addCallbacks(recombine_value, self.error_handler, callbackArgs=(Cx,)) + return result + + result = share.clone() + self.schedule_callback(result, exchange, receivers) + result.addErrback(self.error_handler) + + # do actual communication + self.activate_reactor() + + if self.id in receivers: + return result + def error_handler(self, ex): print "Error: ", ex return ex diff --git a/viff/runtime.py b/viff/runtime.py --- a/viff/runtime.py +++ b/viff/runtime.py @@ -327,13 +327,20 @@ key = (program_counter, data_type) +# print "Player %s has received data %s from %s with pc: %s" % (str(self.factory.runtime.id), +# str(data), +# str(self.peer_id), +# str(key)) + if key in self.waiting_deferreds: +# print "A deferred was waiting" deq = self.waiting_deferreds[key] deferred = deq.popleft() if not deq: del self.waiting_deferreds[key] self.factory.runtime.handle_deferred_data(deferred, data) else: +# print "A deferred is not waiting, lets put the data on the shelf" deq = self.incoming_data.setdefault(key, deque()) deq.append(data) except struct.error, e: @@ -392,7 +399,13 @@ """ try: key = (program_counter, data_type) - + +# print self +# print "Player %s has received data %s from %s with pc: %s" % (str(self.factory.runtime.id), +# str(data), +# str(self.peer_id), +# program_counter) + if key in self.waiting_deferreds: deq = self.waiting_deferreds[key] deferred = deq.popleft() @@ -741,6 +754,7 @@ else: # We have not yet received anything from the other side. deq = self.protocols[peer_id].waiting_deferreds.setdefault(key, deque()) +# print "The deferred %s is waiting on data from %i with key: %s" % (str(deferred), peer_id, str(key)) deq.append(deferred) def _exchange_shares(self, peer_id, field_element): @@ -855,7 +869,6 @@ def handle_deferred_data(self, deferred, data): """Put deferred and data into the queue if the ViffReactor is running. Otherwise, just execute the callback.""" - if self.using_viff_reactor: self.deferred_queue.append((deferred, data)) else: diff --git a/viff/test/test_orlandi_runtime.py b/viff/test/test_orlandi_runtime.py --- a/viff/test/test_orlandi_runtime.py +++ b/viff/test/test_orlandi_runtime.py @@ -53,3 +53,21 @@ share = runtime.secret_share([1], self.Zp) share.addCallback(check) return share + + @protocol + def test_open_secret_share(self, runtime): + """Test sharing and open of a number.""" + + self.Zp = GF(6277101735386680763835789423176059013767194773182842284081) + + def check(v): + self.assertEquals(v, 42) + + if 1 == runtime.id: + x = runtime.secret_share([1], self.Zp, 42) + else: + x = runtime.secret_share([1], self.Zp) + d = runtime.open(x) + d.addCallback(check) + return d + _______________________________________________ viff-patches mailing list [email protected] http://lists.viff.dk/listinfo.cgi/viff-patches-viff.dk
