# HG changeset patch # User Janus Dam Nielsen <janus.niel...@alexandra.dk> # Date 1245394853 -7200 # Node ID 85ae7883768d8367baf57cf3b6647707cb1d9b1d # Parent 1eb98ef76446e9ef06d8d94e31748fe5cfd2ba82 Implementation of addition command.
diff --git a/viff/orlandi.py b/viff/orlandi.py --- a/viff/orlandi.py +++ b/viff/orlandi.py @@ -316,6 +316,66 @@ return sls + def add(self, share_a, share_b): + """Addition 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) + + # Add rho_{x,i} and rho_{y,i} and compute the commitment. + def compute_sums((x, y)): + (zi, (rhozi1, rhozi2), Cz) = self._plus(x, y) + return OrlandiShare(self, field, zi, (rhozi1, rhozi2), Cz) + + result = gather_shares([share_a, share_b]) + result.addCallbacks(compute_sums, self.error_handler) + return result + + def _additive_constant(self, zero, field_element): + """Greate an additive constant. + + Any additive constant can be interpreted as: + [c]_{1} = (c, 0, Com_{ck}(c,0)) and + [c]_{i} = (0, 0, Com_{ck}(c,0)) for i != 1. + """ + v = zero + if self.id == 1: + v = field_element + return (v, (zero, zero), self._Com(field_element, (zero, zero))) + + def _plus(self, x, y): + """Addition 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 @@ -77,4 +77,75 @@ d.addCallback(check) return d + @protocol + def test_sum(self, runtime): + """Test addition 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_sum_plus(self, runtime): + """Test addition 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_sum_constant(self, runtime): + """Test addition 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