Mercurial > viff
changeset 662:c0304d48fbba
Added a single_share_random method.
author | Martin Geisler <mg@daimi.au.dk> |
---|---|
date | Sun, 13 Apr 2008 17:20:10 +0200 |
parents | d66a147bbea6 |
children | 8f2e45ecc8b4 |
files | viff/runtime.py |
diffstat | 1 files changed, 87 insertions(+), 0 deletions(-) [+] |
line wrap: on
line diff
--- a/viff/runtime.py Sun Apr 13 15:03:15 2008 +0200 +++ b/viff/runtime.py Sun Apr 13 17:20:10 2008 +0200 @@ -1016,6 +1016,93 @@ return result @increment_pc + def single_share_random(self, T, degree, field): + """Share a random secret. + + The guarantee is that a number of shares are made and out of + those, the T that are returned by this method will be correct + sharings of a random number using C{degree} as the polynomial + degree. + + @param T: The number of shares output. + @param degree: The degree of the polynomial. + @param field: The field over which to share the secret. + """ + # TODO: Move common code between single_share and + # double_share_random out to their own methods. + inputters = range(1, self.num_players + 1) + if self._hyper is None: + self._hyper = hyper(self.num_players, field) + + # Generate a random element. + si = rand.randint(0, field.modulus - 1) + + # Every player shares the random value with two thresholds. + shares = self.shamir_share(inputters, field, si, degree) + + # Turn the shares into a column vector. + svec = Matrix([shares]).transpose() + + # Apply the hyper-invertible matrix to svec1 and svec2. + rvec = (self._hyper * svec) + + # Get back to normal lists of shares. + svec = svec.transpose().rows[0] + rvec = rvec.transpose().rows[0] + + def verify(shares): + """Verify shares. + + It is checked that they correspond to polynomial of the + expected degree. + + If the verification succeeds, the T shares are returned, + otherwise the errback is called. + """ + # TODO: This is necessary since shamir.recombine expects + # to receive a list of *pairs* of field elements. + shares = map(lambda (i, s): (field(i+1), s), enumerate(shares)) + + # Verify the sharings. If any of the assertions fail and + # raise an exception, the errbacks will be called on the + # share returned by single_share_random. + assert shamir.verify_sharing(shares, degree), "Could not verify" + + # If we reach this point the n - T shares were verified + # and we can safely return the first T shares. + return rvec[:T] + + def exchange(svec): + """Exchange and (if possible) verify shares.""" + pc = tuple(self.program_counter) + + # We send our shares to the verifying players. + for offset, share in enumerate(svec): + if T+1+offset != self.id: + self.protocols[T+1+offset].sendShare(pc, share) + + if self.id > T: + # The other players will send us their shares of si_1 + # and si_2 and we will verify it. + si = [] + for peer_id in inputters: + if self.id == peer_id: + si.append(Share(self, field, svec[peer_id - T - 1])) + else: + si.append(self._expect_share(peer_id, field)) + result = gatherResults(si) + self.schedule_callback(result, verify) + return result + else: + # We cannot verify anything, so we just return the + # first T shares. + return rvec[:T] + + result = gather_shares(svec[T:]) + self.schedule_callback(result, exchange) + return result + + @increment_pc def double_share_random(self, T, d1, d2, field): """Double-share a random secret using two polynomials.