viff

changeset 1396:866a0167ddeb

Merged with Martin.
author Janus Dam Nielsen Thu, 12 Nov 2009 11:40:17 +0100 b4b94221beee 3ede8d56ae64 bf8b5b8a5a43 44ac3a04f413 2 files changed, 108 insertions(+), 22 deletions(-) [+]
line diff
```     1.1 --- a/viff/orlandi.py	Thu Nov 05 12:03:59 2009 +0100
1.2 +++ b/viff/orlandi.py	Thu Nov 12 11:40:17 2009 +0100
1.3 @@ -28,7 +28,7 @@
1.5
1.6  try:
1.7 -    from pypaillier import encrypt_r, decrypt
1.8 +    from pypaillier import encrypt_r, decrypt, tripple
1.9      import commitment
1.10      commitment.set_reference_string(23434347834783478783478L,
1.11                                      489237823478234783478020L)
1.12 @@ -282,6 +282,81 @@
1.14              return result
1.15
1.16 +    def open_multiple_values(self, shares, receivers=None):
1.17 +        """Share reconstruction.
1.18 +
1.19 +        Open multiple values in one burst.
1.20 +        If called with one value it is slower than the open method.
1.21 +        If called with more than two values it is faster than using
1.22 +        multiple calls to the open method.
1.23 +
1.24 +        Every partyi broadcasts a share pair ``(x_i', rho_x,i')``.
1.25 +
1.26 +        The parties compute the sums ``x'``, ``rho_x'`` and check
1.27 +        ``Com_ck(x',rho_x') = C_x``.
1.28 +
1.29 +        If yes, return ``x = x'``, else else return :const:`None`.
1.30 +        """
1.31 +        assert shares
1.32 +        # all players receive result by default
1.33 +        if receivers is None:
1.35 +
1.36 +        field = shares[0].field
1.37 +
1.38 +        self.increment_pc()
1.39 +
1.40 +        def recombine_value((shares, Cx)):
1.41 +            x = 0
1.42 +            rho1 = 0
1.43 +            rho2 = 0
1.44 +            for xi, rhoi1, rhoi2 in shares:
1.45 +                x += xi
1.46 +                rho1 += rhoi1
1.47 +                rho2 += rhoi2
1.48 +            Cx1 = commitment.commit(x.value, rho1.value, rho2.value)
1.49 +            if Cx1 == Cx:
1.50 +                return x
1.51 +            else:
1.52 +                #return x
1.53 +                raise OrlandiException("Wrong commitment for value %s, %s, %s, found %s expected %s." %
1.54 +                                       (x, rho1, rho2, Cx1, Cx))
1.55 +
1.56 +        def deserialize(ls, commitments):
1.57 +            def convert_from_string_to_field(s):
1.58 +                def field_long(x):
1.59 +                    return field(long(x))
1.60 +                xs = s[0:-1].split(';')
1.61 +                ys = [x.split(':') for x in xs]
1.62 +                return [map(field_long, xs) for xs in ys]
1.63 +            shares = map(convert_from_string_to_field, ls)
1.64 +            return map(recombine_value, zip(zip(*shares), commitments))
1.65 +
1.67 +            commitments = [None] * len(ls)
1.69 +            for inx, (xi, (rhoi1, rhoi2), Cx) in enumerate(ls):
1.70 +                broadcast_string += "%s:%s:%s;" % (xi.value, rhoi1.value, rhoi2.value)
1.71 +                commitments[inx] = (Cx)
1.72 +            # Send share to all receivers.
1.74 +
1.75 +            if self.id in receivers:
1.76 +                result = gatherResults(ds)
1.78 +                                    callbackArgs=(commitments,))
1.79 +                return result
1.80 +
1.81 +        result = gather_shares(shares)
1.84 +
1.85 +        # do actual communication
1.86 +        self.activate_reactor()
1.87 +
1.88 +        if self.id in receivers:
1.89 +            return result
1.90 +
1.91      def random_share(self, field):
1.92          """Generate a random share in the field, field.
1.93
1.94 @@ -611,7 +686,9 @@
1.95          if cmul_result is  not None:
1.96              return cmul_result
1.97
1.98 -        def multiply((x, y, d, e, c)):
1.99 +        def multiply((x, y, ds, c)):
1.100 +            d = ds[0]
1.101 +            e = ds[1]
1.102              # [de]
1.103              de = self._additive_constant(field(0), d * e)
1.104              # e[x]
1.105 @@ -627,10 +704,9 @@
1.106              return OrlandiShare(self, field, zi, rhoz, Cz)
1.107
1.108          # d = Open([x] - [a])
1.109 -        d = self.open(share_x - triple_a)
1.110          # e = Open([y] - [b])
1.111 -        e = self.open(share_y - triple_b)
1.112 -        result = gather_shares([share_x, share_y, d, e, triple_c])
1.113 +        ds = self.open_multiple_values([share_x - triple_a, share_y - triple_b])
1.114 +        result = gather_shares([share_x, share_y, ds, triple_c])
1.116
1.117          # do actual communication
1.118 @@ -881,17 +957,10 @@
1.119              pc = tuple(self.program_counter)
1.120              p3 = field.modulus**3
1.121              for pi in self.players.keys():
1.122 -                n = self.players[pi].pubkey['n']
1.123 -                nsq = n * n
1.124                  # choose random d_i,j in Z_p^3
1.125                  dij = random_number(p3)
1.126 -                # Enc_ek_i(1;1)^d_ij
1.127 -                enc = encrypt_r(1, 1, self.players[pi].pubkey)
1.128 -                t1 = pow(enc, dij.value, nsq)
1.129 -                # alpha_i^b_j.
1.130 -                t2 = pow(alphas[pi - 1], bj.value, nsq)
1.131                  # gamma_ij = alpha_i^b_j Enc_ek_i(1;1)^d_ij
1.132 -                gammaij = (t2 * t1) % nsq
1.133 +                gammaij = tripple(alphas[pi - 1], bj.value, dij.value, self.players[pi].pubkey)
1.135                  if pi != self.id:
1.136                      self.protocols[pi].sendData(pc, PAILLIER, str(gammaij))
1.137 @@ -1139,20 +1208,15 @@
1.138
1.139                  # 3) the gammaij he received is equal to the gammaij
1.140                  # he now computes based on the values he reveives
1.141 +                modulus_3 = field.modulus**3
1.142                  for j in xrange(len(ais)):
1.143 -                    n = self.players[self.id].pubkey['n']
1.144 -                    nsq = n * n
1.145                      dij = dijs[j]
1.146                      # 5) ... and dij < p^3.
1.147 -                    if dij >= (field.modulus**3):
1.148 +                    if dij >= (modulus_3):
1.149                          raise OrlandiException("Inconsistent random value dij %i from player %i" % (dij, j + 1))
1.150 -                    # Enc_ek_i(1;1)^d_ij
1.151 -                    enc = encrypt_r(1, 1, self.players[self.id].pubkey)
1.152 -                    t1 = pow(enc, dij.value, nsq)
1.153 -                    # alpha_i^b_j.
1.154 -                    t2 = pow(alphas[self.id - 1], bis[j][0].value, nsq)
1.155                      # gamma_ij = alpha_i^b_j Enc_ek_i(1;1)^d_ij
1.156 -                    gammaij = (t2) * (t1) % nsq
1.157 +                    gammaij = tripple(alphas[self.id - 1], bis[j][0].value,
1.158 +                                      dij.value, self.players[self.id].pubkey)
1.159                      if gammaij != gammas[j]:
1.160                          raise OrlandiException("Inconsistent gammaij, %i, %i" % (gammaij, gammas[j]))
1.161
```
```     2.1 --- a/viff/test/test_orlandi_runtime.py	Thu Nov 05 12:03:59 2009 +0100
2.2 +++ b/viff/test/test_orlandi_runtime.py	Thu Nov 12 11:40:17 2009 +0100
2.3 @@ -92,6 +92,28 @@
2.4          return d
2.5
2.6      @protocol
2.7 +    def test_open_multiple_secret_share(self, runtime):
2.8 +        """Test sharing and open of a number."""
2.9 +
2.10 +        self.Zp = GF(6277101735386680763835789423176059013767194773182842284081)
2.11 +
2.12 +        def check(ls):
2.13 +            for inx, v in enumerate(ls):
2.14 +                self.assertEquals(v, (inx + 1) * 42)
2.15 +
2.16 +        if 1 == runtime.id:
2.17 +            x = runtime.secret_share([1], self.Zp, 42)
2.18 +        else:
2.19 +            x = runtime.secret_share([1], self.Zp)
2.20 +        if 1 == runtime.id:
2.21 +            y = runtime.secret_share([1], self.Zp, 84)
2.22 +        else:
2.23 +            y = runtime.secret_share([1], self.Zp)
2.24 +        d = runtime.open_multiple_values([x, y])