viff

changeset 1569:7cfd212041ac

BeDOZa: Use correct method for triple verification.
author Thomas P Jakobsen <tpj@cs.au.dk>
date Mon, 04 Oct 2010 10:27:01 +0200
parents cec0ff157247
children 6a727af6cb6c
files viff/bedoza/bedoza_triple.py viff/test/bedoza/test_bedoza_triple.py
diffstat 2 files changed, 78 insertions(+), 24 deletions(-) [+]
line diff
     1.1 --- a/viff/bedoza/bedoza_triple.py	Mon Oct 04 10:26:57 2010 +0200
     1.2 +++ b/viff/bedoza/bedoza_triple.py	Mon Oct 04 10:27:01 2010 +0200
     1.3 @@ -20,6 +20,7 @@
     1.4  """
     1.5  
     1.6  import itertools
     1.7 +import hashlib
     1.8  
     1.9  from twisted.internet.defer import Deferred, gatherResults, succeed
    1.10  
    1.11 @@ -177,37 +178,67 @@
    1.12          """
    1.13          assert n == len(triple_candidates) / 6
    1.14  
    1.15 -        def check(v, a, b, c):
    1.16 +        def verify(v, a, b, c):
    1.17              if v.value != 0:
    1.18                  raise Exception(
    1.19                      "TripleTest failed - The two triple candidates were "
    1.20                      "inconsistent.")
    1.21              return Triple(a, b, c)
    1.22 -        
    1.23 -        def compute_value(r, a, b, c, x, y, z):
    1.24 -            l = self.runtime._cmul(r, x, self.Zp)
    1.25 -            m = self.runtime._cmul(r, y, self.Zp)
    1.26 -            k = self.runtime._cmul(r * r, z, self.Zp)
    1.27 -            v = c - self.runtime._basic_multiplication(a, b, l, m, k)
    1.28 -            v = self.runtime.open(v)
    1.29 -            v.addCallback(check, a, b, c)
    1.30 -            return v
    1.31 +
    1.32 +        def prepare_verification(rs_serialized, results):
    1.33 +            # Repr/eval deserialization.
    1.34 +            rs = [eval(rss) for rss in rs_serialized]
    1.35 +
    1.36 +            for i in xrange(n):
    1.37 +                a = triple_candidates[i]
    1.38 +                b = triple_candidates[i + 2 * n]
    1.39 +                c = triple_candidates[i + 4 * n]
    1.40 +                x = triple_candidates[i + n]
    1.41 +                y = triple_candidates[i + 3 * n]
    1.42 +                z = triple_candidates[i + 5 * n]
    1.43 +
    1.44 +                # Hash all received random values to agree on a single
    1.45 +                # random value for each triple.
    1.46 +                hash = hashlib.sha1()
    1.47 +                for rp in rs:
    1.48 +                    hash.update(str(rp[i]))
    1.49 +                # TODO: We should use a secure random generator here.
    1.50 +                rand = Random(hash.digest())
    1.51 +                r = self.Zp(rand.randint(0, self.p - 1))
    1.52 +
    1.53 +                l = self.runtime._cmul(r, x, self.Zp)
    1.54 +                m = self.runtime._cmul(r, y, self.Zp)
    1.55 +                k = self.runtime._cmul(r * r, z, self.Zp)
    1.56 +                v = c - self.runtime._basic_multiplication(a, b, l, m, k)
    1.57 +                v = self.runtime.open(v)
    1.58 +                self.runtime.schedule_callback(v, verify, a, b, c)
    1.59 +                v.addCallbacks(results[i].callback, results[i].errback)
    1.60 +
    1.61 +        # TODO: Handle errors better.
    1.62 +        def err_handler(err):
    1.63 +            print err
    1.64  
    1.65          results = [Deferred() for _ in xrange(n)]
    1.66 -        gen = ShareGenerator(self.Zp, self.runtime, self.random, self.paillier,
    1.67 -                             self.u_bound, self.alpha)
    1.68 -        random_shares = gen.generate_random_shares(n)
    1.69  
    1.70 -        for inx in xrange(n):
    1.71 -            a = triple_candidates[inx]
    1.72 -            b = triple_candidates[inx + 2 * n]
    1.73 -            c = triple_candidates[inx + 4 * n]
    1.74 -            x = triple_candidates[inx + n]
    1.75 -            y = triple_candidates[inx + 3 * n]
    1.76 -            z = triple_candidates[inx + 5 * n]
    1.77 -            r = self.runtime.open(random_shares[inx])
    1.78 -            self.runtime.schedule_callback(r, compute_value, a, b, c, x, y, z)
    1.79 -            r.chainDeferred(results[inx])
    1.80 +        ri = [self.random.randint(0, self.p - 1) for _ in xrange(n)]
    1.81 +        # TODO: We use repr/eval as simple marshalling. Should be
    1.82 +        # factored out and maybe optimized by using better compression
    1.83 +        # here.
    1.84 +        ris = self.runtime.broadcast(
    1.85 +            self.runtime.players.keys(), self.runtime.players.keys(), repr(ri))
    1.86 +        ris = gatherResults(ris)
    1.87 +        self.runtime.schedule_callback(ris, prepare_verification, results)     
    1.88 +        ris.addErrback(err_handler)
    1.89 +        
    1.90 +        # TODO: Which makes most sense?
    1.91 +        # 
    1.92 +        # 1) Compute each triple separately and return list of
    1.93 +        #    deferred triples, or
    1.94 +        #
    1.95 +        # 2) Compute triples as a batch and return single deferred
    1.96 +        #    that evaluates to list of triples.
    1.97 +        #
    1.98 +        
    1.99          return results
   1.100  
   1.101  
     2.1 --- a/viff/test/bedoza/test_bedoza_triple.py	Mon Oct 04 10:26:57 2010 +0200
     2.2 +++ b/viff/test/bedoza/test_bedoza_triple.py	Mon Oct 04 10:27:01 2010 +0200
     2.3 @@ -384,12 +384,35 @@
     2.4      timeout = 25
     2.5  
     2.6      @protocol
     2.7 +    def test_generate_triples_generates_correct_single_triple(self, runtime):
     2.8 +        p = 17
     2.9 +        Zp = GF(p)
    2.10 +        random = Random(574566 + runtime.id)        
    2.11 +        triple_generator = TripleGenerator(runtime, self.security_parameter, p, random)
    2.12 +        triples = triple_generator._generate_triples(1)
    2.13 +
    2.14 +        def check((a, b, c)):
    2.15 +            self.assertEquals(c, a * b)
    2.16 +
    2.17 +        def open(triple):
    2.18 +            d1 = runtime.open(triple.a)
    2.19 +            d2 = runtime.open(triple.b)
    2.20 +            d3 = runtime.open(triple.c)
    2.21 +            d = gatherResults([d1, d2, d3])
    2.22 +            runtime.schedule_callback(d, check)
    2.23 +            return d
    2.24 +
    2.25 +        for triple in triples:
    2.26 +            runtime.schedule_callback(triple, open)
    2.27 +        return gatherResults(triples)
    2.28 +
    2.29 +    @protocol
    2.30      def test_generate_triples_generates_correct_triples(self, runtime):
    2.31          p = 17
    2.32  
    2.33          Zp = GF(p)
    2.34        
    2.35 -        random = Random(283883)        
    2.36 +        random = Random(574566 + runtime.id)        
    2.37          triple_generator = TripleGenerator(runtime, self.security_parameter, p, random)
    2.38  
    2.39          triples = triple_generator._generate_triples(10)