viff

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 diff
     1.1 --- a/viff/bedoza.py	Tue Jul 06 14:23:29 2010 +0200
     1.2 +++ b/viff/bedoza.py	Tue Jul 06 15:00:30 2010 +0200
     1.3 @@ -22,6 +22,8 @@
     1.4  from viff.runtime import Runtime, Share, ShareList, gather_shares
     1.5  from viff.field import FieldElement
     1.6  
     1.7 +from viff.simplearithmetic import SimpleArithmetic
     1.8 +
     1.9  from hash_broadcast import HashBroadcastMixin
    1.10  
    1.11  class BeDOZaException(Exception):
    1.12 @@ -66,6 +68,14 @@
    1.13              keys.append(k1 + k2)
    1.14          return BeDOZaKeyList(self.alpha, keys)
    1.15  
    1.16 +    def __sub__(self, other):
    1.17 +        """Subtraction."""
    1.18 +        assert self.alpha == other.alpha
    1.19 +        keys = []
    1.20 +        for k1, k2 in zip(self.keys, other.keys):
    1.21 +            keys.append(k1 - k2)
    1.22 +        return BeDOZaKeyList(self.alpha, keys)
    1.23 +
    1.24      def __eq__(self, other):
    1.25          return self.alpha == other.alpha and self.keys == other.keys
    1.26  
    1.27 @@ -87,6 +97,13 @@
    1.28              auth_codes.append(c1 + c2)
    1.29          return BeDOZaMessageList(auth_codes)
    1.30  
    1.31 +    def __sub__(self, other):
    1.32 +        """Subtraction."""
    1.33 +        auth_codes = []
    1.34 +        for c1, c2 in zip(self.auth_codes, other.auth_codes):
    1.35 +            auth_codes.append(c1 - c2)
    1.36 +        return BeDOZaMessageList(auth_codes)
    1.37 +
    1.38      def __eq__(self, other):
    1.39          return self.auth_codes == other.auth_codes
    1.40  
    1.41 @@ -138,7 +155,7 @@
    1.42                  2: (field(3), [field(4), field(5), field(6)]),
    1.43                  3: (field(4), [field(7), field(8), field(9)])}
    1.44  
    1.45 -class BeDOZaRuntime(Runtime, HashBroadcastMixin, KeyLoader, RandomShareGenerator):
    1.46 +class BeDOZaRuntime(SimpleArithmetic, Runtime, HashBroadcastMixin, KeyLoader, RandomShareGenerator):
    1.47      """The BeDOZa runtime.
    1.48  
    1.49      The runtime is used for sharing values (:meth:`secret_share` or
    1.50 @@ -254,36 +271,12 @@
    1.51  
    1.52      def get_alpha(self):
    1.53          return self.keys[0]
    1.54 -        
    1.55 -    def add(self, share_a, share_b):
    1.56 -        """Addition of shares.
    1.57  
    1.58 -        Communication cost: none.
    1.59 -
    1.60 -        Each party ``P_i`` computes::
    1.61 -
    1.62 -          [z]_i = [x]_i + [y]_i
    1.63 -                = (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})
    1.64 -
    1.65 -        """
    1.66 -        # Either share_a or share_b must have an attribute called "field".
    1.67 -        field = share_a.field
    1.68 -        if not isinstance(share_b, Share):
    1.69 -            if not isinstance(share_b, FieldElement):
    1.70 -                share_b = field(share_b)
    1.71 -            share_a.addCallbacks(self._add_public, self.error_handler, callbackArgs=(share_b, field))
    1.72 -            return share_a
    1.73 -        else:
    1.74 -            result = gather_shares([share_a, share_b])
    1.75 -            result.addCallbacks(self._plus, self.error_handler, callbackArgs=(field,))
    1.76 -            return result
    1.77 -
    1.78 -    def _add_public(self, x, y, field):
    1.79 -        """Greate an additive constant."""
    1.80 +    def _plus_public(self, x, c, field):
    1.81          (xi, xks, xms) = x
    1.82          if self.id == 1:
    1.83 -            xi = xi + y
    1.84 -        xks.keys[0] = xks.keys[0] - xks.alpha * y
    1.85 +            xi = xi + c
    1.86 +        xks.keys[0] = xks.keys[0] - xks.alpha * c
    1.87          return BeDOZaShare(self, field, xi, xks, xms)
    1.88  
    1.89      def _plus(self, (x, y), field):
    1.90 @@ -301,3 +294,26 @@
    1.91          zks = xks + yks
    1.92          zms = xms + yms
    1.93          return (zi, zks, zms)
    1.94 +
    1.95 +    def _minus_public(self, x, c, field):
    1.96 +        (xi, xks, xms) = x
    1.97 +        if self.id == 1:
    1.98 +            xi = xi - c
    1.99 +        xks.keys[0] = xks.keys[0] + xks.alpha * c
   1.100 +        return BeDOZaShare(self, field, xi, xks, xms)
   1.101 +    
   1.102 +    def _minus(self, (x, y), field):
   1.103 +        """Subtraction of share-tuples *x* and *y*.
   1.104 +
   1.105 +        Each party ``P_i`` computes:
   1.106 +        ``[x]_i = (x_i, xk, xm)``
   1.107 +        ``[y]_i = (y_i, yk, ym)``
   1.108 +        ``[z]_i = [x]_i - [y]_i
   1.109 +                = (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})
   1.110 +        """
   1.111 +        (xi, xks, xms) = x
   1.112 +        (yi, yks, yms) = y
   1.113 +        zi = xi - yi
   1.114 +        zks = xks - yks
   1.115 +        zms = xms - yms
   1.116 +        return (zi, zks, zms)
     2.1 --- a/viff/test/test_bedoza_runtime.py	Tue Jul 06 14:23:29 2010 +0200
     2.2 +++ b/viff/test/test_bedoza_runtime.py	Tue Jul 06 15:00:30 2010 +0200
     2.3 @@ -211,3 +211,84 @@
     2.4          d = runtime.open(z2)
     2.5          d.addCallback(check)
     2.6          return d
     2.7 +
     2.8 +    @protocol
     2.9 +    def test_minus(self, runtime):
    2.10 +        """Test subtraction of two numbers."""
    2.11 +
    2.12 +        Zp = GF(6277101735386680763835789423176059013767194773182842284081)
    2.13 +       
    2.14 +        x = (Zp(2), BeDOZaKeyList(Zp(23), [Zp(5), Zp(4), Zp(7)]), BeDOZaMessageList([Zp(2), Zp(75), Zp(23), Zp(2)]))
    2.15 +        y = (Zp(2), BeDOZaKeyList(Zp(23), [Zp(3), Zp(2), Zp(1)]), BeDOZaMessageList([Zp(2), Zp(74), Zp(23), Zp(2)]))
    2.16 +        zi, zks, zms = runtime._minus((x, y), Zp)
    2.17 +        self.assertEquals(zi, Zp(0))
    2.18 +        self.assertEquals(zks, BeDOZaKeyList(Zp(23), [Zp(2), Zp(2), Zp(6)]))
    2.19 +        self.assertEquals(zms, BeDOZaMessageList([Zp(0), Zp(1), Zp(0), Zp(0)]))
    2.20 +        return zi
    2.21 +
    2.22 +    @protocol
    2.23 +    def test_sub(self, runtime):
    2.24 +        """Test subtraction of two numbers."""
    2.25 +
    2.26 +        self.Zp = GF(6277101735386680763835789423176059013767194773182842284081)
    2.27 +
    2.28 +        def check(v):
    2.29 +            self.assertEquals(v, 0)
    2.30 +
    2.31 +        x2 = runtime.random_share(self.Zp)
    2.32 +        y2 = runtime.random_share(self.Zp)
    2.33 +        z2 = runtime.sub(x2, y2)
    2.34 +        d = runtime.open(z2)
    2.35 +        d.addCallback(check)
    2.36 +        return d
    2.37 +
    2.38 +    @protocol
    2.39 +    def test_sub_minus(self, runtime):
    2.40 +        """Test subtraction of two numbers."""
    2.41 +
    2.42 +        self.Zp = GF(6277101735386680763835789423176059013767194773182842284081)
    2.43 +
    2.44 +        def check(v):
    2.45 +            self.assertEquals(v, 0)
    2.46 +
    2.47 +        x2 = runtime.random_share(self.Zp)
    2.48 +        y2 = runtime.random_share(self.Zp)
    2.49 +        z2 = x2 - y2
    2.50 +        d = runtime.open(z2)
    2.51 +        d.addCallback(check)
    2.52 +        return d
    2.53 +
    2.54 +    @protocol
    2.55 +    def test_sub_constant_right(self, runtime):
    2.56 +        """Test subtraction of secret shared number and a public number."""
    2.57 +
    2.58 +        self.Zp = GF(31)
    2.59 +
    2.60 +        y = 4
    2.61 +
    2.62 +        def check(v):
    2.63 +            self.assertEquals(v, 2)
    2.64 +
    2.65 +        x2 = runtime.random_share(self.Zp)
    2.66 +        z2 = x2 - y
    2.67 +        d = runtime.open(x2)
    2.68 +        d.addCallback(check)
    2.69 +        return d
    2.70 +
    2.71 +    @protocol
    2.72 +    def test_sub_constant_left(self, runtime):
    2.73 +        """Test subtraction of a public number and secret shared number."""
    2.74 +
    2.75 +        self.Zp = GF(6277101735386680763835789423176059013767194773182842284081)
    2.76 +
    2.77 +        x1 = 42
    2.78 +        y1 = 7
    2.79 +
    2.80 +        def check(v):
    2.81 +            self.assertEquals(v, 1)
    2.82 +
    2.83 +        x2 = runtime.random_share(self.Zp)
    2.84 +        z2 = y1 - x2
    2.85 +        d = runtime.open(z2)
    2.86 +        d.addCallback(check)
    2.87 +        return d