# HG changeset patch # User Janus Dam Nielsen <janus.niel...@alexandra.dk> # Date 1245394917 -7200 # Node ID 4c4228af583fc965fb0722c5b051ffa213152f62 # Parent 85ae7883768d8367baf57cf3b6647707cb1d9b1d Implementation of subtraction command.
diff --git a/viff/orlandi.py b/viff/orlandi.py --- a/viff/orlandi.py +++ b/viff/orlandi.py @@ -347,6 +347,37 @@ result.addCallbacks(compute_sums, self.error_handler) return result + def sub(self, share_a, share_b): + """Subtraction of shares. + + Communication cost: none. + + Each party P_{i} computes: + [z]_{i} = [x]_{i} - [y]_{i} + = (x_{i} - y_{i} mod p, rho_{x,i} - rho_{y,i} mod p, C_{x} * C_{y}). + + """ + def is_share(s, field): + if not isinstance(s, Share): + (v, rhov, Cv) = self._additive_constant(field(0), s) + return OrlandiShare(self, field, v, rhov, Cv) + return s + + # Either share_a or share_b must have an attribute called "field". + field = getattr(share_a, "field", getattr(share_b, "field", None)) + + share_a = is_share(share_a, field) + share_b = is_share(share_b, field) + + # Subtract xi and yi, rhoxi and rhoyi, and compute the commitment + def compute_subs((x, y)): + zi, (rhozi1, rhozi2), Cz = self._minus(x, y) + return OrlandiShare(self, field, zi, (rhozi1, rhozi2), Cz) + + result = gather_shares([share_a, share_b]) + result.addCallbacks(compute_subs, self.error_handler) + return result + def _additive_constant(self, zero, field_element): """Greate an additive constant. @@ -376,6 +407,23 @@ Cz = Cx * Cy return (zi, (rhozi1, rhozi2), Cz) + def _minus(self, x, y): + """Subtraction of share-tuples x and y. + + Each party P_{i} computes: + [x]_{i} = (x_{i}, rho_{x,i}, C_{x}) + [y]_{i} = (y_{i}, rho_{y,i}, C_{y}) + [z]_{i} = [x]_{i} - [y]_{i} + = (x_{i} - y_{i} mod p, rho_{x,i} - rho_{y,i} mod p, C_{x} * C_{y}). + """ + xi, (rhoxi1, rhoxi2), Cx = x + yi, (rhoyi1, rhoyi2), Cy = y + zi = xi - yi + rhozi1 = rhoxi1 - rhoyi1 + rhozi2 = rhoxi2 - rhoyi2 + Cz = Cx * Cy + return (zi, (rhozi1, rhozi2), Cz) + 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 @@ -147,5 +147,74 @@ d.addCallback(check) return d + @protocol + def test_sub(self, runtime): + """Test subtration of two numbers.""" + x1 = 42 + y1 = 7 + def check(v): + self.assertEquals(v, x1 + y1) + + if 1 == runtime.id: + x2 = runtime.secret_share([1], self.Zp, x1) + else: + x2 = runtime.secret_share([1], self.Zp) + + if 3 == runtime.id: + y2 = runtime.secret_share([3], self.Zp, y1) + else: + y2 = runtime.secret_share([3], self.Zp) + + z2 = runtime.add(x2, y2) + d = runtime.open(z2) + d.addCallback(check) + return d + + @protocol + def test_sub_minus(self, runtime): + """Test subtration of two numbers.""" + + x1 = 42 + y1 = 7 + + def check(v): + self.assertEquals(v, x1 - y1) + + if 1 == runtime.id: + x2 = runtime.secret_share([1], self.Zp, x1) + else: + x2 = runtime.secret_share([1], self.Zp) + + if 3 == runtime.id: + y2 = runtime.secret_share([3], self.Zp, y1) + else: + y2 = runtime.secret_share([3], self.Zp) + + z2 = x2 - y2 + d = runtime.open(z2) + d.addCallback(check) + return d + + @protocol + def test_sub_constant(self, runtime): + """Test subtration of two numbers.""" + + x1 = 42 + y1 = 7 + + def check(v): + self.assertEquals(v, x1 - y1) + + if 1 == runtime.id: + x2 = runtime.secret_share([1], self.Zp, x1) + else: + x2 = runtime.secret_share([1], self.Zp) + + z2 = x2 - y1 + d = runtime.open(z2) + d.addCallback(check) + return d + + _______________________________________________ viff-devel mailing list (http://viff.dk/) viff-devel@viff.dk http://lists.viff.dk/listinfo.cgi/viff-devel-viff.dk