# HG changeset patch
# User Janus Dam Nielsen <[email protected]>
# 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/)
[email protected]
http://lists.viff.dk/listinfo.cgi/viff-devel-viff.dk