# 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

Reply via email to