changeset 1462:2ac4e8f3b3d0

BeDOZa: Use the SimpleArithmetic mixin for addition and subtraction.
author Janus Dam Nielsen <janus.nielsen@alexandra.dk>
date Tue, 06 Jul 2010 15:00:30 +0200
parents 85c41e1f7328
children d09cd2050333 a28c7d75c09e
files viff/bedoza.py viff/test/test_bedoza_runtime.py
diffstat 2 files changed, 125 insertions(+), 28 deletions(-) [+]
line wrap: on
line diff
--- a/viff/bedoza.py	Tue Jul 06 14:23:29 2010 +0200
+++ b/viff/bedoza.py	Tue Jul 06 15:00:30 2010 +0200
@@ -22,6 +22,8 @@
 from viff.runtime import Runtime, Share, ShareList, gather_shares
 from viff.field import FieldElement
 
+from viff.simplearithmetic import SimpleArithmetic
+
 from hash_broadcast import HashBroadcastMixin
 
 class BeDOZaException(Exception):
@@ -66,6 +68,14 @@
             keys.append(k1 + k2)
         return BeDOZaKeyList(self.alpha, keys)
 
+    def __sub__(self, other):
+        """Subtraction."""
+        assert self.alpha == other.alpha
+        keys = []
+        for k1, k2 in zip(self.keys, other.keys):
+            keys.append(k1 - k2)
+        return BeDOZaKeyList(self.alpha, keys)
+
     def __eq__(self, other):
         return self.alpha == other.alpha and self.keys == other.keys
 
@@ -87,6 +97,13 @@
             auth_codes.append(c1 + c2)
         return BeDOZaMessageList(auth_codes)
 
+    def __sub__(self, other):
+        """Subtraction."""
+        auth_codes = []
+        for c1, c2 in zip(self.auth_codes, other.auth_codes):
+            auth_codes.append(c1 - c2)
+        return BeDOZaMessageList(auth_codes)
+
     def __eq__(self, other):
         return self.auth_codes == other.auth_codes
 
@@ -138,7 +155,7 @@
                 2: (field(3), [field(4), field(5), field(6)]),
                 3: (field(4), [field(7), field(8), field(9)])}
 
-class BeDOZaRuntime(Runtime, HashBroadcastMixin, KeyLoader, RandomShareGenerator):
+class BeDOZaRuntime(SimpleArithmetic, Runtime, HashBroadcastMixin, KeyLoader, RandomShareGenerator):
     """The BeDOZa runtime.
 
     The runtime is used for sharing values (:meth:`secret_share` or
@@ -254,36 +271,12 @@
 
     def get_alpha(self):
         return self.keys[0]
-        
-    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, {xk^{i}_{j} + yk^{i}_{j} mod p}_{j=0}^{j=n}, {xm^{i}_{j} + ym^{i}_{j} mod p}_{j=0}^{j=n})
-
-        """
-        # Either share_a or share_b must have an attribute called "field".
-        field = share_a.field
-        if not isinstance(share_b, Share):
-            if not isinstance(share_b, FieldElement):
-                share_b = field(share_b)
-            share_a.addCallbacks(self._add_public, self.error_handler, callbackArgs=(share_b, field))
-            return share_a
-        else:
-            result = gather_shares([share_a, share_b])
-            result.addCallbacks(self._plus, self.error_handler, callbackArgs=(field,))
-            return result
-
-    def _add_public(self, x, y, field):
-        """Greate an additive constant."""
+    def _plus_public(self, x, c, field):
         (xi, xks, xms) = x
         if self.id == 1:
-            xi = xi + y
-        xks.keys[0] = xks.keys[0] - xks.alpha * y
+            xi = xi + c
+        xks.keys[0] = xks.keys[0] - xks.alpha * c
         return BeDOZaShare(self, field, xi, xks, xms)
 
     def _plus(self, (x, y), field):
@@ -301,3 +294,26 @@
         zks = xks + yks
         zms = xms + yms
         return (zi, zks, zms)
+
+    def _minus_public(self, x, c, field):
+        (xi, xks, xms) = x
+        if self.id == 1:
+            xi = xi - c
+        xks.keys[0] = xks.keys[0] + xks.alpha * c
+        return BeDOZaShare(self, field, xi, xks, xms)
+    
+    def _minus(self, (x, y), field):
+        """Subtraction of share-tuples *x* and *y*.
+
+        Each party ``P_i`` computes:
+        ``[x]_i = (x_i, xk, xm)``
+        ``[y]_i = (y_i, yk, ym)``
+        ``[z]_i = [x]_i - [y]_i
+                = (x_i - y_i mod p, {xk^{i}_{j} - yk^{i}_{j} mod p}_{j=0}^{j=n}, {xm^{i}_{j} - ym^{i}_{j} mod p}_{j=0}^{j=n})
+        """
+        (xi, xks, xms) = x
+        (yi, yks, yms) = y
+        zi = xi - yi
+        zks = xks - yks
+        zms = xms - yms
+        return (zi, zks, zms)
--- a/viff/test/test_bedoza_runtime.py	Tue Jul 06 14:23:29 2010 +0200
+++ b/viff/test/test_bedoza_runtime.py	Tue Jul 06 15:00:30 2010 +0200
@@ -211,3 +211,84 @@
         d = runtime.open(z2)
         d.addCallback(check)
         return d
+
+    @protocol
+    def test_minus(self, runtime):
+        """Test subtraction of two numbers."""
+
+        Zp = GF(6277101735386680763835789423176059013767194773182842284081)
+       
+        x = (Zp(2), BeDOZaKeyList(Zp(23), [Zp(5), Zp(4), Zp(7)]), BeDOZaMessageList([Zp(2), Zp(75), Zp(23), Zp(2)]))
+        y = (Zp(2), BeDOZaKeyList(Zp(23), [Zp(3), Zp(2), Zp(1)]), BeDOZaMessageList([Zp(2), Zp(74), Zp(23), Zp(2)]))
+        zi, zks, zms = runtime._minus((x, y), Zp)
+        self.assertEquals(zi, Zp(0))
+        self.assertEquals(zks, BeDOZaKeyList(Zp(23), [Zp(2), Zp(2), Zp(6)]))
+        self.assertEquals(zms, BeDOZaMessageList([Zp(0), Zp(1), Zp(0), Zp(0)]))
+        return zi
+
+    @protocol
+    def test_sub(self, runtime):
+        """Test subtraction of two numbers."""
+
+        self.Zp = GF(6277101735386680763835789423176059013767194773182842284081)
+
+        def check(v):
+            self.assertEquals(v, 0)
+
+        x2 = runtime.random_share(self.Zp)
+        y2 = runtime.random_share(self.Zp)
+        z2 = runtime.sub(x2, y2)
+        d = runtime.open(z2)
+        d.addCallback(check)
+        return d
+
+    @protocol
+    def test_sub_minus(self, runtime):
+        """Test subtraction of two numbers."""
+
+        self.Zp = GF(6277101735386680763835789423176059013767194773182842284081)
+
+        def check(v):
+            self.assertEquals(v, 0)
+
+        x2 = runtime.random_share(self.Zp)
+        y2 = runtime.random_share(self.Zp)
+        z2 = x2 - y2
+        d = runtime.open(z2)
+        d.addCallback(check)
+        return d
+
+    @protocol
+    def test_sub_constant_right(self, runtime):
+        """Test subtraction of secret shared number and a public number."""
+
+        self.Zp = GF(31)
+
+        y = 4
+
+        def check(v):
+            self.assertEquals(v, 2)
+
+        x2 = runtime.random_share(self.Zp)
+        z2 = x2 - y
+        d = runtime.open(x2)
+        d.addCallback(check)
+        return d
+
+    @protocol
+    def test_sub_constant_left(self, runtime):
+        """Test subtraction of a public number and secret shared number."""
+
+        self.Zp = GF(6277101735386680763835789423176059013767194773182842284081)
+
+        x1 = 42
+        y1 = 7
+
+        def check(v):
+            self.assertEquals(v, 1)
+
+        x2 = runtime.random_share(self.Zp)
+        z2 = y1 - x2
+        d = runtime.open(z2)
+        d.addCallback(check)
+        return d