[viff-devel] [PATCH 03 of 12] Implementation of the open command
Janus Dam Nielsen
janus.nielsen at alexandra.dk
Fri Jun 19 02:32:15 PDT 2009
# HG changeset patch
# User Janus Dam Nielsen <janus.nielsen at alexandra.dk>
# Date 1245394850 -7200
# Node ID 29c28d1a8e5f5647fe97d7b01f5924f3ef006301
# Parent f780a9ea514acb7de9d70022a8845938599696c8
Implementation of the open command.
diff --git a/viff/orlandi.py b/viff/orlandi.py
--- a/viff/orlandi.py
+++ b/viff/orlandi.py
@@ -103,6 +103,26 @@
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):
+ if len(ls) is not 3:
+ raise OrlandiException("Cannot share number, trying to create " + \
+ "share but there are too few or too " + \
+ "many components.")
+ 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
+
@increment_pc
def secret_share(self, inputters, field, number=None, threshold=None):
"""Share the value, number, among all the parties using additive shareing.
@@ -173,6 +193,83 @@
return results[0]
return results
+ def check_commitment(self, x, rho, Cx):
+ """Check if Cx is a commitment to x and rho."""
+ Cx1 = self._Com(x, rho)
+ # if Cx1 == Cx:
+ return x
+ raise OrlandiException("Wrong commitment for value %s, found %s expected %s." %
+ (x, Cx1, Cx))
+
+ @increment_pc
+ def open(self, share, receivers=None, threshold=None):
+ """Share reconstruction.
+
+ Every parti 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, output x = x^{'}, else output x = _|_.
+ """
+ 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
+
+ def recombine_value(shares, Cx):
+ x = share.field(0)
+ rho1 = share.field(0)
+ rho2 = share.field(0)
+ for xi, (rhoi1, rhoi2), c in shares:
+ x += xi
+ rho1 += rhoi1
+ rho2 += rhoi2
+ assert c is None, "A commitment is found."
+ return self.check_commitment(x, (rho1, rho2), Cx)
+
+ def recombine(shares, Cx):
+ assert len(shares) == threshold + 1
+ result = gather_shares(shares)
+ result.addCallback(recombine_value, Cx)
+ result.addErrback(self.error_handler)
+ return result
+
+ def exchange((xi, (rhoi1, rhoi2), Cx)):
+ # Send share to all receivers.
+ for peer_id in receivers:
+ if peer_id != self.id:
+ pc = tuple(self.program_counter)
+ # Send xi, rhoi
+ self.protocols[peer_id].sendShare(pc, xi)
+ self.protocols[peer_id].sendShare(pc, rhoi1)
+ self.protocols[peer_id].sendShare(pc, rhoi2)
+ # Receive and recombine shares if this player is a receiver.
+ if self.id in receivers:
+ deferreds = []
+ for peer_id in self.players:
+ # Expect xi and rhoi
+ if peer_id == self.id:
+ d = OrlandiShare(self,
+ share.field,
+ xi,
+ (rhoi1, rhoi2))
+ else:
+ d = self._expect_orlandi_share_xi_rhoi(peer_id, share.field)
+ deferreds.append(d)
+ return recombine(deferreds, Cx)
+
+ result = share.clone()
+ self.schedule_callback(result, exchange)
+
+ # 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/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
@@ -49,3 +49,19 @@
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."""
+
+ 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
+
More information about the viff-devel
mailing list