## viff

### changeset 1462:2ac4e8f3b3d0

BeDOZa: Use the SimpleArithmetic mixin for addition and subtraction.
author Janus Dam Nielsen Tue, 06 Jul 2010 15:00:30 +0200 85c41e1f7328 d09cd2050333 a28c7d75c09e viff/bedoza.py viff/test/test_bedoza_runtime.py 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.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.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.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.72 -            return share_a
1.73 -        else:
1.74 -            result = gather_shares([share_a, share_b])
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.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.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.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.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)